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