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