• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)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 
cms_enveloped_data_init(CMS_ContentInfo * cms)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 
STACK_OF(CMS_RecipientInfo)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 
CMS_RecipientInfo_type(CMS_RecipientInfo * ri)115 int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
116 	{
117 	return ri->type;
118 	}
119 
CMS_EnvelopedData_create(const EVP_CIPHER * cipher)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 
CMS_add1_recipient_cert(CMS_ContentInfo * cms,X509 * recip,unsigned int flags)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 
CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo * ri,EVP_PKEY ** pk,X509 ** recip,X509_ALGOR ** palg)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 
CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo * ri,ASN1_OCTET_STRING ** keyid,X509_NAME ** issuer,ASN1_INTEGER ** sno)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 
CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo * ri,X509 * cert)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 
CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo * ri,EVP_PKEY * pkey)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 
cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo * cms,CMS_RecipientInfo * ri)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 
cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo * cms,CMS_RecipientInfo * ri)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 
CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo * ri,const unsigned char * id,size_t idlen)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 
aes_wrap_keylen(int nid)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 
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)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 
CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo * ri,X509_ALGOR ** palg,ASN1_OCTET_STRING ** pid,ASN1_GENERALIZEDTIME ** pdate,ASN1_OBJECT ** potherid,ASN1_TYPE ** pothertype)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 
CMS_RecipientInfo_set0_key(CMS_RecipientInfo * ri,unsigned char * key,size_t keylen)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 
cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo * cms,CMS_RecipientInfo * ri)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 
cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo * cms,CMS_RecipientInfo * ri)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 
CMS_RecipientInfo_decrypt(CMS_ContentInfo * cms,CMS_RecipientInfo * ri)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 
cms_EnvelopedData_init_bio(CMS_ContentInfo * cms)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