summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_pkt.c
diff options
context:
space:
mode:
authorjsing <>2022-03-14 16:49:35 +0000
committerjsing <>2022-03-14 16:49:35 +0000
commit07d9625933f5867c4dee9ecde797f4222f5dc516 (patch)
treef36b60b7bdcf81c644d8d156a92e99f3582d41d0 /src/lib/libssl/ssl_pkt.c
parentf3380f46eb991038b5106c03e9edc8021bae09cb (diff)
downloadopenbsd-07d9625933f5867c4dee9ecde797f4222f5dc516.tar.gz
openbsd-07d9625933f5867c4dee9ecde797f4222f5dc516.tar.bz2
openbsd-07d9625933f5867c4dee9ecde797f4222f5dc516.zip
Factor out unexpected handshake message handling code in the legacy stack.
The TLS record layer has to be able to handle unexpected handshake messages that result when it has been asked to read application data. The way that this is currently done in the legacy stack is a layering violation - the record layer knows about DTLS/TLS handshake messages, parsing them and then deciding what action to take. This is further complicated by the need to handle handshake message fragments. For now, factor this code out with minimal changes - since it is a layering violation we have to retain separate code for DTLS and TLS. ok beck@ inoguchi@ tb@
Diffstat (limited to 'src/lib/libssl/ssl_pkt.c')
-rw-r--r--src/lib/libssl/ssl_pkt.c263
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
817static int
818ssl3_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