Loading CHANGES +8 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,14 @@ Changes between 0.9.8i and 0.9.9 [xx XXX xxxx] *) Initial indirect CRL support. Currently only supported in the CRLs passed directly and not via lookup. Process certificate issuer CRL entry extension and lookup CRL entries by bother issuer name and serial number. Check and proces CRL issuer entry in IDP extension. This work was sponsored by Google. [Steve Henson] *) Add support for distinct certificate and CRL paths. The CRL issuer certificate is validated separately in this case. Only enabled if an extended CRL support flag is set: this flag will enable additional Loading crypto/asn1/asn1_locl.h +2 −1 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ struct x509_crl_method_st int flags; int (*crl_init)(X509_CRL *crl); int (*crl_free)(X509_CRL *crl); int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser); int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser, X509_NAME *issuer); int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk); }; crypto/asn1/x_crl.c +130 −12 Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ ASN1_SEQUENCE(X509_REVOKED) = { static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r); static int def_crl_lookup(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial); X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer); static X509_CRL_METHOD int_crl_meth = { Loading Loading @@ -119,6 +119,72 @@ ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = { ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0) } ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO) /* Set CRL entry issuer according to CRL certificate issuer extension. * Check for unhandled critical CRL entry extensions. */ static int crl_set_issuers(X509_CRL *crl) { int i, j; GENERAL_NAMES *gens, *gtmp; STACK_OF(X509_REVOKED) *revoked; revoked = X509_CRL_get_REVOKED(crl); gens = NULL; for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) { X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); STACK_OF(X509_EXTENSION) *exts; X509_EXTENSION *ext; gtmp = X509_REVOKED_get_ext_d2i(rev, NID_certificate_issuer, &j, NULL); if (!gtmp && (j != -1)) { crl->flags |= EXFLAG_INVALID; return 1; } if (gtmp) { gens = gtmp; if (!crl->issuers) { crl->issuers = sk_GENERAL_NAMES_new_null(); if (!crl->issuers) return 0; } if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) return 0; } rev->issuer = gens; /* Check for critical CRL entry extensions */ exts = rev->extensions; for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) { ext = sk_X509_EXTENSION_value(exts, j); if (ext->critical > 0) { if (OBJ_obj2nid(ext->object) == NID_certificate_issuer) continue; crl->flags |= EXFLAG_CRITICAL; break; } } } return 1; } /* The X509_CRL structure needs a bit of customisation. Cache some extensions * and hash of the whole CRL. */ Loading @@ -139,6 +205,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, crl->idp_flags = 0; crl->meth = default_crl_method; crl->meth_data = NULL; crl->issuers = NULL; break; case ASN1_OP_D2I_POST: Loading Loading @@ -176,6 +243,11 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, break; } } if (!crl_set_issuers(crl)) return 0; if (crl->meth->crl_init) { if (crl->meth->crl_init(crl) == 0) Loading @@ -193,6 +265,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, AUTHORITY_KEYID_free(crl->akid); if (crl->idp) ISSUING_DIST_POINT_free(crl->idp); sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); break; } return 1; Loading Loading @@ -284,7 +357,16 @@ int X509_CRL_get0_by_serial(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial) { if (crl->meth->crl_lookup) return crl->meth->crl_lookup(crl, ret, serial); return crl->meth->crl_lookup(crl, ret, serial, NULL); return 0; } int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x) { if (crl->meth->crl_lookup) return crl->meth->crl_lookup(crl, ret, X509_get_serialNumber(x), X509_get_issuer_name(x)); return 0; } Loading @@ -294,10 +376,39 @@ static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r) crl->sig_alg, crl->signature,crl->crl,r)); } static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, X509_REVOKED *rev) { int i; if (!rev->issuer) { if (!nm) return 1; if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) return 1; return 0; } if (!nm) nm = X509_CRL_get_issuer(crl); for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) { GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i); if (gen->type != GEN_DIRNAME) continue; if (!X509_NAME_cmp(nm, gen->d.directoryName)) return 1; } return 0; } static int def_crl_lookup(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial) X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer) { X509_REVOKED rtmp; X509_REVOKED rtmp, *rev; int idx; rtmp.serialNumber = serial; /* Sort revoked into serial number order if not already sorted. Loading @@ -310,15 +421,21 @@ static int def_crl_lookup(X509_CRL *crl, CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL); } idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); /* If found assume revoked: want something cleverer than * this to handle entry extensions in V2 CRLs. */ if(idx >= 0) if(idx < 0) return 0; /* Need to look for matching name */ for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) { rev = sk_X509_REVOKED_value(crl->crl->revoked, idx); if (ASN1_INTEGER_cmp(rev->serialNumber, serial)) return 0; if (crl_revoked_issuer_match(crl, issuer, rev)) { if (ret) *ret = sk_X509_REVOKED_value(crl->crl->revoked, idx); *ret = rev; return 1; } } return 0; } Loading @@ -333,7 +450,8 @@ void X509_CRL_set_default_method(const X509_CRL_METHOD *meth) X509_CRL_METHOD *X509_CRL_METHOD_new( int (*crl_init)(X509_CRL *crl), int (*crl_free)(X509_CRL *crl), int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser), int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser, X509_NAME *issuer), int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk)) { X509_CRL_METHOD *m; Loading crypto/x509/x509.h +6 −1 Original line number Diff line number Diff line Loading @@ -434,6 +434,8 @@ struct x509_revoked_st ASN1_INTEGER *serialNumber; ASN1_TIME *revocationDate; STACK_OF(X509_EXTENSION) /* optional */ *extensions; /* Set up if indirect CRL */ STACK_OF(GENERAL_NAME) *issuer; int sequence; /* load sequence */ }; Loading Loading @@ -469,6 +471,7 @@ struct X509_crl_st #ifndef OPENSSL_NO_SHA unsigned char sha1_hash[SHA_DIGEST_LENGTH]; #endif STACK_OF(GENERAL_NAMES) *issuers; const X509_CRL_METHOD *meth; void *meth_data; } /* X509_CRL */; Loading Loading @@ -617,7 +620,8 @@ void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); X509_CRL_METHOD *X509_CRL_METHOD_new( int (*crl_init)(X509_CRL *crl), int (*crl_free)(X509_CRL *crl), int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser), int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser, X509_NAME *issuer), int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk)); void X509_CRL_METHOD_free(X509_CRL_METHOD *m); Loading Loading @@ -847,6 +851,7 @@ DECLARE_ASN1_FUNCTIONS(X509_CRL) int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); int X509_CRL_get0_by_serial(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial); int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); X509_PKEY * X509_PKEY_new(void ); void X509_PKEY_free(X509_PKEY *a); Loading crypto/x509/x509_vfy.c +59 −28 Original line number Diff line number Diff line Loading @@ -80,7 +80,7 @@ static int check_revocation(X509_STORE_CTX *ctx); static int check_cert(X509_STORE_CTX *ctx); static int check_policy(X509_STORE_CTX *ctx); static int crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer); static int idp_check_scope(X509 *x, X509_CRL *crl); static int idp_check_scope(X509 *x, X509_CRL *crl, int *pimatch); static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path, Loading Loading @@ -751,7 +751,7 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) /* IDP flags which cause a CRL to be rejected */ #define IDP_REJECT (IDP_INVALID|IDP_INDIRECT|IDP_REASONS) #define IDP_REJECT (IDP_INVALID|IDP_REASONS) static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_NAME *nm, STACK_OF(X509_CRL) *crls) Loading @@ -761,11 +761,19 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *crl_issuer, *best_crl_issuer = NULL; for (i = 0; i < sk_X509_CRL_num(crls); i++) { int imatch = 1; crl_score = 0; crl_issuer = NULL; crl = sk_X509_CRL_value(crls, i); if (nm && X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) { /* Issuer name does not match: could be indirect */ if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) continue; if (!(crl->idp_flags & IDP_INDIRECT)) continue; imatch = 0; } if (check_crl_time(ctx, crl, 0)) crl_score |= CRL_SCORE_TIME; Loading @@ -773,12 +781,16 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, { if (crl->idp_flags & IDP_REJECT) continue; if (idp_check_scope(ctx->current_cert, crl)) if (idp_check_scope(ctx->current_cert, crl, &imatch)) crl_score |= CRL_SCORE_SCOPE; } else crl_score |= CRL_SCORE_SCOPE; /* If no issuer match at this point try next CRL */ if (!imatch) continue; if (crl_akid_check(ctx, crl, &crl_issuer)) crl_score |= CRL_SCORE_AKID; /* If CRL matches criteria and issuer is not different use it */ Loading Loading @@ -809,6 +821,7 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, static int crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer) { X509 *crl_issuer; X509_NAME *cnm = X509_CRL_get_issuer(crl); int cidx = ctx->error_depth; int i; if (!crl->akid) Loading @@ -818,25 +831,18 @@ static int crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer) crl_issuer = sk_X509_value(ctx->chain, cidx); if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) return 1; /* If crl_issuer is self issued we may get a match further along the * chain. */ if (crl_issuer->ex_flags & EXFLAG_SI) { for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) { crl_issuer = sk_X509_value(ctx->chain, cidx); if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) continue; if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { *pissuer = crl_issuer; return 1; } if (!(crl_issuer->ex_flags & EXFLAG_SI)) break; } } /* Anything else needs extended CRL support */ if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) Loading @@ -845,7 +851,6 @@ static int crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer) /* Otherwise the CRL issuer is not on the path. Look for it in the * set of untrusted certificates. */ for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { crl_issuer = sk_X509_value(ctx->untrusted, i); Loading Loading @@ -928,6 +933,7 @@ static int check_crl_chain(X509_STORE_CTX *ctx, * 1. Both are relative names and compare X509_NAME types. * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES. * 3. Both are full names and compare two GENERAL_NAMES. * 4. One is NULL: automatic match. */ Loading @@ -937,6 +943,8 @@ static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) GENERAL_NAMES *gens = NULL; GENERAL_NAME *gena, *genb; int i, j; if (!a || !b) return 1; if (a->type == 1) { if (!a->dpname) Loading Loading @@ -995,9 +1003,30 @@ static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) } static int idp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int *pimatch) { int i; X509_NAME *nm = X509_CRL_get_issuer(crl); /* If no CRLissuer return is successful iff don't need a match */ if (!dp->CRLissuer) return *pimatch; for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); if (gen->type != GEN_DIRNAME) continue; if (!X509_NAME_cmp(gen->d.directoryName, nm)) { *pimatch = 1; return 1; } } return 0; } /* Check IDP name matches at least one CRLDP name */ static int idp_check_scope(X509 *x, X509_CRL *crl) static int idp_check_scope(X509 *x, X509_CRL *crl, int *pimatch) { int i; if (crl->idp_flags & IDP_ONLYATTR) Loading @@ -1012,19 +1041,20 @@ static int idp_check_scope(X509 *x, X509_CRL *crl) if (crl->idp_flags & IDP_ONLYCA) return 0; } if (!crl->idp->distpoint) if (!crl->idp->distpoint && *pimatch) return 1; if (!x->crldp) return 0; for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); /* We don't handle these at present */ if (dp->reasons || dp->CRLissuer) if (dp->reasons) continue; if (idp_check_dp(dp->distpoint, crl->idp->distpoint)) { if (idp_check_crlissuer(dp, crl, pimatch)) return 1; } } return 0; } Loading Loading @@ -1117,19 +1147,20 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) if (crl->idp_flags & IDP_PRESENT) { int dmy = 1; if (crl->idp_flags & IDP_INVALID) { ctx->error = X509_V_ERR_INVALID_EXTENSION; ok = ctx->verify_cb(0, ctx); if(!ok) goto err; } if (crl->idp_flags & (IDP_REASONS|IDP_INDIRECT)) if (crl->idp_flags & IDP_REASONS) { ctx->error = X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE; ok = ctx->verify_cb(0, ctx); if(!ok) goto err; } if (!idp_check_scope(ctx->current_cert, crl)) if (!idp_check_scope(ctx->current_cert, crl, &dmy)) { ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; ok = ctx->verify_cb(0, ctx); Loading Loading @@ -1177,7 +1208,7 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) * If found assume revoked: want something cleverer than * this to handle entry extensions in V2 CRLs. */ if (X509_CRL_get0_by_serial(crl, NULL, X509_get_serialNumber(x)) > 0) if (X509_CRL_get0_by_cert(crl, NULL, x) > 0) { ctx->error = X509_V_ERR_CERT_REVOKED; ok = ctx->verify_cb(0, ctx); Loading Loading
CHANGES +8 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,14 @@ Changes between 0.9.8i and 0.9.9 [xx XXX xxxx] *) Initial indirect CRL support. Currently only supported in the CRLs passed directly and not via lookup. Process certificate issuer CRL entry extension and lookup CRL entries by bother issuer name and serial number. Check and proces CRL issuer entry in IDP extension. This work was sponsored by Google. [Steve Henson] *) Add support for distinct certificate and CRL paths. The CRL issuer certificate is validated separately in this case. Only enabled if an extended CRL support flag is set: this flag will enable additional Loading
crypto/asn1/asn1_locl.h +2 −1 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ struct x509_crl_method_st int flags; int (*crl_init)(X509_CRL *crl); int (*crl_free)(X509_CRL *crl); int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser); int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser, X509_NAME *issuer); int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk); };
crypto/asn1/x_crl.c +130 −12 Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ ASN1_SEQUENCE(X509_REVOKED) = { static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r); static int def_crl_lookup(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial); X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer); static X509_CRL_METHOD int_crl_meth = { Loading Loading @@ -119,6 +119,72 @@ ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = { ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0) } ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO) /* Set CRL entry issuer according to CRL certificate issuer extension. * Check for unhandled critical CRL entry extensions. */ static int crl_set_issuers(X509_CRL *crl) { int i, j; GENERAL_NAMES *gens, *gtmp; STACK_OF(X509_REVOKED) *revoked; revoked = X509_CRL_get_REVOKED(crl); gens = NULL; for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) { X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); STACK_OF(X509_EXTENSION) *exts; X509_EXTENSION *ext; gtmp = X509_REVOKED_get_ext_d2i(rev, NID_certificate_issuer, &j, NULL); if (!gtmp && (j != -1)) { crl->flags |= EXFLAG_INVALID; return 1; } if (gtmp) { gens = gtmp; if (!crl->issuers) { crl->issuers = sk_GENERAL_NAMES_new_null(); if (!crl->issuers) return 0; } if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) return 0; } rev->issuer = gens; /* Check for critical CRL entry extensions */ exts = rev->extensions; for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) { ext = sk_X509_EXTENSION_value(exts, j); if (ext->critical > 0) { if (OBJ_obj2nid(ext->object) == NID_certificate_issuer) continue; crl->flags |= EXFLAG_CRITICAL; break; } } } return 1; } /* The X509_CRL structure needs a bit of customisation. Cache some extensions * and hash of the whole CRL. */ Loading @@ -139,6 +205,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, crl->idp_flags = 0; crl->meth = default_crl_method; crl->meth_data = NULL; crl->issuers = NULL; break; case ASN1_OP_D2I_POST: Loading Loading @@ -176,6 +243,11 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, break; } } if (!crl_set_issuers(crl)) return 0; if (crl->meth->crl_init) { if (crl->meth->crl_init(crl) == 0) Loading @@ -193,6 +265,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, AUTHORITY_KEYID_free(crl->akid); if (crl->idp) ISSUING_DIST_POINT_free(crl->idp); sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); break; } return 1; Loading Loading @@ -284,7 +357,16 @@ int X509_CRL_get0_by_serial(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial) { if (crl->meth->crl_lookup) return crl->meth->crl_lookup(crl, ret, serial); return crl->meth->crl_lookup(crl, ret, serial, NULL); return 0; } int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x) { if (crl->meth->crl_lookup) return crl->meth->crl_lookup(crl, ret, X509_get_serialNumber(x), X509_get_issuer_name(x)); return 0; } Loading @@ -294,10 +376,39 @@ static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r) crl->sig_alg, crl->signature,crl->crl,r)); } static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, X509_REVOKED *rev) { int i; if (!rev->issuer) { if (!nm) return 1; if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) return 1; return 0; } if (!nm) nm = X509_CRL_get_issuer(crl); for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) { GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i); if (gen->type != GEN_DIRNAME) continue; if (!X509_NAME_cmp(nm, gen->d.directoryName)) return 1; } return 0; } static int def_crl_lookup(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial) X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer) { X509_REVOKED rtmp; X509_REVOKED rtmp, *rev; int idx; rtmp.serialNumber = serial; /* Sort revoked into serial number order if not already sorted. Loading @@ -310,15 +421,21 @@ static int def_crl_lookup(X509_CRL *crl, CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL); } idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); /* If found assume revoked: want something cleverer than * this to handle entry extensions in V2 CRLs. */ if(idx >= 0) if(idx < 0) return 0; /* Need to look for matching name */ for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) { rev = sk_X509_REVOKED_value(crl->crl->revoked, idx); if (ASN1_INTEGER_cmp(rev->serialNumber, serial)) return 0; if (crl_revoked_issuer_match(crl, issuer, rev)) { if (ret) *ret = sk_X509_REVOKED_value(crl->crl->revoked, idx); *ret = rev; return 1; } } return 0; } Loading @@ -333,7 +450,8 @@ void X509_CRL_set_default_method(const X509_CRL_METHOD *meth) X509_CRL_METHOD *X509_CRL_METHOD_new( int (*crl_init)(X509_CRL *crl), int (*crl_free)(X509_CRL *crl), int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser), int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser, X509_NAME *issuer), int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk)) { X509_CRL_METHOD *m; Loading
crypto/x509/x509.h +6 −1 Original line number Diff line number Diff line Loading @@ -434,6 +434,8 @@ struct x509_revoked_st ASN1_INTEGER *serialNumber; ASN1_TIME *revocationDate; STACK_OF(X509_EXTENSION) /* optional */ *extensions; /* Set up if indirect CRL */ STACK_OF(GENERAL_NAME) *issuer; int sequence; /* load sequence */ }; Loading Loading @@ -469,6 +471,7 @@ struct X509_crl_st #ifndef OPENSSL_NO_SHA unsigned char sha1_hash[SHA_DIGEST_LENGTH]; #endif STACK_OF(GENERAL_NAMES) *issuers; const X509_CRL_METHOD *meth; void *meth_data; } /* X509_CRL */; Loading Loading @@ -617,7 +620,8 @@ void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); X509_CRL_METHOD *X509_CRL_METHOD_new( int (*crl_init)(X509_CRL *crl), int (*crl_free)(X509_CRL *crl), int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser), int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *ser, X509_NAME *issuer), int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk)); void X509_CRL_METHOD_free(X509_CRL_METHOD *m); Loading Loading @@ -847,6 +851,7 @@ DECLARE_ASN1_FUNCTIONS(X509_CRL) int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); int X509_CRL_get0_by_serial(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial); int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); X509_PKEY * X509_PKEY_new(void ); void X509_PKEY_free(X509_PKEY *a); Loading
crypto/x509/x509_vfy.c +59 −28 Original line number Diff line number Diff line Loading @@ -80,7 +80,7 @@ static int check_revocation(X509_STORE_CTX *ctx); static int check_cert(X509_STORE_CTX *ctx); static int check_policy(X509_STORE_CTX *ctx); static int crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer); static int idp_check_scope(X509 *x, X509_CRL *crl); static int idp_check_scope(X509 *x, X509_CRL *crl, int *pimatch); static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path, Loading Loading @@ -751,7 +751,7 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) /* IDP flags which cause a CRL to be rejected */ #define IDP_REJECT (IDP_INVALID|IDP_INDIRECT|IDP_REASONS) #define IDP_REJECT (IDP_INVALID|IDP_REASONS) static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_NAME *nm, STACK_OF(X509_CRL) *crls) Loading @@ -761,11 +761,19 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *crl_issuer, *best_crl_issuer = NULL; for (i = 0; i < sk_X509_CRL_num(crls); i++) { int imatch = 1; crl_score = 0; crl_issuer = NULL; crl = sk_X509_CRL_value(crls, i); if (nm && X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) { /* Issuer name does not match: could be indirect */ if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) continue; if (!(crl->idp_flags & IDP_INDIRECT)) continue; imatch = 0; } if (check_crl_time(ctx, crl, 0)) crl_score |= CRL_SCORE_TIME; Loading @@ -773,12 +781,16 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, { if (crl->idp_flags & IDP_REJECT) continue; if (idp_check_scope(ctx->current_cert, crl)) if (idp_check_scope(ctx->current_cert, crl, &imatch)) crl_score |= CRL_SCORE_SCOPE; } else crl_score |= CRL_SCORE_SCOPE; /* If no issuer match at this point try next CRL */ if (!imatch) continue; if (crl_akid_check(ctx, crl, &crl_issuer)) crl_score |= CRL_SCORE_AKID; /* If CRL matches criteria and issuer is not different use it */ Loading Loading @@ -809,6 +821,7 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, static int crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer) { X509 *crl_issuer; X509_NAME *cnm = X509_CRL_get_issuer(crl); int cidx = ctx->error_depth; int i; if (!crl->akid) Loading @@ -818,25 +831,18 @@ static int crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer) crl_issuer = sk_X509_value(ctx->chain, cidx); if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) return 1; /* If crl_issuer is self issued we may get a match further along the * chain. */ if (crl_issuer->ex_flags & EXFLAG_SI) { for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) { crl_issuer = sk_X509_value(ctx->chain, cidx); if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) continue; if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { *pissuer = crl_issuer; return 1; } if (!(crl_issuer->ex_flags & EXFLAG_SI)) break; } } /* Anything else needs extended CRL support */ if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) Loading @@ -845,7 +851,6 @@ static int crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer) /* Otherwise the CRL issuer is not on the path. Look for it in the * set of untrusted certificates. */ for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { crl_issuer = sk_X509_value(ctx->untrusted, i); Loading Loading @@ -928,6 +933,7 @@ static int check_crl_chain(X509_STORE_CTX *ctx, * 1. Both are relative names and compare X509_NAME types. * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES. * 3. Both are full names and compare two GENERAL_NAMES. * 4. One is NULL: automatic match. */ Loading @@ -937,6 +943,8 @@ static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) GENERAL_NAMES *gens = NULL; GENERAL_NAME *gena, *genb; int i, j; if (!a || !b) return 1; if (a->type == 1) { if (!a->dpname) Loading Loading @@ -995,9 +1003,30 @@ static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) } static int idp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int *pimatch) { int i; X509_NAME *nm = X509_CRL_get_issuer(crl); /* If no CRLissuer return is successful iff don't need a match */ if (!dp->CRLissuer) return *pimatch; for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); if (gen->type != GEN_DIRNAME) continue; if (!X509_NAME_cmp(gen->d.directoryName, nm)) { *pimatch = 1; return 1; } } return 0; } /* Check IDP name matches at least one CRLDP name */ static int idp_check_scope(X509 *x, X509_CRL *crl) static int idp_check_scope(X509 *x, X509_CRL *crl, int *pimatch) { int i; if (crl->idp_flags & IDP_ONLYATTR) Loading @@ -1012,19 +1041,20 @@ static int idp_check_scope(X509 *x, X509_CRL *crl) if (crl->idp_flags & IDP_ONLYCA) return 0; } if (!crl->idp->distpoint) if (!crl->idp->distpoint && *pimatch) return 1; if (!x->crldp) return 0; for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); /* We don't handle these at present */ if (dp->reasons || dp->CRLissuer) if (dp->reasons) continue; if (idp_check_dp(dp->distpoint, crl->idp->distpoint)) { if (idp_check_crlissuer(dp, crl, pimatch)) return 1; } } return 0; } Loading Loading @@ -1117,19 +1147,20 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) if (crl->idp_flags & IDP_PRESENT) { int dmy = 1; if (crl->idp_flags & IDP_INVALID) { ctx->error = X509_V_ERR_INVALID_EXTENSION; ok = ctx->verify_cb(0, ctx); if(!ok) goto err; } if (crl->idp_flags & (IDP_REASONS|IDP_INDIRECT)) if (crl->idp_flags & IDP_REASONS) { ctx->error = X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE; ok = ctx->verify_cb(0, ctx); if(!ok) goto err; } if (!idp_check_scope(ctx->current_cert, crl)) if (!idp_check_scope(ctx->current_cert, crl, &dmy)) { ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; ok = ctx->verify_cb(0, ctx); Loading Loading @@ -1177,7 +1208,7 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) * If found assume revoked: want something cleverer than * this to handle entry extensions in V2 CRLs. */ if (X509_CRL_get0_by_serial(crl, NULL, X509_get_serialNumber(x)) > 0) if (X509_CRL_get0_by_cert(crl, NULL, x) > 0) { ctx->error = X509_V_ERR_CERT_REVOKED; ok = ctx->verify_cb(0, ctx); Loading