diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libssl/ssl_pkt.c | 195 |
1 files changed, 98 insertions, 97 deletions
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c index 2a0dd68acb..e7bbf37bcd 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.16 2019/03/19 16:53:03 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_pkt.c,v 1.17 2020/02/19 18:22:54 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 | * |
| @@ -120,7 +120,7 @@ | |||
| 120 | #include "bytestring.h" | 120 | #include "bytestring.h" |
| 121 | 121 | ||
| 122 | static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, | 122 | static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, |
| 123 | unsigned int len, int create_empty_fragment); | 123 | unsigned int len); |
| 124 | static int ssl3_get_record(SSL *s); | 124 | static int ssl3_get_record(SSL *s); |
| 125 | 125 | ||
| 126 | /* | 126 | /* |
| @@ -596,7 +596,7 @@ ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) | |||
| 596 | else | 596 | else |
| 597 | nw = n; | 597 | nw = n; |
| 598 | 598 | ||
| 599 | i = do_ssl3_write(s, type, &(buf[tot]), nw, 0); | 599 | i = do_ssl3_write(s, type, &(buf[tot]), nw); |
| 600 | if (i <= 0) { | 600 | if (i <= 0) { |
| 601 | S3I(s)->wnum = tot; | 601 | S3I(s)->wnum = tot; |
| 602 | return i; | 602 | return i; |
| @@ -620,44 +620,14 @@ ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) | |||
| 620 | } | 620 | } |
| 621 | 621 | ||
| 622 | static int | 622 | static int |
| 623 | do_ssl3_write(SSL *s, int type, const unsigned char *buf, | 623 | ssl3_create_record(SSL *s, unsigned char *p, int type, const unsigned char *buf, |
| 624 | unsigned int len, int create_empty_fragment) | 624 | unsigned int len) |
| 625 | { | 625 | { |
| 626 | unsigned char *p, *plen; | 626 | SSL3_RECORD *wr = &(S3I(s)->wrec); |
| 627 | int i, mac_size, clear = 0; | 627 | SSL_SESSION *sess = s->session; |
| 628 | int prefix_len = 0; | 628 | unsigned char *plen; |
| 629 | int eivlen; | 629 | int eivlen, mac_size; |
| 630 | size_t align; | 630 | int clear = 0; |
| 631 | SSL3_RECORD *wr; | ||
| 632 | SSL3_BUFFER *wb = &(S3I(s)->wbuf); | ||
| 633 | SSL_SESSION *sess; | ||
| 634 | |||
| 635 | if (wb->buf == NULL) | ||
| 636 | if (!ssl3_setup_write_buffer(s)) | ||
| 637 | return -1; | ||
| 638 | |||
| 639 | /* first check if there is a SSL3_BUFFER still being written | ||
| 640 | * out. This will happen with non blocking IO */ | ||
| 641 | if (wb->left != 0) | ||
| 642 | return (ssl3_write_pending(s, type, buf, len)); | ||
| 643 | |||
| 644 | /* If we have an alert to send, lets send it */ | ||
| 645 | if (S3I(s)->alert_dispatch) { | ||
| 646 | i = s->method->ssl_dispatch_alert(s); | ||
| 647 | if (i <= 0) | ||
| 648 | return (i); | ||
| 649 | /* if it went, fall through and send more stuff */ | ||
| 650 | /* we may have released our buffer, so get it again */ | ||
| 651 | if (wb->buf == NULL) | ||
| 652 | if (!ssl3_setup_write_buffer(s)) | ||
| 653 | return -1; | ||
| 654 | } | ||
| 655 | |||
| 656 | if (len == 0 && !create_empty_fragment) | ||
| 657 | return 0; | ||
| 658 | |||
| 659 | wr = &(S3I(s)->wrec); | ||
| 660 | sess = s->session; | ||
| 661 | 631 | ||
| 662 | if ((sess == NULL) || (s->internal->enc_write_ctx == NULL) || | 632 | if ((sess == NULL) || (s->internal->enc_write_ctx == NULL) || |
| 663 | (EVP_MD_CTX_md(s->internal->write_hash) == NULL)) { | 633 | (EVP_MD_CTX_md(s->internal->write_hash) == NULL)) { |
| @@ -669,56 +639,6 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, | |||
| 669 | goto err; | 639 | goto err; |
| 670 | } | 640 | } |
| 671 | 641 | ||
| 672 | /* | ||
| 673 | * 'create_empty_fragment' is true only when this function calls | ||
| 674 | * itself. | ||
| 675 | */ | ||
| 676 | if (!clear && !create_empty_fragment && !S3I(s)->empty_fragment_done) { | ||
| 677 | /* | ||
| 678 | * Countermeasure against known-IV weakness in CBC ciphersuites | ||
| 679 | * (see http://www.openssl.org/~bodo/tls-cbc.txt) | ||
| 680 | */ | ||
| 681 | if (S3I(s)->need_empty_fragments && | ||
| 682 | type == SSL3_RT_APPLICATION_DATA) { | ||
| 683 | /* recursive function call with 'create_empty_fragment' set; | ||
| 684 | * this prepares and buffers the data for an empty fragment | ||
| 685 | * (these 'prefix_len' bytes are sent out later | ||
| 686 | * together with the actual payload) */ | ||
| 687 | prefix_len = do_ssl3_write(s, type, buf, 0, 1); | ||
| 688 | if (prefix_len <= 0) | ||
| 689 | goto err; | ||
| 690 | |||
| 691 | if (prefix_len > | ||
| 692 | (SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) { | ||
| 693 | /* insufficient space */ | ||
| 694 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 695 | goto err; | ||
| 696 | } | ||
| 697 | } | ||
| 698 | |||
| 699 | S3I(s)->empty_fragment_done = 1; | ||
| 700 | } | ||
| 701 | |||
| 702 | if (create_empty_fragment) { | ||
| 703 | /* extra fragment would be couple of cipher blocks, | ||
| 704 | * which would be multiple of SSL3_ALIGN_PAYLOAD, so | ||
| 705 | * if we want to align the real payload, then we can | ||
| 706 | * just pretent we simply have two headers. */ | ||
| 707 | align = (size_t)wb->buf + 2 * SSL3_RT_HEADER_LENGTH; | ||
| 708 | align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); | ||
| 709 | |||
| 710 | p = wb->buf + align; | ||
| 711 | wb->offset = align; | ||
| 712 | } else if (prefix_len) { | ||
| 713 | p = wb->buf + wb->offset + prefix_len; | ||
| 714 | } else { | ||
| 715 | align = (size_t)wb->buf + SSL3_RT_HEADER_LENGTH; | ||
| 716 | align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); | ||
| 717 | |||
| 718 | p = wb->buf + align; | ||
| 719 | wb->offset = align; | ||
| 720 | } | ||
| 721 | |||
| 722 | /* write the header */ | 642 | /* write the header */ |
| 723 | 643 | ||
| 724 | *(p++) = type&0xff; | 644 | *(p++) = type&0xff; |
| @@ -767,8 +687,7 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, | |||
| 767 | * wr->data still points in the wb->buf */ | 687 | * wr->data still points in the wb->buf */ |
| 768 | 688 | ||
| 769 | if (mac_size != 0) { | 689 | if (mac_size != 0) { |
| 770 | if (tls1_mac(s, | 690 | if (tls1_mac(s, &(p[wr->length + eivlen]), 1) < 0) |
| 771 | &(p[wr->length + eivlen]), 1) < 0) | ||
| 772 | goto err; | 691 | goto err; |
| 773 | wr->length += mac_size; | 692 | wr->length += mac_size; |
| 774 | } | 693 | } |
| @@ -795,13 +714,95 @@ do_ssl3_write(SSL *s, int type, const unsigned char *buf, | |||
| 795 | wr->type=type; /* not needed but helps for debugging */ | 714 | wr->type=type; /* not needed but helps for debugging */ |
| 796 | wr->length += SSL3_RT_HEADER_LENGTH; | 715 | wr->length += SSL3_RT_HEADER_LENGTH; |
| 797 | 716 | ||
| 798 | if (create_empty_fragment) { | 717 | return 1; |
| 799 | /* we are in a recursive call; | 718 | |
| 800 | * just return the length, don't write out anything here | 719 | err: |
| 720 | return 0; | ||
| 721 | } | ||
| 722 | |||
| 723 | static int | ||
| 724 | do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len) | ||
| 725 | { | ||
| 726 | SSL3_RECORD *wr = &(S3I(s)->wrec); | ||
| 727 | SSL3_BUFFER *wb = &(S3I(s)->wbuf); | ||
| 728 | SSL_SESSION *sess = s->session; | ||
| 729 | unsigned char *p; | ||
| 730 | int i, clear = 0; | ||
| 731 | int prefix_len = 0; | ||
| 732 | size_t align; | ||
| 733 | |||
| 734 | if (wb->buf == NULL) | ||
| 735 | if (!ssl3_setup_write_buffer(s)) | ||
| 736 | return -1; | ||
| 737 | |||
| 738 | /* first check if there is a SSL3_BUFFER still being written | ||
| 739 | * out. This will happen with non blocking IO */ | ||
| 740 | if (wb->left != 0) | ||
| 741 | return (ssl3_write_pending(s, type, buf, len)); | ||
| 742 | |||
| 743 | /* If we have an alert to send, lets send it */ | ||
| 744 | if (S3I(s)->alert_dispatch) { | ||
| 745 | i = s->method->ssl_dispatch_alert(s); | ||
| 746 | if (i <= 0) | ||
| 747 | return (i); | ||
| 748 | /* if it went, fall through and send more stuff */ | ||
| 749 | /* we may have released our buffer, so get it again */ | ||
| 750 | if (wb->buf == NULL) | ||
| 751 | if (!ssl3_setup_write_buffer(s)) | ||
| 752 | return -1; | ||
| 753 | } | ||
| 754 | |||
| 755 | if (len == 0) | ||
| 756 | return 0; | ||
| 757 | |||
| 758 | align = (size_t)wb->buf + SSL3_RT_HEADER_LENGTH; | ||
| 759 | align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); | ||
| 760 | |||
| 761 | p = wb->buf + align; | ||
| 762 | wb->offset = align; | ||
| 763 | |||
| 764 | if ((sess == NULL) || (s->internal->enc_write_ctx == NULL) || | ||
| 765 | (EVP_MD_CTX_md(s->internal->write_hash) == NULL)) { | ||
| 766 | clear = s->internal->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */ | ||
| 767 | } | ||
| 768 | |||
| 769 | if (!clear && !S3I(s)->empty_fragment_done) { | ||
| 770 | /* | ||
| 771 | * Countermeasure against known-IV weakness in CBC ciphersuites | ||
| 772 | * (see http://www.openssl.org/~bodo/tls-cbc.txt) | ||
| 801 | */ | 773 | */ |
| 802 | return wr->length; | 774 | if (S3I(s)->need_empty_fragments && |
| 775 | type == SSL3_RT_APPLICATION_DATA) { | ||
| 776 | /* extra fragment would be couple of cipher blocks, | ||
| 777 | * which would be multiple of SSL3_ALIGN_PAYLOAD, so | ||
| 778 | * if we want to align the real payload, then we can | ||
| 779 | * just pretent we simply have two headers. */ | ||
| 780 | align = (size_t)wb->buf + 2 * SSL3_RT_HEADER_LENGTH; | ||
| 781 | align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); | ||
| 782 | |||
| 783 | p = wb->buf + align; | ||
| 784 | wb->offset = align; | ||
| 785 | |||
| 786 | if (!ssl3_create_record(s, p, type, buf, 0)) | ||
| 787 | goto err; | ||
| 788 | |||
| 789 | prefix_len = wr->length; | ||
| 790 | if (prefix_len > (SSL3_RT_HEADER_LENGTH + | ||
| 791 | SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) { | ||
| 792 | /* insufficient space */ | ||
| 793 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
| 794 | goto err; | ||
| 795 | } | ||
| 796 | |||
| 797 | p = wb->buf + wb->offset + prefix_len; | ||
| 798 | } | ||
| 799 | |||
| 800 | S3I(s)->empty_fragment_done = 1; | ||
| 803 | } | 801 | } |
| 804 | 802 | ||
| 803 | if (!ssl3_create_record(s, p, type, buf, len)) | ||
| 804 | goto err; | ||
| 805 | |||
| 805 | /* now let's set up wb */ | 806 | /* now let's set up wb */ |
| 806 | wb->left = prefix_len + wr->length; | 807 | wb->left = prefix_len + wr->length; |
| 807 | 808 | ||
| @@ -1421,7 +1422,7 @@ ssl3_dispatch_alert(SSL *s) | |||
| 1421 | void (*cb)(const SSL *ssl, int type, int val) = NULL; | 1422 | void (*cb)(const SSL *ssl, int type, int val) = NULL; |
| 1422 | 1423 | ||
| 1423 | S3I(s)->alert_dispatch = 0; | 1424 | S3I(s)->alert_dispatch = 0; |
| 1424 | i = do_ssl3_write(s, SSL3_RT_ALERT, &S3I(s)->send_alert[0], 2, 0); | 1425 | i = do_ssl3_write(s, SSL3_RT_ALERT, &S3I(s)->send_alert[0], 2); |
| 1425 | if (i <= 0) { | 1426 | if (i <= 0) { |
| 1426 | S3I(s)->alert_dispatch = 1; | 1427 | S3I(s)->alert_dispatch = 1; |
| 1427 | } else { | 1428 | } else { |
