From 00835009270b823fc73bcd7d1acafc00f44bd0ce Mon Sep 17 00:00:00 2001 From: slontis Date: Wed, 5 Nov 2025 12:20:37 +1100 Subject: [PATCH] PKCS12_set_pbmac1_pbkdf2() fixups. Adding a test that called PKCS12_set_pbmac1_pbkdf2() with a saltlen of zero, pointed out that the libctx and propq were not being propagated. Reviewed-by: Dmitry Belyavskiy Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/29068) --- crypto/pkcs12/p12_mutl.c | 51 +++++++++++++++++++++++----------------- test/pkcs12_api_test.c | 28 ++++++++++++++++++++++ 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c index d2d8ffc35bb..f28a0d9d368 100644 --- a/crypto/pkcs12/p12_mutl.c +++ b/crypto/pkcs12/p12_mutl.c @@ -26,7 +26,8 @@ static int pkcs12_pbmac1_pbkdf2_key_gen(const char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int keylen, unsigned char *out, - const EVP_MD *md_type); + const EVP_MD *md_type, + OSSL_LIB_CTX *libctx, const char *propq); int PKCS12_mac_present(const PKCS12 *p12) { @@ -160,7 +161,9 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, unsigned char *salt, int slen, int id, int iter, int n, unsigned char *out, - const EVP_MD *md_type)) + const EVP_MD *md_type, + OSSL_LIB_CTX *libctx, + const char *propq)) { int ret = 0; const EVP_MD *md; @@ -173,6 +176,8 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, int md_nid = NID_undef; const X509_ALGOR *macalg; const ASN1_OBJECT *macoid; + OSSL_LIB_CTX *libctx; + const char *propq; if (!PKCS7_type_is_data(p12->authsafes)) { ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA); @@ -184,6 +189,8 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, return 0; } + libctx = p12->authsafes->ctx.libctx; + propq = p12->authsafes->ctx.propq; salt = p12->mac->salt->data; saltlen = p12->mac->salt->length; if (p12->mac->iter == NULL) @@ -200,8 +207,7 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, return 0; } (void)ERR_set_mark(); - md = md_fetch = EVP_MD_fetch(p12->authsafes->ctx.libctx, md_name, - p12->authsafes->ctx.propq); + md = md_fetch = EVP_MD_fetch(libctx, md_name, propq); if (md == NULL) md = EVP_get_digestbynid(OBJ_obj2nid(macoid)); @@ -219,8 +225,7 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, /* For PBMAC1 we use a special keygen callback if not provided (e.g. on verification) */ if (pbmac1_md_nid != NID_undef && pkcs12_key_gen == NULL) { - keylen = PBMAC1_PBKDF2_HMAC(p12->authsafes->ctx.libctx, p12->authsafes->ctx.propq, - pass, passlen, macalg, key); + keylen = PBMAC1_PBKDF2_HMAC(libctx, propq, pass, passlen, macalg, key); if (keylen < 0) goto err; } else if ((md_nid == NID_id_GostR3411_94 @@ -242,14 +247,14 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, if (OBJ_obj2txt(hmac_md_name, sizeof(hmac_md_name), OBJ_nid2obj(pbmac1_kdf_nid), 0) < 0) goto err; - hmac_md = EVP_MD_fetch(NULL, hmac_md_name, NULL); + hmac_md = EVP_MD_fetch(libctx, hmac_md_name, propq); if (hmac_md == NULL) goto err; fetched = 1; } if (pkcs12_key_gen != NULL) { int res = (*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_MAC_ID, - iter, keylen, key, hmac_md); + iter, keylen, key, hmac_md, libctx, propq); if (fetched) EVP_MD_free(hmac_md); @@ -262,8 +267,7 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, EVP_MD_free(hmac_md); /* Default to UTF-8 password */ if (!PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, PKCS12_MAC_ID, - iter, keylen, key, md, - p12->authsafes->ctx.libctx, p12->authsafes->ctx.propq)) { + iter, keylen, key, md, libctx, propq)) { ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); goto err; } @@ -377,10 +381,11 @@ static int pkcs12_pbmac1_pbkdf2_key_gen(const char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int keylen, unsigned char *out, - const EVP_MD *md_type) + const EVP_MD *md_type, + OSSL_LIB_CTX *libctx, const char *propq) { - return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, - md_type, keylen, out); + return ossl_pkcs5_pbkdf2_hmac_ex(pass, passlen, salt, saltlen, iter, md_type, + keylen, out, libctx, propq); } static int pkcs12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, @@ -447,6 +452,7 @@ int PKCS12_set_pbmac1_pbkdf2(PKCS12 *p12, const char *pass, int passlen, int keylen = 0; PBMAC1PARAM *param = NULL; X509_ALGOR *hmac_alg = NULL, *macalg = NULL; + OSSL_LIB_CTX *libctx = p12->authsafes->ctx.libctx; if (md_type == NULL) /* No need to do a fetch as the md_type is used only to get a NID */ @@ -471,23 +477,26 @@ int PKCS12_set_pbmac1_pbkdf2(PKCS12 *p12, const char *pass, int passlen, } if (salt == NULL) { - if (saltlen <= 0) { + if (saltlen < 0) { ERR_raise(ERR_LIB_PKCS12, PKCS12_R_INVALID_SALT_LENGTH); goto err; } - known_salt = OPENSSL_malloc(saltlen); - if (known_salt == NULL) - goto err; + if (saltlen > 0) { + known_salt = OPENSSL_malloc(saltlen); + if (known_salt == NULL) + goto err; - if (RAND_bytes_ex(NULL, known_salt, saltlen, 0) <= 0) { - ERR_raise(ERR_LIB_PKCS12, ERR_R_RAND_LIB); - goto err; + if (RAND_bytes_ex(libctx, known_salt, saltlen, 0) <= 0) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_RAND_LIB); + goto err; + } } } param = PBMAC1PARAM_new(); hmac_alg = X509_ALGOR_new(); - alg = PKCS5_pbkdf2_set(iter, salt ? salt : known_salt, saltlen, prf_nid, keylen); + alg = PKCS5_pbkdf2_set_ex(iter, salt ? salt : known_salt, saltlen, + prf_nid, keylen, libctx); if (param == NULL || hmac_alg == NULL || alg == NULL) goto err; diff --git a/test/pkcs12_api_test.c b/test/pkcs12_api_test.c index 5afef5a16ad..e2f9edbb982 100644 --- a/test/pkcs12_api_test.c +++ b/test/pkcs12_api_test.c @@ -253,6 +253,33 @@ const OPTIONS *test_get_options(void) return options; } +static int test_PKCS12_set_pbmac1_pbkdf2_saltlen_zero(void) +{ + int ret = 0; + EVP_PKEY *key = NULL; + X509 *cert = NULL; + STACK_OF(X509) *ca = NULL; + PKCS12 *p12 = NULL; + + if (!TEST_ptr(p12 = PKCS12_load(in_file))) + return 0; + if (!TEST_true(PKCS12_parse(p12, in_pass, &key, &cert, &ca))) + goto err; + PKCS12_free(p12); + + if (!TEST_ptr(p12 = PKCS12_create_ex2("pass", NULL, key, cert, ca, + NID_undef, NID_undef, 0, -1, 0, + testctx, NULL, NULL, NULL))) + goto err; + ret = TEST_true(PKCS12_set_pbmac1_pbkdf2(p12, "pass", -1, NULL, 0, 0, NULL, NULL)); +err: + PKCS12_free(p12); + EVP_PKEY_free(key); + X509_free(cert); + OSSL_STACK_OF_X509_free(ca); + return ret; +} + int setup_tests(void) { OPTION_CHOICE o; @@ -292,6 +319,7 @@ int setup_tests(void) ADD_TEST(test_null_args); ADD_TEST(pkcs12_parse_test); ADD_ALL_TESTS(pkcs12_create_ex2_test, 3); + ADD_TEST(test_PKCS12_set_pbmac1_pbkdf2_saltlen_zero); return 1; } -- 2.47.3