From f6e7d014508b020818707d4b1544379e8b742e32 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 25 Jul 2006 17:39:38 +0000 Subject: [PATCH] Support for multiple CRLs with same issuer name in X509_STORE. Modify verify logic to try to use an unexpired CRL if possible. --- CHANGES | 4 ++++ apps/ca.c | 19 ++++++++++++++++--- crypto/x509/x509.h | 1 + crypto/x509/x509_lu.c | 15 +++++++++++++-- crypto/x509/x509_vfy.c | 33 ++++++++++++++++++++++++++++++++- 5 files changed, 66 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 96f2fbdd09..2fe0ca88c6 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,10 @@ Changes between 0.9.8b and 0.9.9 [xx XXX xxxx] + *) Allow multiple CRLs to exist in an X509_STORE with matching issuer names. + Modify get_crl() to find a valid (unexpired) CRL if possible. + [Steve Henson] + *) New function X509_CRL_match() to check if two CRLs are identical. Normally this would be called X509_CRL_cmp() but that name is already used by a function that just compares CRL issuer names. Cache several CRL diff --git a/apps/ca.c b/apps/ca.c index 9fde400f69..d0fa3d772e 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -258,6 +258,7 @@ int MAIN(int argc, char **argv) int doupdatedb=0; long crldays=0; long crlhours=0; + long crlsec=0; long errorline= -1; char *configfile=NULL; char *md=NULL; @@ -456,6 +457,11 @@ EF_ALIGNMENT=0; if (--argc < 1) goto bad; crlhours= atol(*(++argv)); } + else if (strcmp(*argv,"-crlsec") == 0) + { + if (--argc < 1) goto bad; + crlsec = atol(*(++argv)); + } else if (strcmp(*argv,"-infiles") == 0) { argc--; @@ -1367,7 +1373,7 @@ bad: goto err; } - if (!crldays && !crlhours) + if (!crldays && !crlhours && !crlsec) { if (!NCONF_get_number(conf,section, ENV_DEFAULT_CRL_DAYS, &crldays)) @@ -1376,7 +1382,7 @@ bad: ENV_DEFAULT_CRL_HOURS, &crlhours)) crlhours = 0; } - if ((crldays == 0) && (crlhours == 0)) + if ((crldays == 0) && (crlhours == 0) && (crlsec == 0)) { BIO_printf(bio_err,"cannot lookup how long until the next CRL is issued\n"); goto err; @@ -1390,7 +1396,7 @@ bad: if (!tmptm) goto err; X509_gmtime_adj(tmptm,0); X509_CRL_set_lastUpdate(crl, tmptm); - X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60); + X509_gmtime_adj(tmptm,(crldays*24+crlhours)*60*60 + crlsec); X509_CRL_set_nextUpdate(crl, tmptm); ASN1_TIME_free(tmptm); @@ -1455,6 +1461,12 @@ bad: if (crlnumberfile != NULL) /* we have a CRL number that need updating */ if (!save_serial(crlnumberfile,"new",crlnumber,NULL)) goto err; + if (crlnumber) + { + BN_free(crlnumber); + crlnumber = NULL; + } + if (!X509_CRL_sign(crl,pkey,dgst)) goto err; PEM_write_bio_X509_CRL(Sout,crl); @@ -1507,6 +1519,7 @@ err: if (free_key && key) OPENSSL_free(key); BN_free(serial); + BN_free(crlnumber); free_index(db); EVP_PKEY_free(pkey); if (x509) X509_free(x509); diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h index ac5e4b60e4..31bc7539bf 100644 --- a/crypto/x509/x509.h +++ b/crypto/x509/x509.h @@ -1072,6 +1072,7 @@ int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); unsigned long X509_NAME_hash(X509_NAME *x); int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); #ifndef OPENSSL_NO_FP_API int X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag); int X509_print_fp(FILE *bp,X509 *x); diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index cd2cfb6d85..fbb1497fe2 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -459,13 +459,24 @@ X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x X509_OBJECT *obj; idx = sk_X509_OBJECT_find(h, x); if (idx == -1) return NULL; - if (x->type != X509_LU_X509) return sk_X509_OBJECT_value(h, idx); + if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) + return sk_X509_OBJECT_value(h, idx); for (i = idx; i < sk_X509_OBJECT_num(h); i++) { obj = sk_X509_OBJECT_value(h, i); if (x509_object_cmp((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) return NULL; - if ((x->type != X509_LU_X509) || !X509_cmp(obj->data.x509, x->data.x509)) + if (x->type == X509_LU_X509) + { + if (!X509_cmp(obj->data.x509, x->data.x509)) + return obj; + } + else if (x->type == X509_LU_CRL) + { + if (!X509_CRL_match(obj->data.crl, x->data.crl)) + return obj; + } + else return obj; } return NULL; diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 79dae3d3bf..e2109a4c35 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -713,7 +713,38 @@ static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) return 0; } - *pcrl = xobj.data.crl; + /* If CRL times not valid look through store */ + if (!check_crl_time(ctx, xobj.data.crl, 0)) + { + int idx, i; + X509_OBJECT *pobj; + X509_OBJECT_free_contents(&xobj); + idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, + X509_LU_CRL, nm); + if (idx == -1) + return 0; + *pcrl = NULL; + for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) + { + pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); + /* Check to see if it is a CRL and issuer matches */ + if (pobj->type != X509_LU_CRL) + break; + if (X509_NAME_cmp(nm, + X509_CRL_get_issuer(pobj->data.crl))) + break; + /* Set *pcrl because the CRL will either be valid or + * a "best fit" CRL. + */ + *pcrl = pobj->data.crl; + if (check_crl_time(ctx, *pcrl, 0)) + break; + } + if (*pcrl) + CRYPTO_add(&(*pcrl)->references, 1, CRYPTO_LOCK_X509); + } + else + *pcrl = xobj.data.crl; if (crl) X509_CRL_free(crl); return 1; -- 2.25.1