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