Commit 59471367e3 for openssl.org

commit 59471367e33daa080025280dce833b7e4a2a3154
Author: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Date:   Tue Sep 1 19:47:40 2026 +0200

    apps: cover the -extfile option in the ca recipe

    Sign a request taking the X509v3 extensions from a separate
    extension file, both via its default section and with a section
    explicitly selected using the -extensions option, and check that
    the extensions from the chosen section end up in the certificate.

    Assisted-by: Claude:claude-fable-5
    Reviewed-by: Paul Dale <paul.dale@oracle.com>
    Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
    Merge-date: Mon Sep  7 18:11:16 2026
    Merged-from: https://github.com/openssl/openssl/pull/32632

diff --git a/test/recipes/80-test_ca.t b/test/recipes/80-test_ca.t
index 95e21b92ab..adb9ff8514 100644
--- a/test/recipes/80-test_ca.t
+++ b/test/recipes/80-test_ca.t
@@ -29,7 +29,7 @@ sub src_file {

 rmtree("demoCA", { safe => 0 });

-plan tests => 20;
+plan tests => 28;

 require_ok(srctop_file("test", "recipes", "tconversion.pl"));

@@ -87,6 +87,12 @@ has_version($v3_cert, 3);
 has_SKID($v3_cert, 1);
 has_AKID($v3_cert, 1);

+# Sign with X509v3 extensions from a separate -extfile, once using its
+# default section and once with a section selected via -extensions.
+test_extfile('extfile_default', [], qr/Digital Signature/);
+test_extfile('extfile_section', ['-extensions', 'alt_ext'],
+             qr/Key Encipherment/);
+
 test_revoke('notimes', {
     should_succeed => 1,
 });
@@ -125,6 +131,45 @@ test_revoke('both_generalizedtime', {
     should_succeed => 1,
 });

+sub test_extfile {
+    my ($filename, $ca_opts, $keyusage_re) = @_;
+
+    $ENV{CN2} = $filename;
+    ok(
+        run(app(['openssl',
+                 'req',
+                 '-config',  $cnf,
+                 '-new',
+                 '-key',     data_file('revoked.key'),
+                 '-out',     "$filename-req.pem",
+                 '-section', 'userreq',
+        ])),
+        "Generate CSR: $filename"
+    );
+    delete $ENV{CN2};
+
+    ok(
+        run(app(['openssl',
+                 'ca',
+                 '-batch',
+                 '-config',  $cnf,
+                 '-extfile', data_file('extensions.cnf'),
+                 @$ca_opts,
+                 '-in',      "$filename-req.pem",
+                 '-out',     "$filename-cert.pem",
+        ])),
+        "Sign CSR with -extfile: $filename"
+    );
+
+    has_version("$filename-cert.pem", 3);
+
+    my $keyusage = join('',
+        run(app(['openssl', 'x509', '-in', "$filename-cert.pem",
+                 '-noout', '-ext', 'keyUsage']), capture => 1));
+    ok($keyusage =~ $keyusage_re,
+       "keyUsage taken from the extfile: $filename");
+}
+
 sub test_revoke {
     my ($filename, $opts) = @_;

diff --git a/test/recipes/80-test_ca_data/extensions.cnf b/test/recipes/80-test_ca_data/extensions.cnf
new file mode 100644
index 0000000000..ebfd15019c
--- /dev/null
+++ b/test/recipes/80-test_ca_data/extensions.cnf
@@ -0,0 +1,10 @@
+extensions = default_ext
+
+[ default_ext ]
+basicConstraints = CA:false
+subjectKeyIdentifier = hash
+keyUsage = digitalSignature
+
+[ alt_ext ]
+basicConstraints = CA:false
+keyUsage = keyEncipherment