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 * 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 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 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 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 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 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 313 cms_opt_print(void) 314 { 315 cfg.noout = 1; 316 cfg.print = 1; 317 return (0); 318 } 319 320 static int 321 cms_opt_pwri_pass(char *arg) 322 { 323 cfg.pwri_pass = (unsigned char *)arg; 324 return (0); 325 } 326 327 static int 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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