Line data Source code
1 : /* 2 : * Copyright (C) 2000-2012 Free Software Foundation, Inc. 3 : * Copyright (C) 2015-2018 Red Hat, Inc. 4 : * 5 : * Author: Nikos Mavrogiannopoulos 6 : * 7 : * This file is part of GnuTLS. 8 : * 9 : * The GnuTLS is free software; you can redistribute it and/or 10 : * modify it under the terms of the GNU Lesser General Public License 11 : * as published by the Free Software Foundation; either version 2.1 of 12 : * the License, or (at your option) any later version. 13 : * 14 : * This library is distributed in the hope that it will be useful, but 15 : * WITHOUT ANY WARRANTY; without even the implied warranty of 16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 : * Lesser General Public License for more details. 18 : * 19 : * You should have received a copy of the GNU Lesser General Public License 20 : * along with this program. If not, see <https://www.gnu.org/licenses/> 21 : * 22 : */ 23 : 24 : #ifndef GNUTLS_LIB_HELLO_EXT_H 25 : #define GNUTLS_LIB_HELLO_EXT_H 26 : 27 : #include "gnutls_int.h" 28 : #include <gnutls/gnutls.h> 29 : #include "str.h" 30 : 31 : /* Functions for hello extension parsing. 32 : */ 33 : int _gnutls_parse_hello_extensions(gnutls_session_t session, 34 : gnutls_ext_flags_t msg, 35 : gnutls_ext_parse_type_t parse_type, 36 : const uint8_t * data, int data_size); 37 : int _gnutls_gen_hello_extensions(gnutls_session_t session, 38 : gnutls_buffer_st * extdata, 39 : gnutls_ext_flags_t msg, 40 : gnutls_ext_parse_type_t); 41 : int _gnutls_hello_ext_init(void); 42 : void _gnutls_hello_ext_deinit(void); 43 : 44 : void _gnutls_hello_ext_priv_deinit(gnutls_session_t session); 45 : 46 : /* functions to be used by extensions internally 47 : */ 48 : void _gnutls_hello_ext_unset_priv(gnutls_session_t session, 49 : extensions_t ext); 50 : void _gnutls_hello_ext_set_priv(gnutls_session_t session, extensions_t ext, 51 : gnutls_ext_priv_data_t); 52 : int _gnutls_hello_ext_get_priv(gnutls_session_t session, extensions_t ext, 53 : gnutls_ext_priv_data_t *); 54 : int _gnutls_hello_ext_get_resumed_priv(gnutls_session_t session, 55 : extensions_t ext, 56 : gnutls_ext_priv_data_t * data); 57 : 58 : #define GNUTLS_EXT_FLAG_MSG_MASK (GNUTLS_EXT_FLAG_CLIENT_HELLO | GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO| \ 59 : GNUTLS_EXT_FLAG_TLS13_SERVER_HELLO | GNUTLS_EXT_FLAG_EE | GNUTLS_EXT_FLAG_HRR) 60 : 61 : /* these flags can only be set in the extensions, but cannot be requested; 62 : * they are handled internally by the hello parsing/generating functions. */ 63 : #define GNUTLS_EXT_FLAG_SET_ONLY_FLAGS_MASK ~(GNUTLS_EXT_FLAG_DTLS | GNUTLS_EXT_FLAG_TLS) 64 : 65 : /* obtain the message this extension was received at */ 66 6061 : inline static gnutls_ext_flags_t _gnutls_ext_get_msg(gnutls_session_t session) 67 : { 68 6061 : return session->internals.ext_msg & GNUTLS_EXT_FLAG_MSG_MASK; 69 : } 70 : 71 252353 : inline static void _gnutls_ext_set_msg(gnutls_session_t session, gnutls_ext_flags_t msg) 72 : { 73 252353 : session->internals.ext_msg = msg; 74 : } 75 : 76 24968 : inline static void _gnutls_ext_set_extensions_offset(gnutls_session_t session, 77 : int offset) 78 : { 79 24968 : session->internals.extensions_offset = offset; 80 : } 81 : 82 513 : inline static int _gnutls_ext_get_extensions_offset(gnutls_session_t session) 83 : { 84 513 : return session->internals.extensions_offset; 85 : } 86 : 87 : int _gnutls_ext_set_full_client_hello(gnutls_session_t session, 88 : handshake_buffer_st *recv_buf); 89 : unsigned _gnutls_ext_get_full_client_hello(gnutls_session_t session, 90 : gnutls_datum_t *datum); 91 : 92 : /* for session packing */ 93 : int _gnutls_hello_ext_pack(gnutls_session_t session, gnutls_buffer_st * packed); 94 : int _gnutls_hello_ext_unpack(gnutls_session_t session, 95 : gnutls_buffer_st * packed); 96 : 97 284249 : inline static const char *ext_msg_validity_to_str(gnutls_ext_flags_t msg) 98 : { 99 284249 : msg &= GNUTLS_EXT_FLAG_MSG_MASK; 100 : 101 284249 : switch(msg) { 102 : case GNUTLS_EXT_FLAG_CLIENT_HELLO: 103 : return "client hello"; 104 130390 : case GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO: 105 130390 : return "TLS 1.2 server hello"; 106 76650 : case GNUTLS_EXT_FLAG_TLS13_SERVER_HELLO: 107 76650 : return "TLS 1.3 server hello"; 108 76650 : case GNUTLS_EXT_FLAG_EE: 109 76650 : return "encrypted extensions"; 110 484 : case GNUTLS_EXT_FLAG_HRR: 111 484 : return "hello retry request"; 112 0 : default: 113 0 : return "(unknown)"; 114 : } 115 : } 116 : 117 : typedef struct hello_ext_entry_st { 118 : const char *name; /* const overridden when free_struct is set */ 119 : unsigned free_struct; 120 : 121 : uint16_t tls_id; 122 : unsigned gid; /* gnutls internal ID */ 123 : 124 : gnutls_ext_parse_type_t client_parse_point; 125 : gnutls_ext_parse_type_t server_parse_point; 126 : unsigned validity; /* multiple items of gnutls_ext_flags_t */ 127 : 128 : /* this function must return 0 when Not Applicable 129 : * size of extension data if ok 130 : * < 0 on other error. 131 : */ 132 : gnutls_ext_recv_func recv_func; 133 : 134 : /* this function must return 0 when Not Applicable 135 : * size of extension data if ok 136 : * GNUTLS_E_INT_RET_0 if extension data size is zero 137 : * < 0 on other error. 138 : */ 139 : gnutls_ext_send_func send_func; 140 : 141 : gnutls_ext_deinit_data_func deinit_func; /* this will be called to deinitialize 142 : * internal data 143 : */ 144 : gnutls_ext_pack_func pack_func; /* packs internal data to machine independent format */ 145 : gnutls_ext_unpack_func unpack_func; /* unpacks internal data */ 146 : 147 : /* non-zero if that extension cannot be overridden by the applications. 148 : * That should be set to extensions which allocate data early, e.g., on 149 : * gnutls_init(), or modify the TLS protocol in a way that the application 150 : * cannot control. */ 151 : unsigned cannot_be_overriden; 152 : } hello_ext_entry_st; 153 : 154 : /* Checks if the extension @id provided has been requested 155 : * by us (in client side).In server side it checks whether this 156 : * extension was advertized by the client. 157 : * 158 : * It returns non-zero for true, otherwise zero. 159 : */ 160 : inline static unsigned 161 446000 : _gnutls_hello_ext_is_present(gnutls_session_t session, extensions_t id) 162 : { 163 354520 : if (session->internals.used_exts & ((ext_track_t)1 << id)) 164 59154 : return 1; 165 : 166 : return 0; 167 : } 168 : 169 : /* Adds the extension we want to send in the extensions list. 170 : * This list is used in client side to check whether the (later) received 171 : * extensions are the ones we requested. 172 : * 173 : * In server side, this list is used to ensure we don't send 174 : * extensions that we didn't receive a corresponding value. 175 : * 176 : * Returns zero if failed, non-zero on success. 177 : */ 178 : inline static 179 137390 : unsigned _gnutls_hello_ext_save(gnutls_session_t session, 180 : extensions_t id, 181 : unsigned check_dup) 182 : { 183 116438 : if (check_dup && _gnutls_hello_ext_is_present(session, id)) { 184 : return 0; 185 : } 186 : 187 137092 : session->internals.used_exts |= ((ext_track_t)1 << id); 188 : 189 137092 : return 1; 190 : } 191 : 192 : inline static 193 8399 : void _gnutls_hello_ext_save_sr(gnutls_session_t session) 194 : { 195 16559 : _gnutls_hello_ext_save(session, GNUTLS_EXTENSION_SAFE_RENEGOTIATION, 1); 196 : } 197 : 198 : #endif /* GNUTLS_LIB_HELLO_EXT_H */