From: Jun Aruga Date: Fri, 27 Mar 2026 18:16:55 +0000 (+0000) Subject: crypto/pkcs12/p12_add.c: Restore ERR_set_mark and ERR_pop_to_mark X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8d2a17d4e043f8d5c2512f9fa5cfa41639dbe20c;p=thirdparty%2Fopenssl.git 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 () $ echo $? 0 ``` 80-test_pkcs12.t: Add test_pkcs12_passcerts_legacy_outerr2_empty test to test this change. Reviewed-by: Dmitry Belyavskiy Reviewed-by: Shane Lontis 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 cd6009fd9f4..8ea41676d80 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 7e0fccd08af..d2d6b717e7f 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:/, ; + close DATA; + ok(scalar @match > 0 ? 0 : 1, "test_pkcs12_passcerts_legacy_outerr2_empty"); } # Test export of PEM file with both cert and key