Enable openssl req -x509 to create certificates from CSRs
authorHugo Landau <hlandau@openssl.org>
Tue, 1 Mar 2022 12:55:03 +0000 (12:55 +0000)
committerTomas Mraz <tomas@openssl.org>
Thu, 3 Mar 2022 09:21:51 +0000 (10:21 +0100)
`openssl req -x509` has code allowing it to generate certificates from CSRs
as a replacement for `openssl x509`, but a bug prevents it from working
properly. -CA and -CAkey can now be passed to generate a CA-signed
certificate as documented in openssl-req(1).

Regression testing has been added to `openssl req`.

Fixes #17736.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17782)

apps/req.c
test/recipes/25-test_req.t

index 76b337f6bc8e1837f6b92f3fda98916e771c1918..7e59e673e0296e71bece72870db7d78aa50dab1f 100644 (file)
@@ -765,8 +765,9 @@ int req_main(int argc, char **argv)
         }
     }
     if (newreq || gen_x509) {
-        if (pkey == NULL /* can happen only if !newreq */) {
-            BIO_printf(bio_err, "Must provide a signature key using -key\n");
+        if (CAcert == NULL && pkey == NULL) {
+            BIO_printf(bio_err, "Must provide a signature key using -key or"
+                " provide -CA / -CAkey\n");
             goto end;
         }
 
index c1587b76d75babbc04419ee4df7e9eb10d32e1c8..ca70adf5774d69d4f79d198271ea6119a0a8aaa1 100644 (file)
@@ -15,7 +15,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/;
 
 setup("test_req");
 
-plan tests => 91;
+plan tests => 92;
 
 require_ok(srctop_file('test', 'recipes', 'tconversion.pl'));
 
@@ -49,6 +49,11 @@ ok(!run(app([@addext_args, "-addext", $val, "-addext", $val2])));
 ok(!run(app([@addext_args, "-addext", $val, "-addext", $val3])));
 ok(!run(app([@addext_args, "-addext", $val2, "-addext", $val3])));
 
+# If a CSR is provided with neither of -key or -CA/-CAkey, this should fail.
+ok(!run(app(["openssl", "req", "-x509",
+                "-in", srctop_file(@certs, "x509-check.csr"),
+                "-out", "testreq.pem"])));
+
 subtest "generating alt certificate requests with RSA" => sub {
     plan tests => 3;
 
@@ -383,7 +388,8 @@ sub generate_cert {
     my $ca_key = srctop_file(@certs, "ca-key.pem");
     my $key = $is_ca ? $ca_key : srctop_file(@certs, "ee-key.pem");
     my @cmd = ("openssl", "req", "-config", "", "-x509",
-               "-key", $key, "-subj", "/CN=$cn", @_, "-out", $cert);
+               "-subj", "/CN=$cn", @_, "-out", $cert);
+    push(@cmd, ("-key", $key)) if $ss;
     push(@cmd, ("-CA", $ca_cert, "-CAkey", $ca_key)) unless $ss;
     ok(run(app([@cmd])), "generate $cert");
 }
@@ -551,9 +557,11 @@ cert_ext_has_n_different_lines($cert, 6, $SKID_AKID); # SKID != AKID, both force
 # AKID of not self-issued certs
 
 $cert = "regular_v3_EE_default_KIDs.pem";
-generate_cert($cert, "-addext", "keyUsage = dataEncipherment");
+generate_cert($cert, "-addext", "keyUsage = dataEncipherment",
+    "-key", srctop_file(@certs, "ee-key.pem"));
 cert_ext_has_n_different_lines($cert, 4, $SKID_AKID); # SKID != AKID
 strict_verify($cert, 1, $ca_cert);
+
 $cert = "regular_v3_EE_copied_exts_default_KIDs.pem";
 generate_cert($cert, "-copy_extensions", "copy",
               "-in", srctop_file(@certs, "ext-check.csr"));
@@ -561,7 +569,8 @@ cert_ext_has_n_different_lines($cert, 4, $SKID_AKID); # SKID != AKID
 strict_verify($cert, 1);
 
 $cert = "v3_EE_no_AKID.pem";
-generate_cert($cert, "-addext", "authorityKeyIdentifier = none");
+generate_cert($cert, "-addext", "authorityKeyIdentifier = none",
+    "-key", srctop_file(@certs, "ee-key.pem"));
 has_SKID($cert, 1);
 has_AKID($cert, 0);
 strict_verify($cert, 0, $ca_cert);