예제 #1
0
/*
 * Open the inner, decrypted PKCS7 and try to write CA/RA certificates 
 */
int
write_ca_ra(struct http_reply *s) {
	BIO			*bio;
	PKCS7			*p7;
	STACK_OF(X509)		*certs = NULL;
	X509			*cert = NULL;
	FILE			*fp = NULL;
	int			c, i, index;
        unsigned int		n;
        unsigned char		md[EVP_MAX_MD_SIZE];
	X509_EXTENSION		*ext;

	/* Create read-only memory bio */
	bio = BIO_new_mem_buf(s->payload, s->bytes);
	p7 = d2i_PKCS7_bio(bio, NULL);
	if (p7 == NULL) {
		fprintf(stderr, "%s: error reading PKCS#7 data\n", pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_FILE);
	}
	/* Get certs */
	i = OBJ_obj2nid(p7->type);
	switch (i) {
		case NID_pkcs7_signed:
			certs = p7->d.sign->cert;
			break;
		default:
			printf("%s: wrong PKCS#7 type\n", pname);
			exit (SCEP_PKISTATUS_FILE);
	}
	/* Check  */
	if (certs == NULL) {
		fprintf(stderr, "%s: cannot find certificates\n", pname);
		exit (SCEP_PKISTATUS_FILE);
	} 

	/* Verify the chain
	 * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
	 */
	/* Find cert */
	for (i = 0; i < sk_X509_num(certs); i++) {
		char buffer[1024];
		char name[1024];

		memset(buffer, 0, 1024);
		memset(name, 0, 1024);
		cert = sk_X509_value(certs, i);

		/* Create name */
		snprintf(name, 1024, "%s-%d", c_char, i);

		/* Read and print certificate information */
		printf("\n%s: found certificate with\n  subject: %s\n", pname,
		X509_NAME_oneline(X509_get_subject_name(cert),
					buffer, sizeof(buffer)));
		printf("  issuer: %s\n", 
			X509_NAME_oneline(X509_get_issuer_name(cert),
					buffer, sizeof(buffer)));
		if (!X509_digest(cert, fp_alg, md, &n)) {
			ERR_print_errors_fp(stderr);
			exit (SCEP_PKISTATUS_FILE);
		}
		/* Print key usage: */
		index = X509_get_ext_by_NID(cert, NID_key_usage, -1);
		if (index < 0) {
			if (v_flag)
				fprintf(stderr, "%s: cannot find key usage\n",
					pname);
			/* exit (SCEP_PKISTATUS_FILE); */
		} else {
			ext = X509_get_ext(cert, index);
			printf("  usage: ");
			X509V3_EXT_print_fp(stdout, ext, 0, 0);
			printf("\n");
		}

		printf("  %s fingerprint: ", OBJ_nid2sn(EVP_MD_type(fp_alg)));
		for (c = 0; c < (int)n; c++) {
			printf("%02X%c",md[c], (c + 1 == (int)n) ?'\n':':');
		}

		/* Write PEM-formatted file: */
		if (!(fp = fopen(name, "w"))) {
			fprintf(stderr, "%s: cannot open cert file for "
				"writing\n", pname);
			exit (SCEP_PKISTATUS_FILE);
		}
		if (v_flag)
			printf("%s: writing cert\n", pname);
		if (d_flag)
			PEM_write_X509(stdout, cert);
		if (PEM_write_X509(fp, cert) != 1) {
			fprintf(stderr, "%s: error while writing certificate "
				"file\n", pname);
			ERR_print_errors_fp(stderr);
			exit (SCEP_PKISTATUS_FILE);
		}
		printf("%s: certificate written as %s\n", pname, name);
	}
	(void)fclose(fp);
	exit (SCEP_PKISTATUS_SUCCESS);
}
예제 #2
0
static void x509v3_cache_extensions(X509 *x)
{
    BASIC_CONSTRAINTS *bs;
    PROXY_CERT_INFO_EXTENSION *pci;
    ASN1_BIT_STRING *usage;
    ASN1_BIT_STRING *ns;
    EXTENDED_KEY_USAGE *extusage;
    X509_EXTENSION *ex;

    int i;
    if (x->ex_flags & EXFLAG_SET)
        return;
#ifndef OPENSSL_NO_SHA
    X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
#endif
    /* V1 should mean no extensions ... */
    if (!X509_get_version(x))
        x->ex_flags |= EXFLAG_V1;
    /* Handle basic constraints */
    if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
        if (bs->ca)
            x->ex_flags |= EXFLAG_CA;
        if (bs->pathlen) {
            if ((bs->pathlen->type == V_ASN1_NEG_INTEGER)
                || !bs->ca) {
                x->ex_flags |= EXFLAG_INVALID;
                x->ex_pathlen = 0;
            } else
                x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
        } else
            x->ex_pathlen = -1;
        BASIC_CONSTRAINTS_free(bs);
        x->ex_flags |= EXFLAG_BCONS;
    }
    /* Handle proxy certificates */
    if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
        if (x->ex_flags & EXFLAG_CA
            || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
            || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
            x->ex_flags |= EXFLAG_INVALID;
        }
        if (pci->pcPathLengthConstraint) {
            x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint);
        } else
            x->ex_pcpathlen = -1;
        PROXY_CERT_INFO_EXTENSION_free(pci);
        x->ex_flags |= EXFLAG_PROXY;
    }
    /* Handle key usage */
    if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
        if (usage->length > 0) {
            x->ex_kusage = usage->data[0];
            if (usage->length > 1)
                x->ex_kusage |= usage->data[1] << 8;
        } else
            x->ex_kusage = 0;
        x->ex_flags |= EXFLAG_KUSAGE;
        ASN1_BIT_STRING_free(usage);
    }
    x->ex_xkusage = 0;
    if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
        x->ex_flags |= EXFLAG_XKUSAGE;
        for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
            switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) {
            case NID_server_auth:
                x->ex_xkusage |= XKU_SSL_SERVER;
                break;

            case NID_client_auth:
                x->ex_xkusage |= XKU_SSL_CLIENT;
                break;

            case NID_email_protect:
                x->ex_xkusage |= XKU_SMIME;
                break;

            case NID_code_sign:
                x->ex_xkusage |= XKU_CODE_SIGN;
                break;

            case NID_ms_sgc:
            case NID_ns_sgc:
                x->ex_xkusage |= XKU_SGC;
                break;

            case NID_OCSP_sign:
                x->ex_xkusage |= XKU_OCSP_SIGN;
                break;

            case NID_time_stamp:
                x->ex_xkusage |= XKU_TIMESTAMP;
                break;

            case NID_dvcs:
                x->ex_xkusage |= XKU_DVCS;
                break;

            case NID_anyExtendedKeyUsage:
                x->ex_xkusage |= XKU_ANYEKU;
                break;
            }
        }
        sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
    }

    if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
        if (ns->length > 0)
            x->ex_nscert = ns->data[0];
        else
            x->ex_nscert = 0;
        x->ex_flags |= EXFLAG_NSCERT;
        ASN1_BIT_STRING_free(ns);
    }
    x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
    x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
    /* Does subject name match issuer ? */
    if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
        x->ex_flags |= EXFLAG_SI;
        /* If SKID matches AKID also indicate self signed */
        if (X509_check_akid(x, x->akid) == X509_V_OK)
            x->ex_flags |= EXFLAG_SS;
    }
    x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
    x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
    if (!x->nc && (i != -1))
        x->ex_flags |= EXFLAG_INVALID;
    setup_crldp(x);

