diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/ssl_pkt.c | 115 |
1 files changed, 58 insertions, 57 deletions
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c index 157dd9895b..02282778a2 100644 --- a/src/lib/libssl/ssl_pkt.c +++ b/src/lib/libssl/ssl_pkt.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_pkt.c,v 1.24 2020/03/16 15:25:14 tb Exp $ */ | 1 | /* $OpenBSD: ssl_pkt.c,v 1.25 2020/07/30 16:53:01 jsing Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -622,18 +622,15 @@ ssl3_create_record(SSL *s, unsigned char *p, int type, const unsigned char *buf, | |||
| 622 | { | 622 | { |
| 623 | SSL3_RECORD_INTERNAL *wr = &(S3I(s)->wrec); | 623 | SSL3_RECORD_INTERNAL *wr = &(S3I(s)->wrec); |
| 624 | SSL_SESSION *sess = s->session; | 624 | SSL_SESSION *sess = s->session; |
| 625 | int eivlen, mac_size; | 625 | int eivlen, mac_size = 0; |
| 626 | uint16_t version; | 626 | uint16_t version; |
| 627 | CBB cbb; | 627 | CBB cbb; |
| 628 | 628 | ||
| 629 | memset(&cbb, 0, sizeof(cbb)); | 629 | memset(&cbb, 0, sizeof(cbb)); |
| 630 | 630 | ||
| 631 | if ((sess == NULL) || (s->internal->enc_write_ctx == NULL) || | 631 | if (sess != NULL && s->internal->enc_write_ctx != NULL && |
| 632 | (EVP_MD_CTX_md(s->internal->write_hash) == NULL)) { | 632 | EVP_MD_CTX_md(s->internal->write_hash) != NULL) { |
| 633 | mac_size = 0; | 633 | if ((mac_size = EVP_MD_CTX_size(s->internal->write_hash)) < 0) |
| 634 | } else { | ||
| 635 | mac_size = EVP_MD_CTX_size(s->internal->write_hash); | ||
| 636 | if (mac_size < 0) | ||
| 637 | goto err; | 634 | goto err; |
| 638 | } | 635 | } |
| 639 | 636 | ||
| @@ -682,9 +679,11 @@ ssl3_create_record(SSL *s, unsigned char *p, int type, const unsigned char *buf, | |||
| 682 | memcpy(wr->data, wr->input, wr->length); | 679 | memcpy(wr->data, wr->input, wr->length); |
| 683 | wr->input = wr->data; | 680 | wr->input = wr->data; |
| 684 | 681 | ||
| 685 | /* we should still have the output to wr->data and the input | 682 | /* |
| 683 | * We should still have the output to wr->data and the input | ||
| 686 | * from wr->input. Length should be wr->length. | 684 | * from wr->input. Length should be wr->length. |
| 687 | * wr->data still points in the wb->buf */ | 685 | * wr->data still points in the wb->buf. |
| 686 | */ | ||
| 688 | 687 | ||
| 689 | if (mac_size != 0) { | 688 | if (mac_size != 0) { |
| 690 | if (tls1_mac(s, &(p[wr->length + eivlen]), 1) < 0) | 689 | if (tls1_mac(s, &(p[wr->length + eivlen]), 1) < 0) |
| @@ -732,26 +731,29 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | |||
| 732 | SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf); | 731 | SSL3_BUFFER_INTERNAL *wb = &(S3I(s)->wbuf); |
| 733 | SSL_SESSION *sess = s->session; | 732 | SSL_SESSION *sess = s->session; |
| 734 | unsigned char *p; | 733 | unsigned char *p; |
| 735 | int i, clear = 0; | 734 | int need_empty_fragment = 0; |
| 736 | int prefix_len = 0; | 735 | int prefix_len = 0; |
| 737 | size_t align; | 736 | size_t align; |
| 737 | int ret; | ||
| 738 | 738 | ||
| 739 | if (wb->buf == NULL) | 739 | if (wb->buf == NULL) |
| 740 | if (!ssl3_setup_write_buffer(s)) | 740 | if (!ssl3_setup_write_buffer(s)) |
| 741 | return -1; | 741 | return -1; |
| 742 | 742 | ||
| 743 | /* first check if there is a SSL3_BUFFER_INTERNAL still being written | 743 | /* |
| 744 | * out. This will happen with non blocking IO */ | 744 | * First check if there is a SSL3_BUFFER_INTERNAL still being written |
| 745 | * out. This will happen with non blocking IO. | ||
| 746 | */ | ||
| 745 | if (wb->left != 0) | 747 | if (wb->left != 0) |
| 746 | return (ssl3_write_pending(s, type, buf, len)); | 748 | return (ssl3_write_pending(s, type, buf, len)); |
| 747 | 749 | ||
| 748 | /* If we have an alert to send, lets send it */ | 750 | /* If we have an alert to send, let's send it. */ |
| 749 | if (S3I(s)->alert_dispatch) { | 751 | if (S3I(s)->alert_dispatch) { |
| 750 | i = s->method->ssl_dispatch_alert(s); | 752 | if ((ret = s->method->ssl_dispatch_alert(s)) <= 0) |
| 751 | if (i <= 0) | 753 | return (ret); |
| 752 | return (i); | 754 | /* If it went, fall through and send more stuff. */ |
| 753 | /* if it went, fall through and send more stuff */ | 755 | |
| 754 | /* we may have released our buffer, so get it again */ | 756 | /* We may have released our buffer, if so get it again. */ |
| 755 | if (wb->buf == NULL) | 757 | if (wb->buf == NULL) |
| 756 | if (!ssl3_setup_write_buffer(s)) | 758 | if (!ssl3_setup_write_buffer(s)) |
| 757 | return -1; | 759 | return -1; |
| @@ -760,47 +762,44 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | |||
| 760 | if (len == 0) | 762 | if (len == 0) |
| 761 | return 0; | 763 | return 0; |
| 762 | 764 | ||
| 765 | /* | ||
| 766 | * Countermeasure against known-IV weakness in CBC ciphersuites | ||
| 767 | * (see http://www.openssl.org/~bodo/tls-cbc.txt). Note that this | ||
| 768 | * is unnecessary for AEAD. | ||
| 769 | */ | ||
| 770 | if (sess != NULL && s->internal->enc_write_ctx != NULL && | ||
| 771 | EVP_MD_CTX_md(s->internal->write_hash) != NULL) { | ||
| 772 | if (S3I(s)->need_empty_fragments && | ||
| 773 | !S3I(s)->empty_fragment_done && | ||
| 774 | type == SSL3_RT_APPLICATION_DATA) | ||
| 775 | need_empty_fragment = 1; | ||
| 776 | } | ||
| 777 | |||
| 778 | /* | ||
| 779 | * An extra fragment would be a couple of cipher blocks, which would | ||
| 780 | * be a multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real | ||
| 781 | * payload, then we can just simply pretend we have two headers. | ||
| 782 | */ | ||
| 763 | align = (size_t)wb->buf + SSL3_RT_HEADER_LENGTH; | 783 | align = (size_t)wb->buf + SSL3_RT_HEADER_LENGTH; |
| 784 | if (need_empty_fragment) | ||
| 785 | align += SSL3_RT_HEADER_LENGTH; | ||
| 764 | align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); | 786 | align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); |
| 765 | 787 | ||
| 766 | p = wb->buf + align; | 788 | p = wb->buf + align; |
| 767 | wb->offset = align; | 789 | wb->offset = align; |
| 768 | 790 | ||
| 769 | if ((sess == NULL) || (s->internal->enc_write_ctx == NULL) || | 791 | if (need_empty_fragment) { |
| 770 | (EVP_MD_CTX_md(s->internal->write_hash) == NULL)) { | 792 | if (!ssl3_create_record(s, p, type, buf, 0)) |
| 771 | clear = s->internal->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */ | 793 | goto err; |
| 772 | } | ||
| 773 | |||
| 774 | if (!clear && !S3I(s)->empty_fragment_done) { | ||
| 775 | /* | ||
| 776 | * Countermeasure against known-IV weakness in CBC ciphersuites | ||
| 777 | * (see http://www.openssl.org/~bodo/tls-cbc.txt) | ||
| 778 | */ | ||
| 779 | if (S3I(s)->need_empty_fragments && | ||
| 780 | type == SSL3_RT_APPLICATION_DATA) { | ||
| 781 | /* extra fragment would be couple of cipher blocks, | ||
| 782 | * which would be multiple of SSL3_ALIGN_PAYLOAD, so | ||
| 783 | * if we want to align the real payload, then we can | ||
| 784 | * just pretent we simply have two headers. */ | ||
| 785 | align = (size_t)wb->buf + 2 * SSL3_RT_HEADER_LENGTH; | ||
| 786 | align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); | ||
| 787 | |||
| 788 | p = wb->buf + align; | ||
| 789 | wb->offset = align; | ||
| 790 | |||
| 791 | if (!ssl3_create_record(s, p, type, buf, 0)) | ||
| 792 | goto err; | ||
| 793 | |||
| 794 | prefix_len = wr->length; | ||
| 795 | if (prefix_len > (SSL3_RT_HEADER_LENGTH + | ||
| 796 | SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) { | ||
| 797 | /* insufficient space */ | ||
| 798 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 799 | goto err; | ||
| 800 | } | ||
| 801 | 794 | ||
| 802 | p = wb->buf + wb->offset + prefix_len; | 795 | prefix_len = wr->length; |
| 796 | if (prefix_len > (SSL3_RT_HEADER_LENGTH + | ||
| 797 | SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) { | ||
| 798 | /* insufficient space */ | ||
| 799 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 800 | goto err; | ||
| 803 | } | 801 | } |
| 802 | p = wb->buf + wb->offset + prefix_len; | ||
| 804 | 803 | ||
| 805 | S3I(s)->empty_fragment_done = 1; | 804 | S3I(s)->empty_fragment_done = 1; |
| 806 | } | 805 | } |
| @@ -808,19 +807,21 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | |||
| 808 | if (!ssl3_create_record(s, p, type, buf, len)) | 807 | if (!ssl3_create_record(s, p, type, buf, len)) |
| 809 | goto err; | 808 | goto err; |
| 810 | 809 | ||
| 811 | /* now let's set up wb */ | ||
| 812 | wb->left = prefix_len + wr->length; | 810 | wb->left = prefix_len + wr->length; |
| 813 | 811 | ||
| 814 | /* memorize arguments so that ssl3_write_pending can detect | 812 | /* |
| 815 | * bad write retries later */ | 813 | * Memorize arguments so that ssl3_write_pending can detect |
| 814 | * bad write retries later. | ||
| 815 | */ | ||
| 816 | S3I(s)->wpend_tot = len; | 816 | S3I(s)->wpend_tot = len; |
| 817 | S3I(s)->wpend_buf = buf; | 817 | S3I(s)->wpend_buf = buf; |
| 818 | S3I(s)->wpend_type = type; | 818 | S3I(s)->wpend_type = type; |
| 819 | S3I(s)->wpend_ret = len; | 819 | S3I(s)->wpend_ret = len; |
| 820 | 820 | ||
| 821 | /* we now just need to write the buffer */ | 821 | /* We now just need to write the buffer. */ |
| 822 | return ssl3_write_pending(s, type, buf, len); | 822 | return ssl3_write_pending(s, type, buf, len); |
| 823 | err: | 823 | |
| 824 | err: | ||
| 824 | return -1; | 825 | return -1; |
| 825 | } | 826 | } |
| 826 | 827 | ||
