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_server_supported_versions.h" 17 : : 18 : : #include <stdint.h> 19 : : #include <sys/param.h> 20 : : 21 : : #include "tls/extensions/s2n_supported_versions.h" 22 : : #include "tls/s2n_alerts.h" 23 : : #include "tls/s2n_cipher_preferences.h" 24 : : #include "tls/s2n_tls.h" 25 : : #include "tls/s2n_tls_parameters.h" 26 : : #include "utils/s2n_safety.h" 27 : : 28 : : /** 29 : : * Specified in https://tools.ietf.org/html/rfc8446#section-4.2.1 30 : : * 31 : : * "A server which negotiates TLS 1.3 MUST respond by sending a 32 : : * "supported_versions" extension containing the selected version value 33 : : * (0x0304)." 34 : : * 35 : : * Structure: 36 : : * Extension type (2 bytes) 37 : : * Extension size (2 bytes) 38 : : * Selected Version (2 byte) 39 : : **/ 40 : : 41 : : static int s2n_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out); 42 : : static int s2n_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in); 43 : : 44 : : const s2n_extension_type s2n_server_supported_versions_extension = { 45 : : .iana_value = TLS_EXTENSION_SUPPORTED_VERSIONS, 46 : : .is_response = true, 47 : : .send = s2n_server_supported_versions_send, 48 : : .recv = s2n_server_supported_versions_recv, 49 : : .should_send = s2n_extension_send_if_tls13_connection, 50 : : .if_missing = s2n_extension_noop_if_missing, 51 : : }; 52 : : 53 : : static int s2n_server_supported_versions_send(struct s2n_connection *conn, struct s2n_stuffer *out) 54 : 4897 : { 55 [ - + ]: 4897 : POSIX_GUARD(s2n_stuffer_write_uint8(out, conn->server_protocol_version / 10)); 56 [ - + ]: 4897 : POSIX_GUARD(s2n_stuffer_write_uint8(out, conn->server_protocol_version % 10)); 57 : : 58 : 4897 : return S2N_SUCCESS; 59 : 4897 : } 60 : : 61 : : static int s2n_extensions_server_supported_versions_process(struct s2n_connection *conn, struct s2n_stuffer *extension) 62 : 4880 : { 63 : 4880 : uint8_t highest_supported_version = conn->client_protocol_version; 64 : 4880 : uint8_t minimum_supported_version = s2n_unknown_protocol_version; 65 [ - + ]: 4880 : POSIX_GUARD_RESULT(s2n_connection_get_minimum_supported_version(conn, &minimum_supported_version)); 66 [ + - ][ + + ]: 4880 : POSIX_ENSURE(highest_supported_version >= minimum_supported_version, S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED); 67 : : 68 : 4879 : uint8_t server_version_parts[S2N_TLS_PROTOCOL_VERSION_LEN]; 69 [ + + ]: 4879 : POSIX_GUARD(s2n_stuffer_read_bytes(extension, server_version_parts, S2N_TLS_PROTOCOL_VERSION_LEN)); 70 : : 71 : 4877 : uint16_t server_version = (server_version_parts[0] * 10) + server_version_parts[1]; 72 : : 73 : : /** 74 : : *= https://www.rfc-editor.org/rfc/rfc8446#4.1.4 75 : : *# The value of selected_version in the HelloRetryRequest 76 : : *# "supported_versions" extension MUST be retained in the ServerHello, 77 : : *# and a client MUST abort the handshake with an "illegal_parameter" 78 : : *# alert if the value changes. 79 : : **/ 80 [ + + ][ + + ]: 4877 : if (s2n_is_hello_retry_handshake(conn) && !s2n_is_hello_retry_message(conn)) { 81 [ + + ][ + - ]: 621 : POSIX_ENSURE(conn->server_protocol_version == server_version, 82 : 621 : S2N_ERR_BAD_MESSAGE); 83 : 621 : } 84 : : 85 [ + - ][ + + ]: 4876 : POSIX_ENSURE_GTE(server_version, S2N_TLS13); 86 [ + + ][ + - ]: 4875 : POSIX_ENSURE_LTE(server_version, highest_supported_version); 87 [ - + ][ # # ]: 4874 : POSIX_ENSURE_GTE(server_version, minimum_supported_version); 88 : : 89 : 4874 : conn->server_protocol_version = server_version; 90 : : 91 : 4874 : return S2N_SUCCESS; 92 : 4874 : } 93 : : 94 : : static int s2n_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *in) 95 : 4881 : { 96 [ + + ]: 4881 : if (s2n_connection_get_protocol_version(conn) < S2N_TLS13) { 97 : 1 : return S2N_SUCCESS; 98 : 1 : } 99 : : 100 [ + + ][ + - ]: 4880 : S2N_ERROR_IF(s2n_extensions_server_supported_versions_process(conn, in) < 0, S2N_ERR_BAD_MESSAGE); 101 : 4874 : return S2N_SUCCESS; 102 : 4880 : } 103 : : 104 : : /* Old-style extension functions -- remove after extensions refactor is complete */ 105 : : 106 : : int s2n_extensions_server_supported_versions_size(struct s2n_connection *conn) 107 : 2 : { 108 : 2 : return 6; 109 : 2 : } 110 : : 111 : : int s2n_extensions_server_supported_versions_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) 112 : 0 : { 113 : 0 : return s2n_extension_recv(&s2n_server_supported_versions_extension, conn, extension); 114 : 0 : }