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