]> git.ipfire.org Git - thirdparty/openssl.git/blame - apps/cms.c
Support for verification of signed receipts.
[thirdparty/openssl.git] / apps / cms.c
CommitLineData
8931b30d
DSH
1/* apps/cms.c */
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#include "apps.h"
59
60#ifndef OPENSSL_NO_CMS
61
62#include <openssl/crypto.h>
63#include <openssl/pem.h>
64#include <openssl/err.h>
65#include <openssl/x509_vfy.h>
66#include <openssl/x509v3.h>
67#include <openssl/cms.h>
68
69#undef PROG
70#define PROG cms_main
71static int save_certs(char *signerfile, STACK_OF(X509) *signers);
72static int smime_cb(int ok, X509_STORE_CTX *ctx);
f4cc56f4 73static void receipt_request_print(BIO *out, CMS_ContentInfo *cms);
f5e2354c
DSH
74static CMS_ReceiptRequest *make_receipt_request(STACK *rr_to, int rr_allorfirst,
75 STACK *rr_from);
8931b30d
DSH
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)
b820455c 92#define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP)
d9f5f07e 93#define SMIME_ENCRYPTED_ENCRYPT (14 | SMIME_OP)
eb9d8d8c
DSH
94#define SMIME_SIGN_RECEIPT (15 | SMIME_OP | SMIME_IP)
95#define SMIME_VERIFY_RECEIPT (16 | SMIME_IP)
8931b30d
DSH
96
97int MAIN(int, char **);
98
99int MAIN(int argc, char **argv)
100 {
101 ENGINE *e = NULL;
102 int operation = 0;
103 int ret = 0;
104 char **args;
105 const char *inmode = "r", *outmode = "w";
eb9d8d8c 106 char *infile = NULL, *outfile = NULL, *rctfile = NULL;
8931b30d
DSH
107 char *signerfile = NULL, *recipfile = NULL;
108 STACK *sksigners = NULL, *skkeys = NULL;
109 char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
110 const EVP_CIPHER *cipher = NULL;
eb9d8d8c 111 CMS_ContentInfo *cms = NULL, *rcms = NULL;
8931b30d
DSH
112 X509_STORE *store = NULL;
113 X509 *cert = NULL, *recip = NULL, *signer = NULL;
114 EVP_PKEY *key = NULL;
115 STACK_OF(X509) *encerts = NULL, *other = NULL;
eb9d8d8c 116 BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
8931b30d 117 int badarg = 0;
62051713 118 int flags = CMS_DETACHED, noout = 0, print = 0;
f5e2354c
DSH
119 int rr_print = 0, rr_allorfirst = -1;
120 STACK *rr_to = NULL, *rr_from = NULL;
121 CMS_ReceiptRequest *rr = NULL;
8931b30d
DSH
122 char *to = NULL, *from = NULL, *subject = NULL;
123 char *CAfile = NULL, *CApath = NULL;
124 char *passargin = NULL, *passin = NULL;
125 char *inrand = NULL;
126 int need_rand = 0;
8931b30d
DSH
127 const EVP_MD *sign_md = NULL;
128 int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
eb9d8d8c 129 int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
8931b30d
DSH
130#ifndef OPENSSL_NO_ENGINE
131 char *engine=NULL;
132#endif
ab124380
DSH
133 unsigned char *secret_key = NULL, *secret_keyid = NULL;
134 size_t secret_keylen = 0, secret_keyidlen = 0;
8931b30d 135
054307e7
DSH
136 ASN1_OBJECT *econtent_type = NULL;
137
8931b30d
DSH
138 X509_VERIFY_PARAM *vpm = NULL;
139
140 args = argv + 1;
141 ret = 1;
142
143 apps_startup();
144
145 if (bio_err == NULL)
146 {
147 if ((bio_err = BIO_new(BIO_s_file())) != NULL)
148 BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
149 }
150
151 if (!load_config(bio_err, NULL))
152 goto end;
153
154 while (!badarg && *args && *args[0] == '-')
155 {
156 if (!strcmp (*args, "-encrypt"))
157 operation = SMIME_ENCRYPT;
158 else if (!strcmp (*args, "-decrypt"))
159 operation = SMIME_DECRYPT;
160 else if (!strcmp (*args, "-sign"))
161 operation = SMIME_SIGN;
162 else if (!strcmp (*args, "-resign"))
163 operation = SMIME_RESIGN;
164 else if (!strcmp (*args, "-verify"))
165 operation = SMIME_VERIFY;
eb9d8d8c
DSH
166 else if (!strcmp(*args,"-verify_receipt"))
167 {
168 operation = SMIME_VERIFY_RECEIPT;
169 if (!args[1])
170 goto argerr;
171 args++;
172 rctfile = *args;
173 }
8931b30d
DSH
174 else if (!strcmp (*args, "-cmsout"))
175 operation = SMIME_CMSOUT;
176 else if (!strcmp (*args, "-data_out"))
177 operation = SMIME_DATAOUT;
178 else if (!strcmp (*args, "-data_create"))
179 operation = SMIME_DATA_CREATE;
180 else if (!strcmp (*args, "-digest_verify"))
181 operation = SMIME_DIGEST_VERIFY;
182 else if (!strcmp (*args, "-digest_create"))
183 operation = SMIME_DIGEST_CREATE;
184 else if (!strcmp (*args, "-compress"))
185 operation = SMIME_COMPRESS;
186 else if (!strcmp (*args, "-uncompress"))
187 operation = SMIME_UNCOMPRESS;
1021f9aa 188 else if (!strcmp (*args, "-EncryptedData_decrypt"))
b820455c 189 operation = SMIME_ENCRYPTED_DECRYPT;
d9f5f07e
DSH
190 else if (!strcmp (*args, "-EncryptedData_encrypt"))
191 operation = SMIME_ENCRYPTED_ENCRYPT;
8931b30d
DSH
192#ifndef OPENSSL_NO_DES
193 else if (!strcmp (*args, "-des3"))
194 cipher = EVP_des_ede3_cbc();
195 else if (!strcmp (*args, "-des"))
196 cipher = EVP_des_cbc();
197#endif
198#ifndef OPENSSL_NO_SEED
199 else if (!strcmp (*args, "-seed"))
200 cipher = EVP_seed_cbc();
201#endif
202#ifndef OPENSSL_NO_RC2
203 else if (!strcmp (*args, "-rc2-40"))
204 cipher = EVP_rc2_40_cbc();
205 else if (!strcmp (*args, "-rc2-128"))
206 cipher = EVP_rc2_cbc();
207 else if (!strcmp (*args, "-rc2-64"))
208 cipher = EVP_rc2_64_cbc();
209#endif
210#ifndef OPENSSL_NO_AES
211 else if (!strcmp(*args,"-aes128"))
212 cipher = EVP_aes_128_cbc();
213 else if (!strcmp(*args,"-aes192"))
214 cipher = EVP_aes_192_cbc();
215 else if (!strcmp(*args,"-aes256"))
216 cipher = EVP_aes_256_cbc();
217#endif
218#ifndef OPENSSL_NO_CAMELLIA
219 else if (!strcmp(*args,"-camellia128"))
220 cipher = EVP_camellia_128_cbc();
221 else if (!strcmp(*args,"-camellia192"))
222 cipher = EVP_camellia_192_cbc();
223 else if (!strcmp(*args,"-camellia256"))
224 cipher = EVP_camellia_256_cbc();
225#endif
226 else if (!strcmp (*args, "-text"))
227 flags |= CMS_TEXT;
228 else if (!strcmp (*args, "-nointern"))
229 flags |= CMS_NOINTERN;
230 else if (!strcmp (*args, "-noverify")
231 || !strcmp (*args, "-no_signer_cert_verify"))
232 flags |= CMS_NO_SIGNER_CERT_VERIFY;
233 else if (!strcmp (*args, "-nocerts"))
234 flags |= CMS_NOCERTS;
235 else if (!strcmp (*args, "-noattr"))
236 flags |= CMS_NOATTR;
237 else if (!strcmp (*args, "-nodetach"))
238 flags &= ~CMS_DETACHED;
239 else if (!strcmp (*args, "-nosmimecap"))
240 flags |= CMS_NOSMIMECAP;
241 else if (!strcmp (*args, "-binary"))
242 flags |= CMS_BINARY;
243 else if (!strcmp (*args, "-keyid"))
244 flags |= CMS_USE_KEYID;
245 else if (!strcmp (*args, "-nosigs"))
246 flags |= CMS_NOSIGS;
247 else if (!strcmp (*args, "-no_content_verify"))
248 flags |= CMS_NO_CONTENT_VERIFY;
249 else if (!strcmp (*args, "-no_attr_verify"))
250 flags |= CMS_NO_ATTR_VERIFY;
251 else if (!strcmp (*args, "-stream"))
e4f0e40e 252 flags |= CMS_STREAM;
8931b30d 253 else if (!strcmp (*args, "-indef"))
e4f0e40e 254 flags |= CMS_STREAM;
8931b30d 255 else if (!strcmp (*args, "-noindef"))
e4f0e40e 256 flags &= ~CMS_STREAM;
8931b30d
DSH
257 else if (!strcmp (*args, "-nooldmime"))
258 flags |= CMS_NOOLDMIMETYPE;
259 else if (!strcmp (*args, "-crlfeol"))
260 flags |= CMS_CRLFEOL;
62051713
DSH
261 else if (!strcmp (*args, "-noout"))
262 noout = 1;
f4cc56f4
DSH
263 else if (!strcmp (*args, "-receipt_request_print"))
264 rr_print = 1;
f5e2354c
DSH
265 else if (!strcmp (*args, "-receipt_request_all"))
266 rr_allorfirst = 0;
267 else if (!strcmp (*args, "-receipt_request_first"))
268 rr_allorfirst = 1;
269 else if (!strcmp(*args,"-receipt_request_from"))
270 {
271 if (!args[1])
272 goto argerr;
273 args++;
274 if (!rr_from)
275 rr_from = sk_new_null();
276 sk_push(rr_from, *args);
277 }
278 else if (!strcmp(*args,"-receipt_request_to"))
279 {
280 if (!args[1])
281 goto argerr;
282 args++;
283 if (!rr_to)
284 rr_to = sk_new_null();
285 sk_push(rr_to, *args);
286 }
62051713
DSH
287 else if (!strcmp (*args, "-print"))
288 {
289 noout = 1;
290 print = 1;
291 }
b820455c
DSH
292 else if (!strcmp(*args,"-secretkey"))
293 {
294 long ltmp;
295 if (!args[1])
296 goto argerr;
297 args++;
298 secret_key = string_to_hex(*args, &ltmp);
299 if (!secret_key)
300 {
301 BIO_printf(bio_err, "Invalid key %s\n", *args);
302 goto argerr;
303 }
304 secret_keylen = (size_t)ltmp;
305 }
ab124380
DSH
306 else if (!strcmp(*args,"-secretkeyid"))
307 {
308 long ltmp;
309 if (!args[1])
310 goto argerr;
311 args++;
312 secret_keyid = string_to_hex(*args, &ltmp);
313 if (!secret_keyid)
314 {
315 BIO_printf(bio_err, "Invalid id %s\n", *args);
316 goto argerr;
317 }
318 secret_keyidlen = (size_t)ltmp;
319 }
054307e7
DSH
320 else if (!strcmp(*args,"-econtent_type"))
321 {
322 if (!args[1])
323 goto argerr;
324 args++;
325 econtent_type = OBJ_txt2obj(*args, 0);
326 if (!econtent_type)
327 {
328 BIO_printf(bio_err, "Invalid OID %s\n", *args);
329 goto argerr;
330 }
331 }
8931b30d
DSH
332 else if (!strcmp(*args,"-rand"))
333 {
334 if (!args[1])
335 goto argerr;
336 args++;
337 inrand = *args;
338 need_rand = 1;
339 }
340#ifndef OPENSSL_NO_ENGINE
341 else if (!strcmp(*args,"-engine"))
342 {
343 if (!args[1])
344 goto argerr;
345 engine = *++args;
346 }
347#endif
348 else if (!strcmp(*args,"-passin"))
349 {
350 if (!args[1])
351 goto argerr;
352 passargin = *++args;
353 }
354 else if (!strcmp (*args, "-to"))
355 {
356 if (!args[1])
357 goto argerr;
358 to = *++args;
359 }
360 else if (!strcmp (*args, "-from"))
361 {
362 if (!args[1])
363 goto argerr;
364 from = *++args;
365 }
366 else if (!strcmp (*args, "-subject"))
367 {
368 if (!args[1])
369 goto argerr;
370 subject = *++args;
371 }
372 else if (!strcmp (*args, "-signer"))
373 {
374 if (!args[1])
375 goto argerr;
376 /* If previous -signer argument add signer to list */
377
378 if (signerfile)
379 {
380 if (!sksigners)
381 sksigners = sk_new_null();
382 sk_push(sksigners, signerfile);
383 if (!keyfile)
384 keyfile = signerfile;
385 if (!skkeys)
386 skkeys = sk_new_null();
387 sk_push(skkeys, keyfile);
388 keyfile = NULL;
389 }
390 signerfile = *++args;
391 }
392 else if (!strcmp (*args, "-recip"))
393 {
394 if (!args[1])
395 goto argerr;
396 recipfile = *++args;
397 }
398 else if (!strcmp (*args, "-md"))
399 {
400 if (!args[1])
401 goto argerr;
402 sign_md = EVP_get_digestbyname(*++args);
403 if (sign_md == NULL)
404 {
405 BIO_printf(bio_err, "Unknown digest %s\n",
406 *args);
407 goto argerr;
408 }
409 }
410 else if (!strcmp (*args, "-inkey"))
411 {
412 if (!args[1])
413 goto argerr;
414 /* If previous -inkey arument add signer to list */
415 if (keyfile)
416 {
417 if (!signerfile)
418 {
419 BIO_puts(bio_err, "Illegal -inkey without -signer\n");
420 goto argerr;
421 }
422 if (!sksigners)
423 sksigners = sk_new_null();
424 sk_push(sksigners, signerfile);
425 signerfile = NULL;
426 if (!skkeys)
427 skkeys = sk_new_null();
428 sk_push(skkeys, keyfile);
429 }
430 keyfile = *++args;
431 }
432 else if (!strcmp (*args, "-keyform"))
433 {
434 if (!args[1])
435 goto argerr;
436 keyform = str2fmt(*++args);
437 }
eb9d8d8c
DSH
438 else if (!strcmp (*args, "-rctform"))
439 {
440 if (!args[1])
441 goto argerr;
442 rctformat = str2fmt(*++args);
443 }
8931b30d
DSH
444 else if (!strcmp (*args, "-certfile"))
445 {
446 if (!args[1])
447 goto argerr;
448 certfile = *++args;
449 }
450 else if (!strcmp (*args, "-CAfile"))
451 {
452 if (!args[1])
453 goto argerr;
454 CAfile = *++args;
455 }
456 else if (!strcmp (*args, "-CApath"))
457 {
458 if (!args[1])
459 goto argerr;
460 CApath = *++args;
461 }
462 else if (!strcmp (*args, "-in"))
463 {
464 if (!args[1])
465 goto argerr;
466 infile = *++args;
467 }
468 else if (!strcmp (*args, "-inform"))
469 {
470 if (!args[1])
471 goto argerr;
472 informat = str2fmt(*++args);
473 }
474 else if (!strcmp (*args, "-outform"))
475 {
476 if (!args[1])
477 goto argerr;
478 outformat = str2fmt(*++args);
479 }
480 else if (!strcmp (*args, "-out"))
481 {
482 if (!args[1])
483 goto argerr;
484 outfile = *++args;
485 }
486 else if (!strcmp (*args, "-content"))
487 {
488 if (!args[1])
489 goto argerr;
490 contfile = *++args;
491 }
492 else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))
493 continue;
494 else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)
495 badarg = 1;
496 args++;
497 }
498
f5e2354c
DSH
499 if (((rr_allorfirst != -1) || rr_from) && !rr_to)
500 {
501 BIO_puts(bio_err, "No Signed Receipts Recipients\n");
502 goto argerr;
503 }
504
505 if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from))
506 {
507 BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
508 goto argerr;
509 }
8931b30d
DSH
510 if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners))
511 {
512 BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
513 goto argerr;
514 }
515
516 if (operation & SMIME_SIGNERS)
517 {
8931b30d
DSH
518 if (keyfile && !signerfile)
519 {
520 BIO_puts(bio_err, "Illegal -inkey without -signer\n");
521 goto argerr;
522 }
f5e2354c 523 /* Check to see if any final signer needs to be appended */
8931b30d
DSH
524 if (signerfile)
525 {
526 if (!sksigners)
527 sksigners = sk_new_null();
528 sk_push(sksigners, signerfile);
529 if (!skkeys)
530 skkeys = sk_new_null();
531 if (!keyfile)
532 keyfile = signerfile;
533 sk_push(skkeys, keyfile);
534 }
535 if (!sksigners)
536 {
537 BIO_printf(bio_err, "No signer certificate specified\n");
538 badarg = 1;
539 }
540 signerfile = NULL;
541 keyfile = NULL;
542 need_rand = 1;
543 }
544 else if (operation == SMIME_DECRYPT)
545 {
eeb9cdfc 546 if (!recipfile && !keyfile && !secret_key)
8931b30d
DSH
547 {
548 BIO_printf(bio_err, "No recipient certificate or key specified\n");
549 badarg = 1;
550 }
551 }
552 else if (operation == SMIME_ENCRYPT)
553 {
ab124380 554 if (!*args && !secret_key)
8931b30d
DSH
555 {
556 BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
557 badarg = 1;
558 }
559 need_rand = 1;
560 }
561 else if (!operation)
562 badarg = 1;
563
564 if (badarg)
565 {
566 argerr:
567 BIO_printf (bio_err, "Usage smime [options] cert.pem ...\n");
568 BIO_printf (bio_err, "where options are\n");
569 BIO_printf (bio_err, "-encrypt encrypt message\n");
570 BIO_printf (bio_err, "-decrypt decrypt encrypted message\n");
571 BIO_printf (bio_err, "-sign sign message\n");
572 BIO_printf (bio_err, "-verify verify signed message\n");
573 BIO_printf (bio_err, "-cmsout output CMS structure\n");
574#ifndef OPENSSL_NO_DES
575 BIO_printf (bio_err, "-des3 encrypt with triple DES\n");
576 BIO_printf (bio_err, "-des encrypt with DES\n");
577#endif
578#ifndef OPENSSL_NO_SEED
579 BIO_printf (bio_err, "-seed encrypt with SEED\n");
580#endif
581#ifndef OPENSSL_NO_RC2
582 BIO_printf (bio_err, "-rc2-40 encrypt with RC2-40 (default)\n");
583 BIO_printf (bio_err, "-rc2-64 encrypt with RC2-64\n");
584 BIO_printf (bio_err, "-rc2-128 encrypt with RC2-128\n");
585#endif
586#ifndef OPENSSL_NO_AES
587 BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
588 BIO_printf (bio_err, " encrypt PEM output with cbc aes\n");
589#endif
590#ifndef OPENSSL_NO_CAMELLIA
591 BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
592 BIO_printf (bio_err, " encrypt PEM output with cbc camellia\n");
593#endif
594 BIO_printf (bio_err, "-nointern don't search certificates in message for signer\n");
595 BIO_printf (bio_err, "-nosigs don't verify message signature\n");
596 BIO_printf (bio_err, "-noverify don't verify signers certificate\n");
597 BIO_printf (bio_err, "-nocerts don't include signers certificate when signing\n");
598 BIO_printf (bio_err, "-nodetach use opaque signing\n");
599 BIO_printf (bio_err, "-noattr don't include any signed attributes\n");
600 BIO_printf (bio_err, "-binary don't translate message to text\n");
601 BIO_printf (bio_err, "-certfile file other certificates file\n");
602 BIO_printf (bio_err, "-signer file signer certificate file\n");
603 BIO_printf (bio_err, "-recip file recipient certificate file for decryption\n");
604 BIO_printf (bio_err, "-skeyid use subject key identifier\n");
605 BIO_printf (bio_err, "-in file input file\n");
606 BIO_printf (bio_err, "-inform arg input format SMIME (default), PEM or DER\n");
607 BIO_printf (bio_err, "-inkey file input private key (if not signer or recipient)\n");
608 BIO_printf (bio_err, "-keyform arg input private key format (PEM or ENGINE)\n");
609 BIO_printf (bio_err, "-out file output file\n");
610 BIO_printf (bio_err, "-outform arg output format SMIME (default), PEM or DER\n");
611 BIO_printf (bio_err, "-content file supply or override content for detached signature\n");
612 BIO_printf (bio_err, "-to addr to address\n");
613 BIO_printf (bio_err, "-from ad from address\n");
614 BIO_printf (bio_err, "-subject s subject\n");
615 BIO_printf (bio_err, "-text include or delete text MIME headers\n");
616 BIO_printf (bio_err, "-CApath dir trusted certificates directory\n");
617 BIO_printf (bio_err, "-CAfile file trusted certificates file\n");
618 BIO_printf (bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n");
619 BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
620#ifndef OPENSSL_NO_ENGINE
621 BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n");
622#endif
623 BIO_printf (bio_err, "-passin arg input file pass phrase source\n");
624 BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
625 BIO_printf(bio_err, " load the file (or the files in the directory) into\n");
626 BIO_printf(bio_err, " the random number generator\n");
627 BIO_printf (bio_err, "cert.pem recipient certificate(s) for encryption\n");
628 goto end;
629 }
630
631#ifndef OPENSSL_NO_ENGINE
632 e = setup_engine(bio_err, engine, 0);
633#endif
634
635 if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
636 {
637 BIO_printf(bio_err, "Error getting password\n");
638 goto end;
639 }
640
641 if (need_rand)
642 {
643 app_RAND_load_file(NULL, bio_err, (inrand != NULL));
644 if (inrand != NULL)
645 BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
646 app_RAND_load_files(inrand));
647 }
648
649 ret = 2;
650
651 if (!(operation & SMIME_SIGNERS))
652 flags &= ~CMS_DETACHED;
653
654 if (operation & SMIME_OP)
655 {
656 if (outformat == FORMAT_ASN1)
657 outmode = "wb";
658 }
659 else
660 {
661 if (flags & CMS_BINARY)
662 outmode = "wb";
663 }
664
665 if (operation & SMIME_IP)
666 {
667 if (informat == FORMAT_ASN1)
668 inmode = "rb";
669 }
670 else
671 {
672 if (flags & CMS_BINARY)
673 inmode = "rb";
674 }
675
676 if (operation == SMIME_ENCRYPT)
677 {
678 if (!cipher)
679 {
c220e58f
DSH
680#ifndef OPENSSL_NO_DES
681 cipher = EVP_des_ede3_cbc();
8931b30d
DSH
682#else
683 BIO_printf(bio_err, "No cipher selected\n");
684 goto end;
685#endif
686 }
ab124380
DSH
687
688 if (secret_key && !secret_keyid)
689 {
690 BIO_printf(bio_err, "No sectre key id\n");
691 goto end;
692 }
693
694 if (*args)
695 encerts = sk_X509_new_null();
8931b30d
DSH
696 while (*args)
697 {
698 if (!(cert = load_cert(bio_err,*args,FORMAT_PEM,
699 NULL, e, "recipient certificate file")))
8931b30d 700 goto end;
8931b30d
DSH
701 sk_X509_push(encerts, cert);
702 cert = NULL;
703 args++;
704 }
705 }
706
707 if (certfile)
708 {
709 if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL,
710 e, "certificate file")))
711 {
712 ERR_print_errors(bio_err);
713 goto end;
714 }
715 }
716
717 if (recipfile && (operation == SMIME_DECRYPT))
718 {
719 if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL,
720 e, "recipient certificate file")))
721 {
722 ERR_print_errors(bio_err);
723 goto end;
724 }
725 }
726
727 if (operation == SMIME_DECRYPT)
728 {
729 if (!keyfile)
730 keyfile = recipfile;
731 }
732 else if (operation == SMIME_SIGN)
733 {
734 if (!keyfile)
735 keyfile = signerfile;
736 }
737 else keyfile = NULL;
738
739 if (keyfile)
740 {
741 key = load_key(bio_err, keyfile, keyform, 0, passin, e,
742 "signing key file");
743 if (!key)
744 goto end;
745 }
746
747 if (infile)
748 {
749 if (!(in = BIO_new_file(infile, inmode)))
750 {
751 BIO_printf (bio_err,
752 "Can't open input file %s\n", infile);
753 goto end;
754 }
755 }
756 else
757 in = BIO_new_fp(stdin, BIO_NOCLOSE);
758
759 if (operation & SMIME_IP)
760 {
761 if (informat == FORMAT_SMIME)
762 cms = SMIME_read_CMS(in, &indata);
763 else if (informat == FORMAT_PEM)
764 cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
765 else if (informat == FORMAT_ASN1)
766 cms = d2i_CMS_bio(in, NULL);
767 else
768 {
769 BIO_printf(bio_err, "Bad input format for CMS file\n");
770 goto end;
771 }
772
773 if (!cms)
774 {
775 BIO_printf(bio_err, "Error reading S/MIME message\n");
776 goto end;
777 }
778 if (contfile)
779 {
780 BIO_free(indata);
781 if (!(indata = BIO_new_file(contfile, "rb")))
782 {
783 BIO_printf(bio_err, "Can't read content file %s\n", contfile);
784 goto end;
785 }
786 }
787 }
788
eb9d8d8c
DSH
789 if (rctfile)
790 {
791 char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
792 if (!(rctin = BIO_new_file(rctfile, rctmode)))
793 {
794 BIO_printf (bio_err,
795 "Can't open receipt file %s\n", rctfile);
796 goto end;
797 }
798
799 if (rctformat == FORMAT_SMIME)
800 rcms = SMIME_read_CMS(rctin, NULL);
801 else if (rctformat == FORMAT_PEM)
802 rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
803 else if (rctformat == FORMAT_ASN1)
804 rcms = d2i_CMS_bio(rctin, NULL);
805 else
806 {
807 BIO_printf(bio_err, "Bad input format for receipt\n");
808 goto end;
809 }
810
811 if (!rcms)
812 {
813 BIO_printf(bio_err, "Error reading receipt\n");
814 goto end;
815 }
816 }
817
8931b30d
DSH
818 if (outfile)
819 {
820 if (!(out = BIO_new_file(outfile, outmode)))
821 {
822 BIO_printf (bio_err,
823 "Can't open output file %s\n", outfile);
824 goto end;
825 }
826 }
827 else
828 {
829 out = BIO_new_fp(stdout, BIO_NOCLOSE);
830#ifdef OPENSSL_SYS_VMS
831 {
832 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
833 out = BIO_push(tmpbio, out);
834 }
835#endif
836 }
837
eb9d8d8c 838 if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT))
8931b30d
DSH
839 {
840 if (!(store = setup_verify(bio_err, CAfile, CApath)))
841 goto end;
842 X509_STORE_set_verify_cb_func(store, smime_cb);
843 if (vpm)
844 X509_STORE_set1_param(store, vpm);
845 }
846
847
848 ret = 3;
849
850 if (operation == SMIME_DATA_CREATE)
851 {
8931b30d
DSH
852 cms = CMS_data_create(in, flags);
853 }
854 else if (operation == SMIME_DIGEST_CREATE)
855 {
8931b30d
DSH
856 cms = CMS_digest_create(in, sign_md, flags);
857 }
858 else if (operation == SMIME_COMPRESS)
859 {
8931b30d
DSH
860 cms = CMS_compress(in, -1, flags);
861 }
862 else if (operation == SMIME_ENCRYPT)
863 {
ab124380 864 flags |= CMS_PARTIAL;
8931b30d 865 cms = CMS_encrypt(encerts, in, cipher, flags);
ab124380
DSH
866 if (!cms)
867 goto end;
868 if (secret_key)
869 {
870 if (!CMS_add0_recipient_key(cms, NID_undef,
871 secret_key, secret_keylen,
872 secret_keyid, secret_keyidlen,
873 NULL, NULL, NULL))
874 goto end;
875 /* NULL these because call absorbs them */
876 secret_key = NULL;
877 secret_keyid = NULL;
878 }
879 if (!(flags & CMS_STREAM))
880 {
881 if (!CMS_final(cms, in, flags))
882 goto end;
883 }
8931b30d 884 }
d9f5f07e
DSH
885 else if (operation == SMIME_ENCRYPTED_ENCRYPT)
886 {
d9f5f07e
DSH
887 cms = CMS_EncryptedData_encrypt(in, cipher,
888 secret_key, secret_keylen,
889 flags);
ab124380 890
d9f5f07e 891 }
8931b30d
DSH
892 else if (operation & SMIME_SIGNERS)
893 {
894 int i;
f5e2354c 895 /* If detached data content we enable streaming if
8931b30d
DSH
896 * S/MIME output format.
897 */
898 if (operation == SMIME_SIGN)
899 {
f5e2354c 900
8931b30d
DSH
901 if (flags & CMS_DETACHED)
902 {
f5e2354c
DSH
903 if (outformat == FORMAT_SMIME)
904 flags |= CMS_STREAM;
8931b30d 905 }
8931b30d
DSH
906 flags |= CMS_PARTIAL;
907 cms = CMS_sign(NULL, NULL, other, in, flags);
908 if (!cms)
909 goto end;
f5e2354c
DSH
910 if (econtent_type)
911 CMS_set1_eContentType(cms, econtent_type);
912
913 if (rr_to)
914 {
915 rr = make_receipt_request(rr_to, rr_allorfirst,
916 rr_from);
917 if (!rr)
918 {
919 BIO_puts(bio_err,
920 "Signed Receipt Request Creation Error\n");
921 goto end;
922 }
923 }
8931b30d
DSH
924 }
925 else
926 flags |= CMS_REUSE_DIGEST;
927 for (i = 0; i < sk_num(sksigners); i++)
928 {
f5e2354c 929 CMS_SignerInfo *si;
8931b30d
DSH
930 signerfile = sk_value(sksigners, i);
931 keyfile = sk_value(skkeys, i);
932 signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL,
933 e, "signer certificate");
934 if (!signer)
935 goto end;
936 key = load_key(bio_err, keyfile, keyform, 0, passin, e,
937 "signing key file");
938 if (!key)
939 goto end;
f5e2354c
DSH
940 si = CMS_add1_signer(cms, signer, key, sign_md, flags);
941 if (!si)
942 goto end;
943 if (rr && !CMS_add1_ReceiptRequest(si, rr))
8931b30d
DSH
944 goto end;
945 X509_free(signer);
946 signer = NULL;
947 EVP_PKEY_free(key);
948 key = NULL;
949 }
950 /* If not streaming or resigning finalize structure */
951 if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM))
952 {
953 if (!CMS_final(cms, in, flags))
954 goto end;
955 }
956 }
957
958 if (!cms)
959 {
960 BIO_printf(bio_err, "Error creating CMS structure\n");
961 goto end;
962 }
963
964 ret = 4;
965 if (operation == SMIME_DECRYPT)
966 {
eeb9cdfc
DSH
967
968 if (secret_key)
969 {
970 if (!CMS_decrypt_set1_key(cms,
971 secret_key, secret_keylen,
972 secret_keyid, secret_keyidlen))
973 {
974 BIO_puts(bio_err,
975 "Error decrypting CMS using secret key\n");
976 goto end;
977 }
978 }
979
980 if (key)
981 {
982 if (!CMS_decrypt_set1_pkey(cms, key, recip))
983 {
984 BIO_puts(bio_err,
985 "Error decrypting CMS using private key\n");
986 goto end;
987 }
988 }
989
990 if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags))
8931b30d
DSH
991 {
992 BIO_printf(bio_err, "Error decrypting CMS structure\n");
993 goto end;
994 }
995 }
996 else if (operation == SMIME_DATAOUT)
997 {
998 if (!CMS_data(cms, out, flags))
999 goto end;
1000 }
1001 else if (operation == SMIME_UNCOMPRESS)
1002 {
1003 if (!CMS_uncompress(cms, indata, out, flags))
1004 goto end;
1005 }
1006 else if (operation == SMIME_DIGEST_VERIFY)
1007 {
1008 if (CMS_digest_verify(cms, indata, out, flags) > 0)
1009 BIO_printf(bio_err, "Verification successful\n");
1010 else
1011 {
1012 BIO_printf(bio_err, "Verification failure\n");
1013 goto end;
1014 }
1015 }
b820455c
DSH
1016 else if (operation == SMIME_ENCRYPTED_DECRYPT)
1017 {
1018 if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen,
1019 indata, out, flags))
1020 goto end;
1021 }
8931b30d
DSH
1022 else if (operation == SMIME_VERIFY)
1023 {
1024 if (CMS_verify(cms, other, store, indata, out, flags) > 0)
1025 BIO_printf(bio_err, "Verification successful\n");
1026 else
1027 {
1028 BIO_printf(bio_err, "Verification failure\n");
1029 goto end;
1030 }
1031 if (signerfile)
1032 {
1033 STACK_OF(X509) *signers;
1034 signers = CMS_get0_signers(cms);
1035 if (!save_certs(signerfile, signers))
1036 {
1037 BIO_printf(bio_err,
1038 "Error writing signers to %s\n",
1039 signerfile);
1040 ret = 5;
1041 goto end;
1042 }
1043 sk_X509_free(signers);
1044 }
f4cc56f4
DSH
1045 if (rr_print)
1046 receipt_request_print(bio_err, cms);
1047
8931b30d 1048 }
eb9d8d8c
DSH
1049 else if (operation == SMIME_VERIFY_RECEIPT)
1050 {
1051 if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0)
1052 BIO_printf(bio_err, "Verification successful\n");
1053 else
1054 {
1055 BIO_printf(bio_err, "Verification failure\n");
1056 goto end;
1057 }
1058 }
8931b30d
DSH
1059 else
1060 {
62051713
DSH
1061 if (noout)
1062 {
1063 if (print)
1064 CMS_ContentInfo_print_ctx(out, cms, 0, NULL);
1065 }
1066 else if (outformat == FORMAT_SMIME)
8931b30d
DSH
1067 {
1068 if (to)
1069 BIO_printf(out, "To: %s\n", to);
1070 if (from)
1071 BIO_printf(out, "From: %s\n", from);
1072 if (subject)
1073 BIO_printf(out, "Subject: %s\n", subject);
1074 if (operation == SMIME_RESIGN)
1075 ret = SMIME_write_CMS(out, cms, indata, flags);
1076 else
1077 ret = SMIME_write_CMS(out, cms, in, flags);
1078 }
1079 else if (outformat == FORMAT_PEM)
1080 ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
1081 else if (outformat == FORMAT_ASN1)
1082 ret = i2d_CMS_bio_stream(out,cms, in, flags);
1083 else
1084 {
1085 BIO_printf(bio_err, "Bad output format for CMS file\n");
1086 goto end;
1087 }
1088 if (ret <= 0)
1089 {
1090 ret = 6;
1091 goto end;
1092 }
1093 }
1094 ret = 0;
1095end:
1096 if (ret)
1097 ERR_print_errors(bio_err);
1098 if (need_rand)
1099 app_RAND_write_file(NULL, bio_err);
1100 sk_X509_pop_free(encerts, X509_free);
1101 sk_X509_pop_free(other, X509_free);
1102 if (vpm)
1103 X509_VERIFY_PARAM_free(vpm);
1104 if (sksigners)
1105 sk_free(sksigners);
1106 if (skkeys)
1107 sk_free(skkeys);
b820455c
DSH
1108 if (secret_key)
1109 OPENSSL_free(secret_key);
ab124380
DSH
1110 if (secret_keyid)
1111 OPENSSL_free(secret_keyid);
054307e7
DSH
1112 if (econtent_type)
1113 ASN1_OBJECT_free(econtent_type);
f5e2354c
DSH
1114 if (rr)
1115 CMS_ReceiptRequest_free(rr);
1116 if (rr_to)
1117 sk_free(rr_to);
1118 if (rr_from)
1119 sk_free(rr_from);
8931b30d
DSH
1120 X509_STORE_free(store);
1121 X509_free(cert);
1122 X509_free(recip);
1123 X509_free(signer);
1124 EVP_PKEY_free(key);
1125 CMS_ContentInfo_free(cms);
eb9d8d8c
DSH
1126 CMS_ContentInfo_free(rcms);
1127 BIO_free(rctin);
8931b30d
DSH
1128 BIO_free(in);
1129 BIO_free(indata);
1130 BIO_free_all(out);
1131 if (passin) OPENSSL_free(passin);
1132 return (ret);
1133}
1134
1135static int save_certs(char *signerfile, STACK_OF(X509) *signers)
1136 {
1137 int i;
1138 BIO *tmp;
1139 if (!signerfile)
1140 return 1;
1141 tmp = BIO_new_file(signerfile, "w");
1142 if (!tmp) return 0;
1143 for(i = 0; i < sk_X509_num(signers); i++)
1144 PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
1145 BIO_free(tmp);
1146 return 1;
1147 }
1148
1149
1150/* Minimal callback just to output policy info (if any) */
1151
1152static int smime_cb(int ok, X509_STORE_CTX *ctx)
1153 {
1154 int error;
1155
1156 error = X509_STORE_CTX_get_error(ctx);
1157
1158 if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
1159 && ((error != X509_V_OK) || (ok != 2)))
1160 return ok;
1161
1162 policies_print(NULL, ctx);
1163
1164 return ok;
1165
1166 }
1167
f4cc56f4
DSH
1168static void gnames_stack_print(BIO *out, STACK_OF(GENERAL_NAMES) *gns)
1169 {
1170 STACK_OF(GENERAL_NAME) *gens;
1171 GENERAL_NAME *gen;
1172 int i, j;
1173 for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++)
1174 {
1175 gens = sk_GENERAL_NAMES_value(gns, i);
1176 for (j = 0; j < sk_GENERAL_NAME_num(gens); j++)
1177 {
1178 gen = sk_GENERAL_NAME_value(gens, j);
1179 BIO_puts(out, " ");
1180 GENERAL_NAME_print(out, gen);
1181 BIO_puts(out, "\n");
1182 }
1183 }
1184 return;
1185 }
1186
1187static void receipt_request_print(BIO *out, CMS_ContentInfo *cms)
1188 {
1189 STACK_OF(CMS_SignerInfo) *sis;
1190 CMS_SignerInfo *si;
1191 CMS_ReceiptRequest *rr;
1192 int allorfirst;
1193 STACK_OF(GENERAL_NAMES) *rto, *rlist;
1194 ASN1_STRING *scid;
1195 int i, rv;
1196 sis = CMS_get0_SignerInfos(cms);
1197 for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++)
1198 {
1199 si = sk_CMS_SignerInfo_value(sis, i);
1200 rv = CMS_get1_ReceiptRequest(si, &rr);
1201 BIO_printf(bio_err, "Signer %d:\n", i + 1);
1202 if (rv == 0)
1203 BIO_puts(bio_err, " No Receipt Request\n");
1204 else if (rv < 0)
1205 {
1206 BIO_puts(bio_err, " Receipt Request Parse Error\n");
1207 ERR_print_errors(bio_err);
1208 }
1209 else
1210 {
1211 char *id;
1212 int idlen;
1213 CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
1214 &rlist, &rto);
1215 BIO_puts(out, " Signed Content ID:\n");
1216 idlen = ASN1_STRING_length(scid);
1217 id = (char *)ASN1_STRING_data(scid);
1218 BIO_dump_indent(out, id, idlen, 4);
1219 BIO_puts(out, " Receipts From");
1220 if (rlist)
1221 {
1222 BIO_puts(out, " List:\n");
1223 gnames_stack_print(out, rlist);
1224 }
1225 else if (allorfirst == 1)
1226 BIO_puts(out, ": First Tier\n");
1227 else if (allorfirst == 0)
1228 BIO_puts(out, ": All\n");
1229 else
1230 BIO_printf(out, " Unknown (%d)\n", allorfirst);
1231 BIO_puts(out, " Receipts To:\n");
1232 gnames_stack_print(out, rto);
1233 }
1234 if (rr)
1235 CMS_ReceiptRequest_free(rr);
1236 }
1237 }
1238
f5e2354c
DSH
1239static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK *ns)
1240 {
1241 int i;
1242 STACK_OF(GENERAL_NAMES) *ret;
1243 GENERAL_NAMES *gens = NULL;
1244 GENERAL_NAME *gen = NULL;
1245 ret = sk_GENERAL_NAMES_new_null();
1246 if (!ret)
1247 goto err;
1248 for (i = 0; i < sk_num(ns); i++)
1249 {
1250 char *str = sk_value(ns, i);
1251 gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
1252 if (!gen)
1253 goto err;
1254 gens = GENERAL_NAMES_new();
1255 if (!gens)
1256 goto err;
1257 if (!sk_GENERAL_NAME_push(gens, gen))
1258 goto err;
1259 gen = NULL;
1260 if (!sk_GENERAL_NAMES_push(ret, gens))
1261 goto err;
1262 gens = NULL;
1263 }
1264
1265 return ret;
1266
1267 err:
1268 if (ret)
1269 sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free);
1270 if (gens)
1271 GENERAL_NAMES_free(gens);
1272 if (gen)
1273 GENERAL_NAME_free(gen);
1274 return NULL;
1275 }
1276
1277
1278static CMS_ReceiptRequest *make_receipt_request(STACK *rr_to, int rr_allorfirst,
1279 STACK *rr_from)
1280 {
1281 STACK_OF(GENERAL_NAMES) *rct_to, *rct_from;
1282 CMS_ReceiptRequest *rr;
1283 rct_to = make_names_stack(rr_to);
1284 if (!rct_to)
1285 goto err;
1286 if (rr_from)
1287 {
1288 rct_from = make_names_stack(rr_from);
1289 if (!rct_from)
1290 goto err;
1291 }
1292 else
1293 rct_from = NULL;
1294 rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
1295 rct_to);
1296 return rr;
1297 err:
1298 return NULL;
1299 }
1300
8931b30d 1301#endif