1a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* crypto/cms/cms_smime.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/x509.h>
57a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/x509v3.h>
58a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/err.h>
59a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/cms.h>
60a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include "cms_lcl.h"
61a88cfce91374498578c44013041416c0c5b09b1eKenny Root
62a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
63a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
64a88cfce91374498578c44013041416c0c5b09b1eKenny Root	unsigned char buf[4096];
65a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int r = 0, i;
66a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO *tmpout = NULL;
67a88cfce91374498578c44013041416c0c5b09b1eKenny Root
68a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (out == NULL)
69a88cfce91374498578c44013041416c0c5b09b1eKenny Root		tmpout = BIO_new(BIO_s_null());
70a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else if (flags & CMS_TEXT)
71a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
72a88cfce91374498578c44013041416c0c5b09b1eKenny Root		tmpout = BIO_new(BIO_s_mem());
73a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO_set_mem_eof_return(tmpout, 0);
74a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
75a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
76a88cfce91374498578c44013041416c0c5b09b1eKenny Root		tmpout = out;
77a88cfce91374498578c44013041416c0c5b09b1eKenny Root
78a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if(!tmpout)
79a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
80a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_COPY_CONTENT,ERR_R_MALLOC_FAILURE);
81a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
82a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
83a88cfce91374498578c44013041416c0c5b09b1eKenny Root
84a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Read all content through chain to process digest, decrypt etc */
85a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (;;)
86a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
87a88cfce91374498578c44013041416c0c5b09b1eKenny Root		i=BIO_read(in,buf,sizeof(buf));
88a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (i <= 0)
89a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
90a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (BIO_method_type(in) == BIO_TYPE_CIPHER)
91a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
92a88cfce91374498578c44013041416c0c5b09b1eKenny Root				if (!BIO_get_cipher_status(in))
93a88cfce91374498578c44013041416c0c5b09b1eKenny Root					goto err;
94a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
95a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (i < 0)
96a88cfce91374498578c44013041416c0c5b09b1eKenny Root				goto err;
97a88cfce91374498578c44013041416c0c5b09b1eKenny Root			break;
98a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
99a88cfce91374498578c44013041416c0c5b09b1eKenny Root
100a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (tmpout && (BIO_write(tmpout, buf, i) != i))
101a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
102a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
103a88cfce91374498578c44013041416c0c5b09b1eKenny Root
104a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if(flags & CMS_TEXT)
105a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
106a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if(!SMIME_text(tmpout, out))
107a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
108a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_COPY_CONTENT,CMS_R_SMIME_TEXT_ERROR);
109a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
110a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
111a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
112a88cfce91374498578c44013041416c0c5b09b1eKenny Root
113a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = 1;
114a88cfce91374498578c44013041416c0c5b09b1eKenny Root
115a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
116a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (tmpout && (tmpout != out))
117a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO_free(tmpout);
118a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
119a88cfce91374498578c44013041416c0c5b09b1eKenny Root
120a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
121a88cfce91374498578c44013041416c0c5b09b1eKenny Root
122a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic int check_content(CMS_ContentInfo *cms)
123a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
124a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
125a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!pos || !*pos)
126a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
127a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT);
128a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
129a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
130a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
131a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
132a88cfce91374498578c44013041416c0c5b09b1eKenny Root
133a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic void do_free_upto(BIO *f, BIO *upto)
134a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
135a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (upto)
136a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
137a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO *tbio;
138a88cfce91374498578c44013041416c0c5b09b1eKenny Root		do
139a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
140a88cfce91374498578c44013041416c0c5b09b1eKenny Root			tbio = BIO_pop(f);
141a88cfce91374498578c44013041416c0c5b09b1eKenny Root			BIO_free(f);
142a88cfce91374498578c44013041416c0c5b09b1eKenny Root			f = tbio;
143a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
144a88cfce91374498578c44013041416c0c5b09b1eKenny Root		while (f != upto);
145a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
146a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
147a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO_free_all(f);
148a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
149a88cfce91374498578c44013041416c0c5b09b1eKenny Root
150a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
151a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
152a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO *cont;
153a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int r;
154a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data)
155a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
156a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA);
157a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
158a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
159a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cont = CMS_dataInit(cms, NULL);
160a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cont)
161a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
162a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = cms_copy_content(out, cont, flags);
163a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO_free_all(cont);
164a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
165a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
166a88cfce91374498578c44013041416c0c5b09b1eKenny Root
167a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
168a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
169a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_ContentInfo *cms;
170a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cms = cms_Data_create();
171a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cms)
172a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
173a88cfce91374498578c44013041416c0c5b09b1eKenny Root
174a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
175a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return cms;
176a88cfce91374498578c44013041416c0c5b09b1eKenny Root
177a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_ContentInfo_free(cms);
178a88cfce91374498578c44013041416c0c5b09b1eKenny Root
179a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
180a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
181a88cfce91374498578c44013041416c0c5b09b1eKenny Root
182a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
183a88cfce91374498578c44013041416c0c5b09b1eKenny Root							unsigned int flags)
184a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
185a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO *cont;
186a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int r;
187a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest)
188a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
189a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA);
190a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
191a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
192a88cfce91374498578c44013041416c0c5b09b1eKenny Root
193a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!dcont && !check_content(cms))
194a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
195a88cfce91374498578c44013041416c0c5b09b1eKenny Root
196a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cont = CMS_dataInit(cms, dcont);
197a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cont)
198a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
199a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = cms_copy_content(out, cont, flags);
200a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (r)
201a88cfce91374498578c44013041416c0c5b09b1eKenny Root		r = cms_DigestedData_do_final(cms, cont, 1);
202a88cfce91374498578c44013041416c0c5b09b1eKenny Root	do_free_upto(cont, dcont);
203a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
204a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
205a88cfce91374498578c44013041416c0c5b09b1eKenny Root
206a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
207a88cfce91374498578c44013041416c0c5b09b1eKenny Root					unsigned int flags)
208a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
209a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_ContentInfo *cms;
210a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!md)
211a88cfce91374498578c44013041416c0c5b09b1eKenny Root		md = EVP_sha1();
212a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cms = cms_DigestedData_create(md);
213a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cms)
214a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
215a88cfce91374498578c44013041416c0c5b09b1eKenny Root
216a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if(!(flags & CMS_DETACHED))
217a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMS_set_detached(cms, 0);
218a88cfce91374498578c44013041416c0c5b09b1eKenny Root
219a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
220a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return cms;
221a88cfce91374498578c44013041416c0c5b09b1eKenny Root
222a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_ContentInfo_free(cms);
223a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
224a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
225a88cfce91374498578c44013041416c0c5b09b1eKenny Root
226a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
227a88cfce91374498578c44013041416c0c5b09b1eKenny Root				const unsigned char *key, size_t keylen,
228a88cfce91374498578c44013041416c0c5b09b1eKenny Root				BIO *dcont, BIO *out, unsigned int flags)
229a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
230a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO *cont;
231a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int r;
232a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted)
233a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
234a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
235a88cfce91374498578c44013041416c0c5b09b1eKenny Root					CMS_R_TYPE_NOT_ENCRYPTED_DATA);
236a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
237a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
238a88cfce91374498578c44013041416c0c5b09b1eKenny Root
239a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!dcont && !check_content(cms))
240a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
241a88cfce91374498578c44013041416c0c5b09b1eKenny Root
242a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
243a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
244a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cont = CMS_dataInit(cms, dcont);
245a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cont)
246a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
247a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = cms_copy_content(out, cont, flags);
248a88cfce91374498578c44013041416c0c5b09b1eKenny Root	do_free_upto(cont, dcont);
249a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
250a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
251a88cfce91374498578c44013041416c0c5b09b1eKenny Root
252a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
253a88cfce91374498578c44013041416c0c5b09b1eKenny Root					const unsigned char *key, size_t keylen,
254a88cfce91374498578c44013041416c0c5b09b1eKenny Root					unsigned int flags)
255a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
256a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_ContentInfo *cms;
257a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cipher)
258a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
259a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER);
260a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
261a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
262a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cms = CMS_ContentInfo_new();
263a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cms)
264a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
265a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
266a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
267a88cfce91374498578c44013041416c0c5b09b1eKenny Root
268a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if(!(flags & CMS_DETACHED))
269a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMS_set_detached(cms, 0);
270a88cfce91374498578c44013041416c0c5b09b1eKenny Root
271a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if ((flags & (CMS_STREAM|CMS_PARTIAL))
272a88cfce91374498578c44013041416c0c5b09b1eKenny Root		|| CMS_final(cms, in, NULL, flags))
273a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return cms;
274a88cfce91374498578c44013041416c0c5b09b1eKenny Root
275a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_ContentInfo_free(cms);
276a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
277a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
278a88cfce91374498578c44013041416c0c5b09b1eKenny Root
279a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
280a88cfce91374498578c44013041416c0c5b09b1eKenny Root					X509_STORE *store,
281a88cfce91374498578c44013041416c0c5b09b1eKenny Root					STACK_OF(X509) *certs,
282a88cfce91374498578c44013041416c0c5b09b1eKenny Root					STACK_OF(X509_CRL) *crls,
283a88cfce91374498578c44013041416c0c5b09b1eKenny Root					unsigned int flags)
284a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
285a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509_STORE_CTX ctx;
286a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509 *signer;
287a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i, j, r = 0;
288a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
289a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!X509_STORE_CTX_init(&ctx, store, signer, certs))
290a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
291a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
292a88cfce91374498578c44013041416c0c5b09b1eKenny Root						CMS_R_STORE_INIT_ERROR);
293a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
294a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
295a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509_STORE_CTX_set_default(&ctx, "smime_sign");
296a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (crls)
297a88cfce91374498578c44013041416c0c5b09b1eKenny Root		X509_STORE_CTX_set0_crls(&ctx, crls);
298a88cfce91374498578c44013041416c0c5b09b1eKenny Root
299a88cfce91374498578c44013041416c0c5b09b1eKenny Root	i = X509_verify_cert(&ctx);
300a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (i <= 0)
301a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
302a88cfce91374498578c44013041416c0c5b09b1eKenny Root		j = X509_STORE_CTX_get_error(&ctx);
303a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
304a88cfce91374498578c44013041416c0c5b09b1eKenny Root						CMS_R_CERTIFICATE_VERIFY_ERROR);
305a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ERR_add_error_data(2, "Verify error:",
306a88cfce91374498578c44013041416c0c5b09b1eKenny Root					 X509_verify_cert_error_string(j));
307a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
308a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
309a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = 1;
310a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
311a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509_STORE_CTX_cleanup(&ctx);
312a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
313a88cfce91374498578c44013041416c0c5b09b1eKenny Root
314a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
315a88cfce91374498578c44013041416c0c5b09b1eKenny Root
316a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
317a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
318a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
319a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_SignerInfo *si;
320a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(CMS_SignerInfo) *sinfos;
321a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(X509) *cms_certs = NULL;
322a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(X509_CRL) *crls = NULL;
323a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509 *signer;
324a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i, scount = 0, ret = 0;
325a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO *cmsbio = NULL, *tmpin = NULL;
326a88cfce91374498578c44013041416c0c5b09b1eKenny Root
327a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!dcont && !check_content(cms))
328a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
329a88cfce91374498578c44013041416c0c5b09b1eKenny Root
330a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Attempt to find all signer certificates */
331a88cfce91374498578c44013041416c0c5b09b1eKenny Root
332a88cfce91374498578c44013041416c0c5b09b1eKenny Root	sinfos = CMS_get0_SignerInfos(cms);
333a88cfce91374498578c44013041416c0c5b09b1eKenny Root
334a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (sk_CMS_SignerInfo_num(sinfos) <= 0)
335a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
336a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS);
337a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
338a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
339a88cfce91374498578c44013041416c0c5b09b1eKenny Root
340a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
341a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
342a88cfce91374498578c44013041416c0c5b09b1eKenny Root		si = sk_CMS_SignerInfo_value(sinfos, i);
343a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
344a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (signer)
345a88cfce91374498578c44013041416c0c5b09b1eKenny Root			scount++;
346a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
347a88cfce91374498578c44013041416c0c5b09b1eKenny Root
348a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (scount != sk_CMS_SignerInfo_num(sinfos))
349a88cfce91374498578c44013041416c0c5b09b1eKenny Root		scount += CMS_set1_signers_certs(cms, certs, flags);
350a88cfce91374498578c44013041416c0c5b09b1eKenny Root
351a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (scount != sk_CMS_SignerInfo_num(sinfos))
352a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
353a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND);
354a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
355a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
356a88cfce91374498578c44013041416c0c5b09b1eKenny Root
357a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Attempt to verify all signers certs */
358a88cfce91374498578c44013041416c0c5b09b1eKenny Root
359a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!(flags & CMS_NO_SIGNER_CERT_VERIFY))
360a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
361a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms_certs = CMS_get1_certs(cms);
362a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!(flags & CMS_NOCRL))
363a88cfce91374498578c44013041416c0c5b09b1eKenny Root			crls = CMS_get1_crls(cms);
364a88cfce91374498578c44013041416c0c5b09b1eKenny Root		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
365a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
366a88cfce91374498578c44013041416c0c5b09b1eKenny Root			si = sk_CMS_SignerInfo_value(sinfos, i);
367a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (!cms_signerinfo_verify_cert(si, store,
368a88cfce91374498578c44013041416c0c5b09b1eKenny Root							cms_certs, crls, flags))
369a88cfce91374498578c44013041416c0c5b09b1eKenny Root				goto err;
370a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
371a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
372a88cfce91374498578c44013041416c0c5b09b1eKenny Root
373a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Attempt to verify all SignerInfo signed attribute signatures */
374a88cfce91374498578c44013041416c0c5b09b1eKenny Root
375a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!(flags & CMS_NO_ATTR_VERIFY))
376a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
377a88cfce91374498578c44013041416c0c5b09b1eKenny Root		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
378a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
379a88cfce91374498578c44013041416c0c5b09b1eKenny Root			si = sk_CMS_SignerInfo_value(sinfos, i);
380a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (CMS_signed_get_attr_count(si) < 0)
381a88cfce91374498578c44013041416c0c5b09b1eKenny Root				continue;
382a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (CMS_SignerInfo_verify(si) <= 0)
383a88cfce91374498578c44013041416c0c5b09b1eKenny Root				goto err;
384a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
385a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
386a88cfce91374498578c44013041416c0c5b09b1eKenny Root
387a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Performance optimization: if the content is a memory BIO then
388a88cfce91374498578c44013041416c0c5b09b1eKenny Root	 * store its contents in a temporary read only memory BIO. This
389a88cfce91374498578c44013041416c0c5b09b1eKenny Root	 * avoids potentially large numbers of slow copies of data which will
390a88cfce91374498578c44013041416c0c5b09b1eKenny Root	 * occur when reading from a read write memory BIO when signatures
391a88cfce91374498578c44013041416c0c5b09b1eKenny Root	 * are calculated.
392a88cfce91374498578c44013041416c0c5b09b1eKenny Root	 */
393a88cfce91374498578c44013041416c0c5b09b1eKenny Root
394a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM))
395a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
396a88cfce91374498578c44013041416c0c5b09b1eKenny Root		char *ptr;
397a88cfce91374498578c44013041416c0c5b09b1eKenny Root		long len;
398a88cfce91374498578c44013041416c0c5b09b1eKenny Root		len = BIO_get_mem_data(dcont, &ptr);
399a88cfce91374498578c44013041416c0c5b09b1eKenny Root		tmpin = BIO_new_mem_buf(ptr, len);
400a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (tmpin == NULL)
401a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
402a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_VERIFY,ERR_R_MALLOC_FAILURE);
403a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return 0;
404a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
405a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
406a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
407a88cfce91374498578c44013041416c0c5b09b1eKenny Root		tmpin = dcont;
408a88cfce91374498578c44013041416c0c5b09b1eKenny Root
409a88cfce91374498578c44013041416c0c5b09b1eKenny Root
410a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cmsbio=CMS_dataInit(cms, tmpin);
411a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cmsbio)
412a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
413a88cfce91374498578c44013041416c0c5b09b1eKenny Root
414a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cms_copy_content(out, cmsbio, flags))
415a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
416a88cfce91374498578c44013041416c0c5b09b1eKenny Root
417a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!(flags & CMS_NO_CONTENT_VERIFY))
418a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
419a88cfce91374498578c44013041416c0c5b09b1eKenny Root		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
420a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
421a88cfce91374498578c44013041416c0c5b09b1eKenny Root			si = sk_CMS_SignerInfo_value(sinfos, i);
422a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0)
423a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
424a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMSerr(CMS_F_CMS_VERIFY,
425a88cfce91374498578c44013041416c0c5b09b1eKenny Root					CMS_R_CONTENT_VERIFY_ERROR);
426a88cfce91374498578c44013041416c0c5b09b1eKenny Root				goto err;
427a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
428a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
429a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
430a88cfce91374498578c44013041416c0c5b09b1eKenny Root
431a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ret = 1;
432a88cfce91374498578c44013041416c0c5b09b1eKenny Root
433a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
434a88cfce91374498578c44013041416c0c5b09b1eKenny Root
435a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (dcont && (tmpin == dcont))
436a88cfce91374498578c44013041416c0c5b09b1eKenny Root		do_free_upto(cmsbio, dcont);
437a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
438a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO_free_all(cmsbio);
439a88cfce91374498578c44013041416c0c5b09b1eKenny Root
440a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (cms_certs)
441a88cfce91374498578c44013041416c0c5b09b1eKenny Root		sk_X509_pop_free(cms_certs, X509_free);
442a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (crls)
443a88cfce91374498578c44013041416c0c5b09b1eKenny Root		sk_X509_CRL_pop_free(crls, X509_CRL_free);
444a88cfce91374498578c44013041416c0c5b09b1eKenny Root
445a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return ret;
446a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
447a88cfce91374498578c44013041416c0c5b09b1eKenny Root
448a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
449a88cfce91374498578c44013041416c0c5b09b1eKenny Root			STACK_OF(X509) *certs,
450a88cfce91374498578c44013041416c0c5b09b1eKenny Root			X509_STORE *store, unsigned int flags)
451a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
452a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int r;
453a88cfce91374498578c44013041416c0c5b09b1eKenny Root	flags &= ~(CMS_DETACHED|CMS_TEXT);
454a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
455a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (r <= 0)
456a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return r;
457a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return cms_Receipt_verify(rcms, ocms);
458a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
459a88cfce91374498578c44013041416c0c5b09b1eKenny Root
460a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
461a88cfce91374498578c44013041416c0c5b09b1eKenny Root						BIO *data, unsigned int flags)
462a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
463a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_ContentInfo *cms;
464a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i;
465a88cfce91374498578c44013041416c0c5b09b1eKenny Root
466a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cms = CMS_ContentInfo_new();
467a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cms || !CMS_SignedData_init(cms))
468a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto merr;
469a88cfce91374498578c44013041416c0c5b09b1eKenny Root
470a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags))
471a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
472a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
473a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
474a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
475a88cfce91374498578c44013041416c0c5b09b1eKenny Root
476a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_X509_num(certs); i++)
477a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
478a88cfce91374498578c44013041416c0c5b09b1eKenny Root		X509 *x = sk_X509_value(certs, i);
479a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!CMS_add1_cert(cms, x))
480a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto merr;
481a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
482a88cfce91374498578c44013041416c0c5b09b1eKenny Root
483a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if(!(flags & CMS_DETACHED))
484a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMS_set_detached(cms, 0);
485a88cfce91374498578c44013041416c0c5b09b1eKenny Root
486a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if ((flags & (CMS_STREAM|CMS_PARTIAL))
487a88cfce91374498578c44013041416c0c5b09b1eKenny Root		|| CMS_final(cms, data, NULL, flags))
488a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return cms;
489a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
490a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
491a88cfce91374498578c44013041416c0c5b09b1eKenny Root
492a88cfce91374498578c44013041416c0c5b09b1eKenny Root	merr:
493a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);
494a88cfce91374498578c44013041416c0c5b09b1eKenny Root
495a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
496a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (cms)
497a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMS_ContentInfo_free(cms);
498a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
499a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
500a88cfce91374498578c44013041416c0c5b09b1eKenny Root
501a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
502a88cfce91374498578c44013041416c0c5b09b1eKenny Root					X509 *signcert, EVP_PKEY *pkey,
503a88cfce91374498578c44013041416c0c5b09b1eKenny Root					STACK_OF(X509) *certs,
504a88cfce91374498578c44013041416c0c5b09b1eKenny Root					unsigned int flags)
505a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
506a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_SignerInfo *rct_si;
507a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_ContentInfo *cms = NULL;
508a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_OCTET_STRING **pos, *os;
509a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO *rct_cont = NULL;
510a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int r = 0;
511a88cfce91374498578c44013041416c0c5b09b1eKenny Root
512a88cfce91374498578c44013041416c0c5b09b1eKenny Root	flags &= ~(CMS_STREAM|CMS_TEXT);
513a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Not really detached but avoids content being allocated */
514a88cfce91374498578c44013041416c0c5b09b1eKenny Root	flags |= CMS_PARTIAL|CMS_BINARY|CMS_DETACHED;
515a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!pkey || !signcert)
516a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
517a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT);
518a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
519a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
520a88cfce91374498578c44013041416c0c5b09b1eKenny Root
521a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Initialize signed data */
522a88cfce91374498578c44013041416c0c5b09b1eKenny Root
523a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cms = CMS_sign(NULL, NULL, certs, NULL, flags);
524a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cms)
525a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
526a88cfce91374498578c44013041416c0c5b09b1eKenny Root
527a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Set inner content type to signed receipt */
528a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
529a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
530a88cfce91374498578c44013041416c0c5b09b1eKenny Root
531a88cfce91374498578c44013041416c0c5b09b1eKenny Root	rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
532a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!rct_si)
533a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
534a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR);
535a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
536a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
537a88cfce91374498578c44013041416c0c5b09b1eKenny Root
538a88cfce91374498578c44013041416c0c5b09b1eKenny Root	os = cms_encode_Receipt(si);
539a88cfce91374498578c44013041416c0c5b09b1eKenny Root
540a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!os)
541a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
542a88cfce91374498578c44013041416c0c5b09b1eKenny Root
543a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Set content to digest */
544a88cfce91374498578c44013041416c0c5b09b1eKenny Root	rct_cont = BIO_new_mem_buf(os->data, os->length);
545a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!rct_cont)
546a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
547a88cfce91374498578c44013041416c0c5b09b1eKenny Root
548a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Add msgSigDigest attribute */
549a88cfce91374498578c44013041416c0c5b09b1eKenny Root
550a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cms_msgSigDigest_add1(rct_si, si))
551a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
552a88cfce91374498578c44013041416c0c5b09b1eKenny Root
553a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Finalize structure */
554a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!CMS_final(cms, rct_cont, NULL, flags))
555a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
556a88cfce91374498578c44013041416c0c5b09b1eKenny Root
557a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Set embedded content */
558a88cfce91374498578c44013041416c0c5b09b1eKenny Root	pos = CMS_get0_content(cms);
559a88cfce91374498578c44013041416c0c5b09b1eKenny Root	*pos = os;
560a88cfce91374498578c44013041416c0c5b09b1eKenny Root
561a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = 1;
562a88cfce91374498578c44013041416c0c5b09b1eKenny Root
563a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
564a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (rct_cont)
565a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO_free(rct_cont);
566a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (r)
567a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return cms;
568a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_ContentInfo_free(cms);
569a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
570a88cfce91374498578c44013041416c0c5b09b1eKenny Root
571a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
572a88cfce91374498578c44013041416c0c5b09b1eKenny Root
573a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
574a88cfce91374498578c44013041416c0c5b09b1eKenny Root				const EVP_CIPHER *cipher, unsigned int flags)
575a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
576a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_ContentInfo *cms;
577a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i;
578a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509 *recip;
579a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cms = CMS_EnvelopedData_create(cipher);
580a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cms)
581a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto merr;
582a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_X509_num(certs); i++)
583a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
584a88cfce91374498578c44013041416c0c5b09b1eKenny Root		recip = sk_X509_value(certs, i);
585a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!CMS_add1_recipient_cert(cms, recip, flags))
586a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
587a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
588a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
589a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
590a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
591a88cfce91374498578c44013041416c0c5b09b1eKenny Root
592a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if(!(flags & CMS_DETACHED))
593a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMS_set_detached(cms, 0);
594a88cfce91374498578c44013041416c0c5b09b1eKenny Root
595a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if ((flags & (CMS_STREAM|CMS_PARTIAL))
596a88cfce91374498578c44013041416c0c5b09b1eKenny Root		|| CMS_final(cms, data, NULL, flags))
597a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return cms;
598a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
599a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
600a88cfce91374498578c44013041416c0c5b09b1eKenny Root
601a88cfce91374498578c44013041416c0c5b09b1eKenny Root	merr:
602a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
603a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
604a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (cms)
605a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMS_ContentInfo_free(cms);
606a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
607a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
608a88cfce91374498578c44013041416c0c5b09b1eKenny Root
609a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
610a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
611a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(CMS_RecipientInfo) *ris;
612a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_RecipientInfo *ri;
613a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i, r;
61477c6be7176c48d2ce4d5979a84876d34204eedafKenny Root	int debug = 0, ri_match = 0;
615a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ris = CMS_get0_RecipientInfos(cms);
616a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (ris)
617a88cfce91374498578c44013041416c0c5b09b1eKenny Root		debug = cms->d.envelopedData->encryptedContentInfo->debug;
618a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
619a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
620a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ri = sk_CMS_RecipientInfo_value(ris, i);
621a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS)
622a88cfce91374498578c44013041416c0c5b09b1eKenny Root				continue;
62377c6be7176c48d2ce4d5979a84876d34204eedafKenny Root		ri_match = 1;
624a88cfce91374498578c44013041416c0c5b09b1eKenny Root		/* If we have a cert try matching RecipientInfo
625a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 * otherwise try them all.
626a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 */
627a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!cert || (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0))
628a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
629a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMS_RecipientInfo_set0_pkey(ri, pk);
630a88cfce91374498578c44013041416c0c5b09b1eKenny Root			r = CMS_RecipientInfo_decrypt(cms, ri);
631a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMS_RecipientInfo_set0_pkey(ri, NULL);
632a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (cert)
633a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
634a88cfce91374498578c44013041416c0c5b09b1eKenny Root				/* If not debugging clear any error and
635a88cfce91374498578c44013041416c0c5b09b1eKenny Root				 * return success to avoid leaking of
636a88cfce91374498578c44013041416c0c5b09b1eKenny Root				 * information useful to MMA
637a88cfce91374498578c44013041416c0c5b09b1eKenny Root				 */
638a88cfce91374498578c44013041416c0c5b09b1eKenny Root				if (!debug)
639a88cfce91374498578c44013041416c0c5b09b1eKenny Root					{
640a88cfce91374498578c44013041416c0c5b09b1eKenny Root					ERR_clear_error();
641a88cfce91374498578c44013041416c0c5b09b1eKenny Root					return 1;
642a88cfce91374498578c44013041416c0c5b09b1eKenny Root					}
643a88cfce91374498578c44013041416c0c5b09b1eKenny Root				if (r > 0)
644a88cfce91374498578c44013041416c0c5b09b1eKenny Root					return 1;
645a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY,
646a88cfce91374498578c44013041416c0c5b09b1eKenny Root						CMS_R_DECRYPT_ERROR);
647a88cfce91374498578c44013041416c0c5b09b1eKenny Root				return 0;
648a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
649a88cfce91374498578c44013041416c0c5b09b1eKenny Root			/* If no cert and not debugging don't leave loop
650a88cfce91374498578c44013041416c0c5b09b1eKenny Root			 * after first successful decrypt. Always attempt
651a88cfce91374498578c44013041416c0c5b09b1eKenny Root			 * to decrypt all recipients to avoid leaking timing
652a88cfce91374498578c44013041416c0c5b09b1eKenny Root			 * of a successful decrypt.
653a88cfce91374498578c44013041416c0c5b09b1eKenny Root			 */
654a88cfce91374498578c44013041416c0c5b09b1eKenny Root			else if (r > 0 && debug)
655a88cfce91374498578c44013041416c0c5b09b1eKenny Root				return 1;
656a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
657a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
658a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* If no cert and not debugging always return success */
65977c6be7176c48d2ce4d5979a84876d34204eedafKenny Root	if (ri_match && !cert && !debug)
660a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
661a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ERR_clear_error();
662a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 1;
663a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
664a88cfce91374498578c44013041416c0c5b09b1eKenny Root
665a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT);
666a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 0;
667a88cfce91374498578c44013041416c0c5b09b1eKenny Root
668a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
669a88cfce91374498578c44013041416c0c5b09b1eKenny Root
670a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_decrypt_set1_key(CMS_ContentInfo *cms,
671a88cfce91374498578c44013041416c0c5b09b1eKenny Root				unsigned char *key, size_t keylen,
672a88cfce91374498578c44013041416c0c5b09b1eKenny Root				unsigned char *id, size_t idlen)
673a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
674a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(CMS_RecipientInfo) *ris;
675a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_RecipientInfo *ri;
676a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i, r;
677a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ris = CMS_get0_RecipientInfos(cms);
678a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
679a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
680a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ri = sk_CMS_RecipientInfo_value(ris, i);
681a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK)
682a88cfce91374498578c44013041416c0c5b09b1eKenny Root				continue;
683a88cfce91374498578c44013041416c0c5b09b1eKenny Root
684a88cfce91374498578c44013041416c0c5b09b1eKenny Root		/* If we have an id try matching RecipientInfo
685a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 * otherwise try them all.
686a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 */
687a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0))
688a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
689a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMS_RecipientInfo_set0_key(ri, key, keylen);
690a88cfce91374498578c44013041416c0c5b09b1eKenny Root			r = CMS_RecipientInfo_decrypt(cms, ri);
691a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMS_RecipientInfo_set0_key(ri, NULL, 0);
692a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (r > 0)
693a88cfce91374498578c44013041416c0c5b09b1eKenny Root				return 1;
694a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (id)
695a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
696a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY,
697a88cfce91374498578c44013041416c0c5b09b1eKenny Root						CMS_R_DECRYPT_ERROR);
698a88cfce91374498578c44013041416c0c5b09b1eKenny Root				return 0;
699a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
700a88cfce91374498578c44013041416c0c5b09b1eKenny Root			ERR_clear_error();
701a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
702a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
703a88cfce91374498578c44013041416c0c5b09b1eKenny Root
704a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT);
705a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 0;
706a88cfce91374498578c44013041416c0c5b09b1eKenny Root
707a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
708a88cfce91374498578c44013041416c0c5b09b1eKenny Root
709a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_decrypt_set1_password(CMS_ContentInfo *cms,
710a88cfce91374498578c44013041416c0c5b09b1eKenny Root				unsigned char *pass, ossl_ssize_t passlen)
711a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
712a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(CMS_RecipientInfo) *ris;
713a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_RecipientInfo *ri;
714a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i, r;
715a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ris = CMS_get0_RecipientInfos(cms);
716a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
717a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
718a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ri = sk_CMS_RecipientInfo_value(ris, i);
719a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS)
720a88cfce91374498578c44013041416c0c5b09b1eKenny Root				continue;
721a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMS_RecipientInfo_set0_password(ri, pass, passlen);
722a88cfce91374498578c44013041416c0c5b09b1eKenny Root		r = CMS_RecipientInfo_decrypt(cms, ri);
723a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMS_RecipientInfo_set0_password(ri, NULL, 0);
724a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (r > 0)
725a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return 1;
726a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
727a88cfce91374498578c44013041416c0c5b09b1eKenny Root
728a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT);
729a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 0;
730a88cfce91374498578c44013041416c0c5b09b1eKenny Root
731a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
732a88cfce91374498578c44013041416c0c5b09b1eKenny Root
733a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
734a88cfce91374498578c44013041416c0c5b09b1eKenny Root				BIO *dcont, BIO *out,
735a88cfce91374498578c44013041416c0c5b09b1eKenny Root				unsigned int flags)
736a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
737a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int r;
738a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO *cont;
739a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped)
740a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
741a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
742a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
743a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
744a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!dcont && !check_content(cms))
745a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
746a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (flags & CMS_DEBUG_DECRYPT)
747a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms->d.envelopedData->encryptedContentInfo->debug = 1;
748a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
749a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms->d.envelopedData->encryptedContentInfo->debug = 0;
750a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!pk && !cert && !dcont && !out)
751a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 1;
752a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
753a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
754a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cont = CMS_dataInit(cms, dcont);
755a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cont)
756a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
757a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = cms_copy_content(out, cont, flags);
758a88cfce91374498578c44013041416c0c5b09b1eKenny Root	do_free_upto(cont, dcont);
759a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
760a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
761a88cfce91374498578c44013041416c0c5b09b1eKenny Root
762a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
763a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
764a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO *cmsbio;
765a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int ret = 0;
766a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!(cmsbio = CMS_dataInit(cms, dcont)))
767a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
768a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_FINAL,ERR_R_MALLOC_FAILURE);
769a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
770a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
771a88cfce91374498578c44013041416c0c5b09b1eKenny Root
772a88cfce91374498578c44013041416c0c5b09b1eKenny Root	SMIME_crlf_copy(data, cmsbio, flags);
773a88cfce91374498578c44013041416c0c5b09b1eKenny Root
774a88cfce91374498578c44013041416c0c5b09b1eKenny Root	(void)BIO_flush(cmsbio);
775a88cfce91374498578c44013041416c0c5b09b1eKenny Root
776a88cfce91374498578c44013041416c0c5b09b1eKenny Root
777a88cfce91374498578c44013041416c0c5b09b1eKenny Root        if (!CMS_dataFinal(cms, cmsbio))
778a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
779a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_FINAL,CMS_R_CMS_DATAFINAL_ERROR);
780a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
781a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
782a88cfce91374498578c44013041416c0c5b09b1eKenny Root
783a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ret = 1;
784a88cfce91374498578c44013041416c0c5b09b1eKenny Root
785a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
786a88cfce91374498578c44013041416c0c5b09b1eKenny Root	do_free_upto(cmsbio, dcont);
787a88cfce91374498578c44013041416c0c5b09b1eKenny Root
788a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return ret;
789a88cfce91374498578c44013041416c0c5b09b1eKenny Root
790a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
791a88cfce91374498578c44013041416c0c5b09b1eKenny Root
792a88cfce91374498578c44013041416c0c5b09b1eKenny Root#ifdef ZLIB
793a88cfce91374498578c44013041416c0c5b09b1eKenny Root
794a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
795a88cfce91374498578c44013041416c0c5b09b1eKenny Root							unsigned int flags)
796a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
797a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO *cont;
798a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int r;
799a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData)
800a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
801a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_UNCOMPRESS,
802a88cfce91374498578c44013041416c0c5b09b1eKenny Root					CMS_R_TYPE_NOT_COMPRESSED_DATA);
803a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
804a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
805a88cfce91374498578c44013041416c0c5b09b1eKenny Root
806a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!dcont && !check_content(cms))
807a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
808a88cfce91374498578c44013041416c0c5b09b1eKenny Root
809a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cont = CMS_dataInit(cms, dcont);
810a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cont)
811a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
812a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = cms_copy_content(out, cont, flags);
813a88cfce91374498578c44013041416c0c5b09b1eKenny Root	do_free_upto(cont, dcont);
814a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
815a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
816a88cfce91374498578c44013041416c0c5b09b1eKenny Root
817a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
818a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
819a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_ContentInfo *cms;
820a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (comp_nid <= 0)
821a88cfce91374498578c44013041416c0c5b09b1eKenny Root		comp_nid = NID_zlib_compression;
822a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cms = cms_CompressedData_create(comp_nid);
823a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cms)
824a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
825a88cfce91374498578c44013041416c0c5b09b1eKenny Root
826a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if(!(flags & CMS_DETACHED))
827a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMS_set_detached(cms, 0);
828a88cfce91374498578c44013041416c0c5b09b1eKenny Root
829a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
830a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return cms;
831a88cfce91374498578c44013041416c0c5b09b1eKenny Root
832a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_ContentInfo_free(cms);
833a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
834a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
835a88cfce91374498578c44013041416c0c5b09b1eKenny Root
836a88cfce91374498578c44013041416c0c5b09b1eKenny Root#else
837a88cfce91374498578c44013041416c0c5b09b1eKenny Root
838a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
839a88cfce91374498578c44013041416c0c5b09b1eKenny Root							unsigned int flags)
840a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
841a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
842a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 0;
843a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
844a88cfce91374498578c44013041416c0c5b09b1eKenny Root
845a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
846a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
847a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
848a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
849a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
850a88cfce91374498578c44013041416c0c5b09b1eKenny Root
851a88cfce91374498578c44013041416c0c5b09b1eKenny Root#endif
852