|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* Copyright (C) 2009-2012 Free Software Foundation, Inc.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Author: Steve Dispensa (<dispensa@phonefactor.com>)
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This file is part of GnuTLS.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The GnuTLS is free software; you can redistribute it and/or
|
|
Packit Service |
4684c1 |
* modify it under the terms of the GNU Lesser General Public License
|
|
Packit Service |
4684c1 |
* as published by the Free Software Foundation; either version 2.1 of
|
|
Packit Service |
4684c1 |
* the License, or (at your option) any later version.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This library is distributed in the hope that it will be useful, but
|
|
Packit Service |
4684c1 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
4684c1 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
4684c1 |
* Lesser General Public License for more details.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit Service |
4684c1 |
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include "gnutls_int.h"
|
|
Packit Service |
4684c1 |
#include <ext/safe_renegotiation.h>
|
|
Packit Service |
4684c1 |
#include "errors.h"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int _gnutls_sr_recv_params(gnutls_session_t state,
|
|
Packit Service |
4684c1 |
const uint8_t * data, size_t data_size);
|
|
Packit Service |
4684c1 |
static int _gnutls_sr_send_params(gnutls_session_t state,
|
|
Packit Service |
4684c1 |
gnutls_buffer_st *);
|
|
Packit Service |
4684c1 |
static void _gnutls_sr_deinit_data(gnutls_ext_priv_data_t priv);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
const hello_ext_entry_st ext_mod_sr = {
|
|
Packit Service |
4684c1 |
.name = "Safe Renegotiation",
|
|
Packit Service |
4684c1 |
.tls_id = 65281,
|
|
Packit Service |
4684c1 |
.gid = GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
|
|
Packit Service |
4684c1 |
.validity = GNUTLS_EXT_FLAG_TLS | GNUTLS_EXT_FLAG_DTLS | GNUTLS_EXT_FLAG_CLIENT_HELLO |
|
|
Packit Service |
4684c1 |
GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO,
|
|
Packit Service |
4684c1 |
.client_parse_point = GNUTLS_EXT_MANDATORY,
|
|
Packit Service |
4684c1 |
.server_parse_point = GNUTLS_EXT_MANDATORY,
|
|
Packit Service |
4684c1 |
.recv_func = _gnutls_sr_recv_params,
|
|
Packit Service |
4684c1 |
.send_func = _gnutls_sr_send_params,
|
|
Packit Service |
4684c1 |
.pack_func = NULL,
|
|
Packit Service |
4684c1 |
.unpack_func = NULL,
|
|
Packit Service |
4684c1 |
.deinit_func = _gnutls_sr_deinit_data,
|
|
Packit Service |
4684c1 |
.cannot_be_overriden = 1
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
_gnutls_ext_sr_finished(gnutls_session_t session, void *vdata,
|
|
Packit Service |
4684c1 |
size_t vdata_size, int dir)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
sr_ext_st *priv;
|
|
Packit Service |
4684c1 |
gnutls_ext_priv_data_t epriv;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.priorities->sr == SR_DISABLED ||
|
|
Packit Service |
4684c1 |
session->internals.priorities->no_extensions) {
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_hello_ext_get_priv(session,
|
|
Packit Service |
4684c1 |
GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
|
|
Packit Service |
4684c1 |
&epriv);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
/* if a client didn't advertise safe renegotiation, we treat
|
|
Packit Service |
4684c1 |
* it as disabled. */
|
|
Packit Service |
4684c1 |
if (session->security_parameters.entity == GNUTLS_SERVER)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
priv = epriv;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Save data for safe renegotiation.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if (vdata_size > MAX_VERIFY_DATA_SIZE) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_INTERNAL_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if ((session->security_parameters.entity == GNUTLS_CLIENT
|
|
Packit Service |
4684c1 |
&& dir == 0)
|
|
Packit Service |
4684c1 |
|| (session->security_parameters.entity == GNUTLS_SERVER
|
|
Packit Service |
4684c1 |
&& dir == 1)) {
|
|
Packit Service |
4684c1 |
priv->client_verify_data_len = vdata_size;
|
|
Packit Service |
4684c1 |
memcpy(priv->client_verify_data, vdata, vdata_size);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
priv->server_verify_data_len = vdata_size;
|
|
Packit Service |
4684c1 |
memcpy(priv->server_verify_data, vdata, vdata_size);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int _gnutls_ext_sr_verify(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
sr_ext_st *priv = NULL;
|
|
Packit Service |
4684c1 |
gnutls_ext_priv_data_t epriv;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.priorities->sr == SR_DISABLED) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_hello_ext_get_priv(session,
|
|
Packit Service |
4684c1 |
GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
|
|
Packit Service |
4684c1 |
&epriv);
|
|
Packit Service |
4684c1 |
if (ret >= 0)
|
|
Packit Service |
4684c1 |
priv = epriv;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Safe renegotiation */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (priv && priv->safe_renegotiation_received) {
|
|
Packit Service |
4684c1 |
if ((priv->ri_extension_data_len <
|
|
Packit Service |
4684c1 |
priv->client_verify_data_len)
|
|
Packit Service |
4684c1 |
||
|
|
Packit Service |
4684c1 |
(memcmp
|
|
Packit Service |
4684c1 |
(priv->ri_extension_data, priv->client_verify_data,
|
|
Packit Service |
4684c1 |
priv->client_verify_data_len))) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
_gnutls_handshake_log
|
|
Packit Service |
4684c1 |
("HSK[%p]: Safe renegotiation failed [1]\n",
|
|
Packit Service |
4684c1 |
session);
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->security_parameters.entity == GNUTLS_CLIENT) {
|
|
Packit Service |
4684c1 |
if ((priv->ri_extension_data_len !=
|
|
Packit Service |
4684c1 |
priv->client_verify_data_len +
|
|
Packit Service |
4684c1 |
priv->server_verify_data_len)
|
|
Packit Service |
4684c1 |
|| memcmp(priv->ri_extension_data +
|
|
Packit Service |
4684c1 |
priv->client_verify_data_len,
|
|
Packit Service |
4684c1 |
priv->server_verify_data,
|
|
Packit Service |
4684c1 |
priv->server_verify_data_len) != 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
_gnutls_handshake_log
|
|
Packit Service |
4684c1 |
("HSK[%p]: Safe renegotiation failed [2]\n",
|
|
Packit Service |
4684c1 |
session);
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else { /* Make sure there are 0 extra bytes */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (priv->ri_extension_data_len !=
|
|
Packit Service |
4684c1 |
priv->client_verify_data_len) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
_gnutls_handshake_log
|
|
Packit Service |
4684c1 |
("HSK[%p]: Safe renegotiation failed [3]\n",
|
|
Packit Service |
4684c1 |
session);
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_handshake_log
|
|
Packit Service |
4684c1 |
("HSK[%p]: Safe renegotiation succeeded\n", session);
|
|
Packit Service |
4684c1 |
} else { /* safe renegotiation not received... */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (priv && priv->connection_using_safe_renegotiation) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
_gnutls_handshake_log
|
|
Packit Service |
4684c1 |
("HSK[%p]: Peer previously asked for safe renegotiation\n",
|
|
Packit Service |
4684c1 |
session);
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Clients can't tell if it's an initial negotiation */
|
|
Packit Service |
4684c1 |
if (session->internals.initial_negotiation_completed) {
|
|
Packit Service |
4684c1 |
if (session->internals.priorities->sr < SR_PARTIAL) {
|
|
Packit Service |
4684c1 |
_gnutls_handshake_log
|
|
Packit Service |
4684c1 |
("HSK[%p]: Allowing unsafe (re)negotiation\n",
|
|
Packit Service |
4684c1 |
session);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
_gnutls_handshake_log
|
|
Packit Service |
4684c1 |
("HSK[%p]: Denying unsafe (re)negotiation\n",
|
|
Packit Service |
4684c1 |
session);
|
|
Packit Service |
4684c1 |
return
|
|
Packit Service |
4684c1 |
GNUTLS_E_UNSAFE_RENEGOTIATION_DENIED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
if (session->internals.priorities->sr < SR_SAFE) {
|
|
Packit Service |
4684c1 |
_gnutls_handshake_log
|
|
Packit Service |
4684c1 |
("HSK[%p]: Allowing unsafe initial negotiation\n",
|
|
Packit Service |
4684c1 |
session);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
_gnutls_handshake_log
|
|
Packit Service |
4684c1 |
("HSK[%p]: Denying unsafe initial negotiation\n",
|
|
Packit Service |
4684c1 |
session);
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* if a server received the special ciphersuite.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int _gnutls_ext_sr_recv_cs(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret, set = 0;
|
|
Packit Service |
4684c1 |
sr_ext_st *priv;
|
|
Packit Service |
4684c1 |
gnutls_ext_priv_data_t epriv;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_hello_ext_get_priv(session,
|
|
Packit Service |
4684c1 |
GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
|
|
Packit Service |
4684c1 |
&epriv);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
set = 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (set != 0) {
|
|
Packit Service |
4684c1 |
priv = gnutls_calloc(1, sizeof(*priv));
|
|
Packit Service |
4684c1 |
if (priv == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
epriv = priv;
|
|
Packit Service |
4684c1 |
} else
|
|
Packit Service |
4684c1 |
priv = epriv;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
priv->safe_renegotiation_received = 1;
|
|
Packit Service |
4684c1 |
priv->connection_using_safe_renegotiation = 1;
|
|
Packit Service |
4684c1 |
_gnutls_hello_ext_save_sr(session);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (set != 0)
|
|
Packit Service |
4684c1 |
_gnutls_hello_ext_set_priv(session,
|
|
Packit Service |
4684c1 |
GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
|
|
Packit Service |
4684c1 |
epriv);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int _gnutls_ext_sr_send_cs(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret, set = 0;
|
|
Packit Service |
4684c1 |
sr_ext_st *priv;
|
|
Packit Service |
4684c1 |
gnutls_ext_priv_data_t epriv;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_hello_ext_get_priv(session,
|
|
Packit Service |
4684c1 |
GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
|
|
Packit Service |
4684c1 |
&epriv);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
set = 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (set != 0) {
|
|
Packit Service |
4684c1 |
priv = gnutls_calloc(1, sizeof(*priv));
|
|
Packit Service |
4684c1 |
if (priv == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
epriv = priv;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (set != 0)
|
|
Packit Service |
4684c1 |
_gnutls_hello_ext_set_priv(session,
|
|
Packit Service |
4684c1 |
GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
|
|
Packit Service |
4684c1 |
epriv);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
_gnutls_sr_recv_params(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
const uint8_t * data, size_t data_size)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
unsigned int len;
|
|
Packit Service |
4684c1 |
sr_ext_st *priv;
|
|
Packit Service |
4684c1 |
gnutls_ext_priv_data_t epriv;
|
|
Packit Service |
4684c1 |
int set = 0, ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (data_size == 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
len = data[0];
|
|
Packit Service |
4684c1 |
DECR_LEN(data_size,
|
|
Packit Service |
4684c1 |
len + 1 /* count the first byte and payload */ );
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.priorities->sr == SR_DISABLED) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_hello_ext_get_priv(session,
|
|
Packit Service |
4684c1 |
GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
|
|
Packit Service |
4684c1 |
&epriv);
|
|
Packit Service |
4684c1 |
if (ret < 0
|
|
Packit Service |
4684c1 |
&& session->security_parameters.entity == GNUTLS_SERVER) {
|
|
Packit Service |
4684c1 |
set = 1;
|
|
Packit Service |
4684c1 |
} else if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (set != 0) {
|
|
Packit Service |
4684c1 |
priv = gnutls_calloc(1, sizeof(*priv));
|
|
Packit Service |
4684c1 |
if (priv == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
epriv = priv;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_hello_ext_set_priv(session,
|
|
Packit Service |
4684c1 |
GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
|
|
Packit Service |
4684c1 |
epriv);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
priv = epriv;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* It is not legal to receive this extension on a renegotiation and
|
|
Packit Service |
4684c1 |
* not receive it on the initial negotiation.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if (session->internals.initial_negotiation_completed != 0 &&
|
|
Packit Service |
4684c1 |
priv->connection_using_safe_renegotiation == 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (len > sizeof(priv->ri_extension_data)) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SAFE_RENEGOTIATION_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (len > 0)
|
|
Packit Service |
4684c1 |
memcpy(priv->ri_extension_data, &data[1], len);
|
|
Packit Service |
4684c1 |
priv->ri_extension_data_len = len;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* "safe renegotiation received" means on *this* handshake; "connection using
|
|
Packit Service |
4684c1 |
* safe renegotiation" means that the initial hello received on the connection
|
|
Packit Service |
4684c1 |
* indicated safe renegotiation.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
priv->safe_renegotiation_received = 1;
|
|
Packit Service |
4684c1 |
priv->connection_using_safe_renegotiation = 1;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int
|
|
Packit Service |
4684c1 |
_gnutls_sr_send_params(gnutls_session_t session,
|
|
Packit Service |
4684c1 |
gnutls_buffer_st * extdata)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
/* The format of this extension is a one-byte length of verify data followed
|
|
Packit Service |
4684c1 |
* by the verify data itself. Note that the length byte does not include
|
|
Packit Service |
4684c1 |
* itself; IOW, empty verify data is represented as a length of 0. That means
|
|
Packit Service |
4684c1 |
* the minimum extension is one byte: 0x00.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
sr_ext_st *priv;
|
|
Packit Service |
4684c1 |
int ret, set = 0, len;
|
|
Packit Service |
4684c1 |
gnutls_ext_priv_data_t epriv;
|
|
Packit Service |
4684c1 |
size_t init_length = extdata->length;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->internals.priorities->sr == SR_DISABLED) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_hello_ext_get_priv(session,
|
|
Packit Service |
4684c1 |
GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
|
|
Packit Service |
4684c1 |
&epriv);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
set = 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (set != 0) {
|
|
Packit Service |
4684c1 |
priv = gnutls_calloc(1, sizeof(*priv));
|
|
Packit Service |
4684c1 |
if (priv == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
epriv = priv;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_hello_ext_set_priv(session,
|
|
Packit Service |
4684c1 |
GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
|
|
Packit Service |
4684c1 |
epriv);
|
|
Packit Service |
4684c1 |
} else
|
|
Packit Service |
4684c1 |
priv = epriv;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Always offer the extension if we're a client */
|
|
Packit Service |
4684c1 |
if (priv->connection_using_safe_renegotiation ||
|
|
Packit Service |
4684c1 |
session->security_parameters.entity == GNUTLS_CLIENT) {
|
|
Packit Service |
4684c1 |
len = priv->client_verify_data_len;
|
|
Packit Service |
4684c1 |
if (session->security_parameters.entity == GNUTLS_SERVER)
|
|
Packit Service |
4684c1 |
len += priv->server_verify_data_len;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_buffer_append_prefix(extdata, 8, len);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_buffer_append_data(extdata,
|
|
Packit Service |
4684c1 |
priv->client_verify_data,
|
|
Packit Service |
4684c1 |
priv->
|
|
Packit Service |
4684c1 |
client_verify_data_len);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (session->security_parameters.entity == GNUTLS_SERVER) {
|
|
Packit Service |
4684c1 |
ret =
|
|
Packit Service |
4684c1 |
_gnutls_buffer_append_data(extdata,
|
|
Packit Service |
4684c1 |
priv->
|
|
Packit Service |
4684c1 |
server_verify_data,
|
|
Packit Service |
4684c1 |
priv->
|
|
Packit Service |
4684c1 |
server_verify_data_len);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return extdata->length - init_length;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void _gnutls_sr_deinit_data(gnutls_ext_priv_data_t priv)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_free(priv);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_safe_renegotiation_status:
|
|
Packit Service |
4684c1 |
* @session: is a #gnutls_session_t type.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Can be used to check whether safe renegotiation is being used
|
|
Packit Service |
4684c1 |
* in the current session.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: 0 when safe renegotiation is not used and non (0) when
|
|
Packit Service |
4684c1 |
* safe renegotiation is used.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 2.10.0
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
unsigned gnutls_safe_renegotiation_status(gnutls_session_t session)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
sr_ext_st *priv;
|
|
Packit Service |
4684c1 |
gnutls_ext_priv_data_t epriv;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_hello_ext_get_priv(session,
|
|
Packit Service |
4684c1 |
GNUTLS_EXTENSION_SAFE_RENEGOTIATION,
|
|
Packit Service |
4684c1 |
&epriv);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
priv = epriv;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return priv->connection_using_safe_renegotiation;
|
|
Packit Service |
4684c1 |
}
|