Blame lib/ext/signature.c

Packit 549fdc
/*
Packit 549fdc
 * Copyright (C) 2002-2016 Free Software Foundation, Inc.
Packit 549fdc
 * Copyright (C) 2015-2017 Red Hat, Inc.
Packit 549fdc
 *
Packit 549fdc
 * Author: Nikos Mavrogiannopoulos
Packit 549fdc
 *
Packit 549fdc
 * This file is part of GnuTLS.
Packit 549fdc
 *
Packit 549fdc
 * The GnuTLS is free software; you can redistribute it and/or
Packit 549fdc
 * modify it under the terms of the GNU Lesser General Public License
Packit 549fdc
 * as published by the Free Software Foundation; either version 2.1 of
Packit 549fdc
 * the License, or (at your option) any later version.
Packit 549fdc
 *
Packit 549fdc
 * This library is distributed in the hope that it will be useful, but
Packit 549fdc
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 549fdc
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 549fdc
 * Lesser General Public License for more details.
Packit 549fdc
 *
Packit 549fdc
 * You should have received a copy of the GNU Lesser General Public License
Packit 549fdc
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
Packit 549fdc
 *
Packit 549fdc
 */
Packit 549fdc
Packit 549fdc
/* This file contains the code the Certificate Type TLS extension.
Packit 549fdc
 * This extension is currently gnutls specific.
Packit 549fdc
 */
Packit 549fdc
Packit 549fdc
#include "gnutls_int.h"
Packit 549fdc
#include "errors.h"
Packit 549fdc
#include "num.h"
Packit 549fdc
#include <gnutls/gnutls.h>
Packit 549fdc
#include <ext/signature.h>
Packit 549fdc
#include <state.h>
Packit 549fdc
#include <num.h>
Packit 549fdc
#include <algorithms.h>
Packit 549fdc
#include <abstract_int.h>
Packit 549fdc
Packit 549fdc
static int _gnutls_signature_algorithm_recv_params(gnutls_session_t
Packit 549fdc
						   session,
Packit 549fdc
						   const uint8_t * data,
Packit 549fdc
						   size_t data_size);
Packit 549fdc
static int _gnutls_signature_algorithm_send_params(gnutls_session_t
Packit 549fdc
						   session,
Packit 549fdc
						   gnutls_buffer_st *
Packit 549fdc
						   extdata);
Packit 549fdc
static void signature_algorithms_deinit_data(gnutls_ext_priv_data_t priv);
Packit 549fdc
static int signature_algorithms_pack(gnutls_ext_priv_data_t epriv,
Packit 549fdc
				     gnutls_buffer_st * ps);
Packit 549fdc
static int signature_algorithms_unpack(gnutls_buffer_st * ps,
Packit 549fdc
				       gnutls_ext_priv_data_t * _priv);
Packit 549fdc
Packit 549fdc
const extension_entry_st ext_mod_sig = {
Packit 549fdc
	.name = "Signature Algorithms",
Packit 549fdc
	.type = GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
Packit 549fdc
	.parse_type = GNUTLS_EXT_TLS,
Packit 549fdc
Packit 549fdc
	.recv_func = _gnutls_signature_algorithm_recv_params,
Packit 549fdc
	.send_func = _gnutls_signature_algorithm_send_params,
Packit 549fdc
	.pack_func = signature_algorithms_pack,
Packit 549fdc
	.unpack_func = signature_algorithms_unpack,
Packit 549fdc
	.deinit_func = signature_algorithms_deinit_data,
Packit 549fdc
	.cannot_be_overriden = 1
Packit 549fdc
};
Packit 549fdc
Packit 549fdc
typedef struct {
Packit 549fdc
	/* TLS 1.2 signature algorithms */
Packit 549fdc
	gnutls_sign_algorithm_t sign_algorithms[MAX_ALGOS];
Packit 549fdc
	uint16_t sign_algorithms_size;
Packit 549fdc
} sig_ext_st;
Packit 549fdc
Packit 549fdc
/* generates a SignatureAndHashAlgorithm structure with length as prefix
Packit 549fdc
 * by using the setup priorities.
Packit 549fdc
 */
Packit 549fdc
int
Packit 549fdc
_gnutls_sign_algorithm_write_params(gnutls_session_t session,
Packit 549fdc
				    gnutls_buffer_st * extdata)
