1 /* $OpenBSD: cms_smime.c,v 1.24 2019/10/04 18:03:56 tb Exp $ */ 2 /* 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4 * project. 5 */ 6 /* ==================================================================== 7 * Copyright (c) 2008 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 55 #include "cryptlib.h" 56 #include <openssl/asn1t.h> 57 #include <openssl/x509.h> 58 #include <openssl/x509v3.h> 59 #include <openssl/err.h> 60 #include <openssl/cms.h> 61 #include "cms_lcl.h" 62 #include "asn1/asn1_locl.h" 63 64 static BIO * 65 cms_get_text_bio(BIO *out, unsigned int flags) 66 { 67 BIO *rbio; 68 69 if (out == NULL) 70 rbio = BIO_new(BIO_s_null()); 71 else if (flags & CMS_TEXT) { 72 rbio = BIO_new(BIO_s_mem()); 73 BIO_set_mem_eof_return(rbio, 0); 74 } else 75 rbio = out; 76 77 return rbio; 78 } 79 80 static int 81 cms_copy_content(BIO *out, BIO *in, unsigned int flags) 82 { 83 unsigned char buf[4096]; 84 int r = 0, i; 85 BIO *tmpout; 86 87 tmpout = cms_get_text_bio(out, flags); 88 89 if (tmpout == NULL) { 90 CMSerror(ERR_R_MALLOC_FAILURE); 91 goto err; 92 } 93 94 /* Read all content through chain to process digest, decrypt etc */ 95 for (;;) { 96 i = BIO_read(in, buf, sizeof(buf)); 97 if (i <= 0) { 98 if (BIO_method_type(in) == BIO_TYPE_CIPHER) { 99 if (!BIO_get_cipher_status(in)) 100 goto err; 101 } 102 if (i < 0) 103 goto err; 104 break; 105 } 106 107 if (tmpout && (BIO_write(tmpout, buf, i) != i)) 108 goto err; 109 } 110 111 if (flags & CMS_TEXT) { 112 if (!SMIME_text(tmpout, out)) { 113 CMSerror(CMS_R_SMIME_TEXT_ERROR); 114 goto err; 115 } 116 } 117 118 r = 1; 119 120 err: 121 if (tmpout != out) 122 BIO_free(tmpout); 123 124 return r; 125 } 126 127 static int 128 check_content(CMS_ContentInfo *cms) 129 { 130 ASN1_OCTET_STRING **pos = CMS_get0_content(cms); 131 132 if (!pos || !*pos) { 133 CMSerror(CMS_R_NO_CONTENT); 134 return 0; 135 } 136 137 return 1; 138 } 139 140 static void 141 do_free_upto(BIO *f, BIO *upto) 142 { 143 if (upto) { 144 BIO *tbio; 145 do { 146 tbio = BIO_pop(f); 147 BIO_free(f); 148 f = tbio; 149 } 150 while (f && f != upto); 151 } else 152 BIO_free_all(f); 153 } 154 155 int 156 CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags) 157 { 158 BIO *cont; 159 int r; 160 161 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) { 162 CMSerror(CMS_R_TYPE_NOT_DATA); 163 return 0; 164 } 165 cont = CMS_dataInit(cms, NULL); 166 if (!cont) 167 return 0; 168 r = cms_copy_content(out, cont, flags); 169 BIO_free_all(cont); 170 171 return r; 172 } 173 174 CMS_ContentInfo * 175 CMS_data_create(BIO *in, unsigned int flags) 176 { 177 CMS_ContentInfo *cms; 178 179 cms = cms_Data_create(); 180 if (!cms) 181 return NULL; 182 183 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) 184 return cms; 185 186 CMS_ContentInfo_free(cms); 187 188 return NULL; 189 } 190 191 int 192 CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags) 193 { 194 BIO *cont; 195 int r; 196 197 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) { 198 CMSerror(CMS_R_TYPE_NOT_DIGESTED_DATA); 199 return 0; 200 } 201 202 if (!dcont && !check_content(cms)) 203 return 0; 204 205 cont = CMS_dataInit(cms, dcont); 206 if (!cont) 207 return 0; 208 r = cms_copy_content(out, cont, flags); 209 if (r) 210 r = cms_DigestedData_do_final(cms, cont, 1); 211 do_free_upto(cont, dcont); 212 213 return r; 214 } 215 216 CMS_ContentInfo * 217 CMS_digest_create(BIO *in, const EVP_MD *md, unsigned int flags) 218 { 219 CMS_ContentInfo *cms; 220 221 if (!md) 222 md = EVP_sha1(); 223 cms = cms_DigestedData_create(md); 224 if (!cms) 225 return NULL; 226 227 if (!(flags & CMS_DETACHED)) 228 CMS_set_detached(cms, 0); 229 230 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) 231 return cms; 232 233 CMS_ContentInfo_free(cms); 234 235 return NULL; 236 } 237 238 int 239 CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, const unsigned char *key, 240 size_t keylen, BIO *dcont, BIO *out, unsigned int flags) 241 { 242 BIO *cont; 243 int r; 244 245 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) { 246 CMSerror(CMS_R_TYPE_NOT_ENCRYPTED_DATA); 247 return 0; 248 } 249 250 if (!dcont && !check_content(cms)) 251 return 0; 252 253 if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0) 254 return 0; 255 cont = CMS_dataInit(cms, dcont); 256 if (!cont) 257 return 0; 258 r = cms_copy_content(out, cont, flags); 259 do_free_upto(cont, dcont); 260 261 return r; 262 } 263 264 CMS_ContentInfo * 265 CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, 266 const unsigned char *key, size_t keylen, unsigned int flags) 267 { 268 CMS_ContentInfo *cms; 269 270 if (!cipher) { 271 CMSerror(CMS_R_NO_CIPHER); 272 return NULL; 273 } 274 cms = CMS_ContentInfo_new(); 275 if (cms == NULL) 276 return NULL; 277 if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) 278 return NULL; 279 280 if (!(flags & CMS_DETACHED)) 281 CMS_set_detached(cms, 0); 282 283 if ((flags & (CMS_STREAM | CMS_PARTIAL)) || 284 CMS_final(cms, in, NULL, flags)) 285 return cms; 286 287 CMS_ContentInfo_free(cms); 288 289 return NULL; 290 } 291 292 static int 293 cms_signerinfo_verify_cert(CMS_SignerInfo *si, X509_STORE *store, 294 STACK_OF(X509) *certs, STACK_OF(X509_CRL) *crls) 295 { 296 X509_STORE_CTX *ctx = X509_STORE_CTX_new(); 297 X509 *signer; 298 int i, j, r = 0; 299 300 if (ctx == NULL) { 301 CMSerror(ERR_R_MALLOC_FAILURE); 302 goto err; 303 } 304 CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); 305 if (!X509_STORE_CTX_init(ctx, store, signer, certs)) { 306 CMSerror(CMS_R_STORE_INIT_ERROR); 307 goto err; 308 } 309 X509_STORE_CTX_set_default(ctx, "smime_sign"); 310 if (crls) 311 X509_STORE_CTX_set0_crls(ctx, crls); 312 313 i = X509_verify_cert(ctx); 314 if (i <= 0) { 315 j = X509_STORE_CTX_get_error(ctx); 316 CMSerror(CMS_R_CERTIFICATE_VERIFY_ERROR); 317 ERR_asprintf_error_data("Verify error: %s", 318 X509_verify_cert_error_string(j)); 319 goto err; 320 } 321 r = 1; 322 323 err: 324 X509_STORE_CTX_free(ctx); 325 326 return r; 327 } 328 329 int 330 CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, X509_STORE *store, 331 BIO *dcont, BIO *out, unsigned int flags) 332 { 333 CMS_SignerInfo *si; 334 STACK_OF(CMS_SignerInfo) *sinfos; 335 STACK_OF(X509) *cms_certs = NULL; 336 STACK_OF(X509_CRL) *crls = NULL; 337 X509 *signer; 338 int i, scount = 0, ret = 0; 339 BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL; 340 341 if (!dcont && !check_content(cms)) 342 return 0; 343 if (dcont && !(flags & CMS_BINARY)) { 344 const ASN1_OBJECT *coid = CMS_get0_eContentType(cms); 345 if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF) 346 flags |= CMS_ASCIICRLF; 347 } 348 349 /* Attempt to find all signer certificates */ 350 351 sinfos = CMS_get0_SignerInfos(cms); 352 if (sk_CMS_SignerInfo_num(sinfos) <= 0) { 353 CMSerror(CMS_R_NO_SIGNERS); 354 goto err; 355 } 356 357 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 358 si = sk_CMS_SignerInfo_value(sinfos, i); 359 CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); 360 if (signer) 361 scount++; 362 } 363 364 if (scount != sk_CMS_SignerInfo_num(sinfos)) 365 scount += CMS_set1_signers_certs(cms, certs, flags); 366 367 if (scount != sk_CMS_SignerInfo_num(sinfos)) { 368 CMSerror(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND); 369 goto err; 370 } 371 372 /* Attempt to verify all signers certs */ 373 374 if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) { 375 cms_certs = CMS_get1_certs(cms); 376 if (!(flags & CMS_NOCRL)) 377 crls = CMS_get1_crls(cms); 378 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 379 si = sk_CMS_SignerInfo_value(sinfos, i); 380 if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls)) 381 goto err; 382 } 383 } 384 385 /* Attempt to verify all SignerInfo signed attribute signatures */ 386 387 if (!(flags & CMS_NO_ATTR_VERIFY)) { 388 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 389 si = sk_CMS_SignerInfo_value(sinfos, i); 390 if (CMS_signed_get_attr_count(si) < 0) 391 continue; 392 if (CMS_SignerInfo_verify(si) <= 0) 393 goto err; 394 } 395 } 396 397 /* 398 * Performance optimization: if the content is a memory BIO then store 399 * its contents in a temporary read only memory BIO. This avoids 400 * potentially large numbers of slow copies of data which will occur when 401 * reading from a read write memory BIO when signatures are calculated. 402 */ 403 404 if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) { 405 char *ptr; 406 long len; 407 408 len = BIO_get_mem_data(dcont, &ptr); 409 tmpin = BIO_new_mem_buf(ptr, len); 410 if (tmpin == NULL) { 411 CMSerror(ERR_R_MALLOC_FAILURE); 412 goto err2; 413 } 414 } else 415 tmpin = dcont; 416 417 /* 418 * If not binary mode and detached generate digests by *writing* through 419 * the BIO. That makes it possible to canonicalise the input. 420 */ 421 if (!(flags & SMIME_BINARY) && dcont) { 422 /* 423 * Create output BIO so we can either handle text or to ensure 424 * included content doesn't override detached content. 425 */ 426 tmpout = cms_get_text_bio(out, flags); 427 if (!tmpout) { 428 CMSerror(ERR_R_MALLOC_FAILURE); 429 goto err; 430 } 431 cmsbio = CMS_dataInit(cms, tmpout); 432 if (!cmsbio) 433 goto err; 434 /* 435 * Don't use SMIME_TEXT for verify: it adds headers and we want to 436 * remove them. 437 */ 438 SMIME_crlf_copy(dcont, cmsbio, flags & ~SMIME_TEXT); 439 440 if (flags & CMS_TEXT) { 441 if (!SMIME_text(tmpout, out)) { 442 CMSerror(CMS_R_SMIME_TEXT_ERROR); 443 goto err; 444 } 445 } 446 } else { 447 cmsbio = CMS_dataInit(cms, tmpin); 448 if (!cmsbio) 449 goto err; 450 451 if (!cms_copy_content(out, cmsbio, flags)) 452 goto err; 453 454 } 455 if (!(flags & CMS_NO_CONTENT_VERIFY)) { 456 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 457 si = sk_CMS_SignerInfo_value(sinfos, i); 458 if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) { 459 CMSerror(CMS_R_CONTENT_VERIFY_ERROR); 460 goto err; 461 } 462 } 463 } 464 465 ret = 1; 466 467 err: 468 if (!(flags & SMIME_BINARY) && dcont) { 469 do_free_upto(cmsbio, tmpout); 470 if (tmpin != dcont) 471 BIO_free(tmpin); 472 } else { 473 if (dcont && (tmpin == dcont)) 474 do_free_upto(cmsbio, dcont); 475 else 476 BIO_free_all(cmsbio); 477 } 478 479 if (out != tmpout) 480 BIO_free_all(tmpout); 481 482 err2: 483 sk_X509_pop_free(cms_certs, X509_free); 484 sk_X509_CRL_pop_free(crls, X509_CRL_free); 485 486 return ret; 487 } 488 489 int 490 CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, 491 STACK_OF(X509) *certs, X509_STORE *store, unsigned int flags) 492 { 493 int r; 494 495 flags &= ~(CMS_DETACHED | CMS_TEXT); 496 r = CMS_verify(rcms, certs, store, NULL, NULL, flags); 497 if (r <= 0) 498 return r; 499 500 return cms_Receipt_verify(rcms, ocms); 501 } 502 503 CMS_ContentInfo * 504 CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, 505 unsigned int flags) 506 { 507 CMS_ContentInfo *cms; 508 int i; 509 510 cms = CMS_ContentInfo_new(); 511 if (cms == NULL || !CMS_SignedData_init(cms)) 512 goto merr; 513 if (flags & CMS_ASCIICRLF && 514 !CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF))) 515 goto err; 516 517 if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) { 518 CMSerror(CMS_R_ADD_SIGNER_ERROR); 519 goto err; 520 } 521 522 for (i = 0; i < sk_X509_num(certs); i++) { 523 X509 *x = sk_X509_value(certs, i); 524 if (!CMS_add1_cert(cms, x)) 525 goto merr; 526 } 527 528 if (!(flags & CMS_DETACHED)) 529 CMS_set_detached(cms, 0); 530 531 if ((flags & (CMS_STREAM | CMS_PARTIAL)) || 532 CMS_final(cms, data, NULL, flags)) 533 return cms; 534 else 535 goto err; 536 537 merr: 538 CMSerror(ERR_R_MALLOC_FAILURE); 539 540 err: 541 CMS_ContentInfo_free(cms); 542 543 return NULL; 544 } 545 546 CMS_ContentInfo * 547 CMS_sign_receipt(CMS_SignerInfo *si, X509 *signcert, EVP_PKEY *pkey, 548 STACK_OF(X509) *certs, unsigned int flags) 549 { 550 CMS_SignerInfo *rct_si; 551 CMS_ContentInfo *cms = NULL; 552 ASN1_OCTET_STRING **pos, *os; 553 BIO *rct_cont = NULL; 554 int r = 0; 555 556 flags &= ~(CMS_STREAM | CMS_TEXT); 557 /* Not really detached but avoids content being allocated */ 558 flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED; 559 if (!pkey || !signcert) { 560 CMSerror(CMS_R_NO_KEY_OR_CERT); 561 return NULL; 562 } 563 564 /* Initialize signed data */ 565 566 cms = CMS_sign(NULL, NULL, certs, NULL, flags); 567 if (!cms) 568 goto err; 569 570 /* Set inner content type to signed receipt */ 571 if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt))) 572 goto err; 573 574 rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags); 575 if (!rct_si) { 576 CMSerror(CMS_R_ADD_SIGNER_ERROR); 577 goto err; 578 } 579 580 os = cms_encode_Receipt(si); 581 if (!os) 582 goto err; 583 584 /* Set content to digest */ 585 rct_cont = BIO_new_mem_buf(os->data, os->length); 586 if (!rct_cont) 587 goto err; 588 589 /* Add msgSigDigest attribute */ 590 591 if (!cms_msgSigDigest_add1(rct_si, si)) 592 goto err; 593 594 /* Finalize structure */ 595 if (!CMS_final(cms, rct_cont, NULL, flags)) 596 goto err; 597 598 /* Set embedded content */ 599 pos = CMS_get0_content(cms); 600 *pos = os; 601 602 r = 1; 603 604 err: 605 BIO_free(rct_cont); 606 if (r) 607 return cms; 608 CMS_ContentInfo_free(cms); 609 610 return NULL; 611 } 612 613 CMS_ContentInfo * 614 CMS_encrypt(STACK_OF(X509) *certs, BIO *data, const EVP_CIPHER *cipher, 615 unsigned int flags) 616 { 617 CMS_ContentInfo *cms; 618 int i; 619 X509 *recip; 620 621 cms = CMS_EnvelopedData_create(cipher); 622 if (!cms) 623 goto merr; 624 for (i = 0; i < sk_X509_num(certs); i++) { 625 recip = sk_X509_value(certs, i); 626 if (!CMS_add1_recipient_cert(cms, recip, flags)) { 627 CMSerror(CMS_R_RECIPIENT_ERROR); 628 goto err; 629 } 630 } 631 632 if (!(flags & CMS_DETACHED)) 633 CMS_set_detached(cms, 0); 634 635 if ((flags & (CMS_STREAM | CMS_PARTIAL)) || 636 CMS_final(cms, data, NULL, flags)) 637 return cms; 638 else 639 goto err; 640 641 merr: 642 CMSerror(ERR_R_MALLOC_FAILURE); 643 err: 644 CMS_ContentInfo_free(cms); 645 646 return NULL; 647 } 648 649 static int 650 cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, EVP_PKEY *pk, 651 X509 *cert) 652 { 653 int i; 654 STACK_OF(CMS_RecipientEncryptedKey) *reks; 655 CMS_RecipientEncryptedKey *rek; 656 657 reks = CMS_RecipientInfo_kari_get0_reks(ri); 658 for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { 659 int rv; 660 661 rek = sk_CMS_RecipientEncryptedKey_value(reks, i); 662 if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert)) 663 continue; 664 CMS_RecipientInfo_kari_set0_pkey(ri, pk); 665 rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek); 666 CMS_RecipientInfo_kari_set0_pkey(ri, NULL); 667 if (rv > 0) 668 return 1; 669 return cert == NULL ? 0 : -1; 670 } 671 672 return 0; 673 } 674 675 int 676 CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) 677 { 678 STACK_OF(CMS_RecipientInfo) *ris; 679 CMS_RecipientInfo *ri; 680 int i, r, ri_type; 681 int debug = 0, match_ri = 0; 682 683 ris = CMS_get0_RecipientInfos(cms); 684 if (ris) 685 debug = cms->d.envelopedData->encryptedContentInfo->debug; 686 ri_type = cms_pkey_get_ri_type(pk); 687 if (ri_type == CMS_RECIPINFO_NONE) { 688 CMSerror(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 689 return 0; 690 } 691 692 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { 693 ri = sk_CMS_RecipientInfo_value(ris, i); 694 if (CMS_RecipientInfo_type(ri) != ri_type) 695 continue; 696 match_ri = 1; 697 if (ri_type == CMS_RECIPINFO_AGREE) { 698 r = cms_kari_set1_pkey(cms, ri, pk, cert); 699 if (r > 0) 700 return 1; 701 if (r < 0) 702 return 0; 703 } 704 /* 705 * If we have a cert try matching RecipientInfo otherwise try them 706 * all. 707 */ 708 else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) { 709 EVP_PKEY_up_ref(pk); 710 CMS_RecipientInfo_set0_pkey(ri, pk); 711 r = CMS_RecipientInfo_decrypt(cms, ri); 712 CMS_RecipientInfo_set0_pkey(ri, NULL); 713 if (cert) { 714 /* 715 * If not debugging clear any error and return success to 716 * avoid leaking of information useful to MMA 717 */ 718 if (!debug) { 719 ERR_clear_error(); 720 return 1; 721 } 722 if (r > 0) 723 return 1; 724 CMSerror(CMS_R_DECRYPT_ERROR); 725 return 0; 726 } 727 /* 728 * If no cert and not debugging don't leave loop after first 729 * successful decrypt. Always attempt to decrypt all recipients 730 * to avoid leaking timing of a successful decrypt. 731 */ 732 else if (r > 0 && debug) 733 return 1; 734 } 735 } 736 /* If no cert, key transport and not debugging always return success */ 737 if (cert == NULL && ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) { 738 ERR_clear_error(); 739 return 1; 740 } 741 742 CMSerror(CMS_R_NO_MATCHING_RECIPIENT); 743 744 return 0; 745 } 746 747 int 748 CMS_decrypt_set1_key(CMS_ContentInfo *cms, unsigned char *key, size_t keylen, 749 const unsigned char *id, size_t idlen) 750 { 751 STACK_OF(CMS_RecipientInfo) *ris; 752 CMS_RecipientInfo *ri; 753 int i, r; 754 755 ris = CMS_get0_RecipientInfos(cms); 756 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { 757 ri = sk_CMS_RecipientInfo_value(ris, i); 758 if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK) 759 continue; 760 761 /* 762 * If we have an id try matching RecipientInfo otherwise try them 763 * all. 764 */ 765 if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) { 766 CMS_RecipientInfo_set0_key(ri, key, keylen); 767 r = CMS_RecipientInfo_decrypt(cms, ri); 768 CMS_RecipientInfo_set0_key(ri, NULL, 0); 769 if (r > 0) 770 return 1; 771 if (id) { 772 CMSerror(CMS_R_DECRYPT_ERROR); 773 return 0; 774 } 775 ERR_clear_error(); 776 } 777 } 778 779 CMSerror(CMS_R_NO_MATCHING_RECIPIENT); 780 781 return 0; 782 } 783 784 int 785 CMS_decrypt_set1_password(CMS_ContentInfo *cms, unsigned char *pass, 786 ssize_t passlen) 787 { 788 STACK_OF(CMS_RecipientInfo) *ris; 789 CMS_RecipientInfo *ri; 790 int i, r; 791 792 ris = CMS_get0_RecipientInfos(cms); 793 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { 794 ri = sk_CMS_RecipientInfo_value(ris, i); 795 if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS) 796 continue; 797 CMS_RecipientInfo_set0_password(ri, pass, passlen); 798 r = CMS_RecipientInfo_decrypt(cms, ri); 799 CMS_RecipientInfo_set0_password(ri, NULL, 0); 800 if (r > 0) 801 return 1; 802 } 803 804 CMSerror(CMS_R_NO_MATCHING_RECIPIENT); 805 806 return 0; 807 } 808 809 int 810 CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, BIO *dcont, 811 BIO *out, unsigned int flags) 812 { 813 int r; 814 BIO *cont; 815 816 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) { 817 CMSerror(CMS_R_TYPE_NOT_ENVELOPED_DATA); 818 return 0; 819 } 820 if (!dcont && !check_content(cms)) 821 return 0; 822 if (flags & CMS_DEBUG_DECRYPT) 823 cms->d.envelopedData->encryptedContentInfo->debug = 1; 824 else 825 cms->d.envelopedData->encryptedContentInfo->debug = 0; 826 if (!cert) 827 cms->d.envelopedData->encryptedContentInfo->havenocert = 1; 828 else 829 cms->d.envelopedData->encryptedContentInfo->havenocert = 0; 830 if (!pk && !cert && !dcont && !out) 831 return 1; 832 if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) 833 return 0; 834 cont = CMS_dataInit(cms, dcont); 835 if (!cont) 836 return 0; 837 r = cms_copy_content(out, cont, flags); 838 do_free_upto(cont, dcont); 839 840 return r; 841 } 842 843 int 844 CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) 845 { 846 BIO *cmsbio; 847 int ret = 0; 848 849 if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) { 850 CMSerror(CMS_R_CMS_LIB); 851 return 0; 852 } 853 854 SMIME_crlf_copy(data, cmsbio, flags); 855 856 (void)BIO_flush(cmsbio); 857 858 if (!CMS_dataFinal(cms, cmsbio)) { 859 CMSerror(CMS_R_CMS_DATAFINAL_ERROR); 860 goto err; 861 } 862 863 ret = 1; 864 865 err: 866 do_free_upto(cmsbio, dcont); 867 868 return ret; 869 } 870 871 #ifdef ZLIB 872 873 int 874 CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags) 875 { 876 BIO *cont; 877 int r; 878 879 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) { 880 CMSerror(CMS_R_TYPE_NOT_COMPRESSED_DATA); 881 return 0; 882 } 883 884 if (!dcont && !check_content(cms)) 885 return 0; 886 887 cont = CMS_dataInit(cms, dcont); 888 if (!cont) 889 return 0; 890 r = cms_copy_content(out, cont, flags); 891 do_free_upto(cont, dcont); 892 893 return r; 894 } 895 896 CMS_ContentInfo * 897 CMS_compress(BIO *in, int comp_nid, unsigned int flags) 898 { 899 CMS_ContentInfo *cms; 900 901 if (comp_nid <= 0) 902 comp_nid = NID_zlib_compression; 903 cms = cms_CompressedData_create(comp_nid); 904 if (!cms) 905 return NULL; 906 907 if (!(flags & CMS_DETACHED)) 908 CMS_set_detached(cms, 0); 909 910 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) 911 return cms; 912 913 CMS_ContentInfo_free(cms); 914 915 return NULL; 916 } 917 918 #else 919 920 int 921 CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags) 922 { 923 CMSerror(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); 924 return 0; 925 } 926 927 CMS_ContentInfo * 928 CMS_compress(BIO *in, int comp_nid, unsigned int flags) 929 { 930 CMSerror(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); 931 return NULL; 932 } 933 934 #endif 935