Commit f7ec8c5d5c for openssl.org

commit f7ec8c5d5cfb7c375737f48b154d50a83733e1e1
Author: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Date:   Tue Jul 14 19:41:58 2026 +0200

    apps: test pkcs12 -clcerts/-cacerts and -name options

    The -clcerts and -cacerts certificate filtering and the -name friendly
    name option of the pkcs12 app were not exercised by any test. Add a
    subtest that exports a PKCS#12 holding a client cert (with a localKeyID),
    a CA cert and a friendly name, then checks the friendly name is present,
    that -clcerts outputs only the client certificate and -cacerts only the
    CA certificate.

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

    Reviewed-by: Paul Dale <paul.dale@oracle.com>
    Reviewed-by: Andrew Dinh <andrewd@openssl.org>
    Reviewed-by: Daniel Kubec <kubec@openssl.foundation>
    MergeDate: Mon Jul 27 09:09:09 2026
    (Merged from https://github.com/openssl/openssl/pull/31956)

diff --git a/test/recipes/80-test_pkcs12.t b/test/recipes/80-test_pkcs12.t
index 5e9838d107..37a86e77f3 100644
--- a/test/recipes/80-test_pkcs12.t
+++ b/test/recipes/80-test_pkcs12.t
@@ -56,7 +56,7 @@ $ENV{OPENSSL_WIN32_UTF8}=1;

 my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);

-plan tests => 64 + ($no_fips ? 0 : 5);
+plan tests => 65 + ($no_fips ? 0 : 5);

 # Test different PKCS#12 formats
 ok(run(test(["pkcs12_format_test"])), "test pkcs12 formats");
@@ -322,6 +322,50 @@ with({ exit_checker => sub { return shift == 1; } },
     delete $ENV{OPENSSL_CONF}
 }

+# Test -clcerts/-cacerts cert filtering and the -name friendly name.
+subtest "pkcs12 -clcerts/-cacerts filtering and -name" => sub {
+    plan tests => 7;
+
+    # A PKCS#12 with a key + matching EE cert (gets a localKeyID) and a CA
+    # cert added via -certfile (no localKeyID), plus a friendly name.
+    my $mixed = "mixed.p12";
+    ok(run(app(["openssl", "pkcs12", "-export",
+                "-inkey", srctop_file(@path, "ee-key.pem"),
+                "-in", srctop_file(@path, "ee-cert.pem"),
+                "-certfile", srctop_file(@path, "ca-cert.pem"),
+                "-name", "Friendly Client",
+                "-passout", "pass:", "-out", $mixed])),
+       "export a PKCS#12 with a client cert, a CA cert and a friendly name");
+
+    # -name sets the friendly name, visible in -info output.
+    my @info = run(app(["openssl", "pkcs12", "-in", $mixed, "-info", "-nokeys",
+                        "-passin", "pass:"]), capture => 1);
+    ok(grep(/friendlyName: Friendly Client/, @info) == 1,
+       "the -name friendly name is present in the output");
+
+    # Without filtering both certificates are dumped.
+    my @all = run(app(["openssl", "pkcs12", "-in", $mixed, "-nokeys",
+                       "-passin", "pass:"]), capture => 1);
+    ok(grep(/BEGIN CERTIFICATE/, @all) == 2,
+       "both certificates are output without filtering");
+
+    # -clcerts outputs only the client (leaf) certificate.
+    my @cl = run(app(["openssl", "pkcs12", "-in", $mixed, "-nokeys", "-clcerts",
+                      "-passin", "pass:"]), capture => 1);
+    ok(grep(/BEGIN CERTIFICATE/, @cl) == 1,
+       "-clcerts outputs a single certificate");
+    ok(grep(/subject=CN\s*=\s*server\.example/, @cl) == 1,
+       "-clcerts outputs the client certificate");
+
+    # -cacerts outputs only the CA certificate.
+    my @ca = run(app(["openssl", "pkcs12", "-in", $mixed, "-nokeys", "-cacerts",
+                      "-passin", "pass:"]), capture => 1);
+    ok(grep(/BEGIN CERTIFICATE/, @ca) == 1,
+       "-cacerts outputs a single certificate");
+    ok(grep(/subject=CN\s*=\s*CA\b/, @ca) == 1,
+       "-cacerts outputs the CA certificate");
+};
+
 # Tests for pkcs12_parse
 ok(run(test(["pkcs12_api_test",
              "-in", $outfile1,