1a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* crypto/cms/cms_lib.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 <openssl/asn1t.h>
55a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/x509.h>
56a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/err.h>
57a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/pem.h>
58a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/bio.h>
59a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/asn1.h>
60a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include "cms.h"
61a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include "cms_lcl.h"
62a88cfce91374498578c44013041416c0c5b09b1eKenny Root
63a88cfce91374498578c44013041416c0c5b09b1eKenny RootIMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
64a88cfce91374498578c44013041416c0c5b09b1eKenny RootIMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
65a88cfce91374498578c44013041416c0c5b09b1eKenny Root
66a88cfce91374498578c44013041416c0c5b09b1eKenny RootDECLARE_ASN1_ITEM(CMS_CertificateChoices)
67a88cfce91374498578c44013041416c0c5b09b1eKenny RootDECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
68a88cfce91374498578c44013041416c0c5b09b1eKenny RootDECLARE_STACK_OF(CMS_CertificateChoices)
69a88cfce91374498578c44013041416c0c5b09b1eKenny RootDECLARE_STACK_OF(CMS_RevocationInfoChoice)
70a88cfce91374498578c44013041416c0c5b09b1eKenny Root
71a88cfce91374498578c44013041416c0c5b09b1eKenny Rootconst ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms)
72a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
73a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return cms->contentType;
74a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
75a88cfce91374498578c44013041416c0c5b09b1eKenny Root
76a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_ContentInfo *cms_Data_create(void)
77a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
78a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_ContentInfo *cms;
79a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cms = CMS_ContentInfo_new();
80a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (cms)
81a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
82a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
83a88cfce91374498578c44013041416c0c5b09b1eKenny Root		/* Never detached */
84a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMS_set_detached(cms, 0);
85a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
86a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return cms;
87a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
88a88cfce91374498578c44013041416c0c5b09b1eKenny Root
89a88cfce91374498578c44013041416c0c5b09b1eKenny RootBIO *cms_content_bio(CMS_ContentInfo *cms)
90a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
91a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
92a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!pos)
93a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
94a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* If content detached data goes nowhere: create NULL BIO */
95a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!*pos)
96a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return BIO_new(BIO_s_null());
97a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* If content not detached and created return memory BIO
98a88cfce91374498578c44013041416c0c5b09b1eKenny Root	 */
99a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
100a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return BIO_new(BIO_s_mem());
101a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Else content was read in: return read only BIO for it */
102a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return BIO_new_mem_buf((*pos)->data, (*pos)->length);
103a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
104a88cfce91374498578c44013041416c0c5b09b1eKenny Root
105a88cfce91374498578c44013041416c0c5b09b1eKenny RootBIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
106a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
107a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO *cmsbio, *cont;
108a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (icont)
109a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cont = icont;
110a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
111a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cont = cms_content_bio(cms);
112a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cont)
113a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
114a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT);
115a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
116a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
117a88cfce91374498578c44013041416c0c5b09b1eKenny Root	switch (OBJ_obj2nid(cms->contentType))
118a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
119a88cfce91374498578c44013041416c0c5b09b1eKenny Root
120a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_data:
121a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return cont;
122a88cfce91374498578c44013041416c0c5b09b1eKenny Root
123a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_signed:
124a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cmsbio = cms_SignedData_init_bio(cms);
125a88cfce91374498578c44013041416c0c5b09b1eKenny Root		break;
126a88cfce91374498578c44013041416c0c5b09b1eKenny Root
127a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_digest:
128a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cmsbio = cms_DigestedData_init_bio(cms);
129a88cfce91374498578c44013041416c0c5b09b1eKenny Root		break;
130a88cfce91374498578c44013041416c0c5b09b1eKenny Root#ifdef ZLIB
131a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_id_smime_ct_compressedData:
132a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cmsbio = cms_CompressedData_init_bio(cms);
133a88cfce91374498578c44013041416c0c5b09b1eKenny Root		break;
134a88cfce91374498578c44013041416c0c5b09b1eKenny Root#endif
135a88cfce91374498578c44013041416c0c5b09b1eKenny Root
136a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_encrypted:
137a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cmsbio = cms_EncryptedData_init_bio(cms);
138a88cfce91374498578c44013041416c0c5b09b1eKenny Root		break;
139a88cfce91374498578c44013041416c0c5b09b1eKenny Root
140a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_enveloped:
141a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cmsbio = cms_EnvelopedData_init_bio(cms);
142a88cfce91374498578c44013041416c0c5b09b1eKenny Root		break;
143a88cfce91374498578c44013041416c0c5b09b1eKenny Root
144a88cfce91374498578c44013041416c0c5b09b1eKenny Root		default:
145a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
146a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
147a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
148a88cfce91374498578c44013041416c0c5b09b1eKenny Root
149a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (cmsbio)
150a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return BIO_push(cmsbio, cont);
151a88cfce91374498578c44013041416c0c5b09b1eKenny Root
152a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!icont)
153a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO_free(cont);
154a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
155a88cfce91374498578c44013041416c0c5b09b1eKenny Root
156a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
157a88cfce91374498578c44013041416c0c5b09b1eKenny Root
158a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
159a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
160a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
161a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!pos)
162a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
163a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* If ebmedded content find memory BIO and set content */
164a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT))
165a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
166a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO *mbio;
167a88cfce91374498578c44013041416c0c5b09b1eKenny Root		unsigned char *cont;
168a88cfce91374498578c44013041416c0c5b09b1eKenny Root		long contlen;
169a88cfce91374498578c44013041416c0c5b09b1eKenny Root		mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
170a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!mbio)
171a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
172a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND);
173a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return 0;
174a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
175a88cfce91374498578c44013041416c0c5b09b1eKenny Root		contlen = BIO_get_mem_data(mbio, &cont);
176a88cfce91374498578c44013041416c0c5b09b1eKenny Root		/* Set bio as read only so its content can't be clobbered */
177a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
178a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO_set_mem_eof_return(mbio, 0);
179a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ASN1_STRING_set0(*pos, cont, contlen);
180a88cfce91374498578c44013041416c0c5b09b1eKenny Root		(*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
181a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
182a88cfce91374498578c44013041416c0c5b09b1eKenny Root
183a88cfce91374498578c44013041416c0c5b09b1eKenny Root	switch (OBJ_obj2nid(cms->contentType))
184a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
185a88cfce91374498578c44013041416c0c5b09b1eKenny Root
186a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_data:
187a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_enveloped:
188a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_encrypted:
189a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_id_smime_ct_compressedData:
190a88cfce91374498578c44013041416c0c5b09b1eKenny Root		/* Nothing to do */
191a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 1;
192a88cfce91374498578c44013041416c0c5b09b1eKenny Root
193a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_signed:
194a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return cms_SignedData_final(cms, cmsbio);
195a88cfce91374498578c44013041416c0c5b09b1eKenny Root
196a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_digest:
197a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return cms_DigestedData_do_final(cms, cmsbio, 0);
198a88cfce91374498578c44013041416c0c5b09b1eKenny Root
199a88cfce91374498578c44013041416c0c5b09b1eKenny Root		default:
200a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE);
201a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
202a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
203a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
204a88cfce91374498578c44013041416c0c5b09b1eKenny Root
205a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Return an OCTET STRING pointer to content. This allows it to
206a88cfce91374498578c44013041416c0c5b09b1eKenny Root * be accessed or set later.
207a88cfce91374498578c44013041416c0c5b09b1eKenny Root */
208a88cfce91374498578c44013041416c0c5b09b1eKenny Root
209a88cfce91374498578c44013041416c0c5b09b1eKenny RootASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
210a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
211a88cfce91374498578c44013041416c0c5b09b1eKenny Root	switch (OBJ_obj2nid(cms->contentType))
212a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
213a88cfce91374498578c44013041416c0c5b09b1eKenny Root
214a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_data:
215a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.data;
216a88cfce91374498578c44013041416c0c5b09b1eKenny Root
217a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_signed:
218a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.signedData->encapContentInfo->eContent;
219a88cfce91374498578c44013041416c0c5b09b1eKenny Root
220a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_enveloped:
221a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
222a88cfce91374498578c44013041416c0c5b09b1eKenny Root
223a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_digest:
224a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.digestedData->encapContentInfo->eContent;
225a88cfce91374498578c44013041416c0c5b09b1eKenny Root
226a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_encrypted:
227a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
228a88cfce91374498578c44013041416c0c5b09b1eKenny Root
229a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_id_smime_ct_authData:
230a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.authenticatedData->encapContentInfo->eContent;
231a88cfce91374498578c44013041416c0c5b09b1eKenny Root
232a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_id_smime_ct_compressedData:
233a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.compressedData->encapContentInfo->eContent;
234a88cfce91374498578c44013041416c0c5b09b1eKenny Root
235a88cfce91374498578c44013041416c0c5b09b1eKenny Root		default:
236a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (cms->d.other->type == V_ASN1_OCTET_STRING)
237a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return &cms->d.other->value.octet_string;
238a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE);
239a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
240a88cfce91374498578c44013041416c0c5b09b1eKenny Root
241a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
242a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
243a88cfce91374498578c44013041416c0c5b09b1eKenny Root
244a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Return an ASN1_OBJECT pointer to content type. This allows it to
245a88cfce91374498578c44013041416c0c5b09b1eKenny Root * be accessed or set later.
246a88cfce91374498578c44013041416c0c5b09b1eKenny Root */
247a88cfce91374498578c44013041416c0c5b09b1eKenny Root
248a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
249a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
250a88cfce91374498578c44013041416c0c5b09b1eKenny Root	switch (OBJ_obj2nid(cms->contentType))
251a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
252a88cfce91374498578c44013041416c0c5b09b1eKenny Root
253a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_signed:
254a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.signedData->encapContentInfo->eContentType;
255a88cfce91374498578c44013041416c0c5b09b1eKenny Root
256a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_enveloped:
257a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.envelopedData->encryptedContentInfo->contentType;
258a88cfce91374498578c44013041416c0c5b09b1eKenny Root
259a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_digest:
260a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.digestedData->encapContentInfo->eContentType;
261a88cfce91374498578c44013041416c0c5b09b1eKenny Root
262a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_encrypted:
263a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.encryptedData->encryptedContentInfo->contentType;
264a88cfce91374498578c44013041416c0c5b09b1eKenny Root
265a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_id_smime_ct_authData:
266a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.authenticatedData->encapContentInfo->eContentType;
267a88cfce91374498578c44013041416c0c5b09b1eKenny Root
268a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_id_smime_ct_compressedData:
269a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.compressedData->encapContentInfo->eContentType;
270a88cfce91374498578c44013041416c0c5b09b1eKenny Root
271a88cfce91374498578c44013041416c0c5b09b1eKenny Root		default:
272a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE,
273a88cfce91374498578c44013041416c0c5b09b1eKenny Root					CMS_R_UNSUPPORTED_CONTENT_TYPE);
274a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
275a88cfce91374498578c44013041416c0c5b09b1eKenny Root
276a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
277a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
278a88cfce91374498578c44013041416c0c5b09b1eKenny Root
279a88cfce91374498578c44013041416c0c5b09b1eKenny Rootconst ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
280a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
281a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_OBJECT **petype;
282a88cfce91374498578c44013041416c0c5b09b1eKenny Root	petype = cms_get0_econtent_type(cms);
283a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (petype)
284a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return *petype;
285a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
286a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
287a88cfce91374498578c44013041416c0c5b09b1eKenny Root
288a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
289a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
290a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_OBJECT **petype, *etype;
291a88cfce91374498578c44013041416c0c5b09b1eKenny Root	petype = cms_get0_econtent_type(cms);
292a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!petype)
293a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
294a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!oid)
295a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 1;
296a88cfce91374498578c44013041416c0c5b09b1eKenny Root	etype = OBJ_dup(oid);
297a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!etype)
298a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
299a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_OBJECT_free(*petype);
300a88cfce91374498578c44013041416c0c5b09b1eKenny Root	*petype = etype;
301a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
302a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
303a88cfce91374498578c44013041416c0c5b09b1eKenny Root
304a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_is_detached(CMS_ContentInfo *cms)
305a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
306a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_OCTET_STRING **pos;
307a88cfce91374498578c44013041416c0c5b09b1eKenny Root	pos = CMS_get0_content(cms);
308a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!pos)
309a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return -1;
310a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (*pos)
311a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
312a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
313a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
314a88cfce91374498578c44013041416c0c5b09b1eKenny Root
315a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_set_detached(CMS_ContentInfo *cms, int detached)
316a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
317a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_OCTET_STRING **pos;
318a88cfce91374498578c44013041416c0c5b09b1eKenny Root	pos = CMS_get0_content(cms);
319a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!pos)
320a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
321a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (detached)
322a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
323a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (*pos)
324a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
325a88cfce91374498578c44013041416c0c5b09b1eKenny Root			ASN1_OCTET_STRING_free(*pos);
326a88cfce91374498578c44013041416c0c5b09b1eKenny Root			*pos = NULL;
327a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
328a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 1;
329a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
330a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!*pos)
331a88cfce91374498578c44013041416c0c5b09b1eKenny Root		*pos = ASN1_OCTET_STRING_new();
332a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (*pos)
333a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
334a88cfce91374498578c44013041416c0c5b09b1eKenny Root		/* NB: special flag to show content is created and not
335a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 * read in.
336a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 */
337a88cfce91374498578c44013041416c0c5b09b1eKenny Root		(*pos)->flags |= ASN1_STRING_FLAG_CONT;
338a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 1;
339a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
340a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE);
341a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 0;
342a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
343a88cfce91374498578c44013041416c0c5b09b1eKenny Root
344a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
345a88cfce91374498578c44013041416c0c5b09b1eKenny Root
346a88cfce91374498578c44013041416c0c5b09b1eKenny Rootvoid cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md)
347a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
348a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int param_type;
349a88cfce91374498578c44013041416c0c5b09b1eKenny Root
350a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
351a88cfce91374498578c44013041416c0c5b09b1eKenny Root		param_type = V_ASN1_UNDEF;
352a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
353a88cfce91374498578c44013041416c0c5b09b1eKenny Root		param_type = V_ASN1_NULL;
354a88cfce91374498578c44013041416c0c5b09b1eKenny Root
355a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
356a88cfce91374498578c44013041416c0c5b09b1eKenny Root
357a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
358a88cfce91374498578c44013041416c0c5b09b1eKenny Root
359a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Create a digest BIO from an X509_ALGOR structure */
360a88cfce91374498578c44013041416c0c5b09b1eKenny Root
361a88cfce91374498578c44013041416c0c5b09b1eKenny RootBIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
362a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
363a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO *mdbio = NULL;
364a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_OBJECT *digestoid;
365a88cfce91374498578c44013041416c0c5b09b1eKenny Root	const EVP_MD *digest;
366a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
367a88cfce91374498578c44013041416c0c5b09b1eKenny Root	digest = EVP_get_digestbyobj(digestoid);
368a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!digest)
369a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
370a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
371a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_R_UNKNOWN_DIGEST_ALGORIHM);
372a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
373a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
374a88cfce91374498578c44013041416c0c5b09b1eKenny Root	mdbio = BIO_new(BIO_f_md());
375a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!mdbio || !BIO_set_md(mdbio, digest))
376a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
377a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
378a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_R_MD_BIO_INIT_ERROR);
379a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
380a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
381a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return mdbio;
382a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
383a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (mdbio)
384a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO_free(mdbio);
385a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
386a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
387a88cfce91374498578c44013041416c0c5b09b1eKenny Root
388a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Locate a message digest content from a BIO chain based on SignerInfo */
389a88cfce91374498578c44013041416c0c5b09b1eKenny Root
390a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
391a88cfce91374498578c44013041416c0c5b09b1eKenny Root					X509_ALGOR *mdalg)
392a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
393a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int nid;
394a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_OBJECT *mdoid;
395a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
396a88cfce91374498578c44013041416c0c5b09b1eKenny Root	nid = OBJ_obj2nid(mdoid);
397a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* Look for digest type to match signature */
398a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (;;)
399a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
400a88cfce91374498578c44013041416c0c5b09b1eKenny Root		EVP_MD_CTX *mtmp;
401a88cfce91374498578c44013041416c0c5b09b1eKenny Root		chain = BIO_find_type(chain, BIO_TYPE_MD);
402a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (chain == NULL)
403a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
404a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,
405a88cfce91374498578c44013041416c0c5b09b1eKenny Root						CMS_R_NO_MATCHING_DIGEST);
406a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return 0;
407a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
408a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO_get_md_ctx(chain, &mtmp);
409a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (EVP_MD_CTX_type(mtmp) == nid
410a88cfce91374498578c44013041416c0c5b09b1eKenny Root		/* Workaround for broken implementations that use signature
411a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 * algorithm  OID instead of digest.
412a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 */
413a88cfce91374498578c44013041416c0c5b09b1eKenny Root			|| EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
414a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return EVP_MD_CTX_copy_ex(mctx, mtmp);
415a88cfce91374498578c44013041416c0c5b09b1eKenny Root		chain = BIO_next(chain);
416a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
417a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
418a88cfce91374498578c44013041416c0c5b09b1eKenny Root
419a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms)
420a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
421a88cfce91374498578c44013041416c0c5b09b1eKenny Root	switch (OBJ_obj2nid(cms->contentType))
422a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
423a88cfce91374498578c44013041416c0c5b09b1eKenny Root
424a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_signed:
425a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.signedData->certificates;
426a88cfce91374498578c44013041416c0c5b09b1eKenny Root
427a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_enveloped:
428a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.envelopedData->originatorInfo->certificates;
429a88cfce91374498578c44013041416c0c5b09b1eKenny Root
430a88cfce91374498578c44013041416c0c5b09b1eKenny Root		default:
431a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES,
432a88cfce91374498578c44013041416c0c5b09b1eKenny Root					CMS_R_UNSUPPORTED_CONTENT_TYPE);
433a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
434a88cfce91374498578c44013041416c0c5b09b1eKenny Root
435a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
436a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
437a88cfce91374498578c44013041416c0c5b09b1eKenny Root
438a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
439a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
440a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(CMS_CertificateChoices) **pcerts;
441a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_CertificateChoices *cch;
442a88cfce91374498578c44013041416c0c5b09b1eKenny Root	pcerts = cms_get0_certificate_choices(cms);
443a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!pcerts)
444a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
445a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!*pcerts)
446a88cfce91374498578c44013041416c0c5b09b1eKenny Root		*pcerts = sk_CMS_CertificateChoices_new_null();
447a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!*pcerts)
448a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
449a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cch = M_ASN1_new_of(CMS_CertificateChoices);
450a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cch)
451a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
452a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!sk_CMS_CertificateChoices_push(*pcerts, cch))
453a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
454a88cfce91374498578c44013041416c0c5b09b1eKenny Root		M_ASN1_free_of(cch, CMS_CertificateChoices);
455a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
456a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
457a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return cch;
458a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
459a88cfce91374498578c44013041416c0c5b09b1eKenny Root
460a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
461a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
462a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_CertificateChoices *cch;
463a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(CMS_CertificateChoices) **pcerts;
464a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i;
465a88cfce91374498578c44013041416c0c5b09b1eKenny Root	pcerts = cms_get0_certificate_choices(cms);
466a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!pcerts)
467a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
468a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
469a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
470a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cch = sk_CMS_CertificateChoices_value(*pcerts, i);
471a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (cch->type == CMS_CERTCHOICE_CERT)
472a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
473a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (!X509_cmp(cch->d.certificate, cert))
474a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
475a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMSerr(CMS_F_CMS_ADD0_CERT,
476a88cfce91374498578c44013041416c0c5b09b1eKenny Root					CMS_R_CERTIFICATE_ALREADY_PRESENT);
477a88cfce91374498578c44013041416c0c5b09b1eKenny Root				return 0;
478a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
479a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
480a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
481a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cch = CMS_add0_CertificateChoices(cms);
482a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cch)
483a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
484a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cch->type = CMS_CERTCHOICE_CERT;
485a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cch->d.certificate = cert;
486a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
487a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
488a88cfce91374498578c44013041416c0c5b09b1eKenny Root
489a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
490a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
491a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int r;
492a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = CMS_add0_cert(cms, cert);
493a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (r > 0)
494a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
495a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
496a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
497a88cfce91374498578c44013041416c0c5b09b1eKenny Root
498a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic STACK_OF(CMS_RevocationInfoChoice) **cms_get0_revocation_choices(CMS_ContentInfo *cms)
499a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
500a88cfce91374498578c44013041416c0c5b09b1eKenny Root	switch (OBJ_obj2nid(cms->contentType))
501a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
502a88cfce91374498578c44013041416c0c5b09b1eKenny Root
503a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_signed:
504a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.signedData->crls;
505a88cfce91374498578c44013041416c0c5b09b1eKenny Root
506a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case NID_pkcs7_enveloped:
507a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return &cms->d.envelopedData->originatorInfo->crls;
508a88cfce91374498578c44013041416c0c5b09b1eKenny Root
509a88cfce91374498578c44013041416c0c5b09b1eKenny Root		default:
510a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES,
511a88cfce91374498578c44013041416c0c5b09b1eKenny Root					CMS_R_UNSUPPORTED_CONTENT_TYPE);
512a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
513a88cfce91374498578c44013041416c0c5b09b1eKenny Root
514a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
515a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
516a88cfce91374498578c44013041416c0c5b09b1eKenny Root
517a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
518a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
519a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(CMS_RevocationInfoChoice) **pcrls;
520a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_RevocationInfoChoice *rch;
521a88cfce91374498578c44013041416c0c5b09b1eKenny Root	pcrls = cms_get0_revocation_choices(cms);
522a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!pcrls)
523a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
524a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!*pcrls)
525a88cfce91374498578c44013041416c0c5b09b1eKenny Root		*pcrls = sk_CMS_RevocationInfoChoice_new_null();
526a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!*pcrls)
527a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
528a88cfce91374498578c44013041416c0c5b09b1eKenny Root	rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
529a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!rch)
530a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
531a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch))
532a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
533a88cfce91374498578c44013041416c0c5b09b1eKenny Root		M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
534a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
535a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
536a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return rch;
537a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
538a88cfce91374498578c44013041416c0c5b09b1eKenny Root
539a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
540a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
541a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_RevocationInfoChoice *rch;
542a88cfce91374498578c44013041416c0c5b09b1eKenny Root	rch = CMS_add0_RevocationInfoChoice(cms);
543a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!rch)
544a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
545a88cfce91374498578c44013041416c0c5b09b1eKenny Root	rch->type = CMS_REVCHOICE_CRL;
546a88cfce91374498578c44013041416c0c5b09b1eKenny Root	rch->d.crl = crl;
547a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
548a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
549a88cfce91374498578c44013041416c0c5b09b1eKenny Root
550a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
551a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
552a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int r;
553a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = CMS_add0_crl(cms, crl);
554a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (r > 0)
555a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
556a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
557a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
558a88cfce91374498578c44013041416c0c5b09b1eKenny Root
559a88cfce91374498578c44013041416c0c5b09b1eKenny RootSTACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
560a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
561a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(X509) *certs = NULL;
562a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_CertificateChoices *cch;
563a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(CMS_CertificateChoices) **pcerts;
564a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i;
565a88cfce91374498578c44013041416c0c5b09b1eKenny Root	pcerts = cms_get0_certificate_choices(cms);
566a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!pcerts)
567a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
568a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
569a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
570a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cch = sk_CMS_CertificateChoices_value(*pcerts, i);
571a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (cch->type == 0)
572a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
573a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (!certs)
574a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
575a88cfce91374498578c44013041416c0c5b09b1eKenny Root				certs = sk_X509_new_null();
576a88cfce91374498578c44013041416c0c5b09b1eKenny Root				if (!certs)
577a88cfce91374498578c44013041416c0c5b09b1eKenny Root					return NULL;
578a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
579a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (!sk_X509_push(certs, cch->d.certificate))
580a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
581a88cfce91374498578c44013041416c0c5b09b1eKenny Root				sk_X509_pop_free(certs, X509_free);
582a88cfce91374498578c44013041416c0c5b09b1eKenny Root				return NULL;
583a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
584a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CRYPTO_add(&cch->d.certificate->references,
585a88cfce91374498578c44013041416c0c5b09b1eKenny Root						1, CRYPTO_LOCK_X509);
586a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
587a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
588a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return certs;
589a88cfce91374498578c44013041416c0c5b09b1eKenny Root
590a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
591a88cfce91374498578c44013041416c0c5b09b1eKenny Root
592a88cfce91374498578c44013041416c0c5b09b1eKenny RootSTACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
593a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
594a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(X509_CRL) *crls = NULL;
595a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(CMS_RevocationInfoChoice) **pcrls;
596a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_RevocationInfoChoice *rch;
597a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i;
598a88cfce91374498578c44013041416c0c5b09b1eKenny Root	pcrls = cms_get0_revocation_choices(cms);
599a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!pcrls)
600a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
601a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++)
602a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
603a88cfce91374498578c44013041416c0c5b09b1eKenny Root		rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
604a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (rch->type == 0)
605a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
606a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (!crls)
607a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
608a88cfce91374498578c44013041416c0c5b09b1eKenny Root				crls = sk_X509_CRL_new_null();
609a88cfce91374498578c44013041416c0c5b09b1eKenny Root				if (!crls)
610a88cfce91374498578c44013041416c0c5b09b1eKenny Root					return NULL;
611a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
612a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (!sk_X509_CRL_push(crls, rch->d.crl))
613a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
614a88cfce91374498578c44013041416c0c5b09b1eKenny Root				sk_X509_CRL_pop_free(crls, X509_CRL_free);
615a88cfce91374498578c44013041416c0c5b09b1eKenny Root				return NULL;
616a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
617a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CRYPTO_add(&rch->d.crl->references,
618a88cfce91374498578c44013041416c0c5b09b1eKenny Root						1, CRYPTO_LOCK_X509_CRL);
619a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
620a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
621a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return crls;
622a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
623