X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=apps%2Fca.c;h=16afb8d7ee7e1733d0bdf1d5adf5ac443e8ac83f;hp=ce4181e889a266f0da5cd1d80b2f4390987f344c;hb=ec577822f95a8bca0023c5c77cef1a4916822d4a;hpb=15799403ada7bea696c9882cf0006a4a40ff5baf diff --git a/apps/ca.c b/apps/ca.c index ce4181e889..16afb8d7ee 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -64,16 +64,16 @@ #include #include #include "apps.h" -#include "bio.h" -#include "err.h" -#include "bn.h" -#include "txt_db.h" -#include "evp.h" -#include "x509.h" -#include "x509v3.h" -#include "objects.h" -#include "pem.h" -#include "conf.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifndef W_OK #include @@ -105,6 +105,7 @@ #define ENV_PRESERVE "preserve" #define ENV_POLICY "policy" #define ENV_EXTENSIONS "x509_extensions" +#define ENV_CRLEXT "crl_extensions" #define ENV_MSIE_HACK "msie_hack" #define ENV_DATABASE "database" @@ -143,8 +144,9 @@ static char *ca_usage[]={ " -spkac file - File contains DN and signed public key and challenge\n", " -ss_cert file - File contains a self signed cert to sign\n", " -preserveDN - Don't re-order the DN\n", -" -batch - Don't ask questions\n", -" -msie_hack - msie modifications to handle all those universal strings\n", +" -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", NULL }; @@ -166,20 +168,24 @@ 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, - 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 *policy,TXT_DB *db,BIGNUM *serial, + char *startdate,int days,int batch,char *ext_sect, + LHASH *conf,int verbose); static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, - 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 *policy,TXT_DB *db, + BIGNUM *serial,char *startdate,int days,int batch, + char *ext_sect, LHASH *conf,int verbose); static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, - 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 *policy,TXT_DB *db, + BIGNUM *serial,char *startdate,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, EVP_MD *dgst, +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); +static int do_revoke(X509 *x509, TXT_DB *db); static int check_time_format(char *str); #else static int add_oid_section(); @@ -198,6 +204,7 @@ static int certify_cert(); static int certify_spkac(); static void write_new_certificate(); static int do_body(); +static int do_revoke(); static int check_time_format(); #endif @@ -208,9 +215,7 @@ static char *section=NULL; static int preserve=0; static int msie_hack=0; -int MAIN(argc, argv) -int argc; -char **argv; +int MAIN(int argc, char **argv) { int total=0; int total_done=0; @@ -219,6 +224,7 @@ char **argv; int req=0; int verbose=0; int gencrl=0; + int dorevoke=0; long crldays=0; long crlhours=0; long errorline= -1; @@ -236,6 +242,7 @@ char **argv; char *outdir=NULL; char *serialfile=NULL; char *extensions=NULL; + char *crl_ext=NULL; BIGNUM *serial=NULL; char *startdate=NULL; int days=0; @@ -251,7 +258,7 @@ char **argv; char **pp,*p,*f; int i,j; long l; - EVP_MD *dgst=NULL; + const EVP_MD *dgst=NULL; STACK *attribs=NULL; STACK *cert_sk=NULL; BIO *hex=NULL; @@ -378,6 +385,12 @@ EF_ALIGNMENT=0; spkac_file = *(++argv); req=1; } + else if (strcmp(*argv,"-revoke") == 0) + { + if (--argc < 1) goto bad; + infile= *(++argv); + dorevoke=1; + } else { bad: @@ -588,13 +601,13 @@ bad: if ((pp[DB_type][0] != DB_TYPE_REV) && (pp[DB_rev_date][0] != '\0')) { - BIO_printf(bio_err,"entry %d: not, revoked yet has a revokation date\n",i+1); + BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1); goto err; } if ((pp[DB_type][0] == DB_TYPE_REV) && !check_time_format(pp[DB_rev_date])) { - BIO_printf(bio_err,"entry %d: invalid revokation date\n", + BIO_printf(bio_err,"entry %d: invalid revocation date\n", i+1); goto err; } @@ -697,7 +710,10 @@ bad: extensions=CONF_get_string(conf,section,ENV_EXTENSIONS); if(extensions) { /* Check syntax of file */ - if(!X509V3_EXT_check_conf(conf, extensions)) { + X509V3_CTX ctx; + X509V3_set_ctx_test(&ctx); + X509V3_set_conf_lhash(&ctx, conf); + if(!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL)) { BIO_printf(bio_err, "Error Loading extension section %s\n", extensions); @@ -966,6 +982,20 @@ bad: /*****************************************************************/ if (gencrl) { + crl_ext=CONF_get_string(conf,section,ENV_CRLEXT); + if(crl_ext) { + /* Check syntax of file */ + X509V3_CTX ctx; + X509V3_set_ctx_test(&ctx); + X509V3_set_conf_lhash(&ctx, conf); + if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL)) { + BIO_printf(bio_err, + "Error Loading CRL extension section %s\n", + crl_ext); + ret = 1; + goto err; + } + } if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err; if (!crldays && !crlhours) @@ -1043,11 +1073,88 @@ bad: dgst=EVP_md5(); } + /* Add any extensions asked for */ + + if(crl_ext) { + X509V3_CTX crlctx; + if (ci->version == NULL) + if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err; + ASN1_INTEGER_set(ci->version,1); /* version 2 CRL */ + X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0); + X509V3_set_conf_lhash(&crlctx, conf); + + if(!X509V3_EXT_CRL_add_conf(conf, &crlctx, + crl_ext, crl)) goto err; + } + if (!X509_CRL_sign(crl,pkey,dgst)) goto err; PEM_write_bio_X509_CRL(Sout,crl); } /*****************************************************************/ + if (dorevoke) + { + in=BIO_new(BIO_s_file()); + out=BIO_new(BIO_s_file()); + if ((in == NULL) || (out == NULL)) + { + ERR_print_errors(bio_err); + goto err; + } + if (infile == NULL) + { + BIO_printf(bio_err,"no input files\n"); + goto err; + } + else + { + if (BIO_read_filename(in,infile) <= 0) + { + perror(infile); + BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile); + goto err; + } + x509=PEM_read_bio_X509(in,NULL,NULL); + if (x509 == NULL) + { + BIO_printf(bio_err,"unable to load '%s' certificate\n",infile); + goto err; + } + j=do_revoke(x509,db); + + strncpy(buf[0],dbfile,BSIZE-4); + strcat(buf[0],".new"); + if (BIO_write_filename(out,buf[0]) <= 0) + { + perror(dbfile); + BIO_printf(bio_err,"unable to open '%s'\n",dbfile); + goto err; + } + j=TXT_DB_write(out,db); + if (j <= 0) goto err; + BIO_free(in); + BIO_free(out); + in=NULL; + out=NULL; + strncpy(buf[1],dbfile,BSIZE-4); + strcat(buf[1],".old"); + if (rename(dbfile,buf[1]) < 0) + { + BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]); + perror("reason"); + goto err; + } + if (rename(buf[0],dbfile) < 0) + { + BIO_printf(bio_err,"unable to rename %s to %s\n", buf[0],dbfile); + perror("reason"); + rename(buf[1],dbfile); + goto err; + } + BIO_printf(bio_err,"Data Base Updated\n"); + } + } + /*****************************************************************/ ret=0; err: BIO_free(hex); @@ -1070,16 +1177,12 @@ err: EXIT(ret); } -static void lookup_fail(name,tag) -char *name; -char *tag; +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(buf,len,verify) -char *buf; -int len,verify; +static int MS_CALLBACK key_callback(char *buf, int len, int verify) { int i; @@ -1090,8 +1193,7 @@ int len,verify; return(i); } -static unsigned long index_serial_hash(a) -char **a; +static unsigned long index_serial_hash(char **a) { char *n; @@ -1100,9 +1202,7 @@ char **a; return(lh_strhash(n)); } -static int index_serial_cmp(a,b) -char **a; -char **b; +static int index_serial_cmp(char **a, char **b) { char *aa,*bb; @@ -1111,21 +1211,17 @@ char **b; return(strcmp(aa,bb)); } -static unsigned long index_name_hash(a) -char **a; +static unsigned long index_name_hash(char **a) { return(lh_strhash(a[DB_name])); } -static int index_name_qual(a) -char **a; +static int index_name_qual(char **a) { return(a[0][0] == 'V'); } -static int index_name_cmp(a,b) -char **a; -char **b; - { return(strcmp(a[DB_name],b[DB_name])); } +static int index_name_cmp(char **a, char **b) + { return(strcmp(a[DB_name], + b[DB_name])); } -static BIGNUM *load_serial(serialfile) -char *serialfile; +static BIGNUM *load_serial(char *serialfile) { BIO *in=NULL; BIGNUM *ret=NULL; @@ -1163,9 +1259,7 @@ err: return(ret); } -static int save_serial(serialfile,serial) -char *serialfile; -BIGNUM *serial; +static int save_serial(char *serialfile, BIGNUM *serial) { BIO *out; int ret=0; @@ -1197,22 +1291,10 @@ err: return(ret); } -static int certify(xret,infile,pkey,x509,dgst,policy,db,serial,startdate,days, - batch,ext_sect,lconf,verbose) -X509 **xret; -char *infile; -EVP_PKEY *pkey; -X509 *x509; -EVP_MD *dgst; -STACK *policy; -TXT_DB *db; -BIGNUM *serial; -char *startdate; -int days; -int batch; -char *ext_sect; -LHASH *lconf; -int verbose; +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) { X509_REQ *req=NULL; BIO *in=NULL; @@ -1268,22 +1350,11 @@ err: return(ok); } -static int certify_cert(xret,infile,pkey,x509,dgst,policy,db,serial,startdate, - days,batch,ext_sect,lconf,verbose) -X509 **xret; -char *infile; -EVP_PKEY *pkey; -X509 *x509; -EVP_MD *dgst; -STACK *policy; -TXT_DB *db; -BIGNUM *serial; -char *startdate; -int days; -int batch; -char *ext_sect; -LHASH *lconf; -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 *lconf, + int verbose) + { X509 *req=NULL; X509_REQ *rreq=NULL; @@ -1343,22 +1414,9 @@ err: return(ok); } -static int do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,days, - batch,verbose,req,ext_sect,lconf) -X509 **xret; -EVP_PKEY *pkey; -X509 *x509; -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; +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) { X509_NAME *name=NULL,*CAname=NULL,*subject=NULL; ASN1_UTCTIME *tm,*tmptm; @@ -1689,11 +1747,8 @@ again2: ci->extensions = NULL; - ctx.subject_cert = ret; - ctx.issuer_cert = x509; - ctx.subject_req = req; - ctx.crl = NULL; - ctx.flags = 0; + X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0); + X509V3_set_conf_lhash(&ctx, lconf); if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err; @@ -1789,10 +1844,7 @@ err: return(ok); } -static void write_new_certificate(bp,x, output_der) -BIO *bp; -X509 *x; -int output_der; +static void write_new_certificate(BIO *bp, X509 *x, int output_der) { char *f; char buf[256]; @@ -1818,21 +1870,9 @@ int output_der; BIO_puts(bp,"\n"); } -static int certify_spkac(xret,infile,pkey,x509,dgst,policy,db,serial, - startdate,days,ext_sect,lconf,verbose) -X509 **xret; -char *infile; -EVP_PKEY *pkey; -X509 *x509; -EVP_MD *dgst; -STACK *policy; -TXT_DB *db; -BIGNUM *serial; -char *startdate; -int days; -char *ext_sect; -LHASH *lconf; -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 *lconf, int verbose) { STACK *sk=NULL; LHASH *parms=NULL; @@ -1988,9 +2028,7 @@ err: return(ok); } -static int fix_data(nid,type) -int nid; -int *type; +static int fix_data(int nid, int *type) { if (nid == NID_pkcs9_emailAddress) *type=V_ASN1_IA5STRING; @@ -2005,8 +2043,7 @@ int *type; return(1); } -static int check_time_format(str) -char *str; +static int check_time_format(char *str) { ASN1_UTCTIME tm; @@ -2016,8 +2053,7 @@ char *str; return(ASN1_UTCTIME_check(&tm)); } -static int add_oid_section(hconf) -LHASH *hconf; +static int add_oid_section(LHASH *hconf) { char *p; STACK *sktmp; @@ -2038,3 +2074,109 @@ LHASH *hconf; } return 1; } + +static int do_revoke(X509 *x509, TXT_DB *db) +{ + ASN1_UTCTIME *tm=NULL; + char *row[DB_NUMBER],**rrow,**irow; + int ok=-1,i; + + for (i=0; icert_info->subject,NULL,0); + row[DB_serial]=BN_bn2hex(ASN1_INTEGER_to_BN(x509->cert_info->serialNumber,NULL)); + if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) + { + BIO_printf(bio_err,"Malloc failure\n"); + goto err; + } + rrow=TXT_DB_get_by_index(db,DB_name,row); + if (rrow == NULL) + { + BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]); + + /* We now just add it to the database */ + row[DB_type]=(char *)Malloc(2); + + tm=X509_get_notAfter(x509); + row[DB_exp_date]=(char *)Malloc(tm->length+1); + memcpy(row[DB_exp_date],tm->data,tm->length); + row[DB_exp_date][tm->length]='\0'; + + row[DB_rev_date]=NULL; + + /* row[DB_serial] done already */ + row[DB_file]=(char *)Malloc(8); + + /* row[DB_name] done already */ + + if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) || + (row[DB_file] == NULL)) + { + BIO_printf(bio_err,"Malloc failure\n"); + goto err; + } + strcpy(row[DB_file],"unknown"); + row[DB_type][0]='V'; + row[DB_type][1]='\0'; + + if ((irow=(char **)Malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL) + { + BIO_printf(bio_err,"Malloc failure\n"); + goto err; + } + + for (i=0; ierror); + goto err; + } + + /* Revoke Certificate */ + do_revoke(x509,db); + + ok=1; + goto err; + + } + else if (index_serial_cmp(row,rrow)) + { + BIO_printf(bio_err,"ERROR:no same serial number %s\n", + row[DB_serial]); + goto err; + } + else if (rrow[DB_type][0]=='R') + { + BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n", + row[DB_serial]); + goto err; + } + else + { + BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]); + tm=X509_gmtime_adj(tm,0); + rrow[DB_type][0]='R'; + rrow[DB_type][1]='\0'; + rrow[DB_rev_date]=(char *)Malloc(tm->length+1); + memcpy(rrow[DB_rev_date],tm->data,tm->length); + rrow[DB_rev_date][tm->length]='\0'; + } + ok=1; +err: + for (i=0; i