From 6ee9a73e9f489faa546f09cfbf9c63c8f8798445 Mon Sep 17 00:00:00 2001
From: Neil Horman <nhorman@openssl.org>
Date: Wed, 1 Apr 2026 10:56:44 +0200
Subject: [PATCH] Fix NULL deref in rsa_cms_decrypt
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Very simmilar to CVE-2026-28389, ensure that if we are missing
parameters in RSA-OAEP SourceFunc in CMS KeyTransportRecipientInfo,
we don't segfault when decrypting.

Co-authored-by: Tomas Mraz <tomas@openssl.foundation>

Fixes CVE-2026-28390

Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
MergeDate: Mon Apr  6 19:07:44 2026
---
 crypto/cms/cms_rsa.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/crypto/cms/cms_rsa.c b/crypto/cms/cms_rsa.c
index f132df5c8a..a1e26d3c3d 100644
--- a/crypto/cms/cms_rsa.c
+++ b/crypto/cms/cms_rsa.c
@@ -42,10 +42,13 @@ static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
     X509_ALGOR *cmsalg;
     int nid;
     int rv = -1;
-    unsigned char *label = NULL;
+    const unsigned char *label = NULL;
     int labellen = 0;
     const EVP_MD *mgf1md = NULL, *md = NULL;
     RSA_OAEP_PARAMS *oaep;
+    const ASN1_OBJECT *aoid;
+    const void *parameter = NULL;
+    int ptype = 0;
 
     pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
     if (pkctx == NULL)
@@ -75,21 +78,19 @@ static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
         goto err;
 
     if (oaep->pSourceFunc != NULL) {
-        X509_ALGOR *plab = oaep->pSourceFunc;
+        X509_ALGOR_get0(&aoid, &ptype, &parameter, oaep->pSourceFunc);
 
-        if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) {
+        if (OBJ_obj2nid(aoid) != NID_pSpecified) {
             ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_LABEL_SOURCE);
             goto err;
         }
-        if (plab->parameter->type != V_ASN1_OCTET_STRING) {
+        if (ptype != V_ASN1_OCTET_STRING) {
             ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_LABEL);
             goto err;
         }
 
-        label = plab->parameter->value.octet_string->data;
-        /* Stop label being freed when OAEP parameters are freed */
-        plab->parameter->value.octet_string->data = NULL;
-        labellen = plab->parameter->value.octet_string->length;
+        label = ASN1_STRING_get0_data(parameter);
+        labellen = ASN1_STRING_length(parameter);
     }
 
     if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0)
@@ -98,10 +99,16 @@ static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
         goto err;
     if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
         goto err;
-    if (label != NULL
-            && EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) {
-        OPENSSL_free(label);
-        goto err;
+    if (label != NULL) {
+        unsigned char *dup_label = OPENSSL_memdup(label, labellen);
+
+        if (dup_label == NULL)
+            goto err;
+
+        if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, dup_label, labellen) <= 0) {
+            OPENSSL_free(dup_label);
+            goto err;
+        }
     }
     /* Carry on */
     rv = 1;
-- 
2.53.0

