diff options
Diffstat (limited to 'src/lib/libssl/ssl_pkt.c')
-rw-r--r-- | src/lib/libssl/ssl_pkt.c | 263 |
1 files changed, 135 insertions, 128 deletions
diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c index 33bb4b659f..4dc7f3b610 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.55 2022/03/12 12:53:03 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_pkt.c,v 1.56 2022/03/14 16:49:35 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 | * |
@@ -814,6 +814,134 @@ ssl3_read_change_cipher_spec(SSL *s) | |||
814 | return 1; | 814 | return 1; |
815 | } | 815 | } |
816 | 816 | ||
817 | static int | ||
818 | ssl3_read_handshake_unexpected(SSL *s) | ||
819 | { | ||
820 | SSL3_RECORD_INTERNAL *rr = &s->s3->rrec; | ||
821 | int i; | ||
822 | |||
823 | /* | ||
824 | * We need four bytes of handshake data so we have a handshake message | ||
825 | * header - this may be in the same record or fragmented across multiple | ||
826 | * records. | ||
827 | */ | ||
828 | while (rr->length > 0 && | ||
829 | s->s3->handshake_fragment_len < sizeof(s->s3->handshake_fragment)) { | ||
830 | s->s3->handshake_fragment[s->s3->handshake_fragment_len++] = | ||
831 | rr->data[rr->off++]; | ||
832 | rr->length--; | ||
833 | } | ||
834 | |||
835 | if (s->s3->handshake_fragment_len < sizeof(s->s3->handshake_fragment)) | ||
836 | return 1; | ||
837 | |||
838 | if (s->internal->in_handshake) { | ||
839 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
840 | return -1; | ||
841 | } | ||
842 | |||
843 | /* | ||
844 | * This code currently deals with HelloRequest and ClientHello messages - | ||
845 | * anything else is pushed to the handshake_func. Almost all of this | ||
846 | * belongs in the client/server handshake code. | ||
847 | */ | ||
848 | |||
849 | /* If we are a client, check for an incoming 'Hello Request': */ | ||
850 | if ((!s->server) && (s->s3->handshake_fragment_len >= 4) && | ||
851 | (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && | ||
852 | (s->session != NULL) && (s->session->cipher != NULL)) { | ||
853 | s->s3->handshake_fragment_len = 0; | ||
854 | |||
855 | if ((s->s3->handshake_fragment[1] != 0) || | ||
856 | (s->s3->handshake_fragment[2] != 0) || | ||
857 | (s->s3->handshake_fragment[3] != 0)) { | ||
858 | SSLerror(s, SSL_R_BAD_HELLO_REQUEST); | ||
859 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); | ||
860 | return -1; | ||
861 | } | ||
862 | |||
863 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, | ||
864 | s->s3->handshake_fragment, 4); | ||
865 | |||
866 | if (SSL_is_init_finished(s) && | ||
867 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && | ||
868 | !s->s3->renegotiate) { | ||
869 | ssl3_renegotiate(s); | ||
870 | if (ssl3_renegotiate_check(s)) { | ||
871 | i = s->internal->handshake_func(s); | ||
872 | if (i < 0) | ||
873 | return (i); | ||
874 | if (i == 0) { | ||
875 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
876 | return (-1); | ||
877 | } | ||
878 | |||
879 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
880 | if (s->s3->rbuf.left == 0) { | ||
881 | ssl_force_want_read(s); | ||
882 | return (-1); | ||
883 | } | ||
884 | } | ||
885 | } | ||
886 | } | ||
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 | |||
892 | /* Disallow client initiated renegotiation if configured. */ | ||
893 | if (s->server && SSL_is_init_finished(s) && | ||
894 | s->s3->handshake_fragment_len >= 4 && | ||
895 | s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO && | ||
896 | (s->internal->options & SSL_OP_NO_CLIENT_RENEGOTIATION)) { | ||
897 | ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION); | ||
898 | return -1; | ||
899 | } | ||
900 | |||
901 | /* If we are a server and get a client hello when renegotiation isn't | ||
902 | * allowed send back a no renegotiation alert and carry on. | ||
903 | * WARNING: experimental code, needs reviewing (steve) | ||
904 | */ | ||
905 | if (s->server && | ||
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 | |||
917 | /* Unexpected handshake message (Client Hello, or protocol violation) */ | ||
918 | if ((s->s3->handshake_fragment_len >= 4) && !s->internal->in_handshake) { | ||
919 | if (((s->s3->hs.state&SSL_ST_MASK) == SSL_ST_OK) && | ||
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 | } | ||
925 | i = s->internal->handshake_func(s); | ||
926 | if (i < 0) | ||
927 | return (i); | ||
928 | if (i == 0) { | ||
929 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
930 | return (-1); | ||
931 | } | ||
932 | |||
933 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
934 | if (s->s3->rbuf.left == 0) { | ||
935 | ssl_force_want_read(s); | ||
936 | return (-1); | ||
937 | } | ||
938 | } | ||
939 | return 1; | ||
940 | } | ||
941 | |||
942 | return 1; | ||
943 | } | ||
944 | |||
817 | /* Return up to 'len' payload bytes received in 'type' records. | 945 | /* Return up to 'len' payload bytes received in 'type' records. |
818 | * 'type' is one of the following: | 946 | * 'type' is one of the following: |
819 | * | 947 | * |
@@ -950,7 +1078,6 @@ ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
950 | return (0); | 1078 | return (0); |
951 | } | 1079 | } |
952 | 1080 | ||
953 | |||
954 | /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ | 1081 | /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ |
955 | if (type == rr->type) { | 1082 | if (type == rr->type) { |
956 | /* make sure that we are not getting application data when we | 1083 | /* make sure that we are not getting application data when we |
@@ -986,111 +1113,10 @@ ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
986 | return (n); | 1113 | return (n); |
987 | } | 1114 | } |
988 | 1115 | ||
989 | 1116 | /* | |
990 | /* If we get here, then type != rr->type; if we have a handshake | 1117 | * If we get here, then type != rr->type; if we have a handshake |
991 | * message, then it was unexpected (Hello Request or Client Hello). */ | 1118 | * message, then it was unexpected (Hello Request or Client Hello). |
992 | |||
993 | { | ||
994 | /* | ||
995 | * In case of record types for which we have 'fragment' | ||
996 | * storage, * fill that so that we can process the data | ||
997 | * at a fixed place. | ||
998 | */ | ||
999 | unsigned int dest_maxlen = 0; | ||
1000 | unsigned char *dest = NULL; | ||
1001 | unsigned int *dest_len = NULL; | ||
1002 | |||
1003 | if (rr->type == SSL3_RT_HANDSHAKE) { | ||
1004 | dest_maxlen = sizeof s->s3->handshake_fragment; | ||
1005 | dest = s->s3->handshake_fragment; | ||
1006 | dest_len = &s->s3->handshake_fragment_len; | ||
1007 | } | ||
1008 | if (dest_maxlen > 0) { | ||
1009 | /* available space in 'dest' */ | ||
1010 | n = dest_maxlen - *dest_len; | ||
1011 | if (rr->length < n) | ||
1012 | n = rr->length; /* available bytes */ | ||
1013 | |||
1014 | /* now move 'n' bytes: */ | ||
1015 | while (n-- > 0) { | ||
1016 | dest[(*dest_len)++] = rr->data[rr->off++]; | ||
1017 | rr->length--; | ||
1018 | } | ||
1019 | |||
1020 | if (*dest_len < dest_maxlen) | ||
1021 | goto start; /* fragment was too small */ | ||
1022 | } | ||
1023 | } | ||
1024 | |||
1025 | /* s->s3->handshake_fragment_len == 4 iff rr->type == SSL3_RT_HANDSHAKE; | ||
1026 | * s->s3->alert_fragment_len == 2 iff rr->type == SSL3_RT_ALERT. | ||
1027 | * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */ | ||
1028 | |||
1029 | /* If we are a client, check for an incoming 'Hello Request': */ | ||
1030 | if ((!s->server) && (s->s3->handshake_fragment_len >= 4) && | ||
1031 | (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && | ||
1032 | (s->session != NULL) && (s->session->cipher != NULL)) { | ||
1033 | s->s3->handshake_fragment_len = 0; | ||
1034 | |||
1035 | if ((s->s3->handshake_fragment[1] != 0) || | ||
1036 | (s->s3->handshake_fragment[2] != 0) || | ||
1037 | (s->s3->handshake_fragment[3] != 0)) { | ||
1038 | al = SSL_AD_DECODE_ERROR; | ||
1039 | SSLerror(s, SSL_R_BAD_HELLO_REQUEST); | ||
1040 | goto fatal_err; | ||
1041 | } | ||
1042 | |||
1043 | ssl_msg_callback(s, 0, SSL3_RT_HANDSHAKE, | ||
1044 | s->s3->handshake_fragment, 4); | ||
1045 | |||
1046 | if (SSL_is_init_finished(s) && | ||
1047 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && | ||
1048 | !s->s3->renegotiate) { | ||
1049 | ssl3_renegotiate(s); | ||
1050 | if (ssl3_renegotiate_check(s)) { | ||
1051 | i = s->internal->handshake_func(s); | ||
1052 | if (i < 0) | ||
1053 | return (i); | ||
1054 | if (i == 0) { | ||
1055 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
1056 | return (-1); | ||
1057 | } | ||
1058 | |||
1059 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
1060 | if (s->s3->rbuf.left == 0) { | ||
1061 | ssl_force_want_read(s); | ||
1062 | return (-1); | ||
1063 | } | ||
1064 | } | ||
1065 | } | ||
1066 | } | ||
1067 | /* we either finished a handshake or ignored the request, | ||
1068 | * now try again to obtain the (application) data we were asked for */ | ||
1069 | goto start; | ||
1070 | } | ||
1071 | /* Disallow client initiated renegotiation if configured. */ | ||
1072 | if (s->server && SSL_is_init_finished(s) && | ||
1073 | s->s3->handshake_fragment_len >= 4 && | ||
1074 | s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO && | ||
1075 | (s->internal->options & SSL_OP_NO_CLIENT_RENEGOTIATION)) { | ||
1076 | al = SSL_AD_NO_RENEGOTIATION; | ||
1077 | goto fatal_err; | ||
1078 | } | ||
1079 | /* If we are a server and get a client hello when renegotiation isn't | ||
1080 | * allowed send back a no renegotiation alert and carry on. | ||
1081 | * WARNING: experimental code, needs reviewing (steve) | ||
1082 | */ | 1119 | */ |
1083 | if (s->server && | ||
1084 | SSL_is_init_finished(s) && | ||
1085 | !s->s3->send_connection_binding && | ||
1086 | (s->s3->handshake_fragment_len >= 4) && | ||
1087 | (s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) && | ||
1088 | (s->session != NULL) && (s->session->cipher != NULL)) { | ||
1089 | /*s->s3->handshake_fragment_len = 0;*/ | ||
1090 | rr->length = 0; | ||
1091 | ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); | ||
1092 | goto start; | ||
1093 | } | ||
1094 | 1120 | ||
1095 | if (rr->type == SSL3_RT_ALERT) { | 1121 | if (rr->type == SSL3_RT_ALERT) { |
1096 | if ((ret = ssl3_read_alert(s)) <= 0) | 1122 | if ((ret = ssl3_read_alert(s)) <= 0) |
@@ -1111,28 +1137,9 @@ ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) | |||
1111 | goto start; | 1137 | goto start; |
1112 | } | 1138 | } |
1113 | 1139 | ||
1114 | /* Unexpected handshake message (Client Hello, or protocol violation) */ | 1140 | if (rr->type == SSL3_RT_HANDSHAKE) { |
1115 | if ((s->s3->handshake_fragment_len >= 4) && !s->internal->in_handshake) { | 1141 | if ((ret = ssl3_read_handshake_unexpected(s)) <= 0) |
1116 | if (((s->s3->hs.state&SSL_ST_MASK) == SSL_ST_OK) && | 1142 | return ret; |
1117 | !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { | ||
1118 | s->s3->hs.state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; | ||
1119 | s->internal->renegotiate = 1; | ||
1120 | s->internal->new_session = 1; | ||
1121 | } | ||
1122 | i = s->internal->handshake_func(s); | ||
1123 | if (i < 0) | ||
1124 | return (i); | ||
1125 | if (i == 0) { | ||
1126 | SSLerror(s, SSL_R_SSL_HANDSHAKE_FAILURE); | ||
1127 | return (-1); | ||
1128 | } | ||
1129 | |||
1130 | if (!(s->internal->mode & SSL_MODE_AUTO_RETRY)) { | ||
1131 | if (s->s3->rbuf.left == 0) { | ||
1132 | ssl_force_want_read(s); | ||
1133 | return (-1); | ||
1134 | } | ||
1135 | } | ||
1136 | goto start; | 1143 | goto start; |
1137 | } | 1144 | } |
1138 | 1145 | ||