From: Neil Horman Date: Mon, 16 Mar 2026 17:49:07 +0000 (-0400) Subject: Fix NULL deref in [ec]dh_cms_set_shared_info X-Git-Tag: openssl-4.0.0~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5184bfde21a873248ebf410a0034d07cfcf7a922;p=thirdparty%2Fopenssl.git Fix NULL deref in [ec]dh_cms_set_shared_info Multiple independent reports indicated a SIGSEGV was possible in CMS processing when a crafted CMS EnvelopedData message using A Key Agreement Recipient Info field. If the KeyEncryptionAlgorithmIdentifier omits the optional parameter field, the referenced functions above will attempt to dereference the alg->parameter data prior to checking if the parameter field is NULL. Confirmed to resolve the issues using the reproducers provided in the security reports. Co-authored-by: Tomas Mraz Fixes CVE-2026-28389 Reviewed-by: Saša Nedvědický Reviewed-by: Matt Caswell MergeDate: Mon Apr 6 18:58:28 2026 (cherry picked from commit dea5c521a6a78a1caed451e53a149d327d2a928d) --- diff --git a/crypto/cms/cms_dh.c b/crypto/cms/cms_dh.c index a10df73b104..659ff38b618 100644 --- a/crypto/cms/cms_dh.c +++ b/crypto/cms/cms_dh.c @@ -89,16 +89,21 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) int keylen, plen; EVP_CIPHER *kekcipher = NULL; EVP_CIPHER_CTX *kekctx; + const ASN1_OBJECT *aoid; + const void *parameter = NULL; + int ptype = 0; char name[OSSL_MAX_NAME_SIZE]; if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) goto err; + X509_ALGOR_get0(&aoid, &ptype, ¶meter, alg); + /* * For DH we only have one OID permissible. If ever any more get defined * we will need something cleverer. */ - if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) { + if (OBJ_obj2nid(aoid) != NID_id_smime_alg_ESDH) { ERR_raise(ERR_LIB_CMS, CMS_R_KDF_PARAMETER_ERROR); goto err; } @@ -107,11 +112,11 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) || EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0) goto err; - if (alg->parameter->type != V_ASN1_SEQUENCE) + if (ptype != V_ASN1_SEQUENCE) goto err; - p = alg->parameter->value.sequence->data; - plen = alg->parameter->value.sequence->length; + p = ASN1_STRING_get0_data(parameter); + plen = ASN1_STRING_length(parameter); kekalg = d2i_X509_ALGOR(NULL, &p, plen); if (kekalg == NULL) goto err; diff --git a/crypto/cms/cms_ec.c b/crypto/cms/cms_ec.c index ff8adad6166..e60d0a786ec 100644 --- a/crypto/cms/cms_ec.c +++ b/crypto/cms/cms_ec.c @@ -166,21 +166,27 @@ static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) int plen, keylen; EVP_CIPHER *kekcipher = NULL; EVP_CIPHER_CTX *kekctx; + const ASN1_OBJECT *aoid = NULL; + int ptype = 0; + const void *parameter = NULL; + char name[OSSL_MAX_NAME_SIZE]; if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) return 0; - if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) { + X509_ALGOR_get0(&aoid, &ptype, ¶meter, alg); + + if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(aoid))) { ERR_raise(ERR_LIB_CMS, CMS_R_KDF_PARAMETER_ERROR); return 0; } - if (alg->parameter->type != V_ASN1_SEQUENCE) + if (ptype != V_ASN1_SEQUENCE) return 0; - p = alg->parameter->value.sequence->data; - plen = alg->parameter->value.sequence->length; + p = ASN1_STRING_get0_data(parameter); + plen = ASN1_STRING_length(parameter); kekalg = d2i_X509_ALGOR(NULL, &p, plen); if (kekalg == NULL) goto err;