smime.c revision 296465
1/* smime.c */ 2/* 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4 * project. 5 */ 6/* ==================================================================== 7 * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. All advertising materials mentioning features or use of this 22 * software must display the following acknowledgment: 23 * "This product includes software developed by the OpenSSL Project 24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25 * 26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27 * endorse or promote products derived from this software without 28 * prior written permission. For written permission, please contact 29 * licensing@OpenSSL.org. 30 * 31 * 5. Products derived from this software may not be called "OpenSSL" 32 * nor may "OpenSSL" appear in their names without prior written 33 * permission of the OpenSSL Project. 34 * 35 * 6. Redistributions of any form whatsoever must retain the following 36 * acknowledgment: 37 * "This product includes software developed by the OpenSSL Project 38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51 * OF THE POSSIBILITY OF SUCH DAMAGE. 52 * ==================================================================== 53 * 54 * This product includes cryptographic software written by Eric Young 55 * (eay@cryptsoft.com). This product includes software written by Tim 56 * Hudson (tjh@cryptsoft.com). 57 * 58 */ 59 60/* S/MIME utility function */ 61 62#include <stdio.h> 63#include <string.h> 64#include "apps.h" 65#include <openssl/crypto.h> 66#include <openssl/pem.h> 67#include <openssl/err.h> 68#include <openssl/x509_vfy.h> 69#include <openssl/x509v3.h> 70 71#undef PROG 72#define PROG smime_main 73static int save_certs(char *signerfile, STACK_OF(X509) *signers); 74static int smime_cb(int ok, X509_STORE_CTX *ctx); 75 76#define SMIME_OP 0x10 77#define SMIME_ENCRYPT (1 | SMIME_OP) 78#define SMIME_DECRYPT 2 79#define SMIME_SIGN (3 | SMIME_OP) 80#define SMIME_VERIFY 4 81#define SMIME_PK7OUT 5 82 83int MAIN(int, char **); 84 85int MAIN(int argc, char **argv) 86{ 87 ENGINE *e = NULL; 88 int operation = 0; 89 int ret = 0; 90 char **args; 91 const char *inmode = "r", *outmode = "w"; 92 char *infile = NULL, *outfile = NULL; 93 char *signerfile = NULL, *recipfile = NULL; 94 char *certfile = NULL, *keyfile = NULL, *contfile = NULL; 95 const EVP_CIPHER *cipher = NULL; 96 PKCS7 *p7 = NULL; 97 X509_STORE *store = NULL; 98 X509 *cert = NULL, *recip = NULL, *signer = NULL; 99 EVP_PKEY *key = NULL; 100 STACK_OF(X509) *encerts = NULL, *other = NULL; 101 BIO *in = NULL, *out = NULL, *indata = NULL; 102 int badarg = 0; 103 int flags = PKCS7_DETACHED; 104 char *to = NULL, *from = NULL, *subject = NULL; 105 char *CAfile = NULL, *CApath = NULL; 106 char *passargin = NULL, *passin = NULL; 107 char *inrand = NULL; 108 int need_rand = 0; 109 int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; 110 int keyform = FORMAT_PEM; 111#ifndef OPENSSL_NO_ENGINE 112 char *engine = NULL; 113#endif 114 115 X509_VERIFY_PARAM *vpm = NULL; 116 117 args = argv + 1; 118 ret = 1; 119 120 apps_startup(); 121 122 if (bio_err == NULL) { 123 if ((bio_err = BIO_new(BIO_s_file())) != NULL) 124 BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 125 } 126 127 if (!load_config(bio_err, NULL)) 128 goto end; 129 130 while (!badarg && *args && *args[0] == '-') { 131 if (!strcmp(*args, "-encrypt")) 132 operation = SMIME_ENCRYPT; 133 else if (!strcmp(*args, "-decrypt")) 134 operation = SMIME_DECRYPT; 135 else if (!strcmp(*args, "-sign")) 136 operation = SMIME_SIGN; 137 else if (!strcmp(*args, "-verify")) 138 operation = SMIME_VERIFY; 139 else if (!strcmp(*args, "-pk7out")) 140 operation = SMIME_PK7OUT; 141#ifndef OPENSSL_NO_DES 142 else if (!strcmp(*args, "-des3")) 143 cipher = EVP_des_ede3_cbc(); 144 else if (!strcmp(*args, "-des")) 145 cipher = EVP_des_cbc(); 146#endif 147#ifndef OPENSSL_NO_SEED 148 else if (!strcmp(*args, "-seed")) 149 cipher = EVP_seed_cbc(); 150#endif 151#ifndef OPENSSL_NO_RC2 152 else if (!strcmp(*args, "-rc2-40")) 153 cipher = EVP_rc2_40_cbc(); 154 else if (!strcmp(*args, "-rc2-128")) 155 cipher = EVP_rc2_cbc(); 156 else if (!strcmp(*args, "-rc2-64")) 157 cipher = EVP_rc2_64_cbc(); 158#endif 159#ifndef OPENSSL_NO_AES 160 else if (!strcmp(*args, "-aes128")) 161 cipher = EVP_aes_128_cbc(); 162 else if (!strcmp(*args, "-aes192")) 163 cipher = EVP_aes_192_cbc(); 164 else if (!strcmp(*args, "-aes256")) 165 cipher = EVP_aes_256_cbc(); 166#endif 167#ifndef OPENSSL_NO_CAMELLIA 168 else if (!strcmp(*args, "-camellia128")) 169 cipher = EVP_camellia_128_cbc(); 170 else if (!strcmp(*args, "-camellia192")) 171 cipher = EVP_camellia_192_cbc(); 172 else if (!strcmp(*args, "-camellia256")) 173 cipher = EVP_camellia_256_cbc(); 174#endif 175 else if (!strcmp(*args, "-text")) 176 flags |= PKCS7_TEXT; 177 else if (!strcmp(*args, "-nointern")) 178 flags |= PKCS7_NOINTERN; 179 else if (!strcmp(*args, "-noverify")) 180 flags |= PKCS7_NOVERIFY; 181 else if (!strcmp(*args, "-nochain")) 182 flags |= PKCS7_NOCHAIN; 183 else if (!strcmp(*args, "-nocerts")) 184 flags |= PKCS7_NOCERTS; 185 else if (!strcmp(*args, "-noattr")) 186 flags |= PKCS7_NOATTR; 187 else if (!strcmp(*args, "-nodetach")) 188 flags &= ~PKCS7_DETACHED; 189 else if (!strcmp(*args, "-nosmimecap")) 190 flags |= PKCS7_NOSMIMECAP; 191 else if (!strcmp(*args, "-binary")) 192 flags |= PKCS7_BINARY; 193 else if (!strcmp(*args, "-nosigs")) 194 flags |= PKCS7_NOSIGS; 195 else if (!strcmp(*args, "-nooldmime")) 196 flags |= PKCS7_NOOLDMIMETYPE; 197 else if (!strcmp(*args, "-crlfeol")) 198 flags |= PKCS7_CRLFEOL; 199 else if (!strcmp(*args, "-rand")) { 200 if (args[1]) { 201 args++; 202 inrand = *args; 203 } else 204 badarg = 1; 205 need_rand = 1; 206 } 207#ifndef OPENSSL_NO_ENGINE 208 else if (!strcmp(*args, "-engine")) { 209 if (args[1]) { 210 args++; 211 engine = *args; 212 } else 213 badarg = 1; 214 } 215#endif 216 else if (!strcmp(*args, "-passin")) { 217 if (args[1]) { 218 args++; 219 passargin = *args; 220 } else 221 badarg = 1; 222 } else if (!strcmp(*args, "-to")) { 223 if (args[1]) { 224 args++; 225 to = *args; 226 } else 227 badarg = 1; 228 } else if (!strcmp(*args, "-from")) { 229 if (args[1]) { 230 args++; 231 from = *args; 232 } else 233 badarg = 1; 234 } else if (!strcmp(*args, "-subject")) { 235 if (args[1]) { 236 args++; 237 subject = *args; 238 } else 239 badarg = 1; 240 } else if (!strcmp(*args, "-signer")) { 241 if (args[1]) { 242 args++; 243 signerfile = *args; 244 } else 245 badarg = 1; 246 } else if (!strcmp(*args, "-recip")) { 247 if (args[1]) { 248 args++; 249 recipfile = *args; 250 } else 251 badarg = 1; 252 } else if (!strcmp(*args, "-inkey")) { 253 if (args[1]) { 254 args++; 255 keyfile = *args; 256 } else 257 badarg = 1; 258 } else if (!strcmp(*args, "-keyform")) { 259 if (args[1]) { 260 args++; 261 keyform = str2fmt(*args); 262 } else 263 badarg = 1; 264 } else if (!strcmp(*args, "-certfile")) { 265 if (args[1]) { 266 args++; 267 certfile = *args; 268 } else 269 badarg = 1; 270 } else if (!strcmp(*args, "-CAfile")) { 271 if (args[1]) { 272 args++; 273 CAfile = *args; 274 } else 275 badarg = 1; 276 } else if (!strcmp(*args, "-CApath")) { 277 if (args[1]) { 278 args++; 279 CApath = *args; 280 } else 281 badarg = 1; 282 } else if (!strcmp(*args, "-in")) { 283 if (args[1]) { 284 args++; 285 infile = *args; 286 } else 287 badarg = 1; 288 } else if (!strcmp(*args, "-inform")) { 289 if (args[1]) { 290 args++; 291 informat = str2fmt(*args); 292 } else 293 badarg = 1; 294 } else if (!strcmp(*args, "-outform")) { 295 if (args[1]) { 296 args++; 297 outformat = str2fmt(*args); 298 } else 299 badarg = 1; 300 } else if (!strcmp(*args, "-out")) { 301 if (args[1]) { 302 args++; 303 outfile = *args; 304 } else 305 badarg = 1; 306 } else if (!strcmp(*args, "-content")) { 307 if (args[1]) { 308 args++; 309 contfile = *args; 310 } else 311 badarg = 1; 312 } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) 313 continue; 314 else 315 badarg = 1; 316 args++; 317 } 318 319 if (operation == SMIME_SIGN) { 320 if (!signerfile) { 321 BIO_printf(bio_err, "No signer certificate specified\n"); 322 badarg = 1; 323 } 324 need_rand = 1; 325 } else if (operation == SMIME_DECRYPT) { 326 if (!recipfile && !keyfile) { 327 BIO_printf(bio_err, 328 "No recipient certificate or key specified\n"); 329 badarg = 1; 330 } 331 } else if (operation == SMIME_ENCRYPT) { 332 if (!*args) { 333 BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); 334 badarg = 1; 335 } 336 need_rand = 1; 337 } else if (!operation) 338 badarg = 1; 339 340 if (badarg) { 341 BIO_printf(bio_err, "Usage smime [options] cert.pem ...\n"); 342 BIO_printf(bio_err, "where options are\n"); 343 BIO_printf(bio_err, "-encrypt encrypt message\n"); 344 BIO_printf(bio_err, "-decrypt decrypt encrypted message\n"); 345 BIO_printf(bio_err, "-sign sign message\n"); 346 BIO_printf(bio_err, "-verify verify signed message\n"); 347 BIO_printf(bio_err, "-pk7out output PKCS#7 structure\n"); 348#ifndef OPENSSL_NO_DES 349 BIO_printf(bio_err, "-des3 encrypt with triple DES\n"); 350 BIO_printf(bio_err, "-des encrypt with DES\n"); 351#endif 352#ifndef OPENSSL_NO_SEED 353 BIO_printf(bio_err, "-seed encrypt with SEED\n"); 354#endif 355#ifndef OPENSSL_NO_RC2 356 BIO_printf(bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); 357 BIO_printf(bio_err, "-rc2-64 encrypt with RC2-64\n"); 358 BIO_printf(bio_err, "-rc2-128 encrypt with RC2-128\n"); 359#endif 360#ifndef OPENSSL_NO_AES 361 BIO_printf(bio_err, "-aes128, -aes192, -aes256\n"); 362 BIO_printf(bio_err, 363 " encrypt PEM output with cbc aes\n"); 364#endif 365#ifndef OPENSSL_NO_CAMELLIA 366 BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n"); 367 BIO_printf(bio_err, 368 " encrypt PEM output with cbc camellia\n"); 369#endif 370 BIO_printf(bio_err, 371 "-nointern don't search certificates in message for signer\n"); 372 BIO_printf(bio_err, 373 "-nosigs don't verify message signature\n"); 374 BIO_printf(bio_err, 375 "-noverify don't verify signers certificate\n"); 376 BIO_printf(bio_err, 377 "-nocerts don't include signers certificate when signing\n"); 378 BIO_printf(bio_err, "-nodetach use opaque signing\n"); 379 BIO_printf(bio_err, 380 "-noattr don't include any signed attributes\n"); 381 BIO_printf(bio_err, 382 "-binary don't translate message to text\n"); 383 BIO_printf(bio_err, "-certfile file other certificates file\n"); 384 BIO_printf(bio_err, "-signer file signer certificate file\n"); 385 BIO_printf(bio_err, 386 "-recip file recipient certificate file for decryption\n"); 387 BIO_printf(bio_err, "-in file input file\n"); 388 BIO_printf(bio_err, 389 "-inform arg input format SMIME (default), PEM or DER\n"); 390 BIO_printf(bio_err, 391 "-inkey file input private key (if not signer or recipient)\n"); 392 BIO_printf(bio_err, 393 "-keyform arg input private key format (PEM or ENGINE)\n"); 394 BIO_printf(bio_err, "-out file output file\n"); 395 BIO_printf(bio_err, 396 "-outform arg output format SMIME (default), PEM or DER\n"); 397 BIO_printf(bio_err, 398 "-content file supply or override content for detached signature\n"); 399 BIO_printf(bio_err, "-to addr to address\n"); 400 BIO_printf(bio_err, "-from ad from address\n"); 401 BIO_printf(bio_err, "-subject s subject\n"); 402 BIO_printf(bio_err, 403 "-text include or delete text MIME headers\n"); 404 BIO_printf(bio_err, 405 "-CApath dir trusted certificates directory\n"); 406 BIO_printf(bio_err, "-CAfile file trusted certificates file\n"); 407 BIO_printf(bio_err, 408 "-crl_check check revocation status of signer's certificate using CRLs\n"); 409 BIO_printf(bio_err, 410 "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); 411#ifndef OPENSSL_NO_ENGINE 412 BIO_printf(bio_err, 413 "-engine e use engine e, possibly a hardware device.\n"); 414#endif 415 BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); 416 BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, 417 LIST_SEPARATOR_CHAR); 418 BIO_printf(bio_err, 419 " load the file (or the files in the directory) into\n"); 420 BIO_printf(bio_err, " the random number generator\n"); 421 BIO_printf(bio_err, 422 "cert.pem recipient certificate(s) for encryption\n"); 423 goto end; 424 } 425#ifndef OPENSSL_NO_ENGINE 426 e = setup_engine(bio_err, engine, 0); 427#endif 428 429 if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { 430 BIO_printf(bio_err, "Error getting password\n"); 431 goto end; 432 } 433 434 if (need_rand) { 435 app_RAND_load_file(NULL, bio_err, (inrand != NULL)); 436 if (inrand != NULL) 437 BIO_printf(bio_err, "%ld semi-random bytes loaded\n", 438 app_RAND_load_files(inrand)); 439 } 440 441 ret = 2; 442 443 if (operation != SMIME_SIGN) 444 flags &= ~PKCS7_DETACHED; 445 446 if (operation & SMIME_OP) { 447 if (flags & PKCS7_BINARY) 448 inmode = "rb"; 449 if (outformat == FORMAT_ASN1) 450 outmode = "wb"; 451 } else { 452 if (flags & PKCS7_BINARY) 453 outmode = "wb"; 454 if (informat == FORMAT_ASN1) 455 inmode = "rb"; 456 } 457 458 if (operation == SMIME_ENCRYPT) { 459 if (!cipher) { 460#ifndef OPENSSL_NO_DES 461 cipher = EVP_des_ede3_cbc(); 462#else 463 BIO_printf(bio_err, "No cipher selected\n"); 464 goto end; 465#endif 466 } 467 encerts = sk_X509_new_null(); 468 while (*args) { 469 if (!(cert = load_cert(bio_err, *args, FORMAT_PEM, 470 NULL, e, "recipient certificate file"))) { 471#if 0 /* An appropriate message is already printed */ 472 BIO_printf(bio_err, 473 "Can't read recipient certificate file %s\n", 474 *args); 475#endif 476 goto end; 477 } 478 sk_X509_push(encerts, cert); 479 cert = NULL; 480 args++; 481 } 482 } 483 484 if (signerfile && (operation == SMIME_SIGN)) { 485 if (!(signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL, 486 e, "signer certificate"))) { 487#if 0 /* An appropri message has already been 488 * printed */ 489 BIO_printf(bio_err, "Can't read signer certificate file %s\n", 490 signerfile); 491#endif 492 goto end; 493 } 494 } 495 496 if (certfile) { 497 if (!(other = load_certs(bio_err, certfile, FORMAT_PEM, NULL, 498 e, "certificate file"))) { 499#if 0 /* An appropriate message has already been 500 * printed */ 501 BIO_printf(bio_err, "Can't read certificate file %s\n", certfile); 502#endif 503 ERR_print_errors(bio_err); 504 goto end; 505 } 506 } 507 508 if (recipfile && (operation == SMIME_DECRYPT)) { 509 if (!(recip = load_cert(bio_err, recipfile, FORMAT_PEM, NULL, 510 e, "recipient certificate file"))) { 511#if 0 /* An appropriate message has alrady been 512 * printed */ 513 BIO_printf(bio_err, "Can't read recipient certificate file %s\n", 514 recipfile); 515#endif 516 ERR_print_errors(bio_err); 517 goto end; 518 } 519 } 520 521 if (operation == SMIME_DECRYPT) { 522 if (!keyfile) 523 keyfile = recipfile; 524 } else if (operation == SMIME_SIGN) { 525 if (!keyfile) 526 keyfile = signerfile; 527 } else 528 keyfile = NULL; 529 530 if (keyfile) { 531 key = load_key(bio_err, keyfile, keyform, 0, passin, e, 532 "signing key file"); 533 if (!key) 534 goto end; 535 } 536 537 if (infile) { 538 if (!(in = BIO_new_file(infile, inmode))) { 539 BIO_printf(bio_err, "Can't open input file %s\n", infile); 540 goto end; 541 } 542 } else 543 in = BIO_new_fp(stdin, BIO_NOCLOSE); 544 545 if (outfile) { 546 if (!(out = BIO_new_file(outfile, outmode))) { 547 BIO_printf(bio_err, "Can't open output file %s\n", outfile); 548 goto end; 549 } 550 } else { 551 out = BIO_new_fp(stdout, BIO_NOCLOSE); 552#ifdef OPENSSL_SYS_VMS 553 { 554 BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 555 out = BIO_push(tmpbio, out); 556 } 557#endif 558 } 559 560 if (operation == SMIME_VERIFY) { 561 if (!(store = setup_verify(bio_err, CAfile, CApath))) 562 goto end; 563 X509_STORE_set_verify_cb_func(store, smime_cb); 564 if (vpm) 565 X509_STORE_set1_param(store, vpm); 566 } 567 568 ret = 3; 569 570 if (operation == SMIME_ENCRYPT) 571 p7 = PKCS7_encrypt(encerts, in, cipher, flags); 572 else if (operation == SMIME_SIGN) { 573 /* 574 * If detached data and SMIME output enable partial signing. 575 */ 576 if ((flags & PKCS7_DETACHED) && (outformat == FORMAT_SMIME)) 577 flags |= PKCS7_STREAM; 578 p7 = PKCS7_sign(signer, key, other, in, flags); 579 } else { 580 if (informat == FORMAT_SMIME) 581 p7 = SMIME_read_PKCS7(in, &indata); 582 else if (informat == FORMAT_PEM) 583 p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); 584 else if (informat == FORMAT_ASN1) 585 p7 = d2i_PKCS7_bio(in, NULL); 586 else { 587 BIO_printf(bio_err, "Bad input format for PKCS#7 file\n"); 588 goto end; 589 } 590 591 if (!p7) { 592 BIO_printf(bio_err, "Error reading S/MIME message\n"); 593 goto end; 594 } 595 if (contfile) { 596 BIO_free(indata); 597 if (!(indata = BIO_new_file(contfile, "rb"))) { 598 BIO_printf(bio_err, "Can't read content file %s\n", contfile); 599 goto end; 600 } 601 } 602 } 603 604 if (!p7) { 605 BIO_printf(bio_err, "Error creating PKCS#7 structure\n"); 606 goto end; 607 } 608 609 ret = 4; 610 if (operation == SMIME_DECRYPT) { 611 if (!PKCS7_decrypt(p7, key, recip, out, flags)) { 612 BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n"); 613 goto end; 614 } 615 } else if (operation == SMIME_VERIFY) { 616 STACK_OF(X509) *signers; 617 if (PKCS7_verify(p7, other, store, indata, out, flags)) 618 BIO_printf(bio_err, "Verification successful\n"); 619 else { 620 BIO_printf(bio_err, "Verification failure\n"); 621 goto end; 622 } 623 signers = PKCS7_get0_signers(p7, other, flags); 624 if (!save_certs(signerfile, signers)) { 625 BIO_printf(bio_err, "Error writing signers to %s\n", signerfile); 626 ret = 5; 627 goto end; 628 } 629 sk_X509_free(signers); 630 } else if (operation == SMIME_PK7OUT) 631 PEM_write_bio_PKCS7(out, p7); 632 else { 633 if (to) 634 BIO_printf(out, "To: %s\n", to); 635 if (from) 636 BIO_printf(out, "From: %s\n", from); 637 if (subject) 638 BIO_printf(out, "Subject: %s\n", subject); 639 if (outformat == FORMAT_SMIME) 640 SMIME_write_PKCS7(out, p7, in, flags); 641 else if (outformat == FORMAT_PEM) 642 PEM_write_bio_PKCS7(out, p7); 643 else if (outformat == FORMAT_ASN1) 644 i2d_PKCS7_bio(out, p7); 645 else { 646 BIO_printf(bio_err, "Bad output format for PKCS#7 file\n"); 647 goto end; 648 } 649 } 650 ret = 0; 651 end: 652 if (need_rand) 653 app_RAND_write_file(NULL, bio_err); 654 if (ret) 655 ERR_print_errors(bio_err); 656 sk_X509_pop_free(encerts, X509_free); 657 sk_X509_pop_free(other, X509_free); 658 if (vpm) 659 X509_VERIFY_PARAM_free(vpm); 660 X509_STORE_free(store); 661 X509_free(cert); 662 X509_free(recip); 663 X509_free(signer); 664 EVP_PKEY_free(key); 665 PKCS7_free(p7); 666 BIO_free(in); 667 BIO_free(indata); 668 BIO_free_all(out); 669 if (passin) 670 OPENSSL_free(passin); 671 return (ret); 672} 673 674static int save_certs(char *signerfile, STACK_OF(X509) *signers) 675{ 676 int i; 677 BIO *tmp; 678 if (!signerfile) 679 return 1; 680 tmp = BIO_new_file(signerfile, "w"); 681 if (!tmp) 682 return 0; 683 for (i = 0; i < sk_X509_num(signers); i++) 684 PEM_write_bio_X509(tmp, sk_X509_value(signers, i)); 685 BIO_free(tmp); 686 return 1; 687} 688 689/* Minimal callback just to output policy info (if any) */ 690 691static int smime_cb(int ok, X509_STORE_CTX *ctx) 692{ 693 int error; 694 695 error = X509_STORE_CTX_get_error(ctx); 696 697 if ((error != X509_V_ERR_NO_EXPLICIT_POLICY) 698 && ((error != X509_V_OK) || (ok != 2))) 699 return ok; 700 701 policies_print(NULL, ctx); 702 703 return ok; 704 705} 706