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