CMS_decrypt_set1_password(): prevent mem leak on any previously set decryption key
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Fri, 14 Oct 2022 10:56:54 +0000 (12:56 +0200)
committerDr. David von Oheimb <dev@ddvo.net>
Fri, 25 Nov 2022 08:05:47 +0000 (09:05 +0100)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from https://github.com/openssl/openssl/pull/19222)

crypto/cms/cms_smime.c

index e49c611a2899a7bd9a059aaa7437e0fae0a2539e..6a94d6c5e86498bf67f6d9e3290a7c6acfb75e4a 100644 (file)
@@ -703,7 +703,7 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
 int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk,
                                    X509 *cert, X509 *peer)
 {
-    STACK_OF(CMS_RecipientInfo) *ris;
+    STACK_OF(CMS_RecipientInfo) *ris = CMS_get0_RecipientInfos(cms);
     CMS_RecipientInfo *ri;
     int i, r, cms_pkey_ri_type;
     int debug = 0, match_ri = 0;
@@ -714,7 +714,6 @@ int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk,
     ec->key = NULL;
     ec->keylen = 0;
 
-    ris = CMS_get0_RecipientInfos(cms);
     if (ris != NULL)
         debug = ec->debug;
 
@@ -825,11 +824,16 @@ int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
 int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
                               unsigned char *pass, ossl_ssize_t passlen)
 {
-    STACK_OF(CMS_RecipientInfo) *ris;
+    STACK_OF(CMS_RecipientInfo) *ris = CMS_get0_RecipientInfos(cms);
     CMS_RecipientInfo *ri;
     int i, r;
+    CMS_EncryptedContentInfo *ec = ossl_cms_get0_env_enc_content(cms);
+
+    /* Prevent mem leak on earlier CMS_decrypt_set1_{pkey_and_peer,password} */
+    OPENSSL_clear_free(ec->key, ec->keylen);
+    ec->key = NULL;
+    ec->keylen = 0;
 
-    ris = CMS_get0_RecipientInfos(cms);
     for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
         ri = sk_CMS_RecipientInfo_value(ris, i);
         if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS)