1 /* $OpenBSD: cms.c,v 1.2 2015/08/22 16:36:05 jsing 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/cms.h> 64 #include <openssl/crypto.h> 65 #include <openssl/err.h> 66 #include <openssl/pem.h> 67 #include <openssl/x509_vfy.h> 68 #include <openssl/x509v3.h> 69 70 static int save_certs(char *signerfile, STACK_OF(X509) * signers); 71 static int cms_cb(int ok, X509_STORE_CTX * ctx); 72 static void receipt_request_print(BIO * out, CMS_ContentInfo * cms); 73 static CMS_ReceiptRequest * make_receipt_request( 74 STACK_OF(OPENSSL_STRING) * rr_to, int rr_allorfirst, 75 STACK_OF(OPENSSL_STRING) * rr_from); 76 77 #define SMIME_OP 0x10 78 #define SMIME_IP 0x20 79 #define SMIME_SIGNERS 0x40 80 #define SMIME_ENCRYPT (1 | SMIME_OP) 81 #define SMIME_DECRYPT (2 | SMIME_IP) 82 #define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS) 83 #define SMIME_VERIFY (4 | SMIME_IP) 84 #define SMIME_CMSOUT (5 | SMIME_IP | SMIME_OP) 85 #define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS) 86 #define SMIME_DATAOUT (7 | SMIME_IP) 87 #define SMIME_DATA_CREATE (8 | SMIME_OP) 88 #define SMIME_DIGEST_VERIFY (9 | SMIME_IP) 89 #define SMIME_DIGEST_CREATE (10 | SMIME_OP) 90 #define SMIME_UNCOMPRESS (11 | SMIME_IP) 91 #define SMIME_COMPRESS (12 | SMIME_OP) 92 #define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP) 93 #define SMIME_ENCRYPTED_ENCRYPT (14 | SMIME_OP) 94 #define SMIME_SIGN_RECEIPT (15 | SMIME_IP | SMIME_OP) 95 #define SMIME_VERIFY_RECEIPT (16 | SMIME_IP) 96 97 int verify_err = 0; 98 99 int 100 cms_main(int argc, char **argv) 101 { 102 ENGINE *e = NULL; 103 int operation = 0; 104 int ret = 0; 105 char **args; 106 const char *inmode = "r", *outmode = "w"; 107 char *infile = NULL, *outfile = NULL, *rctfile = NULL; 108 char *signerfile = NULL, *recipfile = NULL; 109 STACK_OF(OPENSSL_STRING) * sksigners = NULL, *skkeys = NULL; 110 char *certfile = NULL, *keyfile = NULL, *contfile = NULL; 111 char *certsoutfile = NULL; 112 const EVP_CIPHER *cipher = NULL; 113 CMS_ContentInfo *cms = NULL, *rcms = NULL; 114 X509_STORE *store = NULL; 115 X509 *cert = NULL, *recip = NULL, *signer = NULL; 116 EVP_PKEY *key = NULL; 117 STACK_OF(X509) * encerts = NULL, *other = NULL; 118 BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL; 119 int badarg = 0; 120 int flags = CMS_DETACHED, noout = 0, print = 0; 121 int verify_retcode = 0; 122 int rr_print = 0, rr_allorfirst = -1; 123 STACK_OF(OPENSSL_STRING) * rr_to = NULL, *rr_from = NULL; 124 CMS_ReceiptRequest *rr = NULL; 125 char *to = NULL, *from = NULL, *subject = NULL; 126 char *CAfile = NULL, *CApath = NULL; 127 char *passargin = NULL, *passin = NULL; 128 const EVP_MD *sign_md = NULL; 129 int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; 130 int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM; 131 #ifndef OPENSSL_NO_ENGINE 132 char *engine = NULL; 133 #endif 134 unsigned char *secret_key = NULL, *secret_keyid = NULL; 135 unsigned char *pwri_pass = NULL, *pwri_tmp = NULL; 136 size_t secret_keylen = 0, secret_keyidlen = 0; 137 138 ASN1_OBJECT *econtent_type = NULL; 139 140 X509_VERIFY_PARAM *vpm = NULL; 141 142 args = argv + 1; 143 ret = 1; 144 145 while (!badarg && *args && *args[0] == '-') { 146 if (!strcmp(*args, "-encrypt")) 147 operation = SMIME_ENCRYPT; 148 else if (!strcmp(*args, "-decrypt")) 149 operation = SMIME_DECRYPT; 150 else if (!strcmp(*args, "-sign")) 151 operation = SMIME_SIGN; 152 else if (!strcmp(*args, "-sign_receipt")) 153 operation = SMIME_SIGN_RECEIPT; 154 else if (!strcmp(*args, "-resign")) 155 operation = SMIME_RESIGN; 156 else if (!strcmp(*args, "-verify")) 157 operation = SMIME_VERIFY; 158 else if (!strcmp(*args, "-verify_retcode")) 159 verify_retcode = 1; 160 else if (!strcmp(*args, "-verify_receipt")) { 161 operation = SMIME_VERIFY_RECEIPT; 162 if (!args[1]) 163 goto argerr; 164 args++; 165 rctfile = *args; 166 } else if (!strcmp(*args, "-cmsout")) 167 operation = SMIME_CMSOUT; 168 else if (!strcmp(*args, "-data_out")) 169 operation = SMIME_DATAOUT; 170 else if (!strcmp(*args, "-data_create")) 171 operation = SMIME_DATA_CREATE; 172 else if (!strcmp(*args, "-digest_verify")) 173 operation = SMIME_DIGEST_VERIFY; 174 else if (!strcmp(*args, "-digest_create")) 175 operation = SMIME_DIGEST_CREATE; 176 else if (!strcmp(*args, "-compress")) 177 operation = SMIME_COMPRESS; 178 else if (!strcmp(*args, "-uncompress")) 179 operation = SMIME_UNCOMPRESS; 180 else if (!strcmp(*args, "-EncryptedData_decrypt")) 181 operation = SMIME_ENCRYPTED_DECRYPT; 182 else if (!strcmp(*args, "-EncryptedData_encrypt")) 183 operation = SMIME_ENCRYPTED_ENCRYPT; 184 #ifndef OPENSSL_NO_DES 185 else if (!strcmp(*args, "-des3")) 186 cipher = EVP_des_ede3_cbc(); 187 else if (!strcmp(*args, "-des")) 188 cipher = EVP_des_cbc(); 189 #endif 190 #ifndef OPENSSL_NO_RC2 191 else if (!strcmp(*args, "-rc2-40")) 192 cipher = EVP_rc2_40_cbc(); 193 else if (!strcmp(*args, "-rc2-128")) 194 cipher = EVP_rc2_cbc(); 195 else if (!strcmp(*args, "-rc2-64")) 196 cipher = EVP_rc2_64_cbc(); 197 #endif 198 #ifndef OPENSSL_NO_AES 199 else if (!strcmp(*args, "-aes128")) 200 cipher = EVP_aes_128_cbc(); 201 else if (!strcmp(*args, "-aes192")) 202 cipher = EVP_aes_192_cbc(); 203 else if (!strcmp(*args, "-aes256")) 204 cipher = EVP_aes_256_cbc(); 205 #endif 206 #ifndef OPENSSL_NO_CAMELLIA 207 else if (!strcmp(*args, "-camellia128")) 208 cipher = EVP_camellia_128_cbc(); 209 else if (!strcmp(*args, "-camellia192")) 210 cipher = EVP_camellia_192_cbc(); 211 else if (!strcmp(*args, "-camellia256")) 212 cipher = EVP_camellia_256_cbc(); 213 #endif 214 else if (!strcmp(*args, "-debug_decrypt")) 215 flags |= CMS_DEBUG_DECRYPT; 216 else if (!strcmp(*args, "-text")) 217 flags |= CMS_TEXT; 218 else if (!strcmp(*args, "-nointern")) 219 flags |= CMS_NOINTERN; 220 else if (!strcmp(*args, "-noverify") || 221 !strcmp(*args, "-no_signer_cert_verify")) 222 flags |= CMS_NO_SIGNER_CERT_VERIFY; 223 else if (!strcmp(*args, "-nocerts")) 224 flags |= CMS_NOCERTS; 225 else if (!strcmp(*args, "-noattr")) 226 flags |= CMS_NOATTR; 227 else if (!strcmp(*args, "-nodetach")) 228 flags &= ~CMS_DETACHED; 229 else if (!strcmp(*args, "-nosmimecap")) 230 flags |= CMS_NOSMIMECAP; 231 else if (!strcmp(*args, "-binary")) 232 flags |= CMS_BINARY; 233 else if (!strcmp(*args, "-keyid")) 234 flags |= CMS_USE_KEYID; 235 else if (!strcmp(*args, "-nosigs")) 236 flags |= CMS_NOSIGS; 237 else if (!strcmp(*args, "-no_content_verify")) 238 flags |= CMS_NO_CONTENT_VERIFY; 239 else if (!strcmp(*args, "-no_attr_verify")) 240 flags |= CMS_NO_ATTR_VERIFY; 241 else if (!strcmp(*args, "-stream")) 242 flags |= CMS_STREAM; 243 else if (!strcmp(*args, "-indef")) 244 flags |= CMS_STREAM; 245 else if (!strcmp(*args, "-noindef")) 246 flags &= ~CMS_STREAM; 247 else if (!strcmp(*args, "-nooldmime")) 248 flags |= CMS_NOOLDMIMETYPE; 249 else if (!strcmp(*args, "-crlfeol")) 250 flags |= CMS_CRLFEOL; 251 else if (!strcmp(*args, "-noout")) 252 noout = 1; 253 else if (!strcmp(*args, "-receipt_request_print")) 254 rr_print = 1; 255 else if (!strcmp(*args, "-receipt_request_all")) 256 rr_allorfirst = 0; 257 else if (!strcmp(*args, "-receipt_request_first")) 258 rr_allorfirst = 1; 259 else if (!strcmp(*args, "-receipt_request_from")) { 260 if (!args[1]) 261 goto argerr; 262 args++; 263 if (!rr_from) 264 rr_from = sk_OPENSSL_STRING_new_null(); 265 sk_OPENSSL_STRING_push(rr_from, *args); 266 } else if (!strcmp(*args, "-receipt_request_to")) { 267 if (!args[1]) 268 goto argerr; 269 args++; 270 if (!rr_to) 271 rr_to = sk_OPENSSL_STRING_new_null(); 272 sk_OPENSSL_STRING_push(rr_to, *args); 273 } else if (!strcmp(*args, "-print")) { 274 noout = 1; 275 print = 1; 276 } else if (!strcmp(*args, "-secretkey")) { 277 long ltmp; 278 if (!args[1]) 279 goto argerr; 280 args++; 281 secret_key = string_to_hex(*args, <mp); 282 if (!secret_key) { 283 BIO_printf(bio_err, "Invalid key %s\n", *args); 284 goto argerr; 285 } 286 secret_keylen = (size_t) ltmp; 287 } else if (!strcmp(*args, "-secretkeyid")) { 288 long ltmp; 289 if (!args[1]) 290 goto argerr; 291 args++; 292 secret_keyid = string_to_hex(*args, <mp); 293 if (!secret_keyid) { 294 BIO_printf(bio_err, "Invalid id %s\n", *args); 295 goto argerr; 296 } 297 secret_keyidlen = (size_t) ltmp; 298 } else if (!strcmp(*args, "-pwri_password")) { 299 if (!args[1]) 300 goto argerr; 301 args++; 302 pwri_pass = (unsigned char *) *args; 303 } else if (!strcmp(*args, "-econtent_type")) { 304 if (!args[1]) 305 goto argerr; 306 args++; 307 econtent_type = OBJ_txt2obj(*args, 0); 308 if (!econtent_type) { 309 BIO_printf(bio_err, "Invalid OID %s\n", *args); 310 goto argerr; 311 } 312 } 313 #ifndef OPENSSL_NO_ENGINE 314 else if (!strcmp(*args, "-engine")) { 315 if (!args[1]) 316 goto argerr; 317 engine = *++args; 318 } 319 #endif 320 else if (!strcmp(*args, "-passin")) { 321 if (!args[1]) 322 goto argerr; 323 passargin = *++args; 324 } else if (!strcmp(*args, "-to")) { 325 if (!args[1]) 326 goto argerr; 327 to = *++args; 328 } else if (!strcmp(*args, "-from")) { 329 if (!args[1]) 330 goto argerr; 331 from = *++args; 332 } else if (!strcmp(*args, "-subject")) { 333 if (!args[1]) 334 goto argerr; 335 subject = *++args; 336 } else if (!strcmp(*args, "-signer")) { 337 if (!args[1]) 338 goto argerr; 339 /* If previous -signer argument add signer to list */ 340 341 if (signerfile) { 342 if (!sksigners) 343 sksigners = 344 sk_OPENSSL_STRING_new_null(); 345 sk_OPENSSL_STRING_push(sksigners, signerfile); 346 if (!keyfile) 347 keyfile = signerfile; 348 if (!skkeys) 349 skkeys = sk_OPENSSL_STRING_new_null(); 350 sk_OPENSSL_STRING_push(skkeys, keyfile); 351 keyfile = NULL; 352 } 353 signerfile = *++args; 354 } else if (!strcmp(*args, "-recip")) { 355 if (!args[1]) 356 goto argerr; 357 recipfile = *++args; 358 } else if (!strcmp(*args, "-certsout")) { 359 if (!args[1]) 360 goto argerr; 361 certsoutfile = *++args; 362 } else if (!strcmp(*args, "-md")) { 363 if (!args[1]) 364 goto argerr; 365 sign_md = EVP_get_digestbyname(*++args); 366 if (sign_md == NULL) { 367 BIO_printf(bio_err, "Unknown digest %s\n", 368 *args); 369 goto argerr; 370 } 371 } else if (!strcmp(*args, "-inkey")) { 372 if (!args[1]) 373 goto argerr; 374 /* If previous -inkey arument add signer to list */ 375 if (keyfile) { 376 if (!signerfile) { 377 BIO_puts(bio_err, 378 "Illegal -inkey without -signer\n"); 379 goto argerr; 380 } 381 if (!sksigners) 382 sksigners = 383 sk_OPENSSL_STRING_new_null(); 384 sk_OPENSSL_STRING_push(sksigners, signerfile); 385 signerfile = NULL; 386 if (!skkeys) 387 skkeys = sk_OPENSSL_STRING_new_null(); 388 sk_OPENSSL_STRING_push(skkeys, keyfile); 389 } 390 keyfile = *++args; 391 } else if (!strcmp(*args, "-keyform")) { 392 if (!args[1]) 393 goto argerr; 394 keyform = str2fmt(*++args); 395 } else if (!strcmp(*args, "-rctform")) { 396 if (!args[1]) 397 goto argerr; 398 rctformat = str2fmt(*++args); 399 } else if (!strcmp(*args, "-certfile")) { 400 if (!args[1]) 401 goto argerr; 402 certfile = *++args; 403 } else if (!strcmp(*args, "-CAfile")) { 404 if (!args[1]) 405 goto argerr; 406 CAfile = *++args; 407 } else if (!strcmp(*args, "-CApath")) { 408 if (!args[1]) 409 goto argerr; 410 CApath = *++args; 411 } else if (!strcmp(*args, "-in")) { 412 if (!args[1]) 413 goto argerr; 414 infile = *++args; 415 } else if (!strcmp(*args, "-inform")) { 416 if (!args[1]) 417 goto argerr; 418 informat = str2fmt(*++args); 419 } else if (!strcmp(*args, "-outform")) { 420 if (!args[1]) 421 goto argerr; 422 outformat = str2fmt(*++args); 423 } else if (!strcmp(*args, "-out")) { 424 if (!args[1]) 425 goto argerr; 426 outfile = *++args; 427 } else if (!strcmp(*args, "-content")) { 428 if (!args[1]) 429 goto argerr; 430 contfile = *++args; 431 } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) 432 continue; 433 else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL) 434 badarg = 1; 435 args++; 436 } 437 438 if (((rr_allorfirst != -1) || rr_from) && !rr_to) { 439 BIO_puts(bio_err, "No Signed Receipts Recipients\n"); 440 goto argerr; 441 } 442 if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) { 443 BIO_puts(bio_err, "Signed receipts only allowed with -sign\n"); 444 goto argerr; 445 } 446 if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) { 447 BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); 448 goto argerr; 449 } 450 if (operation & SMIME_SIGNERS) { 451 if (keyfile && !signerfile) { 452 BIO_puts(bio_err, "Illegal -inkey without -signer\n"); 453 goto argerr; 454 } 455 /* Check to see if any final signer needs to be appended */ 456 if (signerfile) { 457 if (!sksigners) 458 sksigners = sk_OPENSSL_STRING_new_null(); 459 sk_OPENSSL_STRING_push(sksigners, signerfile); 460 if (!skkeys) 461 skkeys = sk_OPENSSL_STRING_new_null(); 462 if (!keyfile) 463 keyfile = signerfile; 464 sk_OPENSSL_STRING_push(skkeys, keyfile); 465 } 466 if (!sksigners) { 467 BIO_printf(bio_err, 468 "No signer certificate specified\n"); 469 badarg = 1; 470 } 471 signerfile = NULL; 472 keyfile = NULL; 473 } else if (operation == SMIME_DECRYPT) { 474 if (!recipfile && !keyfile && !secret_key && !pwri_pass) { 475 BIO_printf(bio_err, 476 "No recipient certificate or key specified\n"); 477 badarg = 1; 478 } 479 } else if (operation == SMIME_ENCRYPT) { 480 if (!*args && !secret_key && !pwri_pass) { 481 BIO_printf(bio_err, 482 "No recipient(s) certificate(s) specified\n"); 483 badarg = 1; 484 } 485 } else if (!operation) 486 badarg = 1; 487 488 if (badarg) { 489 argerr: 490 BIO_printf(bio_err, "Usage cms [options] cert.pem ...\n"); 491 BIO_printf(bio_err, "where options are\n"); 492 BIO_printf(bio_err, "-encrypt encrypt message\n"); 493 BIO_printf(bio_err, "-decrypt decrypt encrypted message\n"); 494 BIO_printf(bio_err, "-sign sign message\n"); 495 BIO_printf(bio_err, "-verify verify signed message\n"); 496 BIO_printf(bio_err, "-cmsout output CMS structure\n"); 497 #ifndef OPENSSL_NO_DES 498 BIO_printf(bio_err, "-des3 encrypt with triple DES\n"); 499 BIO_printf(bio_err, "-des encrypt with DES\n"); 500 #endif 501 #ifndef OPENSSL_NO_RC2 502 BIO_printf(bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); 503 BIO_printf(bio_err, "-rc2-64 encrypt with RC2-64\n"); 504 BIO_printf(bio_err, "-rc2-128 encrypt with RC2-128\n"); 505 #endif 506 #ifndef OPENSSL_NO_AES 507 BIO_printf(bio_err, "-aes128, -aes192, -aes256\n"); 508 BIO_printf(bio_err, " encrypt PEM output with cbc aes\n"); 509 #endif 510 #ifndef OPENSSL_NO_CAMELLIA 511 BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n"); 512 BIO_printf(bio_err, " encrypt PEM output with cbc camellia\n"); 513 #endif 514 BIO_printf(bio_err, "-nointern don't search certificates in message for signer\n"); 515 BIO_printf(bio_err, "-nosigs don't verify message signature\n"); 516 BIO_printf(bio_err, "-noverify don't verify signers certificate\n"); 517 BIO_printf(bio_err, "-nocerts don't include signers certificate when signing\n"); 518 BIO_printf(bio_err, "-nodetach use opaque signing\n"); 519 BIO_printf(bio_err, "-noattr don't include any signed attributes\n"); 520 BIO_printf(bio_err, "-binary don't translate message to text\n"); 521 BIO_printf(bio_err, "-certfile file other certificates file\n"); 522 BIO_printf(bio_err, "-certsout file certificate output file\n"); 523 BIO_printf(bio_err, "-signer file signer certificate file\n"); 524 BIO_printf(bio_err, "-recip file recipient certificate file for decryption\n"); 525 BIO_printf(bio_err, "-keyid use subject key identifier\n"); 526 BIO_printf(bio_err, "-in file input file\n"); 527 BIO_printf(bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); 528 BIO_printf(bio_err, "-inkey file input private key (if not signer or recipient)\n"); 529 BIO_printf(bio_err, "-keyform arg input private key format (PEM or ENGINE)\n"); 530 BIO_printf(bio_err, "-out file output file\n"); 531 BIO_printf(bio_err, "-outform arg output format SMIME (default), PEM or DER\n"); 532 BIO_printf(bio_err, "-content file supply or override content for detached signature\n"); 533 BIO_printf(bio_err, "-to addr to address\n"); 534 BIO_printf(bio_err, "-from ad from address\n"); 535 BIO_printf(bio_err, "-subject s subject\n"); 536 BIO_printf(bio_err, "-text include or delete text MIME headers\n"); 537 BIO_printf(bio_err, "-CApath dir trusted certificates directory\n"); 538 BIO_printf(bio_err, "-CAfile file trusted certificates file\n"); 539 BIO_printf(bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n"); 540 BIO_printf(bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); 541 #ifndef OPENSSL_NO_ENGINE 542 BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); 543 #endif 544 BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); 545 BIO_printf(bio_err, "cert.pem recipient certificate(s) for encryption\n"); 546 goto end; 547 } 548 #ifndef OPENSSL_NO_ENGINE 549 e = setup_engine(bio_err, engine, 0); 550 #endif 551 552 if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { 553 BIO_printf(bio_err, "Error getting password\n"); 554 goto end; 555 } 556 ret = 2; 557 558 if (!(operation & SMIME_SIGNERS)) 559 flags &= ~CMS_DETACHED; 560 561 if (operation & SMIME_OP) { 562 if (outformat == FORMAT_ASN1) 563 outmode = "wb"; 564 } else { 565 if (flags & CMS_BINARY) 566 outmode = "wb"; 567 } 568 569 if (operation & SMIME_IP) { 570 if (informat == FORMAT_ASN1) 571 inmode = "rb"; 572 } else { 573 if (flags & CMS_BINARY) 574 inmode = "rb"; 575 } 576 577 if (operation == SMIME_ENCRYPT) { 578 if (!cipher) { 579 #ifndef OPENSSL_NO_DES 580 cipher = EVP_des_ede3_cbc(); 581 #else 582 BIO_printf(bio_err, "No cipher selected\n"); 583 goto end; 584 #endif 585 } 586 if (secret_key && !secret_keyid) { 587 BIO_printf(bio_err, "No secret key id\n"); 588 goto end; 589 } 590 if (*args) 591 encerts = sk_X509_new_null(); 592 while (*args) { 593 if (!(cert = load_cert(bio_err, *args, FORMAT_PEM, 594 NULL, e, "recipient certificate file"))) 595 goto end; 596 sk_X509_push(encerts, cert); 597 cert = NULL; 598 args++; 599 } 600 } 601 if (certfile) { 602 if (!(other = load_certs(bio_err, certfile, FORMAT_PEM, NULL, 603 e, "certificate file"))) { 604 ERR_print_errors(bio_err); 605 goto end; 606 } 607 } 608 if (recipfile && (operation == SMIME_DECRYPT)) { 609 if (!(recip = load_cert(bio_err, recipfile, FORMAT_PEM, NULL, 610 e, "recipient certificate file"))) { 611 ERR_print_errors(bio_err); 612 goto end; 613 } 614 } 615 if (operation == SMIME_SIGN_RECEIPT) { 616 if (!(signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL, 617 e, "receipt signer certificate file"))) { 618 ERR_print_errors(bio_err); 619 goto end; 620 } 621 } 622 if (operation == SMIME_DECRYPT) { 623 if (!keyfile) 624 keyfile = recipfile; 625 } else if ((operation == SMIME_SIGN) || 626 (operation == SMIME_SIGN_RECEIPT)) { 627 if (!keyfile) 628 keyfile = signerfile; 629 } else 630 keyfile = NULL; 631 632 if (keyfile) { 633 key = load_key(bio_err, keyfile, keyform, 0, passin, e, 634 "signing key file"); 635 if (!key) 636 goto end; 637 } 638 if (infile) { 639 if (!(in = BIO_new_file(infile, inmode))) { 640 BIO_printf(bio_err, 641 "Can't open input file %s\n", infile); 642 goto end; 643 } 644 } else 645 in = BIO_new_fp(stdin, BIO_NOCLOSE); 646 647 if (operation & SMIME_IP) { 648 if (informat == FORMAT_SMIME) 649 cms = SMIME_read_CMS(in, &indata); 650 else if (informat == FORMAT_PEM) 651 cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); 652 else if (informat == FORMAT_ASN1) 653 cms = d2i_CMS_bio(in, NULL); 654 else { 655 BIO_printf(bio_err, "Bad input format for CMS file\n"); 656 goto end; 657 } 658 659 if (!cms) { 660 BIO_printf(bio_err, "Error reading S/MIME message\n"); 661 goto end; 662 } 663 if (contfile) { 664 BIO_free(indata); 665 if (!(indata = BIO_new_file(contfile, "rb"))) { 666 BIO_printf(bio_err, 667 "Can't read content file %s\n", contfile); 668 goto end; 669 } 670 } 671 if (certsoutfile) { 672 STACK_OF(X509) * allcerts; 673 allcerts = CMS_get1_certs(cms); 674 if (!save_certs(certsoutfile, allcerts)) { 675 BIO_printf(bio_err, 676 "Error writing certs to %s\n", 677 certsoutfile); 678 ret = 5; 679 goto end; 680 } 681 sk_X509_pop_free(allcerts, X509_free); 682 } 683 } 684 if (rctfile) { 685 char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r"; 686 if (!(rctin = BIO_new_file(rctfile, rctmode))) { 687 BIO_printf(bio_err, 688 "Can't open receipt file %s\n", rctfile); 689 goto end; 690 } 691 if (rctformat == FORMAT_SMIME) 692 rcms = SMIME_read_CMS(rctin, NULL); 693 else if (rctformat == FORMAT_PEM) 694 rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); 695 else if (rctformat == FORMAT_ASN1) 696 rcms = d2i_CMS_bio(rctin, NULL); 697 else { 698 BIO_printf(bio_err, "Bad input format for receipt\n"); 699 goto end; 700 } 701 702 if (!rcms) { 703 BIO_printf(bio_err, "Error reading receipt\n"); 704 goto end; 705 } 706 } 707 if (outfile) { 708 if (!(out = BIO_new_file(outfile, outmode))) { 709 BIO_printf(bio_err, 710 "Can't open output file %s\n", outfile); 711 goto end; 712 } 713 } else { 714 out = BIO_new_fp(stdout, BIO_NOCLOSE); 715 } 716 717 if ((operation == SMIME_VERIFY) || 718 (operation == SMIME_VERIFY_RECEIPT)) { 719 if (!(store = setup_verify(bio_err, CAfile, CApath))) 720 goto end; 721 X509_STORE_set_verify_cb(store, cms_cb); 722 if (vpm) 723 X509_STORE_set1_param(store, vpm); 724 } 725 ret = 3; 726 727 if (operation == SMIME_DATA_CREATE) { 728 cms = CMS_data_create(in, flags); 729 } else if (operation == SMIME_DIGEST_CREATE) { 730 cms = CMS_digest_create(in, sign_md, flags); 731 } else if (operation == SMIME_COMPRESS) { 732 cms = CMS_compress(in, -1, flags); 733 } else if (operation == SMIME_ENCRYPT) { 734 flags |= CMS_PARTIAL; 735 cms = CMS_encrypt(encerts, in, cipher, flags); 736 if (!cms) 737 goto end; 738 if (secret_key) { 739 if (!CMS_add0_recipient_key(cms, NID_undef, secret_key, 740 secret_keylen, secret_keyid, secret_keyidlen, 741 NULL, NULL, NULL)) 742 goto end; 743 /* NULL these because call absorbs them */ 744 secret_key = NULL; 745 secret_keyid = NULL; 746 } 747 if (pwri_pass) { 748 pwri_tmp = strdup(pwri_pass); 749 if (!pwri_tmp) 750 goto end; 751 if (!CMS_add0_recipient_password(cms, -1, NID_undef, 752 NID_undef, pwri_tmp, -1, NULL)) 753 goto end; 754 pwri_tmp = NULL; 755 } 756 if (!(flags & CMS_STREAM)) { 757 if (!CMS_final(cms, in, NULL, flags)) 758 goto end; 759 } 760 } else if (operation == SMIME_ENCRYPTED_ENCRYPT) { 761 cms = CMS_EncryptedData_encrypt(in, cipher, secret_key, 762 secret_keylen, flags); 763 764 } else if (operation == SMIME_SIGN_RECEIPT) { 765 CMS_ContentInfo *srcms = NULL; 766 STACK_OF(CMS_SignerInfo) * sis; 767 CMS_SignerInfo *si; 768 sis = CMS_get0_SignerInfos(cms); 769 if (!sis) 770 goto end; 771 si = sk_CMS_SignerInfo_value(sis, 0); 772 srcms = CMS_sign_receipt(si, signer, key, other, flags); 773 if (!srcms) 774 goto end; 775 CMS_ContentInfo_free(cms); 776 cms = srcms; 777 } else if (operation & SMIME_SIGNERS) { 778 int i; 779 /* 780 * If detached data content we enable streaming if S/MIME 781 * output format. 782 */ 783 if (operation == SMIME_SIGN) { 784 785 if (flags & CMS_DETACHED) { 786 if (outformat == FORMAT_SMIME) 787 flags |= CMS_STREAM; 788 } 789 flags |= CMS_PARTIAL; 790 cms = CMS_sign(NULL, NULL, other, in, flags); 791 if (!cms) 792 goto end; 793 if (econtent_type) 794 CMS_set1_eContentType(cms, econtent_type); 795 796 if (rr_to) { 797 rr = make_receipt_request(rr_to, rr_allorfirst, 798 rr_from); 799 if (!rr) { 800 BIO_puts(bio_err, 801 "Signed Receipt Request Creation Error\n"); 802 goto end; 803 } 804 } 805 } else 806 flags |= CMS_REUSE_DIGEST; 807 for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { 808 CMS_SignerInfo *si; 809 signerfile = sk_OPENSSL_STRING_value(sksigners, i); 810 keyfile = sk_OPENSSL_STRING_value(skkeys, i); 811 signer = load_cert(bio_err, signerfile, FORMAT_PEM, 812 NULL, e, "signer certificate"); 813 if (!signer) 814 goto end; 815 key = load_key(bio_err, keyfile, keyform, 0, passin, e, 816 "signing key file"); 817 if (!key) 818 goto end; 819 si = CMS_add1_signer(cms, signer, key, sign_md, flags); 820 if (!si) 821 goto end; 822 if (rr && !CMS_add1_ReceiptRequest(si, rr)) 823 goto end; 824 X509_free(signer); 825 signer = NULL; 826 EVP_PKEY_free(key); 827 key = NULL; 828 } 829 /* If not streaming or resigning finalize structure */ 830 if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) { 831 if (!CMS_final(cms, in, NULL, flags)) 832 goto end; 833 } 834 } 835 if (!cms) { 836 BIO_printf(bio_err, "Error creating CMS structure\n"); 837 goto end; 838 } 839 ret = 4; 840 if (operation == SMIME_DECRYPT) { 841 if (flags & CMS_DEBUG_DECRYPT) 842 CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags); 843 844 if (secret_key) { 845 if (!CMS_decrypt_set1_key(cms, secret_key, 846 secret_keylen, secret_keyid, secret_keyidlen)) { 847 BIO_puts(bio_err, 848 "Error decrypting CMS using secret key\n"); 849 goto end; 850 } 851 } 852 if (key) { 853 if (!CMS_decrypt_set1_pkey(cms, key, recip)) { 854 BIO_puts(bio_err, 855 "Error decrypting CMS using private key\n"); 856 goto end; 857 } 858 } 859 if (pwri_pass) { 860 if (!CMS_decrypt_set1_password(cms, pwri_pass, -1)) { 861 BIO_puts(bio_err, 862 "Error decrypting CMS using password\n"); 863 goto end; 864 } 865 } 866 if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) { 867 BIO_printf(bio_err, "Error decrypting CMS structure\n"); 868 goto end; 869 } 870 } else if (operation == SMIME_DATAOUT) { 871 if (!CMS_data(cms, out, flags)) 872 goto end; 873 } else if (operation == SMIME_UNCOMPRESS) { 874 if (!CMS_uncompress(cms, indata, out, flags)) 875 goto end; 876 } else if (operation == SMIME_DIGEST_VERIFY) { 877 if (CMS_digest_verify(cms, indata, out, flags) > 0) 878 BIO_printf(bio_err, "Verification successful\n"); 879 else { 880 BIO_printf(bio_err, "Verification failure\n"); 881 goto end; 882 } 883 } else if (operation == SMIME_ENCRYPTED_DECRYPT) { 884 if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen, 885 indata, out, flags)) 886 goto end; 887 } else if (operation == SMIME_VERIFY) { 888 if (CMS_verify(cms, other, store, indata, out, flags) > 0) 889 BIO_printf(bio_err, "Verification successful\n"); 890 else { 891 BIO_printf(bio_err, "Verification failure\n"); 892 if (verify_retcode) 893 ret = verify_err + 32; 894 goto end; 895 } 896 if (signerfile) { 897 STACK_OF(X509) * signers; 898 signers = CMS_get0_signers(cms); 899 if (!save_certs(signerfile, signers)) { 900 BIO_printf(bio_err, 901 "Error writing signers to %s\n", 902 signerfile); 903 ret = 5; 904 goto end; 905 } 906 sk_X509_free(signers); 907 } 908 if (rr_print) 909 receipt_request_print(bio_err, cms); 910 911 } else if (operation == SMIME_VERIFY_RECEIPT) { 912 if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0) 913 BIO_printf(bio_err, "Verification successful\n"); 914 else { 915 BIO_printf(bio_err, "Verification failure\n"); 916 goto end; 917 } 918 } else { 919 if (noout) { 920 if (print) 921 CMS_ContentInfo_print_ctx(out, cms, 0, NULL); 922 } else if (outformat == FORMAT_SMIME) { 923 if (to) 924 BIO_printf(out, "To: %s\n", to); 925 if (from) 926 BIO_printf(out, "From: %s\n", from); 927 if (subject) 928 BIO_printf(out, "Subject: %s\n", subject); 929 if (operation == SMIME_RESIGN) 930 ret = SMIME_write_CMS(out, cms, indata, flags); 931 else 932 ret = SMIME_write_CMS(out, cms, in, flags); 933 } else if (outformat == FORMAT_PEM) 934 ret = PEM_write_bio_CMS_stream(out, cms, in, flags); 935 else if (outformat == FORMAT_ASN1) 936 ret = i2d_CMS_bio_stream(out, cms, in, flags); 937 else { 938 BIO_printf(bio_err, "Bad output format for CMS file\n"); 939 goto end; 940 } 941 if (ret <= 0) { 942 ret = 6; 943 goto end; 944 } 945 } 946 ret = 0; 947 948 end: 949 if (ret) 950 ERR_print_errors(bio_err); 951 sk_X509_pop_free(encerts, X509_free); 952 sk_X509_pop_free(other, X509_free); 953 if (vpm) 954 X509_VERIFY_PARAM_free(vpm); 955 if (sksigners) 956 sk_OPENSSL_STRING_free(sksigners); 957 if (skkeys) 958 sk_OPENSSL_STRING_free(skkeys); 959 free(secret_key); 960 free(secret_keyid); 961 free(pwri_tmp); 962 if (econtent_type) 963 ASN1_OBJECT_free(econtent_type); 964 if (rr) 965 CMS_ReceiptRequest_free(rr); 966 if (rr_to) 967 sk_OPENSSL_STRING_free(rr_to); 968 if (rr_from) 969 sk_OPENSSL_STRING_free(rr_from); 970 X509_STORE_free(store); 971 X509_free(cert); 972 X509_free(recip); 973 X509_free(signer); 974 EVP_PKEY_free(key); 975 CMS_ContentInfo_free(cms); 976 CMS_ContentInfo_free(rcms); 977 BIO_free(rctin); 978 BIO_free(in); 979 BIO_free(indata); 980 BIO_free_all(out); 981 free(passin); 982 return (ret); 983 } 984 985 static int 986 save_certs(char *signerfile, STACK_OF(X509) * signers) 987 { 988 int i; 989 BIO *tmp; 990 991 if (!signerfile) 992 return 1; 993 tmp = BIO_new_file(signerfile, "w"); 994 if (!tmp) 995 return 0; 996 for (i = 0; i < sk_X509_num(signers); i++) 997 PEM_write_bio_X509(tmp, sk_X509_value(signers, i)); 998 BIO_free(tmp); 999 return 1; 1000 } 1001 1002 /* Minimal callback just to output policy info (if any) */ 1003 1004 static int 1005 cms_cb(int ok, X509_STORE_CTX * ctx) 1006 { 1007 int error; 1008 1009 error = X509_STORE_CTX_get_error(ctx); 1010 1011 verify_err = error; 1012 1013 if ((error != X509_V_ERR_NO_EXPLICIT_POLICY) && 1014 ((error != X509_V_OK) || (ok != 2))) 1015 return ok; 1016 1017 policies_print(NULL, ctx); 1018 1019 return ok; 1020 } 1021 1022 static void 1023 gnames_stack_print(BIO * out, STACK_OF(GENERAL_NAMES) * gns) 1024 { 1025 STACK_OF(GENERAL_NAME) * gens; 1026 GENERAL_NAME *gen; 1027 int i, j; 1028 1029 for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++) { 1030 gens = sk_GENERAL_NAMES_value(gns, i); 1031 for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) { 1032 gen = sk_GENERAL_NAME_value(gens, j); 1033 BIO_puts(out, " "); 1034 GENERAL_NAME_print(out, gen); 1035 BIO_puts(out, "\n"); 1036 } 1037 } 1038 return; 1039 } 1040 1041 static void 1042 receipt_request_print(BIO * out, CMS_ContentInfo * cms) 1043 { 1044 STACK_OF(CMS_SignerInfo) * sis; 1045 CMS_SignerInfo *si; 1046 CMS_ReceiptRequest *rr; 1047 int allorfirst; 1048 STACK_OF(GENERAL_NAMES) * rto, *rlist; 1049 ASN1_STRING *scid; 1050 int i, rv; 1051 1052 sis = CMS_get0_SignerInfos(cms); 1053 for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) { 1054 si = sk_CMS_SignerInfo_value(sis, i); 1055 rv = CMS_get1_ReceiptRequest(si, &rr); 1056 BIO_printf(bio_err, "Signer %d:\n", i + 1); 1057 if (rv == 0) 1058 BIO_puts(bio_err, " No Receipt Request\n"); 1059 else if (rv < 0) { 1060 BIO_puts(bio_err, " Receipt Request Parse Error\n"); 1061 ERR_print_errors(bio_err); 1062 } else { 1063 char *id; 1064 int idlen; 1065 CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst, 1066 &rlist, &rto); 1067 BIO_puts(out, " Signed Content ID:\n"); 1068 idlen = ASN1_STRING_length(scid); 1069 id = (char *) ASN1_STRING_data(scid); 1070 BIO_dump_indent(out, id, idlen, 4); 1071 BIO_puts(out, " Receipts From"); 1072 if (rlist) { 1073 BIO_puts(out, " List:\n"); 1074 gnames_stack_print(out, rlist); 1075 } else if (allorfirst == 1) 1076 BIO_puts(out, ": First Tier\n"); 1077 else if (allorfirst == 0) 1078 BIO_puts(out, ": All\n"); 1079 else 1080 BIO_printf(out, " Unknown (%d)\n", allorfirst); 1081 BIO_puts(out, " Receipts To:\n"); 1082 gnames_stack_print(out, rto); 1083 } 1084 if (rr) 1085 CMS_ReceiptRequest_free(rr); 1086 } 1087 } 1088 1089 static STACK_OF(GENERAL_NAMES) * 1090 make_names_stack(STACK_OF(OPENSSL_STRING) * ns) 1091 { 1092 int i; 1093 STACK_OF(GENERAL_NAMES) * ret; 1094 GENERAL_NAMES *gens = NULL; 1095 GENERAL_NAME *gen = NULL; 1096 ret = sk_GENERAL_NAMES_new_null(); 1097 if (!ret) 1098 goto err; 1099 for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) { 1100 char *str = sk_OPENSSL_STRING_value(ns, i); 1101 gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0); 1102 if (!gen) 1103 goto err; 1104 gens = GENERAL_NAMES_new(); 1105 if (!gens) 1106 goto err; 1107 if (!sk_GENERAL_NAME_push(gens, gen)) 1108 goto err; 1109 gen = NULL; 1110 if (!sk_GENERAL_NAMES_push(ret, gens)) 1111 goto err; 1112 gens = NULL; 1113 } 1114 1115 return ret; 1116 1117 err: 1118 if (ret) 1119 sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free); 1120 if (gens) 1121 GENERAL_NAMES_free(gens); 1122 if (gen) 1123 GENERAL_NAME_free(gen); 1124 return NULL; 1125 } 1126 1127 1128 static CMS_ReceiptRequest * 1129 make_receipt_request(STACK_OF(OPENSSL_STRING) * rr_to, int rr_allorfirst, 1130 STACK_OF(OPENSSL_STRING) * rr_from) 1131 { 1132 STACK_OF(GENERAL_NAMES) * rct_to, *rct_from; 1133 CMS_ReceiptRequest *rr; 1134 1135 rct_to = make_names_stack(rr_to); 1136 if (!rct_to) 1137 goto err; 1138 if (rr_from) { 1139 rct_from = make_names_stack(rr_from); 1140 if (!rct_from) 1141 goto err; 1142 } else 1143 rct_from = NULL; 1144 rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from, 1145 rct_to); 1146 return rr; 1147 1148 err: 1149 return NULL; 1150 } 1151 1152 #endif 1153