1a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* crypto/cms/cms_enc.c */
2a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3a88cfce91374498578c44013041416c0c5b09b1eKenny Root * project.
4a88cfce91374498578c44013041416c0c5b09b1eKenny Root */
5a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* ====================================================================
6a88cfce91374498578c44013041416c0c5b09b1eKenny Root * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
7a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
8a88cfce91374498578c44013041416c0c5b09b1eKenny Root * Redistribution and use in source and binary forms, with or without
9a88cfce91374498578c44013041416c0c5b09b1eKenny Root * modification, are permitted provided that the following conditions
10a88cfce91374498578c44013041416c0c5b09b1eKenny Root * are met:
11a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
12a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 1. Redistributions of source code must retain the above copyright
13a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    notice, this list of conditions and the following disclaimer.
14a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
15a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 2. Redistributions in binary form must reproduce the above copyright
16a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    notice, this list of conditions and the following disclaimer in
17a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    the documentation and/or other materials provided with the
18a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    distribution.
19a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
20a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 3. All advertising materials mentioning features or use of this
21a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    software must display the following acknowledgment:
22a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    "This product includes software developed by the OpenSSL Project
23a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
25a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    endorse or promote products derived from this software without
27a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    prior written permission. For written permission, please contact
28a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    licensing@OpenSSL.org.
29a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
30a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 5. Products derived from this software may not be called "OpenSSL"
31a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    nor may "OpenSSL" appear in their names without prior written
32a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    permission of the OpenSSL Project.
33a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
34a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 6. Redistributions of any form whatsoever must retain the following
35a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    acknowledgment:
36a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    "This product includes software developed by the OpenSSL Project
37a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
39a88cfce91374498578c44013041416c0c5b09b1eKenny Root * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40a88cfce91374498578c44013041416c0c5b09b1eKenny Root * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41a88cfce91374498578c44013041416c0c5b09b1eKenny Root * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42a88cfce91374498578c44013041416c0c5b09b1eKenny Root * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43a88cfce91374498578c44013041416c0c5b09b1eKenny Root * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44a88cfce91374498578c44013041416c0c5b09b1eKenny Root * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45a88cfce91374498578c44013041416c0c5b09b1eKenny Root * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46a88cfce91374498578c44013041416c0c5b09b1eKenny Root * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47a88cfce91374498578c44013041416c0c5b09b1eKenny Root * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48a88cfce91374498578c44013041416c0c5b09b1eKenny Root * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49a88cfce91374498578c44013041416c0c5b09b1eKenny Root * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50a88cfce91374498578c44013041416c0c5b09b1eKenny Root * OF THE POSSIBILITY OF SUCH DAMAGE.
51a88cfce91374498578c44013041416c0c5b09b1eKenny Root * ====================================================================
52a88cfce91374498578c44013041416c0c5b09b1eKenny Root */
53a88cfce91374498578c44013041416c0c5b09b1eKenny Root
54a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include "cryptlib.h"
55a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/asn1t.h>
56a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/pem.h>
57a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/x509v3.h>
58a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/err.h>
59a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/cms.h>
60a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/rand.h>
61a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include "cms_lcl.h"
62a88cfce91374498578c44013041416c0c5b09b1eKenny Root
63a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* CMS EncryptedData Utilities */
64a88cfce91374498578c44013041416c0c5b09b1eKenny Root
65a88cfce91374498578c44013041416c0c5b09b1eKenny RootDECLARE_ASN1_ITEM(CMS_EncryptedData)
66a88cfce91374498578c44013041416c0c5b09b1eKenny Root
67a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Return BIO based on EncryptedContentInfo and key */
68a88cfce91374498578c44013041416c0c5b09b1eKenny Root
69a88cfce91374498578c44013041416c0c5b09b1eKenny RootBIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
70a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
71a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO *b;
72a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_CIPHER_CTX *ctx;
73a88cfce91374498578c44013041416c0c5b09b1eKenny Root	const EVP_CIPHER *ciph;
74a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
75a88cfce91374498578c44013041416c0c5b09b1eKenny Root	unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
76a88cfce91374498578c44013041416c0c5b09b1eKenny Root	unsigned char *tkey = NULL;
77a88cfce91374498578c44013041416c0c5b09b1eKenny Root	size_t tkeylen = 0;
78a88cfce91374498578c44013041416c0c5b09b1eKenny Root
79a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int ok = 0;
80a88cfce91374498578c44013041416c0c5b09b1eKenny Root
81a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int enc, keep_key = 0;
82a88cfce91374498578c44013041416c0c5b09b1eKenny Root
83a88cfce91374498578c44013041416c0c5b09b1eKenny Root	enc = ec->cipher ? 1 : 0;
84a88cfce91374498578c44013041416c0c5b09b1eKenny Root
85a88cfce91374498578c44013041416c0c5b09b1eKenny Root	b = BIO_new(BIO_f_cipher());
86a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!b)
87a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
88a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
89a88cfce91374498578c44013041416c0c5b09b1eKenny Root							ERR_R_MALLOC_FAILURE);
90a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
91a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
92a88cfce91374498578c44013041416c0c5b09b1eKenny Root
93a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO_get_cipher_ctx(b, &ctx);
94a88cfce91374498578c44013041416c0c5b09b1eKenny Root
95a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (enc)
96a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
97a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ciph = ec->cipher;
98a88cfce91374498578c44013041416c0c5b09b1eKenny Root		/* If not keeping key set cipher to NULL so subsequent calls
99a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 * decrypt.
100a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 */
101a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (ec->key)
102a88cfce91374498578c44013041416c0c5b09b1eKenny Root			ec->cipher = NULL;
103a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
104a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
105a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
106a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ciph = EVP_get_cipherbyobj(calg->algorithm);
107a88cfce91374498578c44013041416c0c5b09b1eKenny Root
108a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!ciph)
109a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
110a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
111a88cfce91374498578c44013041416c0c5b09b1eKenny Root							CMS_R_UNKNOWN_CIPHER);
112a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
113a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
114a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
115a88cfce91374498578c44013041416c0c5b09b1eKenny Root
116a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0)
117a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
118a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
119a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_R_CIPHER_INITIALISATION_ERROR);
120a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
121a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
122a88cfce91374498578c44013041416c0c5b09b1eKenny Root
123a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (enc)
124a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
125a88cfce91374498578c44013041416c0c5b09b1eKenny Root		int ivlen;
126a88cfce91374498578c44013041416c0c5b09b1eKenny Root		calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
127a88cfce91374498578c44013041416c0c5b09b1eKenny Root		/* Generate a random IV if we need one */
128a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ivlen = EVP_CIPHER_CTX_iv_length(ctx);
129a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (ivlen > 0)
130a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
131a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (RAND_pseudo_bytes(iv, ivlen) <= 0)
132a88cfce91374498578c44013041416c0c5b09b1eKenny Root				goto err;
133a88cfce91374498578c44013041416c0c5b09b1eKenny Root			piv = iv;
134a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
135a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
136a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0)
137a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
138a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
139a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
140a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
141a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
142a88cfce91374498578c44013041416c0c5b09b1eKenny Root	tkeylen = EVP_CIPHER_CTX_key_length(ctx);
143a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Generate random session key */
144a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!enc || !ec->key)
145a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
146a88cfce91374498578c44013041416c0c5b09b1eKenny Root		tkey = OPENSSL_malloc(tkeylen);
147a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!tkey)
148a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
149a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
150a88cfce91374498578c44013041416c0c5b09b1eKenny Root							ERR_R_MALLOC_FAILURE);
151a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
152a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
153a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0)
154a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
155a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
156a88cfce91374498578c44013041416c0c5b09b1eKenny Root
157a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!ec->key)
158a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
159a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ec->key = tkey;
160a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ec->keylen = tkeylen;
161a88cfce91374498578c44013041416c0c5b09b1eKenny Root		tkey = NULL;
162a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (enc)
163a88cfce91374498578c44013041416c0c5b09b1eKenny Root			keep_key = 1;
164a88cfce91374498578c44013041416c0c5b09b1eKenny Root		else
165a88cfce91374498578c44013041416c0c5b09b1eKenny Root			ERR_clear_error();
166a88cfce91374498578c44013041416c0c5b09b1eKenny Root
167a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
168a88cfce91374498578c44013041416c0c5b09b1eKenny Root
169a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (ec->keylen != tkeylen)
170a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
171a88cfce91374498578c44013041416c0c5b09b1eKenny Root		/* If necessary set key length */
172a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0)
173a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
174a88cfce91374498578c44013041416c0c5b09b1eKenny Root			/* Only reveal failure if debugging so we don't
175a88cfce91374498578c44013041416c0c5b09b1eKenny Root			 * leak information which may be useful in MMA.
176a88cfce91374498578c44013041416c0c5b09b1eKenny Root			 */
177a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (enc || ec->debug)
178a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
179a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
180a88cfce91374498578c44013041416c0c5b09b1eKenny Root						CMS_R_INVALID_KEY_LENGTH);
181a88cfce91374498578c44013041416c0c5b09b1eKenny Root				goto err;
182a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
183a88cfce91374498578c44013041416c0c5b09b1eKenny Root			else
184a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
185a88cfce91374498578c44013041416c0c5b09b1eKenny Root				/* Use random key */
186a88cfce91374498578c44013041416c0c5b09b1eKenny Root				OPENSSL_cleanse(ec->key, ec->keylen);
187a88cfce91374498578c44013041416c0c5b09b1eKenny Root				OPENSSL_free(ec->key);
188a88cfce91374498578c44013041416c0c5b09b1eKenny Root				ec->key = tkey;
189a88cfce91374498578c44013041416c0c5b09b1eKenny Root				ec->keylen = tkeylen;
190a88cfce91374498578c44013041416c0c5b09b1eKenny Root				tkey = NULL;
191a88cfce91374498578c44013041416c0c5b09b1eKenny Root				ERR_clear_error();
192a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
193a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
194a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
195a88cfce91374498578c44013041416c0c5b09b1eKenny Root
196a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0)
197a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
198a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
199a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_R_CIPHER_INITIALISATION_ERROR);
200a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
201a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
202a88cfce91374498578c44013041416c0c5b09b1eKenny Root
203a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (piv)
204a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
205a88cfce91374498578c44013041416c0c5b09b1eKenny Root		calg->parameter = ASN1_TYPE_new();
206a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!calg->parameter)
207a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
208a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
209a88cfce91374498578c44013041416c0c5b09b1eKenny Root							ERR_R_MALLOC_FAILURE);
210a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
211a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
212a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0)
213a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
214a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
215a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
216a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
217a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
218a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
219a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ok = 1;
220a88cfce91374498578c44013041416c0c5b09b1eKenny Root
221a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
222a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (ec->key && !keep_key)
223a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
224a88cfce91374498578c44013041416c0c5b09b1eKenny Root		OPENSSL_cleanse(ec->key, ec->keylen);
225a88cfce91374498578c44013041416c0c5b09b1eKenny Root		OPENSSL_free(ec->key);
226a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ec->key = NULL;
227a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
228a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (tkey)
229a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
230a88cfce91374498578c44013041416c0c5b09b1eKenny Root		OPENSSL_cleanse(tkey, tkeylen);
231a88cfce91374498578c44013041416c0c5b09b1eKenny Root		OPENSSL_free(tkey);
232a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
233a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (ok)
234a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return b;
235a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO_free(b);
236a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
237a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
238a88cfce91374498578c44013041416c0c5b09b1eKenny Root
239a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
240a88cfce91374498578c44013041416c0c5b09b1eKenny Root				const EVP_CIPHER *cipher,
241a88cfce91374498578c44013041416c0c5b09b1eKenny Root				const unsigned char *key, size_t keylen)
242a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
243a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ec->cipher = cipher;
244a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (key)
245a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
246a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ec->key = OPENSSL_malloc(keylen);
247a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!ec->key)
248a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return 0;
249a88cfce91374498578c44013041416c0c5b09b1eKenny Root		memcpy(ec->key, key, keylen);
250a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
251a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ec->keylen = keylen;
252a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (cipher)
253a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ec->contentType = OBJ_nid2obj(NID_pkcs7_data);
254a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
255a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
256a88cfce91374498578c44013041416c0c5b09b1eKenny Root
257a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
258a88cfce91374498578c44013041416c0c5b09b1eKenny Root				const unsigned char *key, size_t keylen)
259a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
260a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_EncryptedContentInfo *ec;
261a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!key || !keylen)
262a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
263a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY);
264a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
265a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
266a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (ciph)
267a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
268a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
269a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!cms->d.encryptedData)
270a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
271a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY,
272a88cfce91374498578c44013041416c0c5b09b1eKenny Root				ERR_R_MALLOC_FAILURE);
273a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return 0;
274a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
275a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted);
276a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms->d.encryptedData->version = 0;
277a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
278a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted)
279a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
280a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY,
281a88cfce91374498578c44013041416c0c5b09b1eKenny Root						CMS_R_NOT_ENCRYPTED_DATA);
282a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
283a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
284a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ec = cms->d.encryptedData->encryptedContentInfo;
285a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return cms_EncryptedContent_init(ec, ciph, key, keylen);
286a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
287a88cfce91374498578c44013041416c0c5b09b1eKenny Root
288a88cfce91374498578c44013041416c0c5b09b1eKenny RootBIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
289a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
290a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_EncryptedData *enc = cms->d.encryptedData;
291a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
292a88cfce91374498578c44013041416c0c5b09b1eKenny Root		enc->version = 2;
293a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
294a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
295