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