@@ -70,6 +70,7 @@ static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr,
int *pkey_type, long *pkeylen,
char **palgnam, ENGINE *keygen_engine);
static CONF *req_conf = NULL ;
+static CONF *addext_conf = NULL ;
static int batch = 0 ;
typedef enum OPTION_choice {
@@ -80,7 +81,7 @@ typedef enum OPTION_choice {
OPT_PKEYOPT, OPT_SIGOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS,
OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8,
OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509,
- OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_EXTENSIONS,
+ OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_ADDEXT, OPT_EXTENSIONS,
OPT_REQEXTS, OPT_PRECERT, OPT_MD,
OPT_R_ENUM
} OPTION_CHOICE;
@@ -124,6 +125,8 @@ const OPTIONS req_options[] = {
" Enable support for multivalued RDNs" },
{" days" , OPT_DAYS, ' p' , " Number of days cert is valid for" },
{" set_serial" , OPT_SET_SERIAL, ' s' , " Serial number to use" },
+ {" addext" , OPT_ADDEXT, ' s' ,
+ " Additional cert extension key=value pair (may be given more than once)" },
{" extensions" , OPT_EXTENSIONS, ' s' ,
" Cert extension section (override value in config file)" },
{" reqexts" , OPT_REQEXTS, ' s' ,
@@ -150,6 +153,7 @@ int req_main(int argc, char **argv)
X509_REQ *req = NULL ;
const EVP_CIPHER *cipher = NULL ;
const EVP_MD *md_alg = NULL , *digest = NULL ;
+ BIO *addext_bio = NULL ;
char *extensions = NULL , *infile = NULL ;
char *outfile = NULL , *keyfile = NULL ;
char *keyalgstr = NULL , *p, *prog, *passargin = NULL , *passargout = NULL ;
@@ -313,6 +317,14 @@ int req_main(int argc, char **argv)
case OPT_MULTIVALUE_RDN:
multirdn = 1 ;
break ;
+ case OPT_ADDEXT:
+ if (addext_bio == NULL ) {
+ addext_bio = BIO_new (BIO_s_mem ());
+ }
+ if (addext_bio == NULL
+ || BIO_printf (addext_bio, " %s \n " , opt_arg ()) < 0 )
+ goto end;
+ break ;
case OPT_EXTENSIONS:
extensions = opt_arg ();
break ;
@@ -349,6 +361,12 @@ int req_main(int argc, char **argv)
if (verbose)
BIO_printf (bio_err, " Using configuration from %s \n " , template);
req_conf = app_load_config (template);
+ if (addext_bio) {
+ if (verbose)
+ BIO_printf (bio_err,
+ " Using additional configuraton from command line\n " );
+ addext_conf = app_load_config_bio (addext_bio, NULL );
+ }
if (template != default_config_file && !app_load_modules (req_conf))
goto end;
@@ -401,6 +419,16 @@ int req_main(int argc, char **argv)
goto end;
}
}
+ if (addext_conf != NULL ) {
+ /* Check syntax of command line extensions */
+ X509V3_CTX ctx;
+ X509V3_set_ctx_test (&ctx);
+ X509V3_set_nconf (&ctx, addext_conf);
+ if (!X509V3_EXT_add_nconf (addext_conf, &ctx, " default" , NULL )) {
+ BIO_printf (bio_err, " Error Loading command line extensions\n " );
+ goto end;
+ }
+ }
if (passin == NULL ) {
passin = nofree_passin =
@@ -605,7 +633,8 @@ int req_main(int argc, char **argv)
goto end;
/* Set version to V3 */
- if (extensions != NULL && !X509_set_version (x509ss, 2 ))
+ if ((extensions != NULL || addext_conf != NULL )
+ && !X509_set_version (x509ss, 2 ))
goto end;
if (serial != NULL ) {
if (!X509_set_serialNumber (x509ss, serial))
@@ -643,6 +672,12 @@ int req_main(int argc, char **argv)
extensions);
goto end;
}
+ if (addext_conf != NULL
+ && !X509V3_EXT_add_nconf (addext_conf, &ext_ctx, " default" ,
+ x509ss)) {
+ BIO_printf (bio_err, " Error Loading command line extensions\n " );
+ goto end;
+ }
/* If a pre-cert was requested, we need to add a poison extension */
if (precert) {
@@ -674,6 +709,12 @@ int req_main(int argc, char **argv)
req_exts);
goto end;
}
+ if (addext_conf != NULL
+ && !X509V3_EXT_REQ_add_nconf (addext_conf, &ext_ctx, " default" ,
+ req)) {
+ BIO_printf (bio_err, " Error Loading command line extensions\n " );
+ goto end;
+ }
i = do_X509_REQ_sign (req, pkey, digest, sigopts);
if (!i) {
ERR_print_errors (bio_err);
@@ -817,6 +858,7 @@ int req_main(int argc, char **argv)
ERR_print_errors (bio_err);
}
NCONF_free (req_conf);
+ BIO_free (addext_bio);
BIO_free (in);
BIO_free_all (out);
EVP_PKEY_free (pkey);
0 comments on commit
bfa470a