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_cookie.h" 17 : : #include "tls/s2n_tls.h" 18 : : #include "utils/s2n_random.h" 19 : : 20 : : /* 21 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.2 22 : : *# When sending the new ClientHello, the client MUST copy 23 : : *# the contents of the extension received in the HelloRetryRequest into 24 : : *# a "cookie" extension in the new ClientHello. 25 : : * 26 : : * If the server sent a cookie, send it back. 27 : : */ 28 : : static bool s2n_client_cookie_should_send(struct s2n_connection *conn) 29 : 40 : { 30 [ + - ][ + + ]: 40 : return conn && conn->cookie.size > 0; 31 : 40 : } 32 : : 33 : : /* 34 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-4.2.2 35 : : *# struct { 36 : : *# opaque cookie<1..2^16-1>; 37 : : *# } Cookie; 38 : : */ 39 : : int s2n_cookie_send(struct s2n_connection *conn, struct s2n_stuffer *out) 40 : 85 : { 41 [ # # ][ - + ]: 85 : POSIX_ENSURE_REF(conn); 42 : : 43 [ - + ]: 85 : POSIX_GUARD(s2n_stuffer_write_uint16(out, conn->cookie.size)); 44 [ - + ]: 85 : POSIX_GUARD(s2n_stuffer_write(out, &conn->cookie)); 45 : : 46 : 85 : return S2N_SUCCESS; 47 : 85 : } 48 : : 49 : : /* 50 : : * Our server does not send cookies in production, so 51 : : * should never receive a cookie back from the client. 52 : : * 53 : : * However, we may enable cookies for testing. 54 : : * In that case, verify the proper client behavior by 55 : : * checking that the cookie sent matches the cookie received. 56 : : * This is also why the "if_missing" behavior is an error. 57 : : */ 58 : : static int s2n_client_cookie_recv(struct s2n_connection *conn, struct s2n_stuffer *extension) 59 : 52 : { 60 [ - + ][ # # ]: 52 : POSIX_ENSURE_REF(conn); 61 [ - + ][ # # ]: 52 : POSIX_ENSURE(s2n_in_unit_test(), S2N_ERR_UNSUPPORTED_EXTENSION); 62 : : 63 : 52 : uint16_t size = 0; 64 [ - + ]: 52 : POSIX_GUARD(s2n_stuffer_read_uint16(extension, &size)); 65 [ + + ][ + - ]: 52 : POSIX_ENSURE(size == conn->cookie.size, S2N_ERR_BAD_MESSAGE); 66 [ - + ][ # # ]: 47 : POSIX_ENSURE(size >= s2n_stuffer_data_available(extension), S2N_ERR_BAD_MESSAGE); 67 : : 68 : 47 : uint8_t *cookie = s2n_stuffer_raw_read(extension, size); 69 [ - + ][ # # ]: 47 : POSIX_ENSURE_REF(cookie); 70 [ + + ][ + - ]: 47 : POSIX_ENSURE(s2n_constant_time_equals(cookie, conn->cookie.data, size), S2N_ERR_BAD_MESSAGE); 71 : : 72 : 42 : return S2N_SUCCESS; 73 : 47 : } 74 : : 75 : : const s2n_extension_type s2n_client_cookie_extension = { 76 : : .iana_value = TLS_EXTENSION_COOKIE, 77 : : .minimum_version = S2N_TLS13, 78 : : .is_response = true, 79 : : .send = s2n_cookie_send, 80 : : .recv = s2n_client_cookie_recv, 81 : : .should_send = s2n_client_cookie_should_send, 82 : : .if_missing = s2n_extension_error_if_missing, 83 : : };