1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: smime.c,v 1.17 2022/01/16 07:12:28 inoguchi Exp $ */
2f5b1c8a1SJohn Marino /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3f5b1c8a1SJohn Marino * project.
4f5b1c8a1SJohn Marino */
5f5b1c8a1SJohn Marino /* ====================================================================
6f5b1c8a1SJohn Marino * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
7f5b1c8a1SJohn Marino *
8f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without
9f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions
10f5b1c8a1SJohn Marino * are met:
11f5b1c8a1SJohn Marino *
12f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the above copyright
13f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer.
14f5b1c8a1SJohn Marino *
15f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright
16f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in
17f5b1c8a1SJohn Marino * the documentation and/or other materials provided with the
18f5b1c8a1SJohn Marino * distribution.
19f5b1c8a1SJohn Marino *
20f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this
21f5b1c8a1SJohn Marino * software must display the following acknowledgment:
22f5b1c8a1SJohn Marino * "This product includes software developed by the OpenSSL Project
23f5b1c8a1SJohn Marino * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24f5b1c8a1SJohn Marino *
25f5b1c8a1SJohn Marino * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26f5b1c8a1SJohn Marino * endorse or promote products derived from this software without
27f5b1c8a1SJohn Marino * prior written permission. For written permission, please contact
28f5b1c8a1SJohn Marino * licensing@OpenSSL.org.
29f5b1c8a1SJohn Marino *
30f5b1c8a1SJohn Marino * 5. Products derived from this software may not be called "OpenSSL"
31f5b1c8a1SJohn Marino * nor may "OpenSSL" appear in their names without prior written
32f5b1c8a1SJohn Marino * permission of the OpenSSL Project.
33f5b1c8a1SJohn Marino *
34f5b1c8a1SJohn Marino * 6. Redistributions of any form whatsoever must retain the following
35f5b1c8a1SJohn Marino * acknowledgment:
36f5b1c8a1SJohn Marino * "This product includes software developed by the OpenSSL Project
37f5b1c8a1SJohn Marino * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38f5b1c8a1SJohn Marino *
39f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40f5b1c8a1SJohn Marino * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42f5b1c8a1SJohn Marino * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43f5b1c8a1SJohn Marino * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44f5b1c8a1SJohn Marino * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45f5b1c8a1SJohn Marino * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46f5b1c8a1SJohn Marino * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48f5b1c8a1SJohn Marino * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49f5b1c8a1SJohn Marino * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50f5b1c8a1SJohn Marino * OF THE POSSIBILITY OF SUCH DAMAGE.
51f5b1c8a1SJohn Marino * ====================================================================
52f5b1c8a1SJohn Marino *
53f5b1c8a1SJohn Marino * This product includes cryptographic software written by Eric Young
54f5b1c8a1SJohn Marino * (eay@cryptsoft.com). This product includes software written by Tim
55f5b1c8a1SJohn Marino * Hudson (tjh@cryptsoft.com).
56f5b1c8a1SJohn Marino *
57f5b1c8a1SJohn Marino */
58f5b1c8a1SJohn Marino
59f5b1c8a1SJohn Marino /* S/MIME utility function */
60f5b1c8a1SJohn Marino
61f5b1c8a1SJohn Marino #include <stdio.h>
62f5b1c8a1SJohn Marino #include <string.h>
63f5b1c8a1SJohn Marino
64f5b1c8a1SJohn Marino #include "apps.h"
65f5b1c8a1SJohn Marino
66f5b1c8a1SJohn Marino #include <openssl/crypto.h>
67f5b1c8a1SJohn Marino #include <openssl/err.h>
68f5b1c8a1SJohn Marino #include <openssl/pem.h>
69f5b1c8a1SJohn Marino #include <openssl/x509_vfy.h>
70f5b1c8a1SJohn Marino #include <openssl/x509v3.h>
71f5b1c8a1SJohn Marino
72f5b1c8a1SJohn Marino static int save_certs(char *signerfile, STACK_OF(X509) *signers);
73f5b1c8a1SJohn Marino static int smime_cb(int ok, X509_STORE_CTX *ctx);
74f5b1c8a1SJohn Marino
75f5b1c8a1SJohn Marino #define SMIME_OP 0x10
76f5b1c8a1SJohn Marino #define SMIME_IP 0x20
77f5b1c8a1SJohn Marino #define SMIME_SIGNERS 0x40
78f5b1c8a1SJohn Marino #define SMIME_ENCRYPT (1 | SMIME_OP)
79f5b1c8a1SJohn Marino #define SMIME_DECRYPT (2 | SMIME_IP)
80f5b1c8a1SJohn Marino #define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS)
81f5b1c8a1SJohn Marino #define SMIME_VERIFY (4 | SMIME_IP)
82f5b1c8a1SJohn Marino #define SMIME_PK7OUT (5 | SMIME_IP | SMIME_OP)
83f5b1c8a1SJohn Marino #define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
84f5b1c8a1SJohn Marino
85*de0e0e4dSAntonio Huete Jimenez static struct {
86*de0e0e4dSAntonio Huete Jimenez char *CAfile;
87*de0e0e4dSAntonio Huete Jimenez char *CApath;
88*de0e0e4dSAntonio Huete Jimenez char *certfile;
89*de0e0e4dSAntonio Huete Jimenez const EVP_CIPHER *cipher;
90*de0e0e4dSAntonio Huete Jimenez char *contfile;
91*de0e0e4dSAntonio Huete Jimenez int flags;
92*de0e0e4dSAntonio Huete Jimenez char *from;
93*de0e0e4dSAntonio Huete Jimenez int indef;
94*de0e0e4dSAntonio Huete Jimenez char *infile;
95*de0e0e4dSAntonio Huete Jimenez int informat;
96*de0e0e4dSAntonio Huete Jimenez char *keyfile;
97*de0e0e4dSAntonio Huete Jimenez int keyform;
98*de0e0e4dSAntonio Huete Jimenez int operation;
99*de0e0e4dSAntonio Huete Jimenez char *outfile;
100*de0e0e4dSAntonio Huete Jimenez int outformat;
101*de0e0e4dSAntonio Huete Jimenez char *passargin;
102*de0e0e4dSAntonio Huete Jimenez char *recipfile;
103*de0e0e4dSAntonio Huete Jimenez const EVP_MD *sign_md;
104*de0e0e4dSAntonio Huete Jimenez char *signerfile;
105*de0e0e4dSAntonio Huete Jimenez STACK_OF(OPENSSL_STRING) *skkeys;
106*de0e0e4dSAntonio Huete Jimenez STACK_OF(OPENSSL_STRING) *sksigners;
107*de0e0e4dSAntonio Huete Jimenez char *subject;
108*de0e0e4dSAntonio Huete Jimenez char *to;
109*de0e0e4dSAntonio Huete Jimenez X509_VERIFY_PARAM *vpm;
110*de0e0e4dSAntonio Huete Jimenez } smime_config;
111*de0e0e4dSAntonio Huete Jimenez
112*de0e0e4dSAntonio Huete Jimenez static const EVP_CIPHER *
get_cipher_by_name(char * name)113*de0e0e4dSAntonio Huete Jimenez get_cipher_by_name(char *name)
114*de0e0e4dSAntonio Huete Jimenez {
115*de0e0e4dSAntonio Huete Jimenez if (name == NULL || strcmp(name, "") == 0)
116*de0e0e4dSAntonio Huete Jimenez return (NULL);
117*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_AES
118*de0e0e4dSAntonio Huete Jimenez else if (strcmp(name, "aes128") == 0)
119*de0e0e4dSAntonio Huete Jimenez return EVP_aes_128_cbc();
120*de0e0e4dSAntonio Huete Jimenez else if (strcmp(name, "aes192") == 0)
121*de0e0e4dSAntonio Huete Jimenez return EVP_aes_192_cbc();
122*de0e0e4dSAntonio Huete Jimenez else if (strcmp(name, "aes256") == 0)
123*de0e0e4dSAntonio Huete Jimenez return EVP_aes_256_cbc();
124*de0e0e4dSAntonio Huete Jimenez #endif
125*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_CAMELLIA
126*de0e0e4dSAntonio Huete Jimenez else if (strcmp(name, "camellia128") == 0)
127*de0e0e4dSAntonio Huete Jimenez return EVP_camellia_128_cbc();
128*de0e0e4dSAntonio Huete Jimenez else if (strcmp(name, "camellia192") == 0)
129*de0e0e4dSAntonio Huete Jimenez return EVP_camellia_192_cbc();
130*de0e0e4dSAntonio Huete Jimenez else if (strcmp(name, "camellia256") == 0)
131*de0e0e4dSAntonio Huete Jimenez return EVP_camellia_256_cbc();
132*de0e0e4dSAntonio Huete Jimenez #endif
133*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DES
134*de0e0e4dSAntonio Huete Jimenez else if (strcmp(name, "des") == 0)
135*de0e0e4dSAntonio Huete Jimenez return EVP_des_cbc();
136*de0e0e4dSAntonio Huete Jimenez else if (strcmp(name, "des3") == 0)
137*de0e0e4dSAntonio Huete Jimenez return EVP_des_ede3_cbc();
138*de0e0e4dSAntonio Huete Jimenez #endif
139*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_RC2
140*de0e0e4dSAntonio Huete Jimenez else if (!strcmp(name, "rc2-40"))
141*de0e0e4dSAntonio Huete Jimenez return EVP_rc2_40_cbc();
142*de0e0e4dSAntonio Huete Jimenez else if (!strcmp(name, "rc2-64"))
143*de0e0e4dSAntonio Huete Jimenez return EVP_rc2_64_cbc();
144*de0e0e4dSAntonio Huete Jimenez else if (!strcmp(name, "rc2-128"))
145*de0e0e4dSAntonio Huete Jimenez return EVP_rc2_cbc();
146*de0e0e4dSAntonio Huete Jimenez #endif
147*de0e0e4dSAntonio Huete Jimenez else
148*de0e0e4dSAntonio Huete Jimenez return NULL;
149*de0e0e4dSAntonio Huete Jimenez }
150*de0e0e4dSAntonio Huete Jimenez
151*de0e0e4dSAntonio Huete Jimenez static int
smime_opt_cipher(int argc,char ** argv,int * argsused)152*de0e0e4dSAntonio Huete Jimenez smime_opt_cipher(int argc, char **argv, int *argsused)
153*de0e0e4dSAntonio Huete Jimenez {
154*de0e0e4dSAntonio Huete Jimenez char *name = argv[0];
155*de0e0e4dSAntonio Huete Jimenez
156*de0e0e4dSAntonio Huete Jimenez if (*name++ != '-')
157*de0e0e4dSAntonio Huete Jimenez return (1);
158*de0e0e4dSAntonio Huete Jimenez
159*de0e0e4dSAntonio Huete Jimenez if ((smime_config.cipher = get_cipher_by_name(name)) == NULL)
160*de0e0e4dSAntonio Huete Jimenez if ((smime_config.cipher = EVP_get_cipherbyname(name)) == NULL)
161*de0e0e4dSAntonio Huete Jimenez return (1);
162*de0e0e4dSAntonio Huete Jimenez
163*de0e0e4dSAntonio Huete Jimenez *argsused = 1;
164*de0e0e4dSAntonio Huete Jimenez return (0);
165*de0e0e4dSAntonio Huete Jimenez }
166*de0e0e4dSAntonio Huete Jimenez
167*de0e0e4dSAntonio Huete Jimenez static int
smime_opt_inkey(char * arg)168*de0e0e4dSAntonio Huete Jimenez smime_opt_inkey(char *arg)
169*de0e0e4dSAntonio Huete Jimenez {
170*de0e0e4dSAntonio Huete Jimenez if (smime_config.keyfile == NULL) {
171*de0e0e4dSAntonio Huete Jimenez smime_config.keyfile = arg;
172*de0e0e4dSAntonio Huete Jimenez return (0);
173*de0e0e4dSAntonio Huete Jimenez }
174*de0e0e4dSAntonio Huete Jimenez
175*de0e0e4dSAntonio Huete Jimenez if (smime_config.signerfile == NULL) {
176*de0e0e4dSAntonio Huete Jimenez BIO_puts(bio_err, "Illegal -inkey without -signer\n");
177*de0e0e4dSAntonio Huete Jimenez return (1);
178*de0e0e4dSAntonio Huete Jimenez }
179*de0e0e4dSAntonio Huete Jimenez
180*de0e0e4dSAntonio Huete Jimenez if (smime_config.sksigners == NULL) {
181*de0e0e4dSAntonio Huete Jimenez if ((smime_config.sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
182*de0e0e4dSAntonio Huete Jimenez return (1);
183*de0e0e4dSAntonio Huete Jimenez }
184*de0e0e4dSAntonio Huete Jimenez if (!sk_OPENSSL_STRING_push(smime_config.sksigners,
185*de0e0e4dSAntonio Huete Jimenez smime_config.signerfile))
186*de0e0e4dSAntonio Huete Jimenez return (1);
187*de0e0e4dSAntonio Huete Jimenez
188*de0e0e4dSAntonio Huete Jimenez smime_config.signerfile = NULL;
189*de0e0e4dSAntonio Huete Jimenez
190*de0e0e4dSAntonio Huete Jimenez if (smime_config.skkeys == NULL) {
191*de0e0e4dSAntonio Huete Jimenez if ((smime_config.skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
192*de0e0e4dSAntonio Huete Jimenez return (1);
193*de0e0e4dSAntonio Huete Jimenez }
194*de0e0e4dSAntonio Huete Jimenez if (!sk_OPENSSL_STRING_push(smime_config.skkeys, smime_config.keyfile))
195*de0e0e4dSAntonio Huete Jimenez return (1);
196*de0e0e4dSAntonio Huete Jimenez
197*de0e0e4dSAntonio Huete Jimenez smime_config.keyfile = arg;
198*de0e0e4dSAntonio Huete Jimenez return (0);
199*de0e0e4dSAntonio Huete Jimenez }
200*de0e0e4dSAntonio Huete Jimenez
201*de0e0e4dSAntonio Huete Jimenez static int
smime_opt_md(char * arg)202*de0e0e4dSAntonio Huete Jimenez smime_opt_md(char *arg)
203*de0e0e4dSAntonio Huete Jimenez {
204*de0e0e4dSAntonio Huete Jimenez if ((smime_config.sign_md = EVP_get_digestbyname(arg)) == NULL) {
205*de0e0e4dSAntonio Huete Jimenez BIO_printf(bio_err, "Unknown digest %s\n", arg);
206*de0e0e4dSAntonio Huete Jimenez return (1);
207*de0e0e4dSAntonio Huete Jimenez }
208*de0e0e4dSAntonio Huete Jimenez return (0);
209*de0e0e4dSAntonio Huete Jimenez }
210*de0e0e4dSAntonio Huete Jimenez
211*de0e0e4dSAntonio Huete Jimenez static int
smime_opt_signer(char * arg)212*de0e0e4dSAntonio Huete Jimenez smime_opt_signer(char *arg)
213*de0e0e4dSAntonio Huete Jimenez {
214*de0e0e4dSAntonio Huete Jimenez if (smime_config.signerfile == NULL) {
215*de0e0e4dSAntonio Huete Jimenez smime_config.signerfile = arg;
216*de0e0e4dSAntonio Huete Jimenez return (0);
217*de0e0e4dSAntonio Huete Jimenez }
218*de0e0e4dSAntonio Huete Jimenez
219*de0e0e4dSAntonio Huete Jimenez if (smime_config.sksigners == NULL) {
220*de0e0e4dSAntonio Huete Jimenez if ((smime_config.sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
221*de0e0e4dSAntonio Huete Jimenez return (1);
222*de0e0e4dSAntonio Huete Jimenez }
223*de0e0e4dSAntonio Huete Jimenez if (!sk_OPENSSL_STRING_push(smime_config.sksigners,
224*de0e0e4dSAntonio Huete Jimenez smime_config.signerfile))
225*de0e0e4dSAntonio Huete Jimenez return (1);
226*de0e0e4dSAntonio Huete Jimenez
227*de0e0e4dSAntonio Huete Jimenez if (smime_config.keyfile == NULL)
228*de0e0e4dSAntonio Huete Jimenez smime_config.keyfile = smime_config.signerfile;
229*de0e0e4dSAntonio Huete Jimenez
230*de0e0e4dSAntonio Huete Jimenez if (smime_config.skkeys == NULL) {
231*de0e0e4dSAntonio Huete Jimenez if ((smime_config.skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
232*de0e0e4dSAntonio Huete Jimenez return (1);
233*de0e0e4dSAntonio Huete Jimenez }
234*de0e0e4dSAntonio Huete Jimenez if (!sk_OPENSSL_STRING_push(smime_config.skkeys, smime_config.keyfile))
235*de0e0e4dSAntonio Huete Jimenez return (1);
236*de0e0e4dSAntonio Huete Jimenez
237*de0e0e4dSAntonio Huete Jimenez smime_config.keyfile = NULL;
238*de0e0e4dSAntonio Huete Jimenez
239*de0e0e4dSAntonio Huete Jimenez smime_config.signerfile = arg;
240*de0e0e4dSAntonio Huete Jimenez return (0);
241*de0e0e4dSAntonio Huete Jimenez }
242*de0e0e4dSAntonio Huete Jimenez
243*de0e0e4dSAntonio Huete Jimenez static int
smime_opt_verify_param(int argc,char ** argv,int * argsused)244*de0e0e4dSAntonio Huete Jimenez smime_opt_verify_param(int argc, char **argv, int *argsused)
245*de0e0e4dSAntonio Huete Jimenez {
246*de0e0e4dSAntonio Huete Jimenez int oargc = argc;
247*de0e0e4dSAntonio Huete Jimenez int badarg = 0;
248*de0e0e4dSAntonio Huete Jimenez
249*de0e0e4dSAntonio Huete Jimenez if (!args_verify(&argv, &argc, &badarg, bio_err, &smime_config.vpm))
250*de0e0e4dSAntonio Huete Jimenez return (1);
251*de0e0e4dSAntonio Huete Jimenez if (badarg)
252*de0e0e4dSAntonio Huete Jimenez return (1);
253*de0e0e4dSAntonio Huete Jimenez
254*de0e0e4dSAntonio Huete Jimenez *argsused = oargc - argc;
255*de0e0e4dSAntonio Huete Jimenez
256*de0e0e4dSAntonio Huete Jimenez return (0);
257*de0e0e4dSAntonio Huete Jimenez }
258*de0e0e4dSAntonio Huete Jimenez
259*de0e0e4dSAntonio Huete Jimenez static const struct option smime_options[] = {
260*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_AES
261*de0e0e4dSAntonio Huete Jimenez {
262*de0e0e4dSAntonio Huete Jimenez .name = "aes128",
263*de0e0e4dSAntonio Huete Jimenez .desc = "Encrypt PEM output with CBC AES",
264*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
265*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_cipher,
266*de0e0e4dSAntonio Huete Jimenez },
267*de0e0e4dSAntonio Huete Jimenez {
268*de0e0e4dSAntonio Huete Jimenez .name = "aes192",
269*de0e0e4dSAntonio Huete Jimenez .desc = "Encrypt PEM output with CBC AES",
270*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
271*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_cipher,
272*de0e0e4dSAntonio Huete Jimenez },
273*de0e0e4dSAntonio Huete Jimenez {
274*de0e0e4dSAntonio Huete Jimenez .name = "aes256",
275*de0e0e4dSAntonio Huete Jimenez .desc = "Encrypt PEM output with CBC AES",
276*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
277*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_cipher,
278*de0e0e4dSAntonio Huete Jimenez },
279*de0e0e4dSAntonio Huete Jimenez #endif
280*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_CAMELLIA
281*de0e0e4dSAntonio Huete Jimenez {
282*de0e0e4dSAntonio Huete Jimenez .name = "camellia128",
283*de0e0e4dSAntonio Huete Jimenez .desc = "Encrypt PEM output with CBC Camellia",
284*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
285*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_cipher,
286*de0e0e4dSAntonio Huete Jimenez },
287*de0e0e4dSAntonio Huete Jimenez {
288*de0e0e4dSAntonio Huete Jimenez .name = "camellia192",
289*de0e0e4dSAntonio Huete Jimenez .desc = "Encrypt PEM output with CBC Camellia",
290*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
291*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_cipher,
292*de0e0e4dSAntonio Huete Jimenez },
293*de0e0e4dSAntonio Huete Jimenez {
294*de0e0e4dSAntonio Huete Jimenez .name = "camellia256",
295*de0e0e4dSAntonio Huete Jimenez .desc = "Encrypt PEM output with CBC Camellia",
296*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
297*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_cipher,
298*de0e0e4dSAntonio Huete Jimenez },
299*de0e0e4dSAntonio Huete Jimenez #endif
300*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_DES
301*de0e0e4dSAntonio Huete Jimenez {
302*de0e0e4dSAntonio Huete Jimenez .name = "des",
303*de0e0e4dSAntonio Huete Jimenez .desc = "Encrypt with DES",
304*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
305*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_cipher,
306*de0e0e4dSAntonio Huete Jimenez },
307*de0e0e4dSAntonio Huete Jimenez {
308*de0e0e4dSAntonio Huete Jimenez .name = "des3",
309*de0e0e4dSAntonio Huete Jimenez .desc = "Encrypt with triple DES",
310*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
311*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_cipher,
312*de0e0e4dSAntonio Huete Jimenez },
313*de0e0e4dSAntonio Huete Jimenez #endif
314*de0e0e4dSAntonio Huete Jimenez #ifndef OPENSSL_NO_RC2
315*de0e0e4dSAntonio Huete Jimenez {
316*de0e0e4dSAntonio Huete Jimenez .name = "rc2-40",
317*de0e0e4dSAntonio Huete Jimenez .desc = "Encrypt with RC2-40 (default)",
318*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
319*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_cipher,
320*de0e0e4dSAntonio Huete Jimenez },
321*de0e0e4dSAntonio Huete Jimenez {
322*de0e0e4dSAntonio Huete Jimenez .name = "rc2-64",
323*de0e0e4dSAntonio Huete Jimenez .desc = "Encrypt with RC2-64",
324*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
325*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_cipher,
326*de0e0e4dSAntonio Huete Jimenez },
327*de0e0e4dSAntonio Huete Jimenez {
328*de0e0e4dSAntonio Huete Jimenez .name = "rc2-128",
329*de0e0e4dSAntonio Huete Jimenez .desc = "Encrypt with RC2-128",
330*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
331*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_cipher,
332*de0e0e4dSAntonio Huete Jimenez },
333*de0e0e4dSAntonio Huete Jimenez #endif
334*de0e0e4dSAntonio Huete Jimenez {
335*de0e0e4dSAntonio Huete Jimenez .name = "CAfile",
336*de0e0e4dSAntonio Huete Jimenez .argname = "file",
337*de0e0e4dSAntonio Huete Jimenez .desc = "Certificate Authority file",
338*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG,
339*de0e0e4dSAntonio Huete Jimenez .opt.arg = &smime_config.CAfile,
340*de0e0e4dSAntonio Huete Jimenez },
341*de0e0e4dSAntonio Huete Jimenez {
342*de0e0e4dSAntonio Huete Jimenez .name = "CApath",
343*de0e0e4dSAntonio Huete Jimenez .argname = "path",
344*de0e0e4dSAntonio Huete Jimenez .desc = "Certificate Authority path",
345*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG,
346*de0e0e4dSAntonio Huete Jimenez .opt.arg = &smime_config.CApath,
347*de0e0e4dSAntonio Huete Jimenez },
348*de0e0e4dSAntonio Huete Jimenez {
349*de0e0e4dSAntonio Huete Jimenez .name = "binary",
350*de0e0e4dSAntonio Huete Jimenez .desc = "Do not translate message to text",
351*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE_OR,
352*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.flags,
353*de0e0e4dSAntonio Huete Jimenez .value = PKCS7_BINARY,
354*de0e0e4dSAntonio Huete Jimenez },
355*de0e0e4dSAntonio Huete Jimenez {
356*de0e0e4dSAntonio Huete Jimenez .name = "certfile",
357*de0e0e4dSAntonio Huete Jimenez .argname = "file",
358*de0e0e4dSAntonio Huete Jimenez .desc = "Other certificates file",
359*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG,
360*de0e0e4dSAntonio Huete Jimenez .opt.arg = &smime_config.certfile,
361*de0e0e4dSAntonio Huete Jimenez },
362*de0e0e4dSAntonio Huete Jimenez {
363*de0e0e4dSAntonio Huete Jimenez .name = "content",
364*de0e0e4dSAntonio Huete Jimenez .argname = "file",
365*de0e0e4dSAntonio Huete Jimenez .desc = "Supply or override content for detached signature",
366*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG,
367*de0e0e4dSAntonio Huete Jimenez .opt.arg = &smime_config.contfile,
368*de0e0e4dSAntonio Huete Jimenez },
369*de0e0e4dSAntonio Huete Jimenez {
370*de0e0e4dSAntonio Huete Jimenez .name = "crlfeol",
371*de0e0e4dSAntonio Huete Jimenez .desc = "Use CRLF as EOL termination instead of CR only",
372*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE_OR,
373*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.flags,
374*de0e0e4dSAntonio Huete Jimenez .value = PKCS7_CRLFEOL,
375*de0e0e4dSAntonio Huete Jimenez },
376*de0e0e4dSAntonio Huete Jimenez {
377*de0e0e4dSAntonio Huete Jimenez .name = "decrypt",
378*de0e0e4dSAntonio Huete Jimenez .desc = "Decrypt encrypted message",
379*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE,
380*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.operation,
381*de0e0e4dSAntonio Huete Jimenez .value = SMIME_DECRYPT,
382*de0e0e4dSAntonio Huete Jimenez },
383*de0e0e4dSAntonio Huete Jimenez {
384*de0e0e4dSAntonio Huete Jimenez .name = "encrypt",
385*de0e0e4dSAntonio Huete Jimenez .desc = "Encrypt message",
386*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE,
387*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.operation,
388*de0e0e4dSAntonio Huete Jimenez .value = SMIME_ENCRYPT,
389*de0e0e4dSAntonio Huete Jimenez },
390*de0e0e4dSAntonio Huete Jimenez {
391*de0e0e4dSAntonio Huete Jimenez .name = "from",
392*de0e0e4dSAntonio Huete Jimenez .argname = "addr",
393*de0e0e4dSAntonio Huete Jimenez .desc = "From address",
394*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG,
395*de0e0e4dSAntonio Huete Jimenez .opt.arg = &smime_config.from,
396*de0e0e4dSAntonio Huete Jimenez },
397*de0e0e4dSAntonio Huete Jimenez {
398*de0e0e4dSAntonio Huete Jimenez .name = "in",
399*de0e0e4dSAntonio Huete Jimenez .argname = "file",
400*de0e0e4dSAntonio Huete Jimenez .desc = "Input file",
401*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG,
402*de0e0e4dSAntonio Huete Jimenez .opt.arg = &smime_config.infile,
403*de0e0e4dSAntonio Huete Jimenez },
404*de0e0e4dSAntonio Huete Jimenez {
405*de0e0e4dSAntonio Huete Jimenez .name = "indef",
406*de0e0e4dSAntonio Huete Jimenez .desc = "Same as -stream",
407*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE,
408*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.indef,
409*de0e0e4dSAntonio Huete Jimenez .value = 1,
410*de0e0e4dSAntonio Huete Jimenez },
411*de0e0e4dSAntonio Huete Jimenez {
412*de0e0e4dSAntonio Huete Jimenez .name = "inform",
413*de0e0e4dSAntonio Huete Jimenez .argname = "fmt",
414*de0e0e4dSAntonio Huete Jimenez .desc = "Input format (DER, PEM or SMIME (default))",
415*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG_FORMAT,
416*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.informat,
417*de0e0e4dSAntonio Huete Jimenez },
418*de0e0e4dSAntonio Huete Jimenez {
419*de0e0e4dSAntonio Huete Jimenez .name = "inkey",
420*de0e0e4dSAntonio Huete Jimenez .argname = "file",
421*de0e0e4dSAntonio Huete Jimenez .desc = "Input key file",
422*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG_FUNC,
423*de0e0e4dSAntonio Huete Jimenez .opt.argfunc = smime_opt_inkey,
424*de0e0e4dSAntonio Huete Jimenez },
425*de0e0e4dSAntonio Huete Jimenez {
426*de0e0e4dSAntonio Huete Jimenez .name = "keyform",
427*de0e0e4dSAntonio Huete Jimenez .argname = "fmt",
428*de0e0e4dSAntonio Huete Jimenez .desc = "Input key format (DER or PEM (default))",
429*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG_FORMAT,
430*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.keyform,
431*de0e0e4dSAntonio Huete Jimenez },
432*de0e0e4dSAntonio Huete Jimenez {
433*de0e0e4dSAntonio Huete Jimenez .name = "md",
434*de0e0e4dSAntonio Huete Jimenez .argname = "digest",
435*de0e0e4dSAntonio Huete Jimenez .desc = "Digest to use when signing or resigning",
436*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG_FUNC,
437*de0e0e4dSAntonio Huete Jimenez .opt.argfunc = smime_opt_md,
438*de0e0e4dSAntonio Huete Jimenez },
439*de0e0e4dSAntonio Huete Jimenez {
440*de0e0e4dSAntonio Huete Jimenez .name = "noattr",
441*de0e0e4dSAntonio Huete Jimenez .desc = "Do not include any signed attributes",
442*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE_OR,
443*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.flags,
444*de0e0e4dSAntonio Huete Jimenez .value = PKCS7_NOATTR,
445*de0e0e4dSAntonio Huete Jimenez },
446*de0e0e4dSAntonio Huete Jimenez {
447*de0e0e4dSAntonio Huete Jimenez .name = "nocerts",
448*de0e0e4dSAntonio Huete Jimenez .desc = "Do not include signer's certificate when signing",
449*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE_OR,
450*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.flags,
451*de0e0e4dSAntonio Huete Jimenez .value = PKCS7_NOCERTS,
452*de0e0e4dSAntonio Huete Jimenez },
453*de0e0e4dSAntonio Huete Jimenez {
454*de0e0e4dSAntonio Huete Jimenez .name = "nochain",
455*de0e0e4dSAntonio Huete Jimenez .desc = "Do not chain verification of signer's certificates",
456*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE_OR,
457*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.flags,
458*de0e0e4dSAntonio Huete Jimenez .value = PKCS7_NOCHAIN,
459*de0e0e4dSAntonio Huete Jimenez },
460*de0e0e4dSAntonio Huete Jimenez {
461*de0e0e4dSAntonio Huete Jimenez .name = "nodetach",
462*de0e0e4dSAntonio Huete Jimenez .desc = "Use opaque signing",
463*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE_AND,
464*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.flags,
465*de0e0e4dSAntonio Huete Jimenez .value = ~PKCS7_DETACHED,
466*de0e0e4dSAntonio Huete Jimenez },
467*de0e0e4dSAntonio Huete Jimenez {
468*de0e0e4dSAntonio Huete Jimenez .name = "noindef",
469*de0e0e4dSAntonio Huete Jimenez .desc = "Disable streaming I/O",
470*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE,
471*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.indef,
472*de0e0e4dSAntonio Huete Jimenez .value = 0,
473*de0e0e4dSAntonio Huete Jimenez },
474*de0e0e4dSAntonio Huete Jimenez {
475*de0e0e4dSAntonio Huete Jimenez .name = "nointern",
476*de0e0e4dSAntonio Huete Jimenez .desc = "Do not search certificates in message for signer",
477*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE_OR,
478*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.flags,
479*de0e0e4dSAntonio Huete Jimenez .value = PKCS7_NOINTERN,
480*de0e0e4dSAntonio Huete Jimenez },
481*de0e0e4dSAntonio Huete Jimenez {
482*de0e0e4dSAntonio Huete Jimenez .name = "nooldmime",
483*de0e0e4dSAntonio Huete Jimenez .desc = "Output old S/MIME content type",
484*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE_OR,
485*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.flags,
486*de0e0e4dSAntonio Huete Jimenez .value = PKCS7_NOOLDMIMETYPE,
487*de0e0e4dSAntonio Huete Jimenez },
488*de0e0e4dSAntonio Huete Jimenez {
489*de0e0e4dSAntonio Huete Jimenez .name = "nosigs",
490*de0e0e4dSAntonio Huete Jimenez .desc = "Do not verify message signature",
491*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE_OR,
492*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.flags,
493*de0e0e4dSAntonio Huete Jimenez .value = PKCS7_NOSIGS,
494*de0e0e4dSAntonio Huete Jimenez },
495*de0e0e4dSAntonio Huete Jimenez {
496*de0e0e4dSAntonio Huete Jimenez .name = "nosmimecap",
497*de0e0e4dSAntonio Huete Jimenez .desc = "Omit the SMIMECapabilities attribute",
498*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE_OR,
499*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.flags,
500*de0e0e4dSAntonio Huete Jimenez .value = PKCS7_NOSMIMECAP,
501*de0e0e4dSAntonio Huete Jimenez },
502*de0e0e4dSAntonio Huete Jimenez {
503*de0e0e4dSAntonio Huete Jimenez .name = "noverify",
504*de0e0e4dSAntonio Huete Jimenez .desc = "Do not verify signer's certificate",
505*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE_OR,
506*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.flags,
507*de0e0e4dSAntonio Huete Jimenez .value = PKCS7_NOVERIFY,
508*de0e0e4dSAntonio Huete Jimenez },
509*de0e0e4dSAntonio Huete Jimenez {
510*de0e0e4dSAntonio Huete Jimenez .name = "out",
511*de0e0e4dSAntonio Huete Jimenez .argname = "file",
512*de0e0e4dSAntonio Huete Jimenez .desc = "Output file",
513*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG,
514*de0e0e4dSAntonio Huete Jimenez .opt.arg = &smime_config.outfile,
515*de0e0e4dSAntonio Huete Jimenez },
516*de0e0e4dSAntonio Huete Jimenez {
517*de0e0e4dSAntonio Huete Jimenez .name = "outform",
518*de0e0e4dSAntonio Huete Jimenez .argname = "fmt",
519*de0e0e4dSAntonio Huete Jimenez .desc = "Output format (DER, PEM or SMIME (default))",
520*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG_FORMAT,
521*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.outformat,
522*de0e0e4dSAntonio Huete Jimenez },
523*de0e0e4dSAntonio Huete Jimenez {
524*de0e0e4dSAntonio Huete Jimenez .name = "passin",
525*de0e0e4dSAntonio Huete Jimenez .argname = "src",
526*de0e0e4dSAntonio Huete Jimenez .desc = "Private key password source",
527*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG,
528*de0e0e4dSAntonio Huete Jimenez .opt.arg = &smime_config.passargin,
529*de0e0e4dSAntonio Huete Jimenez },
530*de0e0e4dSAntonio Huete Jimenez {
531*de0e0e4dSAntonio Huete Jimenez .name = "pk7out",
532*de0e0e4dSAntonio Huete Jimenez .desc = "Output PKCS#7 structure",
533*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE,
534*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.operation,
535*de0e0e4dSAntonio Huete Jimenez .value = SMIME_PK7OUT,
536*de0e0e4dSAntonio Huete Jimenez },
537*de0e0e4dSAntonio Huete Jimenez {
538*de0e0e4dSAntonio Huete Jimenez .name = "recip",
539*de0e0e4dSAntonio Huete Jimenez .argname = "file",
540*de0e0e4dSAntonio Huete Jimenez .desc = "Recipient certificate file for decryption",
541*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG,
542*de0e0e4dSAntonio Huete Jimenez .opt.arg = &smime_config.recipfile,
543*de0e0e4dSAntonio Huete Jimenez },
544*de0e0e4dSAntonio Huete Jimenez {
545*de0e0e4dSAntonio Huete Jimenez .name = "resign",
546*de0e0e4dSAntonio Huete Jimenez .desc = "Resign a signed message",
547*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE,
548*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.operation,
549*de0e0e4dSAntonio Huete Jimenez .value = SMIME_RESIGN,
550*de0e0e4dSAntonio Huete Jimenez },
551*de0e0e4dSAntonio Huete Jimenez {
552*de0e0e4dSAntonio Huete Jimenez .name = "sign",
553*de0e0e4dSAntonio Huete Jimenez .desc = "Sign message",
554*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE,
555*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.operation,
556*de0e0e4dSAntonio Huete Jimenez .value = SMIME_SIGN,
557*de0e0e4dSAntonio Huete Jimenez },
558*de0e0e4dSAntonio Huete Jimenez {
559*de0e0e4dSAntonio Huete Jimenez .name = "signer",
560*de0e0e4dSAntonio Huete Jimenez .argname = "file",
561*de0e0e4dSAntonio Huete Jimenez .desc = "Signer certificate file",
562*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG_FUNC,
563*de0e0e4dSAntonio Huete Jimenez .opt.argfunc = smime_opt_signer,
564*de0e0e4dSAntonio Huete Jimenez },
565*de0e0e4dSAntonio Huete Jimenez {
566*de0e0e4dSAntonio Huete Jimenez .name = "stream",
567*de0e0e4dSAntonio Huete Jimenez .desc = "Enable streaming I/O",
568*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE,
569*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.indef,
570*de0e0e4dSAntonio Huete Jimenez .value = 1,
571*de0e0e4dSAntonio Huete Jimenez },
572*de0e0e4dSAntonio Huete Jimenez {
573*de0e0e4dSAntonio Huete Jimenez .name = "subject",
574*de0e0e4dSAntonio Huete Jimenez .argname = "s",
575*de0e0e4dSAntonio Huete Jimenez .desc = "Subject",
576*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG,
577*de0e0e4dSAntonio Huete Jimenez .opt.arg = &smime_config.subject,
578*de0e0e4dSAntonio Huete Jimenez },
579*de0e0e4dSAntonio Huete Jimenez {
580*de0e0e4dSAntonio Huete Jimenez .name = "text",
581*de0e0e4dSAntonio Huete Jimenez .desc = "Include or delete text MIME headers",
582*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE_OR,
583*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.flags,
584*de0e0e4dSAntonio Huete Jimenez .value = PKCS7_TEXT,
585*de0e0e4dSAntonio Huete Jimenez },
586*de0e0e4dSAntonio Huete Jimenez {
587*de0e0e4dSAntonio Huete Jimenez .name = "to",
588*de0e0e4dSAntonio Huete Jimenez .argname = "addr",
589*de0e0e4dSAntonio Huete Jimenez .desc = "To address",
590*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARG,
591*de0e0e4dSAntonio Huete Jimenez .opt.arg = &smime_config.to,
592*de0e0e4dSAntonio Huete Jimenez },
593*de0e0e4dSAntonio Huete Jimenez {
594*de0e0e4dSAntonio Huete Jimenez .name = "verify",
595*de0e0e4dSAntonio Huete Jimenez .desc = "Verify signed message",
596*de0e0e4dSAntonio Huete Jimenez .type = OPTION_VALUE,
597*de0e0e4dSAntonio Huete Jimenez .opt.value = &smime_config.operation,
598*de0e0e4dSAntonio Huete Jimenez .value = SMIME_VERIFY,
599*de0e0e4dSAntonio Huete Jimenez },
600*de0e0e4dSAntonio Huete Jimenez {
601*de0e0e4dSAntonio Huete Jimenez .name = "check_ss_sig",
602*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
603*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_verify_param,
604*de0e0e4dSAntonio Huete Jimenez },
605*de0e0e4dSAntonio Huete Jimenez {
606*de0e0e4dSAntonio Huete Jimenez .name = "crl_check",
607*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
608*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_verify_param,
609*de0e0e4dSAntonio Huete Jimenez },
610*de0e0e4dSAntonio Huete Jimenez {
611*de0e0e4dSAntonio Huete Jimenez .name = "crl_check_all",
612*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
613*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_verify_param,
614*de0e0e4dSAntonio Huete Jimenez },
615*de0e0e4dSAntonio Huete Jimenez {
616*de0e0e4dSAntonio Huete Jimenez .name = "extended_crl",
617*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
618*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_verify_param,
619*de0e0e4dSAntonio Huete Jimenez },
620*de0e0e4dSAntonio Huete Jimenez {
621*de0e0e4dSAntonio Huete Jimenez .name = "ignore_critical",
622*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
623*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_verify_param,
624*de0e0e4dSAntonio Huete Jimenez },
625*de0e0e4dSAntonio Huete Jimenez {
626*de0e0e4dSAntonio Huete Jimenez .name = "issuer_checks",
627*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
628*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_verify_param,
629*de0e0e4dSAntonio Huete Jimenez },
630*de0e0e4dSAntonio Huete Jimenez {
631*de0e0e4dSAntonio Huete Jimenez .name = "policy_check",
632*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
633*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_verify_param,
634*de0e0e4dSAntonio Huete Jimenez },
635*de0e0e4dSAntonio Huete Jimenez {
636*de0e0e4dSAntonio Huete Jimenez .name = "x509_strict",
637*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
638*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_verify_param,
639*de0e0e4dSAntonio Huete Jimenez },
640*de0e0e4dSAntonio Huete Jimenez {
641*de0e0e4dSAntonio Huete Jimenez .name = NULL,
642*de0e0e4dSAntonio Huete Jimenez .type = OPTION_ARGV_FUNC,
643*de0e0e4dSAntonio Huete Jimenez .opt.argvfunc = smime_opt_cipher,
644*de0e0e4dSAntonio Huete Jimenez },
645*de0e0e4dSAntonio Huete Jimenez { NULL },
646*de0e0e4dSAntonio Huete Jimenez };
647*de0e0e4dSAntonio Huete Jimenez
648*de0e0e4dSAntonio Huete Jimenez static const struct option verify_shared_options[] = {
649*de0e0e4dSAntonio Huete Jimenez {
650*de0e0e4dSAntonio Huete Jimenez .name = "check_ss_sig",
651*de0e0e4dSAntonio Huete Jimenez .desc = "Check the root CA self-signed certificate signature",
652*de0e0e4dSAntonio Huete Jimenez },
653*de0e0e4dSAntonio Huete Jimenez {
654*de0e0e4dSAntonio Huete Jimenez .name = "crl_check",
655*de0e0e4dSAntonio Huete Jimenez .desc = "Enable CRL checking for the leaf certificate",
656*de0e0e4dSAntonio Huete Jimenez },
657*de0e0e4dSAntonio Huete Jimenez {
658*de0e0e4dSAntonio Huete Jimenez .name = "crl_check_all",
659*de0e0e4dSAntonio Huete Jimenez .desc = "Enable CRL checking for the entire certificate chain",
660*de0e0e4dSAntonio Huete Jimenez },
661*de0e0e4dSAntonio Huete Jimenez {
662*de0e0e4dSAntonio Huete Jimenez .name = "extended_crl",
663*de0e0e4dSAntonio Huete Jimenez .desc = "Enable extended CRL support",
664*de0e0e4dSAntonio Huete Jimenez },
665*de0e0e4dSAntonio Huete Jimenez {
666*de0e0e4dSAntonio Huete Jimenez .name = "ignore_critical",
667*de0e0e4dSAntonio Huete Jimenez .desc = "Disable critical extension checking",
668*de0e0e4dSAntonio Huete Jimenez },
669*de0e0e4dSAntonio Huete Jimenez {
670*de0e0e4dSAntonio Huete Jimenez .name = "issuer_checks",
671*de0e0e4dSAntonio Huete Jimenez .desc = "Enable debugging of certificate issuer checks",
672*de0e0e4dSAntonio Huete Jimenez },
673*de0e0e4dSAntonio Huete Jimenez {
674*de0e0e4dSAntonio Huete Jimenez .name = "policy_check",
675*de0e0e4dSAntonio Huete Jimenez .desc = "Enable certificate policy checking",
676*de0e0e4dSAntonio Huete Jimenez },
677*de0e0e4dSAntonio Huete Jimenez {
678*de0e0e4dSAntonio Huete Jimenez .name = "x509_strict",
679*de0e0e4dSAntonio Huete Jimenez .desc = "Use strict X.509 rules (disables workarounds)",
680*de0e0e4dSAntonio Huete Jimenez },
681*de0e0e4dSAntonio Huete Jimenez { NULL },
682*de0e0e4dSAntonio Huete Jimenez };
683*de0e0e4dSAntonio Huete Jimenez
684*de0e0e4dSAntonio Huete Jimenez static void
smime_usage(void)685*de0e0e4dSAntonio Huete Jimenez smime_usage(void)
686*de0e0e4dSAntonio Huete Jimenez {
687*de0e0e4dSAntonio Huete Jimenez fprintf(stderr, "usage: smime "
688*de0e0e4dSAntonio Huete Jimenez "[-aes128 | -aes192 | -aes256 | -des |\n"
689*de0e0e4dSAntonio Huete Jimenez " -des3 | -rc2-40 | -rc2-64 | -rc2-128] [-binary]\n"
690*de0e0e4dSAntonio Huete Jimenez " [-CAfile file] [-CApath directory] [-certfile file]\n"
691*de0e0e4dSAntonio Huete Jimenez " [-content file]\n"
692*de0e0e4dSAntonio Huete Jimenez " [-decrypt] [-encrypt]\n"
693*de0e0e4dSAntonio Huete Jimenez " [-from addr] [-in file] [-indef]\n"
694*de0e0e4dSAntonio Huete Jimenez " [-inform der | pem | smime] [-inkey file]\n"
695*de0e0e4dSAntonio Huete Jimenez " [-keyform der | pem] [-md digest] [-noattr] [-nocerts]\n"
696*de0e0e4dSAntonio Huete Jimenez " [-nochain] [-nodetach] [-noindef] [-nointern] [-nosigs]\n"
697*de0e0e4dSAntonio Huete Jimenez " [-nosmimecap] [-noverify] [-out file]\n"
698*de0e0e4dSAntonio Huete Jimenez " [-outform der | pem | smime] [-passin arg] [-pk7out]\n"
699*de0e0e4dSAntonio Huete Jimenez " [-recip file] [-resign] [-sign]\n"
700*de0e0e4dSAntonio Huete Jimenez " [-signer file] [-stream] [-subject s] [-text] [-to addr]\n"
701*de0e0e4dSAntonio Huete Jimenez " [-verify] [cert.pem ...]\n\n");
702*de0e0e4dSAntonio Huete Jimenez
703*de0e0e4dSAntonio Huete Jimenez options_usage(smime_options);
704*de0e0e4dSAntonio Huete Jimenez
705*de0e0e4dSAntonio Huete Jimenez fprintf(stderr, "\nVerification options:\n\n");
706*de0e0e4dSAntonio Huete Jimenez options_usage(verify_shared_options);
707*de0e0e4dSAntonio Huete Jimenez }
708*de0e0e4dSAntonio Huete Jimenez
709f5b1c8a1SJohn Marino int
smime_main(int argc,char ** argv)710f5b1c8a1SJohn Marino smime_main(int argc, char **argv)
711f5b1c8a1SJohn Marino {
712f5b1c8a1SJohn Marino int ret = 0;
713f5b1c8a1SJohn Marino char **args;
714*de0e0e4dSAntonio Huete Jimenez int argsused = 0;
715f5b1c8a1SJohn Marino const char *inmode = "r", *outmode = "w";
716f5b1c8a1SJohn Marino PKCS7 *p7 = NULL;
717f5b1c8a1SJohn Marino X509_STORE *store = NULL;
718f5b1c8a1SJohn Marino X509 *cert = NULL, *recip = NULL, *signer = NULL;
719f5b1c8a1SJohn Marino EVP_PKEY *key = NULL;
720f5b1c8a1SJohn Marino STACK_OF(X509) *encerts = NULL, *other = NULL;
721f5b1c8a1SJohn Marino BIO *in = NULL, *out = NULL, *indata = NULL;
722f5b1c8a1SJohn Marino int badarg = 0;
723*de0e0e4dSAntonio Huete Jimenez char *passin = NULL;
724f5b1c8a1SJohn Marino
725f5b1c8a1SJohn Marino if (single_execution) {
72672c33676SMaxim Ag if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
727f5b1c8a1SJohn Marino perror("pledge");
728f5b1c8a1SJohn Marino exit(1);
729f5b1c8a1SJohn Marino }
730f5b1c8a1SJohn Marino }
731f5b1c8a1SJohn Marino
732*de0e0e4dSAntonio Huete Jimenez memset(&smime_config, 0, sizeof(smime_config));
733*de0e0e4dSAntonio Huete Jimenez smime_config.flags = PKCS7_DETACHED;
734*de0e0e4dSAntonio Huete Jimenez smime_config.informat = FORMAT_SMIME;
735*de0e0e4dSAntonio Huete Jimenez smime_config.outformat = FORMAT_SMIME;
736*de0e0e4dSAntonio Huete Jimenez smime_config.keyform = FORMAT_PEM;
737*de0e0e4dSAntonio Huete Jimenez if (options_parse(argc, argv, smime_options, NULL, &argsused) != 0) {
738*de0e0e4dSAntonio Huete Jimenez goto argerr;
739*de0e0e4dSAntonio Huete Jimenez }
740*de0e0e4dSAntonio Huete Jimenez args = argv + argsused;
741f5b1c8a1SJohn Marino ret = 1;
742f5b1c8a1SJohn Marino
743*de0e0e4dSAntonio Huete Jimenez if (!(smime_config.operation & SMIME_SIGNERS) &&
744*de0e0e4dSAntonio Huete Jimenez (smime_config.skkeys != NULL || smime_config.sksigners != NULL)) {
745f5b1c8a1SJohn Marino BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
746f5b1c8a1SJohn Marino goto argerr;
747f5b1c8a1SJohn Marino }
748*de0e0e4dSAntonio Huete Jimenez if (smime_config.operation & SMIME_SIGNERS) {
749f5b1c8a1SJohn Marino /* Check to see if any final signer needs to be appended */
750*de0e0e4dSAntonio Huete Jimenez if (smime_config.keyfile != NULL &&
751*de0e0e4dSAntonio Huete Jimenez smime_config.signerfile == NULL) {
752f5b1c8a1SJohn Marino BIO_puts(bio_err, "Illegal -inkey without -signer\n");
753f5b1c8a1SJohn Marino goto argerr;
754f5b1c8a1SJohn Marino }
755*de0e0e4dSAntonio Huete Jimenez if (smime_config.signerfile != NULL) {
756*de0e0e4dSAntonio Huete Jimenez if (smime_config.sksigners == NULL) {
757*de0e0e4dSAntonio Huete Jimenez if ((smime_config.sksigners =
758*de0e0e4dSAntonio Huete Jimenez sk_OPENSSL_STRING_new_null()) == NULL)
759*de0e0e4dSAntonio Huete Jimenez goto end;
760f5b1c8a1SJohn Marino }
761*de0e0e4dSAntonio Huete Jimenez if (!sk_OPENSSL_STRING_push(smime_config.sksigners,
762*de0e0e4dSAntonio Huete Jimenez smime_config.signerfile))
763*de0e0e4dSAntonio Huete Jimenez goto end;
764*de0e0e4dSAntonio Huete Jimenez if (smime_config.skkeys == NULL) {
765*de0e0e4dSAntonio Huete Jimenez if ((smime_config.skkeys =
766*de0e0e4dSAntonio Huete Jimenez sk_OPENSSL_STRING_new_null()) == NULL)
767*de0e0e4dSAntonio Huete Jimenez goto end;
768*de0e0e4dSAntonio Huete Jimenez }
769*de0e0e4dSAntonio Huete Jimenez if (smime_config.keyfile == NULL)
770*de0e0e4dSAntonio Huete Jimenez smime_config.keyfile = smime_config.signerfile;
771*de0e0e4dSAntonio Huete Jimenez if (!sk_OPENSSL_STRING_push(smime_config.skkeys,
772*de0e0e4dSAntonio Huete Jimenez smime_config.keyfile))
773*de0e0e4dSAntonio Huete Jimenez goto end;
774*de0e0e4dSAntonio Huete Jimenez }
775*de0e0e4dSAntonio Huete Jimenez if (smime_config.sksigners == NULL) {
776*de0e0e4dSAntonio Huete Jimenez BIO_printf(bio_err,
777*de0e0e4dSAntonio Huete Jimenez "No signer certificate specified\n");
778f5b1c8a1SJohn Marino badarg = 1;
779f5b1c8a1SJohn Marino }
780*de0e0e4dSAntonio Huete Jimenez smime_config.signerfile = NULL;
781*de0e0e4dSAntonio Huete Jimenez smime_config.keyfile = NULL;
782*de0e0e4dSAntonio Huete Jimenez } else if (smime_config.operation == SMIME_DECRYPT) {
783*de0e0e4dSAntonio Huete Jimenez if (smime_config.recipfile == NULL &&
784*de0e0e4dSAntonio Huete Jimenez smime_config.keyfile == NULL) {
785*de0e0e4dSAntonio Huete Jimenez BIO_printf(bio_err,
786*de0e0e4dSAntonio Huete Jimenez "No recipient certificate or key specified\n");
787f5b1c8a1SJohn Marino badarg = 1;
788f5b1c8a1SJohn Marino }
789*de0e0e4dSAntonio Huete Jimenez } else if (smime_config.operation == SMIME_ENCRYPT) {
790*de0e0e4dSAntonio Huete Jimenez if (*args == NULL) {
791*de0e0e4dSAntonio Huete Jimenez BIO_printf(bio_err,
792*de0e0e4dSAntonio Huete Jimenez "No recipient(s) certificate(s) specified\n");
793f5b1c8a1SJohn Marino badarg = 1;
794f5b1c8a1SJohn Marino }
795*de0e0e4dSAntonio Huete Jimenez } else if (!smime_config.operation) {
796f5b1c8a1SJohn Marino badarg = 1;
797*de0e0e4dSAntonio Huete Jimenez }
798f5b1c8a1SJohn Marino
799f5b1c8a1SJohn Marino if (badarg) {
800f5b1c8a1SJohn Marino argerr:
801*de0e0e4dSAntonio Huete Jimenez smime_usage();
802f5b1c8a1SJohn Marino goto end;
803f5b1c8a1SJohn Marino }
804f5b1c8a1SJohn Marino
805*de0e0e4dSAntonio Huete Jimenez if (!app_passwd(bio_err, smime_config.passargin, NULL, &passin, NULL)) {
806f5b1c8a1SJohn Marino BIO_printf(bio_err, "Error getting password\n");
807f5b1c8a1SJohn Marino goto end;
808f5b1c8a1SJohn Marino }
809f5b1c8a1SJohn Marino ret = 2;
810f5b1c8a1SJohn Marino
811*de0e0e4dSAntonio Huete Jimenez if (!(smime_config.operation & SMIME_SIGNERS))
812*de0e0e4dSAntonio Huete Jimenez smime_config.flags &= ~PKCS7_DETACHED;
813f5b1c8a1SJohn Marino
814*de0e0e4dSAntonio Huete Jimenez if (smime_config.operation & SMIME_OP) {
815*de0e0e4dSAntonio Huete Jimenez if (smime_config.outformat == FORMAT_ASN1)
816f5b1c8a1SJohn Marino outmode = "wb";
817f5b1c8a1SJohn Marino } else {
818*de0e0e4dSAntonio Huete Jimenez if (smime_config.flags & PKCS7_BINARY)
819f5b1c8a1SJohn Marino outmode = "wb";
820f5b1c8a1SJohn Marino }
821f5b1c8a1SJohn Marino
822*de0e0e4dSAntonio Huete Jimenez if (smime_config.operation & SMIME_IP) {
823*de0e0e4dSAntonio Huete Jimenez if (smime_config.informat == FORMAT_ASN1)
824f5b1c8a1SJohn Marino inmode = "rb";
825f5b1c8a1SJohn Marino } else {
826*de0e0e4dSAntonio Huete Jimenez if (smime_config.flags & PKCS7_BINARY)
827f5b1c8a1SJohn Marino inmode = "rb";
828f5b1c8a1SJohn Marino }
829f5b1c8a1SJohn Marino
830*de0e0e4dSAntonio Huete Jimenez if (smime_config.operation == SMIME_ENCRYPT) {
831*de0e0e4dSAntonio Huete Jimenez if (smime_config.cipher == NULL) {
832f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_RC2
833*de0e0e4dSAntonio Huete Jimenez smime_config.cipher = EVP_rc2_40_cbc();
834f5b1c8a1SJohn Marino #else
835f5b1c8a1SJohn Marino BIO_printf(bio_err, "No cipher selected\n");
836f5b1c8a1SJohn Marino goto end;
837f5b1c8a1SJohn Marino #endif
838f5b1c8a1SJohn Marino }
839*de0e0e4dSAntonio Huete Jimenez if ((encerts = sk_X509_new_null()) == NULL)
840*de0e0e4dSAntonio Huete Jimenez goto end;
841*de0e0e4dSAntonio Huete Jimenez while (*args != NULL) {
842*de0e0e4dSAntonio Huete Jimenez if ((cert = load_cert(bio_err, *args, FORMAT_PEM,
843*de0e0e4dSAntonio Huete Jimenez NULL, "recipient certificate file")) == NULL) {
844f5b1c8a1SJohn Marino goto end;
845f5b1c8a1SJohn Marino }
846*de0e0e4dSAntonio Huete Jimenez if (!sk_X509_push(encerts, cert))
847*de0e0e4dSAntonio Huete Jimenez goto end;
848f5b1c8a1SJohn Marino cert = NULL;
849f5b1c8a1SJohn Marino args++;
850f5b1c8a1SJohn Marino }
851f5b1c8a1SJohn Marino }
852*de0e0e4dSAntonio Huete Jimenez if (smime_config.certfile != NULL) {
853*de0e0e4dSAntonio Huete Jimenez if ((other = load_certs(bio_err, smime_config.certfile,
854*de0e0e4dSAntonio Huete Jimenez FORMAT_PEM, NULL, "certificate file")) == NULL) {
855f5b1c8a1SJohn Marino ERR_print_errors(bio_err);
856f5b1c8a1SJohn Marino goto end;
857f5b1c8a1SJohn Marino }
858f5b1c8a1SJohn Marino }
859*de0e0e4dSAntonio Huete Jimenez if (smime_config.recipfile != NULL &&
860*de0e0e4dSAntonio Huete Jimenez (smime_config.operation == SMIME_DECRYPT)) {
861*de0e0e4dSAntonio Huete Jimenez if ((recip = load_cert(bio_err, smime_config.recipfile,
862*de0e0e4dSAntonio Huete Jimenez FORMAT_PEM, NULL, "recipient certificate file")) == NULL) {
863f5b1c8a1SJohn Marino ERR_print_errors(bio_err);
864f5b1c8a1SJohn Marino goto end;
865f5b1c8a1SJohn Marino }
866f5b1c8a1SJohn Marino }
867*de0e0e4dSAntonio Huete Jimenez if (smime_config.operation == SMIME_DECRYPT) {
868*de0e0e4dSAntonio Huete Jimenez if (smime_config.keyfile == NULL)
869*de0e0e4dSAntonio Huete Jimenez smime_config.keyfile = smime_config.recipfile;
870*de0e0e4dSAntonio Huete Jimenez } else if (smime_config.operation == SMIME_SIGN) {
871*de0e0e4dSAntonio Huete Jimenez if (smime_config.keyfile == NULL)
872*de0e0e4dSAntonio Huete Jimenez smime_config.keyfile = smime_config.signerfile;
873*de0e0e4dSAntonio Huete Jimenez } else {
874*de0e0e4dSAntonio Huete Jimenez smime_config.keyfile = NULL;
875*de0e0e4dSAntonio Huete Jimenez }
876f5b1c8a1SJohn Marino
877*de0e0e4dSAntonio Huete Jimenez if (smime_config.keyfile != NULL) {
878*de0e0e4dSAntonio Huete Jimenez key = load_key(bio_err, smime_config.keyfile,
879*de0e0e4dSAntonio Huete Jimenez smime_config.keyform, 0, passin, "signing key file");
880*de0e0e4dSAntonio Huete Jimenez if (key == NULL)
881f5b1c8a1SJohn Marino goto end;
882f5b1c8a1SJohn Marino }
883*de0e0e4dSAntonio Huete Jimenez if (smime_config.infile != NULL) {
884*de0e0e4dSAntonio Huete Jimenez if ((in = BIO_new_file(smime_config.infile, inmode)) == NULL) {
885f5b1c8a1SJohn Marino BIO_printf(bio_err,
886*de0e0e4dSAntonio Huete Jimenez "Can't open input file %s\n", smime_config.infile);
887f5b1c8a1SJohn Marino goto end;
888f5b1c8a1SJohn Marino }
889f5b1c8a1SJohn Marino } else {
890*de0e0e4dSAntonio Huete Jimenez if ((in = BIO_new_fp(stdin, BIO_NOCLOSE)) == NULL)
891*de0e0e4dSAntonio Huete Jimenez goto end;
892f5b1c8a1SJohn Marino }
893f5b1c8a1SJohn Marino
894*de0e0e4dSAntonio Huete Jimenez if (smime_config.operation & SMIME_IP) {
895*de0e0e4dSAntonio Huete Jimenez if (smime_config.informat == FORMAT_SMIME)
896*de0e0e4dSAntonio Huete Jimenez p7 = SMIME_read_PKCS7(in, &indata);
897*de0e0e4dSAntonio Huete Jimenez else if (smime_config.informat == FORMAT_PEM)
898*de0e0e4dSAntonio Huete Jimenez p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
899*de0e0e4dSAntonio Huete Jimenez else if (smime_config.informat == FORMAT_ASN1)
900*de0e0e4dSAntonio Huete Jimenez p7 = d2i_PKCS7_bio(in, NULL);
901*de0e0e4dSAntonio Huete Jimenez else {
902*de0e0e4dSAntonio Huete Jimenez BIO_printf(bio_err,
903*de0e0e4dSAntonio Huete Jimenez "Bad input format for PKCS#7 file\n");
904*de0e0e4dSAntonio Huete Jimenez goto end;
905*de0e0e4dSAntonio Huete Jimenez }
906*de0e0e4dSAntonio Huete Jimenez
907*de0e0e4dSAntonio Huete Jimenez if (p7 == NULL) {
908*de0e0e4dSAntonio Huete Jimenez BIO_printf(bio_err, "Error reading S/MIME message\n");
909*de0e0e4dSAntonio Huete Jimenez goto end;
910*de0e0e4dSAntonio Huete Jimenez }
911*de0e0e4dSAntonio Huete Jimenez if (smime_config.contfile != NULL) {
912*de0e0e4dSAntonio Huete Jimenez BIO_free(indata);
913*de0e0e4dSAntonio Huete Jimenez if ((indata = BIO_new_file(smime_config.contfile,
914*de0e0e4dSAntonio Huete Jimenez "rb")) == NULL) {
915*de0e0e4dSAntonio Huete Jimenez BIO_printf(bio_err,
916*de0e0e4dSAntonio Huete Jimenez "Can't read content file %s\n",
917*de0e0e4dSAntonio Huete Jimenez smime_config.contfile);
918*de0e0e4dSAntonio Huete Jimenez goto end;
919*de0e0e4dSAntonio Huete Jimenez }
920*de0e0e4dSAntonio Huete Jimenez }
921*de0e0e4dSAntonio Huete Jimenez }
922*de0e0e4dSAntonio Huete Jimenez if (smime_config.outfile != NULL) {
923*de0e0e4dSAntonio Huete Jimenez if ((out = BIO_new_file(smime_config.outfile, outmode)) == NULL) {
924*de0e0e4dSAntonio Huete Jimenez BIO_printf(bio_err,
925*de0e0e4dSAntonio Huete Jimenez "Can't open output file %s\n",
926*de0e0e4dSAntonio Huete Jimenez smime_config.outfile);
927*de0e0e4dSAntonio Huete Jimenez goto end;
928*de0e0e4dSAntonio Huete Jimenez }
929*de0e0e4dSAntonio Huete Jimenez } else {
930*de0e0e4dSAntonio Huete Jimenez if ((out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL)
931*de0e0e4dSAntonio Huete Jimenez goto end;
932*de0e0e4dSAntonio Huete Jimenez }
933*de0e0e4dSAntonio Huete Jimenez
934*de0e0e4dSAntonio Huete Jimenez if (smime_config.operation == SMIME_VERIFY) {
935*de0e0e4dSAntonio Huete Jimenez if ((store = setup_verify(bio_err, smime_config.CAfile,
936*de0e0e4dSAntonio Huete Jimenez smime_config.CApath)) == NULL)
937f5b1c8a1SJohn Marino goto end;
938f5b1c8a1SJohn Marino X509_STORE_set_verify_cb(store, smime_cb);
939*de0e0e4dSAntonio Huete Jimenez if (smime_config.vpm != NULL) {
940*de0e0e4dSAntonio Huete Jimenez if (!X509_STORE_set1_param(store, smime_config.vpm))
941*de0e0e4dSAntonio Huete Jimenez goto end;
942*de0e0e4dSAntonio Huete Jimenez }
943f5b1c8a1SJohn Marino }
944f5b1c8a1SJohn Marino ret = 3;
945f5b1c8a1SJohn Marino
946*de0e0e4dSAntonio Huete Jimenez if (smime_config.operation == SMIME_ENCRYPT) {
947*de0e0e4dSAntonio Huete Jimenez if (smime_config.indef)
948*de0e0e4dSAntonio Huete Jimenez smime_config.flags |= PKCS7_STREAM;
949*de0e0e4dSAntonio Huete Jimenez p7 = PKCS7_encrypt(encerts, in, smime_config.cipher,
950*de0e0e4dSAntonio Huete Jimenez smime_config.flags);
951*de0e0e4dSAntonio Huete Jimenez } else if (smime_config.operation & SMIME_SIGNERS) {
952f5b1c8a1SJohn Marino int i;
953f5b1c8a1SJohn Marino /*
954f5b1c8a1SJohn Marino * If detached data content we only enable streaming if
955f5b1c8a1SJohn Marino * S/MIME output format.
956f5b1c8a1SJohn Marino */
957*de0e0e4dSAntonio Huete Jimenez if (smime_config.operation == SMIME_SIGN) {
958*de0e0e4dSAntonio Huete Jimenez if (smime_config.flags & PKCS7_DETACHED) {
959*de0e0e4dSAntonio Huete Jimenez if (smime_config.outformat == FORMAT_SMIME)
960*de0e0e4dSAntonio Huete Jimenez smime_config.flags |= PKCS7_STREAM;
961*de0e0e4dSAntonio Huete Jimenez } else if (smime_config.indef) {
962*de0e0e4dSAntonio Huete Jimenez smime_config.flags |= PKCS7_STREAM;
963*de0e0e4dSAntonio Huete Jimenez }
964*de0e0e4dSAntonio Huete Jimenez smime_config.flags |= PKCS7_PARTIAL;
965*de0e0e4dSAntonio Huete Jimenez p7 = PKCS7_sign(NULL, NULL, other, in,
966*de0e0e4dSAntonio Huete Jimenez smime_config.flags);
967*de0e0e4dSAntonio Huete Jimenez if (p7 == NULL)
968f5b1c8a1SJohn Marino goto end;
969*de0e0e4dSAntonio Huete Jimenez } else {
970*de0e0e4dSAntonio Huete Jimenez smime_config.flags |= PKCS7_REUSE_DIGEST;
971*de0e0e4dSAntonio Huete Jimenez }
972*de0e0e4dSAntonio Huete Jimenez for (i = 0; i < sk_OPENSSL_STRING_num(smime_config.sksigners); i++) {
973*de0e0e4dSAntonio Huete Jimenez smime_config.signerfile =
974*de0e0e4dSAntonio Huete Jimenez sk_OPENSSL_STRING_value(smime_config.sksigners, i);
975*de0e0e4dSAntonio Huete Jimenez smime_config.keyfile =
976*de0e0e4dSAntonio Huete Jimenez sk_OPENSSL_STRING_value(smime_config.skkeys, i);
977*de0e0e4dSAntonio Huete Jimenez signer = load_cert(bio_err, smime_config.signerfile,
978*de0e0e4dSAntonio Huete Jimenez FORMAT_PEM, NULL, "signer certificate");
979*de0e0e4dSAntonio Huete Jimenez if (signer == NULL)
980f5b1c8a1SJohn Marino goto end;
981*de0e0e4dSAntonio Huete Jimenez key = load_key(bio_err, smime_config.keyfile,
982*de0e0e4dSAntonio Huete Jimenez smime_config.keyform, 0, passin,
983f5b1c8a1SJohn Marino "signing key file");
984*de0e0e4dSAntonio Huete Jimenez if (key == NULL)
985f5b1c8a1SJohn Marino goto end;
986*de0e0e4dSAntonio Huete Jimenez if (PKCS7_sign_add_signer(p7, signer, key,
987*de0e0e4dSAntonio Huete Jimenez smime_config.sign_md, smime_config.flags) == NULL)
988f5b1c8a1SJohn Marino goto end;
989f5b1c8a1SJohn Marino X509_free(signer);
990f5b1c8a1SJohn Marino signer = NULL;
991f5b1c8a1SJohn Marino EVP_PKEY_free(key);
992f5b1c8a1SJohn Marino key = NULL;
993f5b1c8a1SJohn Marino }
994f5b1c8a1SJohn Marino /* If not streaming or resigning finalize structure */
995*de0e0e4dSAntonio Huete Jimenez if ((smime_config.operation == SMIME_SIGN) &&
996*de0e0e4dSAntonio Huete Jimenez !(smime_config.flags & PKCS7_STREAM)) {
997*de0e0e4dSAntonio Huete Jimenez if (!PKCS7_final(p7, in, smime_config.flags))
998f5b1c8a1SJohn Marino goto end;
999f5b1c8a1SJohn Marino }
1000f5b1c8a1SJohn Marino }
1001*de0e0e4dSAntonio Huete Jimenez if (p7 == NULL) {
1002f5b1c8a1SJohn Marino BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
1003f5b1c8a1SJohn Marino goto end;
1004f5b1c8a1SJohn Marino }
1005f5b1c8a1SJohn Marino ret = 4;
1006*de0e0e4dSAntonio Huete Jimenez
1007*de0e0e4dSAntonio Huete Jimenez if (smime_config.operation == SMIME_DECRYPT) {
1008*de0e0e4dSAntonio Huete Jimenez if (!PKCS7_decrypt(p7, key, recip, out, smime_config.flags)) {
1009*de0e0e4dSAntonio Huete Jimenez BIO_printf(bio_err,
1010*de0e0e4dSAntonio Huete Jimenez "Error decrypting PKCS#7 structure\n");
1011f5b1c8a1SJohn Marino goto end;
1012f5b1c8a1SJohn Marino }
1013*de0e0e4dSAntonio Huete Jimenez } else if (smime_config.operation == SMIME_VERIFY) {
1014f5b1c8a1SJohn Marino STACK_OF(X509) *signers;
1015*de0e0e4dSAntonio Huete Jimenez if (PKCS7_verify(p7, other, store, indata, out,
1016*de0e0e4dSAntonio Huete Jimenez smime_config.flags)) {
1017f5b1c8a1SJohn Marino BIO_printf(bio_err, "Verification successful\n");
1018*de0e0e4dSAntonio Huete Jimenez } else {
1019f5b1c8a1SJohn Marino BIO_printf(bio_err, "Verification failure\n");
1020f5b1c8a1SJohn Marino goto end;
1021f5b1c8a1SJohn Marino }
1022*de0e0e4dSAntonio Huete Jimenez if ((signers = PKCS7_get0_signers(p7, other,
1023*de0e0e4dSAntonio Huete Jimenez smime_config.flags)) == NULL)
1024*de0e0e4dSAntonio Huete Jimenez goto end;
1025*de0e0e4dSAntonio Huete Jimenez if (!save_certs(smime_config.signerfile, signers)) {
1026f5b1c8a1SJohn Marino BIO_printf(bio_err, "Error writing signers to %s\n",
1027*de0e0e4dSAntonio Huete Jimenez smime_config.signerfile);
1028*de0e0e4dSAntonio Huete Jimenez sk_X509_free(signers);
1029f5b1c8a1SJohn Marino ret = 5;
1030f5b1c8a1SJohn Marino goto end;
1031f5b1c8a1SJohn Marino }
1032f5b1c8a1SJohn Marino sk_X509_free(signers);
1033*de0e0e4dSAntonio Huete Jimenez } else if (smime_config.operation == SMIME_PK7OUT) {
1034f5b1c8a1SJohn Marino PEM_write_bio_PKCS7(out, p7);
1035*de0e0e4dSAntonio Huete Jimenez } else {
1036*de0e0e4dSAntonio Huete Jimenez if (smime_config.to != NULL)
1037*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "To: %s\n", smime_config.to);
1038*de0e0e4dSAntonio Huete Jimenez if (smime_config.from != NULL)
1039*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "From: %s\n", smime_config.from);
1040*de0e0e4dSAntonio Huete Jimenez if (smime_config.subject != NULL)
1041*de0e0e4dSAntonio Huete Jimenez BIO_printf(out, "Subject: %s\n", smime_config.subject);
1042*de0e0e4dSAntonio Huete Jimenez if (smime_config.outformat == FORMAT_SMIME) {
1043*de0e0e4dSAntonio Huete Jimenez if (smime_config.operation == SMIME_RESIGN) {
1044*de0e0e4dSAntonio Huete Jimenez if (!SMIME_write_PKCS7(out, p7, indata,
1045*de0e0e4dSAntonio Huete Jimenez smime_config.flags))
1046*de0e0e4dSAntonio Huete Jimenez goto end;
1047*de0e0e4dSAntonio Huete Jimenez } else {
1048*de0e0e4dSAntonio Huete Jimenez if (!SMIME_write_PKCS7(out, p7, in,
1049*de0e0e4dSAntonio Huete Jimenez smime_config.flags))
1050*de0e0e4dSAntonio Huete Jimenez goto end;
1051*de0e0e4dSAntonio Huete Jimenez }
1052*de0e0e4dSAntonio Huete Jimenez } else if (smime_config.outformat == FORMAT_PEM) {
1053*de0e0e4dSAntonio Huete Jimenez if (!PEM_write_bio_PKCS7_stream(out, p7, in,
1054*de0e0e4dSAntonio Huete Jimenez smime_config.flags))
1055*de0e0e4dSAntonio Huete Jimenez goto end;
1056*de0e0e4dSAntonio Huete Jimenez } else if (smime_config.outformat == FORMAT_ASN1) {
1057*de0e0e4dSAntonio Huete Jimenez if (!i2d_PKCS7_bio_stream(out, p7, in,
1058*de0e0e4dSAntonio Huete Jimenez smime_config.flags))
1059*de0e0e4dSAntonio Huete Jimenez goto end;
1060*de0e0e4dSAntonio Huete Jimenez } else {
1061*de0e0e4dSAntonio Huete Jimenez BIO_printf(bio_err,
1062*de0e0e4dSAntonio Huete Jimenez "Bad output format for PKCS#7 file\n");
1063f5b1c8a1SJohn Marino goto end;
1064f5b1c8a1SJohn Marino }
1065f5b1c8a1SJohn Marino }
1066*de0e0e4dSAntonio Huete Jimenez
1067f5b1c8a1SJohn Marino ret = 0;
1068*de0e0e4dSAntonio Huete Jimenez
1069f5b1c8a1SJohn Marino end:
1070f5b1c8a1SJohn Marino if (ret)
1071f5b1c8a1SJohn Marino ERR_print_errors(bio_err);
1072f5b1c8a1SJohn Marino sk_X509_pop_free(encerts, X509_free);
1073f5b1c8a1SJohn Marino sk_X509_pop_free(other, X509_free);
1074*de0e0e4dSAntonio Huete Jimenez X509_VERIFY_PARAM_free(smime_config.vpm);
1075*de0e0e4dSAntonio Huete Jimenez sk_OPENSSL_STRING_free(smime_config.sksigners);
1076*de0e0e4dSAntonio Huete Jimenez sk_OPENSSL_STRING_free(smime_config.skkeys);
1077f5b1c8a1SJohn Marino X509_STORE_free(store);
1078f5b1c8a1SJohn Marino X509_free(cert);
1079f5b1c8a1SJohn Marino X509_free(recip);
1080f5b1c8a1SJohn Marino X509_free(signer);
1081f5b1c8a1SJohn Marino EVP_PKEY_free(key);
1082f5b1c8a1SJohn Marino PKCS7_free(p7);
1083f5b1c8a1SJohn Marino BIO_free(in);
1084f5b1c8a1SJohn Marino BIO_free(indata);
1085f5b1c8a1SJohn Marino BIO_free_all(out);
1086f5b1c8a1SJohn Marino free(passin);
1087f5b1c8a1SJohn Marino
1088f5b1c8a1SJohn Marino return (ret);
1089f5b1c8a1SJohn Marino }
1090f5b1c8a1SJohn Marino
1091f5b1c8a1SJohn Marino static int
save_certs(char * signerfile,STACK_OF (X509)* signers)1092f5b1c8a1SJohn Marino save_certs(char *signerfile, STACK_OF(X509) *signers)
1093f5b1c8a1SJohn Marino {
1094f5b1c8a1SJohn Marino int i;
1095f5b1c8a1SJohn Marino BIO *tmp;
1096*de0e0e4dSAntonio Huete Jimenez
1097*de0e0e4dSAntonio Huete Jimenez if (signerfile == NULL)
1098f5b1c8a1SJohn Marino return 1;
1099f5b1c8a1SJohn Marino tmp = BIO_new_file(signerfile, "w");
1100*de0e0e4dSAntonio Huete Jimenez if (tmp == NULL)
1101f5b1c8a1SJohn Marino return 0;
1102f5b1c8a1SJohn Marino for (i = 0; i < sk_X509_num(signers); i++)
1103f5b1c8a1SJohn Marino PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
1104f5b1c8a1SJohn Marino BIO_free(tmp);
1105*de0e0e4dSAntonio Huete Jimenez
1106f5b1c8a1SJohn Marino return 1;
1107f5b1c8a1SJohn Marino }
1108f5b1c8a1SJohn Marino
1109f5b1c8a1SJohn Marino /* Minimal callback just to output policy info (if any) */
1110f5b1c8a1SJohn Marino static int
smime_cb(int ok,X509_STORE_CTX * ctx)1111f5b1c8a1SJohn Marino smime_cb(int ok, X509_STORE_CTX *ctx)
1112f5b1c8a1SJohn Marino {
1113f5b1c8a1SJohn Marino int error;
1114f5b1c8a1SJohn Marino
1115f5b1c8a1SJohn Marino error = X509_STORE_CTX_get_error(ctx);
1116f5b1c8a1SJohn Marino
1117*de0e0e4dSAntonio Huete Jimenez if ((error != X509_V_ERR_NO_EXPLICIT_POLICY) &&
1118*de0e0e4dSAntonio Huete Jimenez ((error != X509_V_OK) || (ok != 2)))
1119f5b1c8a1SJohn Marino return ok;
1120f5b1c8a1SJohn Marino
1121f5b1c8a1SJohn Marino policies_print(NULL, ctx);
1122f5b1c8a1SJohn Marino
1123f5b1c8a1SJohn Marino return ok;
1124f5b1c8a1SJohn Marino }
1125