Line data Source code
1 : /* 2 : * Copyright (C) 2017 Red Hat, Inc. 3 : * 4 : * Author: Nikos Mavrogiannopoulos 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 : /* Internal API functions to be used by extension handlers. 24 : */ 25 : 26 : #include "gnutls_int.h" 27 : #include "hello_ext.h" 28 : #include "hello_ext_lib.h" 29 : 30 2128 : void _gnutls_hello_ext_default_deinit(gnutls_ext_priv_data_t priv) 31 : { 32 2128 : gnutls_free(priv); 33 2128 : } 34 : 35 : /* When this is used, the deinitialization function must be set to default: 36 : * _gnutls_hello_ext_default_deinit. 37 : * 38 : * This also prevents and errors on duplicate entries. 39 : */ 40 : int 41 2050 : _gnutls_hello_ext_set_datum(gnutls_session_t session, 42 : extensions_t id, const gnutls_datum_t *data) 43 : { 44 2050 : gnutls_ext_priv_data_t epriv; 45 : 46 2050 : if (_gnutls_hello_ext_get_priv(session, id, &epriv) >= 0) 47 0 : return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); 48 : 49 2050 : if (data->size >= UINT16_MAX) 50 0 : return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); 51 : 52 2050 : epriv = gnutls_malloc(data->size+2); 53 2050 : if (epriv == NULL) 54 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); 55 : 56 2050 : _gnutls_write_uint16(data->size, epriv); 57 2050 : memcpy(((uint8_t*)epriv)+2, data->data, data->size); 58 : 59 2050 : _gnutls_hello_ext_set_priv(session, id, epriv); 60 : 61 2050 : return 0; 62 : } 63 : 64 : int 65 31583 : _gnutls_hello_ext_get_datum(gnutls_session_t session, 66 : extensions_t id, gnutls_datum_t *data /* constant contents */) 67 : { 68 31583 : gnutls_ext_priv_data_t epriv; 69 31583 : int ret; 70 : 71 31583 : ret = _gnutls_hello_ext_get_priv(session, id, &epriv); 72 31583 : if (ret < 0 || epriv == NULL) 73 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; 74 : 75 3482 : data->size = _gnutls_read_uint16(epriv); 76 3482 : data->data = ((uint8_t*)epriv)+2; 77 : 78 3482 : return 0; 79 : } 80 : 81 : int 82 813 : _gnutls_hello_ext_get_resumed_datum(gnutls_session_t session, 83 : extensions_t id, gnutls_datum_t *data /* constant contents */) 84 : { 85 813 : gnutls_ext_priv_data_t epriv; 86 813 : int ret; 87 : 88 813 : ret = _gnutls_hello_ext_get_resumed_priv(session, id, &epriv); 89 813 : if (ret < 0 || epriv == NULL) 90 : return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; 91 : 92 66 : data->size = _gnutls_read_uint16(epriv); 93 66 : data->data = ((uint8_t*)epriv)+2; 94 : 95 66 : return 0; 96 : } 97 : 98 : int 99 690 : _gnutls_hello_ext_default_pack(gnutls_ext_priv_data_t epriv, gnutls_buffer_st *ps) 100 : { 101 690 : size_t size; 102 : 103 690 : size = _gnutls_read_uint16(epriv); 104 : 105 690 : return _gnutls_buffer_append_data(ps, epriv, size+2); 106 : } 107 : 108 : int 109 96 : _gnutls_hello_ext_default_unpack(gnutls_buffer_st *ps, gnutls_ext_priv_data_t *epriv) 110 : { 111 96 : gnutls_datum_t data; 112 96 : uint8_t *store; 113 96 : int ret; 114 : 115 96 : ret = _gnutls_buffer_pop_datum_prefix16(ps, &data); 116 96 : if (ret < 0) 117 0 : return gnutls_assert_val(ret); 118 : 119 96 : store = gnutls_calloc(1, data.size+2); 120 96 : if (store == NULL) 121 0 : return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); 122 : 123 96 : _gnutls_write_uint16(data.size, store); 124 96 : memcpy(store+2, data.data, data.size); 125 : 126 96 : *epriv = store; 127 96 : return 0; 128 : }