xref: /dragonfly/crypto/libressl/apps/openssl/cms.c (revision f5b1c8a1)
1 /* $OpenBSD: cms.c,v 1.5 2015/10/17 07:51:10 semarie Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project.
4  */
5 /* ====================================================================
6  * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  */
53 
54 /* CMS utility function */
55 
56 #include <stdio.h>
57 #include <string.h>
58 
59 #include "apps.h"
60 
61 #ifndef OPENSSL_NO_CMS
62 
63 #include <openssl/cms.h>
64 #include <openssl/crypto.h>
65 #include <openssl/err.h>
66 #include <openssl/pem.h>
67 #include <openssl/x509_vfy.h>
68 #include <openssl/x509v3.h>
69 
70 static int save_certs(char *signerfile, STACK_OF(X509) * signers);
71 static int cms_cb(int ok, X509_STORE_CTX * ctx);
72 static void receipt_request_print(BIO * out, CMS_ContentInfo * cms);
73 static CMS_ReceiptRequest * make_receipt_request(
74     STACK_OF(OPENSSL_STRING) * rr_to, int rr_allorfirst,
75     STACK_OF(OPENSSL_STRING) * rr_from);
76 
77 #define SMIME_OP	0x10
78 #define SMIME_IP	0x20
79 #define SMIME_SIGNERS	0x40
80 #define SMIME_ENCRYPT		(1 | SMIME_OP)
81 #define SMIME_DECRYPT		(2 | SMIME_IP)
82 #define SMIME_SIGN		(3 | SMIME_OP | SMIME_SIGNERS)
83 #define SMIME_VERIFY		(4 | SMIME_IP)
84 #define SMIME_CMSOUT		(5 | SMIME_IP | SMIME_OP)
85 #define SMIME_RESIGN		(6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
86 #define SMIME_DATAOUT		(7 | SMIME_IP)
87 #define SMIME_DATA_CREATE	(8 | SMIME_OP)
88 #define SMIME_DIGEST_VERIFY	(9 | SMIME_IP)
89 #define SMIME_DIGEST_CREATE	(10 | SMIME_OP)
90 #define SMIME_UNCOMPRESS	(11 | SMIME_IP)
91 #define SMIME_COMPRESS		(12 | SMIME_OP)
92 #define SMIME_ENCRYPTED_DECRYPT	(13 | SMIME_IP)
93 #define SMIME_ENCRYPTED_ENCRYPT	(14 | SMIME_OP)
94 #define SMIME_SIGN_RECEIPT	(15 | SMIME_IP | SMIME_OP)
95 #define SMIME_VERIFY_RECEIPT	(16 | SMIME_IP)
96 
97 int verify_err = 0;
98 
99 int
100 cms_main(int argc, char **argv)
101 {
102 	int operation = 0;
103 	int ret = 0;
104 	char **args;
105 	const char *inmode = "r", *outmode = "w";
106 	char *infile = NULL, *outfile = NULL, *rctfile = NULL;
107 	char *signerfile = NULL, *recipfile = NULL;
108 	STACK_OF(OPENSSL_STRING) * sksigners = NULL, *skkeys = NULL;
109 	char *certfile = NULL, *keyfile = NULL, *contfile = NULL;
110 	char *certsoutfile = NULL;
111 	const EVP_CIPHER *cipher = NULL;
112 	CMS_ContentInfo *cms = NULL, *rcms = NULL;
113 	X509_STORE *store = NULL;
114 	X509 *cert = NULL, *recip = NULL, *signer = NULL;
115 	EVP_PKEY *key = NULL;
116 	STACK_OF(X509) * encerts = NULL, *other = NULL;
117 	BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
118 	int badarg = 0;
119 	int flags = CMS_DETACHED, noout = 0, print = 0;
120 	int verify_retcode = 0;
121 	int rr_print = 0, rr_allorfirst = -1;
122 	STACK_OF(OPENSSL_STRING) * rr_to = NULL, *rr_from = NULL;
123 	CMS_ReceiptRequest *rr = NULL;
124 	char *to = NULL, *from = NULL, *subject = NULL;
125 	char *CAfile = NULL, *CApath = NULL;
126 	char *passargin = NULL, *passin = NULL;
127 	const EVP_MD *sign_md = NULL;
128 	int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
129 	int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
130 	unsigned char *secret_key = NULL, *secret_keyid = NULL;
131 	unsigned char *pwri_pass = NULL, *pwri_tmp = NULL;
132 	size_t secret_keylen = 0, secret_keyidlen = 0;
133 
134 	ASN1_OBJECT *econtent_type = NULL;
135 
136 	X509_VERIFY_PARAM *vpm = NULL;
137 
138 	if (single_execution) {
139 		if (pledge("stdio rpath wpath cpath tty", NULL) == -1) {
140 			perror("pledge");
141 			exit(1);
142 		}
143 	}
144 
145 	args = argv + 1;
146 	ret = 1;
147 
148 	while (!badarg && *args && *args[0] == '-') {
149 		if (!strcmp(*args, "-encrypt"))
150 			operation = SMIME_ENCRYPT;
151 		else if (!strcmp(*args, "-decrypt"))
152 			operation = SMIME_DECRYPT;
153 		else if (!strcmp(*args, "-sign"))
154 			operation = SMIME_SIGN;
155 		else if (!strcmp(*args, "-sign_receipt"))
156 			operation = SMIME_SIGN_RECEIPT;
157 		else if (!strcmp(*args, "-resign"))
158 			operation = SMIME_RESIGN;
159 		else if (!strcmp(*args, "-verify"))
160 			operation = SMIME_VERIFY;
161 		else if (!strcmp(*args, "-verify_retcode"))
162 			verify_retcode = 1;
163 		else if (!strcmp(*args, "-verify_receipt")) {
164 			operation = SMIME_VERIFY_RECEIPT;
165 			if (!args[1])
166 				goto argerr;
167 			args++;
168 			rctfile = *args;
169 		} else if (!strcmp(*args, "-cmsout"))
170 			operation = SMIME_CMSOUT;
171 		else if (!strcmp(*args, "-data_out"))
172 			operation = SMIME_DATAOUT;
173 		else if (!strcmp(*args, "-data_create"))
174 			operation = SMIME_DATA_CREATE;
175 		else if (!strcmp(*args, "-digest_verify"))
176 			operation = SMIME_DIGEST_VERIFY;
177 		else if (!strcmp(*args, "-digest_create"))
178 			operation = SMIME_DIGEST_CREATE;
179 		else if (!strcmp(*args, "-compress"))
180 			operation = SMIME_COMPRESS;
181 		else if (!strcmp(*args, "-uncompress"))
182 			operation = SMIME_UNCOMPRESS;
183 		else if (!strcmp(*args, "-EncryptedData_decrypt"))
184 			operation = SMIME_ENCRYPTED_DECRYPT;
185 		else if (!strcmp(*args, "-EncryptedData_encrypt"))
186 			operation = SMIME_ENCRYPTED_ENCRYPT;
187 #ifndef OPENSSL_NO_DES
188 		else if (!strcmp(*args, "-des3"))
189 			cipher = EVP_des_ede3_cbc();
190 		else if (!strcmp(*args, "-des"))
191 			cipher = EVP_des_cbc();
192 #endif
193 #ifndef OPENSSL_NO_RC2
194 		else if (!strcmp(*args, "-rc2-40"))
195 			cipher = EVP_rc2_40_cbc();
196 		else if (!strcmp(*args, "-rc2-128"))
197 			cipher = EVP_rc2_cbc();
198 		else if (!strcmp(*args, "-rc2-64"))
199 			cipher = EVP_rc2_64_cbc();
200 #endif
201 #ifndef OPENSSL_NO_AES
202 		else if (!strcmp(*args, "-aes128"))
203 			cipher = EVP_aes_128_cbc();
204 		else if (!strcmp(*args, "-aes192"))
205 			cipher = EVP_aes_192_cbc();
206 		else if (!strcmp(*args, "-aes256"))
207 			cipher = EVP_aes_256_cbc();
208 #endif
209 #ifndef OPENSSL_NO_CAMELLIA
210 		else if (!strcmp(*args, "-camellia128"))
211 			cipher = EVP_camellia_128_cbc();
212 		else if (!strcmp(*args, "-camellia192"))
213 			cipher = EVP_camellia_192_cbc();
214 		else if (!strcmp(*args, "-camellia256"))
215 			cipher = EVP_camellia_256_cbc();
216 #endif
217 		else if (!strcmp(*args, "-debug_decrypt"))
218 			flags |= CMS_DEBUG_DECRYPT;
219 		else if (!strcmp(*args, "-text"))
220 			flags |= CMS_TEXT;
221 		else if (!strcmp(*args, "-nointern"))
222 			flags |= CMS_NOINTERN;
223 		else if (!strcmp(*args, "-noverify") ||
224 		    !strcmp(*args, "-no_signer_cert_verify"))
225 			flags |= CMS_NO_SIGNER_CERT_VERIFY;
226 		else if (!strcmp(*args, "-nocerts"))
227 			flags |= CMS_NOCERTS;
228 		else if (!strcmp(*args, "-noattr"))
229 			flags |= CMS_NOATTR;
230 		else if (!strcmp(*args, "-nodetach"))
231 			flags &= ~CMS_DETACHED;
232 		else if (!strcmp(*args, "-nosmimecap"))
233 			flags |= CMS_NOSMIMECAP;
234 		else if (!strcmp(*args, "-binary"))
235 			flags |= CMS_BINARY;
236 		else if (!strcmp(*args, "-keyid"))
237 			flags |= CMS_USE_KEYID;
238 		else if (!strcmp(*args, "-nosigs"))
239 			flags |= CMS_NOSIGS;
240 		else if (!strcmp(*args, "-no_content_verify"))
241 			flags |= CMS_NO_CONTENT_VERIFY;
242 		else if (!strcmp(*args, "-no_attr_verify"))
243 			flags |= CMS_NO_ATTR_VERIFY;
244 		else if (!strcmp(*args, "-stream"))
245 			flags |= CMS_STREAM;
246 		else if (!strcmp(*args, "-indef"))
247 			flags |= CMS_STREAM;
248 		else if (!strcmp(*args, "-noindef"))
249 			flags &= ~CMS_STREAM;
250 		else if (!strcmp(*args, "-nooldmime"))
251 			flags |= CMS_NOOLDMIMETYPE;
252 		else if (!strcmp(*args, "-crlfeol"))
253 			flags |= CMS_CRLFEOL;
254 		else if (!strcmp(*args, "-noout"))
255 			noout = 1;
256 		else if (!strcmp(*args, "-receipt_request_print"))
257 			rr_print = 1;
258 		else if (!strcmp(*args, "-receipt_request_all"))
259 			rr_allorfirst = 0;
260 		else if (!strcmp(*args, "-receipt_request_first"))
261 			rr_allorfirst = 1;
262 		else if (!strcmp(*args, "-receipt_request_from")) {
263 			if (!args[1])
264 				goto argerr;
265 			args++;
266 			if (!rr_from)
267 				rr_from = sk_OPENSSL_STRING_new_null();
268 			sk_OPENSSL_STRING_push(rr_from, *args);
269 		} else if (!strcmp(*args, "-receipt_request_to")) {
270 			if (!args[1])
271 				goto argerr;
272 			args++;
273 			if (!rr_to)
274 				rr_to = sk_OPENSSL_STRING_new_null();
275 			sk_OPENSSL_STRING_push(rr_to, *args);
276 		} else if (!strcmp(*args, "-print")) {
277 			noout = 1;
278 			print = 1;
279 		} else if (!strcmp(*args, "-secretkey")) {
280 			long ltmp;
281 			if (!args[1])
282 				goto argerr;
283 			args++;
284 			secret_key = string_to_hex(*args, &ltmp);
285 			if (!secret_key) {
286 				BIO_printf(bio_err, "Invalid key %s\n", *args);
287 				goto argerr;
288 			}
289 			secret_keylen = (size_t) ltmp;
290 		} else if (!strcmp(*args, "-secretkeyid")) {
291 			long ltmp;
292 			if (!args[1])
293 				goto argerr;
294 			args++;
295 			secret_keyid = string_to_hex(*args, &ltmp);
296 			if (!secret_keyid) {
297 				BIO_printf(bio_err, "Invalid id %s\n", *args);
298 				goto argerr;
299 			}
300 			secret_keyidlen = (size_t) ltmp;
301 		} else if (!strcmp(*args, "-pwri_password")) {
302 			if (!args[1])
303 				goto argerr;
304 			args++;
305 			pwri_pass = (unsigned char *) *args;
306 		} else if (!strcmp(*args, "-econtent_type")) {
307 			if (!args[1])
308 				goto argerr;
309 			args++;
310 			econtent_type = OBJ_txt2obj(*args, 0);
311 			if (!econtent_type) {
312 				BIO_printf(bio_err, "Invalid OID %s\n", *args);
313 				goto argerr;
314 			}
315 		}
316 		else if (!strcmp(*args, "-passin")) {
317 			if (!args[1])
318 				goto argerr;
319 			passargin = *++args;
320 		} else if (!strcmp(*args, "-to")) {
321 			if (!args[1])
322 				goto argerr;
323 			to = *++args;
324 		} else if (!strcmp(*args, "-from")) {
325 			if (!args[1])
326 				goto argerr;
327 			from = *++args;
328 		} else if (!strcmp(*args, "-subject")) {
329 			if (!args[1])
330 				goto argerr;
331 			subject = *++args;
332 		} else if (!strcmp(*args, "-signer")) {
333 			if (!args[1])
334 				goto argerr;
335 			/* If previous -signer argument add signer to list */
336 
337 			if (signerfile) {
338 				if (!sksigners)
339 					sksigners =
340 					    sk_OPENSSL_STRING_new_null();
341 				sk_OPENSSL_STRING_push(sksigners, signerfile);
342 				if (!keyfile)
343 					keyfile = signerfile;
344 				if (!skkeys)
345 					skkeys = sk_OPENSSL_STRING_new_null();
346 				sk_OPENSSL_STRING_push(skkeys, keyfile);
347 				keyfile = NULL;
348 			}
349 			signerfile = *++args;
350 		} else if (!strcmp(*args, "-recip")) {
351 			if (!args[1])
352 				goto argerr;
353 			recipfile = *++args;
354 		} else if (!strcmp(*args, "-certsout")) {
355 			if (!args[1])
356 				goto argerr;
357 			certsoutfile = *++args;
358 		} else if (!strcmp(*args, "-md")) {
359 			if (!args[1])
360 				goto argerr;
361 			sign_md = EVP_get_digestbyname(*++args);
362 			if (sign_md == NULL) {
363 				BIO_printf(bio_err, "Unknown digest %s\n",
364 				    *args);
365 				goto argerr;
366 			}
367 		} else if (!strcmp(*args, "-inkey")) {
368 			if (!args[1])
369 				goto argerr;
370 			/* If previous -inkey arument add signer to list */
371 			if (keyfile) {
372 				if (!signerfile) {
373 					BIO_puts(bio_err,
374 					    "Illegal -inkey without -signer\n");
375 					goto argerr;
376 				}
377 				if (!sksigners)
378 					sksigners =
379 					    sk_OPENSSL_STRING_new_null();
380 				sk_OPENSSL_STRING_push(sksigners, signerfile);
381 				signerfile = NULL;
382 				if (!skkeys)
383 					skkeys = sk_OPENSSL_STRING_new_null();
384 				sk_OPENSSL_STRING_push(skkeys, keyfile);
385 			}
386 			keyfile = *++args;
387 		} else if (!strcmp(*args, "-keyform")) {
388 			if (!args[1])
389 				goto argerr;
390 			keyform = str2fmt(*++args);
391 		} else if (!strcmp(*args, "-rctform")) {
392 			if (!args[1])
393 				goto argerr;
394 			rctformat = str2fmt(*++args);
395 		} else if (!strcmp(*args, "-certfile")) {
396 			if (!args[1])
397 				goto argerr;
398 			certfile = *++args;
399 		} else if (!strcmp(*args, "-CAfile")) {
400 			if (!args[1])
401 				goto argerr;
402 			CAfile = *++args;
403 		} else if (!strcmp(*args, "-CApath")) {
404 			if (!args[1])
405 				goto argerr;
406 			CApath = *++args;
407 		} else if (!strcmp(*args, "-in")) {
408 			if (!args[1])
409 				goto argerr;
410 			infile = *++args;
411 		} else if (!strcmp(*args, "-inform")) {
412 			if (!args[1])
413 				goto argerr;
414 			informat = str2fmt(*++args);
415 		} else if (!strcmp(*args, "-outform")) {
416 			if (!args[1])
417 				goto argerr;
418 			outformat = str2fmt(*++args);
419 		} else if (!strcmp(*args, "-out")) {
420 			if (!args[1])
421 				goto argerr;
422 			outfile = *++args;
423 		} else if (!strcmp(*args, "-content")) {
424 			if (!args[1])
425 				goto argerr;
426 			contfile = *++args;
427 		} else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))
428 			continue;
429 		else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)
430 			badarg = 1;
431 		args++;
432 	}
433 
434 	if (((rr_allorfirst != -1) || rr_from) && !rr_to) {
435 		BIO_puts(bio_err, "No Signed Receipts Recipients\n");
436 		goto argerr;
437 	}
438 	if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) {
439 		BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
440 		goto argerr;
441 	}
442 	if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) {
443 		BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
444 		goto argerr;
445 	}
446 	if (operation & SMIME_SIGNERS) {
447 		if (keyfile && !signerfile) {
448 			BIO_puts(bio_err, "Illegal -inkey without -signer\n");
449 			goto argerr;
450 		}
451 		/* Check to see if any final signer needs to be appended */
452 		if (signerfile) {
453 			if (!sksigners)
454 				sksigners = sk_OPENSSL_STRING_new_null();
455 			sk_OPENSSL_STRING_push(sksigners, signerfile);
456 			if (!skkeys)
457 				skkeys = sk_OPENSSL_STRING_new_null();
458 			if (!keyfile)
459 				keyfile = signerfile;
460 			sk_OPENSSL_STRING_push(skkeys, keyfile);
461 		}
462 		if (!sksigners) {
463 			BIO_printf(bio_err,
464 			    "No signer certificate specified\n");
465 			badarg = 1;
466 		}
467 		signerfile = NULL;
468 		keyfile = NULL;
469 	} else if (operation == SMIME_DECRYPT) {
470 		if (!recipfile && !keyfile && !secret_key && !pwri_pass) {
471 			BIO_printf(bio_err,
472 			    "No recipient certificate or key specified\n");
473 			badarg = 1;
474 		}
475 	} else if (operation == SMIME_ENCRYPT) {
476 		if (!*args && !secret_key && !pwri_pass) {
477 			BIO_printf(bio_err,
478 			    "No recipient(s) certificate(s) specified\n");
479 			badarg = 1;
480 		}
481 	} else if (!operation)
482 		badarg = 1;
483 
484 	if (badarg) {
485 argerr:
486 		BIO_printf(bio_err, "Usage cms [options] cert.pem ...\n");
487 		BIO_printf(bio_err, "where options are\n");
488 		BIO_printf(bio_err, "-encrypt       encrypt message\n");
489 		BIO_printf(bio_err, "-decrypt       decrypt encrypted message\n");
490 		BIO_printf(bio_err, "-sign          sign message\n");
491 		BIO_printf(bio_err, "-verify        verify signed message\n");
492 		BIO_printf(bio_err, "-cmsout        output CMS structure\n");
493 #ifndef OPENSSL_NO_DES
494 		BIO_printf(bio_err, "-des3          encrypt with triple DES\n");
495 		BIO_printf(bio_err, "-des           encrypt with DES\n");
496 #endif
497 #ifndef OPENSSL_NO_RC2
498 		BIO_printf(bio_err, "-rc2-40        encrypt with RC2-40 (default)\n");
499 		BIO_printf(bio_err, "-rc2-64        encrypt with RC2-64\n");
500 		BIO_printf(bio_err, "-rc2-128       encrypt with RC2-128\n");
501 #endif
502 #ifndef OPENSSL_NO_AES
503 		BIO_printf(bio_err, "-aes128, -aes192, -aes256\n");
504 		BIO_printf(bio_err, "               encrypt PEM output with cbc aes\n");
505 #endif
506 #ifndef OPENSSL_NO_CAMELLIA
507 		BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n");
508 		BIO_printf(bio_err, "               encrypt PEM output with cbc camellia\n");
509 #endif
510 		BIO_printf(bio_err, "-nointern      don't search certificates in message for signer\n");
511 		BIO_printf(bio_err, "-nosigs        don't verify message signature\n");
512 		BIO_printf(bio_err, "-noverify      don't verify signers certificate\n");
513 		BIO_printf(bio_err, "-nocerts       don't include signers certificate when signing\n");
514 		BIO_printf(bio_err, "-nodetach      use opaque signing\n");
515 		BIO_printf(bio_err, "-noattr        don't include any signed attributes\n");
516 		BIO_printf(bio_err, "-binary        don't translate message to text\n");
517 		BIO_printf(bio_err, "-certfile file other certificates file\n");
518 		BIO_printf(bio_err, "-certsout file certificate output file\n");
519 		BIO_printf(bio_err, "-signer file   signer certificate file\n");
520 		BIO_printf(bio_err, "-recip  file   recipient certificate file for decryption\n");
521 		BIO_printf(bio_err, "-keyid         use subject key identifier\n");
522 		BIO_printf(bio_err, "-in file       input file\n");
523 		BIO_printf(bio_err, "-inform arg    input format SMIME (default), PEM or DER\n");
524 		BIO_printf(bio_err, "-inkey file    input private key (if not signer or recipient)\n");
525 		BIO_printf(bio_err, "-keyform arg   input private key format (PEM)\n");
526 		BIO_printf(bio_err, "-out file      output file\n");
527 		BIO_printf(bio_err, "-outform arg   output format SMIME (default), PEM or DER\n");
528 		BIO_printf(bio_err, "-content file  supply or override content for detached signature\n");
529 		BIO_printf(bio_err, "-to addr       to address\n");
530 		BIO_printf(bio_err, "-from ad       from address\n");
531 		BIO_printf(bio_err, "-subject s     subject\n");
532 		BIO_printf(bio_err, "-text          include or delete text MIME headers\n");
533 		BIO_printf(bio_err, "-CApath dir    trusted certificates directory\n");
534 		BIO_printf(bio_err, "-CAfile file   trusted certificates file\n");
535 		BIO_printf(bio_err, "-crl_check     check revocation status of signer's certificate using CRLs\n");
536 		BIO_printf(bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
537 		BIO_printf(bio_err, "-passin arg    input file pass phrase source\n");
538 		BIO_printf(bio_err, "cert.pem       recipient certificate(s) for encryption\n");
539 		goto end;
540 	}
541 
542 	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
543 		BIO_printf(bio_err, "Error getting password\n");
544 		goto end;
545 	}
546 	ret = 2;
547 
548 	if (!(operation & SMIME_SIGNERS))
549 		flags &= ~CMS_DETACHED;
550 
551 	if (operation & SMIME_OP) {
552 		if (outformat == FORMAT_ASN1)
553 			outmode = "wb";
554 	} else {
555 		if (flags & CMS_BINARY)
556 			outmode = "wb";
557 	}
558 
559 	if (operation & SMIME_IP) {
560 		if (informat == FORMAT_ASN1)
561 			inmode = "rb";
562 	} else {
563 		if (flags & CMS_BINARY)
564 			inmode = "rb";
565 	}
566 
567 	if (operation == SMIME_ENCRYPT) {
568 		if (!cipher) {
569 #ifndef OPENSSL_NO_DES
570 			cipher = EVP_des_ede3_cbc();
571 #else
572 			BIO_printf(bio_err, "No cipher selected\n");
573 			goto end;
574 #endif
575 		}
576 		if (secret_key && !secret_keyid) {
577 			BIO_printf(bio_err, "No secret key id\n");
578 			goto end;
579 		}
580 		if (*args)
581 			encerts = sk_X509_new_null();
582 		while (*args) {
583 			if (!(cert = load_cert(bio_err, *args, FORMAT_PEM,
584 			    NULL, e, "recipient certificate file")))
585 				goto end;
586 			sk_X509_push(encerts, cert);
587 			cert = NULL;
588 			args++;
589 		}
590 	}
591 	if (certfile) {
592 		if (!(other = load_certs(bio_err, certfile, FORMAT_PEM, NULL,
593 		    e, "certificate file"))) {
594 			ERR_print_errors(bio_err);
595 			goto end;
596 		}
597 	}
598 	if (recipfile && (operation == SMIME_DECRYPT)) {
599 		if (!(recip = load_cert(bio_err, recipfile, FORMAT_PEM, NULL,
600 		    e, "recipient certificate file"))) {
601 			ERR_print_errors(bio_err);
602 			goto end;
603 		}
604 	}
605 	if (operation == SMIME_SIGN_RECEIPT) {
606 		if (!(signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL,
607 		    e, "receipt signer certificate file"))) {
608 			ERR_print_errors(bio_err);
609 			goto end;
610 		}
611 	}
612 	if (operation == SMIME_DECRYPT) {
613 		if (!keyfile)
614 			keyfile = recipfile;
615 	} else if ((operation == SMIME_SIGN) ||
616 	    (operation == SMIME_SIGN_RECEIPT)) {
617 		if (!keyfile)
618 			keyfile = signerfile;
619 	} else
620 		keyfile = NULL;
621 
622 	if (keyfile) {
623 		key = load_key(bio_err, keyfile, keyform, 0, passin, e,
624 		    "signing key file");
625 		if (!key)
626 			goto end;
627 	}
628 	if (infile) {
629 		if (!(in = BIO_new_file(infile, inmode))) {
630 			BIO_printf(bio_err,
631 			    "Can't open input file %s\n", infile);
632 			goto end;
633 		}
634 	} else
635 		in = BIO_new_fp(stdin, BIO_NOCLOSE);
636 
637 	if (operation & SMIME_IP) {
638 		if (informat == FORMAT_SMIME)
639 			cms = SMIME_read_CMS(in, &indata);
640 		else if (informat == FORMAT_PEM)
641 			cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
642 		else if (informat == FORMAT_ASN1)
643 			cms = d2i_CMS_bio(in, NULL);
644 		else {
645 			BIO_printf(bio_err, "Bad input format for CMS file\n");
646 			goto end;
647 		}
648 
649 		if (!cms) {
650 			BIO_printf(bio_err, "Error reading S/MIME message\n");
651 			goto end;
652 		}
653 		if (contfile) {
654 			BIO_free(indata);
655 			if (!(indata = BIO_new_file(contfile, "rb"))) {
656 				BIO_printf(bio_err,
657 				    "Can't read content file %s\n", contfile);
658 				goto end;
659 			}
660 		}
661 		if (certsoutfile) {
662 			STACK_OF(X509) * allcerts;
663 			allcerts = CMS_get1_certs(cms);
664 			if (!save_certs(certsoutfile, allcerts)) {
665 				BIO_printf(bio_err,
666 				    "Error writing certs to %s\n",
667 				    certsoutfile);
668 				ret = 5;
669 				goto end;
670 			}
671 			sk_X509_pop_free(allcerts, X509_free);
672 		}
673 	}
674 	if (rctfile) {
675 		char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
676 		if (!(rctin = BIO_new_file(rctfile, rctmode))) {
677 			BIO_printf(bio_err,
678 			    "Can't open receipt file %s\n", rctfile);
679 			goto end;
680 		}
681 		if (rctformat == FORMAT_SMIME)
682 			rcms = SMIME_read_CMS(rctin, NULL);
683 		else if (rctformat == FORMAT_PEM)
684 			rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
685 		else if (rctformat == FORMAT_ASN1)
686 			rcms = d2i_CMS_bio(rctin, NULL);
687 		else {
688 			BIO_printf(bio_err, "Bad input format for receipt\n");
689 			goto end;
690 		}
691 
692 		if (!rcms) {
693 			BIO_printf(bio_err, "Error reading receipt\n");
694 			goto end;
695 		}
696 	}
697 	if (outfile) {
698 		if (!(out = BIO_new_file(outfile, outmode))) {
699 			BIO_printf(bio_err,
700 			    "Can't open output file %s\n", outfile);
701 			goto end;
702 		}
703 	} else {
704 		out = BIO_new_fp(stdout, BIO_NOCLOSE);
705 	}
706 
707 	if ((operation == SMIME_VERIFY) ||
708 	    (operation == SMIME_VERIFY_RECEIPT)) {
709 		if (!(store = setup_verify(bio_err, CAfile, CApath)))
710 			goto end;
711 		X509_STORE_set_verify_cb(store, cms_cb);
712 		if (vpm)
713 			X509_STORE_set1_param(store, vpm);
714 	}
715 	ret = 3;
716 
717 	if (operation == SMIME_DATA_CREATE) {
718 		cms = CMS_data_create(in, flags);
719 	} else if (operation == SMIME_DIGEST_CREATE) {
720 		cms = CMS_digest_create(in, sign_md, flags);
721 	} else if (operation == SMIME_COMPRESS) {
722 		cms = CMS_compress(in, -1, flags);
723 	} else if (operation == SMIME_ENCRYPT) {
724 		flags |= CMS_PARTIAL;
725 		cms = CMS_encrypt(encerts, in, cipher, flags);
726 		if (!cms)
727 			goto end;
728 		if (secret_key) {
729 			if (!CMS_add0_recipient_key(cms, NID_undef, secret_key,
730 			    secret_keylen, secret_keyid, secret_keyidlen,
731 			    NULL, NULL, NULL))
732 				goto end;
733 			/* NULL these because call absorbs them */
734 			secret_key = NULL;
735 			secret_keyid = NULL;
736 		}
737 		if (pwri_pass) {
738 			pwri_tmp = strdup(pwri_pass);
739 			if (!pwri_tmp)
740 				goto end;
741 			if (!CMS_add0_recipient_password(cms, -1, NID_undef,
742 			    NID_undef, pwri_tmp, -1, NULL))
743 				goto end;
744 			pwri_tmp = NULL;
745 		}
746 		if (!(flags & CMS_STREAM)) {
747 			if (!CMS_final(cms, in, NULL, flags))
748 				goto end;
749 		}
750 	} else if (operation == SMIME_ENCRYPTED_ENCRYPT) {
751 		cms = CMS_EncryptedData_encrypt(in, cipher, secret_key,
752 		    secret_keylen, flags);
753 
754 	} else if (operation == SMIME_SIGN_RECEIPT) {
755 		CMS_ContentInfo *srcms = NULL;
756 		STACK_OF(CMS_SignerInfo) * sis;
757 		CMS_SignerInfo *si;
758 		sis = CMS_get0_SignerInfos(cms);
759 		if (!sis)
760 			goto end;
761 		si = sk_CMS_SignerInfo_value(sis, 0);
762 		srcms = CMS_sign_receipt(si, signer, key, other, flags);
763 		if (!srcms)
764 			goto end;
765 		CMS_ContentInfo_free(cms);
766 		cms = srcms;
767 	} else if (operation & SMIME_SIGNERS) {
768 		int i;
769 		/*
770 		 * If detached data content we enable streaming if S/MIME
771 		 * output format.
772 		 */
773 		if (operation == SMIME_SIGN) {
774 
775 			if (flags & CMS_DETACHED) {
776 				if (outformat == FORMAT_SMIME)
777 					flags |= CMS_STREAM;
778 			}
779 			flags |= CMS_PARTIAL;
780 			cms = CMS_sign(NULL, NULL, other, in, flags);
781 			if (!cms)
782 				goto end;
783 			if (econtent_type)
784 				CMS_set1_eContentType(cms, econtent_type);
785 
786 			if (rr_to) {
787 				rr = make_receipt_request(rr_to, rr_allorfirst,
788 				    rr_from);
789 				if (!rr) {
790 					BIO_puts(bio_err,
791 					    "Signed Receipt Request Creation Error\n");
792 					goto end;
793 				}
794 			}
795 		} else
796 			flags |= CMS_REUSE_DIGEST;
797 		for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) {
798 			CMS_SignerInfo *si;
799 			signerfile = sk_OPENSSL_STRING_value(sksigners, i);
800 			keyfile = sk_OPENSSL_STRING_value(skkeys, i);
801 			signer = load_cert(bio_err, signerfile, FORMAT_PEM,
802 			    NULL, e, "signer certificate");
803 			if (!signer)
804 				goto end;
805 			key = load_key(bio_err, keyfile, keyform, 0, passin, e,
806 			    "signing key file");
807 			if (!key)
808 				goto end;
809 			si = CMS_add1_signer(cms, signer, key, sign_md, flags);
810 			if (!si)
811 				goto end;
812 			if (rr && !CMS_add1_ReceiptRequest(si, rr))
813 				goto end;
814 			X509_free(signer);
815 			signer = NULL;
816 			EVP_PKEY_free(key);
817 			key = NULL;
818 		}
819 		/* If not streaming or resigning finalize structure */
820 		if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) {
821 			if (!CMS_final(cms, in, NULL, flags))
822 				goto end;
823 		}
824 	}
825 	if (!cms) {
826 		BIO_printf(bio_err, "Error creating CMS structure\n");
827 		goto end;
828 	}
829 	ret = 4;
830 	if (operation == SMIME_DECRYPT) {
831 		if (flags & CMS_DEBUG_DECRYPT)
832 			CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags);
833 
834 		if (secret_key) {
835 			if (!CMS_decrypt_set1_key(cms, secret_key,
836 			    secret_keylen, secret_keyid, secret_keyidlen)) {
837 				BIO_puts(bio_err,
838 				    "Error decrypting CMS using secret key\n");
839 				goto end;
840 			}
841 		}
842 		if (key) {
843 			if (!CMS_decrypt_set1_pkey(cms, key, recip)) {
844 				BIO_puts(bio_err,
845 				    "Error decrypting CMS using private key\n");
846 				goto end;
847 			}
848 		}
849 		if (pwri_pass) {
850 			if (!CMS_decrypt_set1_password(cms, pwri_pass, -1)) {
851 				BIO_puts(bio_err,
852 				    "Error decrypting CMS using password\n");
853 				goto end;
854 			}
855 		}
856 		if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) {
857 			BIO_printf(bio_err, "Error decrypting CMS structure\n");
858 			goto end;
859 		}
860 	} else if (operation == SMIME_DATAOUT) {
861 		if (!CMS_data(cms, out, flags))
862 			goto end;
863 	} else if (operation == SMIME_UNCOMPRESS) {
864 		if (!CMS_uncompress(cms, indata, out, flags))
865 			goto end;
866 	} else if (operation == SMIME_DIGEST_VERIFY) {
867 		if (CMS_digest_verify(cms, indata, out, flags) > 0)
868 			BIO_printf(bio_err, "Verification successful\n");
869 		else {
870 			BIO_printf(bio_err, "Verification failure\n");
871 			goto end;
872 		}
873 	} else if (operation == SMIME_ENCRYPTED_DECRYPT) {
874 		if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen,
875 		    indata, out, flags))
876 			goto end;
877 	} else if (operation == SMIME_VERIFY) {
878 		if (CMS_verify(cms, other, store, indata, out, flags) > 0)
879 			BIO_printf(bio_err, "Verification successful\n");
880 		else {
881 			BIO_printf(bio_err, "Verification failure\n");
882 			if (verify_retcode)
883 				ret = verify_err + 32;
884 			goto end;
885 		}
886 		if (signerfile) {
887 			STACK_OF(X509) * signers;
888 			signers = CMS_get0_signers(cms);
889 			if (!save_certs(signerfile, signers)) {
890 				BIO_printf(bio_err,
891 				    "Error writing signers to %s\n",
892 				    signerfile);
893 				ret = 5;
894 				goto end;
895 			}
896 			sk_X509_free(signers);
897 		}
898 		if (rr_print)
899 			receipt_request_print(bio_err, cms);
900 
901 	} else if (operation == SMIME_VERIFY_RECEIPT) {
902 		if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0)
903 			BIO_printf(bio_err, "Verification successful\n");
904 		else {
905 			BIO_printf(bio_err, "Verification failure\n");
906 			goto end;
907 		}
908 	} else {
909 		if (noout) {
910 			if (print)
911 				CMS_ContentInfo_print_ctx(out, cms, 0, NULL);
912 		} else if (outformat == FORMAT_SMIME) {
913 			if (to)
914 				BIO_printf(out, "To: %s\n", to);
915 			if (from)
916 				BIO_printf(out, "From: %s\n", from);
917 			if (subject)
918 				BIO_printf(out, "Subject: %s\n", subject);
919 			if (operation == SMIME_RESIGN)
920 				ret = SMIME_write_CMS(out, cms, indata, flags);
921 			else
922 				ret = SMIME_write_CMS(out, cms, in, flags);
923 		} else if (outformat == FORMAT_PEM)
924 			ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
925 		else if (outformat == FORMAT_ASN1)
926 			ret = i2d_CMS_bio_stream(out, cms, in, flags);
927 		else {
928 			BIO_printf(bio_err, "Bad output format for CMS file\n");
929 			goto end;
930 		}
931 		if (ret <= 0) {
932 			ret = 6;
933 			goto end;
934 		}
935 	}
936 	ret = 0;
937 
938 end:
939 	if (ret)
940 		ERR_print_errors(bio_err);
941 	sk_X509_pop_free(encerts, X509_free);
942 	sk_X509_pop_free(other, X509_free);
943 	if (vpm)
944 		X509_VERIFY_PARAM_free(vpm);
945 	if (sksigners)
946 		sk_OPENSSL_STRING_free(sksigners);
947 	if (skkeys)
948 		sk_OPENSSL_STRING_free(skkeys);
949 	free(secret_key);
950 	free(secret_keyid);
951 	free(pwri_tmp);
952 	if (econtent_type)
953 		ASN1_OBJECT_free(econtent_type);
954 	if (rr)
955 		CMS_ReceiptRequest_free(rr);
956 	if (rr_to)
957 		sk_OPENSSL_STRING_free(rr_to);
958 	if (rr_from)
959 		sk_OPENSSL_STRING_free(rr_from);
960 	X509_STORE_free(store);
961 	X509_free(cert);
962 	X509_free(recip);
963 	X509_free(signer);
964 	EVP_PKEY_free(key);
965 	CMS_ContentInfo_free(cms);
966 	CMS_ContentInfo_free(rcms);
967 	BIO_free(rctin);
968 	BIO_free(in);
969 	BIO_free(indata);
970 	BIO_free_all(out);
971 	free(passin);
972 	return (ret);
973 }
974 
975 static int
976 save_certs(char *signerfile, STACK_OF(X509) * signers)
977 {
978 	int i;
979 	BIO *tmp;
980 
981 	if (!signerfile)
982 		return 1;
983 	tmp = BIO_new_file(signerfile, "w");
984 	if (!tmp)
985 		return 0;
986 	for (i = 0; i < sk_X509_num(signers); i++)
987 		PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
988 	BIO_free(tmp);
989 	return 1;
990 }
991 
992 /* Minimal callback just to output policy info (if any) */
993 
994 static int
995 cms_cb(int ok, X509_STORE_CTX * ctx)
996 {
997 	int error;
998 
999 	error = X509_STORE_CTX_get_error(ctx);
1000 
1001 	verify_err = error;
1002 
1003 	if ((error != X509_V_ERR_NO_EXPLICIT_POLICY) &&
1004 	    ((error != X509_V_OK) || (ok != 2)))
1005 		return ok;
1006 
1007 	policies_print(NULL, ctx);
1008 
1009 	return ok;
1010 }
1011 
1012 static void
1013 gnames_stack_print(BIO * out, STACK_OF(GENERAL_NAMES) * gns)
1014 {
1015 	STACK_OF(GENERAL_NAME) * gens;
1016 	GENERAL_NAME *gen;
1017 	int i, j;
1018 
1019 	for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++) {
1020 		gens = sk_GENERAL_NAMES_value(gns, i);
1021 		for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) {
1022 			gen = sk_GENERAL_NAME_value(gens, j);
1023 			BIO_puts(out, "    ");
1024 			GENERAL_NAME_print(out, gen);
1025 			BIO_puts(out, "\n");
1026 		}
1027 	}
1028 	return;
1029 }
1030 
1031 static void
1032 receipt_request_print(BIO * out, CMS_ContentInfo * cms)
1033 {
1034 	STACK_OF(CMS_SignerInfo) * sis;
1035 	CMS_SignerInfo *si;
1036 	CMS_ReceiptRequest *rr;
1037 	int allorfirst;
1038 	STACK_OF(GENERAL_NAMES) * rto, *rlist;
1039 	ASN1_STRING *scid;
1040 	int i, rv;
1041 
1042 	sis = CMS_get0_SignerInfos(cms);
1043 	for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) {
1044 		si = sk_CMS_SignerInfo_value(sis, i);
1045 		rv = CMS_get1_ReceiptRequest(si, &rr);
1046 		BIO_printf(bio_err, "Signer %d:\n", i + 1);
1047 		if (rv == 0)
1048 			BIO_puts(bio_err, "  No Receipt Request\n");
1049 		else if (rv < 0) {
1050 			BIO_puts(bio_err, "  Receipt Request Parse Error\n");
1051 			ERR_print_errors(bio_err);
1052 		} else {
1053 			char *id;
1054 			int idlen;
1055 			CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
1056 			    &rlist, &rto);
1057 			BIO_puts(out, "  Signed Content ID:\n");
1058 			idlen = ASN1_STRING_length(scid);
1059 			id = (char *) ASN1_STRING_data(scid);
1060 			BIO_dump_indent(out, id, idlen, 4);
1061 			BIO_puts(out, "  Receipts From");
1062 			if (rlist) {
1063 				BIO_puts(out, " List:\n");
1064 				gnames_stack_print(out, rlist);
1065 			} else if (allorfirst == 1)
1066 				BIO_puts(out, ": First Tier\n");
1067 			else if (allorfirst == 0)
1068 				BIO_puts(out, ": All\n");
1069 			else
1070 				BIO_printf(out, " Unknown (%d)\n", allorfirst);
1071 			BIO_puts(out, "  Receipts To:\n");
1072 			gnames_stack_print(out, rto);
1073 		}
1074 		if (rr)
1075 			CMS_ReceiptRequest_free(rr);
1076 	}
1077 }
1078 
1079 static STACK_OF(GENERAL_NAMES) *
1080 make_names_stack(STACK_OF(OPENSSL_STRING) * ns)
1081 {
1082 	int i;
1083 	STACK_OF(GENERAL_NAMES) * ret;
1084 	GENERAL_NAMES *gens = NULL;
1085 	GENERAL_NAME *gen = NULL;
1086 	ret = sk_GENERAL_NAMES_new_null();
1087 	if (!ret)
1088 		goto err;
1089 	for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) {
1090 		char *str = sk_OPENSSL_STRING_value(ns, i);
1091 		gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
1092 		if (!gen)
1093 			goto err;
1094 		gens = GENERAL_NAMES_new();
1095 		if (!gens)
1096 			goto err;
1097 		if (!sk_GENERAL_NAME_push(gens, gen))
1098 			goto err;
1099 		gen = NULL;
1100 		if (!sk_GENERAL_NAMES_push(ret, gens))
1101 			goto err;
1102 		gens = NULL;
1103 	}
1104 
1105 	return ret;
1106 
1107 err:
1108 	if (ret)
1109 		sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free);
1110 	if (gens)
1111 		GENERAL_NAMES_free(gens);
1112 	if (gen)
1113 		GENERAL_NAME_free(gen);
1114 	return NULL;
1115 }
1116 
1117 
1118 static CMS_ReceiptRequest *
1119 make_receipt_request(STACK_OF(OPENSSL_STRING) * rr_to, int rr_allorfirst,
1120     STACK_OF(OPENSSL_STRING) * rr_from)
1121 {
1122 	STACK_OF(GENERAL_NAMES) * rct_to, *rct_from;
1123 	CMS_ReceiptRequest *rr;
1124 
1125 	rct_to = make_names_stack(rr_to);
1126 	if (!rct_to)
1127 		goto err;
1128 	if (rr_from) {
1129 		rct_from = make_names_stack(rr_from);
1130 		if (!rct_from)
1131 			goto err;
1132 	} else
1133 		rct_from = NULL;
1134 	rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
1135 	    rct_to);
1136 	return rr;
1137 
1138 err:
1139 	return NULL;
1140 }
1141 
1142 #endif
1143