Support for multiple CRLs with same issuer name in X509_STORE. Modify
authorDr. Stephen Henson <steve@openssl.org>
Tue, 25 Jul 2006 17:39:38 +0000 (17:39 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 25 Jul 2006 17:39:38 +0000 (17:39 +0000)
verify logic to try to use an unexpired CRL if possible.

CHANGES
apps/ca.c
crypto/x509/x509.h
crypto/x509/x509_lu.c
crypto/x509/x509_vfy.c

diff --git a/CHANGES b/CHANGES
index 96f2fbdd09091277fa2a3fb23ce30072f45ae532..2fe0ca88c6dce1d6e4ee7aa791589761dbe4b059 100644 (file)
--- 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 
index 9fde400f69aca561c5ae9226da6da3a9783a89ce..d0fa3d772ef6940efe31b3ea17e4ac5bd890e155 100644 (file)
--- 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);
index ac5e4b60e465a11a3d0ffdd1d47810e63a3df526..31bc7539bffc5da16da04b91aa50cca28c32e1b1 100644 (file)
@@ -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);
index cd2cfb6d855aedd3cbf5a404bb7e49fe71b0bb88..fbb1497fe211efb718bcea3cca3cca1e6462c45b 100644 (file)
@@ -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;
index 79dae3d3bf23702b009864bf9d37f03a95eba9e5..e2109a4c3506d64ed0effb3e98ebff9945afe495 100644 (file)
@@ -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;