]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix Memory leak in CMS_EncryptedData_set1_key
authorRyan Hooper <ryhooper@cisco.com>
Thu, 25 Sep 2025 16:42:24 +0000 (12:42 -0400)
committerTomas Mraz <tomas@openssl.org>
Wed, 1 Oct 2025 15:49:28 +0000 (17:49 +0200)
When CMS_EncryptedData_set1_key is called repeatedly it will
leak data on the second call. This was because
cms->d.encryptedData was already set and needed to be cleared
before the call to M_ASN1_new_of.

Fixes: #28606
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28668)

(cherry picked from commit 7de825efa26d136c7bb118156190437bdcf130b7)

crypto/cms/cms_enc.c
test/cmsapitest.c

index ea8f07e1affc655a4ead339a08145b1e6bc5fabf..393a5672a5f62c913bb3edcee3e21b6060c6debe 100644 (file)
@@ -229,6 +229,10 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
         return 0;
     }
     if (ciph) {
+        if (cms->d.encryptedData != NULL) {
+            M_ASN1_free_of(cms->d.encryptedData, CMS_EncryptedData);
+            cms->d.encryptedData = NULL;
+        }
         cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
         if (!cms->d.encryptedData) {
             ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
index 59dd7faeb28438ecb97f6601d9cd42966699a4c5..1bb8b9278cb206107d80a18bfae2b7f63a25786a 100644 (file)
@@ -385,6 +385,29 @@ end:
     return ret;
 }
 
+static int test_CMS_set1_key_mem_leak(void)
+{
+    CMS_ContentInfo *cms;
+    unsigned char key[32] = {0};
+    int ret = 0;
+
+    if (!TEST_ptr(cms = CMS_ContentInfo_new()))
+        return 0;
+
+    if (!TEST_true(CMS_EncryptedData_set1_key(cms, EVP_aes_256_cbc(),
+                                              key, 32)))
+        goto end;
+
+    if (!TEST_true(CMS_EncryptedData_set1_key(cms, EVP_aes_128_cbc(),
+                                              key, 16)))
+        goto end;
+
+    ret = 1;
+end:
+    CMS_ContentInfo_free(cms);
+    return ret;
+}
+
 OPT_TEST_DECLARE_USAGE("certfile privkeyfile derfile\n")
 
 int setup_tests(void)
@@ -431,6 +454,7 @@ int setup_tests(void)
     ADD_TEST(test_encrypt_decrypt_aes_256_gcm);
     ADD_TEST(test_CMS_add1_cert);
     ADD_TEST(test_d2i_CMS_bio_NULL);
+    ADD_TEST(test_CMS_set1_key_mem_leak);
     ADD_ALL_TESTS(test_d2i_CMS_decode, 2);
     return 1;
 }