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