xref: /dflybsd-src/crypto/libressl/apps/openssl/cms.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: cms.c,v 1.30 2022/03/23 15:16:59 tb Exp $ */
2cca6fc52SDaniel Fojt /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3cca6fc52SDaniel Fojt  * project.
4cca6fc52SDaniel Fojt  */
5cca6fc52SDaniel Fojt /* ====================================================================
6cca6fc52SDaniel Fojt  * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
7cca6fc52SDaniel Fojt  *
8cca6fc52SDaniel Fojt  * Redistribution and use in source and binary forms, with or without
9cca6fc52SDaniel Fojt  * modification, are permitted provided that the following conditions
10cca6fc52SDaniel Fojt  * are met:
11cca6fc52SDaniel Fojt  *
12cca6fc52SDaniel Fojt  * 1. Redistributions of source code must retain the above copyright
13cca6fc52SDaniel Fojt  *    notice, this list of conditions and the following disclaimer.
14cca6fc52SDaniel Fojt  *
15cca6fc52SDaniel Fojt  * 2. Redistributions in binary form must reproduce the above copyright
16cca6fc52SDaniel Fojt  *    notice, this list of conditions and the following disclaimer in
17cca6fc52SDaniel Fojt  *    the documentation and/or other materials provided with the
18cca6fc52SDaniel Fojt  *    distribution.
19cca6fc52SDaniel Fojt  *
20cca6fc52SDaniel Fojt  * 3. All advertising materials mentioning features or use of this
21cca6fc52SDaniel Fojt  *    software must display the following acknowledgment:
22cca6fc52SDaniel Fojt  *    "This product includes software developed by the OpenSSL Project
23cca6fc52SDaniel Fojt  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24cca6fc52SDaniel Fojt  *
25cca6fc52SDaniel Fojt  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26cca6fc52SDaniel Fojt  *    endorse or promote products derived from this software without
27cca6fc52SDaniel Fojt  *    prior written permission. For written permission, please contact
28cca6fc52SDaniel Fojt  *    licensing@OpenSSL.org.
29cca6fc52SDaniel Fojt  *
30cca6fc52SDaniel Fojt  * 5. Products derived from this software may not be called "OpenSSL"
31cca6fc52SDaniel Fojt  *    nor may "OpenSSL" appear in their names without prior written
32cca6fc52SDaniel Fojt  *    permission of the OpenSSL Project.
33cca6fc52SDaniel Fojt  *
34cca6fc52SDaniel Fojt  * 6. Redistributions of any form whatsoever must retain the following
35cca6fc52SDaniel Fojt  *    acknowledgment:
36cca6fc52SDaniel Fojt  *    "This product includes software developed by the OpenSSL Project
37cca6fc52SDaniel Fojt  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38cca6fc52SDaniel Fojt  *
39cca6fc52SDaniel Fojt  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40cca6fc52SDaniel Fojt  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41cca6fc52SDaniel Fojt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42cca6fc52SDaniel Fojt  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43cca6fc52SDaniel Fojt  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44cca6fc52SDaniel Fojt  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45cca6fc52SDaniel Fojt  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46cca6fc52SDaniel Fojt  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47cca6fc52SDaniel Fojt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48cca6fc52SDaniel Fojt  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49cca6fc52SDaniel Fojt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50cca6fc52SDaniel Fojt  * OF THE POSSIBILITY OF SUCH DAMAGE.
51cca6fc52SDaniel Fojt  * ====================================================================
52cca6fc52SDaniel Fojt  */
53cca6fc52SDaniel Fojt 
54cca6fc52SDaniel Fojt /* CMS utility function */
55cca6fc52SDaniel Fojt 
56cca6fc52SDaniel Fojt #include <stdio.h>
57cca6fc52SDaniel Fojt #include <string.h>
58cca6fc52SDaniel Fojt 
59cca6fc52SDaniel Fojt #include "apps.h"
60cca6fc52SDaniel Fojt 
61cca6fc52SDaniel Fojt #ifndef OPENSSL_NO_CMS
62cca6fc52SDaniel Fojt 
63cca6fc52SDaniel Fojt #include <openssl/crypto.h>
64cca6fc52SDaniel Fojt #include <openssl/err.h>
65cca6fc52SDaniel Fojt #include <openssl/pem.h>
66cca6fc52SDaniel Fojt #include <openssl/x509_vfy.h>
67cca6fc52SDaniel Fojt #include <openssl/x509v3.h>
68cca6fc52SDaniel Fojt 
69cca6fc52SDaniel Fojt #include <openssl/cms.h>
70cca6fc52SDaniel Fojt 
71cca6fc52SDaniel Fojt static int save_certs(char *signerfile, STACK_OF(X509) *signers);
72cca6fc52SDaniel Fojt static int cms_cb(int ok, X509_STORE_CTX *ctx);
73cca6fc52SDaniel Fojt static void receipt_request_print(BIO *out, CMS_ContentInfo *cms);
74cca6fc52SDaniel Fojt static CMS_ReceiptRequest *make_receipt_request(
75cca6fc52SDaniel Fojt     STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
76cca6fc52SDaniel Fojt     STACK_OF(OPENSSL_STRING) *rr_from);
77cca6fc52SDaniel Fojt static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
78cca6fc52SDaniel Fojt     STACK_OF(OPENSSL_STRING) *param);
79cca6fc52SDaniel Fojt 
80cca6fc52SDaniel Fojt #define SMIME_OP	0x10
81cca6fc52SDaniel Fojt #define SMIME_IP	0x20
82cca6fc52SDaniel Fojt #define SMIME_SIGNERS	0x40
83cca6fc52SDaniel Fojt #define SMIME_ENCRYPT		(1 | SMIME_OP)
84cca6fc52SDaniel Fojt #define SMIME_DECRYPT		(2 | SMIME_IP)
85cca6fc52SDaniel Fojt #define SMIME_SIGN		(3 | SMIME_OP | SMIME_SIGNERS)
86cca6fc52SDaniel Fojt #define SMIME_VERIFY		(4 | SMIME_IP)
87cca6fc52SDaniel Fojt #define SMIME_CMSOUT		(5 | SMIME_IP | SMIME_OP)
88cca6fc52SDaniel Fojt #define SMIME_RESIGN		(6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
89cca6fc52SDaniel Fojt #define SMIME_DATAOUT		(7 | SMIME_IP)
90cca6fc52SDaniel Fojt #define SMIME_DATA_CREATE	(8 | SMIME_OP)
91cca6fc52SDaniel Fojt #define SMIME_DIGEST_VERIFY	(9 | SMIME_IP)
92cca6fc52SDaniel Fojt #define SMIME_DIGEST_CREATE	(10 | SMIME_OP)
93cca6fc52SDaniel Fojt #define SMIME_UNCOMPRESS	(11 | SMIME_IP)
94cca6fc52SDaniel Fojt #define SMIME_COMPRESS		(12 | SMIME_OP)
95cca6fc52SDaniel Fojt #define SMIME_ENCRYPTED_DECRYPT	(13 | SMIME_IP)
96cca6fc52SDaniel Fojt #define SMIME_ENCRYPTED_ENCRYPT	(14 | SMIME_OP)
97cca6fc52SDaniel Fojt #define SMIME_SIGN_RECEIPT	(15 | SMIME_IP | SMIME_OP)
98cca6fc52SDaniel Fojt #define SMIME_VERIFY_RECEIPT	(16 | SMIME_IP)
99cca6fc52SDaniel Fojt 
100cca6fc52SDaniel Fojt int verify_err = 0;
101cca6fc52SDaniel Fojt 
102cca6fc52SDaniel Fojt struct cms_key_param {
103cca6fc52SDaniel Fojt 	int idx;
104cca6fc52SDaniel Fojt 	STACK_OF(OPENSSL_STRING) *param;
105cca6fc52SDaniel Fojt 	struct cms_key_param *next;
106cca6fc52SDaniel Fojt };
107cca6fc52SDaniel Fojt 
108*de0e0e4dSAntonio Huete Jimenez static struct {
109*de0e0e4dSAntonio Huete Jimenez 	char *CAfile;
110*de0e0e4dSAntonio Huete Jimenez 	char *CApath;
111*de0e0e4dSAntonio Huete Jimenez 	X509 *cert;
112*de0e0e4dSAntonio Huete Jimenez 	char *certfile;
113*de0e0e4dSAntonio Huete Jimenez 	char *certsoutfile;
114*de0e0e4dSAntonio Huete Jimenez 	const EVP_CIPHER *cipher;
115*de0e0e4dSAntonio Huete Jimenez 	char *contfile;
116*de0e0e4dSAntonio Huete Jimenez 	ASN1_OBJECT *econtent_type;
117*de0e0e4dSAntonio Huete Jimenez 	STACK_OF(X509) *encerts;
118*de0e0e4dSAntonio Huete Jimenez 	int flags;
119*de0e0e4dSAntonio Huete Jimenez 	char *from;
120*de0e0e4dSAntonio Huete Jimenez 	char *infile;
121*de0e0e4dSAntonio Huete Jimenez 	int informat;
122*de0e0e4dSAntonio Huete Jimenez 	struct cms_key_param *key_first;
123*de0e0e4dSAntonio Huete Jimenez 	struct cms_key_param *key_param;
124*de0e0e4dSAntonio Huete Jimenez 	char *keyfile;
125*de0e0e4dSAntonio Huete Jimenez 	int keyform;
126*de0e0e4dSAntonio Huete Jimenez 	int noout;
127*de0e0e4dSAntonio Huete Jimenez 	int operation;
128*de0e0e4dSAntonio Huete Jimenez 	char *outfile;
129*de0e0e4dSAntonio Huete Jimenez 	int outformat;
130*de0e0e4dSAntonio Huete Jimenez 	char *passargin;
131*de0e0e4dSAntonio Huete Jimenez 	int print;
132*de0e0e4dSAntonio Huete Jimenez 	unsigned char *pwri_pass;
133*de0e0e4dSAntonio Huete Jimenez 	int rr_allorfirst;
134*de0e0e4dSAntonio Huete Jimenez 	STACK_OF(OPENSSL_STRING) *rr_from;
135*de0e0e4dSAntonio Huete Jimenez 	int rr_print;
136*de0e0e4dSAntonio Huete Jimenez 	STACK_OF(OPENSSL_STRING) *rr_to;
137*de0e0e4dSAntonio Huete Jimenez 	char *rctfile;
138*de0e0e4dSAntonio Huete Jimenez 	int rctformat;
139*de0e0e4dSAntonio Huete Jimenez 	char *recipfile;
140*de0e0e4dSAntonio Huete Jimenez 	unsigned char *secret_key;
141*de0e0e4dSAntonio Huete Jimenez 	unsigned char *secret_keyid;
142*de0e0e4dSAntonio Huete Jimenez 	size_t secret_keyidlen;
143*de0e0e4dSAntonio Huete Jimenez 	size_t secret_keylen;
144*de0e0e4dSAntonio Huete Jimenez 	const EVP_MD *sign_md;
145*de0e0e4dSAntonio Huete Jimenez 	char *signerfile;
146*de0e0e4dSAntonio Huete Jimenez 	STACK_OF(OPENSSL_STRING) *skkeys;
147*de0e0e4dSAntonio Huete Jimenez 	STACK_OF(OPENSSL_STRING) *sksigners;
148*de0e0e4dSAntonio Huete Jimenez 	char *subject;
149*de0e0e4dSAntonio Huete Jimenez 	char *to;
150*de0e0e4dSAntonio Huete Jimenez 	int verify_retcode;
151*de0e0e4dSAntonio Huete Jimenez 	X509_VERIFY_PARAM *vpm;
152*de0e0e4dSAntonio Huete Jimenez } cms_config;
153*de0e0e4dSAntonio Huete Jimenez 
154*de0e0e4dSAntonio Huete Jimenez static const EVP_CIPHER *
get_cipher_by_name(char * name)155*de0e0e4dSAntonio Huete Jimenez get_cipher_by_name(char *name)
156*de0e0e4dSAntonio Huete Jimenez {
157*de0e0e4dSAntonio Huete Jimenez 	if (name == NULL || strcmp(name, "") == 0)
158*de0e0e4dSAntonio Huete Jimenez 		return (NULL);
159*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_AES
160*de0e0e4dSAntonio Huete Jimenez 	else if (strcmp(name, "aes128") == 0)
161*de0e0e4dSAntonio Huete Jimenez 		return EVP_aes_128_cbc();
162*de0e0e4dSAntonio Huete Jimenez 	else if (strcmp(name, "aes192") == 0)
163*de0e0e4dSAntonio Huete Jimenez 		return EVP_aes_192_cbc();
164*de0e0e4dSAntonio Huete Jimenez 	else if (strcmp(name, "aes256") == 0)
165*de0e0e4dSAntonio Huete Jimenez 		return EVP_aes_256_cbc();
166*de0e0e4dSAntonio Huete Jimenez #endif
167*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_CAMELLIA
168*de0e0e4dSAntonio Huete Jimenez 	else if (strcmp(name, "camellia128") == 0)
169*de0e0e4dSAntonio Huete Jimenez 		return EVP_camellia_128_cbc();
170*de0e0e4dSAntonio Huete Jimenez 	else if (strcmp(name, "camellia192") == 0)
171*de0e0e4dSAntonio Huete Jimenez 		return EVP_camellia_192_cbc();
172*de0e0e4dSAntonio Huete Jimenez 	else if (strcmp(name, "camellia256") == 0)
173*de0e0e4dSAntonio Huete Jimenez 		return EVP_camellia_256_cbc();
174*de0e0e4dSAntonio Huete Jimenez #endif
175*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DES
176*de0e0e4dSAntonio Huete Jimenez 	else if (strcmp(name, "des") == 0)
177*de0e0e4dSAntonio Huete Jimenez 		return EVP_des_cbc();
178*de0e0e4dSAntonio Huete Jimenez 	else if (strcmp(name, "des3") == 0)
179*de0e0e4dSAntonio Huete Jimenez 		return EVP_des_ede3_cbc();
180*de0e0e4dSAntonio Huete Jimenez #endif
181*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_RC2
182*de0e0e4dSAntonio Huete Jimenez 	else if (!strcmp(name, "rc2-40"))
183*de0e0e4dSAntonio Huete Jimenez 		return EVP_rc2_40_cbc();
184*de0e0e4dSAntonio Huete Jimenez 	else if (!strcmp(name, "rc2-64"))
185*de0e0e4dSAntonio Huete Jimenez 		return EVP_rc2_64_cbc();
186*de0e0e4dSAntonio Huete Jimenez 	else if (!strcmp(name, "rc2-128"))
187*de0e0e4dSAntonio Huete Jimenez 		return EVP_rc2_cbc();
188*de0e0e4dSAntonio Huete Jimenez #endif
189*de0e0e4dSAntonio Huete Jimenez 	else
190*de0e0e4dSAntonio Huete Jimenez 		return (NULL);
191*de0e0e4dSAntonio Huete Jimenez }
192*de0e0e4dSAntonio Huete Jimenez 
193*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_cipher(int argc,char ** argv,int * argsused)194*de0e0e4dSAntonio Huete Jimenez cms_opt_cipher(int argc, char **argv, int *argsused)
195*de0e0e4dSAntonio Huete Jimenez {
196*de0e0e4dSAntonio Huete Jimenez 	char *name = argv[0];
197*de0e0e4dSAntonio Huete Jimenez 
198*de0e0e4dSAntonio Huete Jimenez 	if (*name++ != '-')
199*de0e0e4dSAntonio Huete Jimenez 		return (1);
200*de0e0e4dSAntonio Huete Jimenez 
201*de0e0e4dSAntonio Huete Jimenez 	if ((cms_config.cipher = get_cipher_by_name(name)) == NULL)
202*de0e0e4dSAntonio Huete Jimenez 		if ((cms_config.cipher = EVP_get_cipherbyname(name)) == NULL)
203*de0e0e4dSAntonio Huete Jimenez 			return (1);
204*de0e0e4dSAntonio Huete Jimenez 
205*de0e0e4dSAntonio Huete Jimenez 	*argsused = 1;
206*de0e0e4dSAntonio Huete Jimenez 	return (0);
207*de0e0e4dSAntonio Huete Jimenez }
208*de0e0e4dSAntonio Huete Jimenez 
209*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_econtent_type(char * arg)210*de0e0e4dSAntonio Huete Jimenez cms_opt_econtent_type(char *arg)
211*de0e0e4dSAntonio Huete Jimenez {
212*de0e0e4dSAntonio Huete Jimenez 	ASN1_OBJECT_free(cms_config.econtent_type);
213*de0e0e4dSAntonio Huete Jimenez 
214*de0e0e4dSAntonio Huete Jimenez 	if ((cms_config.econtent_type = OBJ_txt2obj(arg, 0)) == NULL) {
215*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err, "Invalid OID %s\n", arg);
216*de0e0e4dSAntonio Huete Jimenez 		return (1);
217*de0e0e4dSAntonio Huete Jimenez 	}
218*de0e0e4dSAntonio Huete Jimenez 	return (0);
219*de0e0e4dSAntonio Huete Jimenez }
220*de0e0e4dSAntonio Huete Jimenez 
221*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_inkey(char * arg)222*de0e0e4dSAntonio Huete Jimenez cms_opt_inkey(char *arg)
223*de0e0e4dSAntonio Huete Jimenez {
224*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.keyfile == NULL) {
225*de0e0e4dSAntonio Huete Jimenez 		cms_config.keyfile = arg;
226*de0e0e4dSAntonio Huete Jimenez 		return (0);
227*de0e0e4dSAntonio Huete Jimenez 	}
228*de0e0e4dSAntonio Huete Jimenez 
229*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.signerfile == NULL) {
230*de0e0e4dSAntonio Huete Jimenez 		BIO_puts(bio_err, "Illegal -inkey without -signer\n");
231*de0e0e4dSAntonio Huete Jimenez 		return (1);
232*de0e0e4dSAntonio Huete Jimenez 	}
233*de0e0e4dSAntonio Huete Jimenez 
234*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.sksigners == NULL)
235*de0e0e4dSAntonio Huete Jimenez 		cms_config.sksigners = sk_OPENSSL_STRING_new_null();
236*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.sksigners == NULL)
237*de0e0e4dSAntonio Huete Jimenez 		return (1);
238*de0e0e4dSAntonio Huete Jimenez 	if (!sk_OPENSSL_STRING_push(cms_config.sksigners, cms_config.signerfile))
239*de0e0e4dSAntonio Huete Jimenez 		return (1);
240*de0e0e4dSAntonio Huete Jimenez 
241*de0e0e4dSAntonio Huete Jimenez 	cms_config.signerfile = NULL;
242*de0e0e4dSAntonio Huete Jimenez 
243*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.skkeys == NULL)
244*de0e0e4dSAntonio Huete Jimenez 		cms_config.skkeys = sk_OPENSSL_STRING_new_null();
245*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.skkeys == NULL)
246*de0e0e4dSAntonio Huete Jimenez 		return (1);
247*de0e0e4dSAntonio Huete Jimenez 	if (!sk_OPENSSL_STRING_push(cms_config.skkeys, cms_config.keyfile))
248*de0e0e4dSAntonio Huete Jimenez 		return (1);
249*de0e0e4dSAntonio Huete Jimenez 
250*de0e0e4dSAntonio Huete Jimenez 	cms_config.keyfile = arg;
251*de0e0e4dSAntonio Huete Jimenez 	return (0);
252*de0e0e4dSAntonio Huete Jimenez }
253*de0e0e4dSAntonio Huete Jimenez 
254*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_keyopt(char * arg)255*de0e0e4dSAntonio Huete Jimenez cms_opt_keyopt(char *arg)
256*de0e0e4dSAntonio Huete Jimenez {
257*de0e0e4dSAntonio Huete Jimenez 	int keyidx = -1;
258*de0e0e4dSAntonio Huete Jimenez 
259*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.operation == SMIME_ENCRYPT) {
260*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.encerts != NULL)
261*de0e0e4dSAntonio Huete Jimenez 			keyidx += sk_X509_num(cms_config.encerts);
262*de0e0e4dSAntonio Huete Jimenez 	} else {
263*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.keyfile != NULL || cms_config.signerfile != NULL)
264*de0e0e4dSAntonio Huete Jimenez 			keyidx++;
265*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.skkeys != NULL)
266*de0e0e4dSAntonio Huete Jimenez 			keyidx += sk_OPENSSL_STRING_num(cms_config.skkeys);
267*de0e0e4dSAntonio Huete Jimenez 	}
268*de0e0e4dSAntonio Huete Jimenez 
269*de0e0e4dSAntonio Huete Jimenez 	if (keyidx < 0) {
270*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err, "No key specified\n");
271*de0e0e4dSAntonio Huete Jimenez 		return (1);
272*de0e0e4dSAntonio Huete Jimenez 	}
273*de0e0e4dSAntonio Huete Jimenez 
274*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.key_param == NULL ||
275*de0e0e4dSAntonio Huete Jimenez 	    cms_config.key_param->idx != keyidx) {
276*de0e0e4dSAntonio Huete Jimenez 		struct cms_key_param *nparam;
277*de0e0e4dSAntonio Huete Jimenez 
278*de0e0e4dSAntonio Huete Jimenez 		if ((nparam = calloc(1, sizeof(struct cms_key_param))) == NULL)
279*de0e0e4dSAntonio Huete Jimenez 			return (1);
280*de0e0e4dSAntonio Huete Jimenez 
281*de0e0e4dSAntonio Huete Jimenez 		nparam->idx = keyidx;
282*de0e0e4dSAntonio Huete Jimenez 		if ((nparam->param = sk_OPENSSL_STRING_new_null()) == NULL) {
283*de0e0e4dSAntonio Huete Jimenez 			free(nparam);
284*de0e0e4dSAntonio Huete Jimenez 			return (1);
285*de0e0e4dSAntonio Huete Jimenez 		}
286*de0e0e4dSAntonio Huete Jimenez 
287*de0e0e4dSAntonio Huete Jimenez 		nparam->next = NULL;
288*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.key_first == NULL)
289*de0e0e4dSAntonio Huete Jimenez 			cms_config.key_first = nparam;
290*de0e0e4dSAntonio Huete Jimenez 		else
291*de0e0e4dSAntonio Huete Jimenez 			cms_config.key_param->next = nparam;
292*de0e0e4dSAntonio Huete Jimenez 
293*de0e0e4dSAntonio Huete Jimenez 		cms_config.key_param = nparam;
294*de0e0e4dSAntonio Huete Jimenez 	}
295*de0e0e4dSAntonio Huete Jimenez 
296*de0e0e4dSAntonio Huete Jimenez 	if (!sk_OPENSSL_STRING_push(cms_config.key_param->param, arg))
297*de0e0e4dSAntonio Huete Jimenez 		return (1);
298*de0e0e4dSAntonio Huete Jimenez 
299*de0e0e4dSAntonio Huete Jimenez 	return (0);
300*de0e0e4dSAntonio Huete Jimenez }
301*de0e0e4dSAntonio Huete Jimenez 
302*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_md(char * arg)303*de0e0e4dSAntonio Huete Jimenez cms_opt_md(char *arg)
304*de0e0e4dSAntonio Huete Jimenez {
305*de0e0e4dSAntonio Huete Jimenez 	if ((cms_config.sign_md = EVP_get_digestbyname(arg)) == NULL) {
306*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err, "Unknown digest %s\n", arg);
307*de0e0e4dSAntonio Huete Jimenez 		return (1);
308*de0e0e4dSAntonio Huete Jimenez 	}
309*de0e0e4dSAntonio Huete Jimenez 	return (0);
310*de0e0e4dSAntonio Huete Jimenez }
311*de0e0e4dSAntonio Huete Jimenez 
312*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_print(void)313*de0e0e4dSAntonio Huete Jimenez cms_opt_print(void)
314*de0e0e4dSAntonio Huete Jimenez {
315*de0e0e4dSAntonio Huete Jimenez 	cms_config.noout = 1;
316*de0e0e4dSAntonio Huete Jimenez 	cms_config.print = 1;
317*de0e0e4dSAntonio Huete Jimenez 	return (0);
318*de0e0e4dSAntonio Huete Jimenez }
319*de0e0e4dSAntonio Huete Jimenez 
320*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_pwri_pass(char * arg)321*de0e0e4dSAntonio Huete Jimenez cms_opt_pwri_pass(char *arg)
322*de0e0e4dSAntonio Huete Jimenez {
323*de0e0e4dSAntonio Huete Jimenez 	cms_config.pwri_pass = (unsigned char *)arg;
324*de0e0e4dSAntonio Huete Jimenez 	return (0);
325*de0e0e4dSAntonio Huete Jimenez }
326*de0e0e4dSAntonio Huete Jimenez 
327*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_recip(char * arg)328*de0e0e4dSAntonio Huete Jimenez cms_opt_recip(char *arg)
329*de0e0e4dSAntonio Huete Jimenez {
330*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.operation == SMIME_ENCRYPT) {
331*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.encerts == NULL) {
332*de0e0e4dSAntonio Huete Jimenez 			if ((cms_config.encerts = sk_X509_new_null()) == NULL)
333*de0e0e4dSAntonio Huete Jimenez 				return (1);
334*de0e0e4dSAntonio Huete Jimenez 		}
335*de0e0e4dSAntonio Huete Jimenez 
336*de0e0e4dSAntonio Huete Jimenez 		cms_config.cert = load_cert(bio_err, arg, FORMAT_PEM,
337*de0e0e4dSAntonio Huete Jimenez 		    NULL, "recipient certificate file");
338*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.cert == NULL)
339*de0e0e4dSAntonio Huete Jimenez 			return (1);
340*de0e0e4dSAntonio Huete Jimenez 
341*de0e0e4dSAntonio Huete Jimenez 		if (!sk_X509_push(cms_config.encerts, cms_config.cert))
342*de0e0e4dSAntonio Huete Jimenez 			return (1);
343*de0e0e4dSAntonio Huete Jimenez 
344*de0e0e4dSAntonio Huete Jimenez 		cms_config.cert = NULL;
345*de0e0e4dSAntonio Huete Jimenez 	} else {
346*de0e0e4dSAntonio Huete Jimenez 		cms_config.recipfile = arg;
347*de0e0e4dSAntonio Huete Jimenez 	}
348*de0e0e4dSAntonio Huete Jimenez 	return (0);
349*de0e0e4dSAntonio Huete Jimenez }
350*de0e0e4dSAntonio Huete Jimenez 
351*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_receipt_request_from(char * arg)352*de0e0e4dSAntonio Huete Jimenez cms_opt_receipt_request_from(char *arg)
353*de0e0e4dSAntonio Huete Jimenez {
354*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.rr_from == NULL)
355*de0e0e4dSAntonio Huete Jimenez 		cms_config.rr_from = sk_OPENSSL_STRING_new_null();
356*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.rr_from == NULL)
357*de0e0e4dSAntonio Huete Jimenez 		return (1);
358*de0e0e4dSAntonio Huete Jimenez 	if (!sk_OPENSSL_STRING_push(cms_config.rr_from, arg))
359*de0e0e4dSAntonio Huete Jimenez 		return (1);
360*de0e0e4dSAntonio Huete Jimenez 
361*de0e0e4dSAntonio Huete Jimenez 	return (0);
362*de0e0e4dSAntonio Huete Jimenez }
363*de0e0e4dSAntonio Huete Jimenez 
364*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_receipt_request_to(char * arg)365*de0e0e4dSAntonio Huete Jimenez cms_opt_receipt_request_to(char *arg)
366*de0e0e4dSAntonio Huete Jimenez {
367*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.rr_to == NULL)
368*de0e0e4dSAntonio Huete Jimenez 		cms_config.rr_to = sk_OPENSSL_STRING_new_null();
369*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.rr_to == NULL)
370*de0e0e4dSAntonio Huete Jimenez 		return (1);
371*de0e0e4dSAntonio Huete Jimenez 	if (!sk_OPENSSL_STRING_push(cms_config.rr_to, arg))
372*de0e0e4dSAntonio Huete Jimenez 		return (1);
373*de0e0e4dSAntonio Huete Jimenez 
374*de0e0e4dSAntonio Huete Jimenez 	return (0);
375*de0e0e4dSAntonio Huete Jimenez }
376*de0e0e4dSAntonio Huete Jimenez 
377*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_secretkey(char * arg)378*de0e0e4dSAntonio Huete Jimenez cms_opt_secretkey(char *arg)
379*de0e0e4dSAntonio Huete Jimenez {
380*de0e0e4dSAntonio Huete Jimenez 	long ltmp;
381*de0e0e4dSAntonio Huete Jimenez 
382*de0e0e4dSAntonio Huete Jimenez 	free(cms_config.secret_key);
383*de0e0e4dSAntonio Huete Jimenez 
384*de0e0e4dSAntonio Huete Jimenez 	if ((cms_config.secret_key = string_to_hex(arg, &ltmp)) == NULL) {
385*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err, "Invalid key %s\n", arg);
386*de0e0e4dSAntonio Huete Jimenez 		return (1);
387*de0e0e4dSAntonio Huete Jimenez 	}
388*de0e0e4dSAntonio Huete Jimenez 	cms_config.secret_keylen = (size_t)ltmp;
389*de0e0e4dSAntonio Huete Jimenez 	return (0);
390*de0e0e4dSAntonio Huete Jimenez }
391*de0e0e4dSAntonio Huete Jimenez 
392*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_secretkeyid(char * arg)393*de0e0e4dSAntonio Huete Jimenez cms_opt_secretkeyid(char *arg)
394*de0e0e4dSAntonio Huete Jimenez {
395*de0e0e4dSAntonio Huete Jimenez 	long ltmp;
396*de0e0e4dSAntonio Huete Jimenez 
397*de0e0e4dSAntonio Huete Jimenez 	free(cms_config.secret_keyid);
398*de0e0e4dSAntonio Huete Jimenez 
399*de0e0e4dSAntonio Huete Jimenez 	if ((cms_config.secret_keyid = string_to_hex(arg, &ltmp)) == NULL) {
400*de0e0e4dSAntonio Huete Jimenez 		BIO_printf(bio_err, "Invalid id %s\n", arg);
401*de0e0e4dSAntonio Huete Jimenez 		return (1);
402*de0e0e4dSAntonio Huete Jimenez 	}
403*de0e0e4dSAntonio Huete Jimenez 	cms_config.secret_keyidlen = (size_t)ltmp;
404*de0e0e4dSAntonio Huete Jimenez 	return (0);
405*de0e0e4dSAntonio Huete Jimenez }
406*de0e0e4dSAntonio Huete Jimenez 
407*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_signer(char * arg)408*de0e0e4dSAntonio Huete Jimenez cms_opt_signer(char *arg)
409*de0e0e4dSAntonio Huete Jimenez {
410*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.signerfile == NULL) {
411*de0e0e4dSAntonio Huete Jimenez 		cms_config.signerfile = arg;
412*de0e0e4dSAntonio Huete Jimenez 		return (0);
413*de0e0e4dSAntonio Huete Jimenez 	}
414*de0e0e4dSAntonio Huete Jimenez 
415*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.sksigners == NULL)
416*de0e0e4dSAntonio Huete Jimenez 		cms_config.sksigners = sk_OPENSSL_STRING_new_null();
417*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.sksigners == NULL)
418*de0e0e4dSAntonio Huete Jimenez 		return (1);
419*de0e0e4dSAntonio Huete Jimenez 	if (!sk_OPENSSL_STRING_push(cms_config.sksigners, cms_config.signerfile))
420*de0e0e4dSAntonio Huete Jimenez 		return (1);
421*de0e0e4dSAntonio Huete Jimenez 
422*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.keyfile == NULL)
423*de0e0e4dSAntonio Huete Jimenez 		cms_config.keyfile = cms_config.signerfile;
424*de0e0e4dSAntonio Huete Jimenez 
425*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.skkeys == NULL)
426*de0e0e4dSAntonio Huete Jimenez 		cms_config.skkeys = sk_OPENSSL_STRING_new_null();
427*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.skkeys == NULL)
428*de0e0e4dSAntonio Huete Jimenez 		return (1);
429*de0e0e4dSAntonio Huete Jimenez 	if (!sk_OPENSSL_STRING_push(cms_config.skkeys, cms_config.keyfile))
430*de0e0e4dSAntonio Huete Jimenez 		return (1);
431*de0e0e4dSAntonio Huete Jimenez 
432*de0e0e4dSAntonio Huete Jimenez 	cms_config.keyfile = NULL;
433*de0e0e4dSAntonio Huete Jimenez 
434*de0e0e4dSAntonio Huete Jimenez 	cms_config.signerfile = arg;
435*de0e0e4dSAntonio Huete Jimenez 	return (0);
436*de0e0e4dSAntonio Huete Jimenez }
437*de0e0e4dSAntonio Huete Jimenez 
438*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_verify_param(int argc,char ** argv,int * argsused)439*de0e0e4dSAntonio Huete Jimenez cms_opt_verify_param(int argc, char **argv, int *argsused)
440*de0e0e4dSAntonio Huete Jimenez {
441*de0e0e4dSAntonio Huete Jimenez 	int oargc = argc;
442*de0e0e4dSAntonio Huete Jimenez 	int badarg = 0;
443*de0e0e4dSAntonio Huete Jimenez 
444*de0e0e4dSAntonio Huete Jimenez 	if (!args_verify(&argv, &argc, &badarg, bio_err, &cms_config.vpm))
445*de0e0e4dSAntonio Huete Jimenez 		return (1);
446*de0e0e4dSAntonio Huete Jimenez 	if (badarg)
447*de0e0e4dSAntonio Huete Jimenez 		return (1);
448*de0e0e4dSAntonio Huete Jimenez 
449*de0e0e4dSAntonio Huete Jimenez 	*argsused = oargc - argc;
450*de0e0e4dSAntonio Huete Jimenez 
451*de0e0e4dSAntonio Huete Jimenez 	return (0);
452*de0e0e4dSAntonio Huete Jimenez }
453*de0e0e4dSAntonio Huete Jimenez 
454*de0e0e4dSAntonio Huete Jimenez static int
cms_opt_verify_receipt(char * arg)455*de0e0e4dSAntonio Huete Jimenez cms_opt_verify_receipt(char *arg)
456*de0e0e4dSAntonio Huete Jimenez {
457*de0e0e4dSAntonio Huete Jimenez 	cms_config.operation = SMIME_VERIFY_RECEIPT;
458*de0e0e4dSAntonio Huete Jimenez 	cms_config.rctfile = arg;
459*de0e0e4dSAntonio Huete Jimenez 	return (0);
460*de0e0e4dSAntonio Huete Jimenez }
461*de0e0e4dSAntonio Huete Jimenez 
462*de0e0e4dSAntonio Huete Jimenez static const struct option cms_options[] = {
463*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_AES
464*de0e0e4dSAntonio Huete Jimenez 	{
465*de0e0e4dSAntonio Huete Jimenez 		.name = "aes128",
466*de0e0e4dSAntonio Huete Jimenez 		.desc = "Encrypt PEM output with CBC AES",
467*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
468*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_cipher,
469*de0e0e4dSAntonio Huete Jimenez 	},
470*de0e0e4dSAntonio Huete Jimenez 	{
471*de0e0e4dSAntonio Huete Jimenez 		.name = "aes192",
472*de0e0e4dSAntonio Huete Jimenez 		.desc = "Encrypt PEM output with CBC AES",
473*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
474*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_cipher,
475*de0e0e4dSAntonio Huete Jimenez 	},
476*de0e0e4dSAntonio Huete Jimenez 	{
477*de0e0e4dSAntonio Huete Jimenez 		.name = "aes256",
478*de0e0e4dSAntonio Huete Jimenez 		.desc = "Encrypt PEM output with CBC AES",
479*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
480*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_cipher,
481*de0e0e4dSAntonio Huete Jimenez 	},
482*de0e0e4dSAntonio Huete Jimenez #endif
483*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_CAMELLIA
484*de0e0e4dSAntonio Huete Jimenez 	{
485*de0e0e4dSAntonio Huete Jimenez 		.name = "camellia128",
486*de0e0e4dSAntonio Huete Jimenez 		.desc = "Encrypt PEM output with CBC Camellia",
487*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
488*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_cipher,
489*de0e0e4dSAntonio Huete Jimenez 	},
490*de0e0e4dSAntonio Huete Jimenez 	{
491*de0e0e4dSAntonio Huete Jimenez 		.name = "camellia192",
492*de0e0e4dSAntonio Huete Jimenez 		.desc = "Encrypt PEM output with CBC Camellia",
493*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
494*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_cipher,
495*de0e0e4dSAntonio Huete Jimenez 	},
496*de0e0e4dSAntonio Huete Jimenez 	{
497*de0e0e4dSAntonio Huete Jimenez 		.name = "camellia256",
498*de0e0e4dSAntonio Huete Jimenez 		.desc = "Encrypt PEM output with CBC Camellia",
499*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
500*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_cipher,
501*de0e0e4dSAntonio Huete Jimenez 	},
502*de0e0e4dSAntonio Huete Jimenez #endif
503*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DES
504*de0e0e4dSAntonio Huete Jimenez 	{
505*de0e0e4dSAntonio Huete Jimenez 		.name = "des",
506*de0e0e4dSAntonio Huete Jimenez 		.desc = "Encrypt with DES",
507*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
508*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_cipher,
509*de0e0e4dSAntonio Huete Jimenez 	},
510*de0e0e4dSAntonio Huete Jimenez 	{
511*de0e0e4dSAntonio Huete Jimenez 		.name = "des3",
512*de0e0e4dSAntonio Huete Jimenez 		.desc = "Encrypt with triple DES (default)",
513*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
514*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_cipher,
515*de0e0e4dSAntonio Huete Jimenez 	},
516*de0e0e4dSAntonio Huete Jimenez #endif
517*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_RC2
518*de0e0e4dSAntonio Huete Jimenez 	{
519*de0e0e4dSAntonio Huete Jimenez 		.name = "rc2-40",
520*de0e0e4dSAntonio Huete Jimenez 		.desc = "Encrypt with RC2-40",
521*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
522*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_cipher,
523*de0e0e4dSAntonio Huete Jimenez 	},
524*de0e0e4dSAntonio Huete Jimenez 	{
525*de0e0e4dSAntonio Huete Jimenez 		.name = "rc2-64",
526*de0e0e4dSAntonio Huete Jimenez 		.desc = "Encrypt with RC2-64",
527*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
528*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_cipher,
529*de0e0e4dSAntonio Huete Jimenez 	},
530*de0e0e4dSAntonio Huete Jimenez 	{
531*de0e0e4dSAntonio Huete Jimenez 		.name = "rc2-128",
532*de0e0e4dSAntonio Huete Jimenez 		.desc = "Encrypt with RC2-128",
533*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
534*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_cipher,
535*de0e0e4dSAntonio Huete Jimenez 	},
536*de0e0e4dSAntonio Huete Jimenez #endif
537*de0e0e4dSAntonio Huete Jimenez 	{
538*de0e0e4dSAntonio Huete Jimenez 		.name = "CAfile",
539*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
540*de0e0e4dSAntonio Huete Jimenez 		.desc = "Certificate Authority file",
541*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
542*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &cms_config.CAfile,
543*de0e0e4dSAntonio Huete Jimenez 	},
544*de0e0e4dSAntonio Huete Jimenez 	{
545*de0e0e4dSAntonio Huete Jimenez 		.name = "CApath",
546*de0e0e4dSAntonio Huete Jimenez 		.argname = "path",
547*de0e0e4dSAntonio Huete Jimenez 		.desc = "Certificate Authority path",
548*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
549*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &cms_config.CApath,
550*de0e0e4dSAntonio Huete Jimenez 	},
551*de0e0e4dSAntonio Huete Jimenez 	{
552*de0e0e4dSAntonio Huete Jimenez 		.name = "binary",
553*de0e0e4dSAntonio Huete Jimenez 		.desc = "Do not translate message to text",
554*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
555*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
556*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_BINARY,
557*de0e0e4dSAntonio Huete Jimenez 	},
558*de0e0e4dSAntonio Huete Jimenez 	{
559*de0e0e4dSAntonio Huete Jimenez 		.name = "certfile",
560*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
561*de0e0e4dSAntonio Huete Jimenez 		.desc = "Other certificates file",
562*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
563*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &cms_config.certfile,
564*de0e0e4dSAntonio Huete Jimenez 	},
565*de0e0e4dSAntonio Huete Jimenez 	{
566*de0e0e4dSAntonio Huete Jimenez 		.name = "certsout",
567*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
568*de0e0e4dSAntonio Huete Jimenez 		.desc = "Certificate output file",
569*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
570*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &cms_config.certsoutfile,
571*de0e0e4dSAntonio Huete Jimenez 	},
572*de0e0e4dSAntonio Huete Jimenez 	{
573*de0e0e4dSAntonio Huete Jimenez 		.name = "cmsout",
574*de0e0e4dSAntonio Huete Jimenez 		.desc = "Output CMS structure",
575*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
576*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
577*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_CMSOUT,
578*de0e0e4dSAntonio Huete Jimenez 	},
579*de0e0e4dSAntonio Huete Jimenez 	{
580*de0e0e4dSAntonio Huete Jimenez 		.name = "compress",
581*de0e0e4dSAntonio Huete Jimenez 		.desc = "Create CMS CompressedData type",
582*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
583*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
584*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_COMPRESS,
585*de0e0e4dSAntonio Huete Jimenez 	},
586*de0e0e4dSAntonio Huete Jimenez 	{
587*de0e0e4dSAntonio Huete Jimenez 		.name = "content",
588*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
589*de0e0e4dSAntonio Huete Jimenez 		.desc = "Supply or override content for detached signature",
590*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
591*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &cms_config.contfile,
592*de0e0e4dSAntonio Huete Jimenez 	},
593*de0e0e4dSAntonio Huete Jimenez 	{
594*de0e0e4dSAntonio Huete Jimenez 		.name = "crlfeol",
595*de0e0e4dSAntonio Huete Jimenez 		.desc = "Use CRLF as EOL termination instead of CR only",
596*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
597*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
598*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_CRLFEOL,
599*de0e0e4dSAntonio Huete Jimenez 	},
600*de0e0e4dSAntonio Huete Jimenez 	{
601*de0e0e4dSAntonio Huete Jimenez 		.name = "data_create",
602*de0e0e4dSAntonio Huete Jimenez 		.desc = "Create CMS Data type",
603*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
604*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
605*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_DATA_CREATE,
606*de0e0e4dSAntonio Huete Jimenez 	},
607*de0e0e4dSAntonio Huete Jimenez 	{
608*de0e0e4dSAntonio Huete Jimenez 		.name = "data_out",
609*de0e0e4dSAntonio Huete Jimenez 		.desc = "Output content from the input CMS Data type",
610*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
611*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
612*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_DATAOUT,
613*de0e0e4dSAntonio Huete Jimenez 	},
614*de0e0e4dSAntonio Huete Jimenez 	{
615*de0e0e4dSAntonio Huete Jimenez 		.name = "debug_decrypt",
616*de0e0e4dSAntonio Huete Jimenez 		.desc = "Set the CMS_DEBUG_DECRYPT flag when decrypting",
617*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
618*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
619*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_DEBUG_DECRYPT,
620*de0e0e4dSAntonio Huete Jimenez 	},
621*de0e0e4dSAntonio Huete Jimenez 	{
622*de0e0e4dSAntonio Huete Jimenez 		.name = "decrypt",
623*de0e0e4dSAntonio Huete Jimenez 		.desc = "Decrypt encrypted message",
624*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
625*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
626*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_DECRYPT,
627*de0e0e4dSAntonio Huete Jimenez 	},
628*de0e0e4dSAntonio Huete Jimenez 	{
629*de0e0e4dSAntonio Huete Jimenez 		.name = "digest_create",
630*de0e0e4dSAntonio Huete Jimenez 		.desc = "Create CMS DigestedData type",
631*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
632*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
633*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_DIGEST_CREATE,
634*de0e0e4dSAntonio Huete Jimenez 	},
635*de0e0e4dSAntonio Huete Jimenez 	{
636*de0e0e4dSAntonio Huete Jimenez 		.name = "digest_verify",
637*de0e0e4dSAntonio Huete Jimenez 		.desc = "Verify CMS DigestedData type and output the content",
638*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
639*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
640*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_DIGEST_VERIFY,
641*de0e0e4dSAntonio Huete Jimenez 	},
642*de0e0e4dSAntonio Huete Jimenez 	{
643*de0e0e4dSAntonio Huete Jimenez 		.name = "econtent_type",
644*de0e0e4dSAntonio Huete Jimenez 		.argname = "type",
645*de0e0e4dSAntonio Huete Jimenez 		.desc = "Set the encapsulated content type",
646*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
647*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = cms_opt_econtent_type,
648*de0e0e4dSAntonio Huete Jimenez 	},
649*de0e0e4dSAntonio Huete Jimenez 	{
650*de0e0e4dSAntonio Huete Jimenez 		.name = "encrypt",
651*de0e0e4dSAntonio Huete Jimenez 		.desc = "Encrypt message",
652*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
653*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
654*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_ENCRYPT,
655*de0e0e4dSAntonio Huete Jimenez 	},
656*de0e0e4dSAntonio Huete Jimenez 	{
657*de0e0e4dSAntonio Huete Jimenez 		.name = "EncryptedData_decrypt",
658*de0e0e4dSAntonio Huete Jimenez 		.desc = "Decrypt CMS EncryptedData",
659*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
660*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
661*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_ENCRYPTED_DECRYPT,
662*de0e0e4dSAntonio Huete Jimenez 	},
663*de0e0e4dSAntonio Huete Jimenez 	{
664*de0e0e4dSAntonio Huete Jimenez 		.name = "EncryptedData_encrypt",
665*de0e0e4dSAntonio Huete Jimenez 		.desc = "Encrypt content using supplied symmetric key and algorithm",
666*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
667*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
668*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_ENCRYPTED_ENCRYPT,
669*de0e0e4dSAntonio Huete Jimenez 	},
670*de0e0e4dSAntonio Huete Jimenez 	{
671*de0e0e4dSAntonio Huete Jimenez 		.name = "from",
672*de0e0e4dSAntonio Huete Jimenez 		.argname = "addr",
673*de0e0e4dSAntonio Huete Jimenez 		.desc = "From address",
674*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
675*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &cms_config.from,
676*de0e0e4dSAntonio Huete Jimenez 	},
677*de0e0e4dSAntonio Huete Jimenez 	{
678*de0e0e4dSAntonio Huete Jimenez 		.name = "in",
679*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
680*de0e0e4dSAntonio Huete Jimenez 		.desc = "Input file",
681*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
682*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &cms_config.infile,
683*de0e0e4dSAntonio Huete Jimenez 	},
684*de0e0e4dSAntonio Huete Jimenez 	{
685*de0e0e4dSAntonio Huete Jimenez 		.name = "indef",
686*de0e0e4dSAntonio Huete Jimenez 		.desc = "Same as -stream",
687*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
688*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
689*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_STREAM,
690*de0e0e4dSAntonio Huete Jimenez 	},
691*de0e0e4dSAntonio Huete Jimenez 	{
692*de0e0e4dSAntonio Huete Jimenez 		.name = "inform",
693*de0e0e4dSAntonio Huete Jimenez 		.argname = "fmt",
694*de0e0e4dSAntonio Huete Jimenez 		.desc = "Input format (DER, PEM or SMIME (default))",
695*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FORMAT,
696*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.informat,
697*de0e0e4dSAntonio Huete Jimenez 	},
698*de0e0e4dSAntonio Huete Jimenez 	{
699*de0e0e4dSAntonio Huete Jimenez 		.name = "inkey",
700*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
701*de0e0e4dSAntonio Huete Jimenez 		.desc = "Input key file",
702*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
703*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = cms_opt_inkey,
704*de0e0e4dSAntonio Huete Jimenez 	},
705*de0e0e4dSAntonio Huete Jimenez 	{
706*de0e0e4dSAntonio Huete Jimenez 		.name = "keyform",
707*de0e0e4dSAntonio Huete Jimenez 		.argname = "fmt",
708*de0e0e4dSAntonio Huete Jimenez 		.desc = "Input key format (DER or PEM (default))",
709*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FORMAT,
710*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.keyform,
711*de0e0e4dSAntonio Huete Jimenez 	},
712*de0e0e4dSAntonio Huete Jimenez 	{
713*de0e0e4dSAntonio Huete Jimenez 		.name = "keyid",
714*de0e0e4dSAntonio Huete Jimenez 		.desc = "Use subject key identifier",
715*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
716*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
717*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_USE_KEYID,
718*de0e0e4dSAntonio Huete Jimenez 	},
719*de0e0e4dSAntonio Huete Jimenez 	{
720*de0e0e4dSAntonio Huete Jimenez 		.name = "keyopt",
721*de0e0e4dSAntonio Huete Jimenez 		.argname = "nm:v",
722*de0e0e4dSAntonio Huete Jimenez 		.desc = "Set public key parameters",
723*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
724*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = cms_opt_keyopt,
725*de0e0e4dSAntonio Huete Jimenez 	},
726*de0e0e4dSAntonio Huete Jimenez 	{
727*de0e0e4dSAntonio Huete Jimenez 		.name = "md",
728*de0e0e4dSAntonio Huete Jimenez 		.argname = "digest",
729*de0e0e4dSAntonio Huete Jimenez 		.desc = "Digest to use when signing or resigning",
730*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
731*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = cms_opt_md,
732*de0e0e4dSAntonio Huete Jimenez 	},
733*de0e0e4dSAntonio Huete Jimenez 	{
734*de0e0e4dSAntonio Huete Jimenez 		.name = "no_attr_verify",
735*de0e0e4dSAntonio Huete Jimenez 		.desc = "Do not verify the signer's attribute of a signature",
736*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
737*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
738*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_NO_ATTR_VERIFY,
739*de0e0e4dSAntonio Huete Jimenez 	},
740*de0e0e4dSAntonio Huete Jimenez 	{
741*de0e0e4dSAntonio Huete Jimenez 		.name = "no_content_verify",
742*de0e0e4dSAntonio Huete Jimenez 		.desc = "Do not verify the content of a signed message",
743*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
744*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
745*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_NO_CONTENT_VERIFY,
746*de0e0e4dSAntonio Huete Jimenez 	},
747*de0e0e4dSAntonio Huete Jimenez 	{
748*de0e0e4dSAntonio Huete Jimenez 		.name = "no_signer_cert_verify",
749*de0e0e4dSAntonio Huete Jimenez 		.desc = "Do not verify the signer's certificate",
750*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
751*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
752*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_NO_SIGNER_CERT_VERIFY,
753*de0e0e4dSAntonio Huete Jimenez 	},
754*de0e0e4dSAntonio Huete Jimenez 	{
755*de0e0e4dSAntonio Huete Jimenez 		.name = "noattr",
756*de0e0e4dSAntonio Huete Jimenez 		.desc = "Do not include any signed attributes",
757*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
758*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
759*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_NOATTR,
760*de0e0e4dSAntonio Huete Jimenez 	},
761*de0e0e4dSAntonio Huete Jimenez 	{
762*de0e0e4dSAntonio Huete Jimenez 		.name = "nocerts",
763*de0e0e4dSAntonio Huete Jimenez 		.desc = "Do not include signer's certificate when signing",
764*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
765*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
766*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_NOCERTS,
767*de0e0e4dSAntonio Huete Jimenez 	},
768*de0e0e4dSAntonio Huete Jimenez 	{
769*de0e0e4dSAntonio Huete Jimenez 		.name = "nodetach",
770*de0e0e4dSAntonio Huete Jimenez 		.desc = "Use opaque signing",
771*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_AND,
772*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
773*de0e0e4dSAntonio Huete Jimenez 		.value = ~CMS_DETACHED,
774*de0e0e4dSAntonio Huete Jimenez 	},
775*de0e0e4dSAntonio Huete Jimenez 	{
776*de0e0e4dSAntonio Huete Jimenez 		.name = "noindef",
777*de0e0e4dSAntonio Huete Jimenez 		.desc = "Disable CMS streaming",
778*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_AND,
779*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
780*de0e0e4dSAntonio Huete Jimenez 		.value = ~CMS_STREAM,
781*de0e0e4dSAntonio Huete Jimenez 	},
782*de0e0e4dSAntonio Huete Jimenez 	{
783*de0e0e4dSAntonio Huete Jimenez 		.name = "nointern",
784*de0e0e4dSAntonio Huete Jimenez 		.desc = "Do not search certificates in message for signer",
785*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
786*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
787*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_NOINTERN,
788*de0e0e4dSAntonio Huete Jimenez 	},
789*de0e0e4dSAntonio Huete Jimenez 	{
790*de0e0e4dSAntonio Huete Jimenez 		.name = "nooldmime",
791*de0e0e4dSAntonio Huete Jimenez 		.desc = "Output old S/MIME content type",
792*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
793*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
794*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_NOOLDMIMETYPE,
795*de0e0e4dSAntonio Huete Jimenez 	},
796*de0e0e4dSAntonio Huete Jimenez 	{
797*de0e0e4dSAntonio Huete Jimenez 		.name = "noout",
798*de0e0e4dSAntonio Huete Jimenez 		.desc = "Do not output the parsed CMS structure",
799*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_FLAG,
800*de0e0e4dSAntonio Huete Jimenez 		.opt.flag = &cms_config.noout,
801*de0e0e4dSAntonio Huete Jimenez 	},
802*de0e0e4dSAntonio Huete Jimenez 	{
803*de0e0e4dSAntonio Huete Jimenez 		.name = "nosigs",
804*de0e0e4dSAntonio Huete Jimenez 		.desc = "Do not verify message signature",
805*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
806*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
807*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_NOSIGS,
808*de0e0e4dSAntonio Huete Jimenez 	},
809*de0e0e4dSAntonio Huete Jimenez 	{
810*de0e0e4dSAntonio Huete Jimenez 		.name = "nosmimecap",
811*de0e0e4dSAntonio Huete Jimenez 		.desc = "Omit the SMIMECapabilities attribute",
812*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
813*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
814*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_NOSMIMECAP,
815*de0e0e4dSAntonio Huete Jimenez 	},
816*de0e0e4dSAntonio Huete Jimenez 	{
817*de0e0e4dSAntonio Huete Jimenez 		.name = "noverify",
818*de0e0e4dSAntonio Huete Jimenez 		.desc = "Do not verify signer's certificate",
819*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
820*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
821*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_NO_SIGNER_CERT_VERIFY,
822*de0e0e4dSAntonio Huete Jimenez 	},
823*de0e0e4dSAntonio Huete Jimenez 	{
824*de0e0e4dSAntonio Huete Jimenez 		.name = "out",
825*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
826*de0e0e4dSAntonio Huete Jimenez 		.desc = "Output file",
827*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
828*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &cms_config.outfile,
829*de0e0e4dSAntonio Huete Jimenez 	},
830*de0e0e4dSAntonio Huete Jimenez 	{
831*de0e0e4dSAntonio Huete Jimenez 		.name = "outform",
832*de0e0e4dSAntonio Huete Jimenez 		.argname = "fmt",
833*de0e0e4dSAntonio Huete Jimenez 		.desc = "Output format (DER, PEM or SMIME (default))",
834*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FORMAT,
835*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.outformat,
836*de0e0e4dSAntonio Huete Jimenez 	},
837*de0e0e4dSAntonio Huete Jimenez 	{
838*de0e0e4dSAntonio Huete Jimenez 		.name = "passin",
839*de0e0e4dSAntonio Huete Jimenez 		.argname = "src",
840*de0e0e4dSAntonio Huete Jimenez 		.desc = "Private key password source",
841*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
842*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &cms_config.passargin,
843*de0e0e4dSAntonio Huete Jimenez 	},
844*de0e0e4dSAntonio Huete Jimenez 	{
845*de0e0e4dSAntonio Huete Jimenez 		.name = "print",
846*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print out all fields of the CMS structure for the -cmsout",
847*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_FUNC,
848*de0e0e4dSAntonio Huete Jimenez 		.opt.func = cms_opt_print,
849*de0e0e4dSAntonio Huete Jimenez 	},
850*de0e0e4dSAntonio Huete Jimenez 	{
851*de0e0e4dSAntonio Huete Jimenez 		.name = "pwri_password",
852*de0e0e4dSAntonio Huete Jimenez 		.argname = "arg",
853*de0e0e4dSAntonio Huete Jimenez 		.desc = "Specify PasswordRecipientInfo (PWRI) password to use",
854*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
855*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = cms_opt_pwri_pass,
856*de0e0e4dSAntonio Huete Jimenez 	},
857*de0e0e4dSAntonio Huete Jimenez 	{
858*de0e0e4dSAntonio Huete Jimenez 		.name = "rctform",
859*de0e0e4dSAntonio Huete Jimenez 		.argname = "fmt",
860*de0e0e4dSAntonio Huete Jimenez 		.desc = "Receipt file format (DER, PEM or SMIME (default))",
861*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FORMAT,
862*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.rctformat,
863*de0e0e4dSAntonio Huete Jimenez 	},
864*de0e0e4dSAntonio Huete Jimenez 	{
865*de0e0e4dSAntonio Huete Jimenez 		.name = "receipt_request_all",
866*de0e0e4dSAntonio Huete Jimenez 		.desc = "Indicate requests should be provided by all recipients",
867*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
868*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.rr_allorfirst,
869*de0e0e4dSAntonio Huete Jimenez 		.value = 0,
870*de0e0e4dSAntonio Huete Jimenez 	},
871*de0e0e4dSAntonio Huete Jimenez 	{
872*de0e0e4dSAntonio Huete Jimenez 		.name = "receipt_request_first",
873*de0e0e4dSAntonio Huete Jimenez 		.desc = "Indicate requests should be provided by first tier recipient",
874*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
875*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.rr_allorfirst,
876*de0e0e4dSAntonio Huete Jimenez 		.value = 1,
877*de0e0e4dSAntonio Huete Jimenez 	},
878*de0e0e4dSAntonio Huete Jimenez 	{
879*de0e0e4dSAntonio Huete Jimenez 		.name = "receipt_request_from",
880*de0e0e4dSAntonio Huete Jimenez 		.argname = "addr",
881*de0e0e4dSAntonio Huete Jimenez 		.desc = "Add explicit email address where receipts should be supplied",
882*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
883*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = cms_opt_receipt_request_from,
884*de0e0e4dSAntonio Huete Jimenez 	},
885*de0e0e4dSAntonio Huete Jimenez 	{
886*de0e0e4dSAntonio Huete Jimenez 		.name = "receipt_request_print",
887*de0e0e4dSAntonio Huete Jimenez 		.desc = "Print out the contents of any signed receipt requests",
888*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_FLAG,
889*de0e0e4dSAntonio Huete Jimenez 		.opt.flag = &cms_config.rr_print,
890*de0e0e4dSAntonio Huete Jimenez 	},
891*de0e0e4dSAntonio Huete Jimenez 	{
892*de0e0e4dSAntonio Huete Jimenez 		.name = "receipt_request_to",
893*de0e0e4dSAntonio Huete Jimenez 		.argname = "addr",
894*de0e0e4dSAntonio Huete Jimenez 		.desc = "Add explicit email address where receipts should be sent to",
895*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
896*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = cms_opt_receipt_request_to,
897*de0e0e4dSAntonio Huete Jimenez 	},
898*de0e0e4dSAntonio Huete Jimenez 	{
899*de0e0e4dSAntonio Huete Jimenez 		.name = "recip",
900*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
901*de0e0e4dSAntonio Huete Jimenez 		.desc = "Recipient certificate file for decryption",
902*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
903*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = cms_opt_recip,
904*de0e0e4dSAntonio Huete Jimenez 	},
905*de0e0e4dSAntonio Huete Jimenez 	{
906*de0e0e4dSAntonio Huete Jimenez 		.name = "resign",
907*de0e0e4dSAntonio Huete Jimenez 		.desc = "Resign a signed message",
908*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
909*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
910*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_RESIGN,
911*de0e0e4dSAntonio Huete Jimenez 	},
912*de0e0e4dSAntonio Huete Jimenez 	{
913*de0e0e4dSAntonio Huete Jimenez 		.name = "secretkey",
914*de0e0e4dSAntonio Huete Jimenez 		.argname = "key",
915*de0e0e4dSAntonio Huete Jimenez 		.desc = "Specify symmetric key to use",
916*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
917*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = cms_opt_secretkey,
918*de0e0e4dSAntonio Huete Jimenez 	},
919*de0e0e4dSAntonio Huete Jimenez 	{
920*de0e0e4dSAntonio Huete Jimenez 		.name = "secretkeyid",
921*de0e0e4dSAntonio Huete Jimenez 		.argname = "id",
922*de0e0e4dSAntonio Huete Jimenez 		.desc = "The key identifier for the supplied symmetric key",
923*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
924*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = cms_opt_secretkeyid,
925*de0e0e4dSAntonio Huete Jimenez 	},
926*de0e0e4dSAntonio Huete Jimenez 	{
927*de0e0e4dSAntonio Huete Jimenez 		.name = "sign",
928*de0e0e4dSAntonio Huete Jimenez 		.desc = "Sign message",
929*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
930*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
931*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_SIGN,
932*de0e0e4dSAntonio Huete Jimenez 	},
933*de0e0e4dSAntonio Huete Jimenez 	{
934*de0e0e4dSAntonio Huete Jimenez 		.name = "sign_receipt",
935*de0e0e4dSAntonio Huete Jimenez 		.desc = "Generate a signed receipt for the message",
936*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
937*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
938*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_SIGN_RECEIPT,
939*de0e0e4dSAntonio Huete Jimenez 	},
940*de0e0e4dSAntonio Huete Jimenez 	{
941*de0e0e4dSAntonio Huete Jimenez 		.name = "signer",
942*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
943*de0e0e4dSAntonio Huete Jimenez 		.desc = "Signer certificate file",
944*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
945*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = cms_opt_signer,
946*de0e0e4dSAntonio Huete Jimenez 	},
947*de0e0e4dSAntonio Huete Jimenez 	{
948*de0e0e4dSAntonio Huete Jimenez 		.name = "stream",
949*de0e0e4dSAntonio Huete Jimenez 		.desc = "Enable CMS streaming",
950*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
951*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
952*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_STREAM,
953*de0e0e4dSAntonio Huete Jimenez 	},
954*de0e0e4dSAntonio Huete Jimenez 	{
955*de0e0e4dSAntonio Huete Jimenez 		.name = "subject",
956*de0e0e4dSAntonio Huete Jimenez 		.argname = "s",
957*de0e0e4dSAntonio Huete Jimenez 		.desc = "Subject",
958*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
959*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &cms_config.subject,
960*de0e0e4dSAntonio Huete Jimenez 	},
961*de0e0e4dSAntonio Huete Jimenez 	{
962*de0e0e4dSAntonio Huete Jimenez 		.name = "text",
963*de0e0e4dSAntonio Huete Jimenez 		.desc = "Include or delete text MIME headers",
964*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE_OR,
965*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.flags,
966*de0e0e4dSAntonio Huete Jimenez 		.value = CMS_TEXT,
967*de0e0e4dSAntonio Huete Jimenez 	},
968*de0e0e4dSAntonio Huete Jimenez 	{
969*de0e0e4dSAntonio Huete Jimenez 		.name = "to",
970*de0e0e4dSAntonio Huete Jimenez 		.argname = "addr",
971*de0e0e4dSAntonio Huete Jimenez 		.desc = "To address",
972*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG,
973*de0e0e4dSAntonio Huete Jimenez 		.opt.arg = &cms_config.to,
974*de0e0e4dSAntonio Huete Jimenez 	},
975*de0e0e4dSAntonio Huete Jimenez 	{
976*de0e0e4dSAntonio Huete Jimenez 		.name = "uncompress",
977*de0e0e4dSAntonio Huete Jimenez 		.desc = "Uncompress CMS CompressedData type",
978*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
979*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
980*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_UNCOMPRESS,
981*de0e0e4dSAntonio Huete Jimenez 	},
982*de0e0e4dSAntonio Huete Jimenez 	{
983*de0e0e4dSAntonio Huete Jimenez 		.name = "verify",
984*de0e0e4dSAntonio Huete Jimenez 		.desc = "Verify signed message",
985*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_VALUE,
986*de0e0e4dSAntonio Huete Jimenez 		.opt.value = &cms_config.operation,
987*de0e0e4dSAntonio Huete Jimenez 		.value = SMIME_VERIFY,
988*de0e0e4dSAntonio Huete Jimenez 	},
989*de0e0e4dSAntonio Huete Jimenez 	{
990*de0e0e4dSAntonio Huete Jimenez 		.name = "verify_receipt",
991*de0e0e4dSAntonio Huete Jimenez 		.argname = "file",
992*de0e0e4dSAntonio Huete Jimenez 		.desc = "Verify a signed receipt in file",
993*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARG_FUNC,
994*de0e0e4dSAntonio Huete Jimenez 		.opt.argfunc = cms_opt_verify_receipt,
995*de0e0e4dSAntonio Huete Jimenez 	},
996*de0e0e4dSAntonio Huete Jimenez 	{
997*de0e0e4dSAntonio Huete Jimenez 		.name = "verify_retcode",
998*de0e0e4dSAntonio Huete Jimenez 		.desc = "Set verification error code to exit code",
999*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_FLAG,
1000*de0e0e4dSAntonio Huete Jimenez 		.opt.flag = &cms_config.verify_retcode,
1001*de0e0e4dSAntonio Huete Jimenez 	},
1002*de0e0e4dSAntonio Huete Jimenez 	{
1003*de0e0e4dSAntonio Huete Jimenez 		.name = "check_ss_sig",
1004*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
1005*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_verify_param,
1006*de0e0e4dSAntonio Huete Jimenez 	},
1007*de0e0e4dSAntonio Huete Jimenez 	{
1008*de0e0e4dSAntonio Huete Jimenez 		.name = "crl_check",
1009*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
1010*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_verify_param,
1011*de0e0e4dSAntonio Huete Jimenez 	},
1012*de0e0e4dSAntonio Huete Jimenez 	{
1013*de0e0e4dSAntonio Huete Jimenez 		.name = "crl_check_all",
1014*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
1015*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_verify_param,
1016*de0e0e4dSAntonio Huete Jimenez 	},
1017*de0e0e4dSAntonio Huete Jimenez 	{
1018*de0e0e4dSAntonio Huete Jimenez 		.name = "extended_crl",
1019*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
1020*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_verify_param,
1021*de0e0e4dSAntonio Huete Jimenez 	},
1022*de0e0e4dSAntonio Huete Jimenez 	{
1023*de0e0e4dSAntonio Huete Jimenez 		.name = "ignore_critical",
1024*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
1025*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_verify_param,
1026*de0e0e4dSAntonio Huete Jimenez 	},
1027*de0e0e4dSAntonio Huete Jimenez 	{
1028*de0e0e4dSAntonio Huete Jimenez 		.name = "issuer_checks",
1029*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
1030*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_verify_param,
1031*de0e0e4dSAntonio Huete Jimenez 	},
1032*de0e0e4dSAntonio Huete Jimenez 	{
1033*de0e0e4dSAntonio Huete Jimenez 		.name = "policy",
1034*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
1035*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_verify_param,
1036*de0e0e4dSAntonio Huete Jimenez 	},
1037*de0e0e4dSAntonio Huete Jimenez 	{
1038*de0e0e4dSAntonio Huete Jimenez 		.name = "policy_check",
1039*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
1040*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_verify_param,
1041*de0e0e4dSAntonio Huete Jimenez 	},
1042*de0e0e4dSAntonio Huete Jimenez 	{
1043*de0e0e4dSAntonio Huete Jimenez 		.name = "purpose",
1044*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
1045*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_verify_param,
1046*de0e0e4dSAntonio Huete Jimenez 	},
1047*de0e0e4dSAntonio Huete Jimenez 	{
1048*de0e0e4dSAntonio Huete Jimenez 		.name = "x509_strict",
1049*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
1050*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_verify_param,
1051*de0e0e4dSAntonio Huete Jimenez 	},
1052*de0e0e4dSAntonio Huete Jimenez 	{
1053*de0e0e4dSAntonio Huete Jimenez 		.name = NULL,
1054*de0e0e4dSAntonio Huete Jimenez 		.type = OPTION_ARGV_FUNC,
1055*de0e0e4dSAntonio Huete Jimenez 		.opt.argvfunc = cms_opt_cipher,
1056*de0e0e4dSAntonio Huete Jimenez 	},
1057*de0e0e4dSAntonio Huete Jimenez 	{ NULL },
1058*de0e0e4dSAntonio Huete Jimenez };
1059*de0e0e4dSAntonio Huete Jimenez 
1060*de0e0e4dSAntonio Huete Jimenez static const struct option verify_shared_options[] = {
1061*de0e0e4dSAntonio Huete Jimenez 	{
1062*de0e0e4dSAntonio Huete Jimenez 		.name = "check_ss_sig",
1063*de0e0e4dSAntonio Huete Jimenez 		.desc = "Check the root CA self-signed certificate signature",
1064*de0e0e4dSAntonio Huete Jimenez 	},
1065*de0e0e4dSAntonio Huete Jimenez 	{
1066*de0e0e4dSAntonio Huete Jimenez 		.name = "crl_check",
1067*de0e0e4dSAntonio Huete Jimenez 		.desc = "Enable CRL checking for the leaf certificate",
1068*de0e0e4dSAntonio Huete Jimenez 	},
1069*de0e0e4dSAntonio Huete Jimenez 	{
1070*de0e0e4dSAntonio Huete Jimenez 		.name = "crl_check_all",
1071*de0e0e4dSAntonio Huete Jimenez 		.desc = "Enable CRL checking for the entire certificate chain",
1072*de0e0e4dSAntonio Huete Jimenez 	},
1073*de0e0e4dSAntonio Huete Jimenez 	{
1074*de0e0e4dSAntonio Huete Jimenez 		.name = "extended_crl",
1075*de0e0e4dSAntonio Huete Jimenez 		.desc = "Enable extended CRL support",
1076*de0e0e4dSAntonio Huete Jimenez 	},
1077*de0e0e4dSAntonio Huete Jimenez 	{
1078*de0e0e4dSAntonio Huete Jimenez 		.name = "ignore_critical",
1079*de0e0e4dSAntonio Huete Jimenez 		.desc = "Disable critical extension checking",
1080*de0e0e4dSAntonio Huete Jimenez 	},
1081*de0e0e4dSAntonio Huete Jimenez 	{
1082*de0e0e4dSAntonio Huete Jimenez 		.name = "issuer_checks",
1083*de0e0e4dSAntonio Huete Jimenez 		.desc = "Enable debugging of certificate issuer checks",
1084*de0e0e4dSAntonio Huete Jimenez 	},
1085*de0e0e4dSAntonio Huete Jimenez 	{
1086*de0e0e4dSAntonio Huete Jimenez 		.name = "policy",
1087*de0e0e4dSAntonio Huete Jimenez 		.argname = "name",
1088*de0e0e4dSAntonio Huete Jimenez 		.desc = "Add given policy to the acceptable set",
1089*de0e0e4dSAntonio Huete Jimenez 	},
1090*de0e0e4dSAntonio Huete Jimenez 	{
1091*de0e0e4dSAntonio Huete Jimenez 		.name = "policy_check",
1092*de0e0e4dSAntonio Huete Jimenez 		.desc = "Enable certificate policy checking",
1093*de0e0e4dSAntonio Huete Jimenez 	},
1094*de0e0e4dSAntonio Huete Jimenez 	{
1095*de0e0e4dSAntonio Huete Jimenez 		.name = "purpose",
1096*de0e0e4dSAntonio Huete Jimenez 		.argname = "name",
1097*de0e0e4dSAntonio Huete Jimenez 		.desc = "Verify for the given purpose",
1098*de0e0e4dSAntonio Huete Jimenez 	},
1099*de0e0e4dSAntonio Huete Jimenez 	{
1100*de0e0e4dSAntonio Huete Jimenez 		.name = "x509_strict",
1101*de0e0e4dSAntonio Huete Jimenez 		.desc = "Use strict X.509 rules (disables workarounds)",
1102*de0e0e4dSAntonio Huete Jimenez 	},
1103*de0e0e4dSAntonio Huete Jimenez 	{ NULL },
1104*de0e0e4dSAntonio Huete Jimenez };
1105*de0e0e4dSAntonio Huete Jimenez 
1106*de0e0e4dSAntonio Huete Jimenez static void
cms_usage(void)1107*de0e0e4dSAntonio Huete Jimenez cms_usage(void)
1108*de0e0e4dSAntonio Huete Jimenez {
1109*de0e0e4dSAntonio Huete Jimenez 	int i;
1110*de0e0e4dSAntonio Huete Jimenez 
1111*de0e0e4dSAntonio Huete Jimenez 	fprintf(stderr, "usage: cms "
1112*de0e0e4dSAntonio Huete Jimenez 	    "[-aes128 | -aes192 | -aes256 | -camellia128 |\n"
1113*de0e0e4dSAntonio Huete Jimenez 	    "    -camellia192 | -camellia256 | -des | -des3 |\n"
1114*de0e0e4dSAntonio Huete Jimenez 	    "    -rc2-40 | -rc2-64 | -rc2-128] [-CAfile file]\n"
1115*de0e0e4dSAntonio Huete Jimenez 	    "    [-CApath directory] [-binary] [-certfile file]\n"
1116*de0e0e4dSAntonio Huete Jimenez 	    "    [-certsout file] [-cmsout] [-compress] [-content file]\n"
1117*de0e0e4dSAntonio Huete Jimenez 	    "    [-crlfeol] [-data_create] [-data_out] [-debug_decrypt]\n"
1118*de0e0e4dSAntonio Huete Jimenez 	    "    [-decrypt] [-digest_create] [-digest_verify]\n"
1119*de0e0e4dSAntonio Huete Jimenez 	    "    [-econtent_type type] [-encrypt] [-EncryptedData_decrypt]\n"
1120*de0e0e4dSAntonio Huete Jimenez 	    "    [-EncryptedData_encrypt] [-from addr] [-in file]\n"
1121*de0e0e4dSAntonio Huete Jimenez 	    "    [-inform der | pem | smime] [-inkey file]\n"
1122*de0e0e4dSAntonio Huete Jimenez 	    "    [-keyform der | pem] [-keyid] [-keyopt nm:v] [-md digest]\n"
1123*de0e0e4dSAntonio Huete Jimenez 	    "    [-no_attr_verify] [-no_content_verify]\n"
1124*de0e0e4dSAntonio Huete Jimenez 	    "    [-no_signer_cert_verify] [-noattr] [-nocerts] [-nodetach]\n"
1125*de0e0e4dSAntonio Huete Jimenez 	    "    [-nointern] [-nooldmime] [-noout] [-nosigs] [-nosmimecap]\n"
1126*de0e0e4dSAntonio Huete Jimenez 	    "    [-noverify] [-out file] [-outform der | pem | smime]\n"
1127*de0e0e4dSAntonio Huete Jimenez 	    "    [-passin src] [-print] [-pwri_password arg]\n"
1128*de0e0e4dSAntonio Huete Jimenez 	    "    [-rctform der | pem | smime]\n"
1129*de0e0e4dSAntonio Huete Jimenez 	    "    [-receipt_request_all | -receipt_request_first]\n"
1130*de0e0e4dSAntonio Huete Jimenez 	    "    [-receipt_request_from addr] [-receipt_request_print]\n"
1131*de0e0e4dSAntonio Huete Jimenez 	    "    [-receipt_request_to addr] [-recip file] [-resign]\n"
1132*de0e0e4dSAntonio Huete Jimenez 	    "    [-secretkey key] [-secretkeyid id] [-sign] [-sign_receipt]\n"
1133*de0e0e4dSAntonio Huete Jimenez 	    "    [-signer file] [-stream | -indef | -noindef] [-subject s]\n"
1134*de0e0e4dSAntonio Huete Jimenez 	    "    [-text] [-to addr] [-uncompress] [-verify]\n"
1135*de0e0e4dSAntonio Huete Jimenez 	    "    [-verify_receipt file] [-verify_retcode] [cert.pem ...]\n\n");
1136*de0e0e4dSAntonio Huete Jimenez 
1137*de0e0e4dSAntonio Huete Jimenez 	options_usage(cms_options);
1138*de0e0e4dSAntonio Huete Jimenez 
1139*de0e0e4dSAntonio Huete Jimenez 	fprintf(stderr, "\nVerification options:\n\n");
1140*de0e0e4dSAntonio Huete Jimenez 	options_usage(verify_shared_options);
1141*de0e0e4dSAntonio Huete Jimenez 
1142*de0e0e4dSAntonio Huete Jimenez 	fprintf(stderr, "\nValid purposes:\n\n");
1143*de0e0e4dSAntonio Huete Jimenez 	for (i = 0; i < X509_PURPOSE_get_count(); i++) {
1144*de0e0e4dSAntonio Huete Jimenez 		X509_PURPOSE *ptmp = X509_PURPOSE_get0(i);
1145*de0e0e4dSAntonio Huete Jimenez 		fprintf(stderr, "  %-18s%s\n", X509_PURPOSE_get0_sname(ptmp),
1146*de0e0e4dSAntonio Huete Jimenez 		    X509_PURPOSE_get0_name(ptmp));
1147*de0e0e4dSAntonio Huete Jimenez 	}
1148*de0e0e4dSAntonio Huete Jimenez }
1149*de0e0e4dSAntonio Huete Jimenez 
1150cca6fc52SDaniel Fojt int
cms_main(int argc,char ** argv)1151cca6fc52SDaniel Fojt cms_main(int argc, char **argv)
1152cca6fc52SDaniel Fojt {
1153cca6fc52SDaniel Fojt 	int ret = 0;
1154cca6fc52SDaniel Fojt 	char **args;
1155*de0e0e4dSAntonio Huete Jimenez 	int argsused = 0;
1156cca6fc52SDaniel Fojt 	const char *inmode = "r", *outmode = "w";
1157cca6fc52SDaniel Fojt 	CMS_ContentInfo *cms = NULL, *rcms = NULL;
1158cca6fc52SDaniel Fojt 	X509_STORE *store = NULL;
1159*de0e0e4dSAntonio Huete Jimenez 	X509 *recip = NULL, *signer = NULL;
1160cca6fc52SDaniel Fojt 	EVP_PKEY *key = NULL;
1161*de0e0e4dSAntonio Huete Jimenez 	STACK_OF(X509) *other = NULL;
1162cca6fc52SDaniel Fojt 	BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
1163cca6fc52SDaniel Fojt 	int badarg = 0;
1164cca6fc52SDaniel Fojt 	CMS_ReceiptRequest *rr = NULL;
1165*de0e0e4dSAntonio Huete Jimenez 	char *passin = NULL;
1166*de0e0e4dSAntonio Huete Jimenez 	unsigned char *pwri_tmp = NULL;
1167cca6fc52SDaniel Fojt 
1168cca6fc52SDaniel Fojt 	if (single_execution) {
1169cca6fc52SDaniel Fojt 		if (pledge("stdio rpath wpath cpath tty", NULL) == -1) {
1170cca6fc52SDaniel Fojt 			perror("pledge");
1171cca6fc52SDaniel Fojt 			exit(1);
1172cca6fc52SDaniel Fojt 		}
1173cca6fc52SDaniel Fojt 	}
1174cca6fc52SDaniel Fojt 
1175*de0e0e4dSAntonio Huete Jimenez 	memset(&cms_config, 0, sizeof(cms_config));
1176*de0e0e4dSAntonio Huete Jimenez 	cms_config.flags = CMS_DETACHED;
1177*de0e0e4dSAntonio Huete Jimenez 	cms_config.rr_allorfirst = -1;
1178*de0e0e4dSAntonio Huete Jimenez 	cms_config.informat = FORMAT_SMIME;
1179*de0e0e4dSAntonio Huete Jimenez 	cms_config.outformat = FORMAT_SMIME;
1180*de0e0e4dSAntonio Huete Jimenez 	cms_config.rctformat = FORMAT_SMIME;
1181*de0e0e4dSAntonio Huete Jimenez 	cms_config.keyform = FORMAT_PEM;
1182*de0e0e4dSAntonio Huete Jimenez 	if (options_parse(argc, argv, cms_options, NULL, &argsused) != 0) {
1183*de0e0e4dSAntonio Huete Jimenez 		goto argerr;
1184*de0e0e4dSAntonio Huete Jimenez 	}
1185*de0e0e4dSAntonio Huete Jimenez 	args = argv + argsused;
1186cca6fc52SDaniel Fojt 	ret = 1;
1187cca6fc52SDaniel Fojt 
1188*de0e0e4dSAntonio Huete Jimenez 	if (((cms_config.rr_allorfirst != -1) || cms_config.rr_from != NULL) &&
1189*de0e0e4dSAntonio Huete Jimenez 	    cms_config.rr_to == NULL) {
1190cca6fc52SDaniel Fojt 		BIO_puts(bio_err, "No Signed Receipts Recipients\n");
1191cca6fc52SDaniel Fojt 		goto argerr;
1192cca6fc52SDaniel Fojt 	}
1193*de0e0e4dSAntonio Huete Jimenez 	if (!(cms_config.operation & SMIME_SIGNERS) &&
1194*de0e0e4dSAntonio Huete Jimenez 	    (cms_config.rr_to != NULL || cms_config.rr_from != NULL)) {
1195cca6fc52SDaniel Fojt 		BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
1196cca6fc52SDaniel Fojt 		goto argerr;
1197cca6fc52SDaniel Fojt 	}
1198*de0e0e4dSAntonio Huete Jimenez 	if (!(cms_config.operation & SMIME_SIGNERS) &&
1199*de0e0e4dSAntonio Huete Jimenez 	    (cms_config.skkeys != NULL || cms_config.sksigners != NULL)) {
1200cca6fc52SDaniel Fojt 		BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
1201cca6fc52SDaniel Fojt 		goto argerr;
1202cca6fc52SDaniel Fojt 	}
1203*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.operation & SMIME_SIGNERS) {
1204*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.keyfile != NULL &&
1205*de0e0e4dSAntonio Huete Jimenez 		    cms_config.signerfile == NULL) {
1206cca6fc52SDaniel Fojt 			BIO_puts(bio_err, "Illegal -inkey without -signer\n");
1207cca6fc52SDaniel Fojt 			goto argerr;
1208cca6fc52SDaniel Fojt 		}
1209cca6fc52SDaniel Fojt 		/* Check to see if any final signer needs to be appended */
1210*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.signerfile != NULL) {
1211*de0e0e4dSAntonio Huete Jimenez 			if (cms_config.sksigners == NULL &&
1212*de0e0e4dSAntonio Huete Jimenez 			    (cms_config.sksigners =
1213*de0e0e4dSAntonio Huete Jimenez 			    sk_OPENSSL_STRING_new_null()) == NULL)
1214cca6fc52SDaniel Fojt 				goto end;
1215*de0e0e4dSAntonio Huete Jimenez 			if (!sk_OPENSSL_STRING_push(cms_config.sksigners,
1216*de0e0e4dSAntonio Huete Jimenez 			    cms_config.signerfile))
1217cca6fc52SDaniel Fojt 				goto end;
1218*de0e0e4dSAntonio Huete Jimenez 			if (cms_config.skkeys == NULL &&
1219*de0e0e4dSAntonio Huete Jimenez 			    (cms_config.skkeys =
1220*de0e0e4dSAntonio Huete Jimenez 			    sk_OPENSSL_STRING_new_null()) == NULL)
1221cca6fc52SDaniel Fojt 				goto end;
1222*de0e0e4dSAntonio Huete Jimenez 			if (cms_config.keyfile == NULL)
1223*de0e0e4dSAntonio Huete Jimenez 				cms_config.keyfile = cms_config.signerfile;
1224*de0e0e4dSAntonio Huete Jimenez 			if (!sk_OPENSSL_STRING_push(cms_config.skkeys,
1225*de0e0e4dSAntonio Huete Jimenez 			    cms_config.keyfile))
1226cca6fc52SDaniel Fojt 				goto end;
1227cca6fc52SDaniel Fojt 		}
1228*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.sksigners == NULL) {
1229cca6fc52SDaniel Fojt 			BIO_printf(bio_err,
1230cca6fc52SDaniel Fojt 			    "No signer certificate specified\n");
1231cca6fc52SDaniel Fojt 			badarg = 1;
1232cca6fc52SDaniel Fojt 		}
1233*de0e0e4dSAntonio Huete Jimenez 		cms_config.signerfile = NULL;
1234*de0e0e4dSAntonio Huete Jimenez 		cms_config.keyfile = NULL;
1235*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation == SMIME_DECRYPT) {
1236*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.recipfile == NULL &&
1237*de0e0e4dSAntonio Huete Jimenez 		    cms_config.keyfile == NULL &&
1238*de0e0e4dSAntonio Huete Jimenez 		    cms_config.secret_key == NULL &&
1239*de0e0e4dSAntonio Huete Jimenez 		    cms_config.pwri_pass == NULL) {
1240cca6fc52SDaniel Fojt 			BIO_printf(bio_err,
1241cca6fc52SDaniel Fojt 			    "No recipient certificate or key specified\n");
1242cca6fc52SDaniel Fojt 			badarg = 1;
1243cca6fc52SDaniel Fojt 		}
1244*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation == SMIME_ENCRYPT) {
1245*de0e0e4dSAntonio Huete Jimenez 		if (*args == NULL && cms_config.secret_key == NULL &&
1246*de0e0e4dSAntonio Huete Jimenez 		    cms_config.pwri_pass == NULL &&
1247*de0e0e4dSAntonio Huete Jimenez 		    cms_config.encerts == NULL) {
1248cca6fc52SDaniel Fojt 			BIO_printf(bio_err,
1249cca6fc52SDaniel Fojt 			    "No recipient(s) certificate(s) specified\n");
1250cca6fc52SDaniel Fojt 			badarg = 1;
1251cca6fc52SDaniel Fojt 		}
1252*de0e0e4dSAntonio Huete Jimenez 	} else if (!cms_config.operation) {
1253cca6fc52SDaniel Fojt 		badarg = 1;
1254*de0e0e4dSAntonio Huete Jimenez 	}
1255cca6fc52SDaniel Fojt 
1256cca6fc52SDaniel Fojt 	if (badarg) {
1257cca6fc52SDaniel Fojt  argerr:
1258*de0e0e4dSAntonio Huete Jimenez 		cms_usage();
1259cca6fc52SDaniel Fojt 		goto end;
1260cca6fc52SDaniel Fojt 	}
1261cca6fc52SDaniel Fojt 
1262*de0e0e4dSAntonio Huete Jimenez 	if (!app_passwd(bio_err, cms_config.passargin, NULL, &passin, NULL)) {
1263cca6fc52SDaniel Fojt 		BIO_printf(bio_err, "Error getting password\n");
1264cca6fc52SDaniel Fojt 		goto end;
1265cca6fc52SDaniel Fojt 	}
1266cca6fc52SDaniel Fojt 	ret = 2;
1267cca6fc52SDaniel Fojt 
1268*de0e0e4dSAntonio Huete Jimenez 	if (!(cms_config.operation & SMIME_SIGNERS))
1269*de0e0e4dSAntonio Huete Jimenez 		cms_config.flags &= ~CMS_DETACHED;
1270cca6fc52SDaniel Fojt 
1271*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.operation & SMIME_OP) {
1272*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.outformat == FORMAT_ASN1)
1273cca6fc52SDaniel Fojt 			outmode = "wb";
1274cca6fc52SDaniel Fojt 	} else {
1275*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.flags & CMS_BINARY)
1276cca6fc52SDaniel Fojt 			outmode = "wb";
1277cca6fc52SDaniel Fojt 	}
1278cca6fc52SDaniel Fojt 
1279*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.operation & SMIME_IP) {
1280*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.informat == FORMAT_ASN1)
1281cca6fc52SDaniel Fojt 			inmode = "rb";
1282cca6fc52SDaniel Fojt 	} else {
1283*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.flags & CMS_BINARY)
1284cca6fc52SDaniel Fojt 			inmode = "rb";
1285cca6fc52SDaniel Fojt 	}
1286cca6fc52SDaniel Fojt 
1287*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.operation == SMIME_ENCRYPT) {
1288*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.cipher == NULL) {
1289cca6fc52SDaniel Fojt #ifndef OPENSSL_NO_DES
1290*de0e0e4dSAntonio Huete Jimenez 			cms_config.cipher = EVP_des_ede3_cbc();
1291cca6fc52SDaniel Fojt #else
1292cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "No cipher selected\n");
1293cca6fc52SDaniel Fojt 			goto end;
1294cca6fc52SDaniel Fojt #endif
1295cca6fc52SDaniel Fojt 		}
1296*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.secret_key != NULL &&
1297*de0e0e4dSAntonio Huete Jimenez 		    cms_config.secret_keyid == NULL) {
1298cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "No secret key id\n");
1299cca6fc52SDaniel Fojt 			goto end;
1300cca6fc52SDaniel Fojt 		}
1301*de0e0e4dSAntonio Huete Jimenez 		if (*args != NULL && cms_config.encerts == NULL)
1302*de0e0e4dSAntonio Huete Jimenez 			if ((cms_config.encerts = sk_X509_new_null()) == NULL)
1303cca6fc52SDaniel Fojt 				goto end;
1304cca6fc52SDaniel Fojt 		while (*args) {
1305*de0e0e4dSAntonio Huete Jimenez 			if ((cms_config.cert = load_cert(bio_err, *args,
1306*de0e0e4dSAntonio Huete Jimenez 			    FORMAT_PEM, NULL,
1307*de0e0e4dSAntonio Huete Jimenez 			    "recipient certificate file")) == NULL)
1308cca6fc52SDaniel Fojt 				goto end;
1309*de0e0e4dSAntonio Huete Jimenez 			if (!sk_X509_push(cms_config.encerts, cms_config.cert))
1310cca6fc52SDaniel Fojt 				goto end;
1311*de0e0e4dSAntonio Huete Jimenez 			cms_config.cert = NULL;
1312cca6fc52SDaniel Fojt 			args++;
1313cca6fc52SDaniel Fojt 		}
1314cca6fc52SDaniel Fojt 	}
1315*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.certfile != NULL) {
1316*de0e0e4dSAntonio Huete Jimenez 		if ((other = load_certs(bio_err, cms_config.certfile,
1317*de0e0e4dSAntonio Huete Jimenez 		    FORMAT_PEM, NULL, "certificate file")) == NULL) {
1318cca6fc52SDaniel Fojt 			ERR_print_errors(bio_err);
1319cca6fc52SDaniel Fojt 			goto end;
1320cca6fc52SDaniel Fojt 		}
1321cca6fc52SDaniel Fojt 	}
1322*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.recipfile != NULL &&
1323*de0e0e4dSAntonio Huete Jimenez 	    (cms_config.operation == SMIME_DECRYPT)) {
1324*de0e0e4dSAntonio Huete Jimenez 		if ((recip = load_cert(bio_err, cms_config.recipfile,
1325*de0e0e4dSAntonio Huete Jimenez 		    FORMAT_PEM, NULL, "recipient certificate file")) == NULL) {
1326cca6fc52SDaniel Fojt 			ERR_print_errors(bio_err);
1327cca6fc52SDaniel Fojt 			goto end;
1328cca6fc52SDaniel Fojt 		}
1329cca6fc52SDaniel Fojt 	}
1330*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.operation == SMIME_SIGN_RECEIPT) {
1331*de0e0e4dSAntonio Huete Jimenez 		if ((signer = load_cert(bio_err, cms_config.signerfile,
1332*de0e0e4dSAntonio Huete Jimenez 		    FORMAT_PEM, NULL,
1333*de0e0e4dSAntonio Huete Jimenez 		    "receipt signer certificate file")) == NULL) {
1334cca6fc52SDaniel Fojt 			ERR_print_errors(bio_err);
1335cca6fc52SDaniel Fojt 			goto end;
1336cca6fc52SDaniel Fojt 		}
1337cca6fc52SDaniel Fojt 	}
1338*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.operation == SMIME_DECRYPT) {
1339*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.keyfile == NULL)
1340*de0e0e4dSAntonio Huete Jimenez 			cms_config.keyfile = cms_config.recipfile;
1341*de0e0e4dSAntonio Huete Jimenez 	} else if ((cms_config.operation == SMIME_SIGN) ||
1342*de0e0e4dSAntonio Huete Jimenez 	    (cms_config.operation == SMIME_SIGN_RECEIPT)) {
1343*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.keyfile == NULL)
1344*de0e0e4dSAntonio Huete Jimenez 			cms_config.keyfile = cms_config.signerfile;
1345*de0e0e4dSAntonio Huete Jimenez 	} else {
1346*de0e0e4dSAntonio Huete Jimenez 		cms_config.keyfile = NULL;
1347*de0e0e4dSAntonio Huete Jimenez 	}
1348cca6fc52SDaniel Fojt 
1349*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.keyfile != NULL) {
1350*de0e0e4dSAntonio Huete Jimenez 		key = load_key(bio_err, cms_config.keyfile, cms_config.keyform,
1351*de0e0e4dSAntonio Huete Jimenez 		    0, passin, "signing key file");
1352*de0e0e4dSAntonio Huete Jimenez 		if (key == NULL)
1353cca6fc52SDaniel Fojt 			goto end;
1354cca6fc52SDaniel Fojt 	}
1355*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.infile != NULL) {
1356*de0e0e4dSAntonio Huete Jimenez 		if ((in = BIO_new_file(cms_config.infile, inmode)) == NULL) {
1357cca6fc52SDaniel Fojt 			BIO_printf(bio_err,
1358*de0e0e4dSAntonio Huete Jimenez 			    "Can't open input file %s\n", cms_config.infile);
1359cca6fc52SDaniel Fojt 			goto end;
1360cca6fc52SDaniel Fojt 		}
1361*de0e0e4dSAntonio Huete Jimenez 	} else {
1362*de0e0e4dSAntonio Huete Jimenez 		if ((in = BIO_new_fp(stdin, BIO_NOCLOSE)) == NULL)
1363*de0e0e4dSAntonio Huete Jimenez 			goto end;
1364*de0e0e4dSAntonio Huete Jimenez 	}
1365cca6fc52SDaniel Fojt 
1366*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.operation & SMIME_IP) {
1367*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.informat == FORMAT_SMIME)
1368cca6fc52SDaniel Fojt 			cms = SMIME_read_CMS(in, &indata);
1369*de0e0e4dSAntonio Huete Jimenez 		else if (cms_config.informat == FORMAT_PEM)
1370cca6fc52SDaniel Fojt 			cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
1371*de0e0e4dSAntonio Huete Jimenez 		else if (cms_config.informat == FORMAT_ASN1)
1372cca6fc52SDaniel Fojt 			cms = d2i_CMS_bio(in, NULL);
1373cca6fc52SDaniel Fojt 		else {
1374cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "Bad input format for CMS file\n");
1375cca6fc52SDaniel Fojt 			goto end;
1376cca6fc52SDaniel Fojt 		}
1377cca6fc52SDaniel Fojt 
1378*de0e0e4dSAntonio Huete Jimenez 		if (cms == NULL) {
1379cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "Error reading S/MIME message\n");
1380cca6fc52SDaniel Fojt 			goto end;
1381cca6fc52SDaniel Fojt 		}
1382*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.contfile != NULL) {
1383cca6fc52SDaniel Fojt 			BIO_free(indata);
1384*de0e0e4dSAntonio Huete Jimenez 			if ((indata = BIO_new_file(cms_config.contfile,
1385*de0e0e4dSAntonio Huete Jimenez 			    "rb")) == NULL) {
1386cca6fc52SDaniel Fojt 				BIO_printf(bio_err,
1387*de0e0e4dSAntonio Huete Jimenez 				    "Can't read content file %s\n",
1388*de0e0e4dSAntonio Huete Jimenez 				    cms_config.contfile);
1389cca6fc52SDaniel Fojt 				goto end;
1390cca6fc52SDaniel Fojt 			}
1391cca6fc52SDaniel Fojt 		}
1392*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.certsoutfile != NULL) {
1393cca6fc52SDaniel Fojt 			STACK_OF(X509) *allcerts;
1394cca6fc52SDaniel Fojt 			if ((allcerts = CMS_get1_certs(cms)) == NULL)
1395cca6fc52SDaniel Fojt 				goto end;
1396*de0e0e4dSAntonio Huete Jimenez 			if (!save_certs(cms_config.certsoutfile, allcerts)) {
1397cca6fc52SDaniel Fojt 				BIO_printf(bio_err,
1398cca6fc52SDaniel Fojt 				    "Error writing certs to %s\n",
1399*de0e0e4dSAntonio Huete Jimenez 				    cms_config.certsoutfile);
1400*de0e0e4dSAntonio Huete Jimenez 				sk_X509_pop_free(allcerts, X509_free);
1401cca6fc52SDaniel Fojt 				ret = 5;
1402cca6fc52SDaniel Fojt 				goto end;
1403cca6fc52SDaniel Fojt 			}
1404cca6fc52SDaniel Fojt 			sk_X509_pop_free(allcerts, X509_free);
1405cca6fc52SDaniel Fojt 		}
1406cca6fc52SDaniel Fojt 	}
1407*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.rctfile != NULL) {
1408*de0e0e4dSAntonio Huete Jimenez 		char *rctmode = (cms_config.rctformat == FORMAT_ASN1) ?
1409*de0e0e4dSAntonio Huete Jimenez 		    "rb" : "r";
1410*de0e0e4dSAntonio Huete Jimenez 		if ((rctin = BIO_new_file(cms_config.rctfile, rctmode)) == NULL) {
1411cca6fc52SDaniel Fojt 			BIO_printf(bio_err,
1412*de0e0e4dSAntonio Huete Jimenez 			    "Can't open receipt file %s\n", cms_config.rctfile);
1413cca6fc52SDaniel Fojt 			goto end;
1414cca6fc52SDaniel Fojt 		}
1415*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.rctformat == FORMAT_SMIME)
1416cca6fc52SDaniel Fojt 			rcms = SMIME_read_CMS(rctin, NULL);
1417*de0e0e4dSAntonio Huete Jimenez 		else if (cms_config.rctformat == FORMAT_PEM)
1418cca6fc52SDaniel Fojt 			rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
1419*de0e0e4dSAntonio Huete Jimenez 		else if (cms_config.rctformat == FORMAT_ASN1)
1420cca6fc52SDaniel Fojt 			rcms = d2i_CMS_bio(rctin, NULL);
1421cca6fc52SDaniel Fojt 		else {
1422cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "Bad input format for receipt\n");
1423cca6fc52SDaniel Fojt 			goto end;
1424cca6fc52SDaniel Fojt 		}
1425cca6fc52SDaniel Fojt 
1426*de0e0e4dSAntonio Huete Jimenez 		if (rcms == NULL) {
1427cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "Error reading receipt\n");
1428cca6fc52SDaniel Fojt 			goto end;
1429cca6fc52SDaniel Fojt 		}
1430cca6fc52SDaniel Fojt 	}
1431*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.outfile != NULL) {
1432*de0e0e4dSAntonio Huete Jimenez 		if ((out = BIO_new_file(cms_config.outfile, outmode)) == NULL) {
1433cca6fc52SDaniel Fojt 			BIO_printf(bio_err,
1434*de0e0e4dSAntonio Huete Jimenez 			    "Can't open output file %s\n", cms_config.outfile);
1435cca6fc52SDaniel Fojt 			goto end;
1436cca6fc52SDaniel Fojt 		}
1437cca6fc52SDaniel Fojt 	} else {
1438*de0e0e4dSAntonio Huete Jimenez 		if ((out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL)
1439*de0e0e4dSAntonio Huete Jimenez 			goto end;
1440cca6fc52SDaniel Fojt 	}
1441cca6fc52SDaniel Fojt 
1442*de0e0e4dSAntonio Huete Jimenez 	if ((cms_config.operation == SMIME_VERIFY) ||
1443*de0e0e4dSAntonio Huete Jimenez 	    (cms_config.operation == SMIME_VERIFY_RECEIPT)) {
1444*de0e0e4dSAntonio Huete Jimenez 		if ((store = setup_verify(bio_err, cms_config.CAfile,
1445*de0e0e4dSAntonio Huete Jimenez 		    cms_config.CApath)) == NULL)
1446cca6fc52SDaniel Fojt 			goto end;
1447cca6fc52SDaniel Fojt 		X509_STORE_set_verify_cb(store, cms_cb);
1448*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.vpm != NULL) {
1449*de0e0e4dSAntonio Huete Jimenez 			if (!X509_STORE_set1_param(store, cms_config.vpm))
1450*de0e0e4dSAntonio Huete Jimenez 				goto end;
1451*de0e0e4dSAntonio Huete Jimenez 		}
1452cca6fc52SDaniel Fojt 	}
1453cca6fc52SDaniel Fojt 	ret = 3;
1454cca6fc52SDaniel Fojt 
1455*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.operation == SMIME_DATA_CREATE) {
1456*de0e0e4dSAntonio Huete Jimenez 		cms = CMS_data_create(in, cms_config.flags);
1457*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation == SMIME_DIGEST_CREATE) {
1458*de0e0e4dSAntonio Huete Jimenez 		cms = CMS_digest_create(in, cms_config.sign_md,
1459*de0e0e4dSAntonio Huete Jimenez 		    cms_config.flags);
1460*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation == SMIME_COMPRESS) {
1461*de0e0e4dSAntonio Huete Jimenez 		cms = CMS_compress(in, -1, cms_config.flags);
1462*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation == SMIME_ENCRYPT) {
1463cca6fc52SDaniel Fojt 		int i;
1464*de0e0e4dSAntonio Huete Jimenez 		cms_config.flags |= CMS_PARTIAL;
1465*de0e0e4dSAntonio Huete Jimenez 		cms = CMS_encrypt(NULL, in, cms_config.cipher,
1466*de0e0e4dSAntonio Huete Jimenez 		    cms_config.flags);
1467cca6fc52SDaniel Fojt 		if (cms == NULL)
1468cca6fc52SDaniel Fojt 			goto end;
1469*de0e0e4dSAntonio Huete Jimenez 		for (i = 0; i < sk_X509_num(cms_config.encerts); i++) {
1470cca6fc52SDaniel Fojt 			CMS_RecipientInfo *ri;
1471cca6fc52SDaniel Fojt 			struct cms_key_param *kparam;
1472*de0e0e4dSAntonio Huete Jimenez 			int tflags = cms_config.flags;
1473*de0e0e4dSAntonio Huete Jimenez 			X509 *x;
1474*de0e0e4dSAntonio Huete Jimenez 
1475*de0e0e4dSAntonio Huete Jimenez 			if ((x = sk_X509_value(cms_config.encerts, i)) == NULL)
1476*de0e0e4dSAntonio Huete Jimenez 				goto end;
1477*de0e0e4dSAntonio Huete Jimenez 			for (kparam = cms_config.key_first; kparam != NULL;
1478*de0e0e4dSAntonio Huete Jimenez 			    kparam = kparam->next) {
1479cca6fc52SDaniel Fojt 				if (kparam->idx == i) {
1480cca6fc52SDaniel Fojt 					tflags |= CMS_KEY_PARAM;
1481cca6fc52SDaniel Fojt 					break;
1482cca6fc52SDaniel Fojt 				}
1483cca6fc52SDaniel Fojt 			}
1484cca6fc52SDaniel Fojt 			ri = CMS_add1_recipient_cert(cms, x, tflags);
1485cca6fc52SDaniel Fojt 			if (ri == NULL)
1486cca6fc52SDaniel Fojt 				goto end;
1487cca6fc52SDaniel Fojt 			if (kparam != NULL) {
1488cca6fc52SDaniel Fojt 				EVP_PKEY_CTX *pctx;
1489*de0e0e4dSAntonio Huete Jimenez 				if ((pctx = CMS_RecipientInfo_get0_pkey_ctx(
1490*de0e0e4dSAntonio Huete Jimenez 				    ri)) == NULL)
1491cca6fc52SDaniel Fojt 					goto end;
1492cca6fc52SDaniel Fojt 				if (!cms_set_pkey_param(pctx, kparam->param))
1493cca6fc52SDaniel Fojt 					goto end;
1494cca6fc52SDaniel Fojt 			}
1495cca6fc52SDaniel Fojt 		}
1496cca6fc52SDaniel Fojt 
1497*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.secret_key != NULL) {
1498*de0e0e4dSAntonio Huete Jimenez 			if (CMS_add0_recipient_key(cms, NID_undef,
1499*de0e0e4dSAntonio Huete Jimenez 			    cms_config.secret_key, cms_config.secret_keylen,
1500*de0e0e4dSAntonio Huete Jimenez 			    cms_config.secret_keyid, cms_config.secret_keyidlen,
1501*de0e0e4dSAntonio Huete Jimenez 			    NULL, NULL, NULL) == NULL)
1502cca6fc52SDaniel Fojt 				goto end;
1503cca6fc52SDaniel Fojt 			/* NULL these because call absorbs them */
1504*de0e0e4dSAntonio Huete Jimenez 			cms_config.secret_key = NULL;
1505*de0e0e4dSAntonio Huete Jimenez 			cms_config.secret_keyid = NULL;
1506cca6fc52SDaniel Fojt 		}
1507*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.pwri_pass != NULL) {
1508*de0e0e4dSAntonio Huete Jimenez 			pwri_tmp = strdup(cms_config.pwri_pass);
1509*de0e0e4dSAntonio Huete Jimenez 			if (pwri_tmp == NULL)
1510cca6fc52SDaniel Fojt 				goto end;
1511*de0e0e4dSAntonio Huete Jimenez 			if (CMS_add0_recipient_password(cms, -1, NID_undef,
1512*de0e0e4dSAntonio Huete Jimenez 			    NID_undef, pwri_tmp, -1, NULL) == NULL)
1513cca6fc52SDaniel Fojt 				goto end;
1514cca6fc52SDaniel Fojt 			pwri_tmp = NULL;
1515cca6fc52SDaniel Fojt 		}
1516*de0e0e4dSAntonio Huete Jimenez 		if (!(cms_config.flags & CMS_STREAM)) {
1517*de0e0e4dSAntonio Huete Jimenez 			if (!CMS_final(cms, in, NULL, cms_config.flags))
1518cca6fc52SDaniel Fojt 				goto end;
1519cca6fc52SDaniel Fojt 		}
1520*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation == SMIME_ENCRYPTED_ENCRYPT) {
1521*de0e0e4dSAntonio Huete Jimenez 		cms = CMS_EncryptedData_encrypt(in, cms_config.cipher,
1522*de0e0e4dSAntonio Huete Jimenez 		    cms_config.secret_key, cms_config.secret_keylen,
1523*de0e0e4dSAntonio Huete Jimenez 		    cms_config.flags);
1524cca6fc52SDaniel Fojt 
1525*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation == SMIME_SIGN_RECEIPT) {
1526cca6fc52SDaniel Fojt 		CMS_ContentInfo *srcms = NULL;
1527cca6fc52SDaniel Fojt 		STACK_OF(CMS_SignerInfo) *sis;
1528cca6fc52SDaniel Fojt 		CMS_SignerInfo *si;
1529cca6fc52SDaniel Fojt 		sis = CMS_get0_SignerInfos(cms);
1530*de0e0e4dSAntonio Huete Jimenez 		if (sis == NULL)
1531cca6fc52SDaniel Fojt 			goto end;
1532cca6fc52SDaniel Fojt 		si = sk_CMS_SignerInfo_value(sis, 0);
1533*de0e0e4dSAntonio Huete Jimenez 		if (si == NULL)
1534*de0e0e4dSAntonio Huete Jimenez 			goto end;
1535*de0e0e4dSAntonio Huete Jimenez 		srcms = CMS_sign_receipt(si, signer, key, other,
1536*de0e0e4dSAntonio Huete Jimenez 		    cms_config.flags);
1537*de0e0e4dSAntonio Huete Jimenez 		if (srcms == NULL)
1538cca6fc52SDaniel Fojt 			goto end;
1539cca6fc52SDaniel Fojt 		CMS_ContentInfo_free(cms);
1540cca6fc52SDaniel Fojt 		cms = srcms;
1541*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation & SMIME_SIGNERS) {
1542cca6fc52SDaniel Fojt 		int i;
1543cca6fc52SDaniel Fojt 		/*
1544cca6fc52SDaniel Fojt 		 * If detached data content we enable streaming if S/MIME
1545cca6fc52SDaniel Fojt 		 * output format.
1546cca6fc52SDaniel Fojt 		 */
1547*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.operation == SMIME_SIGN) {
1548cca6fc52SDaniel Fojt 
1549*de0e0e4dSAntonio Huete Jimenez 			if (cms_config.flags & CMS_DETACHED) {
1550*de0e0e4dSAntonio Huete Jimenez 				if (cms_config.outformat == FORMAT_SMIME)
1551*de0e0e4dSAntonio Huete Jimenez 					cms_config.flags |= CMS_STREAM;
1552cca6fc52SDaniel Fojt 			}
1553*de0e0e4dSAntonio Huete Jimenez 			cms_config.flags |= CMS_PARTIAL;
1554*de0e0e4dSAntonio Huete Jimenez 			cms = CMS_sign(NULL, NULL, other, in, cms_config.flags);
1555*de0e0e4dSAntonio Huete Jimenez 			if (cms == NULL)
1556cca6fc52SDaniel Fojt 				goto end;
1557*de0e0e4dSAntonio Huete Jimenez 			if (cms_config.econtent_type != NULL)
1558*de0e0e4dSAntonio Huete Jimenez 				if (!CMS_set1_eContentType(cms,
1559*de0e0e4dSAntonio Huete Jimenez 				    cms_config.econtent_type))
1560cca6fc52SDaniel Fojt 					goto end;
1561cca6fc52SDaniel Fojt 
1562*de0e0e4dSAntonio Huete Jimenez 			if (cms_config.rr_to != NULL) {
1563*de0e0e4dSAntonio Huete Jimenez 				rr = make_receipt_request(cms_config.rr_to,
1564*de0e0e4dSAntonio Huete Jimenez 				    cms_config.rr_allorfirst,
1565*de0e0e4dSAntonio Huete Jimenez 				    cms_config.rr_from);
1566*de0e0e4dSAntonio Huete Jimenez 				if (rr == NULL) {
1567cca6fc52SDaniel Fojt 					BIO_puts(bio_err,
1568cca6fc52SDaniel Fojt 					    "Signed Receipt Request Creation Error\n");
1569cca6fc52SDaniel Fojt 					goto end;
1570cca6fc52SDaniel Fojt 				}
1571cca6fc52SDaniel Fojt 			}
1572*de0e0e4dSAntonio Huete Jimenez 		} else {
1573*de0e0e4dSAntonio Huete Jimenez 			cms_config.flags |= CMS_REUSE_DIGEST;
1574*de0e0e4dSAntonio Huete Jimenez 		}
1575*de0e0e4dSAntonio Huete Jimenez 
1576*de0e0e4dSAntonio Huete Jimenez 		for (i = 0; i < sk_OPENSSL_STRING_num(cms_config.sksigners); i++) {
1577cca6fc52SDaniel Fojt 			CMS_SignerInfo *si;
1578cca6fc52SDaniel Fojt 			struct cms_key_param *kparam;
1579*de0e0e4dSAntonio Huete Jimenez 			int tflags = cms_config.flags;
1580cca6fc52SDaniel Fojt 
1581*de0e0e4dSAntonio Huete Jimenez 			cms_config.signerfile = sk_OPENSSL_STRING_value(
1582*de0e0e4dSAntonio Huete Jimenez 			    cms_config.sksigners, i);
1583*de0e0e4dSAntonio Huete Jimenez 			cms_config.keyfile = sk_OPENSSL_STRING_value(
1584*de0e0e4dSAntonio Huete Jimenez 			    cms_config.skkeys, i);
1585*de0e0e4dSAntonio Huete Jimenez 
1586*de0e0e4dSAntonio Huete Jimenez 			signer = load_cert(bio_err, cms_config.signerfile,
1587*de0e0e4dSAntonio Huete Jimenez 			    FORMAT_PEM, NULL, "signer certificate");
1588*de0e0e4dSAntonio Huete Jimenez 			if (signer == NULL)
1589cca6fc52SDaniel Fojt 				goto end;
1590*de0e0e4dSAntonio Huete Jimenez 			key = load_key(bio_err, cms_config.keyfile,
1591*de0e0e4dSAntonio Huete Jimenez 			    cms_config.keyform, 0, passin, "signing key file");
1592*de0e0e4dSAntonio Huete Jimenez 			if (key == NULL)
1593cca6fc52SDaniel Fojt 				goto end;
1594*de0e0e4dSAntonio Huete Jimenez 			for (kparam = cms_config.key_first; kparam != NULL;
1595*de0e0e4dSAntonio Huete Jimenez 			    kparam = kparam->next) {
1596cca6fc52SDaniel Fojt 				if (kparam->idx == i) {
1597cca6fc52SDaniel Fojt 					tflags |= CMS_KEY_PARAM;
1598cca6fc52SDaniel Fojt 					break;
1599cca6fc52SDaniel Fojt 				}
1600cca6fc52SDaniel Fojt 			}
1601*de0e0e4dSAntonio Huete Jimenez 			si = CMS_add1_signer(cms, signer, key,
1602*de0e0e4dSAntonio Huete Jimenez 			    cms_config.sign_md, tflags);
1603cca6fc52SDaniel Fojt 			if (si == NULL)
1604cca6fc52SDaniel Fojt 				goto end;
1605cca6fc52SDaniel Fojt 			if (kparam != NULL) {
1606cca6fc52SDaniel Fojt 				EVP_PKEY_CTX *pctx;
1607*de0e0e4dSAntonio Huete Jimenez 				if ((pctx = CMS_SignerInfo_get0_pkey_ctx(
1608*de0e0e4dSAntonio Huete Jimenez 				    si)) == NULL)
1609cca6fc52SDaniel Fojt 					goto end;
1610cca6fc52SDaniel Fojt 				if (!cms_set_pkey_param(pctx, kparam->param))
1611cca6fc52SDaniel Fojt 					goto end;
1612cca6fc52SDaniel Fojt 			}
1613*de0e0e4dSAntonio Huete Jimenez 			if (rr != NULL && !CMS_add1_ReceiptRequest(si, rr))
1614cca6fc52SDaniel Fojt 				goto end;
1615cca6fc52SDaniel Fojt 			X509_free(signer);
1616cca6fc52SDaniel Fojt 			signer = NULL;
1617cca6fc52SDaniel Fojt 			EVP_PKEY_free(key);
1618cca6fc52SDaniel Fojt 			key = NULL;
1619cca6fc52SDaniel Fojt 		}
1620cca6fc52SDaniel Fojt 		/* If not streaming or resigning finalize structure */
1621*de0e0e4dSAntonio Huete Jimenez 		if ((cms_config.operation == SMIME_SIGN) &&
1622*de0e0e4dSAntonio Huete Jimenez 		    !(cms_config.flags & CMS_STREAM)) {
1623*de0e0e4dSAntonio Huete Jimenez 			if (!CMS_final(cms, in, NULL, cms_config.flags))
1624cca6fc52SDaniel Fojt 				goto end;
1625cca6fc52SDaniel Fojt 		}
1626cca6fc52SDaniel Fojt 	}
1627*de0e0e4dSAntonio Huete Jimenez 	if (cms == NULL) {
1628cca6fc52SDaniel Fojt 		BIO_printf(bio_err, "Error creating CMS structure\n");
1629cca6fc52SDaniel Fojt 		goto end;
1630cca6fc52SDaniel Fojt 	}
1631cca6fc52SDaniel Fojt 	ret = 4;
1632*de0e0e4dSAntonio Huete Jimenez 	if (cms_config.operation == SMIME_DECRYPT) {
1633*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.flags & CMS_DEBUG_DECRYPT)
1634*de0e0e4dSAntonio Huete Jimenez 			CMS_decrypt(cms, NULL, NULL, NULL, NULL,
1635*de0e0e4dSAntonio Huete Jimenez 			    cms_config.flags);
1636cca6fc52SDaniel Fojt 
1637*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.secret_key != NULL) {
1638*de0e0e4dSAntonio Huete Jimenez 			if (!CMS_decrypt_set1_key(cms, cms_config.secret_key,
1639*de0e0e4dSAntonio Huete Jimenez 			    cms_config.secret_keylen, cms_config.secret_keyid,
1640*de0e0e4dSAntonio Huete Jimenez 			    cms_config.secret_keyidlen)) {
1641cca6fc52SDaniel Fojt 				BIO_puts(bio_err,
1642cca6fc52SDaniel Fojt 				    "Error decrypting CMS using secret key\n");
1643cca6fc52SDaniel Fojt 				goto end;
1644cca6fc52SDaniel Fojt 			}
1645cca6fc52SDaniel Fojt 		}
1646*de0e0e4dSAntonio Huete Jimenez 		if (key != NULL) {
1647cca6fc52SDaniel Fojt 			if (!CMS_decrypt_set1_pkey(cms, key, recip)) {
1648cca6fc52SDaniel Fojt 				BIO_puts(bio_err,
1649cca6fc52SDaniel Fojt 				    "Error decrypting CMS using private key\n");
1650cca6fc52SDaniel Fojt 				goto end;
1651cca6fc52SDaniel Fojt 			}
1652cca6fc52SDaniel Fojt 		}
1653*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.pwri_pass != NULL) {
1654*de0e0e4dSAntonio Huete Jimenez 			if (!CMS_decrypt_set1_password(cms,
1655*de0e0e4dSAntonio Huete Jimenez 			    cms_config.pwri_pass, -1)) {
1656cca6fc52SDaniel Fojt 				BIO_puts(bio_err,
1657cca6fc52SDaniel Fojt 				    "Error decrypting CMS using password\n");
1658cca6fc52SDaniel Fojt 				goto end;
1659cca6fc52SDaniel Fojt 			}
1660cca6fc52SDaniel Fojt 		}
1661*de0e0e4dSAntonio Huete Jimenez 		if (!CMS_decrypt(cms, NULL, NULL, indata, out,
1662*de0e0e4dSAntonio Huete Jimenez 		    cms_config.flags)) {
1663cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "Error decrypting CMS structure\n");
1664cca6fc52SDaniel Fojt 			goto end;
1665cca6fc52SDaniel Fojt 		}
1666*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation == SMIME_DATAOUT) {
1667*de0e0e4dSAntonio Huete Jimenez 		if (!CMS_data(cms, out, cms_config.flags))
1668cca6fc52SDaniel Fojt 			goto end;
1669*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation == SMIME_UNCOMPRESS) {
1670*de0e0e4dSAntonio Huete Jimenez 		if (!CMS_uncompress(cms, indata, out, cms_config.flags))
1671cca6fc52SDaniel Fojt 			goto end;
1672*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation == SMIME_DIGEST_VERIFY) {
1673*de0e0e4dSAntonio Huete Jimenez 		if (CMS_digest_verify(cms, indata, out, cms_config.flags) > 0)
1674cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "Verification successful\n");
1675cca6fc52SDaniel Fojt 		else {
1676cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "Verification failure\n");
1677cca6fc52SDaniel Fojt 			goto end;
1678cca6fc52SDaniel Fojt 		}
1679*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation == SMIME_ENCRYPTED_DECRYPT) {
1680*de0e0e4dSAntonio Huete Jimenez 		if (!CMS_EncryptedData_decrypt(cms, cms_config.secret_key,
1681*de0e0e4dSAntonio Huete Jimenez 		    cms_config.secret_keylen, indata, out, cms_config.flags))
1682cca6fc52SDaniel Fojt 			goto end;
1683*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation == SMIME_VERIFY) {
1684*de0e0e4dSAntonio Huete Jimenez 		if (CMS_verify(cms, other, store, indata, out,
1685*de0e0e4dSAntonio Huete Jimenez 		    cms_config.flags) > 0) {
1686cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "Verification successful\n");
1687*de0e0e4dSAntonio Huete Jimenez 		} else {
1688cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "Verification failure\n");
1689*de0e0e4dSAntonio Huete Jimenez 			if (cms_config.verify_retcode)
1690cca6fc52SDaniel Fojt 				ret = verify_err + 32;
1691cca6fc52SDaniel Fojt 			goto end;
1692cca6fc52SDaniel Fojt 		}
1693*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.signerfile != NULL) {
1694cca6fc52SDaniel Fojt 			STACK_OF(X509) *signers;
1695cca6fc52SDaniel Fojt 			if ((signers = CMS_get0_signers(cms)) == NULL)
1696cca6fc52SDaniel Fojt 				goto end;
1697*de0e0e4dSAntonio Huete Jimenez 			if (!save_certs(cms_config.signerfile, signers)) {
1698cca6fc52SDaniel Fojt 				BIO_printf(bio_err,
1699cca6fc52SDaniel Fojt 				    "Error writing signers to %s\n",
1700*de0e0e4dSAntonio Huete Jimenez 				    cms_config.signerfile);
1701*de0e0e4dSAntonio Huete Jimenez 				sk_X509_free(signers);
1702cca6fc52SDaniel Fojt 				ret = 5;
1703cca6fc52SDaniel Fojt 				goto end;
1704cca6fc52SDaniel Fojt 			}
1705cca6fc52SDaniel Fojt 			sk_X509_free(signers);
1706cca6fc52SDaniel Fojt 		}
1707*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.rr_print)
1708cca6fc52SDaniel Fojt 			receipt_request_print(bio_err, cms);
1709cca6fc52SDaniel Fojt 
1710*de0e0e4dSAntonio Huete Jimenez 	} else if (cms_config.operation == SMIME_VERIFY_RECEIPT) {
1711*de0e0e4dSAntonio Huete Jimenez 		if (CMS_verify_receipt(rcms, cms, other, store,
1712*de0e0e4dSAntonio Huete Jimenez 		    cms_config.flags) > 0) {
1713cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "Verification successful\n");
1714*de0e0e4dSAntonio Huete Jimenez 		} else {
1715cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "Verification failure\n");
1716cca6fc52SDaniel Fojt 			goto end;
1717cca6fc52SDaniel Fojt 		}
1718cca6fc52SDaniel Fojt 	} else {
1719*de0e0e4dSAntonio Huete Jimenez 		if (cms_config.noout) {
1720*de0e0e4dSAntonio Huete Jimenez 			if (cms_config.print &&
1721cca6fc52SDaniel Fojt 			    !CMS_ContentInfo_print_ctx(out, cms, 0, NULL))
1722cca6fc52SDaniel Fojt 				goto end;
1723*de0e0e4dSAntonio Huete Jimenez 		} else if (cms_config.outformat == FORMAT_SMIME) {
1724*de0e0e4dSAntonio Huete Jimenez 			if (cms_config.to != NULL)
1725*de0e0e4dSAntonio Huete Jimenez 				BIO_printf(out, "To: %s\n", cms_config.to);
1726*de0e0e4dSAntonio Huete Jimenez 			if (cms_config.from != NULL)
1727*de0e0e4dSAntonio Huete Jimenez 				BIO_printf(out, "From: %s\n", cms_config.from);
1728*de0e0e4dSAntonio Huete Jimenez 			if (cms_config.subject != NULL)
1729*de0e0e4dSAntonio Huete Jimenez 				BIO_printf(out, "Subject: %s\n",
1730*de0e0e4dSAntonio Huete Jimenez 				    cms_config.subject);
1731*de0e0e4dSAntonio Huete Jimenez 			if (cms_config.operation == SMIME_RESIGN)
1732*de0e0e4dSAntonio Huete Jimenez 				ret = SMIME_write_CMS(out, cms, indata,
1733*de0e0e4dSAntonio Huete Jimenez 				    cms_config.flags);
1734cca6fc52SDaniel Fojt 			else
1735*de0e0e4dSAntonio Huete Jimenez 				ret = SMIME_write_CMS(out, cms, in,
1736*de0e0e4dSAntonio Huete Jimenez 				    cms_config.flags);
1737*de0e0e4dSAntonio Huete Jimenez 		} else if (cms_config.outformat == FORMAT_PEM) {
1738*de0e0e4dSAntonio Huete Jimenez 			ret = PEM_write_bio_CMS_stream(out, cms, in,
1739*de0e0e4dSAntonio Huete Jimenez 			    cms_config.flags);
1740*de0e0e4dSAntonio Huete Jimenez 		} else if (cms_config.outformat == FORMAT_ASN1) {
1741*de0e0e4dSAntonio Huete Jimenez 			ret = i2d_CMS_bio_stream(out, cms, in, cms_config.flags);
1742*de0e0e4dSAntonio Huete Jimenez 		} else {
1743cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "Bad output format for CMS file\n");
1744cca6fc52SDaniel Fojt 			goto end;
1745cca6fc52SDaniel Fojt 		}
1746cca6fc52SDaniel Fojt 		if (ret <= 0) {
1747cca6fc52SDaniel Fojt 			ret = 6;
1748cca6fc52SDaniel Fojt 			goto end;
1749cca6fc52SDaniel Fojt 		}
1750cca6fc52SDaniel Fojt 	}
1751cca6fc52SDaniel Fojt 	ret = 0;
1752cca6fc52SDaniel Fojt 
1753cca6fc52SDaniel Fojt  end:
1754cca6fc52SDaniel Fojt 	if (ret)
1755cca6fc52SDaniel Fojt 		ERR_print_errors(bio_err);
1756cca6fc52SDaniel Fojt 
1757*de0e0e4dSAntonio Huete Jimenez 	sk_X509_pop_free(cms_config.encerts, X509_free);
1758cca6fc52SDaniel Fojt 	sk_X509_pop_free(other, X509_free);
1759*de0e0e4dSAntonio Huete Jimenez 	X509_VERIFY_PARAM_free(cms_config.vpm);
1760*de0e0e4dSAntonio Huete Jimenez 	sk_OPENSSL_STRING_free(cms_config.sksigners);
1761*de0e0e4dSAntonio Huete Jimenez 	sk_OPENSSL_STRING_free(cms_config.skkeys);
1762*de0e0e4dSAntonio Huete Jimenez 	free(cms_config.secret_key);
1763*de0e0e4dSAntonio Huete Jimenez 	free(cms_config.secret_keyid);
1764cca6fc52SDaniel Fojt 	free(pwri_tmp);
1765*de0e0e4dSAntonio Huete Jimenez 	ASN1_OBJECT_free(cms_config.econtent_type);
1766cca6fc52SDaniel Fojt 	CMS_ReceiptRequest_free(rr);
1767*de0e0e4dSAntonio Huete Jimenez 	sk_OPENSSL_STRING_free(cms_config.rr_to);
1768*de0e0e4dSAntonio Huete Jimenez 	sk_OPENSSL_STRING_free(cms_config.rr_from);
1769*de0e0e4dSAntonio Huete Jimenez 	for (cms_config.key_param = cms_config.key_first; cms_config.key_param;) {
1770cca6fc52SDaniel Fojt 		struct cms_key_param *tparam;
1771*de0e0e4dSAntonio Huete Jimenez 		sk_OPENSSL_STRING_free(cms_config.key_param->param);
1772*de0e0e4dSAntonio Huete Jimenez 		tparam = cms_config.key_param->next;
1773*de0e0e4dSAntonio Huete Jimenez 		free(cms_config.key_param);
1774*de0e0e4dSAntonio Huete Jimenez 		cms_config.key_param = tparam;
1775cca6fc52SDaniel Fojt 	}
1776cca6fc52SDaniel Fojt 	X509_STORE_free(store);
1777*de0e0e4dSAntonio Huete Jimenez 	X509_free(cms_config.cert);
1778cca6fc52SDaniel Fojt 	X509_free(recip);
1779cca6fc52SDaniel Fojt 	X509_free(signer);
1780cca6fc52SDaniel Fojt 	EVP_PKEY_free(key);
1781cca6fc52SDaniel Fojt 	CMS_ContentInfo_free(cms);
1782cca6fc52SDaniel Fojt 	CMS_ContentInfo_free(rcms);
1783cca6fc52SDaniel Fojt 	BIO_free(rctin);
1784cca6fc52SDaniel Fojt 	BIO_free(in);
1785cca6fc52SDaniel Fojt 	BIO_free(indata);
1786cca6fc52SDaniel Fojt 	BIO_free_all(out);
1787cca6fc52SDaniel Fojt 	free(passin);
1788cca6fc52SDaniel Fojt 
1789cca6fc52SDaniel Fojt 	return (ret);
1790cca6fc52SDaniel Fojt }
1791cca6fc52SDaniel Fojt 
1792cca6fc52SDaniel Fojt static int
save_certs(char * signerfile,STACK_OF (X509)* signers)1793cca6fc52SDaniel Fojt save_certs(char *signerfile, STACK_OF(X509) *signers)
1794cca6fc52SDaniel Fojt {
1795cca6fc52SDaniel Fojt 	int i;
1796cca6fc52SDaniel Fojt 	BIO *tmp;
1797cca6fc52SDaniel Fojt 
1798*de0e0e4dSAntonio Huete Jimenez 	if (signerfile == NULL)
1799cca6fc52SDaniel Fojt 		return 1;
1800cca6fc52SDaniel Fojt 	tmp = BIO_new_file(signerfile, "w");
1801*de0e0e4dSAntonio Huete Jimenez 	if (tmp == NULL)
1802cca6fc52SDaniel Fojt 		return 0;
1803cca6fc52SDaniel Fojt 	for (i = 0; i < sk_X509_num(signers); i++)
1804cca6fc52SDaniel Fojt 		PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
1805cca6fc52SDaniel Fojt 	BIO_free(tmp);
1806cca6fc52SDaniel Fojt 	return 1;
1807cca6fc52SDaniel Fojt }
1808cca6fc52SDaniel Fojt 
1809cca6fc52SDaniel Fojt /* Minimal callback just to output policy info (if any) */
1810cca6fc52SDaniel Fojt 
1811cca6fc52SDaniel Fojt static int
cms_cb(int ok,X509_STORE_CTX * ctx)1812cca6fc52SDaniel Fojt cms_cb(int ok, X509_STORE_CTX *ctx)
1813cca6fc52SDaniel Fojt {
1814cca6fc52SDaniel Fojt 	int error;
1815cca6fc52SDaniel Fojt 
1816cca6fc52SDaniel Fojt 	error = X509_STORE_CTX_get_error(ctx);
1817cca6fc52SDaniel Fojt 
1818cca6fc52SDaniel Fojt 	verify_err = error;
1819cca6fc52SDaniel Fojt 
1820cca6fc52SDaniel Fojt 	if ((error != X509_V_ERR_NO_EXPLICIT_POLICY) &&
1821cca6fc52SDaniel Fojt 	    ((error != X509_V_OK) || (ok != 2)))
1822cca6fc52SDaniel Fojt 		return ok;
1823cca6fc52SDaniel Fojt 
1824cca6fc52SDaniel Fojt 	policies_print(NULL, ctx);
1825cca6fc52SDaniel Fojt 
1826cca6fc52SDaniel Fojt 	return ok;
1827cca6fc52SDaniel Fojt }
1828cca6fc52SDaniel Fojt 
1829cca6fc52SDaniel Fojt static void
gnames_stack_print(BIO * out,STACK_OF (GENERAL_NAMES)* gns)1830cca6fc52SDaniel Fojt gnames_stack_print(BIO *out, STACK_OF(GENERAL_NAMES) *gns)
1831cca6fc52SDaniel Fojt {
1832cca6fc52SDaniel Fojt 	STACK_OF(GENERAL_NAME) *gens;
1833cca6fc52SDaniel Fojt 	GENERAL_NAME *gen;
1834cca6fc52SDaniel Fojt 	int i, j;
1835cca6fc52SDaniel Fojt 
1836cca6fc52SDaniel Fojt 	for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++) {
1837cca6fc52SDaniel Fojt 		gens = sk_GENERAL_NAMES_value(gns, i);
1838cca6fc52SDaniel Fojt 		for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) {
1839cca6fc52SDaniel Fojt 			gen = sk_GENERAL_NAME_value(gens, j);
1840cca6fc52SDaniel Fojt 			BIO_puts(out, "    ");
1841cca6fc52SDaniel Fojt 			GENERAL_NAME_print(out, gen);
1842cca6fc52SDaniel Fojt 			BIO_puts(out, "\n");
1843cca6fc52SDaniel Fojt 		}
1844cca6fc52SDaniel Fojt 	}
1845cca6fc52SDaniel Fojt 	return;
1846cca6fc52SDaniel Fojt }
1847cca6fc52SDaniel Fojt 
1848cca6fc52SDaniel Fojt static void
receipt_request_print(BIO * out,CMS_ContentInfo * cms)1849cca6fc52SDaniel Fojt receipt_request_print(BIO *out, CMS_ContentInfo *cms)
1850cca6fc52SDaniel Fojt {
1851cca6fc52SDaniel Fojt 	STACK_OF(CMS_SignerInfo) *sis;
1852cca6fc52SDaniel Fojt 	CMS_SignerInfo *si;
1853cca6fc52SDaniel Fojt 	CMS_ReceiptRequest *rr;
1854cca6fc52SDaniel Fojt 	int allorfirst;
1855cca6fc52SDaniel Fojt 	STACK_OF(GENERAL_NAMES) *rto, *rlist;
1856cca6fc52SDaniel Fojt 	ASN1_STRING *scid;
1857cca6fc52SDaniel Fojt 	int i, rv;
1858cca6fc52SDaniel Fojt 
1859cca6fc52SDaniel Fojt 	if ((sis = CMS_get0_SignerInfos(cms)) == NULL)
1860cca6fc52SDaniel Fojt 		return;
1861cca6fc52SDaniel Fojt 	for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) {
1862*de0e0e4dSAntonio Huete Jimenez 		if ((si = sk_CMS_SignerInfo_value(sis, i)) == NULL)
1863*de0e0e4dSAntonio Huete Jimenez 			return;
1864cca6fc52SDaniel Fojt 		rv = CMS_get1_ReceiptRequest(si, &rr);
1865cca6fc52SDaniel Fojt 		BIO_printf(bio_err, "Signer %d:\n", i + 1);
1866*de0e0e4dSAntonio Huete Jimenez 		if (rv == 0) {
1867cca6fc52SDaniel Fojt 			BIO_puts(bio_err, "  No Receipt Request\n");
1868*de0e0e4dSAntonio Huete Jimenez 		} else if (rv < 0) {
1869cca6fc52SDaniel Fojt 			BIO_puts(bio_err, "  Receipt Request Parse Error\n");
1870cca6fc52SDaniel Fojt 			ERR_print_errors(bio_err);
1871cca6fc52SDaniel Fojt 		} else {
1872cca6fc52SDaniel Fojt 			char *id;
1873cca6fc52SDaniel Fojt 			int idlen;
1874*de0e0e4dSAntonio Huete Jimenez 
1875cca6fc52SDaniel Fojt 			CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
1876cca6fc52SDaniel Fojt 			    &rlist, &rto);
1877cca6fc52SDaniel Fojt 			BIO_puts(out, "  Signed Content ID:\n");
1878cca6fc52SDaniel Fojt 			idlen = ASN1_STRING_length(scid);
1879cca6fc52SDaniel Fojt 			id = (char *) ASN1_STRING_data(scid);
1880cca6fc52SDaniel Fojt 			BIO_dump_indent(out, id, idlen, 4);
1881cca6fc52SDaniel Fojt 			BIO_puts(out, "  Receipts From");
1882*de0e0e4dSAntonio Huete Jimenez 			if (rlist != NULL) {
1883cca6fc52SDaniel Fojt 				BIO_puts(out, " List:\n");
1884cca6fc52SDaniel Fojt 				gnames_stack_print(out, rlist);
1885*de0e0e4dSAntonio Huete Jimenez 			} else if (allorfirst == 1) {
1886cca6fc52SDaniel Fojt 				BIO_puts(out, ": First Tier\n");
1887*de0e0e4dSAntonio Huete Jimenez 			} else if (allorfirst == 0) {
1888cca6fc52SDaniel Fojt 				BIO_puts(out, ": All\n");
1889*de0e0e4dSAntonio Huete Jimenez 			} else {
1890cca6fc52SDaniel Fojt 				BIO_printf(out, " Unknown (%d)\n", allorfirst);
1891*de0e0e4dSAntonio Huete Jimenez 			}
1892cca6fc52SDaniel Fojt 			BIO_puts(out, "  Receipts To:\n");
1893cca6fc52SDaniel Fojt 			gnames_stack_print(out, rto);
1894cca6fc52SDaniel Fojt 		}
1895cca6fc52SDaniel Fojt 		CMS_ReceiptRequest_free(rr);
1896cca6fc52SDaniel Fojt 	}
1897cca6fc52SDaniel Fojt }
1898cca6fc52SDaniel Fojt 
STACK_OF(GENERAL_NAMES)1899cca6fc52SDaniel Fojt static STACK_OF(GENERAL_NAMES) *
1900cca6fc52SDaniel Fojt make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
1901cca6fc52SDaniel Fojt {
1902cca6fc52SDaniel Fojt 	int i;
1903cca6fc52SDaniel Fojt 	STACK_OF(GENERAL_NAMES) *ret;
1904cca6fc52SDaniel Fojt 	GENERAL_NAMES *gens = NULL;
1905cca6fc52SDaniel Fojt 	GENERAL_NAME *gen = NULL;
1906*de0e0e4dSAntonio Huete Jimenez 
1907cca6fc52SDaniel Fojt 	if ((ret = sk_GENERAL_NAMES_new_null()) == NULL)
1908cca6fc52SDaniel Fojt 		goto err;
1909cca6fc52SDaniel Fojt 	for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) {
1910cca6fc52SDaniel Fojt 		char *str = sk_OPENSSL_STRING_value(ns, i);
1911cca6fc52SDaniel Fojt 		gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
1912*de0e0e4dSAntonio Huete Jimenez 		if (gen == NULL)
1913cca6fc52SDaniel Fojt 			goto err;
1914cca6fc52SDaniel Fojt 		gens = GENERAL_NAMES_new();
1915*de0e0e4dSAntonio Huete Jimenez 		if (gens == NULL)
1916cca6fc52SDaniel Fojt 			goto err;
1917cca6fc52SDaniel Fojt 		if (!sk_GENERAL_NAME_push(gens, gen))
1918cca6fc52SDaniel Fojt 			goto err;
1919cca6fc52SDaniel Fojt 		gen = NULL;
1920cca6fc52SDaniel Fojt 		if (!sk_GENERAL_NAMES_push(ret, gens))
1921cca6fc52SDaniel Fojt 			goto err;
1922cca6fc52SDaniel Fojt 		gens = NULL;
1923cca6fc52SDaniel Fojt 	}
1924cca6fc52SDaniel Fojt 
1925cca6fc52SDaniel Fojt 	return ret;
1926cca6fc52SDaniel Fojt 
1927cca6fc52SDaniel Fojt  err:
1928cca6fc52SDaniel Fojt 	sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free);
1929cca6fc52SDaniel Fojt 	GENERAL_NAMES_free(gens);
1930cca6fc52SDaniel Fojt 	GENERAL_NAME_free(gen);
1931cca6fc52SDaniel Fojt 
1932cca6fc52SDaniel Fojt 	return NULL;
1933cca6fc52SDaniel Fojt }
1934cca6fc52SDaniel Fojt 
1935cca6fc52SDaniel Fojt 
1936cca6fc52SDaniel Fojt static CMS_ReceiptRequest *
make_receipt_request(STACK_OF (OPENSSL_STRING)* rr_to,int rr_allorfirst,STACK_OF (OPENSSL_STRING)* rr_from)1937cca6fc52SDaniel Fojt make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
1938cca6fc52SDaniel Fojt     STACK_OF(OPENSSL_STRING) *rr_from)
1939cca6fc52SDaniel Fojt {
1940*de0e0e4dSAntonio Huete Jimenez 	STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL;
1941cca6fc52SDaniel Fojt 	CMS_ReceiptRequest *rr;
1942cca6fc52SDaniel Fojt 
1943cca6fc52SDaniel Fojt 	rct_to = make_names_stack(rr_to);
1944*de0e0e4dSAntonio Huete Jimenez 	if (rct_to == NULL)
1945cca6fc52SDaniel Fojt 		goto err;
1946*de0e0e4dSAntonio Huete Jimenez 	if (rr_from != NULL) {
1947cca6fc52SDaniel Fojt 		rct_from = make_names_stack(rr_from);
1948*de0e0e4dSAntonio Huete Jimenez 		if (rct_from == NULL)
1949cca6fc52SDaniel Fojt 			goto err;
1950*de0e0e4dSAntonio Huete Jimenez 	} else {
1951cca6fc52SDaniel Fojt 		rct_from = NULL;
1952*de0e0e4dSAntonio Huete Jimenez 	}
1953cca6fc52SDaniel Fojt 
1954cca6fc52SDaniel Fojt 	if ((rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
1955cca6fc52SDaniel Fojt 	    rct_to)) == NULL)
1956cca6fc52SDaniel Fojt 		goto err;
1957cca6fc52SDaniel Fojt 
1958cca6fc52SDaniel Fojt 	return rr;
1959cca6fc52SDaniel Fojt 
1960cca6fc52SDaniel Fojt  err:
1961*de0e0e4dSAntonio Huete Jimenez 	sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free);
1962*de0e0e4dSAntonio Huete Jimenez 	sk_GENERAL_NAMES_pop_free(rct_from, GENERAL_NAMES_free);
1963cca6fc52SDaniel Fojt 	return NULL;
1964cca6fc52SDaniel Fojt }
1965cca6fc52SDaniel Fojt 
1966cca6fc52SDaniel Fojt static int
cms_set_pkey_param(EVP_PKEY_CTX * pctx,STACK_OF (OPENSSL_STRING)* param)1967cca6fc52SDaniel Fojt cms_set_pkey_param(EVP_PKEY_CTX *pctx, STACK_OF(OPENSSL_STRING) *param)
1968cca6fc52SDaniel Fojt {
1969cca6fc52SDaniel Fojt 	char *keyopt;
1970cca6fc52SDaniel Fojt 	int i;
1971cca6fc52SDaniel Fojt 
1972cca6fc52SDaniel Fojt 	if (sk_OPENSSL_STRING_num(param) <= 0)
1973cca6fc52SDaniel Fojt 		return 1;
1974cca6fc52SDaniel Fojt 	for (i = 0; i < sk_OPENSSL_STRING_num(param); i++) {
1975cca6fc52SDaniel Fojt 		keyopt = sk_OPENSSL_STRING_value(param, i);
1976cca6fc52SDaniel Fojt 		if (pkey_ctrl_string(pctx, keyopt) <= 0) {
1977cca6fc52SDaniel Fojt 			BIO_printf(bio_err, "parameter error \"%s\"\n", keyopt);
1978cca6fc52SDaniel Fojt 			ERR_print_errors(bio_err);
1979cca6fc52SDaniel Fojt 			return 0;
1980cca6fc52SDaniel Fojt 		}
1981cca6fc52SDaniel Fojt 	}
1982cca6fc52SDaniel Fojt 	return 1;
1983cca6fc52SDaniel Fojt }
1984cca6fc52SDaniel Fojt 
1985cca6fc52SDaniel Fojt #endif
1986