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