Line data Source code
1 : /* 2 : * Copyright (C) 2018 Red Hat, Inc. 3 : * 4 : * Author: Daiki Ueno 5 : * 6 : * This file is part of GnuTLS. 7 : * 8 : * The GnuTLS is free software; you can redistribute it and/or 9 : * modify it under the terms of the GNU Lesser General Public License 10 : * as published by the Free Software Foundation; either version 2.1 of 11 : * the License, or (at your option) any later version. 12 : * 13 : * This library is distributed in the hope that it will be useful, but 14 : * WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 : * Lesser General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU Lesser General Public License 19 : * along with this program. If not, see <https://www.gnu.org/licenses/> 20 : * 21 : */ 22 : 23 : /* This file contains the code for the Early Data TLS 1.3 extension. 24 : */ 25 : 26 : #include "gnutls_int.h" 27 : #include "errors.h" 28 : #include "num.h" 29 : #include "hello_ext_lib.h" 30 : #include <ext/early_data.h> 31 : 32 : static int early_data_recv_params(gnutls_session_t session, 33 : const uint8_t * data, 34 : size_t data_size); 35 : static int early_data_send_params(gnutls_session_t session, 36 : gnutls_buffer_st * extdata); 37 : 38 : const hello_ext_entry_st ext_mod_early_data = { 39 : .name = "Early Data", 40 : .tls_id = 42, 41 : .gid = GNUTLS_EXTENSION_EARLY_DATA, 42 : .validity = GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_CLIENT_HELLO | GNUTLS_EXT_FLAG_EE, 43 : .client_parse_point = GNUTLS_EXT_MANDATORY, /* force parsing prior to EXT_TLS extensions */ 44 : .server_parse_point = GNUTLS_EXT_MANDATORY, /* force parsing prior to EXT_TLS extensions */ 45 : .recv_func = early_data_recv_params, 46 : .send_func = early_data_send_params, 47 : .pack_func = NULL, 48 : .unpack_func = NULL, 49 : .deinit_func = _gnutls_hello_ext_default_deinit, 50 : .cannot_be_overriden = 0 51 : }; 52 : 53 : static int 54 29 : early_data_recv_params(gnutls_session_t session, 55 : const uint8_t * data, size_t _data_size) 56 : { 57 29 : const version_entry_st *vers = get_version(session); 58 : 59 29 : if (!vers || !vers->tls13_sem) 60 7 : return gnutls_assert_val(0); 61 : 62 23 : if (session->security_parameters.entity == GNUTLS_SERVER) { 63 : /* The flag may be cleared by pre_shared_key 64 : * extension, when replay is detected. */ 65 18 : if ((session->internals.flags & GNUTLS_ENABLE_EARLY_DATA) && 66 : /* Refuse early data when this is a second CH after HRR */ 67 10 : !(session->internals.hsk_flags & HSK_HRR_SENT)) 68 10 : session->internals.hsk_flags |= HSK_EARLY_DATA_ACCEPTED; 69 : 70 18 : session->internals.hsk_flags |= HSK_EARLY_DATA_IN_FLIGHT; 71 : } else { 72 5 : if (_gnutls_ext_get_msg(session) == GNUTLS_EXT_FLAG_EE) 73 5 : session->internals.hsk_flags |= HSK_EARLY_DATA_ACCEPTED; 74 : } 75 : 76 : return 0; 77 : } 78 : 79 : /* returns data_size or a negative number on failure 80 : */ 81 : static int 82 3482 : early_data_send_params(gnutls_session_t session, 83 : gnutls_buffer_st * extdata) 84 : { 85 3482 : if (session->security_parameters.entity == GNUTLS_SERVER) { 86 15 : if (session->internals.hsk_flags & HSK_EARLY_DATA_ACCEPTED) 87 6 : return GNUTLS_E_INT_RET_0; 88 : } else { 89 3467 : if (session->internals.early_data_presend_buffer.length > 0) { 90 7 : session->internals.hsk_flags |= HSK_EARLY_DATA_IN_FLIGHT; 91 7 : return GNUTLS_E_INT_RET_0; 92 : } 93 : } 94 : 95 : return 0; 96 : } 97 : 98 : /** 99 : * gnutls_record_get_max_early_data_size: 100 : * @session: is a #gnutls_session_t type. 101 : * 102 : * This function returns the maximum early data size in this connection. 103 : * This property can only be set to servers. The client may be 104 : * provided with the maximum allowed size through the "early_data" 105 : * extension of the NewSessionTicket handshake message. 106 : * 107 : * Returns: The maximum early data size in this connection. 108 : * 109 : * Since: 3.6.5 110 : **/ 111 : size_t 112 4 : gnutls_record_get_max_early_data_size(gnutls_session_t session) 113 : { 114 4 : return session->security_parameters.max_early_data_size; 115 : } 116 : 117 : /** 118 : * gnutls_record_set_max_early_data_size: 119 : * @session: is a #gnutls_session_t type. 120 : * @size: is the new size 121 : * 122 : * This function sets the maximum early data size in this connection. 123 : * This property can only be set to servers. The client may be 124 : * provided with the maximum allowed size through the "early_data" 125 : * extension of the NewSessionTicket handshake message. 126 : * 127 : * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, 128 : * otherwise a negative error code is returned. 129 : * 130 : * Since: 3.6.4 131 : **/ 132 : int 133 8 : gnutls_record_set_max_early_data_size(gnutls_session_t session, 134 : size_t size) 135 : { 136 8 : if (session->security_parameters.entity == GNUTLS_CLIENT) 137 : return GNUTLS_E_INVALID_REQUEST; 138 : 139 : /* Reject zero as well, as it is useless. */ 140 8 : if (size == 0 || size > UINT32_MAX) 141 : return GNUTLS_E_INVALID_REQUEST; 142 : 143 8 : session->security_parameters.max_early_data_size = (uint32_t) size; 144 : 145 8 : return 0; 146 : }