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