xref: /openbsd-src/lib/libcrypto/cms/cms_env.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /* crypto/cms/cms_env.c */
2 /* Written by Dr Stephen N Henson (steve@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@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 
64 /* CMS EnvelopedData Utilities */
65 
66 DECLARE_ASN1_ITEM(CMS_EnvelopedData)
67 DECLARE_ASN1_ITEM(CMS_RecipientInfo)
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 static 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 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 		type = CMS_RECIPINFO_KEYIDENTIFIER;
189 		}
190 	else
191 		{
192 		ktri->version = 0;
193 		type = CMS_RECIPINFO_ISSUER_SERIAL;
194 		}
195 
196 	/* Not a typo: RecipientIdentifier and SignerIdentifier are the
197 	 * same structure.
198 	 */
199 
200 	if (!cms_set1_SignerIdentifier(ktri->rid, recip, type))
201 		goto err;
202 
203 	/* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8,
204 	 * hard code algorithm parameters.
205 	 */
206 
207 	if (pk->type == EVP_PKEY_RSA)
208 		{
209 		X509_ALGOR_set0(ktri->keyEncryptionAlgorithm,
210 					OBJ_nid2obj(NID_rsaEncryption),
211 					V_ASN1_NULL, 0);
212 		}
213 	else
214 		{
215 		CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
216 				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
217 		goto err;
218 		}
219 
220 	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
221 		goto merr;
222 
223 	return ri;
224 
225 	merr:
226 	CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
227 	err:
228 	if (ri)
229 		M_ASN1_free_of(ri, CMS_RecipientInfo);
230 	return NULL;
231 
232 	}
233 
234 int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
235 					EVP_PKEY **pk, X509 **recip,
236 					X509_ALGOR **palg)
237 	{
238 	CMS_KeyTransRecipientInfo *ktri;
239 	if (ri->type != CMS_RECIPINFO_TRANS)
240 		{
241 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
242 			CMS_R_NOT_KEY_TRANSPORT);
243 		return 0;
244 		}
245 
246 	ktri = ri->d.ktri;
247 
248 	if (pk)
249 		*pk = ktri->pkey;
250 	if (recip)
251 		*recip = ktri->recip;
252 	if (palg)
253 		*palg = ktri->keyEncryptionAlgorithm;
254 	return 1;
255 	}
256 
257 int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
258 					ASN1_OCTET_STRING **keyid,
259 					X509_NAME **issuer, ASN1_INTEGER **sno)
260 	{
261 	CMS_KeyTransRecipientInfo *ktri;
262 	if (ri->type != CMS_RECIPINFO_TRANS)
263 		{
264 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
265 			CMS_R_NOT_KEY_TRANSPORT);
266 		return 0;
267 		}
268 	ktri = ri->d.ktri;
269 
270 	return cms_SignerIdentifier_get0_signer_id(ktri->rid,
271 							keyid, issuer, sno);
272 	}
273 
274 int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
275 	{
276 	if (ri->type != CMS_RECIPINFO_TRANS)
277 		{
278 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
279 			CMS_R_NOT_KEY_TRANSPORT);
280 		return -2;
281 		}
282 	return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
283 	}
284 
285 int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
286 	{
287 	if (ri->type != CMS_RECIPINFO_TRANS)
288 		{
289 		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY,
290 			CMS_R_NOT_KEY_TRANSPORT);
291 		return 0;
292 		}
293 	ri->d.ktri->pkey = pkey;
294 	return 1;
295 	}
296 
297 /* Encrypt content key in key transport recipient info */
298 
299 static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
300 					CMS_RecipientInfo *ri)
301 	{
302 	CMS_KeyTransRecipientInfo *ktri;
303 	CMS_EncryptedContentInfo *ec;
304 	unsigned char *ek = NULL;
305 	int eklen;
306 
307 	int ret = 0;
308 
309 	if (ri->type != CMS_RECIPINFO_TRANS)
310 		{
311 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
312 			CMS_R_NOT_KEY_TRANSPORT);
313 		return 0;
314 		}
315 	ktri = ri->d.ktri;
316 	ec = cms->d.envelopedData->encryptedContentInfo;
317 
318 	eklen = EVP_PKEY_size(ktri->pkey);
319 
320 	ek = OPENSSL_malloc(eklen);
321 
322 	if (ek == NULL)
323 		{
324 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
325 							ERR_R_MALLOC_FAILURE);
326 		goto err;
327 		}
328 
329 	eklen = EVP_PKEY_encrypt(ek, ec->key, ec->keylen, ktri->pkey);
330 
331 	if (eklen <= 0)
332 		goto err;
333 
334 	ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
335 	ek = NULL;
336 
337 	ret = 1;
338 
339 	err:
340 	if (ek)
341 		OPENSSL_free(ek);
342 	return ret;
343 
344 	}
345 
346 /* Decrypt content key from KTRI */
347 
348 static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
349 							CMS_RecipientInfo *ri)
350 	{
351 	CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
352 	unsigned char *ek = NULL;
353 	int eklen;
354 	int ret = 0;
355 
356 	if (ktri->pkey == NULL)
357 		{
358 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
359 			CMS_R_NO_PRIVATE_KEY);
360 		return 0;
361 		}
362 
363 	eklen = EVP_PKEY_size(ktri->pkey);
364 
365 	ek = OPENSSL_malloc(eklen);
366 
367 	if (ek == NULL)
368 		{
369 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
370 							ERR_R_MALLOC_FAILURE);
371 		goto err;
372 		}
373 
374 	eklen = EVP_PKEY_decrypt(ek,
375 				ktri->encryptedKey->data,
376 				ktri->encryptedKey->length, ktri->pkey);
377 	if (eklen <= 0)
378 		{
379 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
380 		goto err;
381 		}
382 
383 	ret = 1;
384 
385 	cms->d.envelopedData->encryptedContentInfo->key = ek;
386 	cms->d.envelopedData->encryptedContentInfo->keylen = eklen;
387 
388 	err:
389 	if (!ret && ek)
390 		OPENSSL_free(ek);
391 
392 	return ret;
393 	}
394 
395 /* Key Encrypted Key (KEK) RecipientInfo routines */
396 
397 int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
398 					const unsigned char *id, size_t idlen)
399 	{
400 	ASN1_OCTET_STRING tmp_os;
401 	CMS_KEKRecipientInfo *kekri;
402 	if (ri->type != CMS_RECIPINFO_KEK)
403 		{
404 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
405 		return -2;
406 		}
407 	kekri = ri->d.kekri;
408 	tmp_os.type = V_ASN1_OCTET_STRING;
409 	tmp_os.flags = 0;
410 	tmp_os.data = (unsigned char *)id;
411 	tmp_os.length = (int)idlen;
412 	return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
413 	}
414 
415 /* For now hard code AES key wrap info */
416 
417 static size_t aes_wrap_keylen(int nid)
418 	{
419 	switch (nid)
420 		{
421 		case NID_id_aes128_wrap:
422 		return 16;
423 
424 		case NID_id_aes192_wrap:
425 		return  24;
426 
427 		case NID_id_aes256_wrap:
428 		return  32;
429 
430 		default:
431 		return 0;
432 		}
433 	}
434 
435 CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
436 					unsigned char *key, size_t keylen,
437 					unsigned char *id, size_t idlen,
438 					ASN1_GENERALIZEDTIME *date,
439 					ASN1_OBJECT *otherTypeId,
440 					ASN1_TYPE *otherType)
441 	{
442 	CMS_RecipientInfo *ri = NULL;
443 	CMS_EnvelopedData *env;
444 	CMS_KEKRecipientInfo *kekri;
445 	env = cms_get0_enveloped(cms);
446 	if (!env)
447 		goto err;
448 
449 	if (nid == NID_undef)
450 		{
451 		switch (keylen)
452 			{
453 			case 16:
454 			nid = NID_id_aes128_wrap;
455 			break;
456 
457 			case  24:
458 			nid = NID_id_aes192_wrap;
459 			break;
460 
461 			case  32:
462 			nid = NID_id_aes256_wrap;
463 			break;
464 
465 			default:
466 			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
467 						CMS_R_INVALID_KEY_LENGTH);
468 			goto err;
469 			}
470 
471 		}
472 	else
473 		{
474 
475 		size_t exp_keylen = aes_wrap_keylen(nid);
476 
477 		if (!exp_keylen)
478 			{
479 			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
480 					CMS_R_UNSUPPORTED_KEK_ALGORITHM);
481 			goto err;
482 			}
483 
484 		if (keylen != exp_keylen)
485 			{
486 			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
487 					CMS_R_INVALID_KEY_LENGTH);
488 			goto err;
489 			}
490 
491 		}
492 
493 	/* Initialize recipient info */
494 	ri = M_ASN1_new_of(CMS_RecipientInfo);
495 	if (!ri)
496 		goto merr;
497 
498 	ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
499 	if (!ri->d.kekri)
500 		goto merr;
501 	ri->type = CMS_RECIPINFO_KEK;
502 
503 	kekri = ri->d.kekri;
504 
505 	if (otherTypeId)
506 		{
507 		kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
508 		if (kekri->kekid->other == NULL)
509 			goto merr;
510 		}
511 
512 	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
513 		goto merr;
514 
515 
516 	/* After this point no calls can fail */
517 
518 	kekri->version = 4;
519 
520 	kekri->key = key;
521 	kekri->keylen = keylen;
522 
523 	ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
524 
525 	kekri->kekid->date = date;
526 
527 	if (kekri->kekid->other)
528 		{
529 		kekri->kekid->other->keyAttrId = otherTypeId;
530 		kekri->kekid->other->keyAttr = otherType;
531 		}
532 
533 	X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
534 				OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
535 
536 	return ri;
537 
538 	merr:
539 	CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
540 	err:
541 	if (ri)
542 		M_ASN1_free_of(ri, CMS_RecipientInfo);
543 	return NULL;
544 
545 	}
546 
547 int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
548 					X509_ALGOR **palg,
549 					ASN1_OCTET_STRING **pid,
550 					ASN1_GENERALIZEDTIME **pdate,
551 					ASN1_OBJECT **potherid,
552 					ASN1_TYPE **pothertype)
553 	{
554 	CMS_KEKIdentifier *rkid;
555 	if (ri->type != CMS_RECIPINFO_KEK)
556 		{
557 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
558 		return 0;
559 		}
560 	rkid =  ri->d.kekri->kekid;
561 	if (palg)
562 		*palg = ri->d.kekri->keyEncryptionAlgorithm;
563 	if (pid)
564 		*pid = rkid->keyIdentifier;
565 	if (pdate)
566 		*pdate = rkid->date;
567 	if (potherid)
568 		{
569 		if (rkid->other)
570 			*potherid = rkid->other->keyAttrId;
571 		else
572 			*potherid = NULL;
573 		}
574 	if (pothertype)
575 		{
576 		if (rkid->other)
577 			*pothertype = rkid->other->keyAttr;
578 		else
579 			*pothertype = NULL;
580 		}
581 	return 1;
582 	}
583 
584 int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
585 				unsigned char *key, size_t keylen)
586 	{
587 	CMS_KEKRecipientInfo *kekri;
588 	if (ri->type != CMS_RECIPINFO_KEK)
589 		{
590 		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
591 		return 0;
592 		}
593 
594 	kekri = ri->d.kekri;
595 	kekri->key = key;
596 	kekri->keylen = keylen;
597 	return 1;
598 	}
599 
600 
601 /* Encrypt content key in KEK recipient info */
602 
603 static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
604 					CMS_RecipientInfo *ri)
605 	{
606 	CMS_EncryptedContentInfo *ec;
607 	CMS_KEKRecipientInfo *kekri;
608 	AES_KEY actx;
609 	unsigned char *wkey = NULL;
610 	int wkeylen;
611 	int r = 0;
612 
613 	ec = cms->d.envelopedData->encryptedContentInfo;
614 
615 	kekri = ri->d.kekri;
616 
617 	if (!kekri->key)
618 		{
619 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
620 		return 0;
621 		}
622 
623 	if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx))
624 		{
625 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
626 						CMS_R_ERROR_SETTING_KEY);
627 		goto err;
628 		}
629 
630 	wkey = OPENSSL_malloc(ec->keylen + 8);
631 
632 	if (!wkey)
633 		{
634 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
635 						ERR_R_MALLOC_FAILURE);
636 		goto err;
637 		}
638 
639 	wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
640 
641 	if (wkeylen <= 0)
642 		{
643 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
644 		goto err;
645 		}
646 
647 	ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
648 
649 	r = 1;
650 
651 	err:
652 
653 	if (!r && wkey)
654 		OPENSSL_free(wkey);
655 	OPENSSL_cleanse(&actx, sizeof(actx));
656 
657 	return r;
658 
659 	}
660 
661 /* Decrypt content key in KEK recipient info */
662 
663 static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
664 					CMS_RecipientInfo *ri)
665 	{
666 	CMS_EncryptedContentInfo *ec;
667 	CMS_KEKRecipientInfo *kekri;
668 	AES_KEY actx;
669 	unsigned char *ukey = NULL;
670 	int ukeylen;
671 	int r = 0, wrap_nid;
672 
673 	ec = cms->d.envelopedData->encryptedContentInfo;
674 
675 	kekri = ri->d.kekri;
676 
677 	if (!kekri->key)
678 		{
679 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
680 		return 0;
681 		}
682 
683 	wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
684 	if (aes_wrap_keylen(wrap_nid) != kekri->keylen)
685 		{
686 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
687 			CMS_R_INVALID_KEY_LENGTH);
688 		return 0;
689 		}
690 
691 	/* If encrypted key length is invalid don't bother */
692 
693 	if (kekri->encryptedKey->length < 16)
694 		{
695 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
696 					CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
697 		goto err;
698 		}
699 
700 	if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx))
701 		{
702 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
703 						CMS_R_ERROR_SETTING_KEY);
704 		goto err;
705 		}
706 
707 	ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
708 
709 	if (!ukey)
710 		{
711 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
712 						ERR_R_MALLOC_FAILURE);
713 		goto err;
714 		}
715 
716 	ukeylen = AES_unwrap_key(&actx, NULL, ukey,
717 					kekri->encryptedKey->data,
718 					kekri->encryptedKey->length);
719 
720 	if (ukeylen <= 0)
721 		{
722 		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
723 							CMS_R_UNWRAP_ERROR);
724 		goto err;
725 		}
726 
727 	ec->key = ukey;
728 	ec->keylen = ukeylen;
729 
730 	r = 1;
731 
732 	err:
733 
734 	if (!r && ukey)
735 		OPENSSL_free(ukey);
736 	OPENSSL_cleanse(&actx, sizeof(actx));
737 
738 	return r;
739 
740 	}
741 
742 int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
743 	{
744 	switch(ri->type)
745 		{
746 		case CMS_RECIPINFO_TRANS:
747 		return cms_RecipientInfo_ktri_decrypt(cms, ri);
748 
749 		case CMS_RECIPINFO_KEK:
750 		return cms_RecipientInfo_kekri_decrypt(cms, ri);
751 
752 		default:
753 		CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
754 			CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
755 		return 0;
756 		}
757 	}
758 
759 BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
760 	{
761 	CMS_EncryptedContentInfo *ec;
762 	STACK_OF(CMS_RecipientInfo) *rinfos;
763 	CMS_RecipientInfo *ri;
764 	int i, r, ok = 0;
765 	BIO *ret;
766 
767 	/* Get BIO first to set up key */
768 
769 	ec = cms->d.envelopedData->encryptedContentInfo;
770 	ret = cms_EncryptedContent_init_bio(ec);
771 
772 	/* If error or no cipher end of processing */
773 
774 	if (!ret || !ec->cipher)
775 		return ret;
776 
777 	/* Now encrypt content key according to each RecipientInfo type */
778 
779 	rinfos = cms->d.envelopedData->recipientInfos;
780 
781 	for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++)
782 		{
783 		ri = sk_CMS_RecipientInfo_value(rinfos, i);
784 
785 		switch (ri->type)
786 			{
787 			case CMS_RECIPINFO_TRANS:
788 			r = cms_RecipientInfo_ktri_encrypt(cms, ri);
789 			break;
790 
791 			case CMS_RECIPINFO_KEK:
792 			r = cms_RecipientInfo_kekri_encrypt(cms, ri);
793 			break;
794 
795 			default:
796 			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
797 				CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
798 			goto err;
799 			}
800 
801 		if (r <= 0)
802 			{
803 			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
804 				CMS_R_ERROR_SETTING_RECIPIENTINFO);
805 			goto err;
806 			}
807 		}
808 
809 	ok = 1;
810 
811 	err:
812 	ec->cipher = NULL;
813 	if (ec->key)
814 		{
815 		OPENSSL_cleanse(ec->key, ec->keylen);
816 		OPENSSL_free(ec->key);
817 		ec->key = NULL;
818 		ec->keylen = 0;
819 		}
820 	if (ok)
821 		return ret;
822 	BIO_free(ret);
823 	return NULL;
824 
825 	}
826