diff options
Diffstat (limited to 'src/lib/libcrypto/pkcs7/pk7_doit.c')
| -rw-r--r-- | src/lib/libcrypto/pkcs7/pk7_doit.c | 101 |
1 files changed, 25 insertions, 76 deletions
diff --git a/src/lib/libcrypto/pkcs7/pk7_doit.c b/src/lib/libcrypto/pkcs7/pk7_doit.c index 77fda3b82a..3bf1a367bb 100644 --- a/src/lib/libcrypto/pkcs7/pk7_doit.c +++ b/src/lib/libcrypto/pkcs7/pk7_doit.c | |||
| @@ -204,11 +204,11 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, | |||
| 204 | unsigned char *ek = NULL; | 204 | unsigned char *ek = NULL; |
| 205 | size_t eklen; | 205 | size_t eklen; |
| 206 | 206 | ||
| 207 | int ret = -1; | 207 | int ret = 0; |
| 208 | 208 | ||
| 209 | pctx = EVP_PKEY_CTX_new(pkey, NULL); | 209 | pctx = EVP_PKEY_CTX_new(pkey, NULL); |
| 210 | if (!pctx) | 210 | if (!pctx) |
| 211 | return -1; | 211 | return 0; |
| 212 | 212 | ||
| 213 | if (EVP_PKEY_decrypt_init(pctx) <= 0) | 213 | if (EVP_PKEY_decrypt_init(pctx) <= 0) |
| 214 | goto err; | 214 | goto err; |
| @@ -235,19 +235,12 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, | |||
| 235 | if (EVP_PKEY_decrypt(pctx, ek, &eklen, | 235 | if (EVP_PKEY_decrypt(pctx, ek, &eklen, |
| 236 | ri->enc_key->data, ri->enc_key->length) <= 0) | 236 | ri->enc_key->data, ri->enc_key->length) <= 0) |
| 237 | { | 237 | { |
| 238 | ret = 0; | ||
| 239 | PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB); | 238 | PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB); |
| 240 | goto err; | 239 | goto err; |
| 241 | } | 240 | } |
| 242 | 241 | ||
| 243 | ret = 1; | 242 | ret = 1; |
| 244 | 243 | ||
| 245 | if (*pek) | ||
| 246 | { | ||
| 247 | OPENSSL_cleanse(*pek, *peklen); | ||
| 248 | OPENSSL_free(*pek); | ||
| 249 | } | ||
| 250 | |||
| 251 | *pek = ek; | 244 | *pek = ek; |
| 252 | *peklen = eklen; | 245 | *peklen = eklen; |
| 253 | 246 | ||
| @@ -430,8 +423,6 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 430 | STACK_OF(X509_ALGOR) *md_sk=NULL; | 423 | STACK_OF(X509_ALGOR) *md_sk=NULL; |
| 431 | STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; | 424 | STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; |
| 432 | PKCS7_RECIP_INFO *ri=NULL; | 425 | PKCS7_RECIP_INFO *ri=NULL; |
| 433 | unsigned char *ek = NULL, *tkey = NULL; | ||
| 434 | int eklen = 0, tkeylen = 0; | ||
| 435 | 426 | ||
| 436 | i=OBJ_obj2nid(p7->type); | 427 | i=OBJ_obj2nid(p7->type); |
| 437 | p7->state=PKCS7_S_HEADER; | 428 | p7->state=PKCS7_S_HEADER; |
| @@ -509,6 +500,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 509 | int max; | 500 | int max; |
| 510 | X509_OBJECT ret; | 501 | X509_OBJECT ret; |
| 511 | #endif | 502 | #endif |
| 503 | unsigned char *ek = NULL; | ||
| 504 | int eklen; | ||
| 512 | 505 | ||
| 513 | if ((etmp=BIO_new(BIO_f_cipher())) == NULL) | 506 | if ((etmp=BIO_new(BIO_f_cipher())) == NULL) |
| 514 | { | 507 | { |
| @@ -541,28 +534,29 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 541 | } | 534 | } |
| 542 | 535 | ||
| 543 | /* If we haven't got a certificate try each ri in turn */ | 536 | /* If we haven't got a certificate try each ri in turn */ |
| 537 | |||
| 544 | if (pcert == NULL) | 538 | if (pcert == NULL) |
| 545 | { | 539 | { |
| 546 | /* Always attempt to decrypt all rinfo even | ||
| 547 | * after sucess as a defence against MMA timing | ||
| 548 | * attacks. | ||
| 549 | */ | ||
| 550 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) | 540 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) |
| 551 | { | 541 | { |
| 552 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); | 542 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); |
| 553 | |||
| 554 | if (pkcs7_decrypt_rinfo(&ek, &eklen, | 543 | if (pkcs7_decrypt_rinfo(&ek, &eklen, |
| 555 | ri, pkey) < 0) | 544 | ri, pkey) > 0) |
| 556 | goto err; | 545 | break; |
| 557 | ERR_clear_error(); | 546 | ERR_clear_error(); |
| 547 | ri = NULL; | ||
| 548 | } | ||
| 549 | if (ri == NULL) | ||
| 550 | { | ||
| 551 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, | ||
| 552 | PKCS7_R_NO_RECIPIENT_MATCHES_KEY); | ||
| 553 | goto err; | ||
| 558 | } | 554 | } |
| 559 | } | 555 | } |
| 560 | else | 556 | else |
| 561 | { | 557 | { |
| 562 | /* Only exit on fatal errors, not decrypt failure */ | 558 | if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) <= 0) |
| 563 | if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) | ||
| 564 | goto err; | 559 | goto err; |
| 565 | ERR_clear_error(); | ||
| 566 | } | 560 | } |
| 567 | 561 | ||
| 568 | evp_ctx=NULL; | 562 | evp_ctx=NULL; |
| @@ -571,19 +565,6 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 571 | goto err; | 565 | goto err; |
| 572 | if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) | 566 | if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) |
| 573 | goto err; | 567 | goto err; |
| 574 | /* Generate random key as MMA defence */ | ||
| 575 | tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); | ||
| 576 | tkey = OPENSSL_malloc(tkeylen); | ||
| 577 | if (!tkey) | ||
| 578 | goto err; | ||
| 579 | if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) | ||
| 580 | goto err; | ||
| 581 | if (ek == NULL) | ||
| 582 | { | ||
| 583 | ek = tkey; | ||
| 584 | eklen = tkeylen; | ||
| 585 | tkey = NULL; | ||
| 586 | } | ||
| 587 | 568 | ||
| 588 | if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { | 569 | if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { |
| 589 | /* Some S/MIME clients don't use the same key | 570 | /* Some S/MIME clients don't use the same key |
| @@ -592,16 +573,11 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 592 | */ | 573 | */ |
| 593 | if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) | 574 | if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) |
| 594 | { | 575 | { |
| 595 | /* Use random key as MMA defence */ | 576 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, |
| 596 | OPENSSL_cleanse(ek, eklen); | 577 | PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); |
| 597 | OPENSSL_free(ek); | 578 | goto err; |
| 598 | ek = tkey; | ||
| 599 | eklen = tkeylen; | ||
| 600 | tkey = NULL; | ||
| 601 | } | 579 | } |
| 602 | } | 580 | } |
| 603 | /* Clear errors so we don't leak information useful in MMA */ | ||
| 604 | ERR_clear_error(); | ||
| 605 | if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0) | 581 | if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0) |
| 606 | goto err; | 582 | goto err; |
| 607 | 583 | ||
| @@ -609,13 +585,6 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 609 | { | 585 | { |
| 610 | OPENSSL_cleanse(ek,eklen); | 586 | OPENSSL_cleanse(ek,eklen); |
| 611 | OPENSSL_free(ek); | 587 | OPENSSL_free(ek); |
| 612 | ek = NULL; | ||
| 613 | } | ||
| 614 | if (tkey) | ||
| 615 | { | ||
| 616 | OPENSSL_cleanse(tkey,tkeylen); | ||
| 617 | OPENSSL_free(tkey); | ||
| 618 | tkey = NULL; | ||
| 619 | } | 588 | } |
| 620 | 589 | ||
| 621 | if (out == NULL) | 590 | if (out == NULL) |
| @@ -658,16 +627,6 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
| 658 | if (0) | 627 | if (0) |
| 659 | { | 628 | { |
| 660 | err: | 629 | err: |
| 661 | if (ek) | ||
| 662 | { | ||
| 663 | OPENSSL_cleanse(ek,eklen); | ||
| 664 | OPENSSL_free(ek); | ||
| 665 | } | ||
| 666 | if (tkey) | ||
| 667 | { | ||
| 668 | OPENSSL_cleanse(tkey,tkeylen); | ||
| 669 | OPENSSL_free(tkey); | ||
| 670 | } | ||
| 671 | if (out != NULL) BIO_free_all(out); | 630 | if (out != NULL) BIO_free_all(out); |
| 672 | if (btmp != NULL) BIO_free_all(btmp); | 631 | if (btmp != NULL) BIO_free_all(btmp); |
| 673 | if (etmp != NULL) BIO_free_all(etmp); | 632 | if (etmp != NULL) BIO_free_all(etmp); |
| @@ -717,11 +676,7 @@ static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) | |||
| 717 | } | 676 | } |
| 718 | 677 | ||
| 719 | /* Add digest */ | 678 | /* Add digest */ |
| 720 | if (!EVP_DigestFinal_ex(mctx, md_data,&md_len)) | 679 | EVP_DigestFinal_ex(mctx, md_data,&md_len); |
| 721 | { | ||
| 722 | PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB); | ||
| 723 | return 0; | ||
| 724 | } | ||
| 725 | if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) | 680 | if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) |
| 726 | { | 681 | { |
| 727 | PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); | 682 | PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); |
| @@ -829,8 +784,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
| 829 | 784 | ||
| 830 | /* We now have the EVP_MD_CTX, lets do the | 785 | /* We now have the EVP_MD_CTX, lets do the |
| 831 | * signing. */ | 786 | * signing. */ |
| 832 | if (!EVP_MD_CTX_copy_ex(&ctx_tmp,mdc)) | 787 | EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); |
| 833 | goto err; | ||
| 834 | 788 | ||
| 835 | sk=si->auth_attr; | 789 | sk=si->auth_attr; |
| 836 | 790 | ||
| @@ -868,8 +822,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
| 868 | if (!PKCS7_find_digest(&mdc, bio, | 822 | if (!PKCS7_find_digest(&mdc, bio, |
| 869 | OBJ_obj2nid(p7->d.digest->md->algorithm))) | 823 | OBJ_obj2nid(p7->d.digest->md->algorithm))) |
| 870 | goto err; | 824 | goto err; |
| 871 | if (!EVP_DigestFinal_ex(mdc,md_data,&md_len)) | 825 | EVP_DigestFinal_ex(mdc,md_data,&md_len); |
| 872 | goto err; | ||
| 873 | M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); | 826 | M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); |
| 874 | } | 827 | } |
| 875 | 828 | ||
| @@ -1062,8 +1015,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, | |||
| 1062 | 1015 | ||
| 1063 | /* mdc is the digest ctx that we want, unless there are attributes, | 1016 | /* mdc is the digest ctx that we want, unless there are attributes, |
| 1064 | * in which case the digest is the signed attributes */ | 1017 | * in which case the digest is the signed attributes */ |
| 1065 | if (!EVP_MD_CTX_copy_ex(&mdc_tmp,mdc)) | 1018 | EVP_MD_CTX_copy_ex(&mdc_tmp,mdc); |
| 1066 | goto err; | ||
| 1067 | 1019 | ||
| 1068 | sk=si->auth_attr; | 1020 | sk=si->auth_attr; |
| 1069 | if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) | 1021 | if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) |
| @@ -1073,8 +1025,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, | |||
| 1073 | int alen; | 1025 | int alen; |
| 1074 | ASN1_OCTET_STRING *message_digest; | 1026 | ASN1_OCTET_STRING *message_digest; |
| 1075 | 1027 | ||
| 1076 | if (!EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len)) | 1028 | EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len); |
| 1077 | goto err; | ||
| 1078 | message_digest=PKCS7_digest_from_attributes(sk); | 1029 | message_digest=PKCS7_digest_from_attributes(sk); |
| 1079 | if (!message_digest) | 1030 | if (!message_digest) |
| 1080 | { | 1031 | { |
| @@ -1099,8 +1050,7 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n"); | |||
| 1099 | goto err; | 1050 | goto err; |
| 1100 | } | 1051 | } |
| 1101 | 1052 | ||
| 1102 | if (!EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL)) | 1053 | EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL); |
| 1103 | goto err; | ||
| 1104 | 1054 | ||
| 1105 | alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, | 1055 | alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, |
| 1106 | ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); | 1056 | ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); |
| @@ -1110,8 +1060,7 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n"); | |||
| 1110 | ret = -1; | 1060 | ret = -1; |
| 1111 | goto err; | 1061 | goto err; |
| 1112 | } | 1062 | } |
| 1113 | if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen)) | 1063 | EVP_VerifyUpdate(&mdc_tmp, abuf, alen); |
| 1114 | goto err; | ||
| 1115 | 1064 | ||
| 1116 | OPENSSL_free(abuf); | 1065 | OPENSSL_free(abuf); |
| 1117 | } | 1066 | } |
