Coverage Report

Created: 2022-11-30 06:20

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