1 /* $OpenBSD: cms_smime.c,v 1.13 2015/06/11 16:02:05 jsing Exp $ */ 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * project. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2008 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 */ 53 54 #include <openssl/asn1t.h> 55 #include <openssl/cms.h> 56 #include <openssl/err.h> 57 #include <openssl/x509.h> 58 #include <openssl/x509v3.h> 59 60 #include "cms_lcl.h" 61 62 static int 63 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 static int 115 check_content(CMS_ContentInfo *cms) 116 { 117 ASN1_OCTET_STRING **pos = CMS_get0_content(cms); 118 119 if (!pos || !*pos) { 120 CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT); 121 return 0; 122 } 123 return 1; 124 } 125 126 static void 127 do_free_upto(BIO *f, BIO *upto) 128 { 129 if (upto) { 130 BIO *tbio; 131 do { 132 tbio = BIO_pop(f); 133 BIO_free(f); 134 f = tbio; 135 } while (f != NULL && f != upto); 136 } else 137 BIO_free_all(f); 138 } 139 140 int 141 CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags) 142 { 143 BIO *cont; 144 int r; 145 146 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) { 147 CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA); 148 return 0; 149 } 150 cont = CMS_dataInit(cms, NULL); 151 if (!cont) 152 return 0; 153 r = cms_copy_content(out, cont, flags); 154 BIO_free_all(cont); 155 return r; 156 } 157 158 CMS_ContentInfo * 159 CMS_data_create(BIO *in, unsigned int flags) 160 { 161 CMS_ContentInfo *cms; 162 163 cms = cms_Data_create(); 164 if (!cms) 165 return NULL; 166 167 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) 168 return cms; 169 170 CMS_ContentInfo_free(cms); 171 172 return NULL; 173 } 174 175 int 176 CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, 177 unsigned int flags) 178 { 179 BIO *cont; 180 int r; 181 182 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) { 183 CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA); 184 return 0; 185 } 186 187 if (!dcont && !check_content(cms)) 188 return 0; 189 190 cont = CMS_dataInit(cms, dcont); 191 if (!cont) 192 return 0; 193 r = cms_copy_content(out, cont, flags); 194 if (r) 195 r = cms_DigestedData_do_final(cms, cont, 1); 196 do_free_upto(cont, dcont); 197 return r; 198 } 199 200 CMS_ContentInfo * 201 CMS_digest_create(BIO *in, const EVP_MD *md, unsigned int flags) 202 { 203 CMS_ContentInfo *cms; 204 205 if (!md) 206 md = EVP_sha1(); 207 cms = cms_DigestedData_create(md); 208 if (!cms) 209 return NULL; 210 211 if (!(flags & CMS_DETACHED)) 212 CMS_set_detached(cms, 0); 213 214 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) 215 return cms; 216 217 CMS_ContentInfo_free(cms); 218 return NULL; 219 } 220 221 int 222 CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, const unsigned char *key, 223 size_t keylen, BIO *dcont, BIO *out, unsigned int flags) 224 { 225 BIO *cont; 226 int r; 227 228 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) { 229 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT, 230 CMS_R_TYPE_NOT_ENCRYPTED_DATA); 231 return 0; 232 } 233 234 if (!dcont && !check_content(cms)) 235 return 0; 236 237 if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0) 238 return 0; 239 cont = CMS_dataInit(cms, dcont); 240 if (!cont) 241 return 0; 242 r = cms_copy_content(out, cont, flags); 243 do_free_upto(cont, dcont); 244 return r; 245 } 246 247 CMS_ContentInfo * 248 CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, 249 const unsigned char *key, size_t keylen, unsigned int flags) 250 { 251 CMS_ContentInfo *cms; 252 253 if (!cipher) { 254 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER); 255 return NULL; 256 } 257 cms = CMS_ContentInfo_new(); 258 if (!cms) 259 return NULL; 260 if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) 261 return NULL; 262 263 if (!(flags & CMS_DETACHED)) 264 CMS_set_detached(cms, 0); 265 266 if ((flags & (CMS_STREAM|CMS_PARTIAL)) || 267 CMS_final(cms, in, NULL, flags)) 268 return cms; 269 270 CMS_ContentInfo_free(cms); 271 return NULL; 272 } 273 274 static int 275 cms_signerinfo_verify_cert(CMS_SignerInfo *si, X509_STORE *store, 276 STACK_OF(X509) *certs, STACK_OF(X509_CRL) *crls, unsigned int flags) 277 { 278 X509_STORE_CTX ctx; 279 X509 *signer; 280 int i, j, r = 0; 281 282 CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); 283 if (!X509_STORE_CTX_init(&ctx, store, signer, certs)) { 284 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, 285 CMS_R_STORE_INIT_ERROR); 286 goto err; 287 } 288 X509_STORE_CTX_set_default(&ctx, "smime_sign"); 289 if (crls) 290 X509_STORE_CTX_set0_crls(&ctx, crls); 291 292 i = X509_verify_cert(&ctx); 293 if (i <= 0) { 294 j = X509_STORE_CTX_get_error(&ctx); 295 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, 296 CMS_R_CERTIFICATE_VERIFY_ERROR); 297 ERR_asprintf_error_data("Verify error:%s", 298 X509_verify_cert_error_string(j)); 299 goto err; 300 } 301 r = 1; 302 303 err: 304 X509_STORE_CTX_cleanup(&ctx); 305 return r; 306 } 307 308 int 309 CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, X509_STORE *store, 310 BIO *dcont, BIO *out, unsigned int flags) 311 { 312 CMS_SignerInfo *si; 313 STACK_OF(CMS_SignerInfo) *sinfos; 314 STACK_OF(X509) *cms_certs = NULL; 315 STACK_OF(X509_CRL) *crls = NULL; 316 X509 *signer; 317 int i, scount = 0, ret = 0; 318 BIO *cmsbio = NULL, *tmpin = NULL; 319 320 if (!dcont && !check_content(cms)) 321 return 0; 322 323 /* Attempt to find all signer certificates */ 324 325 sinfos = CMS_get0_SignerInfos(cms); 326 327 if (sk_CMS_SignerInfo_num(sinfos) <= 0) { 328 CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS); 329 goto err; 330 } 331 332 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 333 si = sk_CMS_SignerInfo_value(sinfos, i); 334 CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); 335 if (signer) 336 scount++; 337 } 338 339 if (scount != sk_CMS_SignerInfo_num(sinfos)) 340 scount += CMS_set1_signers_certs(cms, certs, flags); 341 342 if (scount != sk_CMS_SignerInfo_num(sinfos)) { 343 CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND); 344 goto err; 345 } 346 347 /* Attempt to verify all signers certs */ 348 349 if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) { 350 cms_certs = CMS_get1_certs(cms); 351 if (!(flags & CMS_NOCRL)) 352 crls = CMS_get1_crls(cms); 353 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 354 si = sk_CMS_SignerInfo_value(sinfos, i); 355 if (!cms_signerinfo_verify_cert(si, store, 356 cms_certs, crls, flags)) 357 goto err; 358 } 359 } 360 361 /* Attempt to verify all SignerInfo signed attribute signatures */ 362 363 if (!(flags & CMS_NO_ATTR_VERIFY)) { 364 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 365 si = sk_CMS_SignerInfo_value(sinfos, i); 366 if (CMS_signed_get_attr_count(si) < 0) 367 continue; 368 if (CMS_SignerInfo_verify(si) <= 0) 369 goto err; 370 } 371 } 372 373 /* Performance optimization: if the content is a memory BIO then 374 * store its contents in a temporary read only memory BIO. This 375 * avoids potentially large numbers of slow copies of data which will 376 * occur when reading from a read write memory BIO when signatures 377 * are calculated. 378 */ 379 380 if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) { 381 char *ptr; 382 long len; 383 len = BIO_get_mem_data(dcont, &ptr); 384 tmpin = BIO_new_mem_buf(ptr, len); 385 if (tmpin == NULL) { 386 CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE); 387 return 0; 388 } 389 } else 390 tmpin = dcont; 391 392 393 cmsbio = CMS_dataInit(cms, tmpin); 394 if (!cmsbio) 395 goto err; 396 397 if (!cms_copy_content(out, cmsbio, flags)) 398 goto err; 399 400 if (!(flags & CMS_NO_CONTENT_VERIFY)) { 401 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 402 si = sk_CMS_SignerInfo_value(sinfos, i); 403 if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) { 404 CMSerr(CMS_F_CMS_VERIFY, 405 CMS_R_CONTENT_VERIFY_ERROR); 406 goto err; 407 } 408 } 409 } 410 411 ret = 1; 412 413 err: 414 if (dcont && (tmpin == dcont)) 415 do_free_upto(cmsbio, dcont); 416 else 417 BIO_free_all(cmsbio); 418 419 if (cms_certs) 420 sk_X509_pop_free(cms_certs, X509_free); 421 if (crls) 422 sk_X509_CRL_pop_free(crls, X509_CRL_free); 423 424 return ret; 425 } 426 427 int 428 CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, 429 STACK_OF(X509) *certs, X509_STORE *store, unsigned int flags) 430 { 431 int r; 432 433 flags &= ~(CMS_DETACHED|CMS_TEXT); 434 r = CMS_verify(rcms, certs, store, NULL, NULL, flags); 435 if (r <= 0) 436 return r; 437 return cms_Receipt_verify(rcms, ocms); 438 } 439 440 CMS_ContentInfo * 441 CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, 442 unsigned int flags) 443 { 444 CMS_ContentInfo *cms; 445 int i; 446 447 cms = CMS_ContentInfo_new(); 448 if (!cms || !CMS_SignedData_init(cms)) 449 goto merr; 450 451 if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) { 452 CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR); 453 goto err; 454 } 455 456 for (i = 0; i < sk_X509_num(certs); i++) { 457 X509 *x = sk_X509_value(certs, i); 458 if (!CMS_add1_cert(cms, x)) 459 goto merr; 460 } 461 462 if (!(flags & CMS_DETACHED)) 463 CMS_set_detached(cms, 0); 464 465 if ((flags & (CMS_STREAM|CMS_PARTIAL)) || 466 CMS_final(cms, data, NULL, flags)) 467 return cms; 468 else 469 goto err; 470 471 merr: 472 CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE); 473 err: 474 if (cms) 475 CMS_ContentInfo_free(cms); 476 return NULL; 477 } 478 479 CMS_ContentInfo * 480 CMS_sign_receipt(CMS_SignerInfo *si, X509 *signcert, EVP_PKEY *pkey, 481 STACK_OF(X509) *certs, unsigned int flags) 482 { 483 CMS_SignerInfo *rct_si; 484 CMS_ContentInfo *cms = NULL; 485 ASN1_OCTET_STRING **pos, *os; 486 BIO *rct_cont = NULL; 487 int r = 0; 488 489 flags &= ~(CMS_STREAM|CMS_TEXT); 490 /* Not really detached but avoids content being allocated */ 491 flags |= CMS_PARTIAL|CMS_BINARY|CMS_DETACHED; 492 if (!pkey || !signcert) { 493 CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT); 494 return NULL; 495 } 496 497 /* Initialize signed data */ 498 499 cms = CMS_sign(NULL, NULL, certs, NULL, flags); 500 if (!cms) 501 goto err; 502 503 /* Set inner content type to signed receipt */ 504 if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt))) 505 goto err; 506 507 rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags); 508 if (!rct_si) { 509 CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR); 510 goto err; 511 } 512 513 os = cms_encode_Receipt(si); 514 515 if (!os) 516 goto err; 517 518 /* Set content to digest */ 519 rct_cont = BIO_new_mem_buf(os->data, os->length); 520 if (!rct_cont) 521 goto err; 522 523 /* Add msgSigDigest attribute */ 524 525 if (!cms_msgSigDigest_add1(rct_si, si)) 526 goto err; 527 528 /* Finalize structure */ 529 if (!CMS_final(cms, rct_cont, NULL, flags)) 530 goto err; 531 532 /* Set embedded content */ 533 pos = CMS_get0_content(cms); 534 *pos = os; 535 536 r = 1; 537 538 err: 539 if (rct_cont) 540 BIO_free(rct_cont); 541 if (r) 542 return cms; 543 CMS_ContentInfo_free(cms); 544 return NULL; 545 } 546 547 CMS_ContentInfo * 548 CMS_encrypt(STACK_OF(X509) *certs, BIO *data, const EVP_CIPHER *cipher, 549 unsigned int flags) 550 { 551 CMS_ContentInfo *cms; 552 int i; 553 X509 *recip; 554 555 cms = CMS_EnvelopedData_create(cipher); 556 if (!cms) 557 goto merr; 558 for (i = 0; i < sk_X509_num(certs); i++) { 559 recip = sk_X509_value(certs, i); 560 if (!CMS_add1_recipient_cert(cms, recip, flags)) { 561 CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR); 562 goto err; 563 } 564 } 565 566 if (!(flags & CMS_DETACHED)) 567 CMS_set_detached(cms, 0); 568 569 if ((flags & (CMS_STREAM|CMS_PARTIAL)) || 570 CMS_final(cms, data, NULL, flags)) 571 return cms; 572 else 573 goto err; 574 575 merr: 576 CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE); 577 err: 578 if (cms) 579 CMS_ContentInfo_free(cms); 580 return NULL; 581 } 582 583 int 584 CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) 585 { 586 STACK_OF(CMS_RecipientInfo) *ris; 587 CMS_RecipientInfo *ri; 588 int i, r; 589 int debug = 0, match_ri = 0; 590 591 ris = CMS_get0_RecipientInfos(cms); 592 if (ris) 593 debug = cms->d.envelopedData->encryptedContentInfo->debug; 594 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { 595 ri = sk_CMS_RecipientInfo_value(ris, i); 596 if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS) 597 continue; 598 match_ri = 1; 599 /* If we have a cert try matching RecipientInfo 600 * otherwise try them all. 601 */ 602 if (!cert || (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0)) { 603 CMS_RecipientInfo_set0_pkey(ri, pk); 604 r = CMS_RecipientInfo_decrypt(cms, ri); 605 CMS_RecipientInfo_set0_pkey(ri, NULL); 606 if (cert) { 607 /* If not debugging clear any error and 608 * return success to avoid leaking of 609 * information useful to MMA 610 */ 611 if (!debug) { 612 ERR_clear_error(); 613 return 1; 614 } 615 if (r > 0) 616 return 1; 617 CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, 618 CMS_R_DECRYPT_ERROR); 619 return 0; 620 } 621 /* If no cert and not debugging don't leave loop 622 * after first successful decrypt. Always attempt 623 * to decrypt all recipients to avoid leaking timing 624 * of a successful decrypt. 625 */ 626 else if (r > 0 && debug) 627 return 1; 628 } 629 } 630 /* If no cert and not debugging always return success */ 631 if (match_ri && !cert && !debug) { 632 ERR_clear_error(); 633 return 1; 634 } 635 636 CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT); 637 return 0; 638 } 639 640 int 641 CMS_decrypt_set1_key(CMS_ContentInfo *cms, unsigned char *key, size_t keylen, 642 unsigned char *id, size_t idlen) 643 { 644 STACK_OF(CMS_RecipientInfo) *ris; 645 CMS_RecipientInfo *ri; 646 int i, r; 647 648 ris = CMS_get0_RecipientInfos(cms); 649 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { 650 ri = sk_CMS_RecipientInfo_value(ris, i); 651 if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK) 652 continue; 653 654 /* If we have an id try matching RecipientInfo 655 * otherwise try them all. 656 */ 657 if (!id || 658 (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) { 659 CMS_RecipientInfo_set0_key(ri, key, keylen); 660 r = CMS_RecipientInfo_decrypt(cms, ri); 661 CMS_RecipientInfo_set0_key(ri, NULL, 0); 662 if (r > 0) 663 return 1; 664 if (id) { 665 CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, 666 CMS_R_DECRYPT_ERROR); 667 return 0; 668 } 669 ERR_clear_error(); 670 } 671 } 672 673 CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT); 674 return 0; 675 } 676 677 int 678 CMS_decrypt_set1_password(CMS_ContentInfo *cms, unsigned char *pass, 679 ssize_t passlen) 680 { 681 STACK_OF(CMS_RecipientInfo) *ris; 682 CMS_RecipientInfo *ri; 683 int i, r; 684 685 ris = CMS_get0_RecipientInfos(cms); 686 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { 687 ri = sk_CMS_RecipientInfo_value(ris, i); 688 if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS) 689 continue; 690 CMS_RecipientInfo_set0_password(ri, pass, passlen); 691 r = CMS_RecipientInfo_decrypt(cms, ri); 692 CMS_RecipientInfo_set0_password(ri, NULL, 0); 693 if (r > 0) 694 return 1; 695 } 696 697 CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT); 698 return 0; 699 } 700 701 int 702 CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, BIO *dcont, 703 BIO *out, unsigned int flags) 704 { 705 int r; 706 BIO *cont; 707 708 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) { 709 CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA); 710 return 0; 711 } 712 if (!dcont && !check_content(cms)) 713 return 0; 714 if (flags & CMS_DEBUG_DECRYPT) 715 cms->d.envelopedData->encryptedContentInfo->debug = 1; 716 else 717 cms->d.envelopedData->encryptedContentInfo->debug = 0; 718 if (!pk && !cert && !dcont && !out) 719 return 1; 720 if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) 721 return 0; 722 cont = CMS_dataInit(cms, dcont); 723 if (!cont) 724 return 0; 725 r = cms_copy_content(out, cont, flags); 726 do_free_upto(cont, dcont); 727 return r; 728 } 729 730 int 731 CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) 732 { 733 BIO *cmsbio; 734 int ret = 0; 735 736 if (!(cmsbio = CMS_dataInit(cms, dcont))) { 737 CMSerr(CMS_F_CMS_FINAL, ERR_R_MALLOC_FAILURE); 738 return 0; 739 } 740 741 SMIME_crlf_copy(data, cmsbio, flags); 742 743 (void)BIO_flush(cmsbio); 744 745 746 if (!CMS_dataFinal(cms, cmsbio)) { 747 CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR); 748 goto err; 749 } 750 751 ret = 1; 752 753 err: 754 do_free_upto(cmsbio, dcont); 755 756 return ret; 757 } 758 759 #ifdef ZLIB 760 761 int 762 CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags) 763 { 764 BIO *cont; 765 int r; 766 767 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) { 768 CMSerr(CMS_F_CMS_UNCOMPRESS, 769 CMS_R_TYPE_NOT_COMPRESSED_DATA); 770 return 0; 771 } 772 773 if (!dcont && !check_content(cms)) 774 return 0; 775 776 cont = CMS_dataInit(cms, dcont); 777 if (!cont) 778 return 0; 779 r = cms_copy_content(out, cont, flags); 780 do_free_upto(cont, dcont); 781 return r; 782 } 783 784 CMS_ContentInfo * 785 CMS_compress(BIO *in, int comp_nid, unsigned int flags) 786 { 787 CMS_ContentInfo *cms; 788 789 if (comp_nid <= 0) 790 comp_nid = NID_zlib_compression; 791 cms = cms_CompressedData_create(comp_nid); 792 if (!cms) 793 return NULL; 794 795 if (!(flags & CMS_DETACHED)) 796 CMS_set_detached(cms, 0); 797 798 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) 799 return cms; 800 801 CMS_ContentInfo_free(cms); 802 return NULL; 803 } 804 805 #else 806 807 int 808 CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags) 809 { 810 CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); 811 return 0; 812 } 813 814 CMS_ContentInfo * 815 CMS_compress(BIO *in, int comp_nid, unsigned int flags) 816 { 817 CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); 818 return NULL; 819 } 820 821 #endif 822