Add CRL utility functions to allow CRLs to be
authorDr. Stephen Henson <steve@openssl.org>
Fri, 17 Aug 2001 00:33:43 +0000 (00:33 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 17 Aug 2001 00:33:43 +0000 (00:33 +0000)
built up without accessing structures directly.

Update ca.c to use new functions.

Fix ca.c so it now build CRLs correctly again.

CHANGES
apps/ca.c
crypto/x509/Makefile.ssl
crypto/x509/x509.h
crypto/x509/x509cset.c [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index a9e7d15..ab1037e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
          *) applies to 0.9.6a/0.9.6b/0.9.6c and 0.9.7
          +) applies to 0.9.7 only
 
+  +) New CRL functions: X509_CRL_set_version(), X509_CRL_set_issuer_name()
+     X509_CRL_set_lastUpdate(), X509_CRL_set_nextUpdate(), X509_CRL_sort(),
+     X509_REVOKED_set_serialNumber(), and X509_REVOKED_set_revocationDate().
+     These allow a CRL to be built without having to access X509_CRL fields
+     directly. Modify 'ca' application to use new functions.
+     [Steve Henson]
+
   *) Fix buggy behaviour of BIO_get_num_renegotiates() and BIO_ctrl()
      for BIO_C_GET_WRITE_BUF_SIZE ("Stephen Hinton" <shinton@netopia.com>).
      [Lutz Jaenicke]
index 7bee4b6..1e34e50 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -312,8 +312,9 @@ int MAIN(int argc, char **argv)
        char *dbfile=NULL;
        TXT_DB *db=NULL;
        X509_CRL *crl=NULL;
-       X509_CRL_INFO *ci=NULL;
        X509_REVOKED *r=NULL;
+       ASN1_TIME *tmptm;
+       ASN1_INTEGER *tmpser;
        char **pp,*p,*f;
        int i,j;
        long l;
@@ -1431,15 +1432,16 @@ bad:
 
                if (verbose) BIO_printf(bio_err,"making CRL\n");
                if ((crl=X509_CRL_new()) == NULL) goto err;
-               ci=crl->crl;
-               X509_NAME_free(ci->issuer);
-               ci->issuer=X509_NAME_dup(x509->cert_info->subject);
-               if (ci->issuer == NULL) goto err;
+               if (!X509_CRL_set_issuer_name(crl, X509_get_issuer_name(x509))) goto err;
 
-               X509_gmtime_adj(ci->lastUpdate,0);
-               if (ci->nextUpdate == NULL)
-                       ci->nextUpdate=ASN1_UTCTIME_new();
-               X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
+               tmptm = ASN1_TIME_new();
+               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_CRL_set_nextUpdate(crl, tmptm);    
+
+               ASN1_TIME_free(tmptm);
 
                for (i=0; i<sk_num(db->data); i++)
                        {
@@ -1452,22 +1454,20 @@ bad:
                                if (j == 2) crl_v2 = 1;
                                if (!BN_hex2bn(&serial, pp[DB_serial]))
                                        goto err;
-                               r->serialNumber = BN_to_ASN1_INTEGER(serial, r->serialNumber);
+                               tmpser = BN_to_ASN1_INTEGER(serial, NULL);
                                BN_free(serial);
                                serial = NULL;
-                               if (!r->serialNumber)
+                               if (!tmpser)
                                        goto err;
+                               X509_REVOKED_set_serialNumber(r, tmpser);
+                               ASN1_INTEGER_free(tmpser);
                                X509_CRL_add0_revoked(crl,r);
                                }
                        }
+
                /* sort the data so it will be written in serial
                 * number order */
-               sk_X509_REVOKED_sort(ci->revoked);
-               for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
-                       {
-                       r=sk_X509_REVOKED_value(ci->revoked,i);
-                       r->sequence=i;
-                       }
+               X509_CRL_sort(crl);
 
                /* we now have a CRL */
                if (verbose) BIO_printf(bio_err,"signing CRL\n");
@@ -1494,8 +1494,6 @@ bad:
                if (crl_ext)
                        {
                        X509V3_CTX crlctx;
-                       if (ci->version == NULL)
-                               if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
                        X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
                        X509V3_set_nconf(&crlctx, conf);
 
@@ -1504,9 +1502,8 @@ bad:
                        }
                if (crl_ext || crl_v2)
                        {
-                       if (ci->version == NULL)
-                               if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err;
-                       ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */
+                       if (!X509_CRL_set_version(crl, 1))
+                               goto err; /* version 2 CRL */
                        }
 
                if (!X509_CRL_sign(crl,pkey,dgst)) goto err;
@@ -2887,12 +2884,16 @@ int make_revoked(X509_REVOKED *rev, char *str)
        ASN1_GENERALIZEDTIME *comp_time = NULL;
        ASN1_ENUMERATED *rtmp = NULL;
 
+       ASN1_TIME *revDate = NULL;
 
-       i = unpack_revinfo(&rev->revocationDate, &reason_code, &hold, &comp_time, str);
+       i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
 
        if (i == 0)
                goto err;
 
