From 64674bcc8cee73853d00388a5e83cb1b2f38bec1 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 20 Apr 2004 12:05:26 +0000 Subject: [PATCH] Reduce chances of issuer and serial number duplication by use of random initial serial numbers. PR: 842 --- CHANGES | 9 +++++++++ apps/CA.pl.in | 6 ++---- apps/apps.c | 32 ++++++++++++++++++++++++++++---- apps/apps.h | 3 +++ apps/ca.c | 5 ++++- apps/req.c | 4 +++- 6 files changed, 49 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index 5dd7a41b51..d6630830fc 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,15 @@ Changes between 0.9.7c and 0.9.8 [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 now moved from CA.pl to the 'ca' utility with a new + option -create_serial. + [Steve Henson] + *) Reduced header interdepencies by declaring more opaque objects in ossl_typ.h. As a consequence, including some headers (eg. engine.h) will give fewer recursive includes, which could break lazy source code - so diff --git a/apps/CA.pl.in b/apps/CA.pl.in index 2242f7e03b..b09820755d 100644 --- a/apps/CA.pl.in +++ b/apps/CA.pl.in @@ -84,9 +84,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; } @@ -105,7 +102,8 @@ foreach (@ARGV) { print "Making CA certificate ...\n"; system ("$REQ -new -keyout " . "${CATOP}/private/$CAKEY -out ${CATOP}/$CAREQ"); - system ("$CA -out ${CATOP}/$CACERT $CADAYS -batch " . + system ("$CA -create_serial " . + "-out ${CATOP}/$CACERT $CADAYS -batch " . "-keyfile ${CATOP}/private/$CAKEY -selfsign " . "-infiles ${CATOP}/$CAREQ "); $RET=$?; diff --git a/apps/apps.c b/apps/apps.c index 5e443221d3..6925ab4cdd 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -1434,12 +1434,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 @@ -1601,6 +1598,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 7edafa4244..6072a10bd3 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -309,6 +309,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); @@ -338,4 +339,6 @@ X509_NAME *parse_name(char *str, long chtype, int multirdn); #define APP_PASS_LEN 1024 +#define SERIAL_RAND_BITS 64 + #endif diff --git a/apps/ca.c b/apps/ca.c index 2e8377391a..0fd445613d 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -241,6 +241,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; @@ -354,6 +355,8 @@ EF_ALIGNMENT=0; subj= *(++argv); /* preserve=1; */ } + else if (strcmp(*argv,"-create_serial") == 0) + create_ser = 1; else if (strcmp(*argv,"-multivalue-rdn") == 0) multirdn=1; else if (strcmp(*argv,"-startdate") == 0) @@ -1097,7 +1100,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 5df8f89fcd..16e27d1b38 100644 --- a/apps/req.c +++ b/apps/req.c @@ -919,7 +919,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; -- 2.25.1