Branch data Line data Source code
1 : : /* 2 : : * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 : : * 4 : : * Licensed under the Apache License, Version 2.0 (the "License"). 5 : : * You may not use this file except in compliance with the License. 6 : : * A copy of the License is located at 7 : : * 8 : : * http://aws.amazon.com/apache2.0 9 : : * 10 : : * or in the "license" file accompanying this file. This file is distributed 11 : : * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 : : * express or implied. See the License for the specific language governing 13 : : * permissions and limitations under the License. 14 : : */ 15 : : 16 : : #include "tls/extensions/s2n_client_renegotiation_info.h" 17 : : 18 : : #include <stdint.h> 19 : : #include <sys/param.h> 20 : : 21 : : #include "tls/s2n_tls.h" 22 : : #include "utils/s2n_safety.h" 23 : : 24 : : static int s2n_client_renegotiation_send(struct s2n_connection *conn, struct s2n_stuffer *out); 25 : : static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); 26 : : static bool s2n_client_renegotiation_should_send(struct s2n_connection *conn); 27 : : static int s2n_client_renegotiation_if_missing(struct s2n_connection *conn); 28 : : 29 : : const s2n_extension_type s2n_client_renegotiation_info_extension = { 30 : : .iana_value = TLS_EXTENSION_RENEGOTIATION_INFO, 31 : : .is_response = false, 32 : : .send = s2n_client_renegotiation_send, 33 : : .recv = s2n_client_renegotiation_recv, 34 : : .should_send = s2n_client_renegotiation_should_send, 35 : : .if_missing = s2n_client_renegotiation_if_missing, 36 : : }; 37 : : 38 : : /** 39 : : *= https://www.rfc-editor.org/rfc/rfc5746#3.5 40 : : *# o The client MUST include the "renegotiation_info" extension in the 41 : : *# ClientHello 42 : : */ 43 : : static bool s2n_client_renegotiation_should_send(struct s2n_connection *conn) 44 : 7354 : { 45 [ + - ][ + + ]: 7354 : return conn && s2n_handshake_is_renegotiation(conn); 46 : 7354 : } 47 : : 48 : : /** 49 : : *= https://www.rfc-editor.org/rfc/rfc5746#3.5 50 : : *# o The client MUST include the "renegotiation_info" extension in the 51 : : *# ClientHello, containing the saved client_verify_data. 52 : : */ 53 : : static int s2n_client_renegotiation_send(struct s2n_connection *conn, struct s2n_stuffer *out) 54 : 263 : { 55 [ - + ][ # # ]: 263 : POSIX_ENSURE_REF(conn); 56 : : 57 : : /** 58 : : *= https://www.rfc-editor.org/rfc/rfc5746#3.5 59 : : *# This text applies if the connection's "secure_renegotiation" flag is 60 : : *# set to TRUE (if it is set to FALSE, see Section 4.2). 61 : : */ 62 [ + + ][ + - ]: 263 : POSIX_ENSURE(conn->secure_renegotiation, S2N_ERR_NO_RENEGOTIATION); 63 : : 64 : 262 : uint8_t renegotiated_connection_len = conn->handshake.finished_len; 65 [ # # ][ - + ]: 262 : POSIX_ENSURE_GT(renegotiated_connection_len, 0); 66 [ - + ]: 262 : POSIX_GUARD(s2n_stuffer_write_uint8(out, renegotiated_connection_len)); 67 [ - + ]: 262 : POSIX_GUARD(s2n_stuffer_write_bytes(out, conn->handshake.client_finished, renegotiated_connection_len)); 68 : : 69 : 262 : return S2N_SUCCESS; 70 : 262 : } 71 : : 72 : : /** 73 : : *= https://www.rfc-editor.org/rfc/rfc5746#3.6 74 : : *# o The server MUST check if the "renegotiation_info" extension is 75 : : *# included in the ClientHello. 76 : : * 77 : : * Note that this extension must also work for SSLv3: 78 : : *= https://www.rfc-editor.org/rfc/rfc5746#4.5 79 : : *# TLS servers that support secure renegotiation and support SSLv3 MUST accept SCSV or the 80 : : *# "renegotiation_info" extension and respond as described in this 81 : : *# specification even if the offered client version is {0x03, 0x00}. 82 : : */ 83 : : static int s2n_client_renegotiation_recv_initial(struct s2n_connection *conn, struct s2n_stuffer *extension) 84 : 14 : { 85 : : /** 86 : : *= https://www.rfc-editor.org/rfc/rfc5746#3.6 87 : : *# The server MUST then verify 88 : : *# that the length of the "renegotiated_connection" field is zero, 89 : : *# and if it is not, MUST abort the handshake. 90 : : */ 91 : 14 : uint8_t renegotiated_connection_len = 0; 92 [ - + ]: 14 : POSIX_GUARD(s2n_stuffer_read_uint8(extension, &renegotiated_connection_len)); 93 [ + + ][ + - ]: 14 : POSIX_ENSURE(s2n_stuffer_data_available(extension) == 0, S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO); 94 [ + - ][ + + ]: 12 : POSIX_ENSURE(renegotiated_connection_len == 0, S2N_ERR_NON_EMPTY_RENEGOTIATION_INFO); 95 : : 96 : : /** 97 : : *= https://www.rfc-editor.org/rfc/rfc5746#3.6 98 : : *# If the extension is present, set secure_renegotiation flag to TRUE. 99 : : */ 100 : 11 : conn->secure_renegotiation = 1; 101 : : 102 : 11 : return S2N_SUCCESS; 103 : 12 : } 104 : : 105 : : static int s2n_client_renegotiation_recv_renegotiation(struct s2n_connection *conn, struct s2n_stuffer *extension) 106 : 258 : { 107 [ - + ][ # # ]: 258 : POSIX_ENSURE_REF(conn); 108 : : 109 : : /* s2n-tls servers do not support renegotiation. 110 : : * We add the renegotiation version of this logic only for testing. 111 : : */ 112 [ # # ][ - + ]: 258 : POSIX_ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST); 113 : : 114 : : /** 115 : : *= https://www.rfc-editor.org/rfc/rfc5746#3.7 116 : : *# This text applies if the connection's "secure_renegotiation" flag is 117 : : *# set to TRUE (if it is set to FALSE, see Section 4.4). 118 : : */ 119 [ + + ][ + - ]: 258 : POSIX_ENSURE(conn->secure_renegotiation, S2N_ERR_NO_RENEGOTIATION); 120 : : 121 : : /** 122 : : *= https://www.rfc-editor.org/rfc/rfc5746#3.7 123 : : *# o The server MUST verify that the value of the 124 : : *# "renegotiated_connection" field is equal to the saved 125 : : *# client_verify_data value; if it is not, the server MUST abort the 126 : : *# handshake. 127 : : */ 128 : : 129 : 257 : uint8_t verify_data_len = conn->handshake.finished_len; 130 [ # # ][ - + ]: 257 : POSIX_ENSURE_GT(verify_data_len, 0); 131 : : 132 : 257 : uint8_t renegotiated_connection_len = 0; 133 [ - + ]: 257 : POSIX_GUARD(s2n_stuffer_read_uint8(extension, &renegotiated_connection_len)); 134 [ + + ][ + - ]: 257 : POSIX_ENSURE(verify_data_len == renegotiated_connection_len, S2N_ERR_BAD_MESSAGE); 135 : : 136 : 256 : uint8_t *renegotiated_connection = s2n_stuffer_raw_read(extension, verify_data_len); 137 [ # # ][ - + ]: 256 : POSIX_ENSURE_REF(renegotiated_connection); 138 [ - + ][ # # ]: 256 : POSIX_ENSURE(s2n_constant_time_equals(renegotiated_connection, conn->handshake.client_finished, verify_data_len), 139 : 256 : S2N_ERR_BAD_MESSAGE); 140 : : 141 : 256 : return S2N_SUCCESS; 142 : 256 : } 143 : : 144 : : static int s2n_client_renegotiation_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) 145 : 272 : { 146 [ + + ]: 272 : if (s2n_handshake_is_renegotiation(conn)) { 147 [ + + ]: 258 : POSIX_GUARD(s2n_client_renegotiation_recv_renegotiation(conn, extension)); 148 : 258 : } else { 149 [ + + ]: 14 : POSIX_GUARD(s2n_client_renegotiation_recv_initial(conn, extension)); 150 : 14 : } 151 [ - + ][ # # ]: 267 : POSIX_ENSURE(s2n_stuffer_data_available(extension) == 0, S2N_ERR_BAD_MESSAGE); 152 : 267 : return S2N_SUCCESS; 153 : 267 : } 154 : : 155 : : static int s2n_client_renegotiation_if_missing(struct s2n_connection *conn) 156 : 7111 : { 157 [ - + ][ # # ]: 7111 : POSIX_ENSURE_REF(conn); 158 [ + + ]: 7111 : if (s2n_handshake_is_renegotiation(conn)) { 159 : : /* s2n-tls servers do not support renegotiation. 160 : : * We add the renegotiation version of this logic only for testing. 161 : : */ 162 [ # # ][ - + ]: 2 : POSIX_ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST); 163 : : 164 : : /** 165 : : *= https://www.rfc-editor.org/rfc/rfc5746#3.7 166 : : *# This text applies if the connection's "secure_renegotiation" flag is 167 : : *# set to TRUE (if it is set to FALSE, see Section 4.4). 168 : : */ 169 [ - + ][ # # ]: 2 : POSIX_ENSURE(conn->secure_renegotiation, S2N_ERR_NO_RENEGOTIATION); 170 : : 171 : : /** 172 : : *= https://www.rfc-editor.org/rfc/rfc5746#3.7 173 : : *# o The server MUST verify that the "renegotiation_info" extension is 174 : : *# present; if it is not, the server MUST abort the handshake. 175 : : */ 176 [ + - ]: 2 : POSIX_BAIL(S2N_ERR_MISSING_EXTENSION); 177 : 7109 : } else { 178 : : /** 179 : : *= https://www.rfc-editor.org/rfc/rfc5746#3.6 180 : : *# o If neither the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV nor the 181 : : *# "renegotiation_info" extension was included, set the 182 : : *# secure_renegotiation flag to FALSE. In this case, some servers 183 : : *# may want to terminate the handshake instead of continuing 184 : : * 185 : : * We do not terminate the handshake for compatibility reasons. 186 : : * See https://github.com/aws/s2n-tls/issues/3528 187 : : */ 188 : 7109 : conn->secure_renegotiation = false; 189 : 7109 : return S2N_SUCCESS; 190 : 7109 : } 191 : 7111 : }