New -set_serial options to 'req' and 'x509'.
authorDr. Stephen Henson <steve@openssl.org>
Mon, 19 Feb 2001 13:38:32 +0000 (13:38 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 19 Feb 2001 13:38:32 +0000 (13:38 +0000)
Remove the old broken bio read of serial numbers in the 'ca' index
file. This would choke if a revoked certificate was specified with
a negative serial number.

Fix typo in uid.c

CHANGES
apps/ca.c
apps/req.c
apps/x509.c
crypto/uid.c

diff --git a/CHANGES b/CHANGES
index 14d0305..79e9dad 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,13 @@
 
  Changes between 0.9.6 and 0.9.7  [xx XXX 2000]
 
+  *) New option -set_serial to 'req' and 'x509' this allows the serial
+     number to use to be specified on the command line. Previously self
+     signed certificates were hard coded with serial number 0 and the 
+     CA options of 'x509' had to use a serial number in a file which was
+     auto incremented.
+     [Steve Henson]
+
   *) Avoid false positives in memory leak detection code (crypto/mem_dbg.c)
      due to incorrect handling of multi-threading:
 
index e0349a7..1fc132b 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -297,7 +297,6 @@ int MAIN(int argc, char **argv)
        const EVP_MD *dgst=NULL;
        STACK_OF(CONF_VALUE) *attribs=NULL;
        STACK_OF(X509) *cert_sk=NULL;
-       BIO *hex=NULL;
 #undef BSIZE
 #define BSIZE 256
        MS_STATIC char buf[3][BSIZE];
@@ -829,6 +828,11 @@ bad:
                        }
                p=pp[DB_serial];
                j=strlen(p);
+               if (*p == '-')
+                       {
+                       p++;
+                       j--;
+                       }
                if ((j&1) || (j < 2))
                        {
                        BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
@@ -1383,7 +1387,6 @@ bad:
                                goto err;
                                }
                        }
-               if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
 
                if (!crldays && !crlhours)
                        {
@@ -1419,12 +1422,13 @@ bad:
                                j = make_revoked(r, pp[DB_rev_date]);
                                if (!j) goto err;
                                if (j == 2) crl_v2 = 1;
-                               (void)BIO_reset(hex);
-                               if (!BIO_puts(hex,pp[DB_serial]))
+                               if (!BN_hex2bn(&serial, pp[DB_serial]))
+                                       goto err;
+                               r->serialNumber = BN_to_ASN1_INTEGER(serial, r->serialNumber);
+                               BN_free(serial);
+                               serial = NULL;
+                               if (!r->serialNumber)
                                        goto err;
-                               if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
-                                       buf[0],BSIZE)) goto err;
-
                                X509_CRL_add0_revoked(crl,r);
                                }
                        }
@@ -1539,7 +1543,6 @@ bad:
        /*****************************************************************/
        ret=0;
 err:
-       BIO_free(hex);
        BIO_free_all(Cout);
        BIO_free_all(Sout);
        BIO_free_all(out);
index b518e47..c6e88ba 100644 (file)
@@ -159,6 +159,7 @@ int MAIN(int argc, char **argv)
        char *extensions = NULL;
        char *req_exts = NULL;
        EVP_CIPHER *cipher=NULL;
+       ASN1_INTEGER *serial = NULL;
        int modulus=0;
        char *inrand=NULL;
        char *passargin = NULL, *passargout = NULL;
@@ -351,6 +352,12 @@ int MAIN(int argc, char **argv)
                        days= atoi(*(++argv));
                        if (days == 0) days=30;
                        }
