]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/cms/cms_env.c
Rename OPENSSL_CTX prefix to OSSL_LIB_CTX
[thirdparty/openssl.git] / crypto / cms / cms_env.c
CommitLineData
0f113f3e 1/*
33388b44 2 * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved.
8931b30d 3 *
08ddd302 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
b1322259
RS
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
8931b30d
DSH
8 */
9
b39fc560 10#include "internal/cryptlib.h"
8931b30d
DSH
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>
2852c672 16#include <openssl/evp.h>
25f2138b
DMSP
17#include "crypto/asn1.h"
18#include "crypto/evp.h"
c1669f41
SL
19#include "crypto/x509.h"
20#include "cms_local.h"
8931b30d
DSH
21
22/* CMS EnvelopedData Utilities */
71434aed
DB
23static void cms_env_set_version(CMS_EnvelopedData *env);
24
924663c3
JZ
25#define CMS_ENVELOPED_STANDARD 1
26#define CMS_ENVELOPED_AUTH 2
27
28static int cms_get_enveloped_type(const CMS_ContentInfo *cms)
29{
30 int nid = OBJ_obj2nid(cms->contentType);
31
32 switch (nid) {
33 case NID_pkcs7_enveloped:
34 return CMS_ENVELOPED_STANDARD;
35
36 case NID_id_smime_ct_authEnvelopedData:
37 return CMS_ENVELOPED_AUTH;
38
39 default:
40 CMSerr(0, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
41 return 0;
42 }
43}
44
d2a53c22 45CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
0f113f3e
MC
46{
47 if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) {
48 CMSerr(CMS_F_CMS_GET0_ENVELOPED,
49 CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
50 return NULL;
51 }
52 return cms->d.envelopedData;
53}
8931b30d 54
924663c3
JZ
55CMS_AuthEnvelopedData *cms_get0_auth_enveloped(CMS_ContentInfo *cms)
56{
57 if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_authEnvelopedData) {
58 CMSerr(0, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
59 return NULL;
60 }
61 return cms->d.authEnvelopedData;
62}
63
8931b30d 64static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
0f113f3e
MC
65{
66 if (cms->d.other == NULL) {
67 cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
924663c3 68 if (cms->d.envelopedData == NULL) {
0f113f3e
MC
69 CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE);
70 return NULL;
71 }
72 cms->d.envelopedData->version = 0;
73 cms->d.envelopedData->encryptedContentInfo->contentType =
74 OBJ_nid2obj(NID_pkcs7_data);
75 ASN1_OBJECT_free(cms->contentType);
76 cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
77 return cms->d.envelopedData;
78 }
79 return cms_get0_enveloped(cms);
80}
8931b30d 81
924663c3
JZ
82static CMS_AuthEnvelopedData *
83cms_auth_enveloped_data_init(CMS_ContentInfo *cms)
84{
85 if (cms->d.other == NULL) {
86 cms->d.authEnvelopedData = M_ASN1_new_of(CMS_AuthEnvelopedData);
87 if (cms->d.authEnvelopedData == NULL) {
88 CMSerr(0, ERR_R_MALLOC_FAILURE);
89 return NULL;
90 }
91 /* Defined in RFC 5083 - Section 2.1. "AuthEnvelopedData Type" */
92 cms->d.authEnvelopedData->version = 0;
93 cms->d.authEnvelopedData->authEncryptedContentInfo->contentType =
94 OBJ_nid2obj(NID_pkcs7_data);
95 ASN1_OBJECT_free(cms->contentType);
96 cms->contentType = OBJ_nid2obj(NID_id_smime_ct_authEnvelopedData);
97 return cms->d.authEnvelopedData;
98 }
99 return cms_get0_auth_enveloped(cms);
100}
101
17c2764d 102int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd)
0f113f3e
MC
103{
104 EVP_PKEY *pkey;
105 int i;
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;
12a765a5
RS
110
111 if (pctx == NULL)
0f113f3e
MC
112 return 0;
113 pkey = EVP_PKEY_CTX_get0_pkey(pctx);
12a765a5 114 if (pkey == NULL)
0f113f3e
MC
115 return 0;
116 } else
117 return 0;
0b3a4ef2 118
9ab7fe48 119#ifndef OPENSSL_NO_DH
0b3a4ef2
MC
120 if (EVP_PKEY_is_a(pkey, "DHX"))
121 return cms_dh_envelope(ri, cmd);
9ab7fe48
MC
122 else
123#endif
124#ifndef OPENSSL_NO_EC
125 if (EVP_PKEY_is_a(pkey, "EC"))
0b3a4ef2 126 return cms_ecdh_envelope(ri, cmd);
9ab7fe48
MC
127 else
128#endif
129 if (EVP_PKEY_is_a(pkey, "RSA"))
0b3a4ef2
MC
130 return cms_rsa_envelope(ri, cmd);
131
132 /* Something else? We'll give engines etc a chance to handle this */
12a765a5 133 if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
0f113f3e
MC
134 return 1;
135 i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri);
136 if (i == -2) {
137 CMSerr(CMS_F_CMS_ENV_ASN1_CTRL,
138 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
139 return 0;
140 }
141 if (i <= 0) {
142 CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE);
143 return 0;
144 }
145 return 1;
146}
e365352d 147
924663c3
JZ
148CMS_EncryptedContentInfo* cms_get0_env_enc_content(const CMS_ContentInfo *cms)
149{
150 switch (cms_get_enveloped_type(cms)) {
151 case CMS_ENVELOPED_STANDARD:
152 return cms->d.envelopedData->encryptedContentInfo;
153
154 case CMS_ENVELOPED_AUTH:
155 return cms->d.authEnvelopedData->authEncryptedContentInfo;
156
157 default:
158 return NULL;
159 }
160}
161
4f1aa191 162STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
0f113f3e 163{
924663c3
JZ
164 switch (cms_get_enveloped_type(cms)) {
165 case CMS_ENVELOPED_STANDARD:
166 return cms->d.envelopedData->recipientInfos;
167
168 case CMS_ENVELOPED_AUTH:
169 return cms->d.authEnvelopedData->recipientInfos;
170
171 default:
0f113f3e 172 return NULL;
924663c3 173 }
0f113f3e 174}
4f1aa191 175
c1669f41
SL
176void cms_RecipientInfos_set_cmsctx(CMS_ContentInfo *cms)
177{
178 int i;
179 CMS_RecipientInfo *ri;
180 const CMS_CTX *ctx = cms_get0_cmsctx(cms);
181 STACK_OF(CMS_RecipientInfo) *rinfos = CMS_get0_RecipientInfos(cms);
182
183 for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) {
184 ri = sk_CMS_RecipientInfo_value(rinfos, i);
185 if (ri != NULL) {
186 switch (ri->type) {
187 case CMS_RECIPINFO_AGREE:
188 ri->d.kari->cms_ctx = ctx;
189 break;
190 case CMS_RECIPINFO_TRANS:
191 ri->d.ktri->cms_ctx = ctx;
192 x509_set0_libctx(ri->d.ktri->recip, ctx->libctx, ctx->propq);
193 break;
194 case CMS_RECIPINFO_KEK:
195 ri->d.kekri->cms_ctx = ctx;
196 break;
197 case CMS_RECIPINFO_PASS:
198 ri->d.pwri->cms_ctx = ctx;
199 break;
200 default:
201 break;
202 }
203 }
204 }
205}
206
4f1aa191 207int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
0f113f3e
MC
208{
209 return ri->type;
210}
4f1aa191 211
e365352d 212EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri)
0f113f3e
MC
213{
214 if (ri->type == CMS_RECIPINFO_TRANS)
215 return ri->d.ktri->pctx;
216 else if (ri->type == CMS_RECIPINFO_AGREE)
217 return ri->d.kari->pctx;
218 return NULL;
219}
e365352d 220
d8652be0 221CMS_ContentInfo *CMS_EnvelopedData_create_ex(const EVP_CIPHER *cipher,
b4250010 222 OSSL_LIB_CTX *libctx,
d8652be0 223 const char *propq)
0f113f3e
MC
224{
225 CMS_ContentInfo *cms;
226 CMS_EnvelopedData *env;
c1669f41 227
d8652be0 228 cms = CMS_ContentInfo_new_ex(libctx, propq);
90945fa3 229 if (cms == NULL)
0f113f3e
MC
230 goto merr;
231 env = cms_enveloped_data_init(cms);
90945fa3 232 if (env == NULL)
0f113f3e 233 goto merr;
c1669f41
SL
234
235 if (!cms_EncryptedContent_init(env->encryptedContentInfo, cipher, NULL, 0,
236 cms_get0_cmsctx(cms)))
0f113f3e
MC
237 goto merr;
238 return cms;
239 merr:
25aaa98a 240 CMS_ContentInfo_free(cms);
c1669f41 241 CMSerr(0, ERR_R_MALLOC_FAILURE);
0f113f3e
MC
242 return NULL;
243}
761ffa72 244
c1669f41
SL
245CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
246{
d8652be0 247 return CMS_EnvelopedData_create_ex(cipher, NULL, NULL);
c1669f41
SL
248}
249
924663c3 250CMS_ContentInfo *
b4250010 251CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *libctx,
d8652be0 252 const char *propq)
71434aed 253{
924663c3
JZ
254 CMS_ContentInfo *cms;
255 CMS_AuthEnvelopedData *aenv;
71434aed 256
d8652be0 257 cms = CMS_ContentInfo_new_ex(libctx, propq);
924663c3
JZ
258 if (cms == NULL)
259 goto merr;
260 aenv = cms_auth_enveloped_data_init(cms);
261 if (aenv == NULL)
262 goto merr;
263 if (!cms_EncryptedContent_init(aenv->authEncryptedContentInfo,
264 cipher, NULL, 0, cms_get0_cmsctx(cms)))
265 goto merr;
266 return cms;
267 merr:
268 CMS_ContentInfo_free(cms);
269 CMSerr(0, ERR_R_MALLOC_FAILURE);
270 return NULL;
271}
71434aed 272
71434aed 273
924663c3
JZ
274CMS_ContentInfo *CMS_AuthEnvelopedData_create(const EVP_CIPHER *cipher)
275{
d8652be0 276 return CMS_AuthEnvelopedData_create_ex(cipher, NULL, NULL);
71434aed
DB
277}
278
ab124380
DSH
279/* Key Transport Recipient Info (KTRI) routines */
280
17c2764d 281/* Initialise a ktri based on passed certificate and key */
ab124380 282
17c2764d 283static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
c1669f41
SL
284 EVP_PKEY *pk, unsigned int flags,
285 const CMS_CTX *ctx)
0f113f3e
MC
286{
287 CMS_KeyTransRecipientInfo *ktri;
288 int idtype;
289
290 ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
291 if (!ri->d.ktri)
292 return 0;
293 ri->type = CMS_RECIPINFO_TRANS;
294
295 ktri = ri->d.ktri;
c1669f41 296 ktri->cms_ctx = ctx;
0f113f3e
MC
297
298 if (flags & CMS_USE_KEYID) {
299 ktri->version = 2;
300 idtype = CMS_RECIPINFO_KEYIDENTIFIER;
301 } else {
302 ktri->version = 0;
303 idtype = CMS_RECIPINFO_ISSUER_SERIAL;
304 }
305
306 /*
307 * Not a typo: RecipientIdentifier and SignerIdentifier are the same
308 * structure.
309 */
310
c1669f41 311 if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype, ctx))
0f113f3e
MC
312 return 0;
313
05f0fb9f 314 X509_up_ref(recip);
03273d61
AG
315 EVP_PKEY_up_ref(pk);
316
0f113f3e
MC
317 ktri->pkey = pk;
318 ktri->recip = recip;
319
320 if (flags & CMS_KEY_PARAM) {
c1669f41
SL
321 ktri->pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, ktri->pkey,
322 ctx->propq);
90945fa3 323 if (ktri->pctx == NULL)
0f113f3e
MC
324 return 0;
325 if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0)
326 return 0;
327 } else if (!cms_env_asn1_ctrl(ri, 0))
328 return 0;
329 return 1;
330}
331
332/*
333 * Add a recipient certificate using appropriate type of RecipientInfo
17c2764d
DSH
334 */
335
71434aed
DB
336CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip,
337 EVP_PKEY *originatorPrivKey,
338 X509 *originator, unsigned int flags)
0f113f3e
MC
339{
340 CMS_RecipientInfo *ri = NULL;
924663c3 341 STACK_OF(CMS_RecipientInfo) *ris;
0f113f3e 342 EVP_PKEY *pk = NULL;
c1669f41
SL
343 const CMS_CTX *ctx = cms_get0_cmsctx(cms);
344
924663c3
JZ
345 ris = CMS_get0_RecipientInfos(cms);
346 if (ris == NULL)
0f113f3e
MC
347 goto err;
348
349 /* Initialize recipient info */
350 ri = M_ASN1_new_of(CMS_RecipientInfo);
924663c3 351 if (ri == NULL)
0f113f3e
MC
352 goto merr;
353
8382fd3a 354 pk = X509_get0_pubkey(recip);
12a765a5 355 if (pk == NULL) {
71434aed 356 CMSerr(CMS_F_CMS_ADD1_RECIPIENT, CMS_R_ERROR_GETTING_PUBLIC_KEY);
0f113f3e
MC
357 goto err;
358 }
359
360 switch (cms_pkey_get_ri_type(pk)) {
361
362 case CMS_RECIPINFO_TRANS:
c1669f41 363 if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags, ctx))
0f113f3e
MC
364 goto err;
365 break;
366
367 case CMS_RECIPINFO_AGREE:
c1669f41
SL
368 if (!cms_RecipientInfo_kari_init(ri, recip, pk, originator,
369 originatorPrivKey, flags, ctx))
0f113f3e
MC
370 goto err;
371 break;
372
373 default:
71434aed 374 CMSerr(CMS_F_CMS_ADD1_RECIPIENT,
0f113f3e
MC
375 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
376 goto err;
377
378 }
379
924663c3 380 if (!sk_CMS_RecipientInfo_push(ris, ri))
0f113f3e
MC
381 goto merr;
382
0f113f3e
MC
383 return ri;
384
385 merr:
71434aed 386 CMSerr(CMS_F_CMS_ADD1_RECIPIENT, ERR_R_MALLOC_FAILURE);
0f113f3e 387 err:
2ace7450 388 M_ASN1_free_of(ri, CMS_RecipientInfo);
0f113f3e
MC
389 return NULL;
390
391}
8931b30d 392
924663c3
JZ
393CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip,
394 unsigned int flags)
71434aed
DB
395{
396 return CMS_add1_recipient(cms, recip, NULL, NULL, flags);
397}
398
8931b30d 399int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
0f113f3e
MC
400 EVP_PKEY **pk, X509 **recip,
401 X509_ALGOR **palg)
402{
403 CMS_KeyTransRecipientInfo *ktri;
404 if (ri->type != CMS_RECIPINFO_TRANS) {
405 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
406 CMS_R_NOT_KEY_TRANSPORT);
407 return 0;
408 }
409
410 ktri = ri->d.ktri;
411
412 if (pk)
413 *pk = ktri->pkey;
414 if (recip)
415 *recip = ktri->recip;
416 if (palg)
417 *palg = ktri->keyEncryptionAlgorithm;
418 return 1;
419}
8931b30d
DSH
420
421int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
0f113f3e
MC
422 ASN1_OCTET_STRING **keyid,
423 X509_NAME **issuer,
424 ASN1_INTEGER **sno)
425{
426 CMS_KeyTransRecipientInfo *ktri;
427 if (ri->type != CMS_RECIPINFO_TRANS) {
428 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
429 CMS_R_NOT_KEY_TRANSPORT);
430 return 0;
431 }
432 ktri = ri->d.ktri;
433
434 return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno);
435}
8931b30d
DSH
436
437int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
0f113f3e
MC
438{
439 if (ri->type != CMS_RECIPINFO_TRANS) {
440 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
441 CMS_R_NOT_KEY_TRANSPORT);
442 return -2;
443 }
444 return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
445}
4f1aa191 446
6e3bc4f0 447int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
0f113f3e
MC
448{
449 if (ri->type != CMS_RECIPINFO_TRANS) {
450 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, CMS_R_NOT_KEY_TRANSPORT);
451 return 0;
452 }
3d551b20 453 EVP_PKEY_free(ri->d.ktri->pkey);
0f113f3e
MC
454 ri->d.ktri->pkey = pkey;
455 return 1;
456}
6e3bc4f0 457
761ffa72
DSH
458/* Encrypt content key in key transport recipient info */
459
9fdcc21f 460static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms,
0f113f3e
MC
461 CMS_RecipientInfo *ri)
462{
463 CMS_KeyTransRecipientInfo *ktri;
464 CMS_EncryptedContentInfo *ec;
465 EVP_PKEY_CTX *pctx;
466 unsigned char *ek = NULL;
467 size_t eklen;
c1669f41 468 const CMS_CTX *ctx = cms_get0_cmsctx(cms);
0f113f3e
MC
469
470 int ret = 0;
471
472 if (ri->type != CMS_RECIPINFO_TRANS) {
473 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT);
474 return 0;
475 }
476 ktri = ri->d.ktri;
924663c3 477 ec = cms_get0_env_enc_content(cms);
0f113f3e
MC
478
479 pctx = ktri->pctx;
480
481 if (pctx) {
482 if (!cms_env_asn1_ctrl(ri, 0))
483 goto err;
484 } else {
c1669f41 485 pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, ktri->pkey, ctx->propq);
90945fa3 486 if (pctx == NULL)
0f113f3e
MC
487 return 0;
488
489 if (EVP_PKEY_encrypt_init(pctx) <= 0)
490 goto err;
491 }
492
493 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
494 EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) {
495 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
496 goto err;
497 }
498
499 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
500 goto err;
501
502 ek = OPENSSL_malloc(eklen);
503
504 if (ek == NULL) {
505 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
506 goto err;
507 }
508
509 if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
510 goto err;
511
512 ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
513 ek = NULL;
514
515 ret = 1;
516
517 err:
25aaa98a
RS
518 EVP_PKEY_CTX_free(pctx);
519 ktri->pctx = NULL;
b548a1f1 520 OPENSSL_free(ek);
0f113f3e 521 return ret;
0f113f3e 522}
761ffa72 523
ab124380
DSH
524/* Decrypt content key from KTRI */
525
6e3bc4f0 526static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
0f113f3e
MC
527 CMS_RecipientInfo *ri)
528{
529 CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
530 EVP_PKEY *pkey = ktri->pkey;
531 unsigned char *ek = NULL;
532 size_t eklen;
533 int ret = 0;
5840ed0c 534 size_t fixlen = 0;
1acb2e6f
SL
535 const EVP_CIPHER *cipher = NULL;
536 EVP_CIPHER *fetched_cipher = NULL;
0f113f3e 537 CMS_EncryptedContentInfo *ec;
c1669f41
SL
538 const CMS_CTX *ctx = cms_get0_cmsctx(cms);
539
924663c3 540 ec = cms_get0_env_enc_content(cms);
0f113f3e
MC
541
542 if (ktri->pkey == NULL) {
543 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY);
544 return 0;
545 }
546
5840ed0c
BE
547 if (cms->d.envelopedData->encryptedContentInfo->havenocert
548 && !cms->d.envelopedData->encryptedContentInfo->debug) {
549 X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
c1669f41 550 const char *name = OBJ_nid2sn(OBJ_obj2nid(calg->algorithm));
5840ed0c 551
1acb2e6f
SL
552 (void)ERR_set_mark();
553 fetched_cipher = EVP_CIPHER_fetch(ctx->libctx, name, ctx->propq);
554
555 if (fetched_cipher != NULL)
556 cipher = fetched_cipher;
557 else
558 cipher = EVP_get_cipherbyobj(calg->algorithm);
559 if (cipher == NULL) {
560 (void)ERR_clear_last_mark();
5840ed0c
BE
561 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_UNKNOWN_CIPHER);
562 return 0;
563 }
1acb2e6f 564 (void)ERR_pop_to_mark();
5840ed0c 565
1acb2e6f
SL
566 fixlen = EVP_CIPHER_key_length(cipher);
567 EVP_CIPHER_free(fetched_cipher);
5840ed0c
BE
568 }
569
c1669f41 570 ktri->pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pkey, ctx->propq);
90945fa3 571 if (ktri->pctx == NULL)
c1669f41 572 goto err;
0f113f3e
MC
573
574 if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0)
575 goto err;
576
577 if (!cms_env_asn1_ctrl(ri, 1))
578 goto err;
579
580 if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT,
581 EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) {
582 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
583 goto err;
584 }
585
586 if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen,
587 ktri->encryptedKey->data,
588 ktri->encryptedKey->length) <= 0)
589 goto err;
590
591 ek = OPENSSL_malloc(eklen);
0f113f3e
MC
592 if (ek == NULL) {
593 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE);
594 goto err;
595 }
596
597 if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
598 ktri->encryptedKey->data,
5840ed0c
BE
599 ktri->encryptedKey->length) <= 0
600 || eklen == 0
601 || (fixlen != 0 && eklen != fixlen)) {
0f113f3e
MC
602 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
603 goto err;
604 }
605
606 ret = 1;
607
4b45c6e5 608 OPENSSL_clear_free(ec->key, ec->keylen);
0f113f3e
MC
609 ec->key = ek;
610 ec->keylen = eklen;
611
612 err:
c5ba2d99
RS
613 EVP_PKEY_CTX_free(ktri->pctx);
614 ktri->pctx = NULL;
b548a1f1 615 if (!ret)
0f113f3e
MC
616 OPENSSL_free(ek);
617
618 return ret;
619}
4f1aa191 620
ab124380
DSH
621/* Key Encrypted Key (KEK) RecipientInfo routines */
622
0f113f3e
MC
623int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
624 const unsigned char *id, size_t idlen)
625{
626 ASN1_OCTET_STRING tmp_os;
627 CMS_KEKRecipientInfo *kekri;
628 if (ri->type != CMS_RECIPINFO_KEK) {
629 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
630 return -2;
631 }
632 kekri = ri->d.kekri;
633 tmp_os.type = V_ASN1_OCTET_STRING;
634 tmp_os.flags = 0;
635 tmp_os.data = (unsigned char *)id;
636 tmp_os.length = (int)idlen;
637 return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
638}
eeb9cdfc 639
ab124380
DSH
640/* For now hard code AES key wrap info */
641
642static size_t aes_wrap_keylen(int nid)
0f113f3e
MC
643{
644 switch (nid) {
645 case NID_id_aes128_wrap:
646 return 16;
ab124380 647
0f113f3e
MC
648 case NID_id_aes192_wrap:
649 return 24;
ab124380 650
0f113f3e
MC
651 case NID_id_aes256_wrap:
652 return 32;
ab124380 653
0f113f3e
MC
654 default:
655 return 0;
656 }
657}
ab124380
DSH
658
659CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
0f113f3e
MC
660 unsigned char *key, size_t keylen,
661 unsigned char *id, size_t idlen,
662 ASN1_GENERALIZEDTIME *date,
663 ASN1_OBJECT *otherTypeId,
664 ASN1_TYPE *otherType)
665{
666 CMS_RecipientInfo *ri = NULL;
0f113f3e 667 CMS_KEKRecipientInfo *kekri;
924663c3
JZ
668 STACK_OF(CMS_RecipientInfo) *ris = CMS_get0_RecipientInfos(cms);
669
670 if (ris == NULL)
0f113f3e 671 goto err;
ab124380 672
0f113f3e
MC
673 if (nid == NID_undef) {
674 switch (keylen) {
675 case 16:
676 nid = NID_id_aes128_wrap;
677 break;
ab124380 678
0f113f3e
MC
679 case 24:
680 nid = NID_id_aes192_wrap;
681 break;
682
683 case 32:
684 nid = NID_id_aes256_wrap;
685 break;
686
687 default:
688 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
689 goto err;
690 }
691
692 } else {
693
694 size_t exp_keylen = aes_wrap_keylen(nid);
695
696 if (!exp_keylen) {
697 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
698 CMS_R_UNSUPPORTED_KEK_ALGORITHM);
699 goto err;
700 }
701
702 if (keylen != exp_keylen) {
703 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
704 goto err;
705 }
706
707 }
708
709 /* Initialize recipient info */
710 ri = M_ASN1_new_of(CMS_RecipientInfo);
711 if (!ri)
712 goto merr;
713
714 ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
715 if (!ri->d.kekri)
716 goto merr;
717 ri->type = CMS_RECIPINFO_KEK;
718
719 kekri = ri->d.kekri;
720
721 if (otherTypeId) {
722 kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
723 if (kekri->kekid->other == NULL)
724 goto merr;
725 }
ab124380 726
924663c3 727 if (!sk_CMS_RecipientInfo_push(ris, ri))
0f113f3e
MC
728 goto merr;
729
730 /* After this point no calls can fail */
731
732 kekri->version = 4;
733
734 kekri->key = key;
735 kekri->keylen = keylen;
736
737 ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
738
739 kekri->kekid->date = date;
740
741 if (kekri->kekid->other) {
742 kekri->kekid->other->keyAttrId = otherTypeId;
743 kekri->kekid->other->keyAttr = otherType;
744 }
745
746 X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
747 OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
748
749 return ri;
750
751 merr:
752 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
753 err:
2ace7450 754 M_ASN1_free_of(ri, CMS_RecipientInfo);
0f113f3e 755 return NULL;
0f113f3e
MC
756}
757
758int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
759 X509_ALGOR **palg,
760 ASN1_OCTET_STRING **pid,
761 ASN1_GENERALIZEDTIME **pdate,
762 ASN1_OBJECT **potherid,
763 ASN1_TYPE **pothertype)
764{
765 CMS_KEKIdentifier *rkid;
766 if (ri->type != CMS_RECIPINFO_KEK) {
767 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
768 return 0;
769 }
770 rkid = ri->d.kekri->kekid;
771 if (palg)
772 *palg = ri->d.kekri->keyEncryptionAlgorithm;
773 if (pid)
774 *pid = rkid->keyIdentifier;
775 if (pdate)
776 *pdate = rkid->date;
777 if (potherid) {
778 if (rkid->other)
779 *potherid = rkid->other->keyAttrId;
780 else
781 *potherid = NULL;
782 }
783 if (pothertype) {
784 if (rkid->other)
785 *pothertype = rkid->other->keyAttr;
786 else
787 *pothertype = NULL;
788 }
789 return 1;
790}
791
792int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
793 unsigned char *key, size_t keylen)
794{
795 CMS_KEKRecipientInfo *kekri;
796 if (ri->type != CMS_RECIPINFO_KEK) {
797 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
798 return 0;
799 }
800
801 kekri = ri->d.kekri;
802 kekri->key = key;
803 kekri->keylen = keylen;
804 return 1;
805}
6e3bc4f0 806
c1669f41 807static EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen, const CMS_CTX *ctx)
2852c672 808{
c1669f41
SL
809 const char *alg = NULL;
810
2852c672
MC
811 switch(keylen) {
812 case 16:
c1669f41
SL
813 alg = "AES-128-WRAP";
814 break;
2852c672 815 case 24:
c1669f41
SL
816 alg = "AES-192-WRAP";
817 break;
2852c672 818 case 32:
c1669f41
SL
819 alg = "AES-256-WRAP";
820 break;
821 default:
822 return NULL;
2852c672 823 }
c1669f41 824 return EVP_CIPHER_fetch(ctx->libctx, alg, ctx->propq);
2852c672
MC
825}
826
827
6e3bc4f0
DSH
828/* Encrypt content key in KEK recipient info */
829
9fdcc21f 830static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms,
0f113f3e
MC
831 CMS_RecipientInfo *ri)
832{
833 CMS_EncryptedContentInfo *ec;
834 CMS_KEKRecipientInfo *kekri;
0f113f3e
MC
835 unsigned char *wkey = NULL;
836 int wkeylen;
837 int r = 0;
c1669f41 838 EVP_CIPHER *cipher = NULL;
2852c672
MC
839 int outlen = 0;
840 EVP_CIPHER_CTX *ctx = NULL;
c1669f41 841 const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms);
6e3bc4f0 842
924663c3
JZ
843 ec = cms_get0_env_enc_content(cms);
844 if (ec == NULL)
845 return 0;
6e3bc4f0 846
0f113f3e 847 kekri = ri->d.kekri;
6e3bc4f0 848
2852c672 849 if (kekri->key == NULL) {
0f113f3e
MC
850 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
851 return 0;
852 }
6e3bc4f0 853
c1669f41 854 cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx);
2852c672
MC
855 if (cipher == NULL) {
856 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_INVALID_KEY_LENGTH);
0f113f3e
MC
857 goto err;
858 }
6e3bc4f0 859
2852c672 860 /* 8 byte prefix for AES wrap ciphers */
0f113f3e 861 wkey = OPENSSL_malloc(ec->keylen + 8);
90945fa3 862 if (wkey == NULL) {
0f113f3e
MC
863 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
864 goto err;
865 }
6e3bc4f0 866
2852c672
MC
867 ctx = EVP_CIPHER_CTX_new();
868 if (ctx == NULL) {
869 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
870 goto err;
871 }
6e3bc4f0 872
2852c672
MC
873 EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
874 if (!EVP_EncryptInit_ex(ctx, cipher, NULL, kekri->key, NULL)
875 || !EVP_EncryptUpdate(ctx, wkey, &wkeylen, ec->key, ec->keylen)
876 || !EVP_EncryptFinal_ex(ctx, wkey + wkeylen, &outlen)) {
877 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
878 goto err;
879 }
880 wkeylen += outlen;
881 if (!ossl_assert((size_t)wkeylen == ec->keylen + 8)) {
0f113f3e
MC
882 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
883 goto err;
884 }
6e3bc4f0 885
0f113f3e 886 ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
6e3bc4f0 887
0f113f3e 888 r = 1;
6e3bc4f0 889
0f113f3e 890 err:
c1669f41 891 EVP_CIPHER_free(cipher);
b548a1f1 892 if (!r)
0f113f3e 893 OPENSSL_free(wkey);
2852c672 894 EVP_CIPHER_CTX_free(ctx);
6e3bc4f0 895
0f113f3e 896 return r;
0f113f3e 897}
6e3bc4f0 898
ab124380
DSH
899/* Decrypt content key in KEK recipient info */
900
6e3bc4f0 901static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
0f113f3e
MC
902 CMS_RecipientInfo *ri)
903{
904 CMS_EncryptedContentInfo *ec;
905 CMS_KEKRecipientInfo *kekri;
0f113f3e
MC
906 unsigned char *ukey = NULL;
907 int ukeylen;
908 int r = 0, wrap_nid;
c1669f41 909 EVP_CIPHER *cipher = NULL;
2852c672
MC
910 int outlen = 0;
911 EVP_CIPHER_CTX *ctx = NULL;
c1669f41 912 const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms);
0f113f3e 913
924663c3
JZ
914 ec = cms_get0_env_enc_content(cms);
915 if (ec == NULL)
916 return 0;
0f113f3e
MC
917
918 kekri = ri->d.kekri;
919
920 if (!kekri->key) {
921 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
922 return 0;
923 }
924
925 wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
926 if (aes_wrap_keylen(wrap_nid) != kekri->keylen) {
927 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
928 CMS_R_INVALID_KEY_LENGTH);
929 return 0;
930 }
931
932 /* If encrypted key length is invalid don't bother */
933
934 if (kekri->encryptedKey->length < 16) {
935 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
936 CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
937 goto err;
938 }
939
c1669f41 940 cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx);
2852c672
MC
941 if (cipher == NULL) {
942 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_INVALID_KEY_LENGTH);
0f113f3e
MC
943 goto err;
944 }
945
946 ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
90945fa3 947 if (ukey == NULL) {
0f113f3e
MC
948 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE);
949 goto err;
950 }
951
2852c672
MC
952 ctx = EVP_CIPHER_CTX_new();
953 if (ctx == NULL) {
954 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE);
955 goto err;
956 }
0f113f3e 957
2852c672
MC
958 if (!EVP_DecryptInit_ex(ctx, cipher, NULL, kekri->key, NULL)
959 || !EVP_DecryptUpdate(ctx, ukey, &ukeylen,
960 kekri->encryptedKey->data,
961 kekri->encryptedKey->length)
962 || !EVP_DecryptFinal_ex(ctx, ukey + ukeylen, &outlen)) {
0f113f3e
MC
963 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR);
964 goto err;
965 }
2852c672 966 ukeylen += outlen;
0f113f3e
MC
967
968 ec->key = ukey;
969 ec->keylen = ukeylen;
970
971 r = 1;
972
973 err:
c1669f41 974 EVP_CIPHER_free(cipher);
b548a1f1 975 if (!r)
0f113f3e 976 OPENSSL_free(ukey);
2852c672 977 EVP_CIPHER_CTX_free(ctx);
0f113f3e
MC
978
979 return r;
0f113f3e 980}
6e3bc4f0
DSH
981
982int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
0f113f3e
MC
983{
984 switch (ri->type) {
985 case CMS_RECIPINFO_TRANS:
986 return cms_RecipientInfo_ktri_decrypt(cms, ri);
6e3bc4f0 987
0f113f3e
MC
988 case CMS_RECIPINFO_KEK:
989 return cms_RecipientInfo_kekri_decrypt(cms, ri);
6e3bc4f0 990
0f113f3e
MC
991 case CMS_RECIPINFO_PASS:
992 return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
d2a53c22 993
0f113f3e
MC
994 default:
995 CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
df578aa0 996 CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE);
0f113f3e
MC
997 return 0;
998 }
999}
6e3bc4f0 1000
9fdcc21f 1001int CMS_RecipientInfo_encrypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
0f113f3e
MC
1002{
1003 switch (ri->type) {
1004 case CMS_RECIPINFO_TRANS:
1005 return cms_RecipientInfo_ktri_encrypt(cms, ri);
1006
1007 case CMS_RECIPINFO_AGREE:
1008 return cms_RecipientInfo_kari_encrypt(cms, ri);
1009
1010 case CMS_RECIPINFO_KEK:
1011 return cms_RecipientInfo_kekri_encrypt(cms, ri);
0f113f3e
MC
1012
1013 case CMS_RECIPINFO_PASS:
1014 return cms_RecipientInfo_pwri_crypt(cms, ri, 1);
0f113f3e
MC
1015
1016 default:
1017 CMSerr(CMS_F_CMS_RECIPIENTINFO_ENCRYPT,
1018 CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
1019 return 0;
1020 }
1021}
e1f1d28f 1022
ff7b6ce9
DSH
1023/* Check structures and fixup version numbers (if necessary) */
1024
1025static void cms_env_set_originfo_version(CMS_EnvelopedData *env)
0f113f3e
MC
1026{
1027 CMS_OriginatorInfo *org = env->originatorInfo;
1028 int i;
1029 if (org == NULL)
1030 return;
1031 for (i = 0; i < sk_CMS_CertificateChoices_num(org->certificates); i++) {
1032 CMS_CertificateChoices *cch;
1033 cch = sk_CMS_CertificateChoices_value(org->certificates, i);
1034 if (cch->type == CMS_CERTCHOICE_OTHER) {
1035 env->version = 4;
1036 return;
1037 } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
1038 if (env->version < 3)
1039 env->version = 3;
1040 }
1041 }
1042
1043 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(org->crls); i++) {
1044 CMS_RevocationInfoChoice *rch;
1045 rch = sk_CMS_RevocationInfoChoice_value(org->crls, i);
1046 if (rch->type == CMS_REVCHOICE_OTHER) {
1047 env->version = 4;
1048 return;
1049 }
1050 }
1051}
ff7b6ce9
DSH
1052
1053static void cms_env_set_version(CMS_EnvelopedData *env)
0f113f3e
MC
1054{
1055 int i;
1056 CMS_RecipientInfo *ri;
1057
1058 /*
1059 * Can't set version higher than 4 so if 4 or more already nothing to do.
1060 */
1061 if (env->version >= 4)
1062 return;
1063
1064 cms_env_set_originfo_version(env);
1065
1066 if (env->version >= 3)
1067 return;
1068
1069 for (i = 0; i < sk_CMS_RecipientInfo_num(env->recipientInfos); i++) {
1070 ri = sk_CMS_RecipientInfo_value(env->recipientInfos, i);
1071 if (ri->type == CMS_RECIPINFO_PASS || ri->type == CMS_RECIPINFO_OTHER) {
1072 env->version = 3;
1073 return;
1074 } else if (ri->type != CMS_RECIPINFO_TRANS
1075 || ri->d.ktri->version != 0) {
1076 env->version = 2;
1077 }
1078 }
0f113f3e
MC
1079 if (env->originatorInfo || env->unprotectedAttrs)
1080 env->version = 2;
35096e91
RS
1081 if (env->version == 2)
1082 return;
0f113f3e
MC
1083 env->version = 0;
1084}
ff7b6ce9 1085
924663c3
JZ
1086static int cms_env_encrypt_content_key(const CMS_ContentInfo *cms,
1087 STACK_OF(CMS_RecipientInfo) *ris)
1088{
1089 int i;
1090 CMS_RecipientInfo *ri;
1091
1092 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
1093 ri = sk_CMS_RecipientInfo_value(ris, i);
1094 if (CMS_RecipientInfo_encrypt(cms, ri) <= 0)
1095 return -1;
1096 }
1097 return 1;
1098}
1099
1100static void cms_env_clear_ec(CMS_EncryptedContentInfo *ec)
1101{
1102 ec->cipher = NULL;
1103 OPENSSL_clear_free(ec->key, ec->keylen);
1104 ec->key = NULL;
1105 ec->keylen = 0;
1106}
1107
71434aed
DB
1108static BIO *cms_EnvelopedData_Decryption_init_bio(CMS_ContentInfo *cms)
1109{
1110 CMS_EncryptedContentInfo *ec = cms->d.envelopedData->encryptedContentInfo;
c1669f41 1111 BIO *contentBio = cms_EncryptedContent_init_bio(ec, cms_get0_cmsctx(cms));
71434aed
DB
1112 EVP_CIPHER_CTX *ctx = NULL;
1113
1114 if (contentBio == NULL)
1115 return NULL;
1116
1117 BIO_get_cipher_ctx(contentBio, &ctx);
1118 if (ctx == NULL) {
1119 BIO_free(contentBio);
1120 return NULL;
1121 }
924663c3
JZ
1122 /*
1123 * If the selected cipher supports unprotected attributes,
1124 * deal with it using special ctrl function
1125 */
71434aed
DB
1126 if ((EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_CIPHER_WITH_MAC)
1127 && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED, 0,
1128 cms->d.envelopedData->unprotectedAttrs) <= 0) {
1129 BIO_free(contentBio);
1130 return NULL;
1131 }
1132 return contentBio;
1133}
1134
1135static BIO *cms_EnvelopedData_Encryption_init_bio(CMS_ContentInfo *cms)
0f113f3e
MC
1136{
1137 CMS_EncryptedContentInfo *ec;
1138 STACK_OF(CMS_RecipientInfo) *rinfos;
924663c3 1139 int ok = 0;
0f113f3e 1140 BIO *ret;
924663c3 1141 CMS_EnvelopedData *env = cms->d.envelopedData;
0f113f3e
MC
1142
1143 /* Get BIO first to set up key */
1144
924663c3 1145 ec = env->encryptedContentInfo;
c1669f41 1146 ret = cms_EncryptedContent_init_bio(ec, cms_get0_cmsctx(cms));
0f113f3e 1147
71434aed
DB
1148 /* If error end of processing */
1149 if (!ret)
0f113f3e
MC
1150 return ret;
1151
1152 /* Now encrypt content key according to each RecipientInfo type */
924663c3
JZ
1153 rinfos = env->recipientInfos;
1154 if (cms_env_encrypt_content_key(cms, rinfos) < 0) {
1155 CMSerr(CMS_F_CMS_ENVELOPEDDATA_ENCRYPTION_INIT_BIO,
1156 CMS_R_ERROR_SETTING_RECIPIENTINFO);
1157 goto err;
0f113f3e 1158 }
924663c3
JZ
1159
1160 /* And finally set the version */
1161 cms_env_set_version(env);
0f113f3e
MC
1162
1163 ok = 1;
1164
1165 err:
924663c3 1166 cms_env_clear_ec(ec);
0f113f3e
MC
1167 if (ok)
1168 return ret;
1169 BIO_free(ret);
1170 return NULL;
71434aed
DB
1171}
1172
1173BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
1174{
1175 if (cms->d.envelopedData->encryptedContentInfo->cipher != NULL) {
1176 /* If cipher is set it's encryption */
1177 return cms_EnvelopedData_Encryption_init_bio(cms);
1178 }
0f113f3e 1179
71434aed
DB
1180 /* If cipher is not set it's decryption */
1181 return cms_EnvelopedData_Decryption_init_bio(cms);
0f113f3e
MC
1182}
1183
924663c3
JZ
1184BIO *cms_AuthEnvelopedData_init_bio(CMS_ContentInfo *cms)
1185{
1186 CMS_EncryptedContentInfo *ec;
1187 STACK_OF(CMS_RecipientInfo) *rinfos;
1188 int ok = 0;
1189 BIO *ret;
1190 CMS_AuthEnvelopedData *aenv = cms->d.authEnvelopedData;
1191
1192 /* Get BIO first to set up key */
1193 ec = aenv->authEncryptedContentInfo;
1194 /* Set tag for decryption */
1195 if (ec->cipher == NULL) {
1196 ec->tag = aenv->mac->data;
1197 ec->taglen = aenv->mac->length;
1198 }
1199 ret = cms_EncryptedContent_init_bio(ec, cms_get0_cmsctx(cms));
1200
1201 /* If error or no cipher end of processing */
1202 if (ret == NULL || ec->cipher == NULL)
1203 return ret;
1204
1205 /* Now encrypt content key according to each RecipientInfo type */
1206 rinfos = aenv->recipientInfos;
1207 if (cms_env_encrypt_content_key(cms, rinfos) < 0) {
1208 CMSerr(0, CMS_R_ERROR_SETTING_RECIPIENTINFO);
1209 goto err;
1210 }
1211
1212 /* And finally set the version */
1213 aenv->version = 0;
1214
1215 ok = 1;
1216
1217 err:
1218 cms_env_clear_ec(ec);
1219 if (ok)
1220 return ret;
1221 BIO_free(ret);
1222 return NULL;
1223}
1224
1225int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain)
1226{
1227 CMS_EnvelopedData *env = NULL;
1228 EVP_CIPHER_CTX *ctx = NULL;
1229 BIO *mbio = BIO_find_type(chain, BIO_TYPE_CIPHER);
1230
1231 env = cms_get0_enveloped(cms);
1232 if (env == NULL)
1233 return 0;
1234
1235 if (mbio == NULL) {
1236 CMSerr(CMS_F_CMS_ENVELOPEDDATA_FINAL, CMS_R_CONTENT_NOT_FOUND);
1237 return 0;
1238 }
1239
1240 BIO_get_cipher_ctx(mbio, &ctx);
1241
1242 /*
1243 * If the selected cipher supports unprotected attributes,
1244 * deal with it using special ctrl function
1245 */
1246 if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_CIPHER_WITH_MAC) {
1247 if (env->unprotectedAttrs == NULL)
1248 env->unprotectedAttrs = sk_X509_ATTRIBUTE_new_null();
1249
1250 if (env->unprotectedAttrs == NULL) {
1251 CMSerr(CMS_F_CMS_ENVELOPEDDATA_FINAL, ERR_R_MALLOC_FAILURE);
1252 return 0;
1253 }
1254
1255 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED,
1256 1, env->unprotectedAttrs) <= 0) {
1257 CMSerr(CMS_F_CMS_ENVELOPEDDATA_FINAL, CMS_R_CTRL_FAILURE);
1258 return 0;
1259 }
1260 }
1261
1262 cms_env_set_version(cms->d.envelopedData);
1263 return 1;
1264}
1265
1266int cms_AuthEnvelopedData_final(CMS_ContentInfo *cms, BIO *cmsbio)
1267{
1268 EVP_CIPHER_CTX *ctx;
1269 unsigned char *tag = NULL;
1270 int taglen, ok = 0;
1271
1272 BIO_get_cipher_ctx(cmsbio, &ctx);
1273
1274 /*
1275 * The tag is set only for encryption. There is nothing to do for
1276 * decryption.
1277 */
1278 if (!EVP_CIPHER_CTX_encrypting(ctx))
1279 return 1;
1280
1281 taglen = EVP_CIPHER_CTX_tag_length(ctx);
1282 if (taglen <= 0
1283 || (tag = OPENSSL_malloc(taglen)) == NULL
1284 || EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen,
1285 tag) <= 0) {
1286 CMSerr(0, CMS_R_CIPHER_GET_TAG);
1287 goto err;
1288 }
1289
1290 if (!ASN1_OCTET_STRING_set(cms->d.authEnvelopedData->mac, tag, taglen))
1291 goto err;
1292
1293 ok = 1;
1294err:
1295 OPENSSL_free(tag);
1296 return ok;
1297}
1298
0f113f3e
MC
1299/*
1300 * Get RecipientInfo type (if any) supported by a key (public or private). To
1301 * retain compatibility with previous behaviour if the ctrl value isn't
17c2764d
DSH
1302 * supported we assume key transport.
1303 */
1304int cms_pkey_get_ri_type(EVP_PKEY *pk)
0f113f3e 1305{
7022d9b9
MC
1306 /* Check types that we know about */
1307 if (EVP_PKEY_is_a(pk, "DH"))
1308 return CMS_RECIPINFO_AGREE;
1309 else if (EVP_PKEY_is_a(pk, "DSA"))
1310 return CMS_RECIPINFO_NONE;
1311 else if (EVP_PKEY_is_a(pk, "EC"))
1312 return CMS_RECIPINFO_AGREE;
1313 else if (EVP_PKEY_is_a(pk, "RSA"))
1314 return CMS_RECIPINFO_TRANS;
1315
1316 /*
1317 * Otherwise this might ben an engine implementation, so see if we can get
1318 * the type from the ameth.
1319 */
0f113f3e
MC
1320 if (pk->ameth && pk->ameth->pkey_ctrl) {
1321 int i, r;
1322 i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r);
1323 if (i > 0)
1324 return r;
1325 }
1326 return CMS_RECIPINFO_TRANS;
1327}
71434aed
DB
1328
1329int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type)
1330{
1331 int supportedRiType;
1332
1333 if (pk->ameth != NULL && pk->ameth->pkey_ctrl != NULL) {
1334 int i, r;
1335
c1669f41
SL
1336 i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED,
1337 ri_type, &r);
71434aed
DB
1338 if (i > 0)
1339 return r;
1340 }
1341
1342 supportedRiType = cms_pkey_get_ri_type(pk);
1343 if (supportedRiType < 0)
1344 return 0;
1345
1346 return (supportedRiType == ri_type);
1347}