Run util/openssl-format-source -v -c .
[openssl.git] / 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
65 /* CMS EnvelopedData Utilities */
66
67 DECLARE_ASN1_ITEM(CMS_EnvelopedData)
68 DECLARE_ASN1_ITEM(CMS_RecipientInfo)
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 static 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 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     /*
200      * Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8, hard code
201      * algorithm parameters.
202      */
203
204     if (pk->type == EVP_PKEY_RSA) {
205         X509_ALGOR_set0(ktri->keyEncryptionAlgorithm,
206                         OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
207     } else {
208         CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
209                CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
210         goto err;
211     }
212
213     if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
214         goto merr;
215
216     return ri;
217
218  merr:
219     CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
220  err:
221     if (ri)
222         M_ASN1_free_of(ri, CMS_RecipientInfo);
223     return NULL;
224
225 }
226
227 int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
228                                      EVP_PKEY **pk, X509 **recip,
229                                      X509_ALGOR **palg)
230 {
231     CMS_KeyTransRecipientInfo *ktri;
232     if (ri->type != CMS_RECIPINFO_TRANS) {
233         CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
234                CMS_R_NOT_KEY_TRANSPORT);
235         return 0;
236     }
237
238     ktri = ri->d.ktri;
239
240     if (pk)
241         *pk = ktri->pkey;
242     if (recip)
243         *recip = ktri->recip;
244     if (palg)
245         *palg = ktri->keyEncryptionAlgorithm;
246     return 1;
247 }
248
249 int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
250                                           ASN1_OCTET_STRING **keyid,
251                                           X509_NAME **issuer,
252                                           ASN1_INTEGER **sno)
253 {
254     CMS_KeyTransRecipientInfo *ktri;
255     if (ri->type != CMS_RECIPINFO_TRANS) {
256         CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
257                CMS_R_NOT_KEY_TRANSPORT);
258         return 0;
259     }
260     ktri = ri->d.ktri;
261
262     return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno);
263 }
264
265 int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
266 {
267     if (ri->type != CMS_RECIPINFO_TRANS) {
268         CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
269                CMS_R_NOT_KEY_TRANSPORT);
270         return -2;
271     }
272     return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
273 }
274
275 int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
276 {
277     if (ri->type != CMS_RECIPINFO_TRANS) {
278         CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, CMS_R_NOT_KEY_TRANSPORT);
279         return 0;
280     }
281     ri->d.ktri->pkey = pkey;
282     return 1;
283 }
284
285 /* Encrypt content key in key transport recipient info */
286
287 static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
288                                           CMS_RecipientInfo *ri)
289 {
290     CMS_KeyTransRecipientInfo *ktri;
291     CMS_EncryptedContentInfo *ec;
292     unsigned char *ek = NULL;
293     int 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     eklen = EVP_PKEY_size(ktri->pkey);
305
306     ek = OPENSSL_malloc(eklen);
307
308     if (ek == NULL) {
309         CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
310         goto err;
311     }
312
313     eklen = EVP_PKEY_encrypt(ek, ec->key, ec->keylen, ktri->pkey);
314
315     if (eklen <= 0)
316         goto err;
317
318     ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
319     ek = NULL;
320
321     ret = 1;
322
323  err:
324     if (ek)
325         OPENSSL_free(ek);
326     return ret;
327
328 }
329
330 /* Decrypt content key from KTRI */
331
332 static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
333                                           CMS_RecipientInfo *ri)
334 {
335     CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
336     unsigned char *ek = NULL;
337     int eklen;
338     int ret = 0;
339     CMS_EncryptedContentInfo *ec;
340     ec = cms->d.envelopedData->encryptedContentInfo;
341
342     if (ktri->pkey == NULL) {
343         CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY);
344         return 0;
345     }
346
347     eklen = EVP_PKEY_size(ktri->pkey);
348
349     ek = OPENSSL_malloc(eklen);
350
351     if (ek == NULL) {
352         CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE);
353         goto err;
354     }
355
356     eklen = EVP_PKEY_decrypt(ek,
357                              ktri->encryptedKey->data,
358                              ktri->encryptedKey->length, ktri->pkey);
359     if (eklen <= 0) {
360         CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
361         goto err;
362     }
363
364     ret = 1;
365
366     if (ec->key) {
367         OPENSSL_cleanse(ec->key, ec->keylen);
368         OPENSSL_free(ec->key);
369     }
370
371     ec->key = ek;
372     ec->keylen = eklen;
373
374  err:
375     if (!ret && ek)
376         OPENSSL_free(ek);
377
378     return ret;
379 }
380
381 /* Key Encrypted Key (KEK) RecipientInfo routines */
382
383 int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
384                                    const unsigned char *id, size_t idlen)
385 {
386     ASN1_OCTET_STRING tmp_os;
387     CMS_KEKRecipientInfo *kekri;
388     if (ri->type != CMS_RECIPINFO_KEK) {
389         CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
390         return -2;
391     }
392     kekri = ri->d.kekri;
393     tmp_os.type = V_ASN1_OCTET_STRING;
394     tmp_os.flags = 0;
395     tmp_os.data = (unsigned char *)id;
396     tmp_os.length = (int)idlen;
397     return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
398 }
399
400 /* For now hard code AES key wrap info */
401
402 static size_t aes_wrap_keylen(int nid)
403 {
404     switch (nid) {
405     case NID_id_aes128_wrap:
406         return 16;
407
408     case NID_id_aes192_wrap:
409         return 24;
410
411     case NID_id_aes256_wrap:
412         return 32;
413
414     default:
415         return 0;
416     }
417 }
418
419 CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
420                                           unsigned char *key, size_t keylen,
421                                           unsigned char *id, size_t idlen,
422                                           ASN1_GENERALIZEDTIME *date,
423                                           ASN1_OBJECT *otherTypeId,
424                                           ASN1_TYPE *otherType)
425 {
426     CMS_RecipientInfo *ri = NULL;
427     CMS_EnvelopedData *env;
428     CMS_KEKRecipientInfo *kekri;
429     env = cms_get0_enveloped(cms);
430     if (!env)
431         goto err;
432
433     if (nid == NID_undef) {
434         switch (keylen) {
435         case 16:
436             nid = NID_id_aes128_wrap;
437             break;
438
439         case 24:
440             nid = NID_id_aes192_wrap;
441             break;
442
443         case 32:
444             nid = NID_id_aes256_wrap;
445             break;
446
447         default:
448             CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
449             goto err;
450         }
451
452     } else {
453
454         size_t exp_keylen = aes_wrap_keylen(nid);
455
456         if (!exp_keylen) {
457             CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
458                    CMS_R_UNSUPPORTED_KEK_ALGORITHM);
459             goto err;
460         }
461
462         if (keylen != exp_keylen) {
463             CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
464             goto err;
465         }
466
467     }
468
469     /* Initialize recipient info */
470     ri = M_ASN1_new_of(CMS_RecipientInfo);
471     if (!ri)
472         goto merr;
473
474     ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
475     if (!ri->d.kekri)
476         goto merr;
477     ri->type = CMS_RECIPINFO_KEK;
478
479     kekri = ri->d.kekri;
480
481     if (otherTypeId) {
482         kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
483         if (kekri->kekid->other == NULL)
484             goto merr;
485     }
486
487     if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
488         goto merr;
489
490     /* After this point no calls can fail */
491
492     kekri->version = 4;
493
494     kekri->key = key;
495     kekri->keylen = keylen;
496
497     ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
498
499     kekri->kekid->date = date;
500
501     if (kekri->kekid->other) {
502         kekri->kekid->other->keyAttrId = otherTypeId;
503         kekri->kekid->other->keyAttr = otherType;
504     }
505
506     X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
507                     OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
508
509     return ri;
510
511  merr:
512     CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
513  err:
514     if (ri)
515         M_ASN1_free_of(ri, CMS_RecipientInfo);
516     return NULL;
517
518 }
519
520 int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
521                                     X509_ALGOR **palg,
522                                     ASN1_OCTET_STRING **pid,
523                                     ASN1_GENERALIZEDTIME **pdate,
524                                     ASN1_OBJECT **potherid,
525                                     ASN1_TYPE **pothertype)
526 {
527     CMS_KEKIdentifier *rkid;
528     if (ri->type != CMS_RECIPINFO_KEK) {
529         CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
530         return 0;
531     }
532     rkid = ri->d.kekri->kekid;
533     if (palg)
534         *palg = ri->d.kekri->keyEncryptionAlgorithm;
535     if (pid)
536         *pid = rkid->keyIdentifier;
537     if (pdate)
538         *pdate = rkid->date;
539     if (potherid) {
540         if (rkid->other)
541             *potherid = rkid->other->keyAttrId;
542         else
543             *potherid = NULL;
544     }
545     if (pothertype) {
546         if (rkid->other)
547             *pothertype = rkid->other->keyAttr;
548         else
549             *pothertype = NULL;
550     }
551     return 1;
552 }
553
554 int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
555                                unsigned char *key, size_t keylen)
556 {
557     CMS_KEKRecipientInfo *kekri;
558     if (ri->type != CMS_RECIPINFO_KEK) {
559         CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
560         return 0;
561     }
562
563     kekri = ri->d.kekri;
564     kekri->key = key;
565     kekri->keylen = keylen;
566     return 1;
567 }
568
569 /* Encrypt content key in KEK recipient info */
570
571 static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
572                                            CMS_RecipientInfo *ri)
573 {
574     CMS_EncryptedContentInfo *ec;
575     CMS_KEKRecipientInfo *kekri;
576     AES_KEY actx;
577     unsigned char *wkey = NULL;
578     int wkeylen;
579     int r = 0;
580
581     ec = cms->d.envelopedData->encryptedContentInfo;
582
583     kekri = ri->d.kekri;
584
585     if (!kekri->key) {
586         CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
587         return 0;
588     }
589
590     if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
591         CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
592                CMS_R_ERROR_SETTING_KEY);
593         goto err;
594     }
595
596     wkey = OPENSSL_malloc(ec->keylen + 8);
597
598     if (!wkey) {
599         CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
600         goto err;
601     }
602
603     wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
604
605     if (wkeylen <= 0) {
606         CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
607         goto err;
608     }
609
610     ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
611
612     r = 1;
613
614  err:
615
616     if (!r && wkey)
617         OPENSSL_free(wkey);
618     OPENSSL_cleanse(&actx, sizeof(actx));
619
620     return r;
621
622 }
623
624 /* Decrypt content key in KEK recipient info */
625
626 static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
627                                            CMS_RecipientInfo *ri)
628 {
629     CMS_EncryptedContentInfo *ec;
630     CMS_KEKRecipientInfo *kekri;
631     AES_KEY actx;
632     unsigned char *ukey = NULL;
633     int ukeylen;
634     int r = 0, wrap_nid;
635
636     ec = cms->d.envelopedData->encryptedContentInfo;
637
638     kekri = ri->d.kekri;
639
640     if (!kekri->key) {
641         CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
642         return 0;
643     }
644
645     wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
646     if (aes_wrap_keylen(wrap_nid) != kekri->keylen) {
647         CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
648                CMS_R_INVALID_KEY_LENGTH);
649         return 0;
650     }
651
652     /* If encrypted key length is invalid don't bother */
653
654     if (kekri->encryptedKey->length < 16) {
655         CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
656                CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
657         goto err;
658     }
659
660     if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
661         CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
662                CMS_R_ERROR_SETTING_KEY);
663         goto err;
664     }
665
666     ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
667
668     if (!ukey) {
669         CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE);
670         goto err;
671     }
672
673     ukeylen = AES_unwrap_key(&actx, NULL, ukey,
674                              kekri->encryptedKey->data,
675                              kekri->encryptedKey->length);
676
677     if (ukeylen <= 0) {
678         CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR);
679         goto err;
680     }
681
682     ec->key = ukey;
683     ec->keylen = ukeylen;
684
685     r = 1;
686
687  err:
688
689     if (!r && ukey)
690         OPENSSL_free(ukey);
691     OPENSSL_cleanse(&actx, sizeof(actx));
692
693     return r;
694
695 }
696
697 int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
698 {
699     switch (ri->type) {
700     case CMS_RECIPINFO_TRANS:
701         return cms_RecipientInfo_ktri_decrypt(cms, ri);
702
703     case CMS_RECIPINFO_KEK:
704         return cms_RecipientInfo_kekri_decrypt(cms, ri);
705
706     default:
707         CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
708                CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
709         return 0;
710     }
711 }
712
713 BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
714 {
715     CMS_EncryptedContentInfo *ec;
716     STACK_OF(CMS_RecipientInfo) *rinfos;
717     CMS_RecipientInfo *ri;
718     int i, r, ok = 0;
719     BIO *ret;
720
721     /* Get BIO first to set up key */
722
723     ec = cms->d.envelopedData->encryptedContentInfo;
724     ret = cms_EncryptedContent_init_bio(ec);
725
726     /* If error or no cipher end of processing */
727
728     if (!ret || !ec->cipher)
729         return ret;
730
731     /* Now encrypt content key according to each RecipientInfo type */
732
733     rinfos = cms->d.envelopedData->recipientInfos;
734
735     for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) {
736         ri = sk_CMS_RecipientInfo_value(rinfos, i);
737
738         switch (ri->type) {
739         case CMS_RECIPINFO_TRANS:
740             r = cms_RecipientInfo_ktri_encrypt(cms, ri);
741             break;
742
743         case CMS_RECIPINFO_KEK:
744             r = cms_RecipientInfo_kekri_encrypt(cms, ri);
745             break;
746
747         default:
748             CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
749                    CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
750             goto err;
751         }
752
753         if (r <= 0) {
754             CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
755                    CMS_R_ERROR_SETTING_RECIPIENTINFO);
756             goto err;
757         }
758     }
759
760     ok = 1;
761
762  err:
763     ec->cipher = NULL;
764     if (ec->key) {
765         OPENSSL_cleanse(ec->key, ec->keylen);
766         OPENSSL_free(ec->key);
767         ec->key = NULL;
768         ec->keylen = 0;
769     }
770     if (ok)
771         return ret;
772     BIO_free(ret);
773     return NULL;
774
775 }