X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=apps%2Fca.c;h=e0a9ef9eae26da0d9ad992720d589fc970d12cf2;hb=3f37e73baea893cd938983b3234658d8141df0e3;hp=584a2f561f4cb0b0343f93e4e061007d0eee8b91;hpb=cf1b7d96647d55e533f779e476e3d4371f40445a;p=oweals%2Fopenssl.git diff --git a/apps/ca.c b/apps/ca.c index 584a2f561f..e0a9ef9eae 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -78,8 +78,14 @@ #include #include +#ifdef OPENSSL_SYS_WINDOWS +#define strcasecmp _stricmp +#else +#include +#endif + #ifndef W_OK -# ifdef VMS +# ifdef OPENSSL_SYS_VMS # if defined(__DECC) # include # else @@ -126,6 +132,9 @@ #define ENV_EXTENSIONS "x509_extensions" #define ENV_CRLEXT "crl_extensions" #define ENV_MSIE_HACK "msie_hack" +#define ENV_NAMEOPT "name_opt" +#define ENV_CERTOPT "cert_opt" +#define ENV_EXTCOPY "copy_extensions" #define ENV_DATABASE "database" @@ -177,6 +186,7 @@ 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", +" -subj arg - Use arg instead of request's subject\n", " -extensions .. - Extension section (override value in config file)\n", " -extfile file - Configuration file with X509v3 extentions to add\n", " -crlexts .. - CRL extension section (override value in config file)\n", @@ -202,32 +212,41 @@ 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_OF(CONF_VALUE) *policy,TXT_DB *db, - BIGNUM *serial, char *startdate,char *enddate, int days, - int batch, char *ext_sect, LHASH *conf,int verbose); + BIGNUM *serial, char *subj, char *startdate,char *enddate, + long days, int batch, char *ext_sect, CONF *conf,int verbose, + unsigned long certopt, unsigned long nameopt, int default_op, + int ext_copy); static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, 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); + TXT_DB *db, BIGNUM *serial, char *subj, char *startdate, + char *enddate, long days, int batch, char *ext_sect, + CONF *conf,int verbose, unsigned long certopt, + unsigned long nameopt, int default_op, int ext_copy, + ENGINE *e); static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509, 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); + TXT_DB *db, BIGNUM *serial,char *subj, char *startdate, + char *enddate, long days, char *ext_sect,CONF *conf, + int verbose, unsigned long certopt, unsigned long nameopt, + int default_op, int ext_copy); static int fix_data(int nid, int *type); static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext); static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, - 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); + STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial,char *subj, + char *startdate, char *enddate, long days, int batch, int verbose, + X509_REQ *req, char *ext_sect, CONF *conf, + unsigned long certopt, unsigned long nameopt, int default_op, + int ext_copy); +static X509_NAME *do_subject(char *subject); static int do_revoke(X509 *x509, TXT_DB *db, int ext, char *extval); static int get_certificate_status(const char *ser_status, TXT_DB *db); static int do_updatedb(TXT_DB *db); static int check_time_format(char *str); char *make_revocation_str(int rev_type, char *rev_arg); int make_revoked(X509_REVOKED *rev, char *str); -static LHASH *conf=NULL; -static LHASH *extconf=NULL; +int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str); +static CONF *conf=NULL; +static CONF *extconf=NULL; static char *section=NULL; static int preserve=0; @@ -274,15 +293,19 @@ int MAIN(int argc, char **argv) char *serialfile=NULL; char *extensions=NULL; char *extfile=NULL; + char *subj=NULL; char *crl_ext=NULL; int rev_type = REV_NONE; char *rev_arg = NULL; BIGNUM *serial=NULL; char *startdate=NULL; char *enddate=NULL; - int days=0; + long days=0; int batch=0; int notext=0; + unsigned long nameopt = 0, certopt = 0; + int default_op = 1; + int ext_copy = EXT_COPY_NONE; X509 *x509=NULL; X509 *x=NULL; BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL; @@ -337,6 +360,12 @@ EF_ALIGNMENT=0; if (--argc < 1) goto bad; section= *(++argv); } + else if (strcmp(*argv,"-subj") == 0) + { + if (--argc < 1) goto bad; + subj= *(++argv); + /* preserve=1; */ + } else if (strcmp(*argv,"-startdate") == 0) { if (--argc < 1) goto bad; @@ -521,23 +550,7 @@ bad: ERR_load_crypto_strings(); - if (engine != NULL) - { - if ((e = ENGINE_by_id(engine)) == NULL) - { - BIO_printf(bio_err,"invalid engine \"%s\"\n", - engine); - goto err; - } - if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) - { - BIO_printf(bio_err,"can't use that engine\n"); - goto err; - } - BIO_printf(bio_err,"engine \"%s\" set.\n", engine); - /* Free our "structural" reference. */ - ENGINE_free(e); - } + e = setup_engine(bio_err, engine, 0); /*****************************************************************/ if (configfile == NULL) configfile = getenv("OPENSSL_CONF"); @@ -545,7 +558,7 @@ bad: if (configfile == NULL) { /* We will just use 'buf[0]' as a temporary buffer. */ -#ifdef VMS +#ifdef OPENSSL_SYS_VMS strncpy(buf[0],X509_get_default_cert_area(), sizeof(buf[0])-1-sizeof(CONFIG_FILE)); #else @@ -558,7 +571,8 @@ bad: } BIO_printf(bio_err,"Using configuration from %s\n",configfile); - if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL) + conf = NCONF_new(NULL); + if (NCONF_load(conf,configfile,&errorline) <= 0) { if (errorline <= 0) BIO_printf(bio_err,"error loading the config file '%s'\n", @@ -572,7 +586,7 @@ bad: /* Lets get the config section we are using */ if (section == NULL) { - section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA); + section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA); if (section == NULL) { lookup_fail(BASE_SECTION,ENV_DEFAULT_CA); @@ -582,7 +596,7 @@ bad: if (conf != NULL) { - p=CONF_get_string(conf,NULL,"oid_file"); + p=NCONF_get_string(conf,NULL,"oid_file"); if (p == NULL) ERR_clear_error(); if (p != NULL) @@ -611,7 +625,7 @@ bad: } } - randfile = CONF_get_string(conf, BASE_SECTION, "RANDFILE"); + randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE"); if (randfile == NULL) ERR_clear_error(); app_RAND_load_file(randfile, bio_err, 0); @@ -630,7 +644,7 @@ bad: /* report status of cert with serial number given on command line */ if (ser_status) { - if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL) + if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL) { lookup_fail(section,ENV_DATABASE); goto err; @@ -663,7 +677,7 @@ bad: /*****************************************************************/ /* we definitely need a public key, so let's get it */ - if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf, + if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf, section,ENV_PRIVATE_KEY)) == NULL)) { lookup_fail(section,ENV_PRIVATE_KEY); @@ -674,57 +688,27 @@ bad: BIO_printf(bio_err,"Error getting password\n"); goto err; } - if (keyform == FORMAT_ENGINE) - { - if (!e) - { - BIO_printf(bio_err,"no engine specified\n"); - goto err; - } - pkey = ENGINE_load_private_key(e, keyfile, key); - } - else if (keyform == FORMAT_PEM) - { - if (BIO_read_filename(in,keyfile) <= 0) - { - perror(keyfile); - BIO_printf(bio_err,"trying to load CA private key\n"); - goto err; - } - pkey=PEM_read_bio_PrivateKey(in,NULL,NULL,key); - } - else - { - BIO_printf(bio_err,"bad input format specified for key file\n"); - goto err; - } + pkey = load_key(bio_err, keyfile, keyform, key, e, + "CA private key"); if (key) memset(key,0,strlen(key)); if (pkey == NULL) { - BIO_printf(bio_err,"unable to load CA private key\n"); + /* load_key() has already printed an appropriate message */ goto err; } /*****************************************************************/ /* we need a certificate */ - if ((certfile == NULL) && ((certfile=CONF_get_string(conf, + if ((certfile == NULL) && ((certfile=NCONF_get_string(conf, section,ENV_CERTIFICATE)) == NULL)) { lookup_fail(section,ENV_CERTIFICATE); goto err; } - if (BIO_read_filename(in,certfile) <= 0) - { - perror(certfile); - BIO_printf(bio_err,"trying to load CA certificate\n"); - goto err; - } - x509=PEM_read_bio_X509(in,NULL,NULL,NULL); + x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e, + "CA certificate"); if (x509 == NULL) - { - BIO_printf(bio_err,"unable to load CA certificate\n"); goto err; - } if (!X509_check_private_key(x509,pkey)) { @@ -732,30 +716,72 @@ bad: goto err; } - f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE); + f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE); if (f == NULL) ERR_clear_error(); if ((f != NULL) && ((*f == 'y') || (*f == 'Y'))) preserve=1; - f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK); + f=NCONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK); if (f == NULL) ERR_clear_error(); if ((f != NULL) && ((*f == 'y') || (*f == 'Y'))) msie_hack=1; + f=NCONF_get_string(conf,section,ENV_NAMEOPT); + + if (f) + { + if (!set_name_ex(&nameopt, f)) + { + BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f); + goto err; + } + default_op = 0; + } + else + ERR_clear_error(); + + f=NCONF_get_string(conf,section,ENV_CERTOPT); + + if (f) + { + if (!set_cert_ex(&certopt, f)) + { + BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f); + goto err; + } + default_op = 0; + } + else + ERR_clear_error(); + + f=NCONF_get_string(conf,section,ENV_EXTCOPY); + + if (f) + { + if (!set_ext_copy(&ext_copy, f)) + { + BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f); + goto err; + } + } + else + ERR_clear_error(); + /*****************************************************************/ /* lookup where to write new certificates */ if ((outdir == NULL) && (req)) { struct stat sb; - if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR)) + if ((outdir=NCONF_get_string(conf,section,ENV_NEW_CERTS_DIR)) == NULL) { BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n"); goto err; } -#ifndef VMS /* outdir is a directory spec, but access() for VMS demands a +#ifndef OPENSSL_SYS_VMS + /* outdir is a directory spec, but access() for VMS demands a filename. In any case, stat(), below, will catch the problem if outdir is not a directory spec, and the fopen() or open() will catch an error if there is no write access. @@ -764,7 +790,7 @@ bad: C routines to convert the directory syntax to Unixly, and give that to access(). However, time's too short to do that just now. - */ + */ if (access(outdir,R_OK|W_OK|X_OK) != 0) { BIO_printf(bio_err,"I am unable to access the %s directory\n",outdir); @@ -791,7 +817,7 @@ bad: /*****************************************************************/ /* we need to load the database file */ - if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL) + if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL) { lookup_fail(section,ENV_DATABASE); goto err; @@ -853,7 +879,7 @@ bad: if (verbose) { BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */ -#ifdef VMS +#ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); @@ -895,9 +921,9 @@ bad: { BIO_printf(bio_err,"Malloc failure\n"); goto err; - } + } else if (i == 0) - { + { if (verbose) BIO_printf(bio_err, "No entries found to mark expired\n"); } @@ -910,7 +936,11 @@ bad: goto err; } +#ifndef OPENSSL_SYS_VMS j = BIO_snprintf(buf[0], sizeof buf[0], "%s.new", dbfile); +#else + j = BIO_snprintf(buf[0], sizeof buf[0], "%s-new", dbfile); +#endif if (j < 0 || j >= sizeof buf[0]) { BIO_printf(bio_err, "file name too long\n"); @@ -928,7 +958,11 @@ bad: BIO_free(out); out = NULL; +#ifndef OPENSSL_SYS_VMS j = BIO_snprintf(buf[1], sizeof buf[1], "%s.old", dbfile); +#else + j = BIO_snprintf(buf[1], sizeof buf[1], "%s-old", dbfile); +#endif if (j < 0 || j >= sizeof buf[1]) { BIO_printf(bio_err, "file name too long\n"); @@ -962,7 +996,8 @@ bad: /* Read extentions config file */ if (extfile) { - if (!(extconf=CONF_load(NULL,extfile,&errorline))) + extconf = NCONF_new(NULL); + if (NCONF_load(extconf,extfile,&errorline) <= 0) { if (errorline <= 0) BIO_printf(bio_err, "ERROR: loading the config file '%s'\n", @@ -978,9 +1013,9 @@ bad: BIO_printf(bio_err, "Succesfully loaded extensions file %s\n", extfile); /* We can have sections in the ext file */ - if (!extensions && !(extensions = CONF_get_string(extconf, "default", "extensions"))) + if (!extensions && !(extensions = NCONF_get_string(extconf, "default", "extensions"))) extensions = "default"; - } + } /*****************************************************************/ if (req || gencrl) @@ -996,7 +1031,7 @@ bad: else { BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT); -#ifdef VMS +#ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); Sout = BIO_push(tmpbio, Sout); @@ -1007,7 +1042,7 @@ bad: if (req) { - if ((md == NULL) && ((md=CONF_get_string(conf, + if ((md == NULL) && ((md=NCONF_get_string(conf, section,ENV_DEFAULT_MD)) == NULL)) { lookup_fail(section,ENV_DEFAULT_MD); @@ -1021,7 +1056,7 @@ bad: if (verbose) BIO_printf(bio_err,"message digest is %s\n", OBJ_nid2ln(dgst->type)); - if ((policy == NULL) && ((policy=CONF_get_string(conf, + if ((policy == NULL) && ((policy=NCONF_get_string(conf, section,ENV_POLICY)) == NULL)) { lookup_fail(section,ENV_POLICY); @@ -1030,7 +1065,7 @@ bad: if (verbose) BIO_printf(bio_err,"policy is %s\n",policy); - if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL)) + if ((serialfile=NCONF_get_string(conf,section,ENV_SERIAL)) == NULL) { lookup_fail(section,ENV_SERIAL); @@ -1043,7 +1078,7 @@ bad: * in the main configuration file */ if (!extensions) { - extensions=CONF_get_string(conf,section, + extensions=NCONF_get_string(conf,section, ENV_EXTENSIONS); if (!extensions) ERR_clear_error(); @@ -1053,8 +1088,8 @@ bad: /* 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, extensions, + X509V3_set_nconf(&ctx, conf); + if (!X509V3_EXT_add_nconf(conf, &ctx, extensions, NULL)) { BIO_printf(bio_err, @@ -1068,7 +1103,7 @@ bad: if (startdate == NULL) { - startdate=CONF_get_string(conf,section, + startdate=NCONF_get_string(conf,section, ENV_DEFAULT_STARTDATE); if (startdate == NULL) ERR_clear_error(); @@ -1082,7 +1117,7 @@ bad: if (enddate == NULL) { - enddate=CONF_get_string(conf,section, + enddate=NCONF_get_string(conf,section, ENV_DEFAULT_ENDDATE); if (enddate == NULL) ERR_clear_error(); @@ -1095,8 +1130,8 @@ bad: if (days == 0) { - days=(int)CONF_get_number(conf,section, - ENV_DEFAULT_DAYS); + if(!NCONF_get_number(conf,section, ENV_DEFAULT_DAYS, &days)) + days = 0; } if (!enddate && (days == 0)) { @@ -1116,7 +1151,7 @@ bad: OPENSSL_free(f); } - if ((attribs=CONF_get_section(conf,policy)) == NULL) + if ((attribs=NCONF_get_section(conf,policy)) == NULL) { BIO_printf(bio_err,"unable to find 'section' for %s\n",policy); goto err; @@ -1131,8 +1166,8 @@ bad: { total++; j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db, - serial,startdate,enddate, days,extensions,conf, - verbose); + serial,subj,startdate,enddate, days,extensions,conf, + verbose, certopt, nameopt, default_op, ext_copy); if (j < 0) goto err; if (j > 0) { @@ -1155,8 +1190,9 @@ bad: { total++; j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs, - db,serial,startdate,enddate,days,batch, - extensions,conf,verbose); + db,serial,subj,startdate,enddate,days,batch, + extensions,conf,verbose, certopt, nameopt, + default_op, ext_copy, e); if (j < 0) goto err; if (j > 0) { @@ -1174,8 +1210,9 @@ bad: { total++; j=certify(&x,infile,pkey,x509,dgst,attribs,db, - serial,startdate,enddate,days,batch, - extensions,conf,verbose); + serial,subj,startdate,enddate,days,batch, + extensions,conf,verbose, certopt, nameopt, + default_op, ext_copy); if (j < 0) goto err; if (j > 0) { @@ -1193,8 +1230,9 @@ bad: { total++; j=certify(&x,argv[i],pkey,x509,dgst,attribs,db, - serial,startdate,enddate,days,batch, - extensions,conf,verbose); + serial,subj,startdate,enddate,days,batch, + extensions,conf,verbose, certopt, nameopt, + default_op, ext_copy); if (j < 0) goto err; if (j > 0) { @@ -1232,7 +1270,7 @@ bad: strncpy(buf[0],serialfile,BSIZE-4); -#ifdef VMS +#ifdef OPENSSL_SYS_VMS strcat(buf[0],"-new"); #else strcat(buf[0],".new"); @@ -1242,7 +1280,7 @@ bad: strncpy(buf[1],dbfile,BSIZE-4); -#ifdef VMS +#ifdef OPENSSL_SYS_VMS strcat(buf[1],"-new"); #else strcat(buf[1],".new"); @@ -1272,7 +1310,7 @@ bad: strncpy(buf[2],outdir,BSIZE-(j*2)-6); -#ifndef VMS +#ifndef OPENSSL_SYS_VMS strcat(buf[2],"/"); #endif @@ -1309,7 +1347,7 @@ bad: /* Rename the database and the serial file */ strncpy(buf[2],serialfile,BSIZE-4); -#ifdef VMS +#ifdef OPENSSL_SYS_VMS strcat(buf[2],"-old"); #else strcat(buf[2],".old"); @@ -1337,7 +1375,7 @@ bad: strncpy(buf[2],dbfile,BSIZE-4); -#ifdef VMS +#ifdef OPENSSL_SYS_VMS strcat(buf[2],"-old"); #else strcat(buf[2],".old"); @@ -1368,7 +1406,7 @@ bad: int crl_v2 = 0; if (!crl_ext) { - crl_ext=CONF_get_string(conf,section,ENV_CRLEXT); + crl_ext=NCONF_get_string(conf,section,ENV_CRLEXT); if (!crl_ext) ERR_clear_error(); } @@ -1377,8 +1415,8 @@ bad: /* 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)) + X509V3_set_nconf(&ctx, conf); + if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL)) { BIO_printf(bio_err, "Error Loading CRL extension section %s\n", @@ -1390,10 +1428,12 @@ bad: if (!crldays && !crlhours) { - crldays=CONF_get_number(conf,section, - ENV_DEFAULT_CRL_DAYS); - crlhours=CONF_get_number(conf,section, - ENV_DEFAULT_CRL_HOURS); + if (!NCONF_get_number(conf,section, + ENV_DEFAULT_CRL_DAYS, &crldays)) + crldays = 0; + if (!NCONF_get_number(conf,section, + ENV_DEFAULT_CRL_HOURS, &crlhours)) + crlhours = 0; } if ((crldays == 0) && (crlhours == 0)) { @@ -1469,9 +1509,9 @@ bad: if (ci->version == NULL) if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err; X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0); - X509V3_set_conf_lhash(&crlctx, conf); + X509V3_set_nconf(&crlctx, conf); - if (!X509V3_EXT_CRL_add_conf(conf, &crlctx, + if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl)) goto err; } if (crl_ext || crl_v2) @@ -1496,24 +1536,20 @@ bad: else { X509 *revcert; - if (BIO_read_filename(in,infile) <= 0) - { - perror(infile); - BIO_printf(bio_err,"error trying to load '%s' certificate\n",infile); - goto err; - } - revcert=PEM_read_bio_X509(in,NULL,NULL,NULL); + revcert=load_cert(bio_err, infile, FORMAT_PEM, + NULL, e, infile); if (revcert == NULL) - { - BIO_printf(bio_err,"unable to load '%s' certificate\n",infile); goto err; - } j=do_revoke(revcert,db, rev_type, rev_arg); if (j <= 0) goto err; X509_free(revcert); strncpy(buf[0],dbfile,BSIZE-4); +#ifndef OPENSSL_SYS_VMS strcat(buf[0],".new"); +#else + strcat(buf[0],"-new"); +#endif if (BIO_write_filename(out,buf[0]) <= 0) { perror(dbfile); @@ -1523,7 +1559,11 @@ bad: j=TXT_DB_write(out,db); if (j <= 0) goto err; strncpy(buf[1],dbfile,BSIZE-4); +#ifndef OPENSSL_SYS_VMS strcat(buf[1],".old"); +#else + strcat(buf[1],"-old"); +#endif if (rename(dbfile,buf[1]) < 0) { BIO_printf(bio_err,"unable to rename %s to %s\n", dbfile, buf[1]); @@ -1546,7 +1586,7 @@ err: BIO_free_all(Cout); BIO_free_all(Sout); BIO_free_all(out); - BIO_free(in); + BIO_free_all(in); sk_X509_pop_free(cert_sk,X509_free); @@ -1557,8 +1597,9 @@ err: EVP_PKEY_free(pkey); X509_free(x509); X509_CRL_free(crl); - CONF_free(conf); + NCONF_free(conf); OBJ_cleanup(); + apps_shutdown(); EXIT(ret); } @@ -1667,8 +1708,10 @@ err: static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, 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) + BIGNUM *serial, char *subj, char *startdate, char *enddate, long days, + int batch, char *ext_sect, CONF *lconf, int verbose, + unsigned long certopt, unsigned long nameopt, int default_op, + int ext_copy) { X509_REQ *req=NULL; BIO *in=NULL; @@ -1715,8 +1758,9 @@ 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, enddate, - days,batch,verbose,req,ext_sect,lconf); + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate, enddate, + days,batch,verbose,req,ext_sect,lconf, + certopt, nameopt, default_op, ext_copy); err: if (req != NULL) X509_REQ_free(req); @@ -1726,27 +1770,18 @@ err: static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, 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) + BIGNUM *serial, char *subj, char *startdate, char *enddate, long days, + int batch, char *ext_sect, CONF *lconf, int verbose, + unsigned long certopt, unsigned long nameopt, int default_op, + int ext_copy, ENGINE *e) { X509 *req=NULL; X509_REQ *rreq=NULL; - BIO *in=NULL; EVP_PKEY *pktmp=NULL; int ok= -1,i; - in=BIO_new(BIO_s_file()); - - if (BIO_read_filename(in,infile) <= 0) - { - perror(infile); - goto err; - } - if ((req=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL) - { - BIO_printf(bio_err,"Error reading self signed certificate in %s\n",infile); + if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL) goto err; - } if (verbose) X509_print(bio_err,req); @@ -1777,20 +1812,22 @@ 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,enddate,days, - batch,verbose,rreq,ext_sect,lconf); + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate,enddate,days, + batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op, + ext_copy); err: if (rreq != NULL) X509_REQ_free(rreq); if (req != NULL) X509_free(req); - if (in != NULL) BIO_free(in); return(ok); } static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, - 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) + STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *subj, + char *startdate, char *enddate, long days, int batch, int verbose, + X509_REQ *req, char *ext_sect, CONF *lconf, + unsigned long certopt, unsigned long nameopt, int default_op, + int ext_copy) { X509_NAME *name=NULL,*CAname=NULL,*subject=NULL; ASN1_UTCTIME *tm,*tmptm; @@ -1805,7 +1842,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, char *p; CONF_VALUE *cv; char *row[DB_NUMBER],**rrow,**irow=NULL; - char buf[25],*pbuf; + char buf[25]; tmptm=ASN1_UTCTIME_new(); if (tmptm == NULL) @@ -1817,20 +1854,28 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, for (i=0; ireq_info->enc.modified = 1; + X509_NAME_free(n); + } + + if (default_op) + BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n"); name=X509_REQ_get_subject_name(req); for (i=0; i0; j--) - *(pbuf++)=' '; - *(pbuf++)=':'; - *(pbuf++)='\0'; - BIO_puts(bio_err,buf); + obj=X509_NAME_ENTRY_get_object(ne); if (msie_hack) { @@ -1849,17 +1894,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, str->type=V_ASN1_IA5STRING; } - if (str->type == V_ASN1_PRINTABLESTRING) - BIO_printf(bio_err,"PRINTABLE:'"); - else if (str->type == V_ASN1_T61STRING) - BIO_printf(bio_err,"T61STRING:'"); - else if (str->type == V_ASN1_IA5STRING) - BIO_printf(bio_err,"IA5STRING:'"); - else if (str->type == V_ASN1_UNIVERSALSTRING) - BIO_printf(bio_err,"UNIVERSALSTRING:'"); - else - BIO_printf(bio_err,"ASN.1 %2d:'",str->type); - /* check some things */ if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (str->type != V_ASN1_IA5STRING)) @@ -1876,20 +1910,9 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n"); goto err; } - - p=(char *)str->data; - for (j=str->length; j>0; j--) - { - if ((*p >= ' ') && (*p <= '~')) - BIO_printf(bio_err,"%c",*p); - else if (*p & 0x80) - BIO_printf(bio_err,"\\0x%02X",*p); - else if ((unsigned char)*p == 0xf7) - BIO_printf(bio_err,"^?"); - else BIO_printf(bio_err,"^%c",*p+'@'); - p++; - } - BIO_printf(bio_err,"'\n"); + + if (default_op) + old_entry_print(bio_err, obj, str); } /* Ok, now we check the 'policy' stuff. */ @@ -2083,7 +2106,6 @@ again2: if (!X509_set_issuer_name(ret,X509_get_subject_name(x509))) goto err; - 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); @@ -2092,10 +2114,6 @@ again2: X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days); else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate); - ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret)); - if (days) BIO_printf(bio_err," (%d days)",days); - BIO_printf(bio_err, "\n"); - if (!X509_set_subject_name(ret,subject)) goto err; pktmp=X509_REQ_get_pubkey(req); @@ -2129,13 +2147,13 @@ again2: BIO_printf(bio_err, "Extra configuration file found\n"); /* Use the extconf configuration db LHASH */ - X509V3_set_conf_lhash(&ctx, extconf); + X509V3_set_nconf(&ctx, extconf); /* Test the structure (needed?) */ /* X509V3_set_ctx_test(&ctx); */ /* Adds exts contained in the configuration file */ - if (!X509V3_EXT_add_conf(extconf, &ctx, ext_sect,ret)) + if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect,ret)) { BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", @@ -2149,9 +2167,9 @@ again2: else if (ext_sect) { /* We found extensions to be set from config file */ - X509V3_set_conf_lhash(&ctx, lconf); + X509V3_set_nconf(&ctx, lconf); - if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) + if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) { BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect); ERR_print_errors(bio_err); @@ -2163,9 +2181,32 @@ again2: } } + /* Copy extensions from request (if any) */ + + if (!copy_extensions(ret, req, ext_copy)) + { + BIO_printf(bio_err, "ERROR: adding extensions from request\n"); + ERR_print_errors(bio_err); + goto err; + } + + + if (!default_op) + { + BIO_printf(bio_err, "Certificate Details:\n"); + /* Never print signature details because signature not present */ + certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME; + X509_print_ex(bio_err, ret, nameopt, certopt); + } + + BIO_printf(bio_err,"Certificate is to be certified until "); + ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret)); + if (days) BIO_printf(bio_err," (%d days)",days); + BIO_printf(bio_err, "\n"); if (!batch) { + BIO_printf(bio_err,"Sign the certificate? [y/n]:"); (void)BIO_flush(bio_err); buf[0]='\0'; @@ -2281,8 +2322,9 @@ static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext) static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, 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) + BIGNUM *serial, char *subj, char *startdate, char *enddate, long days, + char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, + unsigned long nameopt, int default_op, int ext_copy) { STACK_OF(CONF_VALUE) *sk=NULL; LHASH *parms=NULL; @@ -2416,8 +2458,9 @@ 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,enddate, - days,1,verbose,req,ext_sect,lconf); + ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,startdate,enddate, + days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op, + ext_copy); err: if (req != NULL) X509_REQ_free(req); if (parms != NULL) CONF_free(parms); @@ -2966,3 +3009,102 @@ int make_revoked(X509_REVOKED *rev, char *str) return ret; } + +static X509_NAME *do_subject(char *subject) + { + X509_NAME *n = NULL; + + int i, nid, ne_num=0; + + char *ne_name = NULL; + char *ne_value = NULL; + + char *tmp = NULL; + char *p[2]; + + char *str_list[256]; + + p[0] = ",/"; + p[1] = "="; + + n = X509_NAME_new(); + + tmp = strtok(subject, p[0]); + while((tmp != NULL) && (ne_num < (sizeof str_list/sizeof *str_list))) + { + char *token = tmp; + + while (token[0] == ' ') + token++; + str_list[ne_num] = token; + + tmp = strtok(NULL, p[0]); + ne_num++; + } + + for (i = 0; i < ne_num; i++) + { + ne_name = strtok(str_list[i], p[1]); + ne_value = strtok(NULL, p[1]); + + if ((nid=OBJ_txt2nid(ne_name)) == NID_undef) + { + BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_name); + continue; + } + + if (ne_value == NULL) + { + BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_name); + continue; + } + + if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC, (unsigned char*)ne_value, -1,-1,0)) + { + X509_NAME_free(n); + return NULL; + } + } + + return n; + } + + +int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str) + { + char buf[25],*pbuf, *p; + int j; + j=i2a_ASN1_OBJECT(bp,obj); + pbuf=buf; + for (j=22-j; j>0; j--) + *(pbuf++)=' '; + *(pbuf++)=':'; + *(pbuf++)='\0'; + BIO_puts(bp,buf); + + if (str->type == V_ASN1_PRINTABLESTRING) + BIO_printf(bp,"PRINTABLE:'"); + else if (str->type == V_ASN1_T61STRING) + BIO_printf(bp,"T61STRING:'"); + else if (str->type == V_ASN1_IA5STRING) + BIO_printf(bp,"IA5STRING:'"); + else if (str->type == V_ASN1_UNIVERSALSTRING) + BIO_printf(bp,"UNIVERSALSTRING:'"); + else + BIO_printf(bp,"ASN.1 %2d:'",str->type); + + p=(char *)str->data; + for (j=str->length; j>0; j--) + { + if ((*p >= ' ') && (*p <= '~')) + BIO_printf(bp,"%c",*p); + else if (*p & 0x80) + BIO_printf(bp,"\\0x%02X",*p); + else if ((unsigned char)*p == 0xf7) + BIO_printf(bp,"^?"); + else BIO_printf(bp,"^%c",*p+'@'); + p++; + } + BIO_printf(bp,"'\n"); + return 1; + }