Loading CHANGES +6 −0 Original line number Original line Diff line number Diff line Loading @@ -4,6 +4,12 @@ Changes between 0.9.8i and 0.9.9 [xx XXX xxxx] Changes between 0.9.8i and 0.9.9 [xx XXX xxxx] *) Delta CRL support. New use deltas option which will attempt to locate and search any appropriate delta CRLs available. This work was sponsored by Google. [Steve Henson] *) Support for CRLs partitioned by reason code. Reorganise CRL processing *) Support for CRLs partitioned by reason code. Reorganise CRL processing code and add additional score elements. Validate alternate CRL paths code and add additional score elements. Validate alternate CRL paths as part of the CRL checking and indicate a new error "CRL path validation as part of the CRL checking and indicate a new error "CRL path validation Loading apps/apps.c +2 −0 Original line number Original line Diff line number Diff line Loading @@ -2241,6 +2241,8 @@ int args_verify(char ***pargs, int *pargc, flags |= X509_V_FLAG_X509_STRICT; flags |= X509_V_FLAG_X509_STRICT; else if (!strcmp(arg, "-extended_crl")) else if (!strcmp(arg, "-extended_crl")) flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT; flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT; else if (!strcmp(arg, "-use_deltas")) flags |= X509_V_FLAG_USE_DELTAS; else if (!strcmp(arg, "-policy_print")) else if (!strcmp(arg, "-policy_print")) flags |= X509_V_FLAG_NOTIFY_POLICY; flags |= X509_V_FLAG_NOTIFY_POLICY; else else Loading crypto/asn1/x_crl.c +40 −4 Original line number Original line Diff line number Diff line Loading @@ -137,6 +137,7 @@ static int crl_set_issuers(X509_CRL *crl) { { X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); STACK_OF(X509_EXTENSION) *exts; STACK_OF(X509_EXTENSION) *exts; ASN1_ENUMERATED *reason; X509_EXTENSION *ext; X509_EXTENSION *ext; gtmp = X509_REVOKED_get_ext_d2i(rev, gtmp = X509_REVOKED_get_ext_d2i(rev, NID_certificate_issuer, NID_certificate_issuer, Loading @@ -161,6 +162,22 @@ static int crl_set_issuers(X509_CRL *crl) } } rev->issuer = gens; rev->issuer = gens; reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL); if (!reason && (j != -1)) { crl->flags |= EXFLAG_INVALID; return 1; } if (reason) { rev->reason = ASN1_ENUMERATED_get(reason); ASN1_ENUMERATED_free(reason); } else rev->reason = CRL_REASON_NONE; /* Check for critical CRL entry extensions */ /* Check for critical CRL entry extensions */ exts = rev->extensions; exts = rev->extensions; Loading Loading @@ -207,6 +224,8 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, crl->meth = default_crl_method; crl->meth = default_crl_method; crl->meth_data = NULL; crl->meth_data = NULL; crl->issuers = NULL; crl->issuers = NULL; crl->crl_number = NULL; crl->base_crl_number = NULL; break; break; case ASN1_OP_D2I_POST: case ASN1_OP_D2I_POST: Loading @@ -221,6 +240,15 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, crl->akid = X509_CRL_get_ext_d2i(crl, crl->akid = X509_CRL_get_ext_d2i(crl, NID_authority_key_identifier, NULL, NULL); NID_authority_key_identifier, NULL, NULL); crl->crl_number = X509_CRL_get_ext_d2i(crl, NID_crl_number, NULL, NULL); crl->base_crl_number = X509_CRL_get_ext_d2i(crl, NID_delta_crl, NULL, NULL); /* Delta CRLs must have CRL number */ if (crl->base_crl_number && !crl->crl_number) crl->flags |= EXFLAG_INVALID; /* See if we have any unhandled critical CRL extensions and /* See if we have any unhandled critical CRL extensions and * indicate this in a flag. We only currently handle IDP so * indicate this in a flag. We only currently handle IDP so * anything else critical sets the flag. * anything else critical sets the flag. Loading @@ -233,13 +261,17 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) { { int nid; ext = sk_X509_EXTENSION_value(exts, idx); ext = sk_X509_EXTENSION_value(exts, idx); nid = OBJ_obj2nid(ext->object); if (nid == NID_freshest_crl) crl->flags |= EXFLAG_FRESHEST; if (ext->critical > 0) if (ext->critical > 0) { { /* We handle IDP now so permit it */ /* We handle IDP and deltas */ if (OBJ_obj2nid(ext->object) == if ((nid == NID_issuing_distribution_point) NID_issuing_distribution_point) || (nid == NID_delta_crl)) continue; break;; crl->flags |= EXFLAG_CRITICAL; crl->flags |= EXFLAG_CRITICAL; break; break; } } Loading @@ -266,6 +298,8 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, AUTHORITY_KEYID_free(crl->akid); AUTHORITY_KEYID_free(crl->akid); if (crl->idp) if (crl->idp) ISSUING_DIST_POINT_free(crl->idp); ISSUING_DIST_POINT_free(crl->idp); ASN1_INTEGER_free(crl->crl_number); ASN1_INTEGER_free(crl->base_crl_number); sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); break; break; } } Loading Loading @@ -435,6 +469,8 @@ static int def_crl_lookup(X509_CRL *crl, { { if (ret) if (ret) *ret = rev; *ret = rev; if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) return 2; return 1; return 1; } } } } Loading crypto/x509/x509.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -436,6 +436,8 @@ struct x509_revoked_st STACK_OF(X509_EXTENSION) /* optional */ *extensions; STACK_OF(X509_EXTENSION) /* optional */ *extensions; /* Set up if indirect CRL */ /* Set up if indirect CRL */ STACK_OF(GENERAL_NAME) *issuer; STACK_OF(GENERAL_NAME) *issuer; /* Revocation reason */ int reason; int sequence; /* load sequence */ int sequence; /* load sequence */ }; }; Loading Loading @@ -468,6 +470,9 @@ struct X509_crl_st /* Convenient breakdown of IDP */ /* Convenient breakdown of IDP */ int idp_flags; int idp_flags; int idp_reasons; int idp_reasons; /* CRL and base CRL numbers for delta processing */ ASN1_INTEGER *crl_number; ASN1_INTEGER *base_crl_number; #ifndef OPENSSL_NO_SHA #ifndef OPENSSL_NO_SHA unsigned char sha1_hash[SHA_DIGEST_LENGTH]; unsigned char sha1_hash[SHA_DIGEST_LENGTH]; #endif #endif Loading crypto/x509/x509_vfy.c +254 −99 Original line number Original line Diff line number Diff line Loading @@ -70,6 +70,44 @@ #include <openssl/x509v3.h> #include <openssl/x509v3.h> #include <openssl/objects.h> #include <openssl/objects.h> /* CRL score values */ /* No unhandled critical extensions */ #define CRL_SCORE_NOCRITICAL 0x100 /* certificate is within CRL scope */ #define CRL_SCORE_SCOPE 0x080 /* CRL times valid */ #define CRL_SCORE_TIME 0x040 /* Issuer name matches certificate */ #define CRL_SCORE_ISSUER_NAME 0x020 /* If this score or above CRL is probably valid */ #define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) /* CRL issuer is certificate issuer */ #define CRL_SCORE_ISSUER_CERT 0x018 /* CRL issuer is on certificate path */ #define CRL_SCORE_SAME_PATH 0x008 /* CRL issuer matches CRL AKID */ #define CRL_SCORE_AKID 0x004 /* Have a delta CRL with valid times */ #define CRL_SCORE_TIME_DELTA 0x002 static int null_callback(int ok,X509_STORE_CTX *e); static int null_callback(int ok,X509_STORE_CTX *e); static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); Loading @@ -83,6 +121,10 @@ static int check_policy(X509_STORE_CTX *ctx); static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, unsigned int *preasons, unsigned int *preasons, X509_CRL *crl, X509 *x); X509_CRL *crl, X509 *x); static int get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x); static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score, X509_CRL *base, STACK_OF(X509_CRL) *crls); static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, int *pcrl_score); X509 **pissuer, int *pcrl_score); static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, Loading Loading @@ -649,7 +691,7 @@ static int check_revocation(X509_STORE_CTX *ctx) static int check_cert(X509_STORE_CTX *ctx) static int check_cert(X509_STORE_CTX *ctx) { { X509_CRL *crl = NULL; X509_CRL *crl = NULL, *dcrl = NULL; X509 *x; X509 *x; int ok, cnum; int ok, cnum; cnum = ctx->error_depth; cnum = ctx->error_depth; Loading @@ -660,7 +702,10 @@ static int check_cert(X509_STORE_CTX *ctx) while (ctx->current_reasons != CRLDP_ALL_REASONS) while (ctx->current_reasons != CRLDP_ALL_REASONS) { { /* Try to retrieve relevant CRL */ /* Try to retrieve relevant CRL */ if (ctx->get_crl) ok = ctx->get_crl(ctx, &crl, x); ok = ctx->get_crl(ctx, &crl, x); else ok = get_crl_delta(ctx, &crl, &dcrl, x); /* If error looking up CRL, nothing we can do except /* If error looking up CRL, nothing we can do except * notify callback * notify callback */ */ Loading @@ -674,14 +719,36 @@ static int check_cert(X509_STORE_CTX *ctx) ok = ctx->check_crl(ctx, crl); ok = ctx->check_crl(ctx, crl); if (!ok) if (!ok) goto err; goto err; if (dcrl) { ok = ctx->check_crl(ctx, dcrl); if (!ok) goto err; ok = ctx->cert_crl(ctx, dcrl, x); if (!ok) goto err; } else ok = 1; /* Don't look in full CRL if delta reason is removefromCRL */ if (ok != 2) { ok = ctx->cert_crl(ctx, crl, x); ok = ctx->cert_crl(ctx, crl, x); if (!ok) if (!ok) goto err; goto err; } X509_CRL_free(crl); X509_CRL_free(crl); X509_CRL_free(dcrl); crl = NULL; crl = NULL; dcrl = NULL; } } err: err: X509_CRL_free(crl); X509_CRL_free(crl); X509_CRL_free(dcrl); ctx->current_crl = NULL; ctx->current_crl = NULL; return ok; return ok; Loading Loading @@ -731,8 +798,8 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) if (!ctx->verify_cb(0, ctx)) if (!ctx->verify_cb(0, ctx)) return 0; return 0; } } /* Ignore expiry of base CRL is delta is valid */ if (i < 0) if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { { if (!notify) if (!notify) return 0; return 0; Loading @@ -748,46 +815,8 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) return 1; return 1; } } /* CRL score values */ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, X509 **pissuer, int *pscore, unsigned int *preasons, /* No unhandled critical extensions */ #define CRL_SCORE_NOCRITICAL 0x100 /* certificate is within CRL scope */ #define CRL_SCORE_SCOPE 0x080 /* CRL times valid */ #define CRL_SCORE_TIME 0x040 /* Issuer name matches certificate */ #define CRL_SCORE_ISSUER_NAME 0x020 /* If this score or above CRL is probably valid */ #define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) /* CRL issuer is certificate issuer */ #define CRL_SCORE_ISSUER_CERT 0x018 /* CRL issuer is on certificate path */ #define CRL_SCORE_SAME_PATH 0x008 /* CRL issuer matches CRL AKID */ #define CRL_SCORE_AKID 0x004 /* CRL is complete, not delta */ #define CRL_SCORE_COMPLETE 0x002 static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 **pissuer, int *pscore, unsigned int *preasons, STACK_OF(X509_CRL) *crls) STACK_OF(X509_CRL) *crls) { { int i, crl_score, best_score = *pscore; int i, crl_score, best_score = *pscore; Loading Loading @@ -818,9 +847,14 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 **pissuer, *pissuer = best_crl_issuer; *pissuer = best_crl_issuer; *pscore = best_score; *pscore = best_score; *preasons = best_reasons; *preasons = best_reasons; CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509); CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL); if (*pdcrl) { X509_CRL_free(*pdcrl); *pdcrl = NULL; } get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); } } if (best_score >= CRL_SCORE_VALID) if (best_score >= CRL_SCORE_VALID) return 1; return 1; Loading @@ -828,6 +862,106 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 **pissuer, return 0; return 0; } } /* Compare two CRL extensions for delta checking purposes. They should be * both present or both absent. If both present all fields must be identical. */ static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) { ASN1_OCTET_STRING *exta, *extb; int i; i = X509_CRL_get_ext_by_NID(a, nid, 0); if (i >= 0) { /* Can't have multiple occurrences */ if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) return 0; exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); } else exta = NULL; i = X509_CRL_get_ext_by_NID(b, nid, 0); if (i >= 0) { if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) return 0; extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); } else extb = NULL; if (!exta && !extb) return 1; if (!exta || !extb) return 0; if (ASN1_OCTET_STRING_cmp(exta, extb)) return 0; return 1; } /* See if a base and delta are compatible */ static int check_delta_base(X509_CRL *delta, X509_CRL *base) { /* Delta CRL must be a delta */ if (!delta->base_crl_number) return 0; /* Base must have a CRL number */ if (!base->crl_number) return 0; /* Issuer names must match */ if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta))) return 0; /* AKID and IDP must match */ if (!crl_extension_match(delta, base, NID_authority_key_identifier)) return 0; if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) return 0; /* Delta CRL base number must not exceed Full CRL number. */ if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) return 0; /* Delta CRL number must exceed full CRL number */ if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) return 1; return 0; } /* For a given base CRL find a delta... maybe extend to delta scoring * or retrieve a chain of deltas... */ static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, X509_CRL *base, STACK_OF(X509_CRL) *crls) { X509_CRL *delta; int i; if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) return; if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) return; for (i = 0; i < sk_X509_CRL_num(crls); i++) { delta = sk_X509_CRL_value(crls, i); if (check_delta_base(delta, base)) { if (check_crl_time(ctx, delta, 0)) *pscore |= CRL_SCORE_TIME_DELTA; CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL); *dcrl = delta; return; } } *dcrl = NULL; } /* For a given CRL return how suitable it is for the supplied certificate 'x'. /* For a given CRL return how suitable it is for the supplied certificate 'x'. * The return value is a mask of several criteria. * The return value is a mask of several criteria. * If the issuer is not the certificate issuer this is returned in *pissuer. * If the issuer is not the certificate issuer this is returned in *pissuer. Loading Loading @@ -860,6 +994,9 @@ static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, if (!(crl->idp_reasons & ~tmp_reasons)) if (!(crl->idp_reasons & ~tmp_reasons)) return 0; return 0; } } /* Don't process deltas at this stage */ else if (crl->base_crl_number) return 0; /* If issuer name doesn't match certificate need indirect CRL */ /* If issuer name doesn't match certificate need indirect CRL */ if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) { { Loading Loading @@ -1146,22 +1283,24 @@ static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, return 0; return 0; } } /* Retrieve CRL corresponding to current certificate. Currently only /* Retrieve CRL corresponding to current certificate. * one CRL is retrieved. Multiple CRLs may be needed if we handle * If deltas enabled try to find a delta CRL too * CRLs partitioned on reason code later. */ */ static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) static int get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) { { int ok; int ok; X509 *issuer = NULL; X509 *issuer = NULL; int crl_score = 0; int crl_score = 0; unsigned int reasons; unsigned int reasons; X509_CRL *crl = NULL; X509_CRL *crl = NULL, *dcrl = NULL; STACK_OF(X509_CRL) *skcrl; STACK_OF(X509_CRL) *skcrl; X509_NAME *nm = X509_get_issuer_name(x); X509_NAME *nm = X509_get_issuer_name(x); reasons = ctx->current_reasons; reasons = ctx->current_reasons; ok = get_crl_sk(ctx, &crl, &issuer, &crl_score, &reasons, ctx->crls); ok = get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, ctx->crls); if (ok) if (ok) goto done; goto done; Loading @@ -1173,7 +1312,7 @@ static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) if (!skcrl && crl) if (!skcrl && crl) goto done; goto done; get_crl_sk(ctx, &crl, &issuer, &crl_score, &reasons, skcrl); get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); sk_X509_CRL_pop_free(skcrl, X509_CRL_free); sk_X509_CRL_pop_free(skcrl, X509_CRL_free); Loading @@ -1186,6 +1325,7 @@ static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) ctx->current_crl_score = crl_score; ctx->current_crl_score = crl_score; ctx->current_reasons = reasons; ctx->current_reasons = reasons; *pcrl = crl; *pcrl = crl; *pdcrl = dcrl; return 1; return 1; } } Loading @@ -1203,6 +1343,7 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) /* if we have an alternative CRL issuer cert use that */ /* if we have an alternative CRL issuer cert use that */ if (ctx->current_issuer) if (ctx->current_issuer) issuer = ctx->current_issuer; issuer = ctx->current_issuer; /* Else find CRL issuer: if not last certificate then issuer /* Else find CRL issuer: if not last certificate then issuer * is next certificate in chain. * is next certificate in chain. */ */ Loading @@ -1221,6 +1362,11 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) } } if(issuer) if(issuer) { /* Skip most tests for deltas because they have already * been done */ if (!crl->base_crl_number) { { /* Check for cRLSign bit if keyUsage present */ /* Check for cRLSign bit if keyUsage present */ if ((issuer->ex_flags & EXFLAG_KUSAGE) && if ((issuer->ex_flags & EXFLAG_KUSAGE) && Loading @@ -1238,13 +1384,6 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) if(!ok) goto err; if(!ok) goto err; } } if (!(ctx->current_crl_score & CRL_SCORE_TIME)) { ok = check_crl_time(ctx, crl, 1); if (!ok) goto err; } if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) { { if (!check_crl_path(ctx, ctx->current_issuer)) if (!check_crl_path(ctx, ctx->current_issuer)) Loading @@ -1262,6 +1401,16 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) if(!ok) goto err; if(!ok) goto err; } } } if (!(ctx->current_crl_score & CRL_SCORE_TIME)) { ok = check_crl_time(ctx, crl, 1); if (!ok) goto err; } /* Attempt to get issuer certificate public key */ /* Attempt to get issuer certificate public key */ ikey = X509_get_pubkey(issuer); ikey = X509_get_pubkey(issuer); Loading Loading @@ -1294,23 +1443,29 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) { { int ok; int ok; /* Look for serial number of certificate in CRL X509_REVOKED *rev; * If found assume revoked: want something cleverer than /* The rules changed for this... previously if a CRL contained * this to handle entry extensions in V2 CRLs. * unhandled critical extensions it could still be used to indicate * a certificate was revoked. This has since been changed since * critical extension can change the meaning of CRL entries. */ */ if (X509_CRL_get0_by_cert(crl, NULL, x) > 0) if (crl->flags & EXFLAG_CRITICAL) { { ctx->error = X509_V_ERR_CERT_REVOKED; if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) return 1; ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; ok = ctx->verify_cb(0, ctx); ok = ctx->verify_cb(0, ctx); if(!ok) if(!ok) return 0; return 0; } } /* Look for serial number of certificate in CRL if (crl->flags & EXFLAG_CRITICAL) * If found make sure reason is not removeFromCRL. */ if (X509_CRL_get0_by_cert(crl, &rev, x)) { { if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) return 1; return 2; ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; ctx->error = X509_V_ERR_CERT_REVOKED; ok = ctx->verify_cb(0, ctx); ok = ctx->verify_cb(0, ctx); if (!ok) if (!ok) return 0; return 0; Loading Loading @@ -1898,7 +2053,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, if (store && store->get_crl) if (store && store->get_crl) ctx->get_crl = store->get_crl; ctx->get_crl = store->get_crl; else else ctx->get_crl = get_crl; ctx->get_crl = NULL; if (store && store->check_crl) if (store && store->check_crl) ctx->check_crl = store->check_crl; ctx->check_crl = store->check_crl; Loading Loading
CHANGES +6 −0 Original line number Original line Diff line number Diff line Loading @@ -4,6 +4,12 @@ Changes between 0.9.8i and 0.9.9 [xx XXX xxxx] Changes between 0.9.8i and 0.9.9 [xx XXX xxxx] *) Delta CRL support. New use deltas option which will attempt to locate and search any appropriate delta CRLs available. This work was sponsored by Google. [Steve Henson] *) Support for CRLs partitioned by reason code. Reorganise CRL processing *) Support for CRLs partitioned by reason code. Reorganise CRL processing code and add additional score elements. Validate alternate CRL paths code and add additional score elements. Validate alternate CRL paths as part of the CRL checking and indicate a new error "CRL path validation as part of the CRL checking and indicate a new error "CRL path validation Loading
apps/apps.c +2 −0 Original line number Original line Diff line number Diff line Loading @@ -2241,6 +2241,8 @@ int args_verify(char ***pargs, int *pargc, flags |= X509_V_FLAG_X509_STRICT; flags |= X509_V_FLAG_X509_STRICT; else if (!strcmp(arg, "-extended_crl")) else if (!strcmp(arg, "-extended_crl")) flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT; flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT; else if (!strcmp(arg, "-use_deltas")) flags |= X509_V_FLAG_USE_DELTAS; else if (!strcmp(arg, "-policy_print")) else if (!strcmp(arg, "-policy_print")) flags |= X509_V_FLAG_NOTIFY_POLICY; flags |= X509_V_FLAG_NOTIFY_POLICY; else else Loading
crypto/asn1/x_crl.c +40 −4 Original line number Original line Diff line number Diff line Loading @@ -137,6 +137,7 @@ static int crl_set_issuers(X509_CRL *crl) { { X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); STACK_OF(X509_EXTENSION) *exts; STACK_OF(X509_EXTENSION) *exts; ASN1_ENUMERATED *reason; X509_EXTENSION *ext; X509_EXTENSION *ext; gtmp = X509_REVOKED_get_ext_d2i(rev, gtmp = X509_REVOKED_get_ext_d2i(rev, NID_certificate_issuer, NID_certificate_issuer, Loading @@ -161,6 +162,22 @@ static int crl_set_issuers(X509_CRL *crl) } } rev->issuer = gens; rev->issuer = gens; reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL); if (!reason && (j != -1)) { crl->flags |= EXFLAG_INVALID; return 1; } if (reason) { rev->reason = ASN1_ENUMERATED_get(reason); ASN1_ENUMERATED_free(reason); } else rev->reason = CRL_REASON_NONE; /* Check for critical CRL entry extensions */ /* Check for critical CRL entry extensions */ exts = rev->extensions; exts = rev->extensions; Loading Loading @@ -207,6 +224,8 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, crl->meth = default_crl_method; crl->meth = default_crl_method; crl->meth_data = NULL; crl->meth_data = NULL; crl->issuers = NULL; crl->issuers = NULL; crl->crl_number = NULL; crl->base_crl_number = NULL; break; break; case ASN1_OP_D2I_POST: case ASN1_OP_D2I_POST: Loading @@ -221,6 +240,15 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, crl->akid = X509_CRL_get_ext_d2i(crl, crl->akid = X509_CRL_get_ext_d2i(crl, NID_authority_key_identifier, NULL, NULL); NID_authority_key_identifier, NULL, NULL); crl->crl_number = X509_CRL_get_ext_d2i(crl, NID_crl_number, NULL, NULL); crl->base_crl_number = X509_CRL_get_ext_d2i(crl, NID_delta_crl, NULL, NULL); /* Delta CRLs must have CRL number */ if (crl->base_crl_number && !crl->crl_number) crl->flags |= EXFLAG_INVALID; /* See if we have any unhandled critical CRL extensions and /* See if we have any unhandled critical CRL extensions and * indicate this in a flag. We only currently handle IDP so * indicate this in a flag. We only currently handle IDP so * anything else critical sets the flag. * anything else critical sets the flag. Loading @@ -233,13 +261,17 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) { { int nid; ext = sk_X509_EXTENSION_value(exts, idx); ext = sk_X509_EXTENSION_value(exts, idx); nid = OBJ_obj2nid(ext->object); if (nid == NID_freshest_crl) crl->flags |= EXFLAG_FRESHEST; if (ext->critical > 0) if (ext->critical > 0) { { /* We handle IDP now so permit it */ /* We handle IDP and deltas */ if (OBJ_obj2nid(ext->object) == if ((nid == NID_issuing_distribution_point) NID_issuing_distribution_point) || (nid == NID_delta_crl)) continue; break;; crl->flags |= EXFLAG_CRITICAL; crl->flags |= EXFLAG_CRITICAL; break; break; } } Loading @@ -266,6 +298,8 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, AUTHORITY_KEYID_free(crl->akid); AUTHORITY_KEYID_free(crl->akid); if (crl->idp) if (crl->idp) ISSUING_DIST_POINT_free(crl->idp); ISSUING_DIST_POINT_free(crl->idp); ASN1_INTEGER_free(crl->crl_number); ASN1_INTEGER_free(crl->base_crl_number); sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); break; break; } } Loading Loading @@ -435,6 +469,8 @@ static int def_crl_lookup(X509_CRL *crl, { { if (ret) if (ret) *ret = rev; *ret = rev; if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) return 2; return 1; return 1; } } } } Loading
crypto/x509/x509.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -436,6 +436,8 @@ struct x509_revoked_st STACK_OF(X509_EXTENSION) /* optional */ *extensions; STACK_OF(X509_EXTENSION) /* optional */ *extensions; /* Set up if indirect CRL */ /* Set up if indirect CRL */ STACK_OF(GENERAL_NAME) *issuer; STACK_OF(GENERAL_NAME) *issuer; /* Revocation reason */ int reason; int sequence; /* load sequence */ int sequence; /* load sequence */ }; }; Loading Loading @@ -468,6 +470,9 @@ struct X509_crl_st /* Convenient breakdown of IDP */ /* Convenient breakdown of IDP */ int idp_flags; int idp_flags; int idp_reasons; int idp_reasons; /* CRL and base CRL numbers for delta processing */ ASN1_INTEGER *crl_number; ASN1_INTEGER *base_crl_number; #ifndef OPENSSL_NO_SHA #ifndef OPENSSL_NO_SHA unsigned char sha1_hash[SHA_DIGEST_LENGTH]; unsigned char sha1_hash[SHA_DIGEST_LENGTH]; #endif #endif Loading
crypto/x509/x509_vfy.c +254 −99 Original line number Original line Diff line number Diff line Loading @@ -70,6 +70,44 @@ #include <openssl/x509v3.h> #include <openssl/x509v3.h> #include <openssl/objects.h> #include <openssl/objects.h> /* CRL score values */ /* No unhandled critical extensions */ #define CRL_SCORE_NOCRITICAL 0x100 /* certificate is within CRL scope */ #define CRL_SCORE_SCOPE 0x080 /* CRL times valid */ #define CRL_SCORE_TIME 0x040 /* Issuer name matches certificate */ #define CRL_SCORE_ISSUER_NAME 0x020 /* If this score or above CRL is probably valid */ #define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) /* CRL issuer is certificate issuer */ #define CRL_SCORE_ISSUER_CERT 0x018 /* CRL issuer is on certificate path */ #define CRL_SCORE_SAME_PATH 0x008 /* CRL issuer matches CRL AKID */ #define CRL_SCORE_AKID 0x004 /* Have a delta CRL with valid times */ #define CRL_SCORE_TIME_DELTA 0x002 static int null_callback(int ok,X509_STORE_CTX *e); static int null_callback(int ok,X509_STORE_CTX *e); static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); Loading @@ -83,6 +121,10 @@ static int check_policy(X509_STORE_CTX *ctx); static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, unsigned int *preasons, unsigned int *preasons, X509_CRL *crl, X509 *x); X509_CRL *crl, X509 *x); static int get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x); static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score, X509_CRL *base, STACK_OF(X509_CRL) *crls); static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, int *pcrl_score); X509 **pissuer, int *pcrl_score); static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, Loading Loading @@ -649,7 +691,7 @@ static int check_revocation(X509_STORE_CTX *ctx) static int check_cert(X509_STORE_CTX *ctx) static int check_cert(X509_STORE_CTX *ctx) { { X509_CRL *crl = NULL; X509_CRL *crl = NULL, *dcrl = NULL; X509 *x; X509 *x; int ok, cnum; int ok, cnum; cnum = ctx->error_depth; cnum = ctx->error_depth; Loading @@ -660,7 +702,10 @@ static int check_cert(X509_STORE_CTX *ctx) while (ctx->current_reasons != CRLDP_ALL_REASONS) while (ctx->current_reasons != CRLDP_ALL_REASONS) { { /* Try to retrieve relevant CRL */ /* Try to retrieve relevant CRL */ if (ctx->get_crl) ok = ctx->get_crl(ctx, &crl, x); ok = ctx->get_crl(ctx, &crl, x); else ok = get_crl_delta(ctx, &crl, &dcrl, x); /* If error looking up CRL, nothing we can do except /* If error looking up CRL, nothing we can do except * notify callback * notify callback */ */ Loading @@ -674,14 +719,36 @@ static int check_cert(X509_STORE_CTX *ctx) ok = ctx->check_crl(ctx, crl); ok = ctx->check_crl(ctx, crl); if (!ok) if (!ok) goto err; goto err; if (dcrl) { ok = ctx->check_crl(ctx, dcrl); if (!ok) goto err; ok = ctx->cert_crl(ctx, dcrl, x); if (!ok) goto err; } else ok = 1; /* Don't look in full CRL if delta reason is removefromCRL */ if (ok != 2) { ok = ctx->cert_crl(ctx, crl, x); ok = ctx->cert_crl(ctx, crl, x); if (!ok) if (!ok) goto err; goto err; } X509_CRL_free(crl); X509_CRL_free(crl); X509_CRL_free(dcrl); crl = NULL; crl = NULL; dcrl = NULL; } } err: err: X509_CRL_free(crl); X509_CRL_free(crl); X509_CRL_free(dcrl); ctx->current_crl = NULL; ctx->current_crl = NULL; return ok; return ok; Loading Loading @@ -731,8 +798,8 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) if (!ctx->verify_cb(0, ctx)) if (!ctx->verify_cb(0, ctx)) return 0; return 0; } } /* Ignore expiry of base CRL is delta is valid */ if (i < 0) if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { { if (!notify) if (!notify) return 0; return 0; Loading @@ -748,46 +815,8 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) return 1; return 1; } } /* CRL score values */ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, X509 **pissuer, int *pscore, unsigned int *preasons, /* No unhandled critical extensions */ #define CRL_SCORE_NOCRITICAL 0x100 /* certificate is within CRL scope */ #define CRL_SCORE_SCOPE 0x080 /* CRL times valid */ #define CRL_SCORE_TIME 0x040 /* Issuer name matches certificate */ #define CRL_SCORE_ISSUER_NAME 0x020 /* If this score or above CRL is probably valid */ #define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) /* CRL issuer is certificate issuer */ #define CRL_SCORE_ISSUER_CERT 0x018 /* CRL issuer is on certificate path */ #define CRL_SCORE_SAME_PATH 0x008 /* CRL issuer matches CRL AKID */ #define CRL_SCORE_AKID 0x004 /* CRL is complete, not delta */ #define CRL_SCORE_COMPLETE 0x002 static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 **pissuer, int *pscore, unsigned int *preasons, STACK_OF(X509_CRL) *crls) STACK_OF(X509_CRL) *crls) { { int i, crl_score, best_score = *pscore; int i, crl_score, best_score = *pscore; Loading Loading @@ -818,9 +847,14 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 **pissuer, *pissuer = best_crl_issuer; *pissuer = best_crl_issuer; *pscore = best_score; *pscore = best_score; *preasons = best_reasons; *preasons = best_reasons; CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509); CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL); if (*pdcrl) { X509_CRL_free(*pdcrl); *pdcrl = NULL; } get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); } } if (best_score >= CRL_SCORE_VALID) if (best_score >= CRL_SCORE_VALID) return 1; return 1; Loading @@ -828,6 +862,106 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 **pissuer, return 0; return 0; } } /* Compare two CRL extensions for delta checking purposes. They should be * both present or both absent. If both present all fields must be identical. */ static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) { ASN1_OCTET_STRING *exta, *extb; int i; i = X509_CRL_get_ext_by_NID(a, nid, 0); if (i >= 0) { /* Can't have multiple occurrences */ if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) return 0; exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); } else exta = NULL; i = X509_CRL_get_ext_by_NID(b, nid, 0); if (i >= 0) { if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) return 0; extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); } else extb = NULL; if (!exta && !extb) return 1; if (!exta || !extb) return 0; if (ASN1_OCTET_STRING_cmp(exta, extb)) return 0; return 1; } /* See if a base and delta are compatible */ static int check_delta_base(X509_CRL *delta, X509_CRL *base) { /* Delta CRL must be a delta */ if (!delta->base_crl_number) return 0; /* Base must have a CRL number */ if (!base->crl_number) return 0; /* Issuer names must match */ if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta))) return 0; /* AKID and IDP must match */ if (!crl_extension_match(delta, base, NID_authority_key_identifier)) return 0; if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) return 0; /* Delta CRL base number must not exceed Full CRL number. */ if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) return 0; /* Delta CRL number must exceed full CRL number */ if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) return 1; return 0; } /* For a given base CRL find a delta... maybe extend to delta scoring * or retrieve a chain of deltas... */ static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, X509_CRL *base, STACK_OF(X509_CRL) *crls) { X509_CRL *delta; int i; if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) return; if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) return; for (i = 0; i < sk_X509_CRL_num(crls); i++) { delta = sk_X509_CRL_value(crls, i); if (check_delta_base(delta, base)) { if (check_crl_time(ctx, delta, 0)) *pscore |= CRL_SCORE_TIME_DELTA; CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL); *dcrl = delta; return; } } *dcrl = NULL; } /* For a given CRL return how suitable it is for the supplied certificate 'x'. /* For a given CRL return how suitable it is for the supplied certificate 'x'. * The return value is a mask of several criteria. * The return value is a mask of several criteria. * If the issuer is not the certificate issuer this is returned in *pissuer. * If the issuer is not the certificate issuer this is returned in *pissuer. Loading Loading @@ -860,6 +994,9 @@ static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, if (!(crl->idp_reasons & ~tmp_reasons)) if (!(crl->idp_reasons & ~tmp_reasons)) return 0; return 0; } } /* Don't process deltas at this stage */ else if (crl->base_crl_number) return 0; /* If issuer name doesn't match certificate need indirect CRL */ /* If issuer name doesn't match certificate need indirect CRL */ if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) { { Loading Loading @@ -1146,22 +1283,24 @@ static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, return 0; return 0; } } /* Retrieve CRL corresponding to current certificate. Currently only /* Retrieve CRL corresponding to current certificate. * one CRL is retrieved. Multiple CRLs may be needed if we handle * If deltas enabled try to find a delta CRL too * CRLs partitioned on reason code later. */ */ static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) static int get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) { { int ok; int ok; X509 *issuer = NULL; X509 *issuer = NULL; int crl_score = 0; int crl_score = 0; unsigned int reasons; unsigned int reasons; X509_CRL *crl = NULL; X509_CRL *crl = NULL, *dcrl = NULL; STACK_OF(X509_CRL) *skcrl; STACK_OF(X509_CRL) *skcrl; X509_NAME *nm = X509_get_issuer_name(x); X509_NAME *nm = X509_get_issuer_name(x); reasons = ctx->current_reasons; reasons = ctx->current_reasons; ok = get_crl_sk(ctx, &crl, &issuer, &crl_score, &reasons, ctx->crls); ok = get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, ctx->crls); if (ok) if (ok) goto done; goto done; Loading @@ -1173,7 +1312,7 @@ static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) if (!skcrl && crl) if (!skcrl && crl) goto done; goto done; get_crl_sk(ctx, &crl, &issuer, &crl_score, &reasons, skcrl); get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); sk_X509_CRL_pop_free(skcrl, X509_CRL_free); sk_X509_CRL_pop_free(skcrl, X509_CRL_free); Loading @@ -1186,6 +1325,7 @@ static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) ctx->current_crl_score = crl_score; ctx->current_crl_score = crl_score; ctx->current_reasons = reasons; ctx->current_reasons = reasons; *pcrl = crl; *pcrl = crl; *pdcrl = dcrl; return 1; return 1; } } Loading @@ -1203,6 +1343,7 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) /* if we have an alternative CRL issuer cert use that */ /* if we have an alternative CRL issuer cert use that */ if (ctx->current_issuer) if (ctx->current_issuer) issuer = ctx->current_issuer; issuer = ctx->current_issuer; /* Else find CRL issuer: if not last certificate then issuer /* Else find CRL issuer: if not last certificate then issuer * is next certificate in chain. * is next certificate in chain. */ */ Loading @@ -1221,6 +1362,11 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) } } if(issuer) if(issuer) { /* Skip most tests for deltas because they have already * been done */ if (!crl->base_crl_number) { { /* Check for cRLSign bit if keyUsage present */ /* Check for cRLSign bit if keyUsage present */ if ((issuer->ex_flags & EXFLAG_KUSAGE) && if ((issuer->ex_flags & EXFLAG_KUSAGE) && Loading @@ -1238,13 +1384,6 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) if(!ok) goto err; if(!ok) goto err; } } if (!(ctx->current_crl_score & CRL_SCORE_TIME)) { ok = check_crl_time(ctx, crl, 1); if (!ok) goto err; } if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) { { if (!check_crl_path(ctx, ctx->current_issuer)) if (!check_crl_path(ctx, ctx->current_issuer)) Loading @@ -1262,6 +1401,16 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) if(!ok) goto err; if(!ok) goto err; } } } if (!(ctx->current_crl_score & CRL_SCORE_TIME)) { ok = check_crl_time(ctx, crl, 1); if (!ok) goto err; } /* Attempt to get issuer certificate public key */ /* Attempt to get issuer certificate public key */ ikey = X509_get_pubkey(issuer); ikey = X509_get_pubkey(issuer); Loading Loading @@ -1294,23 +1443,29 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) { { int ok; int ok; /* Look for serial number of certificate in CRL X509_REVOKED *rev; * If found assume revoked: want something cleverer than /* The rules changed for this... previously if a CRL contained * this to handle entry extensions in V2 CRLs. * unhandled critical extensions it could still be used to indicate * a certificate was revoked. This has since been changed since * critical extension can change the meaning of CRL entries. */ */ if (X509_CRL_get0_by_cert(crl, NULL, x) > 0) if (crl->flags & EXFLAG_CRITICAL) { { ctx->error = X509_V_ERR_CERT_REVOKED; if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) return 1; ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; ok = ctx->verify_cb(0, ctx); ok = ctx->verify_cb(0, ctx); if(!ok) if(!ok) return 0; return 0; } } /* Look for serial number of certificate in CRL if (crl->flags & EXFLAG_CRITICAL) * If found make sure reason is not removeFromCRL. */ if (X509_CRL_get0_by_cert(crl, &rev, x)) { { if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) return 1; return 2; ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; ctx->error = X509_V_ERR_CERT_REVOKED; ok = ctx->verify_cb(0, ctx); ok = ctx->verify_cb(0, ctx); if (!ok) if (!ok) return 0; return 0; Loading Loading @@ -1898,7 +2053,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, if (store && store->get_crl) if (store && store->get_crl) ctx->get_crl = store->get_crl; ctx->get_crl = store->get_crl; else else ctx->get_crl = get_crl; ctx->get_crl = NULL; if (store && store->check_crl) if (store && store->check_crl) ctx->check_crl = store->check_crl; ctx->check_crl = store->check_crl; Loading