#ifndef OPENSSL_NO_RFC3779
    x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
    x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
                                       NULL, NULL);
#endif
    for (i = 0; i < X509_get_ext_count(x); i++) {
        ex = X509_get_ext(x, i);
        if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
            == NID_freshest_crl)
            x->ex_flags |= EXFLAG_FRESHEST;
        if (!X509_EXTENSION_get_critical(ex))
            continue;
        if (!X509_supported_extension(ex)) {
            x->ex_flags |= EXFLAG_CRITICAL;
            break;
        }
    }
    x->ex_flags |= EXFLAG_SET;
}
예제 #3
0
/**
  Determines if the specified EKU represented in ASN1 form is present
  in a given certificate.

  @param[in]  Cert                  The certificate to check.

  @param[in]  Asn1ToFind            The EKU to look for.

  @retval EFI_SUCCESS               We successfully identified the signing type.
  @retval EFI_INVALID_PARAMETER     A parameter was invalid.
  @retval EFI_NOT_FOUND             One or more EKU's were not found in the signature.

**/
EFI_STATUS
IsEkuInCertificate (
  IN CONST X509  *Cert,
  IN ASN1_OBJECT *Asn1ToFind
  )
{
  EFI_STATUS          Status;
  X509                *ClonedCert;
  X509_EXTENSION      *Extension;
  EXTENDED_KEY_USAGE  *Eku;
  INT32               ExtensionIndex;
  INTN                NumExtensions;
  ASN1_OBJECT         *Asn1InCert;
  INTN                Index;

  Status            = EFI_NOT_FOUND;
  ClonedCert        = NULL;
  Extension         = NULL;
  Eku               = NULL;
  ExtensionIndex    = -1;
  NumExtensions     = 0;
  Asn1InCert        = NULL;

  if (Cert == NULL || Asn1ToFind == NULL) {
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  //
  // Clone the certificate.  This is required because the Extension API's
  // only work once per instance of an X509 object.
  //
  ClonedCert = X509_dup ((X509*)Cert);
  if (ClonedCert == NULL) {
    //
    // Fail to duplicate cert.
    //
    Status = EFI_INVALID_PARAMETER;
    goto Exit;
  }

  //
  // Look for the extended key usage.
  //
  ExtensionIndex = X509_get_ext_by_NID (ClonedCert, NID_ext_key_usage, -1);

  if (ExtensionIndex < 0) {
    //
    // Fail to find 'NID_ext_key_usage' in Cert.
    //
    goto Exit;
  }

  Extension = X509_get_ext (ClonedCert, ExtensionIndex);
  if (Extension == NULL) {
    //
    // Fail to get Extension form cert.
    //
    goto Exit;
  }

  Eku = (EXTENDED_KEY_USAGE*)X509V3_EXT_d2i (Extension);
  if (Eku == NULL) {
    //
    // Fail to get Eku from extension.
    //
    goto Exit;
  }

  NumExtensions = sk_ASN1_OBJECT_num (Eku);

  //
  // Now loop through the extensions, looking for the specified Eku.
  //
  for (Index = 0; Index < NumExtensions; Index++) {
    Asn1InCert = sk_ASN1_OBJECT_value (Eku, (INT32)Index);
    if (Asn1InCert == NULL) {
      //
      // Fail to get ASN object from Eku.
      //
      goto Exit;
    }

    if (Asn1InCert->length == Asn1ToFind->length &&
        CompareMem (Asn1InCert->data, Asn1ToFind->data, Asn1InCert->length) == 0) {
      //
      // Found Eku in certificate.
      //
      Status = EFI_SUCCESS;
      goto Exit;
    }
  }

Exit:

  //
  // Release Resources
  //
  if (ClonedCert) {
    X509_free (ClonedCert);
  }

  if (Eku) {
    sk_ASN1_OBJECT_pop_free (Eku, ASN1_OBJECT_free);
  }

  return Status;
}
예제 #4
0
gboolean
z_proxy_ssl_host_iface_check_name_method(ZProxyHostIface *s,
                                         const gchar *host_name,
                                         gchar *reason_buf, gsize reason_len)
{
  ZProxySslHostIface *self = Z_CAST(s, ZProxySslHostIface);
  gint ext_ndx;
  gboolean found = FALSE, result = FALSE;
  gchar pattern_buf[256];

  if (self->hostname_checked)
    return self->hostname_check_result;

  pattern_buf[0] = 0;
  ext_ndx = X509_get_ext_by_NID(self->server_cert, NID_subject_alt_name, -1);
  if (ext_ndx >= 0)
    {
      /* ok, there's a subjectAltName extension, check that */
      X509_EXTENSION *ext;
      STACK_OF(GENERAL_NAME) *alt_names;
      GENERAL_NAME *gen_name;

      ext = X509_get_ext(self->server_cert, ext_ndx);
      alt_names = X509V3_EXT_d2i(ext);
      if (alt_names)
        {
          gint num, i;

          num = sk_GENERAL_NAME_num(alt_names);

          for (i = 0; i < num; i++)
            {
              gen_name = sk_GENERAL_NAME_value(alt_names, i);
              if (gen_name->type == GEN_DNS)
                {
                  guchar *dnsname = ASN1_STRING_data(gen_name->d.dNSName);
                  guint dnsname_len = ASN1_STRING_length(gen_name->d.dNSName);

                  if (dnsname_len > sizeof(pattern_buf) - 1)
                    {
                      found = TRUE;
                      result = FALSE;
                      break;
                    }

                  memcpy(pattern_buf, dnsname, dnsname_len);
                  pattern_buf[dnsname_len] = 0;
                  /* we have found a DNS name as alternative subject name */
                  found = TRUE;
                  result = z_proxy_ssl_host_iface_check_wildcard(s->owner, host_name, pattern_buf);
                  break;
                }
              else if (gen_name->type == GEN_IPADD)
                {
                  z_inet_ntoa(pattern_buf, sizeof(pattern_buf), *(struct in_addr *) gen_name->d.iPAddress->data);

                  found = TRUE;
                  result = strcmp(host_name, pattern_buf) == 0;
                  break;
                }
            }
          sk_GENERAL_NAME_free(alt_names);
        }
    }

  if (!found)
    {
      /* hmm. there was no subjectAltName (this is deprecated, but still
       * widely used), look up the Subject, most specific CN */
      X509_NAME *name;

      name = X509_get_subject_name(self->server_cert);
      if (X509_NAME_get_text_by_NID(name, NID_commonName, pattern_buf, sizeof(pattern_buf)) != -1)
        {
          result = z_proxy_ssl_host_iface_check_wildcard(s->owner, host_name, pattern_buf);
        }
    }

  if (!result && reason_buf)
    {
      g_snprintf(reason_buf, reason_len, "Certificate does not belong to target host (certificate: %s, host %s)",
                 pattern_buf, host_name);
    }
  self->hostname_checked = TRUE;
  self->hostname_check_result = result;
  return result;

}
예제 #5
0
파일: ca.c 프로젝트: marctmiller/bitrig
int
ca_x509_subjectaltname(X509 *cert, struct iked_id *id)
{
	X509_EXTENSION	*san;
	u_int8_t	 sanhdr[4], *data;
	int		 ext, santype, sanlen;
	char		 idstr[IKED_ID_SIZE];

	if ((ext = X509_get_ext_by_NID(cert,
	    NID_subject_alt_name, -1)) == -1 ||
	    ((san = X509_get_ext(cert, ext)) == NULL)) {
		log_debug("%s: did not find subjectAltName in certificate",
		    __func__);
		return (-1);
	}

	if (san->value == NULL || san->value->data == NULL ||
	    san->value->length < (int)sizeof(sanhdr)) {
		log_debug("%s: invalid subjectAltName in certificate",
		    __func__);
		return (-1);
	}

	/* This is partially based on isakmpd's x509 subjectaltname code */
	data = (u_int8_t *)san->value->data;
	memcpy(&sanhdr, data, sizeof(sanhdr));
	santype = sanhdr[2] & 0x3f;
	sanlen = sanhdr[3];

	if ((sanlen + (int)sizeof(sanhdr)) > san->value->length) {
		log_debug("%s: invalid subjectAltName length", __func__);
		return (-1);
	}

	switch (santype) {
	case GEN_DNS:
		id->id_type = IKEV2_ID_FQDN;
		break;
	case GEN_EMAIL:
		id->id_type = IKEV2_ID_UFQDN;
		break;
	case GEN_IPADD:
		if (sanlen == 4)
			id->id_type = IKEV2_ID_IPV4;
		else if (sanlen == 16)
			id->id_type = IKEV2_ID_IPV6;
		else {
			log_debug("%s: invalid subjectAltName IP address",
			    __func__);
			return (-1);
		}
		break;
	default:
		log_debug("%s: unsupported subjectAltName type %d",
		    __func__, santype);
		return (-1);
	}

	ibuf_release(id->id_buf);
	if ((id->id_buf = ibuf_new(data + sizeof(sanhdr), sanlen)) == NULL) {
		log_debug("%s: failed to get id buffer", __func__);
		return (-1);
	}
	id->id_offset = 0;

	ikev2_print_id(id, idstr, sizeof(idstr));
	log_debug("%s: %s", __func__, idstr);

	return (0);
}