/* retrieve basic constraints ingredients */ BOOL modssl_X509_getBC(X509 *cert, int *ca, int *pathlen) { BASIC_CONSTRAINTS *bc; BIGNUM *bn = NULL; char *cp; bc = X509_get_ext_d2i(cert, NID_basic_constraints, NULL, NULL); if (bc == NULL) return FALSE; *ca = bc->ca; *pathlen = -1 /* unlimited */; if (bc->pathlen != NULL) { if ((bn = ASN1_INTEGER_to_BN(bc->pathlen, NULL)) == NULL) { BASIC_CONSTRAINTS_free(bc); return FALSE; } if ((cp = BN_bn2dec(bn)) == NULL) { BN_free(bn); BASIC_CONSTRAINTS_free(bc); return FALSE; } *pathlen = atoi(cp); OPENSSL_free(cp); BN_free(bn); } BASIC_CONSTRAINTS_free(bc); return TRUE; }
/* retrieve basic constraints ingredients */ BOOL SSL_X509_getBC(X509 *cert, int *ca, int *pathlen) { X509_EXTENSION *ext; BASIC_CONSTRAINTS *bc; int idx; BIGNUM *bn = NULL; char *cp; if ((idx = X509_get_ext_by_NID(cert, NID_basic_constraints, -1)) < 0) return FALSE; ext = X509_get_ext(cert, idx); if (ext == NULL) return FALSE; if ((bc = (BASIC_CONSTRAINTS *)X509V3_EXT_d2i(ext)) == NULL) return FALSE; *ca = bc->ca; *pathlen = -1 /* unlimited */; if (bc->pathlen != NULL) { if ((bn = ASN1_INTEGER_to_BN(bc->pathlen, NULL)) == NULL) return FALSE; if ((cp = BN_bn2dec(bn)) == NULL) return FALSE; *pathlen = atoi(cp); OPENSSL_free(cp); BN_free(bn); } BASIC_CONSTRAINTS_free(bc); return TRUE; }
PKI_X509_CERT_TYPE PKI_X509_CERT_get_type(const PKI_X509_CERT *x) { PKI_X509_CERT_TYPE ret = PKI_X509_CERT_TYPE_USER; const PKI_X509_NAME *subj = NULL; const PKI_X509_NAME *issuer = NULL; BASIC_CONSTRAINTS *bs = NULL; PKI_X509_EXTENSION *ext = NULL; if (!x || !x->value || (x->type != PKI_DATATYPE_X509_CERT) ) return PKI_X509_CERT_TYPE_UNKNOWN; subj = PKI_X509_CERT_get_data ( x, PKI_X509_DATA_SUBJECT ); issuer = PKI_X509_CERT_get_data ( x, PKI_X509_DATA_ISSUER ); if ( subj && issuer ) { if ( PKI_X509_NAME_cmp( subj, issuer ) == 0) { ret |= PKI_X509_CERT_TYPE_ROOT; } } if((ext = PKI_X509_CERT_get_extension_by_id ( x, NID_basic_constraints)) != NULL ) { if(( bs = ext->value )) { if ( bs->ca ) ret |= PKI_X509_CERT_TYPE_CA; BASIC_CONSTRAINTS_free ( bs ); } PKI_X509_EXTENSION_free ( ext ); } if((ext = PKI_X509_CERT_get_extension_by_id ( x, NID_proxyCertInfo )) != NULL ) { if ( ret & PKI_X509_CERT_TYPE_CA ) { PKI_log_err ( "Certificate Error, Proxy Cert info set", "in a CA certificate!"); } else { ret |= PKI_X509_CERT_TYPE_PROXY; } PKI_X509_EXTENSION_free ( ext ); } return ret; }
extern "C" int32_t DecodeX509BasicConstraints2Extension(const unsigned char* encoded, int32_t encodedLength, int32_t* certificateAuthority, int32_t* hasPathLengthConstraint, int32_t* pathLengthConstraint) { if (!certificateAuthority || !hasPathLengthConstraint || !pathLengthConstraint) { return false; } *certificateAuthority = false; *hasPathLengthConstraint = false; *pathLengthConstraint = 0; int32_t result = false; BASIC_CONSTRAINTS* constraints = d2i_BASIC_CONSTRAINTS(nullptr, &encoded, encodedLength); if (constraints) { *certificateAuthority = constraints->ca != 0; if (constraints->pathlen != nullptr) { *hasPathLengthConstraint = true; long pathLength = ASN1_INTEGER_get(constraints->pathlen); // pathLengthConstraint needs to be in the Int32 range assert(pathLength <= INT32_MAX); *pathLengthConstraint = static_cast<int32_t>(pathLength); } else { *hasPathLengthConstraint = false; *pathLengthConstraint = 0; } BASIC_CONSTRAINTS_free(constraints); result = true; } return result; }
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 /* Does subject name match issuer ? */ if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) x->ex_flags |= EXFLAG_SS; /* 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, 0) >= 0 || X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 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; } } 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); for (i = 0; i < X509_get_ext_count(x); i++) { ex = X509_get_ext(x, i); if (!X509_EXTENSION_get_critical(ex)) continue; if (!X509_supported_extension(ex)) { x->ex_flags |= EXFLAG_CRITICAL; break; } } x->ex_flags |= EXFLAG_SET; }