diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libssl/ssl_pkt.c | 192 |
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 | |||
818 | ssl3_read_handshake_unexpected(SSL *s) | 818 | ssl3_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 | ||