evp: prevent underflow in base64 decoding
[openssl.git] / crypto / cms / cms_env.c
1 /* crypto/cms/cms_env.c */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project.
4  */
5 /* ====================================================================
6  * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer. 
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  */
53
54 #include "cryptlib.h"
55 #include <openssl/asn1t.h>
56 #include <openssl/pem.h>
57 #include <openssl/x509v3.h>
58 #include <openssl/err.h>
59 #include <openssl/cms.h>
60 #include <openssl/rand.h>
61 #include <openssl/aes.h>
62 #include "cms_lcl.h"
63 #include "asn1_locl.h"
64
65 /* CMS EnvelopedData Utilities */
66
67 DECLARE_ASN1_ITEM(CMS_EnvelopedData)
68 DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
69 DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
70 DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
71
72 DECLARE_STACK_OF(CMS_RecipientInfo)
73
74 CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
75         {
76         if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped)
77                 {
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                 {
89                 cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
90                 if (!cms->d.envelopedData)
91                         {
92                         CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT,
93                                                         ERR_R_MALLOC_FAILURE);
94                         return NULL;
95                         }
96                 cms->d.envelopedData->version = 0;
97                 cms->d.envelopedData->encryptedContentInfo->contentType =
98                                                 OBJ_nid2obj(NID_pkcs7_data);
99                 ASN1_OBJECT_free(cms->contentType);
100                 cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
101                 return cms->d.envelopedData;
102                 }
103         return cms_get0_enveloped(cms);
104         }
105
106 STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
107         {
108         CMS_EnvelopedData *env;
109         env = cms_get0_enveloped(cms);
110         if (!env)
111                 return NULL;
112         return env->recipientInfos;
113         }
114
115 int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
116         {
117         return ri->type;
118         }
119
120 CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
121         {
122         CMS_ContentInfo *cms;
123         CMS_EnvelopedData *env;
124         cms = CMS_ContentInfo_new();
125         if (!cms)
126                 goto merr;
127         env = cms_enveloped_data_init(cms);
128         if (!env)
129                 goto merr;
130         if (!cms_EncryptedContent_init(env->encryptedContentInfo,
131                                         cipher, NULL, 0))
132                 goto merr;
133         return cms;
134         merr:
135         if (cms)
136                 CMS_ContentInfo_free(cms);
137         CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
138         return NULL;
139         }
140
141 /* Key Transport Recipient Info (KTRI) routines */
142
143 /* Add a recipient certificate. For now only handle key transport.
144  * If we ever handle key agreement will need updating.
145  */
146
147 CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
148                                         X509 *recip, unsigned int flags)
149         {
150         CMS_RecipientInfo *ri = NULL;
151         CMS_KeyTransRecipientInfo *ktri;
152         CMS_EnvelopedData *env;
153         EVP_PKEY *pk = NULL;
154         int i, type;
155         env = cms_get0_enveloped(cms);
156         if (!env)
157                 goto err;
158
159         /* Initialize recipient info */
160         ri = M_ASN1_new_of(CMS_RecipientInfo);
161         if (!ri)
162                 goto merr;
163
164         /* Initialize and add key transport recipient info */
165
166         ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
167         if (!ri->d.ktri)
168                 goto merr;
169         ri->type = CMS_RECIPINFO_TRANS;
170
171         ktri = ri->d.ktri;
172
173         X509_check_purpose(recip, -1, -1);
174         pk = X509_get_pubkey(recip);
175         if (!pk)
176                 {
177                 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
178                                 CMS_R_ERROR_GETTING_PUBLIC_KEY);
179                 goto err;
180                 }
181         CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509);
182         ktri->pkey = pk;
183         ktri->recip = recip;
184
185         if (flags & CMS_USE_KEYID)
186                 {
187                 ktri->version = 2;
188                 if (env->version < 2)
189                         env->version = 2;
190                 type = CMS_RECIPINFO_KEYIDENTIFIER;
191                 }
192         else
193                 {
194                 ktri->version = 0;
195                 type = CMS_RECIPINFO_ISSUER_SERIAL;
196                 }
197
198         /* Not a typo: RecipientIdentifier and SignerIdentifier are the
199          * same structure.
200          */
201
202         if (!cms_set1_SignerIdentifier(ktri->rid, recip, type))
203                 goto err;
204
205         if (pk->ameth && pk->ameth->pkey_ctrl)
206                 {
207                 i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE,
208                                                 0, ri);
209                 if (i == -2)
210                         {
211                         CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
212                                 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
213                         goto err;
214                         }
215                 if (i <= 0)
216                         {
217                         CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
218                                 CMS_R_CTRL_FAILURE);
219                         goto err;
220                         }
221                 }
222
223         if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
224                 goto merr;
225
226         return ri;
227
228         merr:
229         CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
230         err:
231         if (ri)
232                 M_ASN1_free_of(ri, CMS_RecipientInfo);
233         return NULL;
234
235         }
236
237 int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
238                                         EVP_PKEY **pk, X509 **recip,
239                                         X509_ALGOR **palg)
240         {
241         CMS_KeyTransRecipientInfo *ktri;
242         if (ri->type != CMS_RECIPINFO_TRANS)
243                 {
244                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
245                         CMS_R_NOT_KEY_TRANSPORT);
246                 return 0;
247                 }
248
249         ktri = ri->d.ktri;
250
251         if (pk)
252                 *pk = ktri->pkey;
253         if (recip)
254                 *recip = ktri->recip;
255         if (palg)
256                 *palg = ktri->keyEncryptionAlgorithm;
257         return 1;
258         }
259
260 int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
261                                         ASN1_OCTET_STRING **keyid,
262                                         X509_NAME **issuer, ASN1_INTEGER **sno)
263         {
264         CMS_KeyTransRecipientInfo *ktri;
265         if (ri->type != CMS_RECIPINFO_TRANS)
266                 {
267                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
268                         CMS_R_NOT_KEY_TRANSPORT);
269                 return 0;
270                 }
271         ktri = ri->d.ktri;
272
273         return cms_SignerIdentifier_get0_signer_id(ktri->rid,
274                                                         keyid, issuer, sno);
275         }
276
277 int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
278         {
279         if (ri->type != CMS_RECIPINFO_TRANS)
280                 {
281                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
282                         CMS_R_NOT_KEY_TRANSPORT);
283                 return -2;
284                 }
285         return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
286         }
287
288 int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
289         {
290         if (ri->type != CMS_RECIPINFO_TRANS)
291                 {
292                 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY,
293                         CMS_R_NOT_KEY_TRANSPORT);
294                 return 0;
295                 }
296         ri->d.ktri->pkey = pkey;
297         return 1;
298         }
299
300 /* Encrypt content key in key transport recipient info */
301
302 static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
303                                         CMS_RecipientInfo *ri)
304         {
305         CMS_KeyTransRecipientInfo *ktri;
306         CMS_EncryptedContentInfo *ec;
307         EVP_PKEY_CTX *pctx = NULL;
308         unsigned char *ek = NULL;
309         size_t eklen;
310
311         int ret = 0;
312
313         if (ri->type != CMS_RECIPINFO_TRANS)
314                 {
315                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
316                         CMS_R_NOT_KEY_TRANSPORT);
317                 return 0;
318                 }
319         ktri = ri->d.ktri;
320         ec = cms->d.envelopedData->encryptedContentInfo;
321
322         pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
323         if (!pctx)
324                 return 0;
325
326         if (EVP_PKEY_encrypt_init(pctx) <= 0)
327                 goto err;
328
329         if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
330                                 EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0)
331                 {
332                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
333                 goto err;
334                 }
335
336         if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
337                 goto err;
338
339         ek = OPENSSL_malloc(eklen);
340
341         if (ek == NULL)
342                 {
343                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
344                                                         ERR_R_MALLOC_FAILURE);
345                 goto err;
346                 }
347
348         if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
349                 goto err;
350
351         ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
352         ek = NULL;
353
354         ret = 1;
355
356         err:
357         if (pctx)
358                 EVP_PKEY_CTX_free(pctx);
359         if (ek)
360                 OPENSSL_free(ek);
361         return ret;
362
363         }
364
365 /* Decrypt content key from KTRI */
366
367 static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
368                                                         CMS_RecipientInfo *ri)
369         {
370         CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
371         EVP_PKEY_CTX *pctx = NULL;
372         unsigned char *ek = NULL;
373         size_t eklen;
374         int ret = 0;
375         CMS_EncryptedContentInfo *ec;
376         ec = cms->d.envelopedData->encryptedContentInfo;
377
378         if (ktri->pkey == NULL)
379                 {
380                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
381                         CMS_R_NO_PRIVATE_KEY);
382                 return 0;
383                 }
384
385         pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
386         if (!pctx)
387                 return 0;
388
389         if (EVP_PKEY_decrypt_init(pctx) <= 0)
390                 goto err;
391
392         if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
393                                 EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0)
394                 {
395                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
396                 goto err;
397                 }
398
399         if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
400                                 ktri->encryptedKey->data,
401                                 ktri->encryptedKey->length) <= 0)
402                 goto err;
403
404         ek = OPENSSL_malloc(eklen);
405
406         if (ek == NULL)
407                 {
408                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
409                                                         ERR_R_MALLOC_FAILURE);
410                 goto err;
411                 }
412
413         if (EVP_PKEY_decrypt(pctx, ek, &eklen,
414                                 ktri->encryptedKey->data,
415                                 ktri->encryptedKey->length) <= 0)
416                 {
417                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
418                 goto err;
419                 }
420
421         ret = 1;
422
423         if (ec->key)
424                 {
425                 OPENSSL_cleanse(ec->key, ec->keylen);
426                 OPENSSL_free(ec->key);
427                 }
428
429         ec->key = ek;
430         ec->keylen = eklen;
431
432         err:
433         if (pctx)
434                 EVP_PKEY_CTX_free(pctx);
435         if (!ret && ek)
436                 OPENSSL_free(ek);
437
438         return ret;
439         }
440
441 /* Key Encrypted Key (KEK) RecipientInfo routines */
442
443 int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, 
444                                         const unsigned char *id, size_t idlen)
445         {
446         ASN1_OCTET_STRING tmp_os;
447         CMS_KEKRecipientInfo *kekri;
448         if (ri->type != CMS_RECIPINFO_KEK)
449                 {
450                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
451                 return -2;
452                 }
453         kekri = ri->d.kekri;
454         tmp_os.type = V_ASN1_OCTET_STRING;
455         tmp_os.flags = 0;
456         tmp_os.data = (unsigned char *)id;
457         tmp_os.length = (int)idlen;
458         return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
459         }
460
461 /* For now hard code AES key wrap info */
462
463 static size_t aes_wrap_keylen(int nid)
464         {
465         switch (nid)
466                 {
467                 case NID_id_aes128_wrap:
468                 return 16;
469
470                 case NID_id_aes192_wrap:
471                 return  24;
472
473                 case NID_id_aes256_wrap:
474                 return  32;
475
476                 default:
477                 return 0;
478                 }
479         }
480
481 CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
482                                         unsigned char *key, size_t keylen,
483                                         unsigned char *id, size_t idlen,
484                                         ASN1_GENERALIZEDTIME *date,
485                                         ASN1_OBJECT *otherTypeId,
486                                         ASN1_TYPE *otherType)
487         {
488         CMS_RecipientInfo *ri = NULL;
489         CMS_EnvelopedData *env;
490         CMS_KEKRecipientInfo *kekri;
491         env = cms_get0_enveloped(cms);
492         if (!env)
493                 goto err;
494
495         if (nid == NID_undef)
496                 {
497                 switch (keylen)
498                         {
499                         case 16:
500                         nid = NID_id_aes128_wrap;
501                         break;
502
503                         case  24:
504                         nid = NID_id_aes192_wrap;
505                         break;
506
507                         case  32:
508                         nid = NID_id_aes256_wrap;
509                         break;
510
511                         default:
512                         CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
513                                                 CMS_R_INVALID_KEY_LENGTH);
514                         goto err;
515                         }
516
517                 }
518         else
519                 {
520
521                 size_t exp_keylen = aes_wrap_keylen(nid);
522
523                 if (!exp_keylen)
524                         {
525                         CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
526                                         CMS_R_UNSUPPORTED_KEK_ALGORITHM);
527                         goto err;
528                         }
529
530                 if (keylen != exp_keylen)
531                         {
532                         CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
533                                         CMS_R_INVALID_KEY_LENGTH);
534                         goto err;
535                         }
536
537                 }
538
539         /* Initialize recipient info */
540         ri = M_ASN1_new_of(CMS_RecipientInfo);
541         if (!ri)
542                 goto merr;
543
544         ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
545         if (!ri->d.kekri)
546                 goto merr;
547         ri->type = CMS_RECIPINFO_KEK;
548
549         kekri = ri->d.kekri;
550
551         if (otherTypeId)
552                 {
553                 kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
554                 if (kekri->kekid->other == NULL)
555                         goto merr;
556                 }
557
558         if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
559                 goto merr;
560
561
562         /* After this point no calls can fail */
563
564         kekri->version = 4;
565
566         kekri->key = key;
567         kekri->keylen = keylen;
568
569         ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
570
571         kekri->kekid->date = date;
572
573         if (kekri->kekid->other)
574                 {
575                 kekri->kekid->other->keyAttrId = otherTypeId;
576                 kekri->kekid->other->keyAttr = otherType;
577                 }
578
579         X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
580                                 OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
581
582         return ri;
583
584         merr:
585         CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
586         err:
587         if (ri)
588                 M_ASN1_free_of(ri, CMS_RecipientInfo);
589         return NULL;
590
591         }
592
593 int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
594                                         X509_ALGOR **palg,
595                                         ASN1_OCTET_STRING **pid,
596                                         ASN1_GENERALIZEDTIME **pdate,
597                                         ASN1_OBJECT **potherid,
598                                         ASN1_TYPE **pothertype)
599         {
600         CMS_KEKIdentifier *rkid;
601         if (ri->type != CMS_RECIPINFO_KEK)
602                 {
603                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
604                 return 0;
605                 }
606         rkid =  ri->d.kekri->kekid;
607         if (palg)
608                 *palg = ri->d.kekri->keyEncryptionAlgorithm;
609         if (pid)
610                 *pid = rkid->keyIdentifier;
611         if (pdate)
612                 *pdate = rkid->date;
613         if (potherid)
614                 {
615                 if (rkid->other)
616                         *potherid = rkid->other->keyAttrId;
617                 else
618                         *potherid = NULL;
619                 }
620         if (pothertype)
621                 {
622                 if (rkid->other)
623                         *pothertype = rkid->other->keyAttr;
624                 else
625                         *pothertype = NULL;
626                 }
627         return 1;
628         }
629
630 int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, 
631                                 unsigned char *key, size_t keylen)
632         {
633         CMS_KEKRecipientInfo *kekri;
634         if (ri->type != CMS_RECIPINFO_KEK)
635                 {
636                 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
637                 return 0;
638                 }
639
640         kekri = ri->d.kekri;
641         kekri->key = key;
642         kekri->keylen = keylen;
643         return 1;
644         }
645
646
647 /* Encrypt content key in KEK recipient info */
648
649 static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
650                                         CMS_RecipientInfo *ri)
651         {
652         CMS_EncryptedContentInfo *ec;
653         CMS_KEKRecipientInfo *kekri;
654         AES_KEY actx;
655         unsigned char *wkey = NULL;
656         int wkeylen;
657         int r = 0;
658
659         ec = cms->d.envelopedData->encryptedContentInfo;
660
661         kekri = ri->d.kekri;
662
663         if (!kekri->key)
664                 {
665                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
666                 return 0;
667                 }
668
669         if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx))
670                 { 
671                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
672                                                 CMS_R_ERROR_SETTING_KEY);
673                 goto err;
674                 }
675
676         wkey = OPENSSL_malloc(ec->keylen + 8);
677
678         if (!wkey)
679                 { 
680                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
681                                                 ERR_R_MALLOC_FAILURE);
682                 goto err;
683                 }
684
685         wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
686
687         if (wkeylen <= 0)
688                 {
689                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
690                 goto err;
691                 }
692
693         ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
694
695         r = 1;
696
697         err:
698
699         if (!r && wkey)
700                 OPENSSL_free(wkey);
701         OPENSSL_cleanse(&actx, sizeof(actx));
702
703         return r;
704
705         }
706
707 /* Decrypt content key in KEK recipient info */
708
709 static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
710                                         CMS_RecipientInfo *ri)
711         {
712         CMS_EncryptedContentInfo *ec;
713         CMS_KEKRecipientInfo *kekri;
714         AES_KEY actx;
715         unsigned char *ukey = NULL;
716         int ukeylen;
717         int r = 0, wrap_nid;
718
719         ec = cms->d.envelopedData->encryptedContentInfo;
720
721         kekri = ri->d.kekri;
722
723         if (!kekri->key)
724                 {
725                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
726                 return 0;
727                 }
728
729         wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
730         if (aes_wrap_keylen(wrap_nid) != kekri->keylen)
731                 {
732                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
733                         CMS_R_INVALID_KEY_LENGTH);
734                 return 0;
735                 }
736
737         /* If encrypted key length is invalid don't bother */
738
739         if (kekri->encryptedKey->length < 16)
740                 { 
741                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
742                                         CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
743                 goto err;
744                 }
745
746         if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx))
747                 { 
748                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
749                                                 CMS_R_ERROR_SETTING_KEY);
750                 goto err;
751                 }
752
753         ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
754
755         if (!ukey)
756                 { 
757                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
758                                                 ERR_R_MALLOC_FAILURE);
759                 goto err;
760                 }
761
762         ukeylen = AES_unwrap_key(&actx, NULL, ukey,
763                                         kekri->encryptedKey->data,
764                                         kekri->encryptedKey->length);
765
766         if (ukeylen <= 0)
767                 {
768                 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
769                                                         CMS_R_UNWRAP_ERROR);
770                 goto err;
771                 }
772
773         ec->key = ukey;
774         ec->keylen = ukeylen;
775
776         r = 1;
777
778         err:
779
780         if (!r && ukey)
781                 OPENSSL_free(ukey);
782         OPENSSL_cleanse(&actx, sizeof(actx));
783
784         return r;
785
786         }
787
788 int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
789         {
790         switch(ri->type)
791                 {
792                 case CMS_RECIPINFO_TRANS:
793                 return cms_RecipientInfo_ktri_decrypt(cms, ri);
794
795                 case CMS_RECIPINFO_KEK:
796                 return cms_RecipientInfo_kekri_decrypt(cms, ri);
797
798                 case CMS_RECIPINFO_PASS:
799                 return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
800
801                 default:
802                 CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
803                         CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
804                 return 0;
805                 }
806         }
807
808 BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
809         {
810         CMS_EncryptedContentInfo *ec;
811         STACK_OF(CMS_RecipientInfo) *rinfos;
812         CMS_RecipientInfo *ri;
813         int i, r, ok = 0;
814         BIO *ret;
815
816         /* Get BIO first to set up key */
817
818         ec = cms->d.envelopedData->encryptedContentInfo;
819         ret = cms_EncryptedContent_init_bio(ec);
820
821         /* If error or no cipher end of processing */
822
823         if (!ret || !ec->cipher)
824                 return ret;
825
826         /* Now encrypt content key according to each RecipientInfo type */
827
828         rinfos = cms->d.envelopedData->recipientInfos;
829
830         for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++)
831                 {
832                 ri = sk_CMS_RecipientInfo_value(rinfos, i);
833
834                 switch (ri->type)
835                         {
836                         case CMS_RECIPINFO_TRANS:
837                         r = cms_RecipientInfo_ktri_encrypt(cms, ri);
838                         break;
839
840                         case CMS_RECIPINFO_KEK:
841                         r = cms_RecipientInfo_kekri_encrypt(cms, ri);
842                         break;
843
844                         case CMS_RECIPINFO_PASS:
845                         r = cms_RecipientInfo_pwri_crypt(cms, ri, 1);
846                         break;
847
848                         default:
849                         CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
850                                 CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
851                         goto err;
852                         }
853
854                 if (r <= 0)
855                         {
856                         CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
857                                 CMS_R_ERROR_SETTING_RECIPIENTINFO);
858                         goto err;
859                         }
860                 }
861
862         ok = 1;
863
864         err:
865         ec->cipher = NULL;
866         if (ec->key)
867                 {
868                 OPENSSL_cleanse(ec->key, ec->keylen);
869                 OPENSSL_free(ec->key);
870                 ec->key = NULL;
871                 ec->keylen = 0;
872                 }
873         if (ok)
874                 return ret;
875         BIO_free(ret);
876         return NULL;
877
878         }