/* crypto/cms/cms_env.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project.
 */
/* ====================================================================
 * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 */

#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/pem.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/cms.h>
#include <openssl/rand.h>
#include <openssl/aes.h>
#include "cms_lcl.h"
#include "asn1_locl.h"

/* CMS EnvelopedData Utilities */

DECLARE_ASN1_ITEM(CMS_EnvelopedData)
DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)

DECLARE_STACK_OF(CMS_RecipientInfo)

CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
	{
	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped)
		{
		CMSerr(CMS_F_CMS_GET0_ENVELOPED,
				CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
		return NULL;
		}
	return cms->d.envelopedData;
	}

static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
	{
	if (cms->d.other == NULL)
		{
		cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
		if (!cms->d.envelopedData)
			{
			CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT,
							ERR_R_MALLOC_FAILURE);
			return NULL;
			}
		cms->d.envelopedData->version = 0;
		cms->d.envelopedData->encryptedContentInfo->contentType =
						OBJ_nid2obj(NID_pkcs7_data);
		ASN1_OBJECT_free(cms->contentType);
		cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
		return cms->d.envelopedData;
		}
	return cms_get0_enveloped(cms);
	}

STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
	{
	CMS_EnvelopedData *env;
	env = cms_get0_enveloped(cms);
	if (!env)
		return NULL;
	return env->recipientInfos;
	}

int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
	{
	return ri->type;
	}

CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
	{
	CMS_ContentInfo *cms;
	CMS_EnvelopedData *env;
	cms = CMS_ContentInfo_new();
	if (!cms)
		goto merr;
	env = cms_enveloped_data_init(cms);
	if (!env)
		goto merr;
	if (!cms_EncryptedContent_init(env->encryptedContentInfo,
					cipher, NULL, 0))
		goto merr;
	return cms;
	merr:
	if (cms)
		CMS_ContentInfo_free(cms);
	CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
	return NULL;
	}

/* Key Transport Recipient Info (KTRI) routines */

/* Add a recipient certificate. For now only handle key transport.
 * If we ever handle key agreement will need updating.
 */

CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
					X509 *recip, unsigned int flags)
	{
	CMS_RecipientInfo *ri = NULL;
	CMS_KeyTransRecipientInfo *ktri;
	CMS_EnvelopedData *env;
	EVP_PKEY *pk = NULL;
	int i, type;
	env = cms_get0_enveloped(cms);
	if (!env)
		goto err;

	/* Initialize recipient info */
	ri = M_ASN1_new_of(CMS_RecipientInfo);
	if (!ri)
		goto merr;

	/* Initialize and add key transport recipient info */

	ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
	if (!ri->d.ktri)
		goto merr;
	ri->type = CMS_RECIPINFO_TRANS;

	ktri = ri->d.ktri;

	X509_check_purpose(recip, -1, -1);
	pk = X509_get_pubkey(recip);
	if (!pk)
		{
		CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
				CMS_R_ERROR_GETTING_PUBLIC_KEY);
		goto err;
		}
	CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509);
	ktri->pkey = pk;
	ktri->recip = recip;

	if (flags & CMS_USE_KEYID)
		{
		ktri->version = 2;
		type = CMS_RECIPINFO_KEYIDENTIFIER;
		}
	else
		{
		ktri->version = 0;
		type = CMS_RECIPINFO_ISSUER_SERIAL;
		}

	/* Not a typo: RecipientIdentifier and SignerIdentifier are the
	 * same structure.
	 */

	if (!cms_set1_SignerIdentifier(ktri->rid, recip, type))
		goto err;

	if (pk->ameth && pk->ameth->pkey_ctrl)
		{
		i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE,
						0, ri);
		if (i == -2)
			{
			CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
			goto err;
			}
		if (i <= 0)
			{
			CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
				CMS_R_CTRL_FAILURE);
			goto err;
			}
		}

	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
		goto merr;

	return ri;

	merr:
	CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
	err:
	if (ri)
		M_ASN1_free_of(ri, CMS_RecipientInfo);
	return NULL;

	}

