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