diff options
author | Job Snijders <job@sobornost.net> | 2024-01-10 17:15:52 +0000 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2024-01-15 10:40:01 +0100 |
commit | 4e5bf933131863e0459d7b39931d464fef77b078 (patch) | |
tree | 1ca2f5c4702aa4d977c9aa5b0462e79e593473e7 | |
parent | df04e81794ac3083804c34c173eb2b2fa55d373d (diff) | |
download | openssl-4e5bf933131863e0459d7b39931d464fef77b078.tar.gz |
Add apps/x509 -set_issuer & -set_subject option to override issuer & subject
This changeset adds the counterpart to the '-subj' option to allow overriding
the Issuer. For consistency, the `-subj` option is aliased to `-set_subject`.
The issuer can be specified as following apps/openssl x509 -new -set_issuer
'/CN=example-nro-ta' -subj '/CN=2a7dd1d787d793e4c8af56e197d4eed92af6ba13' ...
This is useful in constructing specific test-cases or rechaining PKI trees
Joint work with George Michaelson (@geeohgeegeeoh)
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23257)
-rw-r--r-- | CHANGES.md | 6 | ||||
-rw-r--r-- | apps/x509.c | 26 | ||||
-rw-r--r-- | doc/man1/openssl-x509.pod.in | 21 | ||||
-rw-r--r-- | test/recipes/25-test_x509.t | 11 |
4 files changed, 53 insertions, 11 deletions
diff --git a/CHANGES.md b/CHANGES.md index eb16a6e24e..58d06ae498 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -36,6 +36,12 @@ OpenSSL 3.3 *Neil Horman* + * Added `-set_issuer` and `-set_subject` options to `openssl x509` to + override the Issuer and Subject when creating a certificate. The `-subj` + option now is an alias for `-set_subject`. + + *Job Snijders, George Michaelson* + * OPENSSL_sk_push() and sk_<TYPE>_push() functions now return 0 instead of -1 if called with a NULL stack argument. diff --git a/apps/x509.c b/apps/x509.c index 578af2364f..ce3fda6716 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -43,7 +43,7 @@ typedef enum OPTION_choice { OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM, OPT_CAKEYFORM, OPT_VFYOPT, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE, OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_KEY, OPT_SIGNKEY, OPT_CA, OPT_CAKEY, - OPT_CASERIAL, OPT_SET_SERIAL, OPT_NEW, OPT_FORCE_PUBKEY, OPT_SUBJ, + OPT_CASERIAL, OPT_SET_SERIAL, OPT_NEW, OPT_FORCE_PUBKEY, OPT_ISSU, OPT_SUBJ, OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_DATEOPT, OPT_NAMEOPT, OPT_EMAIL, OPT_OCSP_URI, OPT_SERIAL, OPT_NEXT_SERIAL, OPT_MODULUS, OPT_PUBKEY, OPT_X509TOREQ, OPT_TEXT, OPT_HASH, @@ -138,7 +138,9 @@ const OPTIONS x509_options[] = { "Number of days until newly generated certificate expires - default 30"}, {"preserve_dates", OPT_PRESERVE_DATES, '-', "Preserve existing validity dates"}, - {"subj", OPT_SUBJ, 's', "Set or override certificate subject (and issuer)"}, + {"set_issuer", OPT_ISSU, 's', "Set or override certificate issuer"}, + {"set_subject", OPT_SUBJ, 's', "Set or override certificate subject (and issuer)"}, + {"subj", OPT_SUBJ, 's', "Alias for -set_subject"}, {"force_pubkey", OPT_FORCE_PUBKEY, '<', "Key to be placed in new certificate or certificate request"}, {"clrext", OPT_CLREXT, '-', @@ -262,8 +264,8 @@ int x509_main(int argc, char **argv) EVP_PKEY *privkey = NULL, *CAkey = NULL, *pubkey = NULL; EVP_PKEY *pkey; int newcert = 0; - char *subj = NULL, *digest = NULL; - X509_NAME *fsubj = NULL; + char *issu = NULL, *subj = NULL, *digest = NULL; + X509_NAME *fissu = NULL, *fsubj = NULL; const unsigned long chtype = MBSTRING_ASC; const int multirdn = 1; STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; @@ -425,6 +427,9 @@ int x509_main(int argc, char **argv) case OPT_FORCE_PUBKEY: pubkeyfile = opt_arg(); break; + case OPT_ISSU: + issu = opt_arg(); + break; case OPT_SUBJ: subj = opt_arg(); break; @@ -651,6 +656,9 @@ int x509_main(int argc, char **argv) goto err; } } + if (issu != NULL + && (fissu = parse_name(issu, chtype, multirdn, "issuer")) == NULL) + goto end; if (subj != NULL && (fsubj = parse_name(subj, chtype, multirdn, "subject")) == NULL) goto end; @@ -830,8 +838,13 @@ int x509_main(int argc, char **argv) if (reqfile || newcert || privkey != NULL || CAfile != NULL) { if (!preserve_dates && !set_cert_times(x, NULL, NULL, days)) goto end; - if (!X509_set_issuer_name(x, X509_get_subject_name(issuer_cert))) - goto end; + if (fissu != NULL) { + if (!X509_set_issuer_name(x, fissu)) + goto end; + } else { + if (!X509_set_issuer_name(x, X509_get_subject_name(issuer_cert))) + goto end; + } } X509V3_set_ctx(&ext_ctx, issuer_cert, x, NULL, NULL, X509V3_CTX_REPLACE); @@ -1079,6 +1092,7 @@ int x509_main(int argc, char **argv) NCONF_free(extconf); BIO_free_all(out); X509_STORE_free(ctx); + X509_NAME_free(fissu); X509_NAME_free(fsubj); X509_REQ_free(req); X509_free(x); diff --git a/doc/man1/openssl-x509.pod.in b/doc/man1/openssl-x509.pod.in index 2d7a1b859a..3a5bd25d56 100644 --- a/doc/man1/openssl-x509.pod.in +++ b/doc/man1/openssl-x509.pod.in @@ -56,6 +56,8 @@ B<openssl> B<x509> [B<-next_serial>] [B<-days> I<arg>] [B<-preserve_dates>] +[B<-set_issuer> I<arg>] +[B<-set_subject> I<arg>] [B<-subj> I<arg>] [B<-force_pubkey> I<filename>] [B<-clrext>] @@ -123,7 +125,7 @@ see L<openssl-passphrase-options(1)>. Generate a certificate from scratch, not using an input certificate or certificate request. So this excludes the B<-in> and B<-req> options. -Instead, the B<-subj> option needs to be given. +Instead, the B<-set_subject> option needs to be given. The public key to include can be given with the B<-force_pubkey> option and defaults to the key given with the B<-key> (or B<-signkey>) option, which implies self-signature. @@ -386,10 +388,17 @@ When signing a certificate, preserve "notBefore" and "notAfter" dates of any input certificate instead of adjusting them to current time and duration. Cannot be used together with the B<-days> option. -=item B<-subj> I<arg> +=item B<-set_issuer> I<arg> + +When a certificate is created set its issuer name to the given value. + +See B<-set_subject> on how the arg must be formatted. + +=item B<-set_subject> I<arg> When a certificate is created set its subject name to the given value. -When the certificate is self-signed the issuer name is set to the same value. +When the certificate is self-signed the issuer name is set to the same value, +unless the B<-set_issuer> option is given. The arg must be formatted as C</type0=value0/type1=value1/type2=...>. Special characters may be escaped by C<\> (backslash), whitespace is retained. @@ -405,6 +414,10 @@ C</DC=org/DC=OpenSSL/DC=users/UID=123456+CN=John Doe> This option can be used with the B<-new> and B<-force_pubkey> options to create a new certificate without providing an input certificate or certificate request. +=item B<-subj> I<arg> + +This option is an alias of B<-set_subject>. + =item B<-force_pubkey> I<filename> When a new certificate or certificate request is created @@ -413,7 +426,7 @@ instead of the key contained in the input or given with the B<-key> (or B<-signkey>) option. If the input contains no public key but a private key, its public part is used. -This option can be used in conjunction with b<-new> and B<-subj> +This option can be used in conjunction with b<-new> and B<-set_subject> to directly generate a certificate containing any desired public key. This option is also useful for creating self-issued certificates that are not diff --git a/test/recipes/25-test_x509.t b/test/recipes/25-test_x509.t index 9b11169a98..eeb8083506 100644 --- a/test/recipes/25-test_x509.t +++ b/test/recipes/25-test_x509.t @@ -16,7 +16,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/; setup("test_x509"); -plan tests => 44; +plan tests => 46; # Prevent MSys2 filename munging for arguments that look like file paths but # aren't @@ -81,6 +81,15 @@ ok(run(app(["openssl", "pkey", "-in", $pkey, "-pubout", "-out", $pubkey])) # not unlinking $pubkey # not unlinking $selfout +# test -set_issuer option +my $ca_issu = srctop_file(@certs, "ca-cert.pem"); # issuer cert +my $caout_issu = "ca-issu.out"; +ok(run(app(["openssl", "x509", "-new", "-force_pubkey", $key, "-subj", "/CN=EE", + "-set_issuer", "/CN=TEST-CA", "-extfile", $extfile, "-CA", $ca_issu, + "-CAkey", $pkey, "-text", "-out", $caout_issu]))); +ok(get_issuer($caout_issu) =~ /CN=TEST-CA/); +# not unlinking $caout + # simple way of directly producing a CA-signed cert with private/pubkey input my $ca = srctop_file(@certs, "ca-cert.pem"); # issuer cert my $caout = "ca-issued.out"; |