diff --git a/CHANGES b/CHANGES index eb80eb6184881f741a3dd1a17389029f0f381aec..c11115318eaba97593376f42e7660fef5fd00cdc 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,13 @@ Changes between 0.9.6 and 0.9.7 [xx XXX 2000] + *) New '-extfile ...' option to 'openssl ca' for reading X.509v3 + extensions from a separate configuration file. + As when reading extensions from the main configuration file, + the '-extensions ...' option may be used for specifying the + section to use. + [Massimiliano Pala ] + *) Change PKCS12_key_gen_asc() so it can cope with non null terminated strings whose length is passed in the passlen parameter, for example from PEM callbacks. This was done diff --git a/apps/ca.c b/apps/ca.c index 2cf1697642853f00211b21560e592d265fadd5d7..5e12c0216a55a82d6d911b6e29e080504f0d6379 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -169,6 +169,7 @@ static char *ca_usage[]={ " -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", +" -extfile file - Configuration file with X509v3 extentions to add\n", " -crlexts .. - CRL extension section (override value in config file)\n", " -engine e - use engine e, possibly a hardware device.\n", " -status serial - Shows certificate status given the serial number\n", @@ -215,6 +216,7 @@ 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); static LHASH *conf=NULL; +static LHASH *extconf=NULL; static char *section=NULL; static int preserve=0; @@ -260,6 +262,7 @@ int MAIN(int argc, char **argv) char *outdir=NULL; char *serialfile=NULL; char *extensions=NULL; + char *extfile=NULL; char *crl_ext=NULL; BIGNUM *serial=NULL; char *startdate=NULL; @@ -438,6 +441,11 @@ EF_ALIGNMENT=0; if (--argc < 1) goto bad; extensions= *(++argv); } + else if (strcmp(*argv,"-extfile") == 0) + { + if (--argc < 1) goto bad; + extfile= *(++argv); + } else if (strcmp(*argv,"-status") == 0) { if (--argc < 1) goto bad; @@ -910,12 +918,36 @@ bad: goto err; } + /*****************************************************************/ + /* Read extentions config file */ + if (extfile) + { + long errorline; + if (!(extconf=CONF_load(NULL,extfile,&errorline))) + { + if (errorline <= 0) + BIO_printf(bio_err, "ERROR: loading the config file '%s'\n", + extfile); + else + BIO_printf(bio_err, "ERROR: on line %ld of config file '%s'\n", + errorline,extfile); + ret = 1; + goto err; + } + + if (verbose) + 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"))) + extensions = "default"; + } + /*****************************************************************/ if (req || gencrl) { if (outfile != NULL) { - if (BIO_write_filename(Sout,outfile) <= 0) { perror(outfile); @@ -965,25 +997,33 @@ bad: lookup_fail(section,ENV_SERIAL); goto err; } - if (!extensions) + + if (!extconf) { - extensions=CONF_get_string(conf,section,ENV_EXTENSIONS); + /* no '-extfile' option, so we look for extensions + * in the main configuration file */ if (!extensions) - ERR_clear_error(); - } - if (extensions) - { - /* 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, NULL)) { - BIO_printf(bio_err, - "Error Loading extension section %s\n", + extensions=CONF_get_string(conf,section, + ENV_EXTENSIONS); + if (!extensions) + ERR_clear_error(); + } + if (extensions) + { + /* 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, + NULL)) + { + BIO_printf(bio_err, + "Error Loading extension section %s\n", extensions); - ret = 1; - goto err; + ret = 1; + goto err; + } } } @@ -2039,11 +2079,47 @@ again2: ci->extensions = NULL; + /* Initialize the context structure */ 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; + if (extconf) + { + if (verbose) + BIO_printf(bio_err, "Extra configuration file found\n"); + + /* Use the extconf configuration db LHASH */ + X509V3_set_conf_lhash(&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)) + { + BIO_printf(bio_err, + "ERROR: adding extensions in section %s\n", + ext_sect); + ERR_print_errors(bio_err); + goto err; + } + if (verbose) + BIO_printf(bio_err, "Successfully added extensions from file.\n"); + } + else if (ext_sect) + { + /* We found extensions to be set from config file */ + X509V3_set_conf_lhash(&ctx, lconf); + if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) + { + BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect); + ERR_print_errors(bio_err); + goto err; + } + + if (verbose) + BIO_printf(bio_err, "Successfully added extensions from config\n"); + } } @@ -2481,7 +2557,8 @@ static int get_certificate_status(const char *serial, TXT_DB *db) /* Make it Upper Case */ for (i=0; row[DB_serial][i] != '\0'; i++) - row[DB_serial][i] = toupper((unsigned char)row[DB_serial][i]); + row[DB_serial][i] = toupper(row[DB_serial][i]); + ok=1; diff --git a/doc/apps/ca.pod b/doc/apps/ca.pod index d35292586458c2bbb23fa7fac0058c423d517654..8121886ebbade4b6da61152fba4f3671369b9c12 100644 --- a/doc/apps/ca.pod +++ b/doc/apps/ca.pod @@ -36,6 +36,7 @@ B B [B<-batch>] [B<-msie_hack>] [B<-extensions section>] +[B<-extfile section>] =head1 DESCRIPTION @@ -162,9 +163,16 @@ and all certificates will be certified automatically. =item B<-extensions section> the section of the configuration file containing certificate extensions -to be added when a certificate is issued. If no extension section is -present then a V1 certificate is created. If the extension section -is present (even if it is empty) then a V3 certificate is created. +to be added when a certificate is issued (defaults to B +unless the B<-extfile> option is used). If no extension section is +present then, a V1 certificate is created. If the extension section +is present (even if it is empty), then a V3 certificate is created. + +=item B<-extfile file> + +an additional configuration file to read certificate extensions from +(using the default section unless the B<-extensions> option is also +used). =back