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: Todd Short <todd.short@me.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22031)
EVP_PKEY_free(si->pkey);
X509_free(si->signer);
EVP_MD_CTX_free(si->mctx);
+ EVP_PKEY_CTX_free(si->pctx);
}
return 1;
}
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),
return 0;
break;
+ case ASN1_OP_FREE_POST:
+ OPENSSL_free(cms->ctx.propq);
+ break;
+
}
return 1;
}
return ret;
}
-void ossl_cms_env_enc_content_free(const CMS_ContentInfo *cinf)
-{
- if (cms_get_enveloped_type_simple(cinf) != 0) {
- CMS_EncryptedContentInfo *ec = ossl_cms_get0_env_enc_content(cinf);
- if (ec != NULL)
- OPENSSL_clear_free(ec->key, ec->keylen);
- }
-}
-
CMS_EnvelopedData *ossl_cms_get0_enveloped(CMS_ContentInfo *cms)
{
if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) {
secret == NULL ? cert : NULL, detached_data, bio, flags);
end:
- if (ci != NULL)
+ if (ci != NULL) {
ci->d.envelopedData = NULL; /* do not indirectly free |env| */
+ ci->contentType = NULL;
+ }
CMS_ContentInfo_free(ci);
if (!res) {
BIO_free(bio);
static STACK_OF(CMS_CertificateChoices)
**cms_get0_certificate_choices(CMS_ContentInfo *cms);
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(CMS_ContentInfo)
IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
CMS_ContentInfo *d2i_CMS_ContentInfo(CMS_ContentInfo **a,
return ci;
}
-CMS_ContentInfo *CMS_ContentInfo_new(void)
-{
- return CMS_ContentInfo_new_ex(NULL, NULL);
-}
-
-void CMS_ContentInfo_free(CMS_ContentInfo *cms)
-{
- if (cms != NULL) {
- ossl_cms_env_enc_content_free(cms);
- OPENSSL_free(cms->ctx.propq);
- ASN1_item_free((ASN1_VALUE *)cms, ASN1_ITEM_rptr(CMS_ContentInfo));
- }
-}
-
const CMS_CTX *ossl_cms_get0_cmsctx(const CMS_ContentInfo *cms)
{
return cms != NULL ? &cms->ctx : NULL;
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)
int ossl_cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain);
BIO *ossl_cms_AuthEnvelopedData_init_bio(CMS_ContentInfo *cms);
int ossl_cms_AuthEnvelopedData_final(CMS_ContentInfo *cms, BIO *cmsbio);
-void ossl_cms_env_enc_content_free(const CMS_ContentInfo *cinf);
CMS_EnvelopedData *ossl_cms_get0_enveloped(CMS_ContentInfo *cms);
CMS_AuthEnvelopedData *ossl_cms_get0_auth_enveloped(CMS_ContentInfo *cms);
CMS_EncryptedContentInfo *ossl_cms_get0_env_enc_content(const CMS_ContentInfo *cms);
ossl_cms_ctx_get0_libctx(ctx),
ossl_cms_ctx_get0_propq(ctx),
pk, NULL) <= 0) {
+ si->pctx = NULL;
goto err;
}
+ else {
+ EVP_MD_CTX_set_flags(si->mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
+ }
}
if (sd->signerInfos == NULL)
unsigned char computed_md[EVP_MAX_MD_SIZE];
pctx = si->pctx;
+ si->pctx = NULL;
if (md == NULL) {
if (!EVP_DigestFinal_ex(mctx, computed_md, &mdlen))
goto err;
ossl_cms_ctx_get0_propq(ctx), si->pkey,
NULL) <= 0)
goto err;
+ EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
si->pctx = pctx;
}
goto err;
}
mctx = si->mctx;
+ if (si->pctx != NULL) {
+ EVP_PKEY_CTX_free(si->pctx);
+ si->pctx = NULL;
+ }
if (EVP_DigestVerifyInit_ex(mctx, &si->pctx, EVP_MD_get0_name(md), libctx,
- propq, si->pkey, NULL) <= 0)
+ propq, si->pkey, NULL) <= 0) {
+ si->pctx = NULL;
goto err;
+ }
+ EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
if (!cms_sd_asn1_ctrl(si, 1))
goto err;
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) {
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);
|| CMS_final(cms, in, NULL, flags))
return cms;
+ err:
CMS_ContentInfo_free(cms);
return NULL;
}
"-out", "{output}.txt" ],
\&final_compare
],
+
+ [ "encrypted content test streaming PEM format -noout, 128 bit AES key",
+ [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
+ "-aes128", "-secretkey", "000102030405060708090A0B0C0D0E0F",
+ "-stream", "-noout" ],
+ [ "{cmd2}", @prov, "-help" ]
+ ],
);
my @smime_cms_cades_tests = (