|
Packit |
aea12f |
/*
|
|
Packit |
aea12f |
* Copyright (C) 2017 Red Hat, Inc.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Author: Nikos Mavrogiannopoulos
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This file is part of GnuTLS.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* The GnuTLS is free software; you can redistribute it and/or
|
|
Packit |
aea12f |
* modify it under the terms of the GNU Lesser General Public License
|
|
Packit |
aea12f |
* as published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
aea12f |
* the License, or (at your option) any later version.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This library is distributed in the hope that it will be useful, but
|
|
Packit |
aea12f |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
aea12f |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
aea12f |
* Lesser General Public License for more details.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit |
aea12f |
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Internal API functions to be used by extension handlers.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
#include "gnutls_int.h"
|
|
Packit |
aea12f |
#include "hello_ext.h"
|
|
Packit |
aea12f |
#include "hello_ext_lib.h"
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
void _gnutls_hello_ext_default_deinit(gnutls_ext_priv_data_t priv)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_free(priv);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* When this is used, the deinitialization function must be set to default:
|
|
Packit |
aea12f |
* _gnutls_hello_ext_default_deinit.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This also prevents and errors on duplicate entries.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_hello_ext_set_datum(gnutls_session_t session,
|
|
Packit |
aea12f |
extensions_t id, const gnutls_datum_t *data)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_ext_priv_data_t epriv;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (_gnutls_hello_ext_get_priv(session, id, &epriv) >= 0)
|
|
Packit |
aea12f |
return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (data->size >= UINT16_MAX)
|
|
Packit |
aea12f |
return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
epriv = gnutls_malloc(data->size+2);
|
|
Packit |
aea12f |
if (epriv == NULL)
|
|
Packit |
aea12f |
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_write_uint16(data->size, epriv);
|
|
Packit |
aea12f |
memcpy(((uint8_t*)epriv)+2, data->data, data->size);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_hello_ext_set_priv(session, id, epriv);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_hello_ext_get_datum(gnutls_session_t session,
|
|
Packit |
aea12f |
extensions_t id, gnutls_datum_t *data /* constant contents */)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_ext_priv_data_t epriv;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_hello_ext_get_priv(session, id, &epriv);
|
|
Packit |
aea12f |
if (ret < 0 || epriv == NULL)
|
|
Packit |
aea12f |
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
data->size = _gnutls_read_uint16(epriv);
|
|
Packit |
aea12f |
data->data = ((uint8_t*)epriv)+2;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_hello_ext_get_resumed_datum(gnutls_session_t session,
|
|
Packit |
aea12f |
extensions_t id, gnutls_datum_t *data /* constant contents */)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_ext_priv_data_t epriv;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_hello_ext_get_resumed_priv(session, id, &epriv);
|
|
Packit |
aea12f |
if (ret < 0 || epriv == NULL)
|
|
Packit |
aea12f |
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
data->size = _gnutls_read_uint16(epriv);
|
|
Packit |
aea12f |
data->data = ((uint8_t*)epriv)+2;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_hello_ext_default_pack(gnutls_ext_priv_data_t epriv, gnutls_buffer_st *ps)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
size_t size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
size = _gnutls_read_uint16(epriv);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return _gnutls_buffer_append_data(ps, epriv, size+2);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_hello_ext_default_unpack(gnutls_buffer_st *ps, gnutls_ext_priv_data_t *epriv)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_datum_t data;
|
|
Packit |
aea12f |
uint8_t *store;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_buffer_pop_datum_prefix16(ps, &data);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
return gnutls_assert_val(ret);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
store = gnutls_calloc(1, data.size+2);
|
|
Packit |
aea12f |
if (store == NULL)
|
|
Packit |
aea12f |
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_write_uint16(data.size, store);
|
|
Packit |
aea12f |
memcpy(store+2, data.data, data.size);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*epriv = store;
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|