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