From acba75c59dc6c42b39caab6168d1284ae0f09e8f Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 19 Feb 2001 13:38:32 +0000 Subject: [PATCH] New -set_serial options to 'req' and 'x509'. 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 | 7 +++++ apps/ca.c | 19 +++++++------ apps/req.c | 16 +++++++++-- apps/x509.c | 79 +++++++++++++++++++++++++++++++++++----------------- crypto/uid.c | 2 +- 5 files changed, 86 insertions(+), 37 deletions(-) diff --git a/CHANGES b/CHANGES index 14d0305e5d..79e9daddc9 100644 --- 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: diff --git a/apps/ca.c b/apps/ca.c index e0349a7656..1fc132b0be 100644 --- 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); diff --git a/apps/req.c b/apps/req.c index b518e47370..c6e88ba4e1 100644 --- a/apps/req.c +++ b/apps/req.c @@ -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(); diff --git a/apps/x509.c b/apps/x509.c index af3843b1f8..1ae673d469 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -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; } diff --git a/crypto/uid.c b/crypto/uid.c index 2afed36331..5612af48cf 100644 --- a/crypto/uid.c +++ b/crypto/uid.c @@ -64,7 +64,7 @@ int OPENSSL_issetugid(void) return issetugid(); } -#elsif defined(WIN32) +#elif defined(WIN32) int OPENSSL_issetugid(void) { -- 2.34.1