summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2022-03-17 17:28:08 +0000
committerjsing <>2022-03-17 17:28:08 +0000
commite43f72664814b516c70029cf02fd7327521d8b80 (patch)
tree37d11738d2dfcfb9ba174aad716f2b29740674fd
parent296c22446a2c3bd5088375546bc4afc9b6fda98b (diff)
downloadopenbsd-e43f72664814b516c70029cf02fd7327521d8b80.tar.gz
openbsd-e43f72664814b516c70029cf02fd7327521d8b80.tar.bz2
openbsd-e43f72664814b516c70029cf02fd7327521d8b80.zip
Rewrite legacy TLS unexpected handshake message handling.
Rewrite the code that handles unexpected handshake messages in the legacy TLS stack. Parse the TLS message header up front, then process it based on the message type. Overall the code should be more strict and we should reject various invalid messages that would have previously been accepted. I also reviewed steve's experimental code and fixed the bug that it contained. ok inoguchi@ tb@
-rw-r--r--src/lib/libssl/ssl_pkt.c192
1 files changed, 114 insertions, 78 deletions
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c
index 4dc7f3b610..57230f8fae 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.56 2022/03/14 16:49:35 jsing Exp $ */ 1/* $OpenBSD: ssl_pkt.c,v 1.57 2022/03/17 17:28:08 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 *
@@ -818,7 +818,10 @@ static int
818ssl3_read_handshake_unexpected(SSL *s) 818ssl3_read_handshake_unexpected(SSL *s)
819{ 819{
820 SSL3_RECORD_INTERNAL *rr = &s->s3->rrec; 820 SSL3_RECORD_INTERNAL *rr = &s->s3->rrec;
821 int i; 821 uint32_t hs_msg_length;
822 uint8_t hs_msg_type;
823 CBS cbs;
824 int ret;
822 825
823 /* 826 /*
824 * We need four bytes of handshake data so we have a handshake message 827 * We need four bytes of handshake data so we have a handshake message
@@ -846,99 +849,132 @@ ssl3_read_handshake_unexpected(SSL *s)
846 * belongs in the client/server handshake code. 849 * belongs in the client/server handshake code.
847 */ 850 */
848 851
849 /* If we are a client, check for an incoming 'Hello Request': */ 852 /* Parse handshake message header. */
850 if ((!s->server) && (s->s3->handshake_fragment_len >= 4) && 853 CBS_init(&cbs, s->s3->handshake_fragment, s->s3->handshake_fragment_len);
851 (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && 854 if (!CBS_get_u8(&cbs, &hs_msg_type))
852 (s->session != NULL) && (s->session->cipher != NULL)) { 855 return -1;
853 s->s3->handshake_fragment_len = 0; 856 if (!CBS_get_u24(&cbs, &hs_msg_length))
857 return -1;
858
859 if (hs_msg_type == SSL3_MT_HELLO_REQUEST) {
860 /*
861 * Incoming HelloRequest messages should only be received by a
862 * client. A server may send these at any time - a client should
863 * ignore the message if received in the middle of a handshake.
864 * See RFC 5246 sections 7.4 and 7.4.1.1.
865 */
866 if (s->server) {
867 SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
868 ssl3_send_alert(s, SSL3_AL_FATAL,
869 SSL_AD_UNEXPECTED_MESSAGE);
870 return -1;
871 }
854 872
855 if ((s->s3->handshake_fragment[1] != 0) || 873 if (hs_msg_length != 0) {
856 (s->s3->handshake_fragment[2] != 0) ||
857 (s->s3->handshake_fragment[3] != 0)) {
858 SSLerror(s, SSL_R_BAD_HELLO_REQUEST); 874 SSLerror(s, SSL_R_BAD_HELLO_REQUEST);
859 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); 875 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
860 return -1; 876 return -1;
861 } 877 }
862 878
863 ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, 879 ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE,
864 s->s3->handshake_fragment, 4); 880 s->s3->handshake_fragment, s->s3->handshake_fragment_len);
865 881
866 if (SSL_is_init_finished(s) && 882 s->s3->handshake_fragment_len = 0;
867 !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && 883
868 !s->s3->renegotiate) { 884 /*
869 ssl3_renegotiate(s); 885 * It should be impossible to hit this, but keep the safety
870 if (ssl3_renegotiate_check(s)) { 886 * harness for now...
871 i = s->internal->handshake_func(s); 887 */
872 if (i < 0) 888 if (s->session == NULL || s->session->cipher == NULL)
873 return (i); 889 return 1;
874 if (i == 0) { 890
875 SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); 891 /*
876 return (-1); 892 * Ignore this message if we're currently handshaking,
877 } 893 * renegotiation is already pending or renegotiation is disabled
878 894 * via flags.
879 if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { 895 */
880 if (s->s3->rbuf.left == 0) { 896 if (!SSL_is_init_finished(s) || s->s3->renegotiate ||
881 ssl_force_want_read(s); 897 (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) != 0)
882 return (-1); 898 return 1;
883 } 899
884 } 900 if (!ssl3_renegotiate(s))
885 } 901 return 1;
902 if (!ssl3_renegotiate_check(s))
903 return 1;
904
905 } else if (hs_msg_type == SSL3_MT_CLIENT_HELLO) {
906 /*
907 * Incoming ClientHello messages should only be received by a
908 * server. A client may send these in response to server
909 * initiated renegotiation (HelloRequest) or in order to
910 * initiate renegotiation by the client. See RFC 5246 section
911 * 7.4.1.2.
912 */
913 if (!s->server) {
914 SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
915 ssl3_send_alert(s, SSL3_AL_FATAL,
916 SSL_AD_UNEXPECTED_MESSAGE);
917 return -1;
886 } 918 }
887 /* we either finished a handshake or ignored the request,
888 * now try again to obtain the (application) data we were asked for */
889 return 1;
890 }
891 919
892 /* Disallow client initiated renegotiation if configured. */ 920 /*
893 if (s->server && SSL_is_init_finished(s) && 921 * A client should not be sending a ClientHello unless we're not
894 s->s3->handshake_fragment_len >= 4 && 922 * currently handshaking.
895 s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO && 923 */
896 (s->internal->options & SSL_OP_NO_CLIENT_RENEGOTIATION)) { 924 if (!SSL_is_init_finished(s)) {
897 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION); 925 SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
898 return -1; 926 ssl3_send_alert(s, SSL3_AL_FATAL,
899 } 927 SSL_AD_UNEXPECTED_MESSAGE);
928 return -1;
929 }
900 930
901 /* If we are a server and get a client hello when renegotiation isn't 931 if ((s->internal->options & SSL_OP_NO_CLIENT_RENEGOTIATION) != 0) {
902 * allowed send back a no renegotiation alert and carry on. 932 ssl3_send_alert(s, SSL3_AL_FATAL,
903 * WARNING: experimental code, needs reviewing (steve) 933 SSL_AD_NO_RENEGOTIATION);
904 */ 934 return -1;
905 if (s->server && 935 }
906 SSL_is_init_finished(s) &&
907 !s->s3->send_connection_binding &&
908 (s->s3->handshake_fragment_len >= 4) &&
909 (s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
910 (s->session != NULL) && (s->session->cipher != NULL)) {
911 /*s->s3->handshake_fragment_len = 0;*/
912 rr->length = 0;
913 ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
914 return 1;
915 }
916 936
917 /* Unexpected handshake message (Client Hello, or protocol violation) */ 937 if (s->session == NULL || s->session->cipher == NULL) {
918 if ((s->s3->handshake_fragment_len >= 4) && !s->internal->in_handshake) { 938 SSLerror(s, ERR_R_INTERNAL_ERROR);
919 if (((s->s3->hs.state&SSL_ST_MASK) == SSL_ST_OK) && 939 return -1;
920 !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) {
921 s->s3->hs.state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
922 s->internal->renegotiate = 1;
923 s->internal->new_session = 1;
924 } 940 }
925 i = s->internal->handshake_func(s); 941
926 if (i < 0) 942 /* Client requested renegotiation but it is not permitted. */
927 return (i); 943 if (!s->s3->send_connection_binding ||
928 if (i == 0) { 944 (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) != 0) {
929 SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); 945 ssl3_send_alert(s, SSL3_AL_WARNING,
930 return (-1); 946 SSL_AD_NO_RENEGOTIATION);
947 return 1;
931 } 948 }
932 949
933 if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { 950 s->s3->hs.state = SSL_ST_ACCEPT;
934 if (s->s3->rbuf.left == 0) { 951 s->internal->renegotiate = 1;
935 ssl_force_want_read(s); 952 s->internal->new_session = 1;
936 return (-1); 953
937 } 954 } else {
955 SSLerror(s, SSL_R_UNEXPECTED_MESSAGE);
956 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
957 return -1;
958 }
959
960 if ((ret = s->internal->handshake_func(s)) < 0)
961 return ret;
962 if (ret == 0) {
963 SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE);
964 return -1;
965 }
966
967 if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) {
968 if (s->s3->rbuf.left == 0) {
969 ssl_force_want_read(s);
970 return -1;
938 } 971 }
939 return 1;
940 } 972 }
941 973
974 /*
975 * We either finished a handshake or ignored the request, now try again
976 * to obtain the (application) data we were asked for.
977 */
942 return 1; 978 return 1;
943} 979}
944 980