fix x509 -force_pubkey option to take effect with cert input or self-signing; improve...
authorDavid von Oheimb <David.von.Oheimb@siemens.com>
Sun, 3 Feb 2019 06:57:59 +0000 (07:57 +0100)
committerMatt Caswell <matt@openssl.org>
Mon, 25 Feb 2019 10:26:23 +0000 (10:26 +0000)
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8165)

apps/x509.c
doc/man1/x509.pod

index e9de495..e4d5e07 100644 (file)
@@ -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)
index 75919ca..251e3f7 100644 (file)
@@ -52,7 +52,7 @@ B<openssl> B<x509>
 [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<x509v3_config(5)> 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<key> 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<filename>
+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<key> can be specified using the B<-keyform> option.
+The format of the key file can be specified using the B<-keyform> option.
 
 =back