X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=apps%2Fca.c;h=d12530ad98919fd1845a9a4a3ca0599d7e51440b;hb=462f79ec44fb9259c48be448b231df3073c000d9;hp=1f2423977fb3b0e4235ade99d7a278ad0425c37f;hpb=d58d092bc9f0a541ce5f0b265ee819f7ab086560;p=openssl.git diff --git a/apps/ca.c b/apps/ca.c index 1f2423977f..d12530ad98 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -114,6 +114,7 @@ #define ENV_RANDFILE "RANDFILE" #define ENV_DEFAULT_DAYS "default_days" #define ENV_DEFAULT_STARTDATE "default_startdate" +#define ENV_DEFAULT_ENDDATE "default_enddate" #define ENV_DEFAULT_CRL_DAYS "default_crl_days" #define ENV_DEFAULT_CRL_HOURS "default_crl_hours" #define ENV_DEFAULT_MD "default_md" @@ -146,6 +147,8 @@ static char *ca_usage[]={ " -gencrl - Generate a new CRL\n", " -crldays days - Days is when the next CRL is due\n", " -crlhours hours - Hours is when the next CRL is due\n", +" -startdate YYMMDDHHMMSSZ - certificate validity notBefore\n", +" -enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)\n", " -days arg - number of days to certify the certificate for\n", " -md arg - md to use, one of md2, md5, sha or sha1\n", " -policy arg - The CA 'policy' to support\n", @@ -162,6 +165,8 @@ static char *ca_usage[]={ " -batch - Don't ask questions\n", " -msie_hack - msie modifications to handle all those universal strings\n", " -revoke file - Revoke a certificate (given in file)\n", +" -extensions .. - Extension section (override value in config file)\n", +" -crlexts .. - CRL extension section (override value in config file)\n", NULL }; @@ -173,7 +178,7 @@ extern int EF_ALIGNMENT; static int add_oid_section(LHASH *conf); static void lookup_fail(char *name,char *tag); -static int MS_CALLBACK key_callback(char *buf,int len,int verify); +static int MS_CALLBACK key_callback(char *buf,int len,int verify,void *u); static unsigned long index_serial_hash(char **a); static int index_serial_cmp(char **a, char **b); static unsigned long index_name_hash(char **a); @@ -182,26 +187,28 @@ static int index_name_cmp(char **a,char **b); static BIGNUM *load_serial(char *serialfile); static int save_serial(char *serialfile, BIGNUM *serial); static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, - const EVP_MD *dgst,STACK *policy,TXT_DB *db,BIGNUM *serial, - char *startdate,int days,int batch,char *ext_sect, - LHASH *conf,int verbose); + const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,TXT_DB *db, + BIGNUM *serial, char *startdate,char *enddate, int days, + int batch, char *ext_sect, LHASH *conf,int verbose); static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, - const EVP_MD *dgst,STACK *policy,TXT_DB *db, - BIGNUM *serial,char *startdate,int days,int batch, - char *ext_sect, LHASH *conf,int verbose); + const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy, + TXT_DB *db, BIGNUM *serial,char *startdate, + char *enddate, int days, int batch, char *ext_sect, + LHASH *conf,int verbose); static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, - const EVP_MD *dgst,STACK *policy,TXT_DB *db, - BIGNUM *serial,char *startdate,int days, - char *ext_sect,LHASH *conf,int verbose); + const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy, + TXT_DB *db, BIGNUM *serial,char *startdate, + char *enddate, int days, char *ext_sect,LHASH *conf, + int verbose); static int fix_data(int nid, int *type); static void write_new_certificate(BIO *bp, X509 *x, int output_der); static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, - STACK *policy, TXT_DB *db, BIGNUM *serial, char *startdate, - int days, int batch, int verbose, X509_REQ *req, char *ext_sect, - LHASH *conf); + STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, + char *startdate, char *enddate, int days, int batch, int verbose, + X509_REQ *req, char *ext_sect, LHASH *conf); static int do_revoke(X509 *x509, TXT_DB *db); static int check_time_format(char *str); -static LHASH *conf; +static LHASH *conf=NULL; static char *key=NULL; static char *section=NULL; @@ -238,6 +245,7 @@ int MAIN(int argc, char **argv) char *crl_ext=NULL; BIGNUM *serial=NULL; char *startdate=NULL; + char *enddate=NULL; int days=0; int batch=0; X509 *x509=NULL; @@ -252,7 +260,7 @@ int MAIN(int argc, char **argv) int i,j; long l; const EVP_MD *dgst=NULL; - STACK *attribs=NULL; + STACK_OF(CONF_VALUE) *attribs=NULL; STACK *cert_sk=NULL; BIO *hex=NULL; #undef BSIZE @@ -267,9 +275,14 @@ EF_ALIGNMENT=0; apps_startup(); + conf = NULL; + key = NULL; + section = NULL; + X509V3_add_standard_extensions(); preserve=0; + msie_hack=0; if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); @@ -295,6 +308,11 @@ EF_ALIGNMENT=0; if (--argc < 1) goto bad; startdate= *(++argv); } + else if (strcmp(*argv,"-enddate") == 0) + { + if (--argc < 1) goto bad; + enddate= *(++argv); + } else if (strcmp(*argv,"-days") == 0) { if (--argc < 1) goto bad; @@ -384,6 +402,16 @@ EF_ALIGNMENT=0; infile= *(++argv); dorevoke=1; } + else if (strcmp(*argv,"-extensions") == 0) + { + if (--argc < 1) goto bad; + extensions= *(++argv); + } + else if (strcmp(*argv,"-crlexts") == 0) + { + if (--argc < 1) goto bad; + crl_ext= *(++argv); + } else { bad: @@ -499,10 +527,10 @@ bad: goto err; } if (key == NULL) - pkey=PEM_read_bio_PrivateKey(in,NULL,NULL); + pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,NULL); else { - pkey=PEM_read_bio_PrivateKey(in,NULL,key_callback); + pkey=PEM_read_bio_PrivateKey(in,NULL,key_callback,NULL); memset(key,0,strlen(key)); } if (pkey == NULL) @@ -525,7 +553,7 @@ bad: BIO_printf(bio_err,"trying to load CA certificate\n"); goto err; } - x509=PEM_read_bio_X509(in,NULL,NULL); + x509=PEM_read_bio_X509(in,NULL,NULL,NULL); if (x509 == NULL) { BIO_printf(bio_err,"unable to load CA certificate\n"); @@ -711,8 +739,8 @@ bad: lookup_fail(section,ENV_SERIAL); goto err; } - - extensions=CONF_get_string(conf,section,ENV_EXTENSIONS); + if(!extensions) + extensions=CONF_get_string(conf,section,ENV_EXTENSIONS); if(extensions) { /* Check syntax of file */ X509V3_CTX ctx; @@ -729,18 +757,25 @@ bad: if (startdate == NULL) { - startdate=(char *)CONF_get_string(conf,section, + startdate=CONF_get_string(conf,section, ENV_DEFAULT_STARTDATE); - if (startdate == NULL) - startdate="today"; - else - { - if (!ASN1_UTCTIME_set_string(NULL,startdate)) - { - BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSS\n"); - goto err; - } - } + } + if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate)) + { + BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n"); + goto err; + } + if (startdate == NULL) startdate="today"; + + if (enddate == NULL) + { + enddate=CONF_get_string(conf,section, + ENV_DEFAULT_ENDDATE); + } + if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate)) + { + BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n"); + goto err; } if (days == 0) @@ -748,7 +783,7 @@ bad: days=(int)CONF_get_number(conf,section, ENV_DEFAULT_DAYS); } - if (days == 0) + if (!enddate && (days == 0)) { BIO_printf(bio_err,"cannot lookup how many days to certify for\n"); goto err; @@ -781,7 +816,8 @@ bad: { total++; j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db, - serial,startdate,days,extensions,conf,verbose); + serial,startdate,enddate, days,extensions,conf, + verbose); if (j < 0) goto err; if (j > 0) { @@ -804,7 +840,7 @@ bad: { total++; j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs, - db,serial,startdate,days,batch, + db,serial,startdate,enddate,days,batch, extensions,conf,verbose); if (j < 0) goto err; if (j > 0) @@ -823,7 +859,7 @@ bad: { total++; j=certify(&x,infile,pkey,x509,dgst,attribs,db, - serial,startdate,days,batch, + serial,startdate,enddate,days,batch, extensions,conf,verbose); if (j < 0) goto err; if (j > 0) @@ -842,7 +878,7 @@ bad: { total++; j=certify(&x,argv[i],pkey,x509,dgst,attribs,db, - serial,startdate,days,batch, + serial,startdate,enddate,days,batch, extensions,conf,verbose); if (j < 0) goto err; if (j > 0) @@ -1014,7 +1050,7 @@ bad: /*****************************************************************/ if (gencrl) { - crl_ext=CONF_get_string(conf,section,ENV_CRLEXT); + if(!crl_ext) crl_ext=CONF_get_string(conf,section,ENV_CRLEXT); if(crl_ext) { /* Check syntax of file */ X509V3_CTX ctx; @@ -1146,7 +1182,7 @@ bad: BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile); goto err; } - x509=PEM_read_bio_X509(in,NULL,NULL); + x509=PEM_read_bio_X509(in,NULL,NULL,NULL); if (x509 == NULL) { BIO_printf(bio_err,"unable to load '%s' certificate\n",infile); @@ -1214,7 +1250,7 @@ static void lookup_fail(char *name, char *tag) BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag); } -static int MS_CALLBACK key_callback(char *buf, int len, int verify) +static int MS_CALLBACK key_callback(char *buf, int len, int verify, void *u) { int i; @@ -1324,9 +1360,9 @@ err: } static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, - const EVP_MD *dgst, STACK *policy, TXT_DB *db, BIGNUM *serial, - char *startdate, int days, int batch, char *ext_sect, LHASH *lconf, - int verbose) + const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, + BIGNUM *serial, char *startdate, char *enddate, int days, + int batch, char *ext_sect, LHASH *lconf, int verbose) { X509_REQ *req=NULL; BIO *in=NULL; @@ -1340,7 +1376,7 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, perror(infile); goto err; } - if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL)) == NULL) + if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL) { BIO_printf(bio_err,"Error reading certificate request in %s\n", infile); @@ -1373,7 +1409,7 @@ static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, else BIO_printf(bio_err,"Signature ok\n"); - ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, enddate, days,batch,verbose,req,ext_sect,lconf); err: @@ -1383,10 +1419,9 @@ err: } static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, - const EVP_MD *dgst, STACK *policy, TXT_DB *db, BIGNUM *serial, - char *startdate, int days, int batch, char *ext_sect, LHASH *lconf, - int verbose) - + const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, + BIGNUM *serial, char *startdate, char *enddate, int days, + int batch, char *ext_sect, LHASH *lconf, int verbose) { X509 *req=NULL; X509_REQ *rreq=NULL; @@ -1401,7 +1436,7 @@ static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, perror(infile); goto err; } - if ((req=PEM_read_bio_X509(in,NULL,NULL)) == NULL) + if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) { BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile); goto err; @@ -1436,7 +1471,7 @@ static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL) goto err; - ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,days, + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate,days, batch,verbose,rreq,ext_sect,lconf); err: @@ -1447,8 +1482,9 @@ err: } static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, - STACK *policy, TXT_DB *db, BIGNUM *serial, char *startdate, int days, - int batch, int verbose, X509_REQ *req, char *ext_sect, LHASH *lconf) + STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, + char *startdate, char *enddate, int days, int batch, int verbose, + X509_REQ *req, char *ext_sect, LHASH *lconf) { X509_NAME *name=NULL,*CAname=NULL,*subject=NULL; ASN1_UTCTIME *tm,*tmptm; @@ -1562,9 +1598,9 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, if (CAname == NULL) goto err; str=str2=NULL; - for (i=0; iname)) == NID_undef) { BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name); @@ -1744,17 +1780,16 @@ again2: BIO_printf(bio_err,"Certificate is to be certified until "); if (strcmp(startdate,"today") == 0) - { X509_gmtime_adj(X509_get_notBefore(ret),0); + else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate); + + if (enddate == NULL) X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days); - } - else - { - /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ - ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate); - } + else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate); + ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret)); - BIO_printf(bio_err," (%d days)\n",days); + if(days) BIO_printf(bio_err," (%d days)",days); + BIO_printf(bio_err, "\n"); if (!X509_set_subject_name(ret,subject)) goto err; @@ -1904,15 +1939,15 @@ static void write_new_certificate(BIO *bp, X509 *x, int output_der) } static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, - const EVP_MD *dgst, STACK *policy, TXT_DB *db, BIGNUM *serial, - char *startdate, int days, char *ext_sect, LHASH *lconf, int verbose) + const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, + BIGNUM *serial, char *startdate, char *enddate, int days, + char *ext_sect, LHASH *lconf, int verbose) { - STACK *sk=NULL; + STACK_OF(CONF_VALUE) *sk=NULL; LHASH *parms=NULL; X509_REQ *req=NULL; CONF_VALUE *cv=NULL; NETSCAPE_SPKI *spki = NULL; - unsigned char *spki_der = NULL,*p; X509_REQ_INFO *ri; char *type,*buf; EVP_PKEY *pktmp=NULL; @@ -1936,7 +1971,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, } sk=CONF_get_section(parms, "default"); - if (sk_num(sk) == 0) + if (sk_CONF_VALUE_num(sk) == 0) { BIO_printf(bio_err, "no name/value pairs found in %s\n", infile); CONF_free(parms); @@ -1965,35 +2000,26 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, for (i = 0; ; i++) { - if ((int)sk_num(sk) <= i) break; + if (sk_CONF_VALUE_num(sk) <= i) break; - cv=(CONF_VALUE *)sk_value(sk,i); + cv=sk_CONF_VALUE_value(sk,i); type=cv->name; - buf=cv->value; + /* Skip past any leading X. X: X, etc to allow for + * multiple instances + */ + for(buf = cv->name; *buf ; buf++) + if ((*buf == ':') || (*buf == ',') || (*buf == '.')) { + buf++; + if(*buf) type = buf; + break; + } + buf=cv->value; if ((nid=OBJ_txt2nid(type)) == NID_undef) { if (strcmp(type, "SPKAC") == 0) { - spki_der=(unsigned char *)Malloc( - strlen(cv->value)+1); - if (spki_der == NULL) - { - BIO_printf(bio_err,"Malloc failure\n"); - goto err; - } - j = EVP_DecodeBlock(spki_der, (unsigned char *)cv->value, - strlen(cv->value)); - if (j <= 0) - { - BIO_printf(bio_err, "Can't b64 decode SPKAC structure\n"); - goto err; - } - - p=spki_der; - spki = d2i_NETSCAPE_SPKI(&spki, &p, j); - Free(spki_der); - spki_der = NULL; + spki = NETSCAPE_SPKI_b64_decode(cv->value, -1); if (spki == NULL) { BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n"); @@ -2033,7 +2059,7 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n"); - if ((pktmp=X509_PUBKEY_get(spki->spkac->pubkey)) == NULL) + if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL) { BIO_printf(bio_err,"error unpacking SPKAC public key\n"); goto err; @@ -2049,12 +2075,11 @@ static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, X509_REQ_set_pubkey(req,pktmp); EVP_PKEY_free(pktmp); - ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate, + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate, days,1,verbose,req,ext_sect,lconf); err: if (req != NULL) X509_REQ_free(req); if (parms != NULL) CONF_free(parms); - if (spki_der != NULL) Free(spki_der); if (spki != NULL) NETSCAPE_SPKI_free(spki); if (ne != NULL) X509_NAME_ENTRY_free(ne); @@ -2089,7 +2114,7 @@ static int check_time_format(char *str) static int add_oid_section(LHASH *hconf) { char *p; - STACK *sktmp; + STACK_OF(CONF_VALUE) *sktmp; CONF_VALUE *cnf; int i; if(!(p=CONF_get_string(hconf,NULL,"oid_section"))) return 1; @@ -2097,8 +2122,8 @@ static int add_oid_section(LHASH *hconf) BIO_printf(bio_err, "problem loading oid section %s\n", p); return 0; } - for(i = 0; i < sk_num(sktmp); i++) { - cnf = (CONF_VALUE *)sk_value(sktmp, i); + for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { + cnf = sk_CONF_VALUE_value(sktmp, i); if(OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) { BIO_printf(bio_err, "problem creating object %s=%s\n", cnf->name, cnf->value);