openssl/0135-CVE-2024-0727.patch
Dmitry Belyavskiy e6e479521b Denial of service via null dereference in PKCS#12
Resolves: RHEL-22486
2024-01-29 13:30:00 +01:00

179 lines
6.2 KiB
Diff

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<mRyon58xHv)BAVy}k(l(hJwF5pk-=q7<yb@T0s;sC$etR(
literal 0
HcmV?d00001
diff --git a/test/recipes/80-test_pkcs12_data/bad2.p12 b/test/recipes/80-test_pkcs12_data/bad2.p12
new file mode 100644
index 0000000000000000000000000000000000000000..113cb6f1cd523e880db869f518e60142dc875115
GIT binary patch
literal 104
zcmXp=V`5}BkYnT2YV&CO&dbQoxImDF-+<SE8zIDI;AmiIz{|#&(B{FI%FM#V$jZQ?
z@Tpc|>#<$m7-wj)xrauuD`}hF=<J_T`^8$QMBK7d>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-+<SE8%fB((ZJAvmyI)_&4V$OnT3gwm4QWp
zJ2GXlSm>oA$5$MVJL*60=F*5iN*C_e&wD%dwCM*q{=+OBX|Z+F7XSHN#>B+I003La
BAqM~e
literal 0
HcmV?d00001