Home | History | Annotate | Download | only in cms
      1 /* crypto/cms/cms_env.c */
      2 /* Written by Dr Stephen N Henson (steve (at) openssl.org) for the OpenSSL
      3  * project.
      4  */
      5 /* ====================================================================
      6  * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  *
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in
     17  *    the documentation and/or other materials provided with the
     18  *    distribution.
     19  *
     20  * 3. All advertising materials mentioning features or use of this
     21  *    software must display the following acknowledgment:
     22  *    "This product includes software developed by the OpenSSL Project
     23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     24  *
     25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     26  *    endorse or promote products derived from this software without
     27  *    prior written permission. For written permission, please contact
     28  *    licensing (at) OpenSSL.org.
     29  *
     30  * 5. Products derived from this software may not be called "OpenSSL"
     31  *    nor may "OpenSSL" appear in their names without prior written
     32  *    permission of the OpenSSL Project.
     33  *
     34  * 6. Redistributions of any form whatsoever must retain the following
     35  *    acknowledgment:
     36  *    "This product includes software developed by the OpenSSL Project
     37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     38  *
     39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     50  * OF THE POSSIBILITY OF SUCH DAMAGE.
     51  * ====================================================================
     52  */
     53 
     54 #include "cryptlib.h"
     55 #include <openssl/asn1t.h>
     56 #include <openssl/pem.h>
     57 #include <openssl/x509v3.h>
     58 #include <openssl/err.h>
     59 #include <openssl/cms.h>
     60 #include <openssl/rand.h>
     61 #include <openssl/aes.h>
     62 #include "cms_lcl.h"
     63 #include "asn1_locl.h"
     64 
     65 /* CMS EnvelopedData Utilities */
     66 
     67 DECLARE_ASN1_ITEM(CMS_EnvelopedData)
     68 DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
     69 DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
     70 DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
     71 
     72 DECLARE_STACK_OF(CMS_RecipientInfo)
     73 
     74 CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
     75 	{
     76 	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped)
     77 		{
     78 		CMSerr(CMS_F_CMS_GET0_ENVELOPED,
     79 				CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
     80 		return NULL;
     81 		}
     82 	return cms->d.envelopedData;
     83 	}
     84 
     85 static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
     86 	{
     87 	if (cms->d.other == NULL)
     88 		{
     89 		cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
     90 		if (!cms->d.envelopedData)
     91 			{
     92 			CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT,
     93 							ERR_R_MALLOC_FAILURE);
     94 			return NULL;
     95 			}
     96 		cms->d.envelopedData->version = 0;
     97 		cms->d.envelopedData->encryptedContentInfo->contentType =
     98 						OBJ_nid2obj(NID_pkcs7_data);
     99 		ASN1_OBJECT_free(cms->contentType);
    100 		cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
    101 		return cms->d.envelopedData;
    102 		}
    103 	return cms_get0_enveloped(cms);
    104 	}
    105 
    106 STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
    107 	{
    108 	CMS_EnvelopedData *env;
    109 	env = cms_get0_enveloped(cms);
    110 	if (!env)
    111 		return NULL;
    112 	return env->recipientInfos;
    113 	}
    114 
    115 int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
    116 	{
    117 	return ri->type;
    118 	}
    119 
    120 CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
    121 	{
    122 	CMS_ContentInfo *cms;
    123 	CMS_EnvelopedData *env;
    124 	cms = CMS_ContentInfo_new();
    125 	if (!cms)
    126 		goto merr;
    127 	env = cms_enveloped_data_init(cms);
    128 	if (!env)
    129 		goto merr;
    130 	if (!cms_EncryptedContent_init(env->encryptedContentInfo,
    131 					cipher, NULL, 0))
    132 		goto merr;
    133 	return cms;
    134 	merr:
    135 	if (cms)
    136 		CMS_ContentInfo_free(cms);
    137 	CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
    138 	return NULL;
    139 	}
    140 
    141 /* Key Transport Recipient Info (KTRI) routines */
    142 
    143 /* Add a recipient certificate. For now only handle key transport.
    144  * If we ever handle key agreement will need updating.
    145  */
    146 
    147 CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
    148 					X509 *recip, unsigned int flags)
    149 	{
    150 	CMS_RecipientInfo *ri = NULL;
    151 	CMS_KeyTransRecipientInfo *ktri;
    152 	CMS_EnvelopedData *env;
    153 	EVP_PKEY *pk = NULL;
    154 	int i, type;
    155 	env = cms_get0_enveloped(cms);
    156 	if (!env)
    157 		goto err;
    158 
    159 	/* Initialize recipient info */
    160 	ri = M_ASN1_new_of(CMS_RecipientInfo);
    161 	if (!ri)
    162 		goto merr;
    163 
    164 	/* Initialize and add key transport recipient info */
    165 
    166 	ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
    167 	if (!ri->d.ktri)
    168 		goto merr;
    169 	ri->type = CMS_RECIPINFO_TRANS;
    170 
    171 	ktri = ri->d.ktri;
    172 
    173 	X509_check_purpose(recip, -1, -1);
    174 	pk = X509_get_pubkey(recip);
    175 	if (!pk)
    176 		{
    177 		CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
    178 				CMS_R_ERROR_GETTING_PUBLIC_KEY);
    179 		goto err;
    180 		}
    181 	CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509);
    182 	ktri->pkey = pk;
    183 	ktri->recip = recip;
    184 
    185 	if (flags & CMS_USE_KEYID)
    186 		{
    187 		ktri->version = 2;
    188 		if (env->version < 2)
    189 			env->version = 2;
    190 		type = CMS_RECIPINFO_KEYIDENTIFIER;
    191 		}
    192 	else
    193 		{
    194 		ktri->version = 0;
    195 		type = CMS_RECIPINFO_ISSUER_SERIAL;
    196 		}
    197 
    198 	/* Not a typo: RecipientIdentifier and SignerIdentifier are the
    199 	 * same structure.
    200 	 */
    201 
    202 	if (!cms_set1_SignerIdentifier(ktri->rid, recip, type))
    203 		goto err;
    204 
    205 	if (pk->ameth && pk->ameth->pkey_ctrl)
    206 		{
    207 		i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE,
    208 						0, ri);
    209 		if (i == -2)
    210 			{
    211 			CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
    212 				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
    213 			goto err;
    214 			}
    215 		if (i <= 0)
    216 			{
    217 			CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
    218 				CMS_R_CTRL_FAILURE);
    219 			goto err;
    220 			}
    221 		}
    222 
    223 	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
    224 		goto merr;
    225 
    226 	return ri;
    227 
    228 	merr:
    229 	CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
    230 	err:
    231 	if (ri)
    232 		M_ASN1_free_of(ri, CMS_RecipientInfo);
    233 	return NULL;
    234 
    235 	}
    236 
    237 int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
    238 					EVP_PKEY **pk, X509 **recip,
    239 					X509_ALGOR **palg)
    240 	{
    241 	CMS_KeyTransRecipientInfo *ktri;
    242 	if (ri->type != CMS_RECIPINFO_TRANS)
    243 		{
    244 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
    245 			CMS_R_NOT_KEY_TRANSPORT);
    246 		return 0;
    247 		}
    248 
    249 	ktri = ri->d.ktri;
    250 
    251 	if (pk)
    252 		*pk = ktri->pkey;
    253 	if (recip)
    254 		*recip = ktri->recip;
    255 	if (palg)
    256 		*palg = ktri->keyEncryptionAlgorithm;
    257 	return 1;
    258 	}
    259 
    260 int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
    261 					ASN1_OCTET_STRING **keyid,
    262 					X509_NAME **issuer, ASN1_INTEGER **sno)
    263 	{
    264 	CMS_KeyTransRecipientInfo *ktri;
    265 	if (ri->type != CMS_RECIPINFO_TRANS)
    266 		{
    267 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
    268 			CMS_R_NOT_KEY_TRANSPORT);
    269 		return 0;
    270 		}
    271 	ktri = ri->d.ktri;
    272 
    273 	return cms_SignerIdentifier_get0_signer_id(ktri->rid,
    274 							keyid, issuer, sno);
    275 	}
    276 
    277 int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
    278 	{
    279 	if (ri->type != CMS_RECIPINFO_TRANS)
    280 		{
    281 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
    282 			CMS_R_NOT_KEY_TRANSPORT);
    283 		return -2;
    284 		}
    285 	return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
    286 	}
    287 
    288 int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
    289 	{
    290 	if (ri->type != CMS_RECIPINFO_TRANS)
    291 		{
    292 		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY,
    293 			CMS_R_NOT_KEY_TRANSPORT);
    294 		return 0;
    295 		}
    296 	ri->d.ktri->pkey = pkey;
    297 	return 1;
    298 	}
    299 
    300 /* Encrypt content key in key transport recipient info */
    301 
    302 static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
    303 					CMS_RecipientInfo *ri)
    304 	{
    305 	CMS_KeyTransRecipientInfo *ktri;
    306 	CMS_EncryptedContentInfo *ec;
    307 	EVP_PKEY_CTX *pctx = NULL;
    308 	unsigned char *ek = NULL;
    309 	size_t eklen;
    310 
    311 	int ret = 0;
    312 
    313 	if (ri->type != CMS_RECIPINFO_TRANS)
    314 		{
    315 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
    316 			CMS_R_NOT_KEY_TRANSPORT);
    317 		return 0;
    318 		}
    319 	ktri = ri->d.ktri;
    320 	ec = cms->d.envelopedData->encryptedContentInfo;
    321 
    322 	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
    323 	if (!pctx)
    324 		return 0;
    325 
    326 	if (EVP_PKEY_encrypt_init(pctx) <= 0)
    327 		goto err;
    328 
    329 	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
    330 				EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0)
    331 		{
    332 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
    333 		goto err;
    334 		}
    335 
    336 	if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
    337 		goto err;
    338 
    339 	ek = OPENSSL_malloc(eklen);
    340 
    341 	if (ek == NULL)
    342 		{
    343 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
    344 							ERR_R_MALLOC_FAILURE);
    345 		goto err;
    346 		}
    347 
    348 	if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
    349 		goto err;
    350 
    351 	ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
    352 	ek = NULL;
    353 
    354 	ret = 1;
    355 
    356 	err:
    357 	if (pctx)
    358 		EVP_PKEY_CTX_free(pctx);
    359 	if (ek)
    360 		OPENSSL_free(ek);
    361 	return ret;
    362 
    363 	}
    364 
    365 /* Decrypt content key from KTRI */
    366 
    367 static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
    368 							CMS_RecipientInfo *ri)
    369 	{
    370 	CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
    371 	EVP_PKEY_CTX *pctx = NULL;
    372 	unsigned char *ek = NULL;
    373 	size_t eklen;
    374 	int ret = 0;
    375 	CMS_EncryptedContentInfo *ec;
    376 	ec = cms->d.envelopedData->encryptedContentInfo;
    377 
    378 	if (ktri->pkey == NULL)
    379 		{
    380 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
    381 			CMS_R_NO_PRIVATE_KEY);
    382 		return 0;
    383 		}
    384 
    385 	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
    386 	if (!pctx)
    387 		return 0;
    388 
    389 	if (EVP_PKEY_decrypt_init(pctx) <= 0)
    390 		goto err;
    391 
    392 	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
    393 				EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0)
    394 		{
    395 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
    396 		goto err;
    397 		}
    398 
    399 	if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
    400 				ktri->encryptedKey->data,
    401 				ktri->encryptedKey->length) <= 0)
    402 		goto err;
    403 
    404 	ek = OPENSSL_malloc(eklen);
    405 
    406 	if (ek == NULL)
    407 		{
    408 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
    409 							ERR_R_MALLOC_FAILURE);
    410 		goto err;
    411 		}
    412 
    413 	if (EVP_PKEY_decrypt(pctx, ek, &eklen,
    414 				ktri->encryptedKey->data,
    415 				ktri->encryptedKey->length) <= 0)
    416 		{
    417 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
    418 		goto err;
    419 		}
    420 
    421 	ret = 1;
    422 
    423 	if (ec->key)
    424 		{
    425 		OPENSSL_cleanse(ec->key, ec->keylen);
    426 		OPENSSL_free(ec->key);
    427 		}
    428 
    429 	ec->key = ek;
    430 	ec->keylen = eklen;
    431 
    432 	err:
    433 	if (pctx)
    434 		EVP_PKEY_CTX_free(pctx);
    435 	if (!ret && ek)
    436 		OPENSSL_free(ek);
    437 
    438 	return ret;
    439 	}
    440 
    441 /* Key Encrypted Key (KEK) RecipientInfo routines */
    442 
    443 int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
    444 					const unsigned char *id, size_t idlen)
    445 	{
    446 	ASN1_OCTET_STRING tmp_os;
    447 	CMS_KEKRecipientInfo *kekri;
    448 	if (ri->type != CMS_RECIPINFO_KEK)
    449 		{
    450 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
    451 		return -2;
    452 		}
    453 	kekri = ri->d.kekri;
    454 	tmp_os.type = V_ASN1_OCTET_STRING;
    455 	tmp_os.flags = 0;
    456 	tmp_os.data = (unsigned char *)id;
    457 	tmp_os.length = (int)idlen;
    458 	return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
    459 	}
    460 
    461 /* For now hard code AES key wrap info */
    462 
    463 static size_t aes_wrap_keylen(int nid)
    464 	{
    465 	switch (nid)
    466 		{
    467 		case NID_id_aes128_wrap:
    468 		return 16;
    469 
    470 		case NID_id_aes192_wrap:
    471 		return  24;
    472 
    473 		case NID_id_aes256_wrap:
    474 		return  32;
    475 
    476 		default:
    477 		return 0;
    478 		}
    479 	}
    480 
    481 CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
    482 					unsigned char *key, size_t keylen,
    483 					unsigned char *id, size_t idlen,
    484 					ASN1_GENERALIZEDTIME *date,
    485 					ASN1_OBJECT *otherTypeId,
    486 					ASN1_TYPE *otherType)
    487 	{
    488 	CMS_RecipientInfo *ri = NULL;
    489 	CMS_EnvelopedData *env;
    490 	CMS_KEKRecipientInfo *kekri;
    491 	env = cms_get0_enveloped(cms);
    492 	if (!env)
    493 		goto err;
    494 
    495 	if (nid == NID_undef)
    496 		{
    497 		switch (keylen)
    498 			{
    499 			case 16:
    500 			nid = NID_id_aes128_wrap;
    501 			break;
    502 
    503 			case  24:
    504 			nid = NID_id_aes192_wrap;
    505 			break;
    506 
    507 			case  32:
    508 			nid = NID_id_aes256_wrap;
    509 			break;
    510 
    511 			default:
    512 			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
    513 						CMS_R_INVALID_KEY_LENGTH);
    514 			goto err;
    515 			}
    516 
    517 		}
    518 	else
    519 		{
    520 
    521 		size_t exp_keylen = aes_wrap_keylen(nid);
    522 
    523 		if (!exp_keylen)
    524 			{
    525 			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
    526 					CMS_R_UNSUPPORTED_KEK_ALGORITHM);
    527 			goto err;
    528 			}
    529 
    530 		if (keylen != exp_keylen)
    531 			{
    532 			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
    533 					CMS_R_INVALID_KEY_LENGTH);
    534 			goto err;
    535 			}
    536 
    537 		}
    538 
    539 	/* Initialize recipient info */
    540 	ri = M_ASN1_new_of(CMS_RecipientInfo);
    541 	if (!ri)
    542 		goto merr;
    543 
    544 	ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
    545 	if (!ri->d.kekri)
    546 		goto merr;
    547 	ri->type = CMS_RECIPINFO_KEK;
    548 
    549 	kekri = ri->d.kekri;
    550 
    551 	if (otherTypeId)
    552 		{
    553 		kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
    554 		if (kekri->kekid->other == NULL)
    555 			goto merr;
    556 		}
    557 
    558 	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
    559 		goto merr;
    560 
    561 
    562 	/* After this point no calls can fail */
    563 
    564 	kekri->version = 4;
    565 
    566 	kekri->key = key;
    567 	kekri->keylen = keylen;
    568 
    569 	ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
    570 
    571 	kekri->kekid->date = date;
    572 
    573 	if (kekri->kekid->other)
    574 		{
    575 		kekri->kekid->other->keyAttrId = otherTypeId;
    576 		kekri->kekid->other->keyAttr = otherType;
    577 		}
    578 
    579 	X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
    580 				OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
    581 
    582 	return ri;
    583 
    584 	merr:
    585 	CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
    586 	err:
    587 	if (ri)
    588 		M_ASN1_free_of(ri, CMS_RecipientInfo);
    589 	return NULL;
    590 
    591 	}
    592 
    593 int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
    594 					X509_ALGOR **palg,
    595 					ASN1_OCTET_STRING **pid,
    596 					ASN1_GENERALIZEDTIME **pdate,
    597 					ASN1_OBJECT **potherid,
    598 					ASN1_TYPE **pothertype)
    599 	{
    600 	CMS_KEKIdentifier *rkid;
    601 	if (ri->type != CMS_RECIPINFO_KEK)
    602 		{
    603 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
    604 		return 0;
    605 		}
    606 	rkid =  ri->d.kekri->kekid;
    607 	if (palg)
    608 		*palg = ri->d.kekri->keyEncryptionAlgorithm;
    609 	if (pid)
    610 		*pid = rkid->keyIdentifier;
    611 	if (pdate)
    612 		*pdate = rkid->date;
    613 	if (potherid)
    614 		{
    615 		if (rkid->other)
    616 			*potherid = rkid->other->keyAttrId;
    617 		else
    618 			*potherid = NULL;
    619 		}
    620 	if (pothertype)
    621 		{
    622 		if (rkid->other)
    623 			*pothertype = rkid->other->keyAttr;
    624 		else
    625 			*pothertype = NULL;
    626 		}
    627 	return 1;
    628 	}
    629 
    630 int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
    631 				unsigned char *key, size_t keylen)
    632 	{
    633 	CMS_KEKRecipientInfo *kekri;
    634 	if (ri->type != CMS_RECIPINFO_KEK)
    635 		{
    636 		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
    637 		return 0;
    638 		}
    639 
    640 	kekri = ri->d.kekri;
    641 	kekri->key = key;
    642 	kekri->keylen = keylen;
    643 	return 1;
    644 	}
    645 
    646 
    647 /* Encrypt content key in KEK recipient info */
    648 
    649 static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
    650 					CMS_RecipientInfo *ri)
    651 	{
    652 	CMS_EncryptedContentInfo *ec;
    653 	CMS_KEKRecipientInfo *kekri;
    654 	AES_KEY actx;
    655 	unsigned char *wkey = NULL;
    656 	int wkeylen;
    657 	int r = 0;
    658 
    659 	ec = cms->d.envelopedData->encryptedContentInfo;
    660 
    661 	kekri = ri->d.kekri;
    662 
    663 	if (!kekri->key)
    664 		{
    665 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
    666 		return 0;
    667 		}
    668 
    669 	if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx))
    670 		{
    671 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
    672 						CMS_R_ERROR_SETTING_KEY);
    673 		goto err;
    674 		}
    675 
    676 	wkey = OPENSSL_malloc(ec->keylen + 8);
    677 
    678 	if (!wkey)
    679 		{
    680 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
    681 						ERR_R_MALLOC_FAILURE);
    682 		goto err;
    683 		}
    684 
    685 	wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
    686 
    687 	if (wkeylen <= 0)
    688 		{
    689 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
    690 		goto err;
    691 		}
    692 
    693 	ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
    694 
    695 	r = 1;
    696 
    697 	err:
    698 
    699 	if (!r && wkey)
    700 		OPENSSL_free(wkey);
    701 	OPENSSL_cleanse(&actx, sizeof(actx));
    702 
    703 	return r;
    704 
    705 	}
    706 
    707 /* Decrypt content key in KEK recipient info */
    708 
    709 static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
    710 					CMS_RecipientInfo *ri)
    711 	{
    712 	CMS_EncryptedContentInfo *ec;
    713 	CMS_KEKRecipientInfo *kekri;
    714 	AES_KEY actx;
    715 	unsigned char *ukey = NULL;
    716 	int ukeylen;
    717 	int r = 0, wrap_nid;
    718 
    719 	ec = cms->d.envelopedData->encryptedContentInfo;
    720 
    721 	kekri = ri->d.kekri;
    722 
    723 	if (!kekri->key)
    724 		{
    725 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
    726 		return 0;
    727 		}
    728 
    729 	wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
    730 	if (aes_wrap_keylen(wrap_nid) != kekri->keylen)
    731 		{
    732 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
    733 			CMS_R_INVALID_KEY_LENGTH);
    734 		return 0;
    735 		}
    736 
    737 	/* If encrypted key length is invalid don't bother */
    738 
    739 	if (kekri->encryptedKey->length < 16)
    740 		{
    741 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
    742 					CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
    743 		goto err;
    744 		}
    745 
    746 	if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx))
    747 		{
    748 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
    749 						CMS_R_ERROR_SETTING_KEY);
    750 		goto err;
    751 		}
    752 
    753 	ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
    754 
    755 	if (!ukey)
    756 		{
    757 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
    758 						ERR_R_MALLOC_FAILURE);
    759 		goto err;
    760 		}
    761 
    762 	ukeylen = AES_unwrap_key(&actx, NULL, ukey,
    763 					kekri->encryptedKey->data,
    764 					kekri->encryptedKey->length);
    765 
    766 	if (ukeylen <= 0)
    767 		{
    768 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
    769 							CMS_R_UNWRAP_ERROR);
    770 		goto err;
    771 		}
    772 
    773 	ec->key = ukey;
    774 	ec->keylen = ukeylen;
    775 
    776 	r = 1;
    777 
    778 	err:
    779 
    780 	if (!r && ukey)
    781 		OPENSSL_free(ukey);
    782 	OPENSSL_cleanse(&actx, sizeof(actx));
    783 
    784 	return r;
    785 
    786 	}
    787 
    788 int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
    789 	{
    790 	switch(ri->type)
    791 		{
    792 		case CMS_RECIPINFO_TRANS:
    793 		return cms_RecipientInfo_ktri_decrypt(cms, ri);
    794 
    795 		case CMS_RECIPINFO_KEK:
    796 		return cms_RecipientInfo_kekri_decrypt(cms, ri);
    797 
    798 		case CMS_RECIPINFO_PASS:
    799 		return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
    800 
    801 		default:
    802 		CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
    803 			CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
    804 		return 0;
    805 		}
    806 	}
    807 
    808 BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
    809 	{
    810 	CMS_EncryptedContentInfo *ec;
    811 	STACK_OF(CMS_RecipientInfo) *rinfos;
    812 	CMS_RecipientInfo *ri;
    813 	int i, r, ok = 0;
    814 	BIO *ret;
    815 
    816 	/* Get BIO first to set up key */
    817 
    818 	ec = cms->d.envelopedData->encryptedContentInfo;
    819 	ret = cms_EncryptedContent_init_bio(ec);
    820 
    821 	/* If error or no cipher end of processing */
    822 
    823 	if (!ret || !ec->cipher)
    824 		return ret;
    825 
    826 	/* Now encrypt content key according to each RecipientInfo type */
    827 
    828 	rinfos = cms->d.envelopedData->recipientInfos;
    829 
    830 	for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++)
    831 		{
    832 		ri = sk_CMS_RecipientInfo_value(rinfos, i);
    833 
    834 		switch (ri->type)
    835 			{
    836 			case CMS_RECIPINFO_TRANS:
    837 			r = cms_RecipientInfo_ktri_encrypt(cms, ri);
    838 			break;
    839 
    840 			case CMS_RECIPINFO_KEK:
    841 			r = cms_RecipientInfo_kekri_encrypt(cms, ri);
    842 			break;
    843 
    844 			case CMS_RECIPINFO_PASS:
    845 			r = cms_RecipientInfo_pwri_crypt(cms, ri, 1);
    846 			break;
    847 
    848 			default:
    849 			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
    850 				CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
    851 			goto err;
    852 			}
    853 
    854 		if (r <= 0)
    855 			{
    856 			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
    857 				CMS_R_ERROR_SETTING_RECIPIENTINFO);
    858 			goto err;
    859 			}
    860 		}
    861 
    862 	ok = 1;
    863 
    864 	err:
    865 	ec->cipher = NULL;
    866 	if (ec->key)
    867 		{
    868 		OPENSSL_cleanse(ec->key, ec->keylen);
    869 		OPENSSL_free(ec->key);
    870 		ec->key = NULL;
    871 		ec->keylen = 0;
    872 		}
    873 	if (ok)
    874 		return ret;
    875 	BIO_free(ret);
    876 	return NULL;
    877 
    878 	}
    879