提交 d43c4497 编写于 作者: D Dr. Stephen Henson

Initial support for delta CRLs. If "use deltas" flag is set attempt to find

a delta CRL in addition to a full CRL. Check and search delta in addition to
the base.
上级 4b96839f
...@@ -4,6 +4,12 @@ ...@@ -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
......
...@@ -2241,6 +2241,8 @@ int args_verify(char ***pargs, int *pargc, ...@@ -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
......
...@@ -137,6 +137,7 @@ static int crl_set_issuers(X509_CRL *crl) ...@@ -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,
...@@ -161,6 +162,22 @@ static int crl_set_issuers(X509_CRL *crl) ...@@ -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;
...@@ -207,6 +224,8 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ...@@ -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:
...@@ -221,6 +240,15 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ...@@ -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.
...@@ -233,13 +261,17 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ...@@ -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;
} }
...@@ -266,6 +298,8 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ...@@ -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;
} }
...@@ -435,6 +469,8 @@ static int def_crl_lookup(X509_CRL *crl, ...@@ -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;
} }
} }
......
...@@ -436,6 +436,8 @@ struct x509_revoked_st ...@@ -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 */
}; };
...@@ -468,6 +470,9 @@ struct X509_crl_st ...@@ -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
......
...@@ -70,6 +70,44 @@ ...@@ -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);
...@@ -83,6 +121,10 @@ static int check_policy(X509_STORE_CTX *ctx); ...@@ -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,
...@@ -649,7 +691,7 @@ static int check_revocation(X509_STORE_CTX *ctx) ...@@ -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;
...@@ -660,7 +702,10 @@ static int check_cert(X509_STORE_CTX *ctx) ...@@ -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 */
ok = ctx->get_crl(ctx, &crl, x); if (ctx->get_crl)
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
*/ */
...@@ -674,14 +719,36 @@ static int check_cert(X509_STORE_CTX *ctx) ...@@ -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;
ok = ctx->cert_crl(ctx, crl, x);
if (!ok) if (dcrl)
goto err; {
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);
if (!ok)
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;
...@@ -731,8 +798,8 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) ...@@ -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;
...@@ -748,46 +815,8 @@ static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) ...@@ -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;
...@@ -818,16 +847,121 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 **pissuer, ...@@ -818,16 +847,121 @@ 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;
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.
...@@ -860,6 +994,9 @@ static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, ...@@ -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)))
{ {
...@@ -1146,22 +1283,24 @@ static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, ...@@ -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;
...@@ -1173,7 +1312,7 @@ static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) ...@@ -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);
...@@ -1186,6 +1325,7 @@ static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) ...@@ -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;
} }
...@@ -1203,6 +1343,7 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) ...@@ -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.
*/ */
...@@ -1222,44 +1363,52 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) ...@@ -1222,44 +1363,52 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
if(issuer) if(issuer)
{ {
/* Check for cRLSign bit if keyUsage present */ /* Skip most tests for deltas because they have already
if ((issuer->ex_flags & EXFLAG_KUSAGE) && * been done
!(issuer->ex_kusage & KU_CRL_SIGN)) */
if (!crl->base_crl_number)
{ {
ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; /* Check for cRLSign bit if keyUsage present */
ok = ctx->verify_cb(0, ctx); if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
if(!ok) goto err; !(issuer->ex_kusage & KU_CRL_SIGN))
} {
ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
ok = ctx->verify_cb(0, ctx);
if(!ok) goto err;
}
if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) if (!(ctx->current_crl_score & CRL_SCORE_SCOPE))
{ {
ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
ok = ctx->verify_cb(0, ctx); ok = ctx->verify_cb(0, ctx);
if(!ok) goto err; if(!ok) goto err;
} }
if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH))
{
if (!check_crl_path(ctx, ctx->current_issuer))
{
ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
ok = ctx->verify_cb(0, ctx);
if(!ok) goto err;
}
}
if (crl->idp_flags & IDP_INVALID)
{
ctx->error = X509_V_ERR_INVALID_EXTENSION;
ok = ctx->verify_cb(0, ctx);
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 (!check_crl_path(ctx, ctx->current_issuer))
{
ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
ok = ctx->verify_cb(0, ctx);
if(!ok) goto err;
} }
}
if (crl->idp_flags & IDP_INVALID) if (!(ctx->current_crl_score & CRL_SCORE_TIME))
{ {
ctx->error = X509_V_ERR_INVALID_EXTENSION; ok = check_crl_time(ctx, crl, 1);
ok = ctx->verify_cb(0, ctx); if (!ok)
if(!ok) goto err; goto err;
} }
/* Attempt to get issuer certificate public key */ /* Attempt to get issuer certificate public key */
...@@ -1294,18 +1443,12 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) ...@@ -1294,18 +1443,12 @@ 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)
{
ctx->error = X509_V_ERR_CERT_REVOKED;
ok = ctx->verify_cb(0, ctx);
if (!ok)
return 0;
}
if (crl->flags & EXFLAG_CRITICAL) if (crl->flags & EXFLAG_CRITICAL)
{ {
if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
...@@ -1315,6 +1458,18 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) ...@@ -1315,6 +1458,18 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
if(!ok) if(!ok)
return 0; return 0;
} }
/* Look for serial number of certificate in CRL
* If found make sure reason is not removeFromCRL.
*/
if (X509_CRL_get0_by_cert(crl, &rev, x))
{
if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
return 2;
ctx->error = X509_V_ERR_CERT_REVOKED;
ok = ctx->verify_cb(0, ctx);
if (!ok)
return 0;
}
return 1; return 1;
} }
...@@ -1898,7 +2053,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, ...@@ -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;
......
...@@ -385,6 +385,8 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); ...@@ -385,6 +385,8 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
#define X509_V_FLAG_NOTIFY_POLICY 0x800 #define X509_V_FLAG_NOTIFY_POLICY 0x800
/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ /* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
#define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 #define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000
/* Delta CRL support */
#define X509_V_FLAG_USE_DELTAS 0x2000
#define X509_VP_FLAG_DEFAULT 0x1 #define X509_VP_FLAG_DEFAULT 0x1
#define X509_VP_FLAG_OVERWRITE 0x2 #define X509_VP_FLAG_OVERWRITE 0x2
......
...@@ -61,14 +61,17 @@ ...@@ -61,14 +61,17 @@
#include <openssl/x509v3.h> #include <openssl/x509v3.h>
static ENUMERATED_NAMES crl_reasons[] = { static ENUMERATED_NAMES crl_reasons[] = {
{0, "Unspecified", "unspecified"}, {CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"},
{1, "Key Compromise", "keyCompromise"}, {CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"},
{2, "CA Compromise", "CACompromise"}, {CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"},
{3, "Affiliation Changed", "affiliationChanged"}, {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", "affiliationChanged"},
{4, "Superseded", "superseded"}, {CRL_REASON_SUPERSEDED, "Superseded", "superseded"},
{5, "Cessation Of Operation", "cessationOfOperation"}, {CRL_REASON_CESSATION_OF_OPERATION,
{6, "Certificate Hold", "certificateHold"}, "Cessation Of Operation", "cessationOfOperation"},
{8, "Remove From CRL", "removeFromCRL"}, {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"},
{CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"},
{CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", "privilegeWithdrawn"},
{CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"},
{-1, NULL, NULL} {-1, NULL, NULL}
}; };
......
...@@ -465,8 +465,7 @@ static void x509v3_cache_extensions(X509 *x) ...@@ -465,8 +465,7 @@ static void x509v3_cache_extensions(X509 *x)
if (!x->nc && (i != -1)) if (!x->nc && (i != -1))
x->ex_flags |= EXFLAG_INVALID; x->ex_flags |= EXFLAG_INVALID;
setup_crldp(x); setup_crldp(x);
#ifndef OPENSSL_NO_RFC3779 #ifndef OPENSSL_NO_RFC3779
x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL); x->rfc3779_addr =X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, x->rfc3779_asid =X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
...@@ -477,6 +476,9 @@ static void x509v3_cache_extensions(X509 *x) ...@@ -477,6 +476,9 @@ static void x509v3_cache_extensions(X509 *x)
ex = X509_get_ext(x, i); ex = X509_get_ext(x, i);
if (!X509_EXTENSION_get_critical(ex)) if (!X509_EXTENSION_get_critical(ex))
continue; continue;
if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
== NID_freshest_crl)
x->ex_flags |= EXFLAG_FRESHEST;
if (!X509_supported_extension(ex)) if (!X509_supported_extension(ex))
{ {
x->ex_flags |= EXFLAG_CRITICAL; x->ex_flags |= EXFLAG_CRITICAL;
......
...@@ -226,6 +226,18 @@ X509_NAME *dpname; ...@@ -226,6 +226,18 @@ X509_NAME *dpname;
/* All existing reasons */ /* All existing reasons */
#define CRLDP_ALL_REASONS 0x807f #define CRLDP_ALL_REASONS 0x807f
#define CRL_REASON_NONE -1
#define CRL_REASON_UNSPECIFIED 0
#define CRL_REASON_KEY_COMPROMISE 1
#define CRL_REASON_CA_COMPROMISE 2
#define CRL_REASON_AFFILIATION_CHANGED 3
#define CRL_REASON_SUPERSEDED 4
#define CRL_REASON_CESSATION_OF_OPERATION 5
#define CRL_REASON_CERTIFICATE_HOLD 6
#define CRL_REASON_REMOVE_FROM_CRL 8
#define CRL_REASON_PRIVILEGE_WITHDRAWN 9
#define CRL_REASON_AA_COMPROMISE 10
struct DIST_POINT_st { struct DIST_POINT_st {
DIST_POINT_NAME *distpoint; DIST_POINT_NAME *distpoint;
ASN1_BIT_STRING *reasons; ASN1_BIT_STRING *reasons;
...@@ -402,7 +414,8 @@ struct ISSUING_DIST_POINT_st ...@@ -402,7 +414,8 @@ struct ISSUING_DIST_POINT_st
#define EXFLAG_CRITICAL 0x200 #define EXFLAG_CRITICAL 0x200
#define EXFLAG_PROXY 0x400 #define EXFLAG_PROXY 0x400
#define EXFLAG_INVALID_POLICY 0x400 #define EXFLAG_INVALID_POLICY 0x800
#define EXFLAG_FRESHEST 0x1000
#define KU_DIGITAL_SIGNATURE 0x0080 #define KU_DIGITAL_SIGNATURE 0x0080
#define KU_NON_REPUDIATION 0x0040 #define KU_NON_REPUDIATION 0x0040
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册