1a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* crypto/cms/cms_sd.c */
2a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3a88cfce91374498578c44013041416c0c5b09b1eKenny Root * project.
4a88cfce91374498578c44013041416c0c5b09b1eKenny Root */
5a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* ====================================================================
6a88cfce91374498578c44013041416c0c5b09b1eKenny Root * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
7a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
8a88cfce91374498578c44013041416c0c5b09b1eKenny Root * Redistribution and use in source and binary forms, with or without
9a88cfce91374498578c44013041416c0c5b09b1eKenny Root * modification, are permitted provided that the following conditions
10a88cfce91374498578c44013041416c0c5b09b1eKenny Root * are met:
11a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
12a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 1. Redistributions of source code must retain the above copyright
13a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    notice, this list of conditions and the following disclaimer.
14a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
15a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 2. Redistributions in binary form must reproduce the above copyright
16a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    notice, this list of conditions and the following disclaimer in
17a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    the documentation and/or other materials provided with the
18a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    distribution.
19a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
20a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 3. All advertising materials mentioning features or use of this
21a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    software must display the following acknowledgment:
22a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    "This product includes software developed by the OpenSSL Project
23a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
25a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    endorse or promote products derived from this software without
27a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    prior written permission. For written permission, please contact
28a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    licensing@OpenSSL.org.
29a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
30a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 5. Products derived from this software may not be called "OpenSSL"
31a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    nor may "OpenSSL" appear in their names without prior written
32a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    permission of the OpenSSL Project.
33a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
34a88cfce91374498578c44013041416c0c5b09b1eKenny Root * 6. Redistributions of any form whatsoever must retain the following
35a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    acknowledgment:
36a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    "This product includes software developed by the OpenSSL Project
37a88cfce91374498578c44013041416c0c5b09b1eKenny Root *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38a88cfce91374498578c44013041416c0c5b09b1eKenny Root *
39a88cfce91374498578c44013041416c0c5b09b1eKenny Root * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40a88cfce91374498578c44013041416c0c5b09b1eKenny Root * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41a88cfce91374498578c44013041416c0c5b09b1eKenny Root * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42a88cfce91374498578c44013041416c0c5b09b1eKenny Root * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43a88cfce91374498578c44013041416c0c5b09b1eKenny Root * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44a88cfce91374498578c44013041416c0c5b09b1eKenny Root * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45a88cfce91374498578c44013041416c0c5b09b1eKenny Root * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46a88cfce91374498578c44013041416c0c5b09b1eKenny Root * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47a88cfce91374498578c44013041416c0c5b09b1eKenny Root * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48a88cfce91374498578c44013041416c0c5b09b1eKenny Root * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49a88cfce91374498578c44013041416c0c5b09b1eKenny Root * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50a88cfce91374498578c44013041416c0c5b09b1eKenny Root * OF THE POSSIBILITY OF SUCH DAMAGE.
51a88cfce91374498578c44013041416c0c5b09b1eKenny Root * ====================================================================
52a88cfce91374498578c44013041416c0c5b09b1eKenny Root */
53a88cfce91374498578c44013041416c0c5b09b1eKenny Root
54a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include "cryptlib.h"
55a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/asn1t.h>
56a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/pem.h>
57a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/x509v3.h>
58a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/err.h>
59a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include <openssl/cms.h>
60a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include "cms_lcl.h"
61a88cfce91374498578c44013041416c0c5b09b1eKenny Root#include "asn1_locl.h"
62a88cfce91374498578c44013041416c0c5b09b1eKenny Root
63a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* CMS SignedData Utilities */
64a88cfce91374498578c44013041416c0c5b09b1eKenny Root
65a88cfce91374498578c44013041416c0c5b09b1eKenny RootDECLARE_ASN1_ITEM(CMS_SignedData)
66a88cfce91374498578c44013041416c0c5b09b1eKenny Root
67a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
68a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
69a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed)
70a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
71a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
72a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
73a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
74a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return cms->d.signedData;
75a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
76a88cfce91374498578c44013041416c0c5b09b1eKenny Root
77a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
78a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
79a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (cms->d.other == NULL)
80a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
81a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
82a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!cms->d.signedData)
83a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
84a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);
85a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return NULL;
86a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
87a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms->d.signedData->version = 1;
88a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms->d.signedData->encapContentInfo->eContentType =
89a88cfce91374498578c44013041416c0c5b09b1eKenny Root						OBJ_nid2obj(NID_pkcs7_data);
90a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms->d.signedData->encapContentInfo->partial = 1;
91a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ASN1_OBJECT_free(cms->contentType);
92a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
93a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return cms->d.signedData;
94a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
95a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return cms_get0_signed(cms);
96a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
97a88cfce91374498578c44013041416c0c5b09b1eKenny Root
98a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Just initialize SignedData e.g. for certs only structure */
99a88cfce91374498578c44013041416c0c5b09b1eKenny Root
100a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_SignedData_init(CMS_ContentInfo *cms)
101a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
102a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (cms_signed_data_init(cms))
103a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 1;
104a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
105a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
106a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
107a88cfce91374498578c44013041416c0c5b09b1eKenny Root
108a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Check structures and fixup version numbers (if necessary) */
109a88cfce91374498578c44013041416c0c5b09b1eKenny Root
110a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic void cms_sd_set_version(CMS_SignedData *sd)
111a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
112a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i;
113a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_CertificateChoices *cch;
114a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_RevocationInfoChoice *rch;
115a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_SignerInfo *si;
116a88cfce91374498578c44013041416c0c5b09b1eKenny Root
117a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++)
118a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
119a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
120a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (cch->type == CMS_CERTCHOICE_OTHER)
121a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
122a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (sd->version < 5)
123a88cfce91374498578c44013041416c0c5b09b1eKenny Root				sd->version = 5;
124a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
125a88cfce91374498578c44013041416c0c5b09b1eKenny Root		else if (cch->type == CMS_CERTCHOICE_V2ACERT)
126a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
127a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (sd->version < 4)
128a88cfce91374498578c44013041416c0c5b09b1eKenny Root				sd->version = 4;
129a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
130a88cfce91374498578c44013041416c0c5b09b1eKenny Root		else if (cch->type == CMS_CERTCHOICE_V1ACERT)
131a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
132a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (sd->version < 3)
133a88cfce91374498578c44013041416c0c5b09b1eKenny Root				sd->version = 3;
134a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
135a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
136a88cfce91374498578c44013041416c0c5b09b1eKenny Root
137a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++)
138a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
139a88cfce91374498578c44013041416c0c5b09b1eKenny Root		rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
140a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (rch->type == CMS_REVCHOICE_OTHER)
141a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
142a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (sd->version < 5)
143a88cfce91374498578c44013041416c0c5b09b1eKenny Root				sd->version = 5;
144a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
145a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
146a88cfce91374498578c44013041416c0c5b09b1eKenny Root
147a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
148a88cfce91374498578c44013041416c0c5b09b1eKenny Root			&& (sd->version < 3))
149a88cfce91374498578c44013041416c0c5b09b1eKenny Root		sd->version = 3;
150a88cfce91374498578c44013041416c0c5b09b1eKenny Root
151a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++)
152a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
153a88cfce91374498578c44013041416c0c5b09b1eKenny Root		si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
154a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
155a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
156a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (si->version < 3)
157a88cfce91374498578c44013041416c0c5b09b1eKenny Root				si->version = 3;
158a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (sd->version < 3)
159a88cfce91374498578c44013041416c0c5b09b1eKenny Root				sd->version = 3;
160a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
16177c6be7176c48d2ce4d5979a84876d34204eedafKenny Root		else if (si->version < 1)
16277c6be7176c48d2ce4d5979a84876d34204eedafKenny Root			si->version = 1;
163a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
164a88cfce91374498578c44013041416c0c5b09b1eKenny Root
165a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (sd->version < 1)
166a88cfce91374498578c44013041416c0c5b09b1eKenny Root		sd->version = 1;
167a88cfce91374498578c44013041416c0c5b09b1eKenny Root
168a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
169a88cfce91374498578c44013041416c0c5b09b1eKenny Root
170a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Copy an existing messageDigest value */
171a88cfce91374498578c44013041416c0c5b09b1eKenny Root
172a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
173a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
174a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(CMS_SignerInfo) *sinfos;
175a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_SignerInfo *sitmp;
176a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i;
177a88cfce91374498578c44013041416c0c5b09b1eKenny Root	sinfos = CMS_get0_SignerInfos(cms);
178a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
179a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
180a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ASN1_OCTET_STRING *messageDigest;
181a88cfce91374498578c44013041416c0c5b09b1eKenny Root		sitmp = sk_CMS_SignerInfo_value(sinfos, i);
182a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (sitmp == si)
183a88cfce91374498578c44013041416c0c5b09b1eKenny Root			continue;
184a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (CMS_signed_get_attr_count(sitmp) < 0)
185a88cfce91374498578c44013041416c0c5b09b1eKenny Root			continue;
186a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (OBJ_cmp(si->digestAlgorithm->algorithm,
187a88cfce91374498578c44013041416c0c5b09b1eKenny Root				sitmp->digestAlgorithm->algorithm))
188a88cfce91374498578c44013041416c0c5b09b1eKenny Root			continue;
189a88cfce91374498578c44013041416c0c5b09b1eKenny Root		messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
190a88cfce91374498578c44013041416c0c5b09b1eKenny Root					OBJ_nid2obj(NID_pkcs9_messageDigest),
191a88cfce91374498578c44013041416c0c5b09b1eKenny Root					-3, V_ASN1_OCTET_STRING);
192a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!messageDigest)
193a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
194a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
195a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
196a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return 0;
197a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
198a88cfce91374498578c44013041416c0c5b09b1eKenny Root
199a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
200a88cfce91374498578c44013041416c0c5b09b1eKenny Root						V_ASN1_OCTET_STRING,
201a88cfce91374498578c44013041416c0c5b09b1eKenny Root						messageDigest, -1))
202a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return 1;
203a88cfce91374498578c44013041416c0c5b09b1eKenny Root		else
204a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return 0;
205a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
206a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
207a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
208a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
209a88cfce91374498578c44013041416c0c5b09b1eKenny Root
210a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
211a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
212a88cfce91374498578c44013041416c0c5b09b1eKenny Root	switch(type)
213a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
214a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case CMS_SIGNERINFO_ISSUER_SERIAL:
215a88cfce91374498578c44013041416c0c5b09b1eKenny Root		sid->d.issuerAndSerialNumber =
216a88cfce91374498578c44013041416c0c5b09b1eKenny Root			M_ASN1_new_of(CMS_IssuerAndSerialNumber);
217a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!sid->d.issuerAndSerialNumber)
218a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto merr;
219a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer,
220a88cfce91374498578c44013041416c0c5b09b1eKenny Root					X509_get_issuer_name(cert)))
221a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto merr;
222a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!ASN1_STRING_copy(
223a88cfce91374498578c44013041416c0c5b09b1eKenny Root			sid->d.issuerAndSerialNumber->serialNumber,
224a88cfce91374498578c44013041416c0c5b09b1eKenny Root				X509_get_serialNumber(cert)))
225a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto merr;
226a88cfce91374498578c44013041416c0c5b09b1eKenny Root		break;
227a88cfce91374498578c44013041416c0c5b09b1eKenny Root
228a88cfce91374498578c44013041416c0c5b09b1eKenny Root		case CMS_SIGNERINFO_KEYIDENTIFIER:
229a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!cert->skid)
230a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
231a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER,
232a88cfce91374498578c44013041416c0c5b09b1eKenny Root					CMS_R_CERTIFICATE_HAS_NO_KEYID);
233a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return 0;
234a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
235a88cfce91374498578c44013041416c0c5b09b1eKenny Root		sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid);
236a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!sid->d.subjectKeyIdentifier)
237a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto merr;
238a88cfce91374498578c44013041416c0c5b09b1eKenny Root		break;
239a88cfce91374498578c44013041416c0c5b09b1eKenny Root
240a88cfce91374498578c44013041416c0c5b09b1eKenny Root		default:
241a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);
242a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
243a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
244a88cfce91374498578c44013041416c0c5b09b1eKenny Root
245a88cfce91374498578c44013041416c0c5b09b1eKenny Root	sid->type = type;
246a88cfce91374498578c44013041416c0c5b09b1eKenny Root
247a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
248a88cfce91374498578c44013041416c0c5b09b1eKenny Root
249a88cfce91374498578c44013041416c0c5b09b1eKenny Root	merr:
250a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE);
251a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 0;
252a88cfce91374498578c44013041416c0c5b09b1eKenny Root
253a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
254a88cfce91374498578c44013041416c0c5b09b1eKenny Root
255a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
256a88cfce91374498578c44013041416c0c5b09b1eKenny Root					ASN1_OCTET_STRING **keyid,
257a88cfce91374498578c44013041416c0c5b09b1eKenny Root					X509_NAME **issuer, ASN1_INTEGER **sno)
258a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
259a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
260a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
261a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (issuer)
262a88cfce91374498578c44013041416c0c5b09b1eKenny Root			*issuer = sid->d.issuerAndSerialNumber->issuer;
263a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (sno)
264a88cfce91374498578c44013041416c0c5b09b1eKenny Root			*sno = sid->d.issuerAndSerialNumber->serialNumber;
265a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
266a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
267a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
268a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (keyid)
269a88cfce91374498578c44013041416c0c5b09b1eKenny Root			*keyid = sid->d.subjectKeyIdentifier;
270a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
271a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
272a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
273a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
274a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
275a88cfce91374498578c44013041416c0c5b09b1eKenny Root
276a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
277a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
278a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int ret;
279a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
280a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
281a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer,
282a88cfce91374498578c44013041416c0c5b09b1eKenny Root					X509_get_issuer_name(cert));
283a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (ret)
284a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return ret;
285a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber,
286a88cfce91374498578c44013041416c0c5b09b1eKenny Root					X509_get_serialNumber(cert));
287a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
288a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
289a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
290a88cfce91374498578c44013041416c0c5b09b1eKenny Root		X509_check_purpose(cert, -1, -1);
291a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!cert->skid)
292a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return -1;
293a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier,
294a88cfce91374498578c44013041416c0c5b09b1eKenny Root							cert->skid);
295a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
296a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
297a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return -1;
298a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
299a88cfce91374498578c44013041416c0c5b09b1eKenny Root
300a88cfce91374498578c44013041416c0c5b09b1eKenny RootCMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
301a88cfce91374498578c44013041416c0c5b09b1eKenny Root			X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
302a88cfce91374498578c44013041416c0c5b09b1eKenny Root			unsigned int flags)
303a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
304a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_SignedData *sd;
305a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_SignerInfo *si = NULL;
306a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509_ALGOR *alg;
307a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i, type;
308a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if(!X509_check_private_key(signer, pk))
309a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
310a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_ADD1_SIGNER,
311a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
312a88cfce91374498578c44013041416c0c5b09b1eKenny Root                return NULL;
313a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
314a88cfce91374498578c44013041416c0c5b09b1eKenny Root	sd = cms_signed_data_init(cms);
315a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!sd)
316a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
317a88cfce91374498578c44013041416c0c5b09b1eKenny Root	si = M_ASN1_new_of(CMS_SignerInfo);
318a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!si)
319a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto merr;
320a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509_check_purpose(signer, -1, -1);
321a88cfce91374498578c44013041416c0c5b09b1eKenny Root
322a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
323a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
324a88cfce91374498578c44013041416c0c5b09b1eKenny Root
325a88cfce91374498578c44013041416c0c5b09b1eKenny Root	si->pkey = pk;
326a88cfce91374498578c44013041416c0c5b09b1eKenny Root	si->signer = signer;
327a88cfce91374498578c44013041416c0c5b09b1eKenny Root
328a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (flags & CMS_USE_KEYID)
329a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
330a88cfce91374498578c44013041416c0c5b09b1eKenny Root		si->version = 3;
331a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (sd->version < 3)
332a88cfce91374498578c44013041416c0c5b09b1eKenny Root			sd->version = 3;
333a88cfce91374498578c44013041416c0c5b09b1eKenny Root		type = CMS_SIGNERINFO_KEYIDENTIFIER;
334a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
335a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
336a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
337a88cfce91374498578c44013041416c0c5b09b1eKenny Root		type = CMS_SIGNERINFO_ISSUER_SERIAL;
338a88cfce91374498578c44013041416c0c5b09b1eKenny Root		si->version = 1;
339a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
340a88cfce91374498578c44013041416c0c5b09b1eKenny Root
341a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cms_set1_SignerIdentifier(si->sid, signer, type))
342a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
343a88cfce91374498578c44013041416c0c5b09b1eKenny Root
344a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (md == NULL)
345a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
346a88cfce91374498578c44013041416c0c5b09b1eKenny Root		int def_nid;
347a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
348a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
349a88cfce91374498578c44013041416c0c5b09b1eKenny Root		md = EVP_get_digestbynid(def_nid);
350a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (md == NULL)
351a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
352a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST);
353a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
354a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
355a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
356a88cfce91374498578c44013041416c0c5b09b1eKenny Root
357a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!md)
358a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
359a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
360a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
361a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
362a88cfce91374498578c44013041416c0c5b09b1eKenny Root
363a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cms_DigestAlgorithm_set(si->digestAlgorithm, md);
364a88cfce91374498578c44013041416c0c5b09b1eKenny Root
365a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* See if digest is present in digestAlgorithms */
366a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
367a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
368a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ASN1_OBJECT *aoid;
369a88cfce91374498578c44013041416c0c5b09b1eKenny Root		alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
370a88cfce91374498578c44013041416c0c5b09b1eKenny Root		X509_ALGOR_get0(&aoid, NULL, NULL, alg);
371a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
372a88cfce91374498578c44013041416c0c5b09b1eKenny Root			break;
373a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
374a88cfce91374498578c44013041416c0c5b09b1eKenny Root
375a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (i == sk_X509_ALGOR_num(sd->digestAlgorithms))
376a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
377a88cfce91374498578c44013041416c0c5b09b1eKenny Root		alg = X509_ALGOR_new();
378a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!alg)
379a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto merr;
380a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms_DigestAlgorithm_set(alg, md);
381a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg))
382a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
383a88cfce91374498578c44013041416c0c5b09b1eKenny Root			X509_ALGOR_free(alg);
384a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto merr;
385a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
386a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
387a88cfce91374498578c44013041416c0c5b09b1eKenny Root
388a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (pk->ameth && pk->ameth->pkey_ctrl)
389a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
390a88cfce91374498578c44013041416c0c5b09b1eKenny Root		i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN,
391a88cfce91374498578c44013041416c0c5b09b1eKenny Root						0, si);
392a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (i == -2)
393a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
394a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_ADD1_SIGNER,
395a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
396a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
397a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
398a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (i <= 0)
399a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
400a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE);
401a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
402a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
403a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
404a88cfce91374498578c44013041416c0c5b09b1eKenny Root
405a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!(flags & CMS_NOATTR))
406a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
407a88cfce91374498578c44013041416c0c5b09b1eKenny Root		/* Initialialize signed attributes strutucture so other
408a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 * attributes such as signing time etc are added later
409a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 * even if we add none here.
410a88cfce91374498578c44013041416c0c5b09b1eKenny Root		 */
411a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!si->signedAttrs)
412a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
413a88cfce91374498578c44013041416c0c5b09b1eKenny Root			si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
414a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (!si->signedAttrs)
415a88cfce91374498578c44013041416c0c5b09b1eKenny Root				goto merr;
416a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
417a88cfce91374498578c44013041416c0c5b09b1eKenny Root
418a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!(flags & CMS_NOSMIMECAP))
419a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
420a88cfce91374498578c44013041416c0c5b09b1eKenny Root			STACK_OF(X509_ALGOR) *smcap = NULL;
421a88cfce91374498578c44013041416c0c5b09b1eKenny Root			i = CMS_add_standard_smimecap(&smcap);
422a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (i)
423a88cfce91374498578c44013041416c0c5b09b1eKenny Root				i = CMS_add_smimecap(si, smcap);
424a88cfce91374498578c44013041416c0c5b09b1eKenny Root			sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
425a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (!i)
426a88cfce91374498578c44013041416c0c5b09b1eKenny Root				goto merr;
427a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
428a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (flags & CMS_REUSE_DIGEST)
429a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
430a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (!cms_copy_messageDigest(cms, si))
431a88cfce91374498578c44013041416c0c5b09b1eKenny Root				goto err;
432a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (!(flags & CMS_PARTIAL) &&
433a88cfce91374498578c44013041416c0c5b09b1eKenny Root					!CMS_SignerInfo_sign(si))
434a88cfce91374498578c44013041416c0c5b09b1eKenny Root				goto err;
435a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
436a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
437a88cfce91374498578c44013041416c0c5b09b1eKenny Root
438a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!(flags & CMS_NOCERTS))
439a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
440a88cfce91374498578c44013041416c0c5b09b1eKenny Root		/* NB ignore -1 return for duplicate cert */
441a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!CMS_add1_cert(cms, signer))
442a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto merr;
443a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
444a88cfce91374498578c44013041416c0c5b09b1eKenny Root
445a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!sd->signerInfos)
446a88cfce91374498578c44013041416c0c5b09b1eKenny Root		sd->signerInfos = sk_CMS_SignerInfo_new_null();
447a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!sd->signerInfos ||
448a88cfce91374498578c44013041416c0c5b09b1eKenny Root		!sk_CMS_SignerInfo_push(sd->signerInfos, si))
449a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto merr;
450a88cfce91374498578c44013041416c0c5b09b1eKenny Root
451a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return si;
452a88cfce91374498578c44013041416c0c5b09b1eKenny Root
453a88cfce91374498578c44013041416c0c5b09b1eKenny Root	merr:
454a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
455a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
456a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (si)
457a88cfce91374498578c44013041416c0c5b09b1eKenny Root		M_ASN1_free_of(si, CMS_SignerInfo);
458a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
459a88cfce91374498578c44013041416c0c5b09b1eKenny Root
460a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
461a88cfce91374498578c44013041416c0c5b09b1eKenny Root
462a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
463a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
464a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_TIME *tt;
465a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int r = 0;
466a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (t)
467a88cfce91374498578c44013041416c0c5b09b1eKenny Root		tt = t;
468a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
469a88cfce91374498578c44013041416c0c5b09b1eKenny Root		tt = X509_gmtime_adj(NULL, 0);
470a88cfce91374498578c44013041416c0c5b09b1eKenny Root
471a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!tt)
472a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto merr;
473a88cfce91374498578c44013041416c0c5b09b1eKenny Root
474a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
475a88cfce91374498578c44013041416c0c5b09b1eKenny Root						tt->type, tt, -1) <= 0)
476a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto merr;
477a88cfce91374498578c44013041416c0c5b09b1eKenny Root
478a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = 1;
479a88cfce91374498578c44013041416c0c5b09b1eKenny Root
480a88cfce91374498578c44013041416c0c5b09b1eKenny Root	merr:
481a88cfce91374498578c44013041416c0c5b09b1eKenny Root
482a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!t)
483a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ASN1_TIME_free(tt);
484a88cfce91374498578c44013041416c0c5b09b1eKenny Root
485a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!r)
486a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);
487a88cfce91374498578c44013041416c0c5b09b1eKenny Root
488a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
489a88cfce91374498578c44013041416c0c5b09b1eKenny Root
490a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
491a88cfce91374498578c44013041416c0c5b09b1eKenny Root
492a88cfce91374498578c44013041416c0c5b09b1eKenny RootSTACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
493a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
494a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_SignedData *sd;
495a88cfce91374498578c44013041416c0c5b09b1eKenny Root	sd = cms_get0_signed(cms);
496a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!sd)
497a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
498a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return sd->signerInfos;
499a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
500a88cfce91374498578c44013041416c0c5b09b1eKenny Root
501a88cfce91374498578c44013041416c0c5b09b1eKenny RootSTACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
502a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
503a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(X509) *signers = NULL;
504a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(CMS_SignerInfo) *sinfos;
505a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_SignerInfo *si;
506a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i;
507a88cfce91374498578c44013041416c0c5b09b1eKenny Root	sinfos = CMS_get0_SignerInfos(cms);
508a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
509a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
510a88cfce91374498578c44013041416c0c5b09b1eKenny Root		si = sk_CMS_SignerInfo_value(sinfos, i);
511a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (si->signer)
512a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
513a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (!signers)
514a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
515a88cfce91374498578c44013041416c0c5b09b1eKenny Root				signers = sk_X509_new_null();
516a88cfce91374498578c44013041416c0c5b09b1eKenny Root				if (!signers)
517a88cfce91374498578c44013041416c0c5b09b1eKenny Root					return NULL;
518a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
519a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (!sk_X509_push(signers, si->signer))
520a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
521a88cfce91374498578c44013041416c0c5b09b1eKenny Root				sk_X509_free(signers);
522a88cfce91374498578c44013041416c0c5b09b1eKenny Root				return NULL;
523a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
524a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
525a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
526a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return signers;
527a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
528a88cfce91374498578c44013041416c0c5b09b1eKenny Root
529a88cfce91374498578c44013041416c0c5b09b1eKenny Rootvoid CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
530a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
531a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (signer)
532a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
533a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
534a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (si->pkey)
535a88cfce91374498578c44013041416c0c5b09b1eKenny Root			EVP_PKEY_free(si->pkey);
536a88cfce91374498578c44013041416c0c5b09b1eKenny Root		si->pkey = X509_get_pubkey(signer);
537a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
538a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (si->signer)
539a88cfce91374498578c44013041416c0c5b09b1eKenny Root		X509_free(si->signer);
540a88cfce91374498578c44013041416c0c5b09b1eKenny Root	si->signer = signer;
541a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
542a88cfce91374498578c44013041416c0c5b09b1eKenny Root
543a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
544a88cfce91374498578c44013041416c0c5b09b1eKenny Root					ASN1_OCTET_STRING **keyid,
545a88cfce91374498578c44013041416c0c5b09b1eKenny Root					X509_NAME **issuer, ASN1_INTEGER **sno)
546a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
547a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
548a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
549a88cfce91374498578c44013041416c0c5b09b1eKenny Root
550a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
551a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
552a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return cms_SignerIdentifier_cert_cmp(si->sid, cert);
553a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
554a88cfce91374498578c44013041416c0c5b09b1eKenny Root
555a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
556a88cfce91374498578c44013041416c0c5b09b1eKenny Root				unsigned int flags)
557a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
558a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_SignedData *sd;
559a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_SignerInfo *si;
560a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_CertificateChoices *cch;
561a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(CMS_CertificateChoices) *certs;
562a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509 *x;
563a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i, j;
564a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int ret = 0;
565a88cfce91374498578c44013041416c0c5b09b1eKenny Root	sd = cms_get0_signed(cms);
566a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!sd)
567a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return -1;
568a88cfce91374498578c44013041416c0c5b09b1eKenny Root	certs = sd->certificates;
569a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++)
570a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
571a88cfce91374498578c44013041416c0c5b09b1eKenny Root		si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
572a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (si->signer)
573a88cfce91374498578c44013041416c0c5b09b1eKenny Root			continue;
574a88cfce91374498578c44013041416c0c5b09b1eKenny Root
575a88cfce91374498578c44013041416c0c5b09b1eKenny Root		for (j = 0; j < sk_X509_num(scerts); j++)
576a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
577a88cfce91374498578c44013041416c0c5b09b1eKenny Root			x = sk_X509_value(scerts, j);
578a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (CMS_SignerInfo_cert_cmp(si, x) == 0)
579a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
580a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_SignerInfo_set1_signer_cert(si, x);
581a88cfce91374498578c44013041416c0c5b09b1eKenny Root				ret++;
582a88cfce91374498578c44013041416c0c5b09b1eKenny Root				break;
583a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
584a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
585a88cfce91374498578c44013041416c0c5b09b1eKenny Root
586a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (si->signer || (flags & CMS_NOINTERN))
587a88cfce91374498578c44013041416c0c5b09b1eKenny Root			continue;
588a88cfce91374498578c44013041416c0c5b09b1eKenny Root
589a88cfce91374498578c44013041416c0c5b09b1eKenny Root		for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++)
590a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
591a88cfce91374498578c44013041416c0c5b09b1eKenny Root			cch = sk_CMS_CertificateChoices_value(certs, j);
592a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (cch->type != 0)
593a88cfce91374498578c44013041416c0c5b09b1eKenny Root				continue;
594a88cfce91374498578c44013041416c0c5b09b1eKenny Root			x = cch->d.certificate;
595a88cfce91374498578c44013041416c0c5b09b1eKenny Root			if (CMS_SignerInfo_cert_cmp(si, x) == 0)
596a88cfce91374498578c44013041416c0c5b09b1eKenny Root				{
597a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_SignerInfo_set1_signer_cert(si, x);
598a88cfce91374498578c44013041416c0c5b09b1eKenny Root				ret++;
599a88cfce91374498578c44013041416c0c5b09b1eKenny Root				break;
600a88cfce91374498578c44013041416c0c5b09b1eKenny Root				}
601a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
602a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
603a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return ret;
604a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
605a88cfce91374498578c44013041416c0c5b09b1eKenny Root
606a88cfce91374498578c44013041416c0c5b09b1eKenny Rootvoid CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
607a88cfce91374498578c44013041416c0c5b09b1eKenny Root					X509_ALGOR **pdig, X509_ALGOR **psig)
608a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
609a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (pk)
610a88cfce91374498578c44013041416c0c5b09b1eKenny Root		*pk = si->pkey;
611a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (signer)
612a88cfce91374498578c44013041416c0c5b09b1eKenny Root		*signer = si->signer;
613a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (pdig)
614a88cfce91374498578c44013041416c0c5b09b1eKenny Root		*pdig = si->digestAlgorithm;
615a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (psig)
616a88cfce91374498578c44013041416c0c5b09b1eKenny Root		*psig = si->signatureAlgorithm;
617a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
618a88cfce91374498578c44013041416c0c5b09b1eKenny Root
619a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
620a88cfce91374498578c44013041416c0c5b09b1eKenny Root					CMS_SignerInfo *si, BIO *chain)
621a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
622a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_MD_CTX mctx;
623a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int r = 0;
624a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_MD_CTX_init(&mctx);
625a88cfce91374498578c44013041416c0c5b09b1eKenny Root
626a88cfce91374498578c44013041416c0c5b09b1eKenny Root
627a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!si->pkey)
628a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
629a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
630a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
631a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
632a88cfce91374498578c44013041416c0c5b09b1eKenny Root
633a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
634a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
635a88cfce91374498578c44013041416c0c5b09b1eKenny Root
636a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* If any signed attributes calculate and add messageDigest attribute */
637a88cfce91374498578c44013041416c0c5b09b1eKenny Root
638a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (CMS_signed_get_attr_count(si) >= 0)
639a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
640a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ASN1_OBJECT *ctype =
641a88cfce91374498578c44013041416c0c5b09b1eKenny Root			cms->d.signedData->encapContentInfo->eContentType;
642a88cfce91374498578c44013041416c0c5b09b1eKenny Root		unsigned char md[EVP_MAX_MD_SIZE];
643a88cfce91374498578c44013041416c0c5b09b1eKenny Root		unsigned int mdlen;
644a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!EVP_DigestFinal_ex(&mctx, md, &mdlen))
645a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
646a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
647a88cfce91374498578c44013041416c0c5b09b1eKenny Root						V_ASN1_OCTET_STRING,
648a88cfce91374498578c44013041416c0c5b09b1eKenny Root						md, mdlen))
649a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
650a88cfce91374498578c44013041416c0c5b09b1eKenny Root		/* Copy content type across */
651a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
652a88cfce91374498578c44013041416c0c5b09b1eKenny Root					V_ASN1_OBJECT, ctype, -1) <= 0)
653a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
654a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!CMS_SignerInfo_sign(si))
655a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
656a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
657a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
658a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
659a88cfce91374498578c44013041416c0c5b09b1eKenny Root		unsigned char *sig;
660a88cfce91374498578c44013041416c0c5b09b1eKenny Root		unsigned int siglen;
661a88cfce91374498578c44013041416c0c5b09b1eKenny Root		sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
662a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!sig)
663a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
664a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
665a88cfce91374498578c44013041416c0c5b09b1eKenny Root					ERR_R_MALLOC_FAILURE);
666a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
667a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
668a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey))
669a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
670a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
671a88cfce91374498578c44013041416c0c5b09b1eKenny Root					CMS_R_SIGNFINAL_ERROR);
672a88cfce91374498578c44013041416c0c5b09b1eKenny Root			OPENSSL_free(sig);
673a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
674a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
675a88cfce91374498578c44013041416c0c5b09b1eKenny Root		ASN1_STRING_set0(si->signature, sig, siglen);
676a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
677a88cfce91374498578c44013041416c0c5b09b1eKenny Root
678a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = 1;
679a88cfce91374498578c44013041416c0c5b09b1eKenny Root
680a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
681a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_MD_CTX_cleanup(&mctx);
682a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
683a88cfce91374498578c44013041416c0c5b09b1eKenny Root
684a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
685a88cfce91374498578c44013041416c0c5b09b1eKenny Root
686a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
687a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
688a88cfce91374498578c44013041416c0c5b09b1eKenny Root	STACK_OF(CMS_SignerInfo) *sinfos;
689a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_SignerInfo *si;
690a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i;
691a88cfce91374498578c44013041416c0c5b09b1eKenny Root	sinfos = CMS_get0_SignerInfos(cms);
692a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
693a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
694a88cfce91374498578c44013041416c0c5b09b1eKenny Root		si = sk_CMS_SignerInfo_value(sinfos, i);
695a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!cms_SignerInfo_content_sign(cms, si, chain))
696a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return 0;
697a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
698a88cfce91374498578c44013041416c0c5b09b1eKenny Root	cms->d.signedData->encapContentInfo->partial = 0;
699a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
700a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
701a88cfce91374498578c44013041416c0c5b09b1eKenny Root
702a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_SignerInfo_sign(CMS_SignerInfo *si)
703a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
704a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_MD_CTX mctx;
705a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_PKEY_CTX *pctx;
706a88cfce91374498578c44013041416c0c5b09b1eKenny Root	unsigned char *abuf = NULL;
707a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int alen;
708a88cfce91374498578c44013041416c0c5b09b1eKenny Root	size_t siglen;
709a88cfce91374498578c44013041416c0c5b09b1eKenny Root	const EVP_MD *md = NULL;
710a88cfce91374498578c44013041416c0c5b09b1eKenny Root
711a88cfce91374498578c44013041416c0c5b09b1eKenny Root	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
712a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (md == NULL)
713a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
714a88cfce91374498578c44013041416c0c5b09b1eKenny Root
715a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_MD_CTX_init(&mctx);
716a88cfce91374498578c44013041416c0c5b09b1eKenny Root
717a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0)
718a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
719a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!cms_add1_signingTime(si, NULL))
720a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
721a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
722a88cfce91374498578c44013041416c0c5b09b1eKenny Root
723a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
724a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
725a88cfce91374498578c44013041416c0c5b09b1eKenny Root
726a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
727a88cfce91374498578c44013041416c0c5b09b1eKenny Root				EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0)
728a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
729a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
730a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
731a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
732a88cfce91374498578c44013041416c0c5b09b1eKenny Root
733a88cfce91374498578c44013041416c0c5b09b1eKenny Root	alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
734a88cfce91374498578c44013041416c0c5b09b1eKenny Root				ASN1_ITEM_rptr(CMS_Attributes_Sign));
735a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if(!abuf)
736a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
737a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
738a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
739a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
740a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
741a88cfce91374498578c44013041416c0c5b09b1eKenny Root	OPENSSL_free(abuf);
742a88cfce91374498578c44013041416c0c5b09b1eKenny Root	abuf = OPENSSL_malloc(siglen);
743a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if(!abuf)
744a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
745a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
746a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
747a88cfce91374498578c44013041416c0c5b09b1eKenny Root
748a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
749a88cfce91374498578c44013041416c0c5b09b1eKenny Root				EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0)
750a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
751a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
752a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
753a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
754a88cfce91374498578c44013041416c0c5b09b1eKenny Root
755a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_MD_CTX_cleanup(&mctx);
756a88cfce91374498578c44013041416c0c5b09b1eKenny Root
757a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_STRING_set0(si->signature, abuf, siglen);
758a88cfce91374498578c44013041416c0c5b09b1eKenny Root
759a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
760a88cfce91374498578c44013041416c0c5b09b1eKenny Root
761a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
762a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (abuf)
763a88cfce91374498578c44013041416c0c5b09b1eKenny Root		OPENSSL_free(abuf);
764a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_MD_CTX_cleanup(&mctx);
765a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 0;
766a88cfce91374498578c44013041416c0c5b09b1eKenny Root
767a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
768a88cfce91374498578c44013041416c0c5b09b1eKenny Root
769a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_SignerInfo_verify(CMS_SignerInfo *si)
770a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
771a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_MD_CTX mctx;
772a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_PKEY_CTX *pctx;
773a88cfce91374498578c44013041416c0c5b09b1eKenny Root	unsigned char *abuf = NULL;
774a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int alen, r = -1;
775a88cfce91374498578c44013041416c0c5b09b1eKenny Root	const EVP_MD *md = NULL;
776a88cfce91374498578c44013041416c0c5b09b1eKenny Root
777a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!si->pkey)
778a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
779a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
780a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return -1;
781a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
782a88cfce91374498578c44013041416c0c5b09b1eKenny Root
783a88cfce91374498578c44013041416c0c5b09b1eKenny Root	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
784a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (md == NULL)
785a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return -1;
786a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_MD_CTX_init(&mctx);
787a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
788a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
789a88cfce91374498578c44013041416c0c5b09b1eKenny Root
790a88cfce91374498578c44013041416c0c5b09b1eKenny Root	alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
791a88cfce91374498578c44013041416c0c5b09b1eKenny Root				ASN1_ITEM_rptr(CMS_Attributes_Verify));
792a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if(!abuf)
793a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
794a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = EVP_DigestVerifyUpdate(&mctx, abuf, alen);
795a88cfce91374498578c44013041416c0c5b09b1eKenny Root	OPENSSL_free(abuf);
796a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (r <= 0)
797a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
798a88cfce91374498578c44013041416c0c5b09b1eKenny Root		r = -1;
799a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
800a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
801a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = EVP_DigestVerifyFinal(&mctx,
802a88cfce91374498578c44013041416c0c5b09b1eKenny Root			si->signature->data, si->signature->length);
803a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (r <= 0)
804a88cfce91374498578c44013041416c0c5b09b1eKenny Root		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
805a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
806a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_MD_CTX_cleanup(&mctx);
807a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
808a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
809a88cfce91374498578c44013041416c0c5b09b1eKenny Root
810a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Create a chain of digest BIOs from a CMS ContentInfo */
811a88cfce91374498578c44013041416c0c5b09b1eKenny Root
812a88cfce91374498578c44013041416c0c5b09b1eKenny RootBIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
813a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
814a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int i;
815a88cfce91374498578c44013041416c0c5b09b1eKenny Root	CMS_SignedData *sd;
816a88cfce91374498578c44013041416c0c5b09b1eKenny Root	BIO *chain = NULL;
817a88cfce91374498578c44013041416c0c5b09b1eKenny Root	sd = cms_get0_signed(cms);
818a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!sd)
819a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return NULL;
820a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (cms->d.signedData->encapContentInfo->partial)
821a88cfce91374498578c44013041416c0c5b09b1eKenny Root		cms_sd_set_version(sd);
822a88cfce91374498578c44013041416c0c5b09b1eKenny Root	for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
823a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
824a88cfce91374498578c44013041416c0c5b09b1eKenny Root		X509_ALGOR *digestAlgorithm;
825a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO *mdbio;
826a88cfce91374498578c44013041416c0c5b09b1eKenny Root		digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
827a88cfce91374498578c44013041416c0c5b09b1eKenny Root		mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
828a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!mdbio)
829a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
830a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (chain)
831a88cfce91374498578c44013041416c0c5b09b1eKenny Root			 BIO_push(chain, mdbio);
832a88cfce91374498578c44013041416c0c5b09b1eKenny Root		else
833a88cfce91374498578c44013041416c0c5b09b1eKenny Root			chain = mdbio;
834a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
835a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return chain;
836a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
837a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (chain)
838a88cfce91374498578c44013041416c0c5b09b1eKenny Root		BIO_free_all(chain);
839a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return NULL;
840a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
841a88cfce91374498578c44013041416c0c5b09b1eKenny Root
842a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
843a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
844a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_OCTET_STRING *os = NULL;
845a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_MD_CTX mctx;
846a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int r = -1;
847a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_MD_CTX_init(&mctx);
848a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* If we have any signed attributes look for messageDigest value */
849a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (CMS_signed_get_attr_count(si) >= 0)
850a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
851a88cfce91374498578c44013041416c0c5b09b1eKenny Root		os = CMS_signed_get0_data_by_OBJ(si,
852a88cfce91374498578c44013041416c0c5b09b1eKenny Root					OBJ_nid2obj(NID_pkcs9_messageDigest),
853a88cfce91374498578c44013041416c0c5b09b1eKenny Root					-3, V_ASN1_OCTET_STRING);
854a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!os)
855a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
856a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
857a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
858a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
859a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
860a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
861a88cfce91374498578c44013041416c0c5b09b1eKenny Root
862a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
863a88cfce91374498578c44013041416c0c5b09b1eKenny Root		goto err;
864a88cfce91374498578c44013041416c0c5b09b1eKenny Root
865a88cfce91374498578c44013041416c0c5b09b1eKenny Root	/* If messageDigest found compare it */
866a88cfce91374498578c44013041416c0c5b09b1eKenny Root
867a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (os)
868a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
869a88cfce91374498578c44013041416c0c5b09b1eKenny Root		unsigned char mval[EVP_MAX_MD_SIZE];
870a88cfce91374498578c44013041416c0c5b09b1eKenny Root		unsigned int mlen;
871a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0)
872a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
873a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
874a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
875a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
876a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
877a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (mlen != (unsigned int)os->length)
878a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
879a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
880a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
881a88cfce91374498578c44013041416c0c5b09b1eKenny Root			goto err;
882a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
883a88cfce91374498578c44013041416c0c5b09b1eKenny Root
884a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (memcmp(mval, os->data, mlen))
885a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
886a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
887a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_R_VERIFICATION_FAILURE);
888a88cfce91374498578c44013041416c0c5b09b1eKenny Root			r = 0;
889a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
890a88cfce91374498578c44013041416c0c5b09b1eKenny Root		else
891a88cfce91374498578c44013041416c0c5b09b1eKenny Root			r = 1;
892a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
893a88cfce91374498578c44013041416c0c5b09b1eKenny Root	else
894a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
895a88cfce91374498578c44013041416c0c5b09b1eKenny Root		r = EVP_VerifyFinal(&mctx, si->signature->data,
896a88cfce91374498578c44013041416c0c5b09b1eKenny Root					si->signature->length, si->pkey);
897a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (r <= 0)
898a88cfce91374498578c44013041416c0c5b09b1eKenny Root			{
899a88cfce91374498578c44013041416c0c5b09b1eKenny Root			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
900a88cfce91374498578c44013041416c0c5b09b1eKenny Root				CMS_R_VERIFICATION_FAILURE);
901a88cfce91374498578c44013041416c0c5b09b1eKenny Root			r = 0;
902a88cfce91374498578c44013041416c0c5b09b1eKenny Root			}
903a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
904a88cfce91374498578c44013041416c0c5b09b1eKenny Root
905a88cfce91374498578c44013041416c0c5b09b1eKenny Root	err:
906a88cfce91374498578c44013041416c0c5b09b1eKenny Root	EVP_MD_CTX_cleanup(&mctx);
907a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
908a88cfce91374498578c44013041416c0c5b09b1eKenny Root
909a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
910a88cfce91374498578c44013041416c0c5b09b1eKenny Root
911a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
912a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
913a88cfce91374498578c44013041416c0c5b09b1eKenny Root	unsigned char *smder = NULL;
914a88cfce91374498578c44013041416c0c5b09b1eKenny Root	int smderlen, r;
915a88cfce91374498578c44013041416c0c5b09b1eKenny Root	smderlen = i2d_X509_ALGORS(algs, &smder);
916a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (smderlen <= 0)
917a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
918a88cfce91374498578c44013041416c0c5b09b1eKenny Root	r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
919a88cfce91374498578c44013041416c0c5b09b1eKenny Root					V_ASN1_SEQUENCE, smder, smderlen);
920a88cfce91374498578c44013041416c0c5b09b1eKenny Root	OPENSSL_free(smder);
921a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return r;
922a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
923a88cfce91374498578c44013041416c0c5b09b1eKenny Root
924a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
925a88cfce91374498578c44013041416c0c5b09b1eKenny Root				int algnid, int keysize)
926a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
927a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509_ALGOR *alg;
928a88cfce91374498578c44013041416c0c5b09b1eKenny Root	ASN1_INTEGER *key = NULL;
929a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (keysize > 0)
930a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
931a88cfce91374498578c44013041416c0c5b09b1eKenny Root		key = ASN1_INTEGER_new();
932a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (!key || !ASN1_INTEGER_set(key, keysize))
933a88cfce91374498578c44013041416c0c5b09b1eKenny Root			return 0;
934a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
935a88cfce91374498578c44013041416c0c5b09b1eKenny Root	alg = X509_ALGOR_new();
936a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!alg)
937a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
938a88cfce91374498578c44013041416c0c5b09b1eKenny Root		if (key)
939a88cfce91374498578c44013041416c0c5b09b1eKenny Root			ASN1_INTEGER_free(key);
940a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
941a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
942a88cfce91374498578c44013041416c0c5b09b1eKenny Root
943a88cfce91374498578c44013041416c0c5b09b1eKenny Root	X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
944a88cfce91374498578c44013041416c0c5b09b1eKenny Root				key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
945a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!*algs)
946a88cfce91374498578c44013041416c0c5b09b1eKenny Root		*algs = sk_X509_ALGOR_new_null();
947a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!*algs || !sk_X509_ALGOR_push(*algs, alg))
948a88cfce91374498578c44013041416c0c5b09b1eKenny Root		{
949a88cfce91374498578c44013041416c0c5b09b1eKenny Root		X509_ALGOR_free(alg);
950a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
951a88cfce91374498578c44013041416c0c5b09b1eKenny Root		}
952a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
953a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
954a88cfce91374498578c44013041416c0c5b09b1eKenny Root
955a88cfce91374498578c44013041416c0c5b09b1eKenny Root/* Check to see if a cipher exists and if so add S/MIME capabilities */
956a88cfce91374498578c44013041416c0c5b09b1eKenny Root
957a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
958a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
959a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (EVP_get_cipherbynid(nid))
960a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return CMS_add_simple_smimecap(sk, nid, arg);
961a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
962a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
963a88cfce91374498578c44013041416c0c5b09b1eKenny Root
964a88cfce91374498578c44013041416c0c5b09b1eKenny Rootstatic int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
965a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
966a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (EVP_get_digestbynid(nid))
967a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return CMS_add_simple_smimecap(sk, nid, arg);
968a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
969a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
970a88cfce91374498578c44013041416c0c5b09b1eKenny Root
971a88cfce91374498578c44013041416c0c5b09b1eKenny Rootint CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
972a88cfce91374498578c44013041416c0c5b09b1eKenny Root	{
973a88cfce91374498578c44013041416c0c5b09b1eKenny Root	if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
974a88cfce91374498578c44013041416c0c5b09b1eKenny Root		|| !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
975a88cfce91374498578c44013041416c0c5b09b1eKenny Root		|| !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
976a88cfce91374498578c44013041416c0c5b09b1eKenny Root		|| !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
977a88cfce91374498578c44013041416c0c5b09b1eKenny Root		|| !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
978a88cfce91374498578c44013041416c0c5b09b1eKenny Root		|| !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
979a88cfce91374498578c44013041416c0c5b09b1eKenny Root		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
980a88cfce91374498578c44013041416c0c5b09b1eKenny Root		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
981a88cfce91374498578c44013041416c0c5b09b1eKenny Root		|| !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
982a88cfce91374498578c44013041416c0c5b09b1eKenny Root		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
983a88cfce91374498578c44013041416c0c5b09b1eKenny Root		return 0;
984a88cfce91374498578c44013041416c0c5b09b1eKenny Root	return 1;
985a88cfce91374498578c44013041416c0c5b09b1eKenny Root	}
986