From 75fb38c7ebf6db240ec57376a68ebadd3378d827 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Thu, 29 Apr 2004 19:10:52 +0000 Subject: [PATCH] Recent changes from 0.9.7-stable. --- CHANGES | 9 ++++++++- apps/CA.pl.in | 7 ++++--- apps/apps.c | 32 ++++++++++++++++++++++++++++---- apps/apps.h | 3 +++ apps/ca.c | 3 ++- apps/req.c | 4 +++- apps/x509.c | 24 ++++++++++++++++++++++-- 7 files changed, 70 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index d388a528c2..713876a1e9 100644 --- a/CHANGES +++ b/CHANGES @@ -4,7 +4,14 @@ Changes between 0.9.7d and 0.9.7e [XX xxx XXXX] - *) + *) Reduce the chances of duplicate issuer name and serial numbers (in + violation of RFC3280) using the OpenSSL certificate creation utilities. + This is done by creating a random 64 bit value for the initial serial + number when a serial number file is created or when a self signed + certificate is created using 'openssl req -x509'. The initial serial + number file is created using 'openssl x509 -next_serial' in CA.pl + rather than being initialized to 1. + [Steve Henson] Changes between 0.9.7c and 0.9.7d [17 Mar 2004] diff --git a/apps/CA.pl.in b/apps/CA.pl.in index 8b2ce7ea42..ae7d9c045f 100644 --- a/apps/CA.pl.in +++ b/apps/CA.pl.in @@ -82,9 +82,6 @@ foreach (@ARGV) { mkdir "${CATOP}/crl", $DIRMODE ; mkdir "${CATOP}/newcerts", $DIRMODE; mkdir "${CATOP}/private", $DIRMODE; - open OUT, ">${CATOP}/serial"; - print OUT "01\n"; - close OUT; open OUT, ">${CATOP}/index.txt"; close OUT; } @@ -106,6 +103,10 @@ foreach (@ARGV) { $RET=$?; } } + if (! -f "${CATOP}/serial" ) { + system ("$X509 -in ${CATOP}/$CACERT -noout " + . "-next_serial -out ${CATOP}/serial"); + } } elsif (/^-pkcs12$/) { my $cname = $ARGV[1]; $cname = "My Certificate" unless defined $cname; diff --git a/apps/apps.c b/apps/apps.c index 0f15e27cd0..b747e2d3cf 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -1438,12 +1438,9 @@ BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai) } else { - ASN1_INTEGER_set(ai,1); ret=BN_new(); - if (ret == NULL) + if (ret == NULL || !rand_serial(ret, ai)) BIO_printf(bio_err, "Out of memory\n"); - else - BN_one(ret); } } else @@ -1605,6 +1602,33 @@ int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix) return 0; } +int rand_serial(BIGNUM *b, ASN1_INTEGER *ai) + { + BIGNUM *btmp; + int ret = 0; + if (b) + btmp = b; + else + btmp = BN_new(); + + if (!btmp) + return 0; + + if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) + goto error; + if (ai && !BN_to_ASN1_INTEGER(btmp, ai)) + goto error; + + ret = 1; + + error: + + if (!b) + BN_free(btmp); + + return ret; + } + CA_DB *load_index(char *dbfile, DB_ATTR *db_attr) { CA_DB *retdb = NULL; diff --git a/apps/apps.h b/apps/apps.h index 0d50a94774..f3f8882b29 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -307,6 +307,7 @@ typedef struct ca_db_st BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai); int save_serial(char *serialfile, char *suffix, BIGNUM *serial, ASN1_INTEGER **retai); int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix); +int rand_serial(BIGNUM *b, ASN1_INTEGER *ai); CA_DB *load_index(char *dbfile, DB_ATTR *dbattr); int index_index(CA_DB *db); int save_index(char *dbfile, char *suffix, CA_DB *db); @@ -335,4 +336,6 @@ X509_NAME *do_subject(char *str, long chtype); #define APP_PASS_LEN 1024 +#define SERIAL_RAND_BITS 64 + #endif diff --git a/apps/ca.c b/apps/ca.c index 325320e2a0..f7cc6a12a1 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -238,6 +238,7 @@ int MAIN(int argc, char **argv) { ENGINE *e = NULL; char *key=NULL,*passargin=NULL; + int create_ser = 0; int free_key = 0; int total=0; int total_done=0; @@ -1098,7 +1099,7 @@ bad: goto err; } - if ((serial=load_serial(serialfile, 0, NULL)) == NULL) + if ((serial=load_serial(serialfile, create_ser, NULL)) == NULL) { BIO_printf(bio_err,"error while loading serial number\n"); goto err; diff --git a/apps/req.c b/apps/req.c index 1a3d1d0dfa..046bb3dc90 100644 --- a/apps/req.c +++ b/apps/req.c @@ -831,7 +831,9 @@ loop: } else { - if (!ASN1_INTEGER_set(X509_get_serialNumber(x509ss),0L)) goto end; + if (!rand_serial(NULL, + X509_get_serialNumber(x509ss))) + goto end; } if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) goto end; diff --git a/apps/x509.c b/apps/x509.c index 9b95f7bd3f..710a46fcd4 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -168,7 +168,7 @@ int MAIN(int argc, char **argv) char *CAkeyfile=NULL,*CAserial=NULL; char *alias=NULL; int text=0,serial=0,hash=0,subject=0,issuer=0,startdate=0,enddate=0; - int ocspid=0; + int next_serial=0,ocspid=0; int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0; int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0; int C=0; @@ -371,6 +371,8 @@ int MAIN(int argc, char **argv) email= ++num; else if (strcmp(*argv,"-serial") == 0) serial= ++num; + else if (strcmp(*argv,"-next_serial") == 0) + next_serial= ++num; else if (strcmp(*argv,"-modulus") == 0) modulus= ++num; else if (strcmp(*argv,"-pubkey") == 0) @@ -617,7 +619,7 @@ bad: if (xca == NULL) goto end; } - if (!noout || text) + if (!noout || text || next_serial) { OBJ_create("2.99999.3", "SET.ex3","SET x509v3 extension 3"); @@ -691,6 +693,24 @@ bad: i2a_ASN1_INTEGER(STDout,x->cert_info->serialNumber); BIO_printf(STDout,"\n"); } + else if (next_serial == i) + { + BIGNUM *bnser; + ASN1_INTEGER *ser; + ser = X509_get_serialNumber(x); + bnser = ASN1_INTEGER_to_BN(ser, NULL); + if (!bnser) + goto end; + if (!BN_add_word(bnser, 1)) + goto end; + ser = BN_to_ASN1_INTEGER(bnser, NULL); + if (!ser) + goto end; + BN_free(bnser); + i2a_ASN1_INTEGER(out, ser); + ASN1_INTEGER_free(ser); + BIO_puts(out, "\n"); + } else if (email == i) { int j;