summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/cms/cms_env.c
diff options
context:
space:
mode:
authorjsing <>2019-08-10 15:55:20 +0000
committerjsing <>2019-08-10 15:55:20 +0000
commita0845ead6d459f388701fe3fe8fa27635f4885f1 (patch)
treecfa2d4e7280cbfe7b7007556c8dcab6691e87b83 /src/lib/libcrypto/cms/cms_env.c
parent38e170324f2dafb68786e79022ddafab241aad3d (diff)
downloadopenbsd-a0845ead6d459f388701fe3fe8fa27635f4885f1.tar.gz
openbsd-a0845ead6d459f388701fe3fe8fa27635f4885f1.tar.bz2
openbsd-a0845ead6d459f388701fe3fe8fa27635f4885f1.zip
Work towards supporting Cryptographic Message Syntax (CMS) in libcrypto.
Cryptographic Message Syntax (CMS) is a standard for cryptographically protecting messages, as defined in RFC 5652. It is derived from PKCS #7 version 1.5 and utilises various ASN.1 structures, making it complex and fairly heavyweight. Various protocols - including RPKI (RFC 6480) - have been built on top of it, which means it is necessary to support CMS, in order to support RPKI. This imports around 6,000 lines of code from OpenSSL 1.1.1, which is still under the original OpenSSL license. Further work will occur in tree. Requested by and discussed with many. ok deraadt@ tb@
Diffstat (limited to 'src/lib/libcrypto/cms/cms_env.c')
-rw-r--r--src/lib/libcrypto/cms/cms_env.c903
1 files changed, 903 insertions, 0 deletions
diff --git a/src/lib/libcrypto/cms/cms_env.c b/src/lib/libcrypto/cms/cms_env.c
new file mode 100644
index 0000000000..bb95af75e3
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_env.c
@@ -0,0 +1,903 @@
1/*
2 * Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include "internal/cryptlib.h"
11#include <openssl/asn1t.h>
12#include <openssl/pem.h>
13#include <openssl/x509v3.h>
14#include <openssl/err.h>
15#include <openssl/cms.h>
16#include <openssl/aes.h>
17#include "cms_lcl.h"
18#include "internal/asn1_int.h"
19#include "internal/evp_int.h"
20
21/* CMS EnvelopedData Utilities */
22
23CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
24{
25 if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) {
26 CMSerr(CMS_F_CMS_GET0_ENVELOPED,
27 CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
28 return NULL;
29 }
30 return cms->d.envelopedData;
31}
32
33static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
34{
35 if (cms->d.other == NULL) {
36 cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
37 if (!cms->d.envelopedData) {
38 CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE);
39 return NULL;
40 }
41 cms->d.envelopedData->version = 0;
42 cms->d.envelopedData->encryptedContentInfo->contentType =
43 OBJ_nid2obj(NID_pkcs7_data);
44 ASN1_OBJECT_free(cms->contentType);
45 cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
46 return cms->d.envelopedData;
47 }
48 return cms_get0_enveloped(cms);
49}
50
51int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd)
52{
53 EVP_PKEY *pkey;
54 int i;
55 if (ri->type == CMS_RECIPINFO_TRANS)
56 pkey = ri->d.ktri->pkey;
57 else if (ri->type == CMS_RECIPINFO_AGREE) {
58 EVP_PKEY_CTX *pctx = ri->d.kari->pctx;
59 if (!pctx)
60 return 0;
61 pkey = EVP_PKEY_CTX_get0_pkey(pctx);
62 if (!pkey)
63 return 0;
64 } else
65 return 0;
66 if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
67 return 1;
68 i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri);
69 if (i == -2) {
70 CMSerr(CMS_F_CMS_ENV_ASN1_CTRL,
71 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
72 return 0;
73 }
74 if (i <= 0) {
75 CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE);
76 return 0;
77 }
78 return 1;
79}
80
81STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
82{
83 CMS_EnvelopedData *env;
84 env = cms_get0_enveloped(cms);
85 if (!env)
86 return NULL;
87 return env->recipientInfos;
88}
89
90int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
91{
92 return ri->type;
93}
94
95EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri)
96{
97 if (ri->type == CMS_RECIPINFO_TRANS)
98 return ri->d.ktri->pctx;
99 else if (ri->type == CMS_RECIPINFO_AGREE)
100 return ri->d.kari->pctx;
101 return NULL;
102}
103
104CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
105{
106 CMS_ContentInfo *cms;
107 CMS_EnvelopedData *env;
108 cms = CMS_ContentInfo_new();
109 if (cms == NULL)
110 goto merr;
111 env = cms_enveloped_data_init(cms);
112 if (env == NULL)
113 goto merr;
114 if (!cms_EncryptedContent_init(env->encryptedContentInfo,
115 cipher, NULL, 0))
116 goto merr;
117 return cms;
118 merr:
119 CMS_ContentInfo_free(cms);
120 CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
121 return NULL;
122}
123
124/* Key Transport Recipient Info (KTRI) routines */
125
126/* Initialise a ktri based on passed certificate and key */
127
128static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
129 EVP_PKEY *pk, unsigned int flags)
130{
131 CMS_KeyTransRecipientInfo *ktri;
132 int idtype;
133
134 ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
135 if (!ri->d.ktri)
136 return 0;
137 ri->type = CMS_RECIPINFO_TRANS;
138
139 ktri = ri->d.ktri;
140
141 if (flags & CMS_USE_KEYID) {
142 ktri->version = 2;
143 idtype = CMS_RECIPINFO_KEYIDENTIFIER;
144 } else {
145 ktri->version = 0;
146 idtype = CMS_RECIPINFO_ISSUER_SERIAL;
147 }
148
149 /*
150 * Not a typo: RecipientIdentifier and SignerIdentifier are the same
151 * structure.
152 */
153
154 if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype))
155 return 0;
156
157 X509_up_ref(recip);
158 EVP_PKEY_up_ref(pk);
159
160 ktri->pkey = pk;
161 ktri->recip = recip;
162
163 if (flags & CMS_KEY_PARAM) {
164 ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
165 if (ktri->pctx == NULL)
166 return 0;
167 if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0)
168 return 0;
169 } else if (!cms_env_asn1_ctrl(ri, 0))
170 return 0;
171 return 1;
172}
173
174/*
175 * Add a recipient certificate using appropriate type of RecipientInfo
176 */
177
178CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
179 X509 *recip, unsigned int flags)
180{
181 CMS_RecipientInfo *ri = NULL;
182 CMS_EnvelopedData *env;
183 EVP_PKEY *pk = NULL;
184 env = cms_get0_enveloped(cms);
185 if (!env)
186 goto err;
187
188 /* Initialize recipient info */
189 ri = M_ASN1_new_of(CMS_RecipientInfo);
190 if (!ri)
191 goto merr;
192
193 pk = X509_get0_pubkey(recip);
194 if (!pk) {
195 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY);
196 goto err;
197 }
198
199 switch (cms_pkey_get_ri_type(pk)) {
200
201 case CMS_RECIPINFO_TRANS:
202 if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags))
203 goto err;
204 break;
205
206 case CMS_RECIPINFO_AGREE:
207 if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags))
208 goto err;
209 break;
210
211 default:
212 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
213 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
214 goto err;
215
216 }
217
218 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
219 goto merr;
220
221 return ri;
222
223 merr:
224 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
225 err:
226 M_ASN1_free_of(ri, CMS_RecipientInfo);
227 return NULL;
228
229}
230
231int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
232 EVP_PKEY **pk, X509 **recip,
233 X509_ALGOR **palg)
234{
235 CMS_KeyTransRecipientInfo *ktri;
236 if (ri->type != CMS_RECIPINFO_TRANS) {
237 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
238 CMS_R_NOT_KEY_TRANSPORT);
239 return 0;
240 }
241
242 ktri = ri->d.ktri;
243
244 if (pk)
245 *pk = ktri->pkey;
246 if (recip)
247 *recip = ktri->recip;
248 if (palg)
249 *palg = ktri->keyEncryptionAlgorithm;
250 return 1;
251}
252
253int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
254 ASN1_OCTET_STRING **keyid,
255 X509_NAME **issuer,
256 ASN1_INTEGER **sno)
257{
258 CMS_KeyTransRecipientInfo *ktri;
259 if (ri->type != CMS_RECIPINFO_TRANS) {
260 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
261 CMS_R_NOT_KEY_TRANSPORT);
262 return 0;
263 }
264 ktri = ri->d.ktri;
265
266 return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno);
267}
268
269int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
270{
271 if (ri->type != CMS_RECIPINFO_TRANS) {
272 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
273 CMS_R_NOT_KEY_TRANSPORT);
274 return -2;
275 }
276 return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
277}
278
279int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
280{
281 if (ri->type != CMS_RECIPINFO_TRANS) {
282 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, CMS_R_NOT_KEY_TRANSPORT);
283 return 0;
284 }
285 EVP_PKEY_free(ri->d.ktri->pkey);
286 ri->d.ktri->pkey = pkey;
287 return 1;
288}
289
290/* Encrypt content key in key transport recipient info */
291
292static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
293 CMS_RecipientInfo *ri)
294{
295 CMS_KeyTransRecipientInfo *ktri;
296 CMS_EncryptedContentInfo *ec;
297 EVP_PKEY_CTX *pctx;
298 unsigned char *ek = NULL;
299 size_t eklen;
300
301 int ret = 0;
302
303 if (ri->type != CMS_RECIPINFO_TRANS) {
304 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT);
305 return 0;
306 }
307 ktri = ri->d.ktri;
308 ec = cms->d.envelopedData->encryptedContentInfo;
309
310 pctx = ktri->pctx;
311
312 if (pctx) {
313 if (!cms_env_asn1_ctrl(ri, 0))
314 goto err;
315 } else {
316 pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
317 if (pctx == NULL)
318 return 0;
319
320 if (EVP_PKEY_encrypt_init(pctx) <= 0)
321 goto err;
322 }
323
324 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
325 EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) {
326 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
327 goto err;
328 }
329
330 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
331 goto err;
332
333 ek = OPENSSL_malloc(eklen);
334
335 if (ek == NULL) {
336 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
337 goto err;
338 }
339
340 if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
341 goto err;
342
343 ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
344 ek = NULL;
345
346 ret = 1;
347
348 err:
349 EVP_PKEY_CTX_free(pctx);
350 ktri->pctx = NULL;
351 OPENSSL_free(ek);
352 return ret;
353
354}
355
356/* Decrypt content key from KTRI */
357
358static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
359 CMS_RecipientInfo *ri)
360{
361 CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
362 EVP_PKEY *pkey = ktri->pkey;
363 unsigned char *ek = NULL;
364 size_t eklen;
365 int ret = 0;
366 CMS_EncryptedContentInfo *ec;
367 ec = cms->d.envelopedData->encryptedContentInfo;
368
369 if (ktri->pkey == NULL) {
370 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY);
371 return 0;
372 }
373
374 ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
375 if (ktri->pctx == NULL)
376 return 0;
377
378 if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0)
379 goto err;
380
381 if (!cms_env_asn1_ctrl(ri, 1))
382 goto err;
383
384 if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT,
385 EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) {
386 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
387 goto err;
388 }
389
390 if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen,
391 ktri->encryptedKey->data,
392 ktri->encryptedKey->length) <= 0)
393 goto err;
394
395 ek = OPENSSL_malloc(eklen);
396
397 if (ek == NULL) {
398 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE);
399 goto err;
400 }
401
402 if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
403 ktri->encryptedKey->data,
404 ktri->encryptedKey->length) <= 0) {
405 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
406 goto err;
407 }
408
409 ret = 1;
410
411 OPENSSL_clear_free(ec->key, ec->keylen);
412 ec->key = ek;
413 ec->keylen = eklen;
414
415 err:
416 EVP_PKEY_CTX_free(ktri->pctx);
417 ktri->pctx = NULL;
418 if (!ret)
419 OPENSSL_free(ek);
420
421 return ret;
422}
423
424/* Key Encrypted Key (KEK) RecipientInfo routines */
425
426int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
427 const unsigned char *id, size_t idlen)
428{
429 ASN1_OCTET_STRING tmp_os;
430 CMS_KEKRecipientInfo *kekri;
431 if (ri->type != CMS_RECIPINFO_KEK) {
432 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
433 return -2;
434 }
435 kekri = ri->d.kekri;
436 tmp_os.type = V_ASN1_OCTET_STRING;
437 tmp_os.flags = 0;
438 tmp_os.data = (unsigned char *)id;
439 tmp_os.length = (int)idlen;
440 return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
441}
442
443/* For now hard code AES key wrap info */
444
445static size_t aes_wrap_keylen(int nid)
446{
447 switch (nid) {
448 case NID_id_aes128_wrap:
449 return 16;
450
451 case NID_id_aes192_wrap:
452 return 24;
453
454 case NID_id_aes256_wrap:
455 return 32;
456
457 default:
458 return 0;
459 }
460}
461
462CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
463 unsigned char *key, size_t keylen,
464 unsigned char *id, size_t idlen,
465 ASN1_GENERALIZEDTIME *date,
466 ASN1_OBJECT *otherTypeId,
467 ASN1_TYPE *otherType)
468{
469 CMS_RecipientInfo *ri = NULL;
470 CMS_EnvelopedData *env;
471 CMS_KEKRecipientInfo *kekri;
472 env = cms_get0_enveloped(cms);
473 if (!env)
474 goto err;
475
476 if (nid == NID_undef) {
477 switch (keylen) {
478 case 16:
479 nid = NID_id_aes128_wrap;
480 break;
481
482 case 24:
483 nid = NID_id_aes192_wrap;
484 break;
485
486 case 32:
487 nid = NID_id_aes256_wrap;
488 break;
489
490 default:
491 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
492 goto err;
493 }
494
495 } else {
496
497 size_t exp_keylen = aes_wrap_keylen(nid);
498
499 if (!exp_keylen) {
500 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
501 CMS_R_UNSUPPORTED_KEK_ALGORITHM);
502 goto err;
503 }
504
505 if (keylen != exp_keylen) {
506 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
507 goto err;
508 }
509
510 }
511
512 /* Initialize recipient info */
513 ri = M_ASN1_new_of(CMS_RecipientInfo);
514 if (!ri)
515 goto merr;
516
517 ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
518 if (!ri->d.kekri)
519 goto merr;
520 ri->type = CMS_RECIPINFO_KEK;
521
522 kekri = ri->d.kekri;
523
524 if (otherTypeId) {
525 kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
526 if (kekri->kekid->other == NULL)
527 goto merr;
528 }
529
530 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
531 goto merr;
532
533 /* After this point no calls can fail */
534
535 kekri->version = 4;
536
537 kekri->key = key;
538 kekri->keylen = keylen;
539
540 ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
541
542 kekri->kekid->date = date;
543
544 if (kekri->kekid->other) {
545 kekri->kekid->other->keyAttrId = otherTypeId;
546 kekri->kekid->other->keyAttr = otherType;
547 }
548
549 X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
550 OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
551
552 return ri;
553
554 merr:
555 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
556 err:
557 M_ASN1_free_of(ri, CMS_RecipientInfo);
558 return NULL;
559
560}
561
562int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
563 X509_ALGOR **palg,
564 ASN1_OCTET_STRING **pid,
565 ASN1_GENERALIZEDTIME **pdate,
566 ASN1_OBJECT **potherid,
567 ASN1_TYPE **pothertype)
568{
569 CMS_KEKIdentifier *rkid;
570 if (ri->type != CMS_RECIPINFO_KEK) {
571 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
572 return 0;
573 }
574 rkid = ri->d.kekri->kekid;
575 if (palg)
576 *palg = ri->d.kekri->keyEncryptionAlgorithm;
577 if (pid)
578 *pid = rkid->keyIdentifier;
579 if (pdate)
580 *pdate = rkid->date;
581 if (potherid) {
582 if (rkid->other)
583 *potherid = rkid->other->keyAttrId;
584 else
585 *potherid = NULL;
586 }
587 if (pothertype) {
588 if (rkid->other)
589 *pothertype = rkid->other->keyAttr;
590 else
591 *pothertype = NULL;
592 }
593 return 1;
594}
595
596int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
597 unsigned char *key, size_t keylen)
598{
599 CMS_KEKRecipientInfo *kekri;
600 if (ri->type != CMS_RECIPINFO_KEK) {
601 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
602 return 0;
603 }
604
605 kekri = ri->d.kekri;
606 kekri->key = key;
607 kekri->keylen = keylen;
608 return 1;
609}
610
611/* Encrypt content key in KEK recipient info */
612
613static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
614 CMS_RecipientInfo *ri)
615{
616 CMS_EncryptedContentInfo *ec;
617 CMS_KEKRecipientInfo *kekri;
618 AES_KEY actx;
619 unsigned char *wkey = NULL;
620 int wkeylen;
621 int r = 0;
622
623 ec = cms->d.envelopedData->encryptedContentInfo;
624
625 kekri = ri->d.kekri;
626
627 if (!kekri->key) {
628 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
629 return 0;
630 }
631
632 if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
633 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
634 CMS_R_ERROR_SETTING_KEY);
635 goto err;
636 }
637
638 wkey = OPENSSL_malloc(ec->keylen + 8);
639
640 if (wkey == NULL) {
641 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
642 goto err;
643 }
644
645 wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
646
647 if (wkeylen <= 0) {
648 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
649 goto err;
650 }
651
652 ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
653
654 r = 1;
655
656 err:
657
658 if (!r)
659 OPENSSL_free(wkey);
660 OPENSSL_cleanse(&actx, sizeof(actx));
661
662 return r;
663
664}
665
666/* Decrypt content key in KEK recipient info */
667
668static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
669 CMS_RecipientInfo *ri)
670{
671 CMS_EncryptedContentInfo *ec;
672 CMS_KEKRecipientInfo *kekri;
673 AES_KEY actx;
674 unsigned char *ukey = NULL;
675 int ukeylen;
676 int r = 0, wrap_nid;
677
678 ec = cms->d.envelopedData->encryptedContentInfo;
679
680 kekri = ri->d.kekri;
681
682 if (!kekri->key) {
683 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
684 return 0;
685 }
686
687 wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
688 if (aes_wrap_keylen(wrap_nid) != kekri->keylen) {
689 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
690 CMS_R_INVALID_KEY_LENGTH);
691 return 0;
692 }
693
694 /* If encrypted key length is invalid don't bother */
695
696 if (kekri->encryptedKey->length < 16) {
697 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
698 CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
699 goto err;
700 }
701
702 if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
703 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
704 CMS_R_ERROR_SETTING_KEY);
705 goto err;
706 }
707
708 ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
709
710 if (ukey == NULL) {
711 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE);
712 goto err;
713 }
714
715 ukeylen = AES_unwrap_key(&actx, NULL, ukey,
716 kekri->encryptedKey->data,
717 kekri->encryptedKey->length);
718
719 if (ukeylen <= 0) {
720 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR);
721 goto err;
722 }
723
724 ec->key = ukey;
725 ec->keylen = ukeylen;
726
727 r = 1;
728
729 err:
730
731 if (!r)
732 OPENSSL_free(ukey);
733 OPENSSL_cleanse(&actx, sizeof(actx));
734
735 return r;
736
737}
738
739int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
740{
741 switch (ri->type) {
742 case CMS_RECIPINFO_TRANS:
743 return cms_RecipientInfo_ktri_decrypt(cms, ri);
744
745 case CMS_RECIPINFO_KEK:
746 return cms_RecipientInfo_kekri_decrypt(cms, ri);
747
748 case CMS_RECIPINFO_PASS:
749 return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
750
751 default:
752 CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
753 CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE);
754 return 0;
755 }
756}
757
758int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
759{
760 switch (ri->type) {
761 case CMS_RECIPINFO_TRANS:
762 return cms_RecipientInfo_ktri_encrypt(cms, ri);
763
764 case CMS_RECIPINFO_AGREE:
765 return cms_RecipientInfo_kari_encrypt(cms, ri);
766
767 case CMS_RECIPINFO_KEK:
768 return cms_RecipientInfo_kekri_encrypt(cms, ri);
769
770 case CMS_RECIPINFO_PASS:
771 return cms_RecipientInfo_pwri_crypt(cms, ri, 1);
772
773 default:
774 CMSerr(CMS_F_CMS_RECIPIENTINFO_ENCRYPT,
775 CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
776 return 0;
777 }
778}
779
780/* Check structures and fixup version numbers (if necessary) */
781
782static void cms_env_set_originfo_version(CMS_EnvelopedData *env)
783{
784 CMS_OriginatorInfo *org = env->originatorInfo;
785 int i;
786 if (org == NULL)
787 return;
788 for (i = 0; i < sk_CMS_CertificateChoices_num(org->certificates); i++) {
789 CMS_CertificateChoices *cch;
790 cch = sk_CMS_CertificateChoices_value(org->certificates, i);
791 if (cch->type == CMS_CERTCHOICE_OTHER) {
792 env->version = 4;
793 return;
794 } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
795 if (env->version < 3)
796 env->version = 3;
797 }
798 }
799
800 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(org->crls); i++) {
801 CMS_RevocationInfoChoice *rch;
802 rch = sk_CMS_RevocationInfoChoice_value(org->crls, i);
803 if (rch->type == CMS_REVCHOICE_OTHER) {
804 env->version = 4;
805 return;
806 }
807 }
808}
809
810static void cms_env_set_version(CMS_EnvelopedData *env)
811{
812 int i;
813 CMS_RecipientInfo *ri;
814
815 /*
816 * Can't set version higher than 4 so if 4 or more already nothing to do.
817 */
818 if (env->version >= 4)
819 return;
820
821 cms_env_set_originfo_version(env);
822
823 if (env->version >= 3)
824 return;
825
826 for (i = 0; i < sk_CMS_RecipientInfo_num(env->recipientInfos); i++) {
827 ri = sk_CMS_RecipientInfo_value(env->recipientInfos, i);
828 if (ri->type == CMS_RECIPINFO_PASS || ri->type == CMS_RECIPINFO_OTHER) {
829 env->version = 3;
830 return;
831 } else if (ri->type != CMS_RECIPINFO_TRANS
832 || ri->d.ktri->version != 0) {
833 env->version = 2;
834 }
835 }
836 if (env->originatorInfo || env->unprotectedAttrs)
837 env->version = 2;
838 if (env->version == 2)
839 return;
840 env->version = 0;
841}
842
843BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
844{
845 CMS_EncryptedContentInfo *ec;
846 STACK_OF(CMS_RecipientInfo) *rinfos;
847 CMS_RecipientInfo *ri;
848 int i, ok = 0;
849 BIO *ret;
850
851 /* Get BIO first to set up key */
852
853 ec = cms->d.envelopedData->encryptedContentInfo;
854 ret = cms_EncryptedContent_init_bio(ec);
855
856 /* If error or no cipher end of processing */
857
858 if (!ret || !ec->cipher)
859 return ret;
860
861 /* Now encrypt content key according to each RecipientInfo type */
862
863 rinfos = cms->d.envelopedData->recipientInfos;
864
865 for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) {
866 ri = sk_CMS_RecipientInfo_value(rinfos, i);
867 if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) {
868 CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
869 CMS_R_ERROR_SETTING_RECIPIENTINFO);
870 goto err;
871 }
872 }
873 cms_env_set_version(cms->d.envelopedData);
874
875 ok = 1;
876
877 err:
878 ec->cipher = NULL;
879 OPENSSL_clear_free(ec->key, ec->keylen);
880 ec->key = NULL;
881 ec->keylen = 0;
882 if (ok)
883 return ret;
884 BIO_free(ret);
885 return NULL;
886
887}
888
889/*
890 * Get RecipientInfo type (if any) supported by a key (public or private). To
891 * retain compatibility with previous behaviour if the ctrl value isn't
892 * supported we assume key transport.
893 */
894int cms_pkey_get_ri_type(EVP_PKEY *pk)
895{
896 if (pk->ameth && pk->ameth->pkey_ctrl) {
897 int i, r;
898 i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r);
899 if (i > 0)
900 return r;
901 }
902 return CMS_RECIPINFO_TRANS;
903}