+       if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
+               goto err;
+
        if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS))
                {
                rtmp = ASN1_ENUMERATED_new();
@@ -2923,6 +2924,7 @@ int make_revoked(X509_REVOKED *rev, char *str)
        ASN1_OBJECT_free(hold);
        ASN1_GENERALIZEDTIME_free(comp_time);
        ASN1_ENUMERATED_free(rtmp);
+       ASN1_TIME_free(revDate);
 
        return ret;
        }
@@ -3121,6 +3123,8 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_G
        if (pinvtm) *pinvtm = comp_time;
        else ASN1_GENERALIZEDTIME_free(comp_time);
 
+       ret = 1;
+
        err:
 
        if (tmp) OPENSSL_free(tmp);
index ab3fc29..b818371 100644 (file)
@@ -25,13 +25,13 @@ APPS=
 LIB=$(TOP)/libcrypto.a
 LIBSRC=        x509_def.c x509_d2.c x509_r2x.c x509_cmp.c \
        x509_obj.c x509_req.c x509spki.c x509_vfy.c \
-       x509_set.c x509rset.c x509_err.c \
+       x509_set.c x509cset.c x509rset.c x509_err.c \
        x509name.c x509_v3.c x509_ext.c x509_att.c \
        x509type.c x509_lu.c x_all.c x509_txt.c \
        x509_trs.c by_file.c by_dir.c 
 LIBOBJ= x509_def.o x509_d2.o x509_r2x.o x509_cmp.o \
        x509_obj.o x509_req.o x509spki.o x509_vfy.o \
-       x509_set.o x509rset.o x509_err.o \
+       x509_set.o x509cset.o x509rset.o x509_err.o \
        x509name.o x509_v3.o x509_ext.o x509_att.o \
        x509type.o x509_lu.o x_all.o x509_txt.o \
        x509_trs.o by_file.o by_dir.o
index 2663224..2d0ecf2 100644 (file)
@@ -975,6 +975,15 @@ int X509_REQ_add1_attr_by_txt(X509_REQ *req,
                        const char *attrname, int type,
                        const unsigned char *bytes, int len);
 
+int X509_CRL_set_version(X509_CRL *x, long version);
+int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
+int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm);
+int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm);
+int X509_CRL_sort(X509_CRL *crl);
+
+int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
+int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
+
 int            X509_check_private_key(X509 *x509,EVP_PKEY *pkey);
 
 int            X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
diff --git a/crypto/x509/x509cset.c b/crypto/x509/x509cset.c
new file mode 100644 (file)
index 0000000..6cac440
--- /dev/null
@@ -0,0 +1,169 @@
+/* crypto/x509/x509cset.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+int X509_CRL_set_version(X509_CRL *x, long version)
+       {
+       if (x == NULL) return(0);
+       if (x->crl->version == NULL)
+               {
+               if ((x->crl->version=M_ASN1_INTEGER_new()) == NULL)
+                       return(0);
+               }
+       return(ASN1_INTEGER_set(x->crl->version,version));
+       }
+
+int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name)
+       {
+       if ((x == NULL) || (x->crl == NULL)) return(0);
+       return(X509_NAME_set(&x->crl->issuer,name));
+       }
+
+
+int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm)
+       {
+       ASN1_TIME *in;
+
+       if (x == NULL) return(0);
+       in=x->crl->lastUpdate;
+       if (in != tm)
+               {
+               in=M_ASN1_TIME_dup(tm);
+               if (in != NULL)
+                       {
+                       M_ASN1_TIME_free(x->crl->lastUpdate);
+                       x->crl->lastUpdate=in;
+                       }
+               }
+       return(in != NULL);
+       }
+
+int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm)
+       {
+       ASN1_TIME *in;
+
+       if (x == NULL) return(0);
+       in=x->crl->nextUpdate;
+       if (in != tm)
+               {
+               in=M_ASN1_TIME_dup(tm);
+               if (in != NULL)
+                       {
+                       M_ASN1_TIME_free(x->crl->nextUpdate);
+                       x->crl->nextUpdate=in;
+                       }
+               }
+       return(in != NULL);
+       }
+
+int X509_CRL_sort(X509_CRL *c)
+       {
+       int i;
+       X509_REVOKED *r;
+       /* sort the data so it will be written in serial
+        * number order */
+       sk_X509_REVOKED_sort(c->crl->revoked);
+       for (i=0; i<sk_X509_REVOKED_num(c->crl->revoked); i++)
+               {
+               r=sk_X509_REVOKED_value(c->crl->revoked,i);
+               r->sequence=i;
+               }
+       return 1;
+       }
+
+int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm)
+       {
+       ASN1_TIME *in;
+
+       if (x == NULL) return(0);
+       in=x->revocationDate;
+       if (in != tm)
+               {
+               in=M_ASN1_TIME_dup(tm);
+               if (in != NULL)
+                       {
+                       M_ASN1_TIME_free(x->revocationDate);
+                       x->revocationDate=in;
+                       }
+               }
+       return(in != NULL);
+       }
+
+int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial)
+       {
+       ASN1_INTEGER *in;
+
+       if (x == NULL) return(0);
+       in=x->serialNumber;
+       if (in != serial)
+               {
+               in=M_ASN1_INTEGER_dup(serial);
+               if (in != NULL)
+                       {
+                       M_ASN1_INTEGER_free(x->serialNumber);
+                       x->serialNumber=in;
+                       }
+               }
+       return(in != NULL);
+       }