From e6e479521be51254c68225e8e9256dfb5037c8b0 Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Mon, 29 Jan 2024 13:30:00 +0100 Subject: [PATCH] Denial of service via null dereference in PKCS#12 Resolves: RHEL-22486 --- 0135-CVE-2024-0727.patch | 178 +++++++++++++++++++++++++++++++++++++++ openssl.spec | 4 + 2 files changed, 182 insertions(+) create mode 100644 0135-CVE-2024-0727.patch diff --git a/0135-CVE-2024-0727.patch b/0135-CVE-2024-0727.patch new file mode 100644 index 0000000..ddebf85 --- /dev/null +++ b/0135-CVE-2024-0727.patch @@ -0,0 +1,178 @@ +diff --git a/crypto/pkcs12/p12_add.c b/crypto/pkcs12/p12_add.c +index 6fd4184af5a52..80ce31b3bca66 100644 +--- a/crypto/pkcs12/p12_add.c ++++ b/crypto/pkcs12/p12_add.c +@@ -78,6 +78,12 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7) + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA); + return NULL; + } ++ ++ if (p7->d.data == NULL) { ++ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR); ++ return NULL; ++ } ++ + return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS)); + } + +@@ -150,6 +156,12 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + { + if (!PKCS7_type_is_encrypted(p7)) + return NULL; ++ ++ if (p7->d.encrypted == NULL) { ++ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR); ++ return NULL; ++ } ++ + return PKCS12_item_decrypt_d2i_ex(p7->d.encrypted->enc_data->algorithm, + ASN1_ITEM_rptr(PKCS12_SAFEBAGS), + pass, passlen, +@@ -188,6 +200,12 @@ STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12) + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA); + return NULL; + } ++ ++ if (p12->authsafes->d.data == NULL) { ++ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR); ++ return NULL; ++ } ++ + p7s = ASN1_item_unpack(p12->authsafes->d.data, + ASN1_ITEM_rptr(PKCS12_AUTHSAFES)); + if (p7s != NULL) { +diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c +index 67a885a45f89e..68ff54d0e90ee 100644 +--- a/crypto/pkcs12/p12_mutl.c ++++ b/crypto/pkcs12/p12_mutl.c +@@ -98,6 +98,11 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + return 0; + } + ++ if (p12->authsafes->d.data == NULL) { ++ ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR); ++ return 0; ++ } ++ + salt = p12->mac->salt->data; + saltlen = p12->mac->salt->length; + if (p12->mac->iter == NULL) +diff --git a/crypto/pkcs12/p12_npas.c b/crypto/pkcs12/p12_npas.c +index 62230bc6187ff..1e5b5495991a4 100644 +--- a/crypto/pkcs12/p12_npas.c ++++ b/crypto/pkcs12/p12_npas.c +@@ -77,8 +77,9 @@ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) + bags = PKCS12_unpack_p7data(p7); + } else if (bagnid == NID_pkcs7_encrypted) { + bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); +- if (!alg_get(p7->d.encrypted->enc_data->algorithm, +- &pbe_nid, &pbe_iter, &pbe_saltlen)) ++ if (p7->d.encrypted == NULL ++ || !alg_get(p7->d.encrypted->enc_data->algorithm, ++ &pbe_nid, &pbe_iter, &pbe_saltlen)) + goto err; + } else { + continue; +diff --git a/crypto/pkcs7/pk7_mime.c b/crypto/pkcs7/pk7_mime.c +index 49a0da5f819c4..8228315eeaa3a 100644 +--- a/crypto/pkcs7/pk7_mime.c ++++ b/crypto/pkcs7/pk7_mime.c +@@ -33,10 +33,13 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) + int ctype_nid = OBJ_obj2nid(p7->type); + const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7); + +- if (ctype_nid == NID_pkcs7_signed) ++ if (ctype_nid == NID_pkcs7_signed) { ++ if (p7->d.sign == NULL) ++ return 0; + mdalgs = p7->d.sign->md_algs; +- else ++ } else { + mdalgs = NULL; ++ } + + flags ^= SMIME_OLDMIME; + +diff --git a/test/recipes/80-test_pkcs12.t b/test/recipes/80-test_pkcs12.t +index 1f0cb4d501488..b2c376249646d 100644 +--- a/test/recipes/80-test_pkcs12.t ++++ b/test/recipes/80-test_pkcs12.t +@@ -9,7 +9,7 @@ + use strict; + use warnings; + +-use OpenSSL::Test qw/:DEFAULT srctop_file/; ++use OpenSSL::Test qw/:DEFAULT srctop_file with/; + use OpenSSL::Test::Utils; + + use Encode; +@@ -54,7 +54,7 @@ if (eval { require Win32::API; 1; }) { + } + $ENV{OPENSSL_WIN32_UTF8}=1; + +-plan tests => 13; ++plan tests => 17; + + # Test different PKCS#12 formats + ok(run(test(["pkcs12_format_test"])), "test pkcs12 formats"); +@@ -148,4 +148,25 @@ ok(grep(/subject=CN = server.example/, @pkcs12info) == 1, + # Test that the expected friendly name is present in the output + ok(grep(/testname/, @pkcs12info) == 1, "test friendly name in output"); + ++# Test some bad pkcs12 files ++my $bad1 = srctop_file("test", "recipes", "80-test_pkcs12_data", "bad1.p12"); ++my $bad2 = srctop_file("test", "recipes", "80-test_pkcs12_data", "bad2.p12"); ++my $bad3 = srctop_file("test", "recipes", "80-test_pkcs12_data", "bad3.p12"); ++ ++with({ exit_checker => sub { return shift == 1; } }, ++ sub { ++ ok(run(app(["openssl", "pkcs12", "-in", $bad1, "-password", "pass:"])), ++ "test bad pkcs12 file 1"); ++ ++ ok(run(app(["openssl", "pkcs12", "-in", $bad1, "-password", "pass:", ++ "-nomacver"])), ++ "test bad pkcs12 file 1 (nomacver)"); ++ ++ ok(run(app(["openssl", "pkcs12", "-in", $bad2, "-password", "pass:"])), ++ "test bad pkcs12 file 2"); ++ ++ ok(run(app(["openssl", "pkcs12", "-in", $bad3, "-password", "pass:"])), ++ "test bad pkcs12 file 3"); ++ }); ++ + SetConsoleOutputCP($savedcp) if (defined($savedcp)); +diff --git a/test/recipes/80-test_pkcs12_data/bad1.p12 b/test/recipes/80-test_pkcs12_data/bad1.p12 +new file mode 100644 +index 0000000000000000000000000000000000000000..8f3387c7e356e4aa374729f3f3939343557b9c09 +GIT binary patch +literal 85 +zcmV-b0IL5mQvv}4Fbf6=Duzgg_YDCD0Wd)@F)$4V31Egu0c8UO0s#d81R(r{)waiY +rfR=Py6XX#<$m7-wj)xrauuD`}hF=Ng9=0`~S~)@=J%OiUaM0Oze6 +AD*ylh + +literal 0 +HcmV?d00001 + +diff --git a/test/recipes/80-test_pkcs12_data/bad3.p12 b/test/recipes/80-test_pkcs12_data/bad3.p12 +new file mode 100644 +index 0000000000000000000000000000000000000000..ef86a1d86fb0bc09471ca2596d82e7d521d973a4 +GIT binary patch +literal 104 +zcmXp=V`5}BkYnT2YV&CO&dbQoxImDF-+oA$5$MVJL*60=F*5iN*C_e&wD%dwCM*q{=+OBX|Z+F7XSHN#>B+I003La +BAqM~e + +literal 0 +HcmV?d00001 + diff --git a/openssl.spec b/openssl.spec index ec1af2e..1dfd443 100644 --- a/openssl.spec +++ b/openssl.spec @@ -212,6 +212,8 @@ Patch132: 0132-CVE-2023-6129.patch Patch133: 0133-CVE-2023-6237.patch # https://github.com/openssl/openssl/pull/20780 Patch134: 0134-engine-based-ECDHE-kex.patch +# https://github.com/openssl/openssl/pull/23362 +Patch135: 0135-CVE-2024-0727.patch License: ASL 2.0 URL: http://www.openssl.org/ @@ -554,6 +556,8 @@ ln -s /etc/crypto-policies/back-ends/openssl_fips.config $RPM_BUILD_ROOT%{_sysco Resolves: RHEL-21654 - SSL ECDHE Kex fails when pkcs11 engine is set in config file Resolves: RHEL-20249 +- Denial of service via null dereference in PKCS#12 + Resolves: RHEL-22486 * Mon Oct 16 2023 Dmitry Belyavskiy - 1:3.0.7-25 - Provide relevant diagnostics when FIPS checksum is corrupted