Commit 8d2a17d4e0 for openssl.org

commit 8d2a17d4e043f8d5c2512f9fa5cfa41639dbe20c
Author: Jun Aruga <jaruga@redhat.com>
Date:   Fri Mar 27 18:16:55 2026 +0000

    crypto/pkcs12/p12_add.c: Restore ERR_set_mark and ERR_pop_to_mark

    The commit <2ea6e785f526f88f913cc6f49372aae9dc54bc63> removed the
    ERR_set_mark and ERR_pop_to_mark calls before and after the EVP_CIPHER_fetch
    call in several files.

    However, in PKCS12_pack_p7encdata_ex, crypto/pkcs12/p12_add.c, there is a valid
    case that EVP_CIPHER_fetch returns NULL, raising an error, and calls
    PKCS5_pbe_set_ex. The case is such as PBE-SHA1-3DES.

    PKCS12_pack_p7encdata_ex, crypto/pkcs12/p12_add.c:
    ```
    ...
        pbe_ciph = EVP_CIPHER_fetch(ctx, OBJ_nid2sn(pbe_nid), propq);

        if (pbe_ciph != NULL) {
            pbe = PKCS5_pbe2_set_iv_ex(pbe_ciph, iter, salt, saltlen, NULL, -1, ctx);
        } else {
            pbe = PKCS5_pbe_set_ex(pbe_nid, iter, salt, saltlen, ctx);
        }
    ...
    ```

    So, we need to restore ERR_set_mark and ERR_pop_to_mark calls before and after
    the EVP_CIPHER_fetch call for this case.

    A reproducer is below.

    ```
    $ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -nodes \
      -subj "/CN=Test" 2> /dev/null
    $ openssl pkcs12 \
        -export -in cert.pem -inkey key.pem -out test.p12 -passout pass: \
        -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES
    40276EC7677F0000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:376:Global default library context, Algorithm (PBE-SHA1-3DES : 0), Properties (<null>)
    $ echo $?
    0
    ```

    80-test_pkcs12.t: Add test_pkcs12_passcerts_legacy_outerr2_empty test to test
    this change.

    Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
    Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
    MergeDate: Wed Apr  8 10:09:07 2026
    (Merged from https://github.com/openssl/openssl/pull/30607)

diff --git a/crypto/pkcs12/p12_add.c b/crypto/pkcs12/p12_add.c
index cd6009fd9f..8ea41676d8 100644
--- a/crypto/pkcs12/p12_add.c
+++ b/crypto/pkcs12/p12_add.c
@@ -109,7 +109,9 @@ PKCS7 *PKCS12_pack_p7encdata_ex(int pbe_nid, const char *pass, int passlen,
         goto err;
     }

+    ERR_set_mark();
     pbe_ciph = EVP_CIPHER_fetch(ctx, OBJ_nid2sn(pbe_nid), propq);
+    ERR_pop_to_mark();

     if (pbe_ciph != NULL) {
         pbe = PKCS5_pbe2_set_iv_ex(pbe_ciph, iter, salt, saltlen, NULL, -1, ctx);
diff --git a/test/recipes/80-test_pkcs12.t b/test/recipes/80-test_pkcs12.t
index 7e0fccd08a..d2d6b717e7 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 => $no_fips ? 58 : 63;
+plan tests => 59 + ($no_fips ? 0 : 5);

 # Test different PKCS#12 formats
 ok(run(test(["pkcs12_format_test"])), "test pkcs12 formats");
@@ -107,7 +107,7 @@ SKIP: {
 }

 SKIP: {
-    skip "Skipping legacy PKCS#12 test because the required algorithms are disabled", 1
+    skip "Skipping legacy PKCS#12 test because the required algorithms are disabled", 2
         if disabled("des") || disabled("rc2") || disabled("legacy");
     # Test reading legacy PKCS#12 file
     ok(run(app(["openssl", "pkcs12", "-export",
@@ -115,8 +115,12 @@ SKIP: {
                 "-passin", "pass:v3-certs",
                 "-provider", "default", "-provider", "legacy",
                 "-nokeys", "-passout", "pass:v3-certs", "-descert",
-                "-out", $outfile3])),
+                "-out", $outfile3], stderr => "outerr2.txt")),
     "test_pkcs12_passcerts_legacy");
+    open DATA, "outerr2.txt";
+    my @match = grep /:error:/, <DATA>;
+    close DATA;
+    ok(scalar @match > 0 ? 0 : 1, "test_pkcs12_passcerts_legacy_outerr2_empty");
 }

 # Test export of PEM file with both cert and key