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_psk_key_exchange_modes.h" 17 : : 18 : : #include <stdint.h> 19 : : 20 : : #include "tls/extensions/s2n_client_psk.h" 21 : : #include "tls/s2n_tls_parameters.h" 22 : : #include "utils/s2n_safety.h" 23 : : 24 : : static bool s2n_psk_key_exchange_modes_should_send(struct s2n_connection *conn); 25 : : static int s2n_psk_key_exchange_modes_send(struct s2n_connection *conn, struct s2n_stuffer *out); 26 : : static int s2n_psk_key_exchange_modes_recv(struct s2n_connection *conn, struct s2n_stuffer *extension); 27 : : 28 : : const s2n_extension_type s2n_psk_key_exchange_modes_extension = { 29 : : .iana_value = TLS_EXTENSION_PSK_KEY_EXCHANGE_MODES, 30 : : .minimum_version = S2N_TLS13, 31 : : .is_response = false, 32 : : .send = s2n_psk_key_exchange_modes_send, 33 : : .recv = s2n_psk_key_exchange_modes_recv, 34 : : .should_send = s2n_psk_key_exchange_modes_should_send, 35 : : .if_missing = s2n_extension_noop_if_missing, 36 : : }; 37 : : 38 : : static bool s2n_psk_key_exchange_modes_should_send(struct s2n_connection *conn) 39 : 5633 : { 40 : : /** 41 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.9 42 : : *# Servers MUST NOT select a key exchange mode that is not listed by the 43 : : *# client. This extension also restricts the modes for use with PSK 44 : : *# resumption. 45 : : * 46 : : * The RFC is ambiguous about whether the psk_kx_modes extension should be 47 : : * sent in the first flight of messages, but we choose to do so for 48 : : * interoperability with other TLS implementations. 49 : : * https://github.com/aws/s2n-tls/issues/4124 50 : : * The final check for psk_list.len > 0 is necessary because external 51 : : * PSKs are used without setting `use_tickets` to true. 52 : : */ 53 [ + + ][ + + ]: 5633 : return conn->config->use_tickets || conn->psk_params.psk_list.len > 0; 54 : 5633 : } 55 : : 56 : : static int s2n_psk_key_exchange_modes_send(struct s2n_connection *conn, struct s2n_stuffer *out) 57 : 1146 : { 58 [ - + ][ # # ]: 1146 : POSIX_ENSURE_REF(conn); 59 : : 60 [ - + ]: 1146 : POSIX_GUARD(s2n_stuffer_write_uint8(out, PSK_KEY_EXCHANGE_MODE_SIZE)); 61 : : 62 : : /* s2n currently only supports pre-shared keys with (EC)DHE key establishment */ 63 [ - + ]: 1146 : POSIX_GUARD(s2n_stuffer_write_uint8(out, TLS_PSK_DHE_KE_MODE)); 64 : : 65 : 1146 : return S2N_SUCCESS; 66 : 1146 : } 67 : : 68 : : static int s2n_psk_key_exchange_modes_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) 69 : 1137 : { 70 [ - + ][ # # ]: 1137 : POSIX_ENSURE_REF(conn); 71 : : 72 : 1137 : uint8_t psk_ke_mode_list_len = 0; 73 [ - + ]: 1137 : POSIX_GUARD(s2n_stuffer_read_uint8(extension, &psk_ke_mode_list_len)); 74 [ + + ]: 1137 : if (psk_ke_mode_list_len > s2n_stuffer_data_available(extension)) { 75 : : /* Malformed length, ignore the extension */ 76 : 1 : return S2N_SUCCESS; 77 : 1 : } 78 : : 79 [ + + ]: 1155 : for (size_t i = 0; i < psk_ke_mode_list_len; i++) { 80 : 1151 : uint8_t wire_psk_ke_mode = 0; 81 [ - + ]: 1151 : POSIX_GUARD(s2n_stuffer_read_uint8(extension, &wire_psk_ke_mode)); 82 : : 83 : : /* s2n currently only supports pre-shared keys with (EC)DHE key establishment */ 84 [ + + ]: 1151 : if (wire_psk_ke_mode == TLS_PSK_DHE_KE_MODE) { 85 : 1132 : conn->psk_params.psk_ke_mode = S2N_PSK_DHE_KE; 86 : 1132 : return S2N_SUCCESS; 87 : 1132 : } 88 : 1151 : } 89 : : 90 : 4 : return S2N_SUCCESS; 91 : 1136 : }