Commit e211f88c64 for openssl.org

commit e211f88c646aaf5dd57cbe13bc0613c605c33894
Author: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Date:   Wed Jul 8 13:29:24 2026 +0200

    apps: test genpkey app cipher option

    Add coverage for encrypting the generated private key with a cipher,
    checking it can only be read back with the correct passphrase, and that
    a cipher is rejected together with the -genparam option.

    Assisted-by: Claude:claude-opus-4-8

    Reviewed-by: Paul Dale <paul.dale@oracle.com>
    Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
    MergeDate: Wed Jul 15 16:03:37 2026
    (Merged from https://github.com/openssl/openssl/pull/31893)

diff --git a/test/recipes/15-test_genpkey.t b/test/recipes/15-test_genpkey.t
index b918f73f9f..ddef803ff1 100644
--- a/test/recipes/15-test_genpkey.t
+++ b/test/recipes/15-test_genpkey.t
@@ -9,7 +9,7 @@
 use strict;
 use warnings;

-use OpenSSL::Test qw/:DEFAULT/;
+use OpenSSL::Test qw/:DEFAULT with/;
 use OpenSSL::Test::Utils;

 setup("test_genpkey");
@@ -22,7 +22,7 @@ push @algs, qw(EC) unless disabled("ec");
 push @algs, qw(X25519 X448) unless disabled("ecx");
 push @algs, qw(SM2) unless disabled("sm2");

-plan tests => scalar(@algs);
+plan tests => scalar(@algs) + 2;

 foreach (@algs) {
     my $alg = $_;
@@ -30,3 +30,40 @@ foreach (@algs) {
     ok(run(app([ 'openssl', 'genpkey', '-algorithm', $alg, '-help'])),
        "show genpkey pkeyopt values for $alg");
 }
+
+SKIP: {
+    skip "RSA is not supported by this OpenSSL build", 1 if disabled("rsa");
+
+    subtest "genpkey with a cipher encrypts the private key" => sub {
+        plan tests => 3;
+
+        my $key = "genpkey_enc.pem";
+
+        ok(run(app(['openssl', 'genpkey', '-algorithm', 'RSA',
+                    '-pkeyopt', 'rsa_keygen_bits:512',
+                    '-aes256', '-pass', 'pass:secret', '-out', $key])),
+           "Generate an AES-256 encrypted RSA key");
+        ok(run(app(['openssl', 'pkey', '-in', $key,
+                    '-passin', 'pass:secret', '-noout'])),
+           "Read the encrypted key back with the correct passphrase");
+        # A wrong passphrase must not decrypt the key.
+        with({ exit_checker => sub { return shift == 1; } },
+            sub {
+                ok(run(app(['openssl', 'pkey', '-in', $key,
+                            '-passin', 'pass:wrong', '-noout'])),
+                   "Reading with a wrong passphrase fails");
+            });
+    };
+}
+
+SKIP: {
+    skip "DSA is not supported by this OpenSSL build", 1 if disabled("dsa");
+
+    # A cipher only encrypts a private key, so it is rejected with -genparam.
+    with({ exit_checker => sub { return shift == 1; } },
+        sub {
+            ok(run(app(['openssl', 'genpkey', '-genparam', '-algorithm', 'DSA',
+                        '-pkeyopt', 'dsa_paramgen_bits:512', '-aes256'])),
+               "Cannot use a cipher with -genparam");
+        });
+}