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