int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
					EVP_PKEY **pk, X509 **recip,
					X509_ALGOR **palg)
	{
	CMS_KeyTransRecipientInfo *ktri;
	if (ri->type != CMS_RECIPINFO_TRANS)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
			CMS_R_NOT_KEY_TRANSPORT);
		return 0;
		}

	ktri = ri->d.ktri;

	if (pk)
		*pk = ktri->pkey;
	if (recip)
		*recip = ktri->recip;
	if (palg)
		*palg = ktri->keyEncryptionAlgorithm;
	return 1;
	}

int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
					ASN1_OCTET_STRING **keyid,
					X509_NAME **issuer, ASN1_INTEGER **sno)
	{
	CMS_KeyTransRecipientInfo *ktri;
	if (ri->type != CMS_RECIPINFO_TRANS)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
			CMS_R_NOT_KEY_TRANSPORT);
		return 0;
		}
	ktri = ri->d.ktri;

	return cms_SignerIdentifier_get0_signer_id(ktri->rid,
							keyid, issuer, sno);
	}

int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
	{
	if (ri->type != CMS_RECIPINFO_TRANS)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
			CMS_R_NOT_KEY_TRANSPORT);
		return -2;
		}
	return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
	}

int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
	{
	if (ri->type != CMS_RECIPINFO_TRANS)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY,
			CMS_R_NOT_KEY_TRANSPORT);
		return 0;
		}
	ri->d.ktri->pkey = pkey;
	return 1;
	}

/* Encrypt content key in key transport recipient info */

static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
					CMS_RecipientInfo *ri)
	{
	CMS_KeyTransRecipientInfo *ktri;
	CMS_EncryptedContentInfo *ec;
	EVP_PKEY_CTX *pctx = NULL;
	unsigned char *ek = NULL;
	size_t eklen;

	int ret = 0;

	if (ri->type != CMS_RECIPINFO_TRANS)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
			CMS_R_NOT_KEY_TRANSPORT);
		return 0;
		}
	ktri = ri->d.ktri;
	ec = cms->d.envelopedData->encryptedContentInfo;

	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
	if (!pctx)
		return 0;

	if (EVP_PKEY_encrypt_init(pctx) <= 0)
		goto err;

	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
				EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
		goto err;
		}

	if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
		goto err;

	ek = OPENSSL_malloc(eklen);

	if (ek == NULL)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
							ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
		goto err;

	ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
	ek = NULL;

	ret = 1;

	err:
	if (pctx)
		EVP_PKEY_CTX_free(pctx);
	if (ek)
		OPENSSL_free(ek);
	return ret;

	}

/* Decrypt content key from KTRI */

static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
							CMS_RecipientInfo *ri)
	{
	CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
	EVP_PKEY_CTX *pctx = NULL;
	unsigned char *ek = NULL;
	size_t eklen;
	int ret = 0;

	if (ktri->pkey == NULL)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
			CMS_R_NO_PRIVATE_KEY);
		return 0;
		}

	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
	if (!pctx)
		return 0;

	if (EVP_PKEY_decrypt_init(pctx) <= 0)
		goto err;

	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
				EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
		goto err;
		}

	if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
				ktri->encryptedKey->data,
				ktri->encryptedKey->length) <= 0)
		goto err;

	ek = OPENSSL_malloc(eklen);

	if (ek == NULL)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
							ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (EVP_PKEY_decrypt(pctx, ek, &eklen,
				ktri->encryptedKey->data,
				ktri->encryptedKey->length) <= 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
		goto err;
		}

	ret = 1;

	cms->d.envelopedData->encryptedContentInfo->key = ek;
	cms->d.envelopedData->encryptedContentInfo->keylen = eklen;

	err:
	if (pctx)
		EVP_PKEY_CTX_free(pctx);
	if (!ret && ek)
		OPENSSL_free(ek);

	return ret;
	}

/* Key Encrypted Key (KEK) RecipientInfo routines */

int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, 
					const unsigned char *id, size_t idlen)
	{
	ASN1_OCTET_STRING tmp_os;
	CMS_KEKRecipientInfo *kekri;
	if (ri->type != CMS_RECIPINFO_KEK)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
		return -2;
		}
	kekri = ri->d.kekri;
	tmp_os.type = V_ASN1_OCTET_STRING;
	tmp_os.flags = 0;
	tmp_os.data = (unsigned char *)id;
	tmp_os.length = (int)idlen;
	return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
	}

/* For now hard code AES key wrap info */

