From: David von Oheimb Date: Sun, 3 Feb 2019 06:57:59 +0000 (+0100) Subject: fix x509 -force_pubkey option to take effect with cert input or self-signing; improve... X-Git-Tag: openssl-3.0.0-alpha1~2480 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=56a98c3efde3a49084a232a56aa666533362f1a2 fix x509 -force_pubkey option to take effect with cert input or self-signing; improve its doc Reviewed-by: Viktor Dukhovni Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/8165) --- diff --git a/apps/x509.c b/apps/x509.c index e9de4950f9..e4d5e079dd 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -33,7 +33,7 @@ #define DEF_DAYS 30 static int callb(int ok, X509_STORE_CTX *ctx); -static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, +static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey, int days, int clrext, const EVP_MD *digest, CONF *conf, const char *section, int preserve_dates); static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *digest, @@ -132,7 +132,7 @@ const OPTIONS x509_options[] = { {"CAform", OPT_CAFORM, 'F', "CA format - default PEM"}, {"CAkeyform", OPT_CAKEYFORM, 'f', "CA key format - default PEM"}, {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, - {"force_pubkey", OPT_FORCE_PUBKEY, '<', "Force the Key to put inside certificate"}, + {"force_pubkey", OPT_FORCE_PUBKEY, '<', "Force the key to put inside certificate"}, {"next_serial", OPT_NEXT_SERIAL, '-', "Increment current certificate serial number"}, {"clrreject", OPT_CLRREJECT, '-', "Clears all the prohibited or rejected uses of the certificate"}, @@ -574,18 +574,16 @@ int x509_main(int argc, char **argv) if (!set_cert_times(x, NULL, NULL, days)) goto end; - if (fkey != NULL) { - X509_set_pubkey(x, fkey); - } else { - pkey = X509_REQ_get0_pubkey(req); - X509_set_pubkey(x, pkey); - } + if (!X509_set_pubkey(x, fkey != NULL ? fkey : X509_REQ_get0_pubkey(req))) + goto end; } else { x = load_cert(infile, informat, "Certificate"); + if (x == NULL) + goto end; + if (fkey != NULL && !X509_set_pubkey(x, fkey)) + goto end; } - if (x == NULL) - goto end; if (CA_flag) { xca = load_cert(CAfile, CAformat, "CA Certificate"); if (xca == NULL) @@ -799,7 +797,8 @@ int x509_main(int argc, char **argv) goto end; } - if (!sign(x, Upkey, days, clrext, digest, extconf, extsect, preserve_dates)) + if (!sign(x, Upkey, fkey, days, clrext, digest, extconf, + extsect, preserve_dates)) goto end; } else if (CA_flag == i) { BIO_printf(bio_err, "Getting CA Private Key\n"); @@ -1054,8 +1053,8 @@ static int callb(int ok, X509_STORE_CTX *ctx) } } -/* self sign */ -static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, +/* self-issue; self-sign unless a forced public key (fkey) is given */ +static int sign(X509 *x, EVP_PKEY *pkey, EVP_PKEY *fkey, int days, int clrext, const EVP_MD *digest, CONF *conf, const char *section, int preserve_dates) { @@ -1064,7 +1063,7 @@ static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, goto err; if (!preserve_dates && !set_cert_times(x, NULL, NULL, days)) goto err; - if (!X509_set_pubkey(x, pkey)) + if (fkey == NULL && !X509_set_pubkey(x, pkey)) goto err; if (clrext) { while (X509_get_ext_count(x) > 0) diff --git a/doc/man1/x509.pod b/doc/man1/x509.pod index 75919ca75f..251e3f7a05 100644 --- a/doc/man1/x509.pod +++ b/doc/man1/x509.pod @@ -52,7 +52,7 @@ B B [B<-CAkey filename>] [B<-CAcreateserial>] [B<-CAserial filename>] -[B<-force_pubkey key>] +[B<-force_pubkey filename>] [B<-text>] [B<-ext extensions>] [B<-certopt option>] @@ -140,8 +140,9 @@ for all available algorithms. =item B<-preserve_dates> -When signing a certificate, preserve the "notBefore" and "notAfter" dates instead -of adjusting them to current time and duration. Cannot be used with the B<-days> option. +When signing a certificate, preserve the "notBefore" and "notAfter" dates +instead of adjusting them to current time and duration. +Cannot be used with the B<-days> option. =back @@ -354,17 +355,12 @@ can thus behave like a "mini CA". This option causes the input file to be self signed using the supplied private key. -If the input file is a certificate it sets the issuer name to the -subject name (i.e. makes it self signed) changes the public key to the -supplied value and changes the start and end dates. The start date is -set to the current time and the end date is set to a value determined -by the B<-days> option. Any certificate extensions are retained unless -the B<-clrext> option is supplied; this includes, for example, any existing -key identifier extensions. - -If the input is a certificate request then a self signed certificate -is created using the supplied private key using the subject name in -the request. +It sets the issuer name to the subject name (i.e., makes it self-issued) +and changes the public key to the supplied value (unless overridden by +B<-force_pubkey>). It sets the validity start date to the current time +and the end date to a value determined by the B<-days> option. +It retains any certificate extensions unless the B<-clrext> option is supplied; +this includes, for example, any existing key identifier extensions. =item B<-passin arg> @@ -458,14 +454,14 @@ specified then the extensions should either be contained in the unnamed L manual page for details of the extension section format. -=item B<-force_pubkey key> +=item B<-force_pubkey filename> -When a certificate is created set its public key to B instead of the -key in the certificate or certificate request. This option is useful for -creating certificates where the algorithm can't normally sign requests, for -example DH. +When a certificate is created set its public key to the key in B +instead of the key contained in the input or given with the B<-signkey> option. +This option is useful for creating self-issued certificates that are not +self-signed, for instance when the key cannot be used for signing, such as DH. -The format or B can be specified using the B<-keyform> option. +The format of the key file can be specified using the B<-keyform> option. =back