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