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