Packit 549fdc
{
Packit 549fdc
	uint8_t *p;
Packit 549fdc
	unsigned int len, i;
Packit 549fdc
	const sign_algorithm_st *aid;
Packit 549fdc
	uint8_t buffer[MAX_ALGOS*2];
Packit 549fdc
Packit 549fdc
	p = buffer;
Packit 549fdc
	len = 0;
Packit 549fdc
Packit 549fdc
	for (i=0;i<session->internals.priorities->sigalg.size;i++) {
Packit 549fdc
		aid = &session->internals.priorities->sigalg.entry[i]->aid;
Packit 549fdc
Packit 549fdc
		if (HAVE_UNKNOWN_SIGAID(aid))
Packit 549fdc
			continue;
Packit 549fdc
Packit 549fdc
		_gnutls_handshake_log
Packit 549fdc
		    ("EXT[%p]: sent signature algo (%d.%d) %s\n", session,
Packit 549fdc
		     (int)aid->id[0], (int)aid->id[1],
Packit 549fdc
		     session->internals.priorities->sigalg.entry[i]->name);
Packit 549fdc
Packit 549fdc
		len += 2;
Packit 549fdc
		if (unlikely(len >= sizeof(buffer))) {
Packit 549fdc
			len -= 2;
Packit 549fdc
			break;
Packit 549fdc
		}
Packit 549fdc
Packit 549fdc
		*p = aid->id[0];
Packit 549fdc
		p++;
Packit 549fdc
		*p = aid->id[1];
Packit 549fdc
		p++;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	return _gnutls_buffer_append_data_prefix(extdata, 16, buffer, len);
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
Packit 549fdc
/* Parses the Signature Algorithm structure and stores data into
Packit 549fdc
 * session->security_parameters.extensions.
Packit 549fdc
 */
Packit 549fdc
int
Packit 549fdc
_gnutls_sign_algorithm_parse_data(gnutls_session_t session,
Packit 549fdc
				  const uint8_t * data, size_t data_size)
Packit 549fdc
{
Packit 549fdc
	unsigned int sig, i;
Packit 549fdc
	sig_ext_st *priv;
Packit 549fdc
	gnutls_ext_priv_data_t epriv;
Packit 549fdc
Packit 549fdc
	if (data_size == 0 || data_size % 2 != 0)
Packit 549fdc
		return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
Packit 549fdc
Packit 549fdc
	priv = gnutls_calloc(1, sizeof(*priv));
Packit 549fdc
	if (priv == NULL) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_MEMORY_ERROR;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	for (i = 0; i < data_size; i += 2) {
Packit 549fdc
		sign_algorithm_st aid;
Packit 549fdc
Packit 549fdc
		aid.id[0] = data[i];
Packit 549fdc
		aid.id[1] = data[i + 1];
Packit 549fdc
Packit 549fdc
		sig = _gnutls_tls_aid_to_sign(&aid);
Packit 549fdc
Packit 549fdc
		_gnutls_handshake_log
Packit 549fdc
		    ("EXT[%p]: rcvd signature algo (%d.%d) %s\n", session,
Packit 549fdc
		     aid.id[0], aid.id[1],
Packit 549fdc
		     gnutls_sign_get_name(sig));
Packit 549fdc
Packit 549fdc
		if (sig != GNUTLS_SIGN_UNKNOWN) {
Packit 549fdc
			if (priv->sign_algorithms_size ==
Packit 549fdc
			    MAX_ALGOS)
Packit 549fdc
				break;
Packit 549fdc
			priv->sign_algorithms[priv->
Packit 549fdc
					      sign_algorithms_size++] =
Packit 549fdc
			    sig;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	epriv = priv;
Packit 549fdc
	_gnutls_ext_set_session_data(session,
Packit 549fdc
				     GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
Packit 549fdc
				     epriv);
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/*
Packit 549fdc
 * In case of a server: if a SIGNATURE_ALGORITHMS extension type is
Packit 549fdc
 * received then it stores into the session security parameters the
Packit 549fdc
 * new value.
Packit 549fdc
 *
Packit 549fdc
 * In case of a client: If a signature_algorithms have been specified
Packit 549fdc
 * then it is an error;
Packit 549fdc
 */
Packit 549fdc
Packit 549fdc
static int
Packit 549fdc
_gnutls_signature_algorithm_recv_params(gnutls_session_t session,
Packit 549fdc
					const uint8_t * data,
Packit 549fdc
					size_t _data_size)
Packit 549fdc
{
Packit 549fdc
	ssize_t data_size = _data_size;
Packit 549fdc
	int ret;
Packit 549fdc
Packit 549fdc
	if (session->security_parameters.entity == GNUTLS_CLIENT) {
Packit 549fdc
		/* nothing for now */
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		/* Although TLS 1.2 mandates that we must not accept reply
Packit 549fdc
		 * to this message, there are good reasons to just ignore it. Check
Packit 549fdc
		 * http://www.ietf.org/mail-archive/web/tls/current/msg03880.html
Packit 549fdc
		 */
Packit 549fdc
		/* return GNUTLS_E_UNEXPECTED_PACKET; */
Packit 549fdc
	} else {
Packit 549fdc
		/* SERVER SIDE - we must check if the sent cert type is the right one
Packit 549fdc
		 */
Packit 549fdc
		if (data_size >= 2) {
Packit 549fdc
			uint16_t len;
Packit 549fdc
Packit 549fdc
			DECR_LEN(data_size, 2);
Packit 549fdc
			len = _gnutls_read_uint16(data);
Packit 549fdc
			DECR_LEN(data_size, len);
Packit 549fdc
Packit 549fdc
			if (data_size > 0)
Packit 549fdc
				return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
Packit 549fdc
Packit 549fdc
			ret =
Packit 549fdc
			    _gnutls_sign_algorithm_parse_data(session,
Packit 549fdc
							      data + 2,
Packit 549fdc
							      len);
Packit 549fdc
			if (ret < 0) {
Packit 549fdc
				gnutls_assert();
Packit 549fdc
				return ret;
Packit 549fdc
			}
Packit 549fdc
		} else {
Packit 549fdc
			return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/* returns data_size or a negative number on failure
Packit 549fdc
 */
Packit 549fdc
static int
Packit 549fdc
_gnutls_signature_algorithm_send_params(gnutls_session_t session,
Packit 549fdc
					gnutls_buffer_st * extdata)
Packit 549fdc
{
Packit 549fdc
	int ret;
Packit 549fdc
	size_t init_length = extdata->length;
Packit 549fdc
	const version_entry_st *ver = get_version(session);
Packit 549fdc
Packit 549fdc
	if (unlikely(ver == NULL))
Packit 549fdc
		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
Packit 549fdc
Packit 549fdc
	/* this function sends the client extension data */
Packit 549fdc
	if (session->security_parameters.entity == GNUTLS_CLIENT
Packit 549fdc
	    && _gnutls_version_has_selectable_sighash(ver)) {
Packit 549fdc
		if (session->internals.priorities->sigalg.size > 0) {
Packit 549fdc
			ret =
Packit 549fdc
			    _gnutls_sign_algorithm_write_params(session, extdata);
Packit 549fdc
			if (ret < 0)
Packit 549fdc
				return gnutls_assert_val(ret);
Packit 549fdc
Packit 549fdc
			return extdata->length - init_length;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* if we are here it means we don't send the extension */
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/* Returns a requested by the peer signature algorithm that
Packit 549fdc
 * matches the given certificate's public key algorithm. 
Packit 549fdc
 *
Packit 549fdc
 * When the @client_cert flag is not set, then this function will
Packit 549fdc
 * also check whether the signature algorithm is allowed to be
Packit 549fdc
 * used in that session. Otherwise GNUTLS_SIGN_UNKNOWN is
Packit 549fdc
 * returned.
Packit 549fdc
 */
Packit 549fdc
gnutls_sign_algorithm_t
Packit 549fdc
_gnutls_session_get_sign_algo(gnutls_session_t session,
Packit 549fdc
			      gnutls_pcert_st * cert,
Packit 549fdc
			      gnutls_privkey_t privkey,
Packit 549fdc
			      unsigned client_cert)
Packit 549fdc
{
Packit 549fdc
	unsigned i;
Packit 549fdc
	int ret;
Packit 549fdc
	const version_entry_st *ver = get_version(session);
Packit 549fdc
	sig_ext_st *priv;
Packit 549fdc
	gnutls_ext_priv_data_t epriv;
Packit 549fdc
	unsigned int cert_algo;
Packit 549fdc
Packit 549fdc
	if (unlikely(ver == NULL))
Packit 549fdc
		return gnutls_assert_val(GNUTLS_SIGN_UNKNOWN);
Packit 549fdc
Packit 549fdc
	cert_algo = gnutls_pubkey_get_pk_algorithm(cert->pubkey, NULL);
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_ext_get_session_data(session,
Packit 549fdc
					 GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
Packit 549fdc
					 &epriv);
Packit 549fdc
	priv = epriv;
Packit 549fdc
Packit 549fdc
	if (ret < 0 || !_gnutls_version_has_selectable_sighash(ver)) {
Packit 549fdc
		/* none set, allow SHA-1 only */
Packit 549fdc
		ret = gnutls_pk_to_sign(cert_algo, GNUTLS_DIG_SHA1);
Packit 549fdc
Packit 549fdc
		if (!client_cert && _gnutls_session_sign_algo_enabled(session, ret) < 0)
Packit 549fdc
			goto fail;
Packit 549fdc
		return ret;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	for (i = 0; i < priv->sign_algorithms_size; i++) {
Packit 549fdc
		if (_gnutls_privkey_compatible_with_sig(privkey, priv->sign_algorithms[i]) == 0)
Packit 549fdc
			continue;
Packit 549fdc
Packit 549fdc
		if (gnutls_sign_supports_pk_algorithm(priv->sign_algorithms[i], cert_algo) != 0) {
Packit 549fdc
			if (_gnutls_pubkey_compatible_with_sig
Packit 549fdc
			    (session, cert->pubkey, ver,
Packit 549fdc
			     priv->sign_algorithms[i]) < 0)
Packit 549fdc
				continue;
Packit 549fdc
Packit 549fdc
			if (_gnutls_session_sign_algo_enabled
Packit 549fdc
			    (session, priv->sign_algorithms[i]) < 0)
Packit 549fdc
				continue;
Packit 549fdc
Packit 549fdc
			return priv->sign_algorithms[i];
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* When having a legacy client certificate which can only be signed
Packit 549fdc
	 * using algorithms we don't always enable by default (e.g., DSA-SHA1),
Packit 549fdc
	 * continue and sign with it. */
Packit 549fdc
	if (client_cert) {
Packit 549fdc
		_gnutls_audit_log(session, "No shared signature schemes with peer for client certificate (%s). Is the certificate a legacy one?",
Packit 549fdc
				  gnutls_pk_get_name(cert_algo));
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
 fail:
Packit 549fdc
	return GNUTLS_SIGN_UNKNOWN;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/* Check if the given signature algorithm is supported.
Packit 549fdc
 * This means that it is enabled by the priority functions,
Packit 549fdc
 * and in case of a server a matching certificate exists.
Packit 549fdc
 */
Packit 549fdc
int
Packit 549fdc
_gnutls_session_sign_algo_enabled(gnutls_session_t session,
Packit 549fdc
				  gnutls_sign_algorithm_t sig)
Packit 549fdc
{
Packit 549fdc
	unsigned i;
Packit 549fdc
	const version_entry_st *ver = get_version(session);
Packit 549fdc
Packit 549fdc
	if (unlikely(ver == NULL))
Packit 549fdc
		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
Packit 549fdc
Packit 549fdc
	if (!_gnutls_version_has_selectable_sighash(ver)) {
Packit 549fdc
		return 0;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	for (i = 0; i < session->internals.priorities->sigalg.size;
Packit 549fdc
	     i++) {
Packit 549fdc
		if (session->internals.priorities->sigalg.entry[i]->id ==
Packit 549fdc
		    sig) {
Packit 549fdc
			return 0;	/* ok */
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
static void signature_algorithms_deinit_data(gnutls_ext_priv_data_t priv)
Packit 549fdc
{
Packit 549fdc
	gnutls_free(priv);
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
static int
Packit 549fdc
signature_algorithms_pack(gnutls_ext_priv_data_t epriv,
Packit 549fdc
			  gnutls_buffer_st * ps)
Packit 549fdc
{
Packit 549fdc
	sig_ext_st *priv = epriv;
Packit 549fdc
	int ret, i;
Packit 549fdc
Packit 549fdc
	BUFFER_APPEND_NUM(ps, priv->sign_algorithms_size);
Packit 549fdc
	for (i = 0; i < priv->sign_algorithms_size; i++) {
Packit 549fdc
		BUFFER_APPEND_NUM(ps, priv->sign_algorithms[i]);
Packit 549fdc
	}
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
static int
Packit 549fdc
signature_algorithms_unpack(gnutls_buffer_st * ps,
Packit 549fdc
			    gnutls_ext_priv_data_t * _priv)
Packit 549fdc
{
Packit 549fdc
	sig_ext_st *priv;
Packit 549fdc
	int i, ret;
Packit 549fdc
	gnutls_ext_priv_data_t epriv;
Packit 549fdc
Packit 549fdc
	priv = gnutls_calloc(1, sizeof(*priv));
Packit 549fdc
	if (priv == NULL) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_MEMORY_ERROR;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	BUFFER_POP_NUM(ps, priv->sign_algorithms_size);
Packit 549fdc
	for (i = 0; i < priv->sign_algorithms_size; i++) {
Packit 549fdc
		BUFFER_POP_NUM(ps, priv->sign_algorithms[i]);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	epriv = priv;
Packit 549fdc
	*_priv = epriv;
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
Packit 549fdc
      error:
Packit 549fdc
	gnutls_free(priv);
Packit 549fdc
	return ret;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
Packit 549fdc
Packit 549fdc
/**
Packit 549fdc
 * gnutls_sign_algorithm_get_requested:
Packit 549fdc
 * @session: is a #gnutls_session_t type.
Packit 549fdc
 * @indx: is an index of the signature algorithm to return
Packit 549fdc
 * @algo: the returned certificate type will be stored there
Packit 549fdc
 *
Packit 549fdc
 * Returns the signature algorithm specified by index that was
Packit 549fdc
 * requested by the peer. If the specified index has no data available
Packit 549fdc
 * this function returns %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE.  If
Packit 549fdc
 * the negotiated TLS version does not support signature algorithms
Packit 549fdc
 * then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned even
Packit 549fdc
 * for the first index.  The first index is 0.
Packit 549fdc
 *
Packit 549fdc
 * This function is useful in the certificate callback functions
Packit 549fdc
 * to assist in selecting the correct certificate.
Packit 549fdc
 *
Packit 549fdc
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
Packit 549fdc
 *   an error code is returned.
Packit 549fdc
 *
Packit 549fdc
 * Since: 2.10.0
Packit 549fdc
 **/
Packit 549fdc
int
Packit 549fdc
gnutls_sign_algorithm_get_requested(gnutls_session_t session,
Packit 549fdc
				    size_t indx,
Packit 549fdc
				    gnutls_sign_algorithm_t * algo)
Packit 549fdc
{
Packit 549fdc
	const version_entry_st *ver = get_version(session);
Packit 549fdc
	sig_ext_st *priv;
Packit 549fdc
	gnutls_ext_priv_data_t epriv;
Packit 549fdc
	int ret;
Packit 549fdc
Packit 549fdc
	if (unlikely(ver == NULL))
Packit 549fdc
		return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_ext_get_session_data(session,
Packit 549fdc
					 GNUTLS_EXTENSION_SIGNATURE_ALGORITHMS,
Packit 549fdc
					 &epriv);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return ret;
Packit 549fdc
	}
Packit 549fdc
	priv = epriv;
Packit 549fdc
Packit 549fdc
	if (!_gnutls_version_has_selectable_sighash(ver)
Packit 549fdc
	    || priv->sign_algorithms_size == 0) {
Packit 549fdc
		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (indx < priv->sign_algorithms_size) {
Packit 549fdc
		*algo = priv->sign_algorithms[indx];
Packit 549fdc
		return 0;
Packit 549fdc
	} else
Packit 549fdc
		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/**
Packit 549fdc
 * gnutls_sign_algorithm_get:
Packit 549fdc
 * @session: is a #gnutls_session_t type.
Packit 549fdc
 *
Packit 549fdc
 * Returns the signature algorithm that is (or will be) used in this 
Packit 549fdc
 * session by the server to sign data. This function should be
Packit 549fdc
 * used only with TLS 1.2 or later.
Packit 549fdc
 *
Packit 549fdc
 * Returns: The sign algorithm or %GNUTLS_SIGN_UNKNOWN.
Packit 549fdc
 *
Packit 549fdc
 * Since: 3.1.1
Packit 549fdc
 **/
Packit 549fdc
int gnutls_sign_algorithm_get(gnutls_session_t session)
Packit 549fdc
{
Packit 549fdc
	return session->security_parameters.server_sign_algo;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/**
Packit 549fdc
 * gnutls_sign_algorithm_get_client:
Packit 549fdc
 * @session: is a #gnutls_session_t type.
Packit 549fdc
 *
Packit 549fdc
 * Returns the signature algorithm that is (or will be) used in this 
Packit 549fdc
 * session by the client to sign data. This function should be
Packit 549fdc
 * used only with TLS 1.2 or later.
Packit 549fdc
 *
Packit 549fdc
 * Returns: The sign algorithm or %GNUTLS_SIGN_UNKNOWN.
Packit 549fdc
 *
Packit 549fdc
 * Since: 3.1.11
Packit 549fdc
 **/
Packit 549fdc
int gnutls_sign_algorithm_get_client(gnutls_session_t session)
Packit 549fdc
{
Packit 549fdc
	return session->security_parameters.client_sign_algo;
Packit 549fdc
}