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