summaryrefslogtreecommitdiff
path: root/src/lib/libssl/src/crypto/pkcs7/pk7_doit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl/src/crypto/pkcs7/pk7_doit.c')
-rw-r--r--src/lib/libssl/src/crypto/pkcs7/pk7_doit.c101
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 {
629err: 660err:
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 }