171 lines
6.2 KiB
Diff
171 lines
6.2 KiB
Diff
|
|
From 13dd772f61d149628a768d987828aa6dbc72fb31 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||
|
|
Date: Thu, 7 Sep 2023 18:05:44 +0200
|
||
|
|
Subject: [PATCH] Fix error handling in CMS_EncryptedData_encrypt
|
||
|
|
|
||
|
|
That caused several memory leaks in case of error.
|
||
|
|
Also when the CMS object that is created by CMS_EncryptedData_encrypt
|
||
|
|
is not used in the normal way, but instead just deleted
|
||
|
|
by CMS_ContentInfo_free some memory was lost.
|
||
|
|
|
||
|
|
Fixes #21985
|
||
|
|
|
||
|
|
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
|
||
|
|
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||
|
|
(Merged from https://github.com/openssl/openssl/pull/22008)
|
||
|
|
---
|
||
|
|
crypto/cms/cms_asn1.c | 15 +++++++++++++--
|
||
|
|
crypto/cms/cms_local.h | 1 +
|
||
|
|
crypto/cms/cms_sd.c | 14 +++++++++++++-
|
||
|
|
crypto/cms/cms_smime.c | 3 ++-
|
||
|
|
test/recipes/80-test_cms.t | 7 +++++++
|
||
|
|
7 files changed, 36 insertions(+), 4 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/crypto/cms/cms_asn1.c b/crypto/cms/cms_asn1.c
|
||
|
|
index 08069d72a2..d006ada998 100644
|
||
|
|
--- a/crypto/cms/cms_asn1.c
|
||
|
|
+++ b/crypto/cms/cms_asn1.c
|
||
|
|
@@ -51,6 +51,7 @@ static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||
|
|
EVP_PKEY_free(si->pkey);
|
||
|
|
X509_free(si->signer);
|
||
|
|
EVP_MD_CTX_free(si->mctx);
|
||
|
|
+ EVP_PKEY_CTX_free(si->pctx);
|
||
|
|
}
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
@@ -89,11 +90,21 @@ ASN1_SEQUENCE(CMS_OriginatorInfo) = {
|
||
|
|
ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1)
|
||
|
|
} static_ASN1_SEQUENCE_END(CMS_OriginatorInfo)
|
||
|
|
|
||
|
|
-ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = {
|
||
|
|
+static int cms_ec_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||
|
|
+ void *exarg)
|
||
|
|
+{
|
||
|
|
+ CMS_EncryptedContentInfo *ec = (CMS_EncryptedContentInfo *)*pval;
|
||
|
|
+
|
||
|
|
+ if (operation == ASN1_OP_FREE_POST)
|
||
|
|
+ OPENSSL_clear_free(ec->key, ec->keylen);
|
||
|
|
+ return 1;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+ASN1_NDEF_SEQUENCE_cb(CMS_EncryptedContentInfo, cms_ec_cb) = {
|
||
|
|
ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT),
|
||
|
|
ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR),
|
||
|
|
ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0)
|
||
|
|
-} static_ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo)
|
||
|
|
+} ASN1_NDEF_SEQUENCE_END_cb(CMS_EncryptedContentInfo, CMS_EncryptedContentInfo)
|
||
|
|
|
||
|
|
ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = {
|
||
|
|
ASN1_EMBED(CMS_KeyTransRecipientInfo, version, INT32),
|
||
|
|
diff --git a/crypto/cms/cms_local.h b/crypto/cms/cms_local.h
|
||
|
|
index a0ce4448f6..b275bddf75 100644
|
||
|
|
--- a/crypto/cms/cms_local.h
|
||
|
|
+++ b/crypto/cms/cms_local.h
|
||
|
|
@@ -342,6 +342,7 @@ struct CMS_Receipt_st {
|
||
|
|
|
||
|
|
DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
|
||
|
|
DECLARE_ASN1_ITEM(CMS_SignerInfo)
|
||
|
|
+DECLARE_ASN1_ITEM(CMS_EncryptedContentInfo)
|
||
|
|
DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
|
||
|
|
DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
|
||
|
|
DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
|
||
|
|
diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c
|
||
|
|
index 3f2a782565..708b443704 100644
|
||
|
|
--- a/crypto/cms/cms_sd.c
|
||
|
|
+++ b/crypto/cms/cms_sd.c
|
||
|
|
@@ -375,6 +375,8 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
|
||
|
|
} else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <=
|
||
|
|
0)
|
||
|
|
goto err;
|
||
|
|
+ else
|
||
|
|
+ EVP_MD_CTX_set_flags(si->mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!sd->signerInfos)
|
||
|
|
@@ -600,6 +602,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
|
||
|
|
unsigned char md[EVP_MAX_MD_SIZE];
|
||
|
|
unsigned int mdlen;
|
||
|
|
pctx = si->pctx;
|
||
|
|
+ si->pctx = NULL;
|
||
|
|
if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
|
||
|
|
goto err;
|
||
|
|
siglen = EVP_PKEY_size(si->pkey);
|
||
|
|
@@ -680,6 +683,7 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
|
||
|
|
EVP_MD_CTX_reset(mctx);
|
||
|
|
if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
|
||
|
|
goto err;
|
||
|
|
+ EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
|
||
|
|
si->pctx = pctx;
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -745,8 +749,13 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
mctx = si->mctx;
|
||
|
|
+ if (si->pctx != NULL) {
|
||
|
|
+ EVP_PKEY_CTX_free(si->pctx);
|
||
|
|
+ si->pctx = NULL;
|
||
|
|
+ }
|
||
|
|
if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0)
|
||
|
|
goto err;
|
||
|
|
+ EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
|
||
|
|
|
||
|
|
if (!cms_sd_asn1_ctrl(si, 1))
|
||
|
|
goto err;
|
||
|
|
@@ -859,8 +868,11 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
|
||
|
|
if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0)
|
||
|
|
goto err;
|
||
|
|
si->pctx = pkctx;
|
||
|
|
- if (!cms_sd_asn1_ctrl(si, 1))
|
||
|
|
+ if (!cms_sd_asn1_ctrl(si, 1)) {
|
||
|
|
+ si->pctx = NULL;
|
||
|
|
goto err;
|
||
|
|
+ }
|
||
|
|
+ si->pctx = NULL;
|
||
|
|
r = EVP_PKEY_verify(pkctx, si->signature->data,
|
||
|
|
si->signature->length, mval, mlen);
|
||
|
|
if (r <= 0) {
|
||
|
|
diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c
|
||
|
|
index 6e7dbc4da1..8f3a9fbaeb 100644
|
||
|
|
--- a/crypto/cms/cms_smime.c
|
||
|
|
+++ b/crypto/cms/cms_smime.c
|
||
|
|
@@ -211,7 +211,7 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
|
||
|
|
if (cms == NULL)
|
||
|
|
return NULL;
|
||
|
|
if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
|
||
|
|
- return NULL;
|
||
|
|
+ goto err;
|
||
|
|
|
||
|
|
if (!(flags & CMS_DETACHED))
|
||
|
|
CMS_set_detached(cms, 0);
|
||
|
|
@@ -220,6 +220,7 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
|
||
|
|
|| CMS_final(cms, in, NULL, flags))
|
||
|
|
return cms;
|
||
|
|
|
||
|
|
+ err:
|
||
|
|
CMS_ContentInfo_free(cms);
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t
|
||
|
|
index adb60e1436..544d4466b5 100644
|
||
|
|
--- a/test/recipes/80-test_cms.t
|
||
|
|
+++ b/test/recipes/80-test_cms.t
|
||
|
|
@@ -288,6 +288,13 @@ my @smime_cms_tests = (
|
||
|
|
"-secretkey", "000102030405060708090A0B0C0D0E0F", "-out", "smtst.txt" ]
|
||
|
|
],
|
||
|
|
|
||
|
|
+ [ "encrypted content test streaming PEM format -noout, 128 bit AES key",
|
||
|
|
+ [ "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
|
||
|
|
+ "-aes128", "-secretkey", "000102030405060708090A0B0C0D0E0F",
|
||
|
|
+ "-stream", "-noout" ],
|
||
|
|
+ [ "-help" ]
|
||
|
|
+ ],
|
||
|
|
+
|
||
|
|
);
|
||
|
|
|
||
|
|
my @smime_cms_comp_tests = (
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|