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