+               else if (strcmp(*argv,"-set_serial") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       serial = s2i_ASN1_INTEGER(NULL, *(++argv));
+                       if (!serial) goto bad;
+                       }
                else if ((md_alg=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
                        {
                        /* ok */
@@ -404,7 +411,8 @@ bad:
                BIO_printf(bio_err," -config file   request template file.\n");
                BIO_printf(bio_err," -new           new request.\n");
                BIO_printf(bio_err," -x509          output a x509 structure instead of a cert. req.\n");
-               BIO_printf(bio_err," -days          number of days a x509 generated by -x509 is valid for.\n");
+               BIO_printf(bio_err," -days          number of days a certificate generated by -x509 is valid for.\n");
+               BIO_printf(bio_err," -set_serial    serial number to use for a certificate generated by -x509.\n");
                BIO_printf(bio_err," -newhdr        output \"NEW\" in the header lines\n");
                BIO_printf(bio_err," -asn1-kludge   Output the 'request' in a format that is wrong but some CA's\n");
                BIO_printf(bio_err,"                have been reported as requiring\n");
@@ -807,7 +815,10 @@ loop:
 
                        /* Set version to V3 */
                        if(!X509_set_version(x509ss, 2)) goto end;
-                       ASN1_INTEGER_set(X509_get_serialNumber(x509ss),0L);
+                       if (serial)
+                               X509_set_serialNumber(x509ss, serial);
+                       else
+                               ASN1_INTEGER_set(X509_get_serialNumber(x509ss),0L);
 
                        X509_set_issuer_name(x509ss,
                                X509_REQ_get_subject_name(req));
@@ -1003,6 +1014,7 @@ end:
        EVP_PKEY_free(pkey);
        X509_REQ_free(req);
        X509_free(x509ss);
+       ASN1_INTEGER_free(serial);
        if(passargin && passin) OPENSSL_free(passin);
        if(passargout && passout) OPENSSL_free(passout);
        OBJ_cleanup();
index af3843b..1ae673d 100644 (file)
@@ -124,6 +124,7 @@ static char *x509_usage[]={
 "                   missing, it is assumed to be in the CA file.\n",
 " -CAcreateserial - create serial number file if it does not exist\n",
 " -CAserial       - serial file\n",
+" -set_serial     - serial number to use\n",
 " -text           - print the certificate in text form\n",
 " -C              - print out C code forms\n",
 " -md2/-md5/-sha1/-mdc2 - digest to use\n",
@@ -141,7 +142,8 @@ static int sign (X509 *x, EVP_PKEY *pkey,int days,int clrext, const EVP_MD *dige
                                                LHASH *conf, char *section);
 static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest,
                         X509 *x,X509 *xca,EVP_PKEY *pkey,char *serial,
-                        int create,int days, int clrext, LHASH *conf, char *section);
+                        int create,int days, int clrext, LHASH *conf, char *section,
+                                               ASN1_INTEGER *sno);
 static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
 static int reqfile=0;
 
@@ -155,6 +157,7 @@ int MAIN(int argc, char **argv)
        X509 *x=NULL,*xca=NULL;
        ASN1_OBJECT *objtmp;
        EVP_PKEY *Upkey=NULL,*CApkey=NULL;
+       ASN1_INTEGER *sno = NULL;
        int i,num,badops=0;
        BIO *out=NULL;
        BIO *STDout=NULL;
@@ -301,6 +304,12 @@ int MAIN(int argc, char **argv)
                        if (--argc < 1) goto bad;
                        CAserial= *(++argv);
                        }
+               else if (strcmp(*argv,"-set_serial") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
+                               goto bad;
+                       }
                else if (strcmp(*argv,"-addtrust") == 0)
                        {
                        if (--argc < 1) goto bad;
@@ -593,7 +602,12 @@ bad:
                if ((x=X509_new()) == NULL) goto end;
                ci=x->cert_info;
 
-               if (!ASN1_INTEGER_set(X509_get_serialNumber(x),0)) goto end;
+               if (sno)
+                       {
+                       if (!X509_set_serialNumber(x, sno))
+                               goto end;
+                       }
+               else if (!ASN1_INTEGER_set(X509_get_serialNumber(x),0)) goto end;
                if (!X509_set_issuer_name(x,req->req_info->subject)) goto end;
                if (!X509_set_subject_name(x,req->req_info->subject)) goto end;
 
@@ -890,7 +904,7 @@ bad:
                                assert(need_rand);
                                if (!x509_certify(ctx,CAfile,digest,x,xca,
                                        CApkey, CAserial,CA_createserial,days, clrext,
-                                       extconf, extsect))
+                                       extconf, extsect, sno))
                                        goto end;
                                }
                        else if (x509req == i)
