1 /* $OpenBSD: cms.c,v 1.30 2022/03/23 15:16:59 tb Exp $ */ 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * project. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 */ 53 54 /* CMS utility function */ 55 56 #include <stdio.h> 57 #include <string.h> 58 59 #include "apps.h" 60 61 #ifndef OPENSSL_NO_CMS 62 63 #include <openssl/crypto.h> 64 #include <openssl/err.h> 65 #include <openssl/pem.h> 66 #include <openssl/x509_vfy.h> 67 #include <openssl/x509v3.h> 68 69 #include <openssl/cms.h> 70 71 static int save_certs(char *signerfile, STACK_OF(X509) *signers); 72 static 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 (single_execution) { 1169 if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { 1170 perror("pledge"); 1171 exit(1); 1172 } 1173 } 1174 1175 memset(&cms_config, 0, sizeof(cms_config)); 1176 cms_config.flags = CMS_DETACHED; 1177 cms_config.rr_allorfirst = -1; 1178 cms_config.informat = FORMAT_SMIME; 1179 cms_config.outformat = FORMAT_SMIME; 1180 cms_config.rctformat = FORMAT_SMIME; 1181 cms_config.keyform = FORMAT_PEM; 1182 if (options_parse(argc, argv, cms_options, NULL, &argsused) != 0) { 1183 goto argerr; 1184 } 1185 args = argv + argsused; 1186 ret = 1; 1187 1188 if (((cms_config.rr_allorfirst != -1) || cms_config.rr_from != NULL) && 1189 cms_config.rr_to == NULL) { 1190 BIO_puts(bio_err, "No Signed Receipts Recipients\n"); 1191 goto argerr; 1192 } 1193 if (!(cms_config.operation & SMIME_SIGNERS) && 1194 (cms_config.rr_to != NULL || cms_config.rr_from != NULL)) { 1195 BIO_puts(bio_err, "Signed receipts only allowed with -sign\n"); 1196 goto argerr; 1197 } 1198 if (!(cms_config.operation & SMIME_SIGNERS) && 1199 (cms_config.skkeys != NULL || cms_config.sksigners != NULL)) { 1200 BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); 1201 goto argerr; 1202 } 1203 if (cms_config.operation & SMIME_SIGNERS) { 1204 if (cms_config.keyfile != NULL && 1205 cms_config.signerfile == NULL) { 1206 BIO_puts(bio_err, "Illegal -inkey without -signer\n"); 1207 goto argerr; 1208 } 1209 /* Check to see if any final signer needs to be appended */ 1210 if (cms_config.signerfile != NULL) { 1211 if (cms_config.sksigners == NULL && 1212 (cms_config.sksigners = 1213 sk_OPENSSL_STRING_new_null()) == NULL) 1214 goto end; 1215 if (!sk_OPENSSL_STRING_push(cms_config.sksigners, 1216 cms_config.signerfile)) 1217 goto end; 1218 if (cms_config.skkeys == NULL && 1219 (cms_config.skkeys = 1220 sk_OPENSSL_STRING_new_null()) == NULL) 1221 goto end; 1222 if (cms_config.keyfile == NULL) 1223 cms_config.keyfile = cms_config.signerfile; 1224 if (!sk_OPENSSL_STRING_push(cms_config.skkeys, 1225 cms_config.keyfile)) 1226 goto end; 1227 } 1228 if (cms_config.sksigners == NULL) { 1229 BIO_printf(bio_err, 1230 "No signer certificate specified\n"); 1231 badarg = 1; 1232 } 1233 cms_config.signerfile = NULL; 1234 cms_config.keyfile = NULL; 1235 } else if (cms_config.operation == SMIME_DECRYPT) { 1236 if (cms_config.recipfile == NULL && 1237 cms_config.keyfile == NULL && 1238 cms_config.secret_key == NULL && 1239 cms_config.pwri_pass == NULL) { 1240 BIO_printf(bio_err, 1241 "No recipient certificate or key specified\n"); 1242 badarg = 1; 1243 } 1244 } else if (cms_config.operation == SMIME_ENCRYPT) { 1245 if (*args == NULL && cms_config.secret_key == NULL && 1246 cms_config.pwri_pass == NULL && 1247 cms_config.encerts == NULL) { 1248 BIO_printf(bio_err, 1249 "No recipient(s) certificate(s) specified\n"); 1250 badarg = 1; 1251 } 1252 } else if (!cms_config.operation) { 1253 badarg = 1; 1254 } 1255 1256 if (badarg) { 1257 argerr: 1258 cms_usage(); 1259 goto end; 1260 } 1261 1262 if (!app_passwd(bio_err, cms_config.passargin, NULL, &passin, NULL)) { 1263 BIO_printf(bio_err, "Error getting password\n"); 1264 goto end; 1265 } 1266 ret = 2; 1267 1268 if (!(cms_config.operation & SMIME_SIGNERS)) 1269 cms_config.flags &= ~CMS_DETACHED; 1270 1271 if (cms_config.operation & SMIME_OP) { 1272 if (cms_config.outformat == FORMAT_ASN1) 1273 outmode = "wb"; 1274 } else { 1275 if (cms_config.flags & CMS_BINARY) 1276 outmode = "wb"; 1277 } 1278 1279 if (cms_config.operation & SMIME_IP) { 1280 if (cms_config.informat == FORMAT_ASN1) 1281 inmode = "rb"; 1282 } else { 1283 if (cms_config.flags & CMS_BINARY) 1284 inmode = "rb"; 1285 } 1286 1287 if (cms_config.operation == SMIME_ENCRYPT) { 1288 if (cms_config.cipher == NULL) { 1289 #ifndef OPENSSL_NO_DES 1290 cms_config.cipher = EVP_des_ede3_cbc(); 1291 #else 1292 BIO_printf(bio_err, "No cipher selected\n"); 1293 goto end; 1294 #endif 1295 } 1296 if (cms_config.secret_key != NULL && 1297 cms_config.secret_keyid == NULL) { 1298 BIO_printf(bio_err, "No secret key id\n"); 1299 goto end; 1300 } 1301 if (*args != NULL && cms_config.encerts == NULL) 1302 if ((cms_config.encerts = sk_X509_new_null()) == NULL) 1303 goto end; 1304 while (*args) { 1305 if ((cms_config.cert = load_cert(bio_err, *args, 1306 FORMAT_PEM, NULL, 1307 "recipient certificate file")) == NULL) 1308 goto end; 1309 if (!sk_X509_push(cms_config.encerts, cms_config.cert)) 1310 goto end; 1311 cms_config.cert = NULL; 1312 args++; 1313 } 1314 } 1315 if (cms_config.certfile != NULL) { 1316 if ((other = load_certs(bio_err, cms_config.certfile, 1317 FORMAT_PEM, NULL, "certificate file")) == NULL) { 1318 ERR_print_errors(bio_err); 1319 goto end; 1320 } 1321 } 1322 if (cms_config.recipfile != NULL && 1323 (cms_config.operation == SMIME_DECRYPT)) { 1324 if ((recip = load_cert(bio_err, cms_config.recipfile, 1325 FORMAT_PEM, NULL, "recipient certificate file")) == NULL) { 1326 ERR_print_errors(bio_err); 1327 goto end; 1328 } 1329 } 1330 if (cms_config.operation == SMIME_SIGN_RECEIPT) { 1331 if ((signer = load_cert(bio_err, cms_config.signerfile, 1332 FORMAT_PEM, NULL, 1333 "receipt signer certificate file")) == NULL) { 1334 ERR_print_errors(bio_err); 1335 goto end; 1336 } 1337 } 1338 if (cms_config.operation == SMIME_DECRYPT) { 1339 if (cms_config.keyfile == NULL) 1340 cms_config.keyfile = cms_config.recipfile; 1341 } else if ((cms_config.operation == SMIME_SIGN) || 1342 (cms_config.operation == SMIME_SIGN_RECEIPT)) { 1343 if (cms_config.keyfile == NULL) 1344 cms_config.keyfile = cms_config.signerfile; 1345 } else { 1346 cms_config.keyfile = NULL; 1347 } 1348 1349 if (cms_config.keyfile != NULL) { 1350 key = load_key(bio_err, cms_config.keyfile, cms_config.keyform, 1351 0, passin, "signing key file"); 1352 if (key == NULL) 1353 goto end; 1354 } 1355 if (cms_config.infile != NULL) { 1356 if ((in = BIO_new_file(cms_config.infile, inmode)) == NULL) { 1357 BIO_printf(bio_err, 1358 "Can't open input file %s\n", cms_config.infile); 1359 goto end; 1360 } 1361 } else { 1362 if ((in = BIO_new_fp(stdin, BIO_NOCLOSE)) == NULL) 1363 goto end; 1364 } 1365 1366 if (cms_config.operation & SMIME_IP) { 1367 if (cms_config.informat == FORMAT_SMIME) 1368 cms = SMIME_read_CMS(in, &indata); 1369 else if (cms_config.informat == FORMAT_PEM) 1370 cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); 1371 else if (cms_config.informat == FORMAT_ASN1) 1372 cms = d2i_CMS_bio(in, NULL); 1373 else { 1374 BIO_printf(bio_err, "Bad input format for CMS file\n"); 1375 goto end; 1376 } 1377 1378 if (cms == NULL) { 1379 BIO_printf(bio_err, "Error reading S/MIME message\n"); 1380 goto end; 1381 } 1382 if (cms_config.contfile != NULL) { 1383 BIO_free(indata); 1384 if ((indata = BIO_new_file(cms_config.contfile, 1385 "rb")) == NULL) { 1386 BIO_printf(bio_err, 1387 "Can't read content file %s\n", 1388 cms_config.contfile); 1389 goto end; 1390 } 1391 } 1392 if (cms_config.certsoutfile != NULL) { 1393 STACK_OF(X509) *allcerts; 1394 if ((allcerts = CMS_get1_certs(cms)) == NULL) 1395 goto end; 1396 if (!save_certs(cms_config.certsoutfile, allcerts)) { 1397 BIO_printf(bio_err, 1398 "Error writing certs to %s\n", 1399 cms_config.certsoutfile); 1400 sk_X509_pop_free(allcerts, X509_free); 1401 ret = 5; 1402 goto end; 1403 } 1404 sk_X509_pop_free(allcerts, X509_free); 1405 } 1406 } 1407 if (cms_config.rctfile != NULL) { 1408 char *rctmode = (cms_config.rctformat == FORMAT_ASN1) ? 1409 "rb" : "r"; 1410 if ((rctin = BIO_new_file(cms_config.rctfile, rctmode)) == NULL) { 1411 BIO_printf(bio_err, 1412 "Can't open receipt file %s\n", cms_config.rctfile); 1413 goto end; 1414 } 1415 if (cms_config.rctformat == FORMAT_SMIME) 1416 rcms = SMIME_read_CMS(rctin, NULL); 1417 else if (cms_config.rctformat == FORMAT_PEM) 1418 rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); 1419 else if (cms_config.rctformat == FORMAT_ASN1) 1420 rcms = d2i_CMS_bio(rctin, NULL); 1421 else { 1422 BIO_printf(bio_err, "Bad input format for receipt\n"); 1423 goto end; 1424 } 1425 1426 if (rcms == NULL) { 1427 BIO_printf(bio_err, "Error reading receipt\n"); 1428 goto end; 1429 } 1430 } 1431 if (cms_config.outfile != NULL) { 1432 if ((out = BIO_new_file(cms_config.outfile, outmode)) == NULL) { 1433 BIO_printf(bio_err, 1434 "Can't open output file %s\n", cms_config.outfile); 1435 goto end; 1436 } 1437 } else { 1438 if ((out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL) 1439 goto end; 1440 } 1441 1442 if ((cms_config.operation == SMIME_VERIFY) || 1443 (cms_config.operation == SMIME_VERIFY_RECEIPT)) { 1444 if ((store = setup_verify(bio_err, cms_config.CAfile, 1445 cms_config.CApath)) == NULL) 1446 goto end; 1447 X509_STORE_set_verify_cb(store, cms_cb); 1448 if (cms_config.vpm != NULL) { 1449 if (!X509_STORE_set1_param(store, cms_config.vpm)) 1450 goto end; 1451 } 1452 } 1453 ret = 3; 1454 1455 if (cms_config.operation == SMIME_DATA_CREATE) { 1456 cms = CMS_data_create(in, cms_config.flags); 1457 } else if (cms_config.operation == SMIME_DIGEST_CREATE) { 1458 cms = CMS_digest_create(in, cms_config.sign_md, 1459 cms_config.flags); 1460 } else if (cms_config.operation == SMIME_COMPRESS) { 1461 cms = CMS_compress(in, -1, cms_config.flags); 1462 } else if (cms_config.operation == SMIME_ENCRYPT) { 1463 int i; 1464 cms_config.flags |= CMS_PARTIAL; 1465 cms = CMS_encrypt(NULL, in, cms_config.cipher, 1466 cms_config.flags); 1467 if (cms == NULL) 1468 goto end; 1469 for (i = 0; i < sk_X509_num(cms_config.encerts); i++) { 1470 CMS_RecipientInfo *ri; 1471 struct cms_key_param *kparam; 1472 int tflags = cms_config.flags; 1473 X509 *x; 1474 1475 if ((x = sk_X509_value(cms_config.encerts, i)) == NULL) 1476 goto end; 1477 for (kparam = cms_config.key_first; kparam != NULL; 1478 kparam = kparam->next) { 1479 if (kparam->idx == i) { 1480 tflags |= CMS_KEY_PARAM; 1481 break; 1482 } 1483 } 1484 ri = CMS_add1_recipient_cert(cms, x, tflags); 1485 if (ri == NULL) 1486 goto end; 1487 if (kparam != NULL) { 1488 EVP_PKEY_CTX *pctx; 1489 if ((pctx = CMS_RecipientInfo_get0_pkey_ctx( 1490 ri)) == NULL) 1491 goto end; 1492 if (!cms_set_pkey_param(pctx, kparam->param)) 1493 goto end; 1494 } 1495 } 1496 1497 if (cms_config.secret_key != NULL) { 1498 if (CMS_add0_recipient_key(cms, NID_undef, 1499 cms_config.secret_key, cms_config.secret_keylen, 1500 cms_config.secret_keyid, cms_config.secret_keyidlen, 1501 NULL, NULL, NULL) == NULL) 1502 goto end; 1503 /* NULL these because call absorbs them */ 1504 cms_config.secret_key = NULL; 1505 cms_config.secret_keyid = NULL; 1506 } 1507 if (cms_config.pwri_pass != NULL) { 1508 pwri_tmp = strdup(cms_config.pwri_pass); 1509 if (pwri_tmp == NULL) 1510 goto end; 1511 if (CMS_add0_recipient_password(cms, -1, NID_undef, 1512 NID_undef, pwri_tmp, -1, NULL) == NULL) 1513 goto end; 1514 pwri_tmp = NULL; 1515 } 1516 if (!(cms_config.flags & CMS_STREAM)) { 1517 if (!CMS_final(cms, in, NULL, cms_config.flags)) 1518 goto end; 1519 } 1520 } else if (cms_config.operation == SMIME_ENCRYPTED_ENCRYPT) { 1521 cms = CMS_EncryptedData_encrypt(in, cms_config.cipher, 1522 cms_config.secret_key, cms_config.secret_keylen, 1523 cms_config.flags); 1524 1525 } else if (cms_config.operation == SMIME_SIGN_RECEIPT) { 1526 CMS_ContentInfo *srcms = NULL; 1527 STACK_OF(CMS_SignerInfo) *sis; 1528 CMS_SignerInfo *si; 1529 sis = CMS_get0_SignerInfos(cms); 1530 if (sis == NULL) 1531 goto end; 1532 si = sk_CMS_SignerInfo_value(sis, 0); 1533 if (si == NULL) 1534 goto end; 1535 srcms = CMS_sign_receipt(si, signer, key, other, 1536 cms_config.flags); 1537 if (srcms == NULL) 1538 goto end; 1539 CMS_ContentInfo_free(cms); 1540 cms = srcms; 1541 } else if (cms_config.operation & SMIME_SIGNERS) { 1542 int i; 1543 /* 1544 * If detached data content we enable streaming if S/MIME 1545 * output format. 1546 */ 1547 if (cms_config.operation == SMIME_SIGN) { 1548 1549 if (cms_config.flags & CMS_DETACHED) { 1550 if (cms_config.outformat == FORMAT_SMIME) 1551 cms_config.flags |= CMS_STREAM; 1552 } 1553 cms_config.flags |= CMS_PARTIAL; 1554 cms = CMS_sign(NULL, NULL, other, in, cms_config.flags); 1555 if (cms == NULL) 1556 goto end; 1557 if (cms_config.econtent_type != NULL) 1558 if (!CMS_set1_eContentType(cms, 1559 cms_config.econtent_type)) 1560 goto end; 1561 1562 if (cms_config.rr_to != NULL) { 1563 rr = make_receipt_request(cms_config.rr_to, 1564 cms_config.rr_allorfirst, 1565 cms_config.rr_from); 1566 if (rr == NULL) { 1567 BIO_puts(bio_err, 1568 "Signed Receipt Request Creation Error\n"); 1569 goto end; 1570 } 1571 } 1572 } else { 1573 cms_config.flags |= CMS_REUSE_DIGEST; 1574 } 1575 1576 for (i = 0; i < sk_OPENSSL_STRING_num(cms_config.sksigners); i++) { 1577 CMS_SignerInfo *si; 1578 struct cms_key_param *kparam; 1579 int tflags = cms_config.flags; 1580 1581 cms_config.signerfile = sk_OPENSSL_STRING_value( 1582 cms_config.sksigners, i); 1583 cms_config.keyfile = sk_OPENSSL_STRING_value( 1584 cms_config.skkeys, i); 1585 1586 signer = load_cert(bio_err, cms_config.signerfile, 1587 FORMAT_PEM, NULL, "signer certificate"); 1588 if (signer == NULL) 1589 goto end; 1590 key = load_key(bio_err, cms_config.keyfile, 1591 cms_config.keyform, 0, passin, "signing key file"); 1592 if (key == NULL) 1593 goto end; 1594 for (kparam = cms_config.key_first; kparam != NULL; 1595 kparam = kparam->next) { 1596 if (kparam->idx == i) { 1597 tflags |= CMS_KEY_PARAM; 1598 break; 1599 } 1600 } 1601 si = CMS_add1_signer(cms, signer, key, 1602 cms_config.sign_md, tflags); 1603 if (si == NULL) 1604 goto end; 1605 if (kparam != NULL) { 1606 EVP_PKEY_CTX *pctx; 1607 if ((pctx = CMS_SignerInfo_get0_pkey_ctx( 1608 si)) == NULL) 1609 goto end; 1610 if (!cms_set_pkey_param(pctx, kparam->param)) 1611 goto end; 1612 } 1613 if (rr != NULL && !CMS_add1_ReceiptRequest(si, rr)) 1614 goto end; 1615 X509_free(signer); 1616 signer = NULL; 1617 EVP_PKEY_free(key); 1618 key = NULL; 1619 } 1620 /* If not streaming or resigning finalize structure */ 1621 if ((cms_config.operation == SMIME_SIGN) && 1622 !(cms_config.flags & CMS_STREAM)) { 1623 if (!CMS_final(cms, in, NULL, cms_config.flags)) 1624 goto end; 1625 } 1626 } 1627 if (cms == NULL) { 1628 BIO_printf(bio_err, "Error creating CMS structure\n"); 1629 goto end; 1630 } 1631 ret = 4; 1632 if (cms_config.operation == SMIME_DECRYPT) { 1633 if (cms_config.flags & CMS_DEBUG_DECRYPT) 1634 CMS_decrypt(cms, NULL, NULL, NULL, NULL, 1635 cms_config.flags); 1636 1637 if (cms_config.secret_key != NULL) { 1638 if (!CMS_decrypt_set1_key(cms, cms_config.secret_key, 1639 cms_config.secret_keylen, cms_config.secret_keyid, 1640 cms_config.secret_keyidlen)) { 1641 BIO_puts(bio_err, 1642 "Error decrypting CMS using secret key\n"); 1643 goto end; 1644 } 1645 } 1646 if (key != NULL) { 1647 if (!CMS_decrypt_set1_pkey(cms, key, recip)) { 1648 BIO_puts(bio_err, 1649 "Error decrypting CMS using private key\n"); 1650 goto end; 1651 } 1652 } 1653 if (cms_config.pwri_pass != NULL) { 1654 if (!CMS_decrypt_set1_password(cms, 1655 cms_config.pwri_pass, -1)) { 1656 BIO_puts(bio_err, 1657 "Error decrypting CMS using password\n"); 1658 goto end; 1659 } 1660 } 1661 if (!CMS_decrypt(cms, NULL, NULL, indata, out, 1662 cms_config.flags)) { 1663 BIO_printf(bio_err, "Error decrypting CMS structure\n"); 1664 goto end; 1665 } 1666 } else if (cms_config.operation == SMIME_DATAOUT) { 1667 if (!CMS_data(cms, out, cms_config.flags)) 1668 goto end; 1669 } else if (cms_config.operation == SMIME_UNCOMPRESS) { 1670 if (!CMS_uncompress(cms, indata, out, cms_config.flags)) 1671 goto end; 1672 } else if (cms_config.operation == SMIME_DIGEST_VERIFY) { 1673 if (CMS_digest_verify(cms, indata, out, cms_config.flags) > 0) 1674 BIO_printf(bio_err, "Verification successful\n"); 1675 else { 1676 BIO_printf(bio_err, "Verification failure\n"); 1677 goto end; 1678 } 1679 } else if (cms_config.operation == SMIME_ENCRYPTED_DECRYPT) { 1680 if (!CMS_EncryptedData_decrypt(cms, cms_config.secret_key, 1681 cms_config.secret_keylen, indata, out, cms_config.flags)) 1682 goto end; 1683 } else if (cms_config.operation == SMIME_VERIFY) { 1684 if (CMS_verify(cms, other, store, indata, out, 1685 cms_config.flags) > 0) { 1686 BIO_printf(bio_err, "Verification successful\n"); 1687 } else { 1688 BIO_printf(bio_err, "Verification failure\n"); 1689 if (cms_config.verify_retcode) 1690 ret = verify_err + 32; 1691 goto end; 1692 } 1693 if (cms_config.signerfile != NULL) { 1694 STACK_OF(X509) *signers; 1695 if ((signers = CMS_get0_signers(cms)) == NULL) 1696 goto end; 1697 if (!save_certs(cms_config.signerfile, signers)) { 1698 BIO_printf(bio_err, 1699 "Error writing signers to %s\n", 1700 cms_config.signerfile); 1701 sk_X509_free(signers); 1702 ret = 5; 1703 goto end; 1704 } 1705 sk_X509_free(signers); 1706 } 1707 if (cms_config.rr_print) 1708 receipt_request_print(bio_err, cms); 1709 1710 } else if (cms_config.operation == SMIME_VERIFY_RECEIPT) { 1711 if (CMS_verify_receipt(rcms, cms, other, store, 1712 cms_config.flags) > 0) { 1713 BIO_printf(bio_err, "Verification successful\n"); 1714 } else { 1715 BIO_printf(bio_err, "Verification failure\n"); 1716 goto end; 1717 } 1718 } else { 1719 if (cms_config.noout) { 1720 if (cms_config.print && 1721 !CMS_ContentInfo_print_ctx(out, cms, 0, NULL)) 1722 goto end; 1723 } else if (cms_config.outformat == FORMAT_SMIME) { 1724 if (cms_config.to != NULL) 1725 BIO_printf(out, "To: %s\n", cms_config.to); 1726 if (cms_config.from != NULL) 1727 BIO_printf(out, "From: %s\n", cms_config.from); 1728 if (cms_config.subject != NULL) 1729 BIO_printf(out, "Subject: %s\n", 1730 cms_config.subject); 1731 if (cms_config.operation == SMIME_RESIGN) 1732 ret = SMIME_write_CMS(out, cms, indata, 1733 cms_config.flags); 1734 else 1735 ret = SMIME_write_CMS(out, cms, in, 1736 cms_config.flags); 1737 } else if (cms_config.outformat == FORMAT_PEM) { 1738 ret = PEM_write_bio_CMS_stream(out, cms, in, 1739 cms_config.flags); 1740 } else if (cms_config.outformat == FORMAT_ASN1) { 1741 ret = i2d_CMS_bio_stream(out, cms, in, cms_config.flags); 1742 } else { 1743 BIO_printf(bio_err, "Bad output format for CMS file\n"); 1744 goto end; 1745 } 1746 if (ret <= 0) { 1747 ret = 6; 1748 goto end; 1749 } 1750 } 1751 ret = 0; 1752 1753 end: 1754 if (ret) 1755 ERR_print_errors(bio_err); 1756 1757 sk_X509_pop_free(cms_config.encerts, X509_free); 1758 sk_X509_pop_free(other, X509_free); 1759 X509_VERIFY_PARAM_free(cms_config.vpm); 1760 sk_OPENSSL_STRING_free(cms_config.sksigners); 1761 sk_OPENSSL_STRING_free(cms_config.skkeys); 1762 free(cms_config.secret_key); 1763 free(cms_config.secret_keyid); 1764 free(pwri_tmp); 1765 ASN1_OBJECT_free(cms_config.econtent_type); 1766 CMS_ReceiptRequest_free(rr); 1767 sk_OPENSSL_STRING_free(cms_config.rr_to); 1768 sk_OPENSSL_STRING_free(cms_config.rr_from); 1769 for (cms_config.key_param = cms_config.key_first; cms_config.key_param;) { 1770 struct cms_key_param *tparam; 1771 sk_OPENSSL_STRING_free(cms_config.key_param->param); 1772 tparam = cms_config.key_param->next; 1773 free(cms_config.key_param); 1774 cms_config.key_param = tparam; 1775 } 1776 X509_STORE_free(store); 1777 X509_free(cms_config.cert); 1778 X509_free(recip); 1779 X509_free(signer); 1780 EVP_PKEY_free(key); 1781 CMS_ContentInfo_free(cms); 1782 CMS_ContentInfo_free(rcms); 1783 BIO_free(rctin); 1784 BIO_free(in); 1785 BIO_free(indata); 1786 BIO_free_all(out); 1787 free(passin); 1788 1789 return (ret); 1790 } 1791 1792 static int 1793 save_certs(char *signerfile, STACK_OF(X509) *signers) 1794 { 1795 int i; 1796 BIO *tmp; 1797 1798 if (signerfile == NULL) 1799 return 1; 1800 tmp = BIO_new_file(signerfile, "w"); 1801 if (tmp == NULL) 1802 return 0; 1803 for (i = 0; i < sk_X509_num(signers); i++) 1804 PEM_write_bio_X509(tmp, sk_X509_value(signers, i)); 1805 BIO_free(tmp); 1806 return 1; 1807 } 1808 1809 /* Minimal callback just to output policy info (if any) */ 1810 1811 static int 1812 cms_cb(int ok, X509_STORE_CTX *ctx) 1813 { 1814 int error; 1815 1816 error = X509_STORE_CTX_get_error(ctx); 1817 1818 verify_err = error; 1819 1820 if ((error != X509_V_ERR_NO_EXPLICIT_POLICY) && 1821 ((error != X509_V_OK) || (ok != 2))) 1822 return ok; 1823 1824 policies_print(NULL, ctx); 1825 1826 return ok; 1827 } 1828 1829 static void 1830 gnames_stack_print(BIO *out, STACK_OF(GENERAL_NAMES) *gns) 1831 { 1832 STACK_OF(GENERAL_NAME) *gens; 1833 GENERAL_NAME *gen; 1834 int i, j; 1835 1836 for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++) { 1837 gens = sk_GENERAL_NAMES_value(gns, i); 1838 for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) { 1839 gen = sk_GENERAL_NAME_value(gens, j); 1840 BIO_puts(out, " "); 1841 GENERAL_NAME_print(out, gen); 1842 BIO_puts(out, "\n"); 1843 } 1844 } 1845 return; 1846 } 1847 1848 static void 1849 receipt_request_print(BIO *out, CMS_ContentInfo *cms) 1850 { 1851 STACK_OF(CMS_SignerInfo) *sis; 1852 CMS_SignerInfo *si; 1853 CMS_ReceiptRequest *rr; 1854 int allorfirst; 1855 STACK_OF(GENERAL_NAMES) *rto, *rlist; 1856 ASN1_STRING *scid; 1857 int i, rv; 1858 1859 if ((sis = CMS_get0_SignerInfos(cms)) == NULL) 1860 return; 1861 for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) { 1862 if ((si = sk_CMS_SignerInfo_value(sis, i)) == NULL) 1863 return; 1864 rv = CMS_get1_ReceiptRequest(si, &rr); 1865 BIO_printf(bio_err, "Signer %d:\n", i + 1); 1866 if (rv == 0) { 1867 BIO_puts(bio_err, " No Receipt Request\n"); 1868 } else if (rv < 0) { 1869 BIO_puts(bio_err, " Receipt Request Parse Error\n"); 1870 ERR_print_errors(bio_err); 1871 } else { 1872 char *id; 1873 int idlen; 1874 1875 CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst, 1876 &rlist, &rto); 1877 BIO_puts(out, " Signed Content ID:\n"); 1878 idlen = ASN1_STRING_length(scid); 1879 id = (char *) ASN1_STRING_data(scid); 1880 BIO_dump_indent(out, id, idlen, 4); 1881 BIO_puts(out, " Receipts From"); 1882 if (rlist != NULL) { 1883 BIO_puts(out, " List:\n"); 1884 gnames_stack_print(out, rlist); 1885 } else if (allorfirst == 1) { 1886 BIO_puts(out, ": First Tier\n"); 1887 } else if (allorfirst == 0) { 1888 BIO_puts(out, ": All\n"); 1889 } else { 1890 BIO_printf(out, " Unknown (%d)\n", allorfirst); 1891 } 1892 BIO_puts(out, " Receipts To:\n"); 1893 gnames_stack_print(out, rto); 1894 } 1895 CMS_ReceiptRequest_free(rr); 1896 } 1897 } 1898 1899 static STACK_OF(GENERAL_NAMES) * 1900 make_names_stack(STACK_OF(OPENSSL_STRING) *ns) 1901 { 1902 int i; 1903 STACK_OF(GENERAL_NAMES) *ret; 1904 GENERAL_NAMES *gens = NULL; 1905 GENERAL_NAME *gen = NULL; 1906 1907 if ((ret = sk_GENERAL_NAMES_new_null()) == NULL) 1908 goto err; 1909 for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) { 1910 char *str = sk_OPENSSL_STRING_value(ns, i); 1911 gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0); 1912 if (gen == NULL) 1913 goto err; 1914 gens = GENERAL_NAMES_new(); 1915 if (gens == NULL) 1916 goto err; 1917 if (!sk_GENERAL_NAME_push(gens, gen)) 1918 goto err; 1919 gen = NULL; 1920 if (!sk_GENERAL_NAMES_push(ret, gens)) 1921 goto err; 1922 gens = NULL; 1923 } 1924 1925 return ret; 1926 1927 err: 1928 sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free); 1929 GENERAL_NAMES_free(gens); 1930 GENERAL_NAME_free(gen); 1931 1932 return NULL; 1933 } 1934 1935 1936 static CMS_ReceiptRequest * 1937 make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst, 1938 STACK_OF(OPENSSL_STRING) *rr_from) 1939 { 1940 STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL; 1941 CMS_ReceiptRequest *rr; 1942 1943 rct_to = make_names_stack(rr_to); 1944 if (rct_to == NULL) 1945 goto err; 1946 if (rr_from != NULL) { 1947 rct_from = make_names_stack(rr_from); 1948 if (rct_from == NULL) 1949 goto err; 1950 } else { 1951 rct_from = NULL; 1952 } 1953 1954 if ((rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from, 1955 rct_to)) == NULL) 1956 goto err; 1957 1958 return rr; 1959 1960 err: 1961 sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free); 1962 sk_GENERAL_NAMES_pop_free(rct_from, GENERAL_NAMES_free); 1963 return NULL; 1964 } 1965 1966 static int 1967 cms_set_pkey_param(EVP_PKEY_CTX *pctx, STACK_OF(OPENSSL_STRING) *param) 1968 { 1969 char *keyopt; 1970 int i; 1971 1972 if (sk_OPENSSL_STRING_num(param) <= 0) 1973 return 1; 1974 for (i = 0; i < sk_OPENSSL_STRING_num(param); i++) { 1975 keyopt = sk_OPENSSL_STRING_value(param, i); 1976 if (pkey_ctrl_string(pctx, keyopt) <= 0) { 1977 BIO_printf(bio_err, "parameter error \"%s\"\n", keyopt); 1978 ERR_print_errors(bio_err); 1979 return 0; 1980 } 1981 } 1982 return 1; 1983 } 1984 1985 #endif 1986