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