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