diff options
author | jsing <> | 2022-11-10 18:06:37 +0000 |
---|---|---|
committer | jsing <> | 2022-11-10 18:06:37 +0000 |
commit | 3fbacf810de490214fc4dba0b34a532906eadfac (patch) | |
tree | 1c172cf5ae25ab26fa6f64cb114505e1bfcc1267 /src/lib/libssl/ssl_pkt.c | |
parent | 67d2b90781cde981c11f7630740bca9847e85165 (diff) | |
download | openbsd-3fbacf810de490214fc4dba0b34a532906eadfac.tar.gz openbsd-3fbacf810de490214fc4dba0b34a532906eadfac.tar.bz2 openbsd-3fbacf810de490214fc4dba0b34a532906eadfac.zip |
Use tls_buffer for alert and handshake fragments in the legacy stack.
This avoids a bunch of pointer munging and a handrolled memmove.
ok tb@
Diffstat (limited to 'src/lib/libssl/ssl_pkt.c')
-rw-r--r-- | src/lib/libssl/ssl_pkt.c | 108 |
1 files changed, 69 insertions, 39 deletions
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c index ddb2ce0935..58d3ee1db2 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.62 2022/10/21 15:48:14 tb Exp $ */ | 1 | /* $OpenBSD: ssl_pkt.c,v 1.63 2022/11/10 18:06:37 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 | * |
@@ -688,11 +688,32 @@ ssl3_write_pending(SSL *s, int type, const unsigned char *buf, unsigned int len) | |||
688 | } | 688 | } |
689 | } | 689 | } |
690 | 690 | ||
691 | static ssize_t | ||
692 | ssl3_read_cb(void *buf, size_t n, void *cb_arg) | ||
693 | { | ||
694 | SSL3_RECORD_INTERNAL *rr; | ||
695 | SSL *s = cb_arg; | ||
696 | |||
697 | rr = &s->s3->rrec; | ||
698 | |||
699 | if (n > rr->length) | ||
700 | n = rr->length; | ||
701 | |||
702 | memcpy(buf, &rr->data[rr->off], n); | ||
703 | |||
704 | rr->off += n; | ||
705 | rr->length -= n; | ||
706 | |||
707 | return n; | ||
708 | } | ||
709 | |||
710 | #define SSL3_ALERT_LENGTH 2 | ||
711 | |||
691 | int | 712 | int |
692 | ssl3_read_alert(SSL *s) | 713 | ssl3_read_alert(SSL *s) |
693 | { | 714 | { |
694 | SSL3_RECORD_INTERNAL *rr = &s->s3->rrec; | ||
695 | uint8_t alert_level, alert_descr; | 715 | uint8_t alert_level, alert_descr; |
716 | ssize_t ret; | ||
696 | CBS cbs; | 717 | CBS cbs; |
697 | 718 | ||
698 | /* | 719 | /* |
@@ -702,13 +723,17 @@ ssl3_read_alert(SSL *s) | |||
702 | * fragmented across multiple records, hence a full alert must be | 723 | * fragmented across multiple records, hence a full alert must be |
703 | * available in the record. | 724 | * available in the record. |
704 | */ | 725 | */ |
705 | while (rr->length > 0 && | 726 | if (s->s3->alert_fragment == NULL) { |
706 | s->s3->alert_fragment_len < sizeof(s->s3->alert_fragment)) { | 727 | if ((s->s3->alert_fragment = tls_buffer_new(0)) == NULL) |
707 | s->s3->alert_fragment[s->s3->alert_fragment_len++] = | 728 | return -1; |
708 | rr->data[rr->off++]; | 729 | tls_buffer_set_capacity_limit(s->s3->alert_fragment, |
709 | rr->length--; | 730 | SSL3_ALERT_LENGTH); |
710 | } | 731 | } |
711 | if (s->s3->alert_fragment_len < sizeof(s->s3->alert_fragment)) { | 732 | ret = tls_buffer_extend(s->s3->alert_fragment, SSL3_ALERT_LENGTH, |
733 | ssl3_read_cb, s); | ||
734 | if (ret <= 0 && ret != TLS_IO_WANT_POLLIN) | ||
735 | return -1; | ||
736 | if (ret != SSL3_ALERT_LENGTH) { | ||
712 | if (SSL_is_dtls(s)) { | 737 | if (SSL_is_dtls(s)) { |
713 | SSLerror(s, SSL_R_BAD_LENGTH); | 738 | SSLerror(s, SSL_R_BAD_LENGTH); |
714 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); | 739 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); |
@@ -717,7 +742,8 @@ ssl3_read_alert(SSL *s) | |||
717 | return 1; | 742 | return 1; |
718 | } | 743 | } |
719 | 744 | ||
720 | CBS_init(&cbs, s->s3->alert_fragment, sizeof(s->s3->alert_fragment)); | 745 | if (!tls_buffer_data(s->s3->alert_fragment, &cbs)) |
746 | return -1; | ||
721 | 747 | ||
722 | ssl_msg_callback_cbs(s, 0, SSL3_RT_ALERT, &cbs); | 748 | ssl_msg_callback_cbs(s, 0, SSL3_RT_ALERT, &cbs); |
723 | 749 | ||
@@ -726,7 +752,8 @@ ssl3_read_alert(SSL *s) | |||
726 | if (!CBS_get_u8(&cbs, &alert_descr)) | 752 | if (!CBS_get_u8(&cbs, &alert_descr)) |
727 | return -1; | 753 | return -1; |
728 | 754 | ||
729 | s->s3->alert_fragment_len = 0; | 755 | tls_buffer_free(s->s3->alert_fragment); |
756 | s->s3->alert_fragment = NULL; | ||
730 | 757 | ||
731 | ssl_info_callback(s, SSL_CB_READ_ALERT, | 758 | ssl_info_callback(s, SSL_CB_READ_ALERT, |
732 | (alert_level << 8) | alert_descr); | 759 | (alert_level << 8) | alert_descr); |
@@ -829,9 +856,9 @@ ssl3_read_change_cipher_spec(SSL *s) | |||
829 | static int | 856 | static int |
830 | ssl3_read_handshake_unexpected(SSL *s) | 857 | ssl3_read_handshake_unexpected(SSL *s) |
831 | { | 858 | { |
832 | SSL3_RECORD_INTERNAL *rr = &s->s3->rrec; | ||
833 | uint32_t hs_msg_length; | 859 | uint32_t hs_msg_length; |
834 | uint8_t hs_msg_type; | 860 | uint8_t hs_msg_type; |
861 | ssize_t ssret; | ||
835 | CBS cbs; | 862 | CBS cbs; |
836 | int ret; | 863 | int ret; |
837 | 864 | ||
@@ -840,14 +867,17 @@ ssl3_read_handshake_unexpected(SSL *s) | |||
840 | * header - this may be in the same record or fragmented across multiple | 867 | * header - this may be in the same record or fragmented across multiple |
841 | * records. | 868 | * records. |
842 | */ | 869 | */ |
843 | while (rr->length > 0 && | 870 | if (s->s3->handshake_fragment == NULL) { |
844 | s->s3->handshake_fragment_len < sizeof(s->s3->handshake_fragment)) { | 871 | if ((s->s3->handshake_fragment = tls_buffer_new(0)) == NULL) |
845 | s->s3->handshake_fragment[s->s3->handshake_fragment_len++] = | 872 | return -1; |
846 | rr->data[rr->off++]; | 873 | tls_buffer_set_capacity_limit(s->s3->handshake_fragment, |
847 | rr->length--; | 874 | SSL3_HM_HEADER_LENGTH); |
848 | } | 875 | } |
849 | 876 | ssret = tls_buffer_extend(s->s3->handshake_fragment, SSL3_HM_HEADER_LENGTH, | |
850 | if (s->s3->handshake_fragment_len < sizeof(s->s3->handshake_fragment)) | 877 | ssl3_read_cb, s); |
878 | if (ssret <= 0 && ssret != TLS_IO_WANT_POLLIN) | ||
879 | return -1; | ||
880 | if (ssret != SSL3_HM_HEADER_LENGTH) | ||
851 | return 1; | 881 | return 1; |
852 | 882 | ||
853 | if (s->in_handshake) { | 883 | if (s->in_handshake) { |
@@ -862,7 +892,8 @@ ssl3_read_handshake_unexpected(SSL *s) | |||
862 | */ | 892 | */ |
863 | 893 | ||
864 | /* Parse handshake message header. */ | 894 | /* Parse handshake message header. */ |
865 | CBS_init(&cbs, s->s3->handshake_fragment, s->s3->handshake_fragment_len); | 895 | if (!tls_buffer_data(s->s3->handshake_fragment, &cbs)) |
896 | return -1; | ||
866 | if (!CBS_get_u8(&cbs, &hs_msg_type)) | 897 | if (!CBS_get_u8(&cbs, &hs_msg_type)) |
867 | return -1; | 898 | return -1; |
868 | if (!CBS_get_u24(&cbs, &hs_msg_length)) | 899 | if (!CBS_get_u24(&cbs, &hs_msg_length)) |
@@ -888,10 +919,12 @@ ssl3_read_handshake_unexpected(SSL *s) | |||
888 | return -1; | 919 | return -1; |
889 | } | 920 | } |
890 | 921 | ||
891 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, | 922 | if (!tls_buffer_data(s->s3->handshake_fragment, &cbs)) |
892 | s->s3->handshake_fragment, s->s3->handshake_fragment_len); | 923 | return -1; |
924 | ssl_msg_callback_cbs(s, 0, SSL3_RT_HANDSHAKE, &cbs); | ||
893 | 925 | ||
894 | s->s3->handshake_fragment_len = 0; | 926 | tls_buffer_free(s->s3->handshake_fragment); |
927 | s->s3->handshake_fragment = NULL; | ||
895 | 928 | ||
896 | /* | 929 | /* |
897 | * It should be impossible to hit this, but keep the safety | 930 | * It should be impossible to hit this, but keep the safety |
@@ -1045,24 +1078,21 @@ ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
1045 | return -1; | 1078 | return -1; |
1046 | } | 1079 | } |
1047 | 1080 | ||
1048 | if (type == SSL3_RT_HANDSHAKE && s->s3->handshake_fragment_len > 0) { | 1081 | if (type == SSL3_RT_HANDSHAKE && |
1049 | /* Partially satisfy request from fragment storage. */ | 1082 | s->s3->handshake_fragment != NULL && |
1050 | unsigned char *src = s->s3->handshake_fragment; | 1083 | tls_buffer_remaining(s->s3->handshake_fragment) > 0) { |
1051 | unsigned char *dst = buf; | 1084 | ssize_t ssn; |
1052 | unsigned int k; | 1085 | |
1053 | 1086 | if ((ssn = tls_buffer_read(s->s3->handshake_fragment, buf, | |
1054 | /* peek == 0 */ | 1087 | len)) <= 0) |
1055 | n = 0; | 1088 | return -1; |
1056 | while (len > 0 && s->s3->handshake_fragment_len > 0) { | 1089 | |
1057 | *dst++ = *src++; | 1090 | if (tls_buffer_remaining(s->s3->handshake_fragment) == 0) { |
1058 | len--; | 1091 | tls_buffer_free(s->s3->handshake_fragment); |
1059 | s->s3->handshake_fragment_len--; | 1092 | s->s3->handshake_fragment = NULL; |
1060 | n++; | ||
1061 | } | 1093 | } |
1062 | /* move any remaining fragment bytes: */ | 1094 | |
1063 | for (k = 0; k < s->s3->handshake_fragment_len; k++) | 1095 | return (int)ssn; |
1064 | s->s3->handshake_fragment[k] = *src++; | ||
1065 | return n; | ||
1066 | } | 1096 | } |
1067 | 1097 | ||
1068 | if (SSL_in_init(s) && !s->in_handshake) { | 1098 | if (SSL_in_init(s) && !s->in_handshake) { |