Skip to content

Commit fb3cdfb

Browse files
moritzkirchnersapByteOtter
authored andcommitted
Merge pull request #11 from gardenlinux/cvefixes
CVE fixes
1 parent b6db973 commit fb3cdfb

12 files changed

Lines changed: 1246 additions & 0 deletions
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
From: Neil Horman <nhorman@openssl.org>
2+
Date: Sun, 29 Mar 2026 10:47:03 -0400
3+
Subject: Add test for CMS decryption with RSA keys
4+
5+
Ensure we don't encounter a segfault when decrypting CMS messages with
6+
malformed EnvelopedData when using RSA-OAEP.
7+
8+
Co-authored-by: Tomas Mraz <tomas@openssl.foundation>
9+
---
10+
test/recipes/80-test_cms.t | 14 +++++++++++++-
11+
1 file changed, 13 insertions(+), 1 deletion(-)
12+
13+
diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t
14+
index 90aeb2959707..bbf3925ba98b 100644
15+
--- a/test/recipes/80-test_cms.t
16+
+++ b/test/recipes/80-test_cms.t
17+
@@ -53,7 +53,7 @@ my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib)
18+
19+
$no_rc2 = 1 if disabled("legacy");
20+
21+
-plan tests => 33;
22+
+plan tests => 34;
23+
24+
ok(run(test(["pkcs7_test"])), "test pkcs7");
25+
26+
@@ -1391,6 +1391,18 @@ with({ exit_checker => sub { return shift == 4; } },
27+
}
28+
});
29+
30+
+$smcont_malformed = srctop_file("test", "recipes", "80-test_cms_data", "rsa-malformed.der");
31+
+my $smrsacert = catfile($smdir, "smrsa3.pem");
32+
+my $smrsakey = catfile($smdir, "smrsa3-key.pem");
33+
+
34+
+# Test case for CVE-2026-28390
35+
+with({ exit_checker => sub { return shift == 4; } },
36+
+ sub {
37+
+ ok(run(app(["openssl", "cms", @prov, "-decrypt", "-in", $smcont_malformed, "-inform",
38+
+ "DER", "-recip", $smrsacert, "-inkey", $smrsakey, "-out", "{output}.cms"])),
39+
+ "Must not crash on malformed cms inputs with RSA key");
40+
+ });
41+
+
42+
# Test encrypt to three recipients, and decrypt using key-only;
43+
# i.e. do not follow the recommended practice of providing the
44+
# recipient cert in the decrypt op.
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
From: Daniel Kubec <kubec@openssl.org>
2+
Date: Tue, 17 Mar 2026 11:14:56 +0100
3+
Subject: Added test for CVE-2026-28388
4+
5+
---
6+
test/certs/cve-2026-28388-ca.pem | 19 +++++++++++++++++++
7+
test/certs/cve-2026-28388-crls.pem | 22 ++++++++++++++++++++++
8+
test/certs/cve-2026-28388-leaf.pem | 19 +++++++++++++++++++
9+
test/recipes/25-test_verify.t | 14 +++++++++++++-
10+
4 files changed, 73 insertions(+), 1 deletion(-)
11+
create mode 100644 test/certs/cve-2026-28388-ca.pem
12+
create mode 100644 test/certs/cve-2026-28388-crls.pem
13+
create mode 100644 test/certs/cve-2026-28388-leaf.pem
14+
15+
diff --git a/test/certs/cve-2026-28388-ca.pem b/test/certs/cve-2026-28388-ca.pem
16+
new file mode 100644
17+
index 000000000000..9e36d11c4b4b
18+
--- /dev/null
19+
+++ b/test/certs/cve-2026-28388-ca.pem
20+
@@ -0,0 +1,19 @@
21+
+-----BEGIN CERTIFICATE-----
22+
+MIIDFTCCAf2gAwIBAgIUOl5NN/jfsuLU9JSGLZAfRzviF+owDQYJKoZIhvcNAQEL
23+
+BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAeFw0yNjAzMTcwODE5NDdaFw0yNzAzMTcw
24+
+ODE5NDdaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB
25+
+DwAwggEKAoIBAQD0m4KETjF0c25spNWUiNChWP0GalDL0gVDFbtAoMVF/lvlZEcp
26+
+hcg62ifHJRPntWyVAmH70DAI87cWzl/73QYGaOcMVcH5yEM31BoK83FvhsS3RTPO
27+
+FSrNCHaZrrWuga+QkBmMcR6qX7GF5eb6ASMBsLuuDqbkCRbTJ2ryhYeWF+VFemBF
28+
+pSHpcinSSLvswTVbZiCqmoy0WkK8eiyfLMZA17PgVLQpyPZ3rp5YG5vEZZoqFc/f
29+
+1bCHjwQ7fNdLCEMqPvE/I0mg2skRClb1L1Vieud/jmjL8nVd9I12j1eUOcSKtCkW
30+
+nj4BFa7TRz13sN3LZOFvV774ZaXRJ1GxoAlnAgMBAAGjYzBhMB0GA1UdDgQWBBSt
31+
+UxfaVbV9QMmfwMoImdgi4MZHzTAfBgNVHSMEGDAWgBStUxfaVbV9QMmfwMoImdgi
32+
+4MZHzTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0B
33+
+AQsFAAOCAQEA84w49n0pPJlqiD1/mn3pUZ66lBP0fFZiCuV/3YatBZcW+xcboW0Q
34+
+xImYztjZo0i+sQLZOalI4GoBqD77Dv4Qas0QoJZIp0wM8DjE3YcudCr4cpUhT1XC
35+
+ruHVHQA9bY5rW0GsfUBW6/3RbRpiK4SaFG3sUBbXPo0dC2EaLDjpLM7o2UljRrWu
36+
+d/vg6ieKuAicexLxqQLdM4SxjyvBpCwHg/dnMxawSj4Xhks1BHJ0hTLKJGDgfVHh
37+
+ex8+878u6Gf7fAOZa5idWUgTvdt5WHSW5x+Tm/P6LGG3HkM425ZU6BLTCHONoBud
38+
+cOlfWTTuIyweX5TRL5HY3SuO1cpMBpjiAA==
39+
+-----END CERTIFICATE-----
40+
diff --git a/test/certs/cve-2026-28388-crls.pem b/test/certs/cve-2026-28388-crls.pem
41+
new file mode 100644
42+
index 000000000000..46cbd7876dcd
43+
--- /dev/null
44+
+++ b/test/certs/cve-2026-28388-crls.pem
45+
@@ -0,0 +1,22 @@
46+
+-----BEGIN X509 CRL-----
47+
+MIIBizB1AgEBMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EXDTI2
48+
+MDMxNzA4MTk0N1oXDTI2MDQxNjA4MTk0N1qgLzAtMB8GA1UdIwQYMBaAFK1TF9pV
49+
+tX1AyZ/AygiZ2CLgxkfNMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IBAQBl
50+
+3vVknchCNA/oW0ovtnrE+xQs8yAk3uElooQlw88moTcts2YAcKWl49lnNWZk/RbF
51+
+Zs8m+MUuNb2W861siuvY3EwnSKVaJB2tKPfCRBP4xt+Q0g/Tn5CWxzpzHjQfLT6l
52+
+pvWOwaO7aE6bthX7MQ9XBpnHSPxsbul+MhV5PER11BYZGVh5MH0XxfMI0jDHFh2M
53+
+klTamgaao3TkVOI3OQPgzUx/q0Lz/YoCIH0pYGGP6KTGUX2x7UfD1tcIOcUp6tvO
54+
+6hG3utMgJOpZJl9yMzhG+ZURjbz4MSbBM0FVIaWnBn2VzY1jHGky0nK83IZhiddf
55+
+OohWoSH8tqwrNFZkblAH
56+
+-----END X509 CRL-----
57+
+-----BEGIN X509 CRL-----
58+
+MIIBjjB4AgEBMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EXDTI2
59+
+MDEwODEyMDAwMFoXDTI2MDIwODEyMDAwMFqgMjAwMB8GA1UdIwQYMBaAFK1TF9pV
60+
+tX1AyZ/AygiZ2CLgxkfNMA0GA1UdGwEB/wQDAgEBMA0GCSqGSIb3DQEBCwUAA4IB
61+
+AQCyYxa5iVUFxBpdXgBGSMqkuxJqQzVni8nXK0DiXHfgbTud+HD5Qp/6PX2EQuwK
62+
+SrT0yeNJBU1gxxMMsbdA0yVTPa7N2Ny39mjq/27yBXduiljo3Gs4NLEW9grJRnep
63+
+WOD1cQe3Fea5HlEfUoQJF1WVekF6CnOSqESaDvTAzqpZd7pxU8cuduiRJPin93ki
64+
+1nicQAU/G4Td190+JEAWD3/dJTg2LF6LKrmHiv2ZUTuNsVBfcbhFSoC6FpnjFUAI
65+
+kF8EgJpuBEfqV6erIuT1GD+5p1QGNqdcNl7LO9erJaUFnssJBJtj84iXd7RZARNs
66+
+njcibOSKC9YWgNmZUy0QV5D8
67+
+-----END X509 CRL-----
68+
diff --git a/test/certs/cve-2026-28388-leaf.pem b/test/certs/cve-2026-28388-leaf.pem
69+
new file mode 100644
70+
index 000000000000..02b22997cdd8
71+
--- /dev/null
72+
+++ b/test/certs/cve-2026-28388-leaf.pem
73+
@@ -0,0 +1,19 @@
74+
+-----BEGIN CERTIFICATE-----
75+
+MIIDHTCCAgWgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0
76+
+IENBMB4XDTI2MDMxNzA4MTk0N1oXDTI3MDMxNzA4MTk0N1owFDESMBAGA1UEAwwJ
77+
+VGVzdCBMZWFmMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqx7jpC6+
78+
+nRZ4ol6sShkpv04hGYtt7y+Ns4oIfdQTqo57DItFab8D8cH04zR8NND42MMnsPPn
79+
+Ovh9gv2l1mj9ZfwgXI5PvaKc6CoXvXb0ttekdDUS1iw9g04BxIXTDANxsdSXrCDd
80+
+Npyr1Pxdo3N2fiH6qN9/Lsh7yg0vJW/aJzdvhLcCTFcr89qmCsh17XfcTR0wZJXP
81+
+QdlRib9EK8aa6aKOYmm44SBbuXXyWojhheUaqVuzDj6A0L9opmh/DVXa9bdIN/FX
82+
+CKJB+d60Qxy5pKwpzDDxbCdG2vA1U2cPz8yAgelFG5AmXSHF7Id4G6GTCAY6PbTO
83+
+Jy2Z4I6NY+mj5wIDAQABo3wwejAdBgNVHQ4EFgQUlf2YZ93MvS4kZm7fshosgp+J
84+
+ImkwHwYDVR0jBBgwFoAUrVMX2lW1fUDJn8DKCJnYIuDGR80wCQYDVR0TBAIwADAt
85+
+BgNVHS4EJjAkMCKgIKAehhxodHRwOi8vZXhhbXBsZS5jb20vZGVsdGEucGVtMA0G
86+
+CSqGSIb3DQEBCwUAA4IBAQDoNAQGLS0Juf3i2fhuVQyWIFvNIMElLexeLnnd/y80
87+
+13nsP68ZGT2D3DoHQSz3SL7sNjLBc2CiUVftdaRQ4dNCz8sBY5BRTS5XEGbbTAFZ
88+
+bQUReykuuTy83CGw/JYN6YT/OHcf4gEhUnWtRMCmIz3J/NMRVSRnpV2Ezjltm/Q+
89+
+emFS/QclRhkP6Vu+lwM/nV6uAN8T7Ba68Hym2MN0clozrpoKeqFouB7D0i+iCZMw
90+
+zbac5as0hn7Fm+HGTbfTs2/fqUslvE6PmagepceP37pTSSVmYRmdpOD2cyCb30A+
91+
+nJFGQg7PcacGSL1re65W35XzdU8Si8OYD+PxjDaRbPcP
92+
+-----END CERTIFICATE-----
93+
diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
94+
index 673c3d5f1772..fcb343b9ee3a 100644
95+
--- a/test/recipes/25-test_verify.t
96+
+++ b/test/recipes/25-test_verify.t
97+
@@ -30,7 +30,7 @@ sub verify {
98+
run(app([@args]));
99+
}
100+
101+
-plan tests => 203;
102+
+plan tests => 204;
103+
104+
# Canonical success
105+
ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
106+
@@ -594,6 +594,18 @@ ok(!verify("ee-cert-policies-bad", "", ["root-cert"], ["ca-pol-cert"],
107+
"-explicit_policy"),
108+
"Bad certificate policy");
109+
110+
+# CVE-2026-28388
111+
+my $cve_28388_stderr = "cve-2026-28388.err";
112+
+run(app(["openssl", "verify",
113+
+ "-attime", "1739527200",
114+
+ "-CAfile", srctop_file(@certspath, "cve-2026-28388-ca.pem"),
115+
+ "-crl_check", "-use_deltas",
116+
+ "-CRLfile", srctop_file(@certspath, "cve-2026-28388-crls.pem"),
117+
+ srctop_file(@certspath, "cve-2026-28388-leaf.pem")],
118+
+ stderr => $cve_28388_stderr));
119+
+ok(grep(/CRL is not yet valid/, do { open my $fh, '<', $cve_28388_stderr; <$fh> }),
120+
+ "CVE-2026-28388");
121+
+
122+
# CAstore option
123+
my $rootcertname = "root-cert";
124+
my $rootcert = srctop_file(@certspath, "${rootcertname}.pem");
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
From: Igor Ustinov <igus68@gmail.com>
2+
Date: Thu, 5 Mar 2026 15:47:34 +0100
3+
Subject: Avoid possible buffer overflow in buf2hex conversion
4+
5+
Fixes CVE-2026-31789
6+
---
7+
crypto/o_str.c | 13 ++++++++++++-
8+
1 file changed, 12 insertions(+), 1 deletion(-)
9+
10+
diff --git a/crypto/o_str.c b/crypto/o_str.c
11+
index 35540630be25..9b9e7751fdd9 100644
12+
--- a/crypto/o_str.c
13+
+++ b/crypto/o_str.c
14+
@@ -296,6 +296,11 @@ static int buf2hexstr_sep(char *str, size_t str_n, size_t *strlength,
15+
int has_sep = (sep != CH_ZERO);
16+
size_t i, len = has_sep ? buflen * 3 : 1 + buflen * 2;
17+
18+
+ if (buflen > (has_sep ? SIZE_MAX / 3 : (SIZE_MAX - 1) / 2)) {
19+
+ ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_BYTES);
20+
+ return 0;
21+
+ }
22+
+
23+
if (len == 0)
24+
++len;
25+
if (strlength != NULL)
26+
@@ -339,7 +344,13 @@ char *ossl_buf2hexstr_sep(const unsigned char *buf, long buflen, char sep)
27+
if (buflen == 0)
28+
return OPENSSL_zalloc(1);
29+
30+
- tmp_n = (sep != CH_ZERO) ? buflen * 3 : 1 + buflen * 2;
31+
+ if ((sep != CH_ZERO && (size_t)buflen > SIZE_MAX / 3)
32+
+ || (sep == CH_ZERO && (size_t)buflen > (SIZE_MAX - 1) / 2)) {
33+
+ ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_BYTES);
34+
+ return NULL;
35+
+ }
36+
+
37+
+ tmp_n = (sep != CH_ZERO) ? (size_t)buflen * 3 : 1 + (size_t)buflen * 2;
38+
if ((tmp = OPENSSL_malloc(tmp_n)) == NULL)
39+
return NULL;
40+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
From: Daniel Kubec <kubec@openssl.org>
2+
Date: Tue, 17 Mar 2026 11:11:22 +0100
3+
Subject: Fix NULL Dereference When Delta CRL Lacks CRL Number Extension
4+
5+
Fixes CVE-2026-28388
6+
Fixes https://github.com/openssl/srt/issues/77
7+
---
8+
crypto/x509/x509_vfy.c | 2 ++
9+
1 file changed, 2 insertions(+)
10+
11+
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
12+
index ca3ffc420473..e71d71e9caa6 100644
13+
--- a/crypto/x509/x509_vfy.c
14+
+++ b/crypto/x509/x509_vfy.c
15+
@@ -1307,6 +1307,8 @@ static int check_delta_base(X509_CRL *delta, X509_CRL *base)
16+
if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
17+
return 0;
18+
/* Delta CRL number must exceed full CRL number */
19+
+ if (delta->crl_number == NULL)
20+
+ return 0;
21+
return ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0;
22+
}
23+
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
From: Neil Horman <nhorman@openssl.org>
2+
Date: Mon, 16 Mar 2026 13:49:07 -0400
3+
Subject: Fix NULL deref in [ec]dh_cms_set_shared_info
4+
5+
Multiple independent reports indicated a SIGSEGV was possible in CMS
6+
processing when a crafted CMS EnvelopedData message using A Key
7+
Agreement Recipient Info field. If the
8+
KeyEncryptionAlgorithmIdentifier omits the optional parameter field, the
9+
referenced functions above will attempt to dereference the
10+
alg->parameter data prior to checking if the parameter field is NULL.
11+
12+
Confirmed to resolve the issues using the reproducers provided in the
13+
security reports.
14+
15+
Co-authored-by: Tomas Mraz <tomas@openssl.foundation>
16+
17+
Fixes CVE-2026-28389
18+
---
19+
crypto/cms/cms_dh.c | 13 +++++++++----
20+
crypto/cms/cms_ec.c | 14 ++++++++++----
21+
2 files changed, 19 insertions(+), 8 deletions(-)
22+
23+
diff --git a/crypto/cms/cms_dh.c b/crypto/cms/cms_dh.c
24+
index ab3453d1c7c1..424729523697 100644
25+
--- a/crypto/cms/cms_dh.c
26+
+++ b/crypto/cms/cms_dh.c
27+
@@ -89,16 +89,21 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
28+
int keylen, plen;
29+
EVP_CIPHER *kekcipher = NULL;
30+
EVP_CIPHER_CTX *kekctx;
31+
+ const ASN1_OBJECT *aoid;
32+
+ const void *parameter = NULL;
33+
+ int ptype = 0;
34+
char name[OSSL_MAX_NAME_SIZE];
35+
36+
if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
37+
goto err;
38+
39+
+ X509_ALGOR_get0(&aoid, &ptype, &parameter, alg);
40+
+
41+
/*
42+
* For DH we only have one OID permissible. If ever any more get defined
43+
* we will need something cleverer.
44+
*/
45+
- if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) {
46+
+ if (OBJ_obj2nid(aoid) != NID_id_smime_alg_ESDH) {
47+
ERR_raise(ERR_LIB_CMS, CMS_R_KDF_PARAMETER_ERROR);
48+
goto err;
49+
}
50+
@@ -107,11 +112,11 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
51+
|| EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0)
52+
goto err;
53+
54+
- if (alg->parameter->type != V_ASN1_SEQUENCE)
55+
+ if (ptype != V_ASN1_SEQUENCE)
56+
goto err;
57+
58+
- p = alg->parameter->value.sequence->data;
59+
- plen = alg->parameter->value.sequence->length;
60+
+ p = ASN1_STRING_get0_data(parameter);
61+
+ plen = ASN1_STRING_length(parameter);
62+
kekalg = d2i_X509_ALGOR(NULL, &p, plen);
63+
if (kekalg == NULL)
64+
goto err;
65+
diff --git a/crypto/cms/cms_ec.c b/crypto/cms/cms_ec.c
66+
index ff8adad61668..e60d0a786ec5 100644
67+
--- a/crypto/cms/cms_ec.c
68+
+++ b/crypto/cms/cms_ec.c
69+
@@ -166,21 +166,27 @@ static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
70+
int plen, keylen;
71+
EVP_CIPHER *kekcipher = NULL;
72+
EVP_CIPHER_CTX *kekctx;
73+
+ const ASN1_OBJECT *aoid = NULL;
74+
+ int ptype = 0;
75+
+ const void *parameter = NULL;
76+
+
77+
char name[OSSL_MAX_NAME_SIZE];
78+
79+
if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
80+
return 0;
81+
82+
- if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) {
83+
+ X509_ALGOR_get0(&aoid, &ptype, &parameter, alg);
84+
+
85+
+ if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(aoid))) {
86+
ERR_raise(ERR_LIB_CMS, CMS_R_KDF_PARAMETER_ERROR);
87+
return 0;
88+
}
89+
90+
- if (alg->parameter->type != V_ASN1_SEQUENCE)
91+
+ if (ptype != V_ASN1_SEQUENCE)
92+
return 0;
93+
94+
- p = alg->parameter->value.sequence->data;
95+
- plen = alg->parameter->value.sequence->length;
96+
+ p = ASN1_STRING_get0_data(parameter);
97+
+ plen = ASN1_STRING_length(parameter);
98+
kekalg = d2i_X509_ALGOR(NULL, &p, plen);
99+
if (kekalg == NULL)
100+
goto err;

0 commit comments

Comments
 (0)