summaryrefslogtreecommitdiffstats
path: root/apps/req.c
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2017-12-27 18:29:36 +0100
committerRichard Levitte <levitte@openssl.org>2017-12-28 16:07:58 +0100
commitbfa470a4f64313651a35571883e235d3335054eb (patch)
treeb6675484f7b90f396b23c34b5449e86ce8d58c4d /apps/req.c
parent8175af50cc208c09f92b30358d30dd86c798b60e (diff)
Add 'openssl req' option to specify extension values on command line
The idea is to be able to add extension value lines directly on the command line instead of through the config file, for example: openssl req -new -extension 'subjectAltName = DNS:dom.ain, DNS:oth.er' \ -extension 'certificatePolicies = 1.2.3.4' Fixes #3311 Thank you Jacob Hoffman-Andrews for the inspiration Reviewed-by: Andy Polyakov <appro@openssl.org> (Merged from https://github.com/openssl/openssl/pull/4986)
Diffstat (limited to 'apps/req.c')
-rw-r--r--apps/req.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/apps/req.c b/apps/req.c
index 989a6ad7cd..dca6038a28 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -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);