diff options
author | Michael Baentsch <57787676+baentsch@users.noreply.github.com> | 2023-09-22 17:52:09 +0200 |
---|---|---|
committer | Dmitry Belyavskiy <beldmit@gmail.com> | 2023-09-24 20:51:42 +0200 |
commit | 6c03fa21ed4bbc9fd6d3013fdf9f4646d231f831 (patch) | |
tree | 991eabe28a9a72a3aaa9332d88ac9584a1e925c0 | |
parent | 1acc3e8cc3c69187b55cc557c1bc03278ab38063 (diff) |
adding -outpubkey option to genpkey
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22173)
-rw-r--r-- | apps/genpkey.c | 26 | ||||
-rw-r--r-- | doc/man1/openssl-genpkey.pod.in | 18 | ||||
-rw-r--r-- | test/recipes/15-test_genec.t | 4 |
3 files changed, 36 insertions, 12 deletions
diff --git a/apps/genpkey.c b/apps/genpkey.c index 080f1f6075..66f0e1eaf0 100644 --- a/apps/genpkey.c +++ b/apps/genpkey.c @@ -23,7 +23,7 @@ typedef enum OPTION_choice { OPT_COMMON, OPT_ENGINE, OPT_OUTFORM, OPT_OUT, OPT_PASS, OPT_PARAMFILE, OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER, - OPT_VERBOSE, OPT_QUIET, OPT_CONFIG, + OPT_VERBOSE, OPT_QUIET, OPT_CONFIG, OPT_OUTPUBKEY, OPT_PROV_ENUM } OPTION_CHOICE; @@ -42,11 +42,12 @@ const OPTIONS genpkey_options[] = { OPT_CONFIG_OPTION, OPT_SECTION("Output"), - {"out", OPT_OUT, '>', "Output file"}, + {"out", OPT_OUT, '>', "Output (private key) file"}, + {"outpubkey", OPT_OUTPUBKEY, '>', "Output public key file"}, {"outform", OPT_OUTFORM, 'F', "output format (DER or PEM)"}, {"pass", OPT_PASS, 's', "Output file pass phrase source"}, {"genparam", OPT_GENPARAM, '-', "Generate parameters, not key"}, - {"text", OPT_TEXT, '-', "Print the in text"}, + {"text", OPT_TEXT, '-', "Print the private key in text"}, {"", OPT_CIPHER, '-', "Cipher to use to encrypt the key"}, OPT_PROV_OPTIONS, @@ -104,11 +105,12 @@ cleanup: int genpkey_main(int argc, char **argv) { CONF *conf = NULL; - BIO *in = NULL, *out = NULL; + BIO *in = NULL, *out = NULL, *outpubkey = NULL; ENGINE *e = NULL; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; char *outfile = NULL, *passarg = NULL, *pass = NULL, *prog, *p; + char *outpubkeyfile = NULL; const char *ciphername = NULL, *paramfile = NULL, *algname = NULL; EVP_CIPHER *cipher = NULL; OPTION_CHOICE o; @@ -141,6 +143,9 @@ int genpkey_main(int argc, char **argv) case OPT_OUT: outfile = opt_arg(); break; + case OPT_OUTPUBKEY: + outpubkeyfile = opt_arg(); + break; case OPT_PASS: passarg = opt_arg(); break; @@ -228,6 +233,12 @@ int genpkey_main(int argc, char **argv) if (out == NULL) goto end; + if (outpubkeyfile != NULL) { + outpubkey = bio_open_owner(outpubkeyfile, outformat, private); + if (outpubkey == NULL) + goto end; + } + if (verbose) EVP_PKEY_CTX_set_cb(ctx, progress_cb); EVP_PKEY_CTX_set_app_data(ctx, bio_err); @@ -242,9 +253,13 @@ int genpkey_main(int argc, char **argv) } else if (outformat == FORMAT_PEM) { assert(private); rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, pass); + if (rv > 0 && outpubkey != NULL) + rv = PEM_write_bio_PUBKEY(outpubkey, pkey); } else if (outformat == FORMAT_ASN1) { assert(private); rv = i2d_PrivateKey_bio(out, pkey); + if (rv > 0 && outpubkey != NULL) + rv = i2d_PUBKEY_bio(outpubkey, pkey); } else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; @@ -253,7 +268,7 @@ int genpkey_main(int argc, char **argv) ret = 0; if (rv <= 0) { - BIO_puts(bio_err, "Error writing key\n"); + BIO_puts(bio_err, "Error writing key(s)\n"); ret = 1; } @@ -277,6 +292,7 @@ int genpkey_main(int argc, char **argv) EVP_PKEY_CTX_free(ctx); EVP_CIPHER_free(cipher); BIO_free_all(out); + BIO_free_all(outpubkey); BIO_free(in); release_engine(e); OPENSSL_free(pass); diff --git a/doc/man1/openssl-genpkey.pod.in b/doc/man1/openssl-genpkey.pod.in index e760d613fe..aa0b74e8aa 100644 --- a/doc/man1/openssl-genpkey.pod.in +++ b/doc/man1/openssl-genpkey.pod.in @@ -7,13 +7,14 @@ =head1 NAME -openssl-genpkey - generate a private key +openssl-genpkey - generate a private key or key pair =head1 SYNOPSIS B<openssl> B<genpkey> [B<-help>] [B<-out> I<filename>] +[B<-outpubkey> I<filename>] [B<-outform> B<DER>|B<PEM>] [B<-verbose>] [B<-quiet>] @@ -29,7 +30,7 @@ B<openssl> B<genpkey> =head1 DESCRIPTION -This command generates a private key. +This command generates a private key or key pair. =head1 OPTIONS @@ -41,8 +42,13 @@ Print out a usage message. =item B<-out> I<filename> -Output the key to the specified file. If this argument is not specified then -standard output is used. +Output the private key to the specified file. If this argument is not +specified then standard output is used. + +=item B<-outpubkey> I<filename> + +Output the public key to the specified file. If this argument is not +specified then the public key is not output. =item B<-outform> B<DER>|B<PEM> @@ -73,8 +79,8 @@ name accepted by EVP_get_cipherbyname() is acceptable such as B<des3>. Public key algorithm to use such as RSA, DSA, DH or DHX. If used this option must precede any B<-pkeyopt> options. The options B<-paramfile> and B<-algorithm> -are mutually exclusive. Engines may add algorithms in addition to the standard -built-in ones. +are mutually exclusive. Engines or providers may add algorithms in addition to +the standard built-in ones. Valid built-in algorithm names for private key generation are RSA, RSA-PSS, EC, X25519, X448, ED25519 and ED448. diff --git a/test/recipes/15-test_genec.t b/test/recipes/15-test_genec.t index 2dfed387ca..3e8c55071c 100644 --- a/test/recipes/15-test_genec.t +++ b/test/recipes/15-test_genec.t @@ -232,13 +232,15 @@ foreach my $curvename (@curve_list) { foreach my $outform (@output_formats) { my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform; + my $outpubfile = "ecgen.${curvename}.${paramenc}-pub." . lc $outform; $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (${outform})", app([ 'openssl', 'genpkey', '-algorithm', 'EC', '-pkeyopt', 'ec_paramgen_curve:'.$curvename, '-pkeyopt', 'ec_param_enc:'.$paramenc, '-outform', $outform, - '-out', $outfile])); + '-out', $outfile, + '-outpubkey', $outpubfile])); } } } |