Blame lib/ext/safe_renegotiation.c

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
}