/* Provenance: openssl/openssl cms_RecipientInfo_ktri_decrypt (fixed). * repo: openssl/openssl * commit: d5030cdf32d6cd27bd964a0cb7aed2b7cb713369 * parent: f04d65692dd8109be9f387ce2ddd9fb1ab612b6b * commit_url: https://github.com/openssl/openssl/commit/d5030cdf32d6cd27bd964a0cb7aed2b7cb713369 * cve: CVE-2026-42768 * license: Apache-2.0 * function: cms_RecipientInfo_ktri_decrypt * relpath: crypto/cms/cms_env.c */ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) { CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; EVP_PKEY *pkey = ktri->pkey; unsigned char *ek = NULL; size_t eklen; int ret = 0; size_t fixlen = 0; const EVP_CIPHER *cipher = NULL; EVP_CIPHER *fetched_cipher = NULL; CMS_EncryptedContentInfo *ec; const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx); const char *propq = ossl_cms_ctx_get0_propq(ctx); ec = ossl_cms_get0_env_enc_content(cms); if (ktri->pkey == NULL) { ERR_raise(ERR_LIB_CMS, CMS_R_NO_PRIVATE_KEY); return 0; } if (cms->d.envelopedData->encryptedContentInfo->havenocert && !cms->d.envelopedData->encryptedContentInfo->debug) { X509_ALGOR *calg = ec->contentEncryptionAlgorithm; char name[OSSL_MAX_NAME_SIZE]; OBJ_obj2txt(name, sizeof(name), calg->algorithm, 0); (void)ERR_set_mark(); fetched_cipher = EVP_CIPHER_fetch(libctx, name, propq); if (fetched_cipher != NULL) cipher = fetched_cipher; else cipher = EVP_get_cipherbyobj(calg->algorithm); if (cipher == NULL) { (void)ERR_clear_last_mark(); ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_CIPHER); return 0; } (void)ERR_pop_to_mark(); fixlen = EVP_CIPHER_get_key_length(cipher); EVP_CIPHER_free(fetched_cipher); } ktri->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); if (ktri->pctx == NULL) goto err; if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0) goto err; if (!ossl_cms_env_asn1_ctrl(ri, 1)) goto err; if (evp_pkey_decrypt_alloc(ktri->pctx, &ek, &eklen, fixlen, ktri->encryptedKey->data, ktri->encryptedKey->length) <= 0) goto err; ret = 1; OPENSSL_clear_free(ec->key, ec->keylen); ec->key = ek; ec->keylen = eklen; err: EVP_PKEY_CTX_free(ktri->pctx); ktri->pctx = NULL; if (!ret) OPENSSL_free(ek); return ret; }