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