static size_t aes_wrap_keylen(int nid)
	{
	switch (nid)
		{
		case NID_id_aes128_wrap:
		return 16;

		case NID_id_aes192_wrap:
		return  24;

		case NID_id_aes256_wrap:
		return  32;

		default:
		return 0;
		}
	}

CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
					unsigned char *key, size_t keylen,
					unsigned char *id, size_t idlen,
					ASN1_GENERALIZEDTIME *date,
					ASN1_OBJECT *otherTypeId,
					ASN1_TYPE *otherType)
	{
	CMS_RecipientInfo *ri = NULL;
	CMS_EnvelopedData *env;
	CMS_KEKRecipientInfo *kekri;
	env = cms_get0_enveloped(cms);
	if (!env)
		goto err;

	if (nid == NID_undef)
		{
		switch (keylen)
			{
			case 16:
			nid = NID_id_aes128_wrap;
			break;

			case  24:
			nid = NID_id_aes192_wrap;
			break;

			case  32:
			nid = NID_id_aes256_wrap;
			break;

			default:
			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
						CMS_R_INVALID_KEY_LENGTH);
			goto err;
			}

		}
	else
		{

		size_t exp_keylen = aes_wrap_keylen(nid);

		if (!exp_keylen)
			{
			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
					CMS_R_UNSUPPORTED_KEK_ALGORITHM);
			goto err;
			}

		if (keylen != exp_keylen)
			{
			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
					CMS_R_INVALID_KEY_LENGTH);
			goto err;
			}

		}

	/* Initialize recipient info */
	ri = M_ASN1_new_of(CMS_RecipientInfo);
	if (!ri)
		goto merr;

	ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
	if (!ri->d.kekri)
		goto merr;
	ri->type = CMS_RECIPINFO_KEK;

	kekri = ri->d.kekri;

	if (otherTypeId)
		{
		kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
		if (kekri->kekid->other == NULL)
			goto merr;
		}

	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
		goto merr;


	/* After this point no calls can fail */

	kekri->version = 4;

	kekri->key = key;
	kekri->keylen = keylen;

	ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);

	kekri->kekid->date = date;

	if (kekri->kekid->other)
		{
		kekri->kekid->other->keyAttrId = otherTypeId;
		kekri->kekid->other->keyAttr = otherType;
		}

	X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
				OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);

	return ri;

	merr:
	CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
	err:
	if (ri)
		M_ASN1_free_of(ri, CMS_RecipientInfo);
	return NULL;

	}

int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
					X509_ALGOR **palg,
					ASN1_OCTET_STRING **pid,
					ASN1_GENERALIZEDTIME **pdate,
					ASN1_OBJECT **potherid,
					ASN1_TYPE **pothertype)
	{
	CMS_KEKIdentifier *rkid;
	if (ri->type != CMS_RECIPINFO_KEK)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
		return 0;
		}
	rkid =  ri->d.kekri->kekid;
	if (palg)
		*palg = ri->d.kekri->keyEncryptionAlgorithm;
	if (pid)
		*pid = rkid->keyIdentifier;
	if (pdate)
		*pdate = rkid->date;
	if (potherid)
		{
		if (rkid->other)
			*potherid = rkid->other->keyAttrId;
		else
			*potherid = NULL;
		}
	if (pothertype)
		{
		if (rkid->other)
			*pothertype = rkid->other->keyAttr;
		else
			*pothertype = NULL;
		}
	return 1;
	}

int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, 
				unsigned char *key, size_t keylen)
	{
	CMS_KEKRecipientInfo *kekri;
	if (ri->type != CMS_RECIPINFO_KEK)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
		return 0;
		}

	kekri = ri->d.kekri;
	kekri->key = key;
	kekri->keylen = keylen;
	return 1;
	}


/* Encrypt content key in KEK recipient info */