@@ -1005,32 +1019,21 @@ end:
        EVP_PKEY_free(Upkey);
        EVP_PKEY_free(CApkey);
        X509_REQ_free(rq);
+       ASN1_INTEGER_free(sno);
        sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
        sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
        if (passin) OPENSSL_free(passin);
        EXIT(ret);
        }
 
-static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
-            X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create,
-            int days, int clrext, LHASH *conf, char *section)
+static ASN1_INTEGER *load_serial(char *CAfile, char *serialfile, int create)
        {
-       int ret=0;
-       BIO *io=NULL;
+       char *buf = NULL, *p;
        MS_STATIC char buf2[1024];
-       char *buf=NULL,*p;
-       BIGNUM *serial=NULL;
-       ASN1_INTEGER *bs=NULL,bs2;
-       X509_STORE_CTX xsc;
-       EVP_PKEY *upkey;
-
-       upkey = X509_get_pubkey(xca);
-       EVP_PKEY_copy_parameters(upkey,pkey);
-       EVP_PKEY_free(upkey);
-
-       X509_STORE_CTX_init(&xsc,ctx,x,NULL);
-       buf=OPENSSL_malloc(EVP_PKEY_size(pkey)*2+
-               ((serialfile == NULL)
+       ASN1_INTEGER *bs = NULL, bs2;
+       BIO *io = NULL;
+       BIGNUM *serial;
+       buf=OPENSSL_malloc( ((serialfile == NULL)
                        ?(strlen(CAfile)+strlen(POSTFIX)+1)
                        :(strlen(serialfile)))+1);
        if (buf == NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; }
@@ -1109,7 +1112,34 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
        BIO_puts(io,"\n");
        BIO_free(io);
        io=NULL;
-       
+       return bs;
+
+       end:
+       BIO_free(io);
+       ASN1_INTEGER_free(bs);
+       BN_free(serial);
+       return NULL;
+
+       }
+
+static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
+            X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create,
+            int days, int clrext, LHASH *conf, char *section, ASN1_INTEGER *sno)
+       {
+       int ret=0;
+       ASN1_INTEGER *bs=NULL;
+       X509_STORE_CTX xsc;
+       EVP_PKEY *upkey;
+
+       upkey = X509_get_pubkey(xca);
+       EVP_PKEY_copy_parameters(upkey,pkey);
+       EVP_PKEY_free(upkey);
+
+       X509_STORE_CTX_init(&xsc,ctx,x,NULL);
+       if (sno) bs = sno;
+       else if (!(bs = load_serial(CAfile, serialfile, create)))
+               goto end;
+
        if (!X509_STORE_add_cert(ctx,x)) goto end;
 
        /* NOTE: this certificate can/should be self signed, unless it was
@@ -1154,10 +1184,7 @@ end:
        X509_STORE_CTX_cleanup(&xsc);
        if (!ret)
                ERR_print_errors(bio_err);
-       if (buf != NULL) OPENSSL_free(buf);
-       if (bs != NULL) ASN1_INTEGER_free(bs);
-       if (io != NULL) BIO_free(io);
-       if (serial != NULL) BN_free(serial);
+       if (!sno) ASN1_INTEGER_free(bs);
        return ret;
        }
 
index 2afed36..5612af4 100644 (file)
@@ -64,7 +64,7 @@ int OPENSSL_issetugid(void)
        return issetugid();
        }
 
-#elsif defined(WIN32)
+#elif defined(WIN32)
 
 int OPENSSL_issetugid(void)
        {