]> CyberLeo.Net >> Repos - FreeBSD/releng/10.1.git/blob - crypto/openssl/crypto/cms/cms_env.c
Fix multiple OpenSSL vulnerabilities.
[FreeBSD/releng/10.1.git] / crypto / openssl / crypto / cms / cms_env.c
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 {
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
85 static 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
103 STACK_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
112 int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
113 {
114     return ri->type;
115 }
116
117 CMS_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
145 CMS_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
226 int 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
248 int 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
264 int 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
274 int 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
286 static 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
346 static 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
415 int 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
434 static 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
451 CMS_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
552 int 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
586 int 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
603 static 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
658 static 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
729 int 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
748 BIO *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 }