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