]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix NULL deref in [ec]dh_cms_set_shared_info
authorNeil Horman <nhorman@openssl.org>
Mon, 16 Mar 2026 17:49:07 +0000 (13:49 -0400)
committerTomas Mraz <tomas@openssl.foundation>
Mon, 6 Apr 2026 18:59:57 +0000 (20:59 +0200)
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 <tomas@openssl.foundation>
Fixes CVE-2026-28389

Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.foundation>
MergeDate: Mon Apr  6 18:58:28 2026
(cherry picked from commit dea5c521a6a78a1caed451e53a149d327d2a928d)

crypto/cms/cms_dh.c
crypto/cms/cms_ec.c

index a10df73b104641c35c1eeae735d60bc1403ee031..659ff38b6181b6cf996e0a769ee802ea9c3d5f28 100644 (file)
@@ -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, &parameter, 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;
index ff8adad616686ff2c064ad9b3eb5f36964bff1a1..e60d0a786ec58f92e70124f94ec89f3fc90357d3 100644 (file)
@@ -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, &parameter, 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;