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