static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
					CMS_RecipientInfo *ri)
	{
	CMS_EncryptedContentInfo *ec;
	CMS_KEKRecipientInfo *kekri;
	AES_KEY actx;
	unsigned char *wkey = NULL;
	int wkeylen;
	int r = 0;

	ec = cms->d.envelopedData->encryptedContentInfo;

	kekri = ri->d.kekri;

	if (!kekri->key)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
		return 0;
		}

	if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx))
		{ 
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
						CMS_R_ERROR_SETTING_KEY);
		goto err;
		}

	wkey = OPENSSL_malloc(ec->keylen + 8);

	if (!wkey)
		{ 
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
						ERR_R_MALLOC_FAILURE);
		goto err;
		}

	wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);

	if (wkeylen <= 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
		goto err;
		}

	ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);

	r = 1;

	err:

	if (!r && wkey)
		OPENSSL_free(wkey);
	OPENSSL_cleanse(&actx, sizeof(actx));

	return r;

	}

/* Decrypt content key in KEK recipient info */

static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
					CMS_RecipientInfo *ri)
	{
	CMS_EncryptedContentInfo *ec;
	CMS_KEKRecipientInfo *kekri;
	AES_KEY actx;
	unsigned char *ukey = NULL;
	int ukeylen;
	int r = 0, wrap_nid;

	ec = cms->d.envelopedData->encryptedContentInfo;

	kekri = ri->d.kekri;

	if (!kekri->key)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
		return 0;
		}

	wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
	if (aes_wrap_keylen(wrap_nid) != kekri->keylen)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
			CMS_R_INVALID_KEY_LENGTH);
		return 0;
		}

	/* If encrypted key length is invalid don't bother */

	if (kekri->encryptedKey->length < 16)
		{ 
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
					CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
		goto err;
		}

	if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx))
		{ 
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
						CMS_R_ERROR_SETTING_KEY);
		goto err;
		}

	ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);

	if (!ukey)
		{ 
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
						ERR_R_MALLOC_FAILURE);
		goto err;
		}

	ukeylen = AES_unwrap_key(&actx, NULL, ukey,
					kekri->encryptedKey->data,
					kekri->encryptedKey->length);

	if (ukeylen <= 0)
		{
		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
							CMS_R_UNWRAP_ERROR);
		goto err;
		}

	ec->key = ukey;
	ec->keylen = ukeylen;

	r = 1;

	err:

	if (!r && ukey)
		OPENSSL_free(ukey);
	OPENSSL_cleanse(&actx, sizeof(actx));

	return r;

	}

int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
	{
	switch(ri->type)
		{
		case CMS_RECIPINFO_TRANS:
		return cms_RecipientInfo_ktri_decrypt(cms, ri);

		case CMS_RECIPINFO_KEK:
		return cms_RecipientInfo_kekri_decrypt(cms, ri);

		case CMS_RECIPINFO_PASS:
		return cms_RecipientInfo_pwri_crypt(cms, ri, 0);

		default:
		CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
			CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
		return 0;
		}
	}

BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
	{
	CMS_EncryptedContentInfo *ec;
	STACK_OF(CMS_RecipientInfo) *rinfos;
	CMS_RecipientInfo *ri;
	int i, r, ok = 0;
	BIO *ret;

	/* Get BIO first to set up key */

	ec = cms->d.envelopedData->encryptedContentInfo;
	ret = cms_EncryptedContent_init_bio(ec);

	/* If error or no cipher end of processing */

	if (!ret || !ec->cipher)
		return ret;

	/* Now encrypt content key according to each RecipientInfo type */

	rinfos = cms->d.envelopedData->recipientInfos;

	for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++)
		{
		ri = sk_CMS_RecipientInfo_value(rinfos, i);

		switch (ri->type)
			{
			case CMS_RECIPINFO_TRANS:
			r = cms_RecipientInfo_ktri_encrypt(cms, ri);
			break;

			case CMS_RECIPINFO_KEK:
			r = cms_RecipientInfo_kekri_encrypt(cms, ri);
			break;

			case CMS_RECIPINFO_PASS:
			r = cms_RecipientInfo_pwri_crypt(cms, ri, 1);
			break;

			default:
			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
				CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
			goto err;
			}

		if (r <= 0)
			{
			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
				CMS_R_ERROR_SETTING_RECIPIENTINFO);
			goto err;
			}
		}

	ok = 1;

	err:
	ec->cipher = NULL;
	if (ec->key)
		{
		OPENSSL_cleanse(ec->key, ec->keylen);
		OPENSSL_free(ec->key);
		ec->key = NULL;
		ec->keylen = 0;
		}
	if (ok)
		return ret;
	BIO_free(ret);
	return NULL;

	}
