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