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 | ||
