Blame lib/pk.c

Packit 549fdc
/*
Packit 549fdc
 * Copyright (C) 2001-2014 Free Software Foundation, Inc.
Packit 549fdc
 * Copyright (C) 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 functions needed for RSA/DSA public key
Packit 549fdc
 * encryption and signatures. 
Packit 549fdc
 */
Packit 549fdc
Packit 549fdc
#include "gnutls_int.h"
Packit 549fdc
#include <mpi.h>
Packit 549fdc
#include <pk.h>
Packit 549fdc
#include "errors.h"
Packit 549fdc
#include <datum.h>
Packit 549fdc
#include <global.h>
Packit 549fdc
#include <num.h>
Packit 549fdc
#include "debug.h"
Packit 549fdc
#include <x509/x509_int.h>
Packit 549fdc
#include <x509/common.h>
Packit 549fdc
#include <random.h>
Packit 549fdc
#include <gnutls/crypto.h>
Packit 549fdc
Packit 549fdc
/**
Packit 549fdc
 * gnutls_encode_rs_value:
Packit 549fdc
 * @sig_value: will hold a Dss-Sig-Value DER encoded structure
Packit 549fdc
 * @r: must contain the r value
Packit 549fdc
 * @s: must contain the s value
Packit 549fdc
 *
Packit 549fdc
 * This function will encode the provided r and s values, 
Packit 549fdc
 * into a Dss-Sig-Value structure, used for DSA and ECDSA
Packit 549fdc
 * signatures.
Packit 549fdc
 *
Packit 549fdc
 * The output value should be deallocated using gnutls_free().
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: 3.6.0
Packit 549fdc
 *
Packit 549fdc
 **/
Packit 549fdc
int
Packit 549fdc
gnutls_encode_rs_value(gnutls_datum_t * sig_value,
Packit 549fdc
			const gnutls_datum_t * r,
Packit 549fdc
			const gnutls_datum_t * s)
Packit 549fdc
{
Packit 549fdc
	return _gnutls_encode_ber_rs_raw(sig_value, r, s);
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/* same as gnutls_encode_rs_value(), but kept since it used
Packit 549fdc
 * to be exported for FIPS140 CAVS testing.
Packit 549fdc
 */
Packit 549fdc
int
Packit 549fdc
_gnutls_encode_ber_rs_raw(gnutls_datum_t * sig_value,
Packit 549fdc
			  const gnutls_datum_t * r,
Packit 549fdc
			  const gnutls_datum_t * s)
Packit 549fdc
{
Packit 549fdc
	ASN1_TYPE sig;
Packit 549fdc
	int result, ret;
Packit 549fdc
	uint8_t *tmp = NULL;
Packit 549fdc
Packit 549fdc
	if ((result =
Packit 549fdc
	     asn1_create_element(_gnutls_get_gnutls_asn(),
Packit 549fdc
				 "GNUTLS.DSASignatureValue",
Packit 549fdc
				 &sig)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (s->data[0] >= 0x80 || r->data[0] >= 0x80) {
Packit 549fdc
		tmp = gnutls_malloc(MAX(r->size, s->size)+1);
Packit 549fdc
		if (tmp == NULL) {
Packit 549fdc
			ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
Packit 549fdc
			goto cleanup;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (r->data[0] >= 0x80) {
Packit 549fdc
		tmp[0] = 0;
Packit 549fdc
		memcpy(&tmp[1], r->data, r->size);
Packit 549fdc
		result = asn1_write_value(sig, "r", tmp, 1+r->size);
Packit 549fdc
	} else {
Packit 549fdc
		result = asn1_write_value(sig, "r", r->data, r->size);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (result != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		ret = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
Packit 549fdc
	if (s->data[0] >= 0x80) {
Packit 549fdc
		tmp[0] = 0;
Packit 549fdc
		memcpy(&tmp[1], s->data, s->size);
Packit 549fdc
		result = asn1_write_value(sig, "s", tmp, 1+s->size);
Packit 549fdc
	} else {
Packit 549fdc
		result = asn1_write_value(sig, "s", s->data, s->size);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (result != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		ret = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret = _gnutls_x509_der_encode(sig, "", sig_value, 0);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret = 0;
Packit 549fdc
 cleanup:
Packit 549fdc
	gnutls_free(tmp);
Packit 549fdc
	asn1_delete_structure(&sig);
Packit 549fdc
	return ret;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
int
Packit 549fdc
_gnutls_encode_ber_rs(gnutls_datum_t * sig_value, bigint_t r, bigint_t s)
Packit 549fdc
{
Packit 549fdc
	ASN1_TYPE sig;
Packit 549fdc
	int result;
Packit 549fdc
Packit 549fdc
	if ((result =
Packit 549fdc
	     asn1_create_element(_gnutls_get_gnutls_asn(),
Packit 549fdc
				 "GNUTLS.DSASignatureValue",
Packit 549fdc
				 &sig)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_write_int(sig, "r", r, 1);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&sig);
Packit 549fdc
		return result;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_write_int(sig, "s", s, 1);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&sig);
Packit 549fdc
		return result;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_der_encode(sig, "", sig_value, 0);
Packit 549fdc
	asn1_delete_structure(&sig);
Packit 549fdc
Packit 549fdc
	if (result < 0)
Packit 549fdc
		return gnutls_assert_val(result);
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
Packit 549fdc
/* decodes the Dss-Sig-Value structure
Packit 549fdc
 */
Packit 549fdc
int
Packit 549fdc
_gnutls_decode_ber_rs(const gnutls_datum_t * sig_value, bigint_t * r,
Packit 549fdc
		      bigint_t * s)
Packit 549fdc
{
Packit 549fdc
	ASN1_TYPE sig;
Packit 549fdc
	int result;
Packit 549fdc
Packit 549fdc
	if ((result =
Packit 549fdc
	     asn1_create_element(_gnutls_get_gnutls_asn(),
Packit 549fdc
				 "GNUTLS.DSASignatureValue",
Packit 549fdc
				 &sig)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* rfc3279 doesn't specify whether Dss-Sig-Value is encoded
Packit 549fdc
	 * as DER or BER. As such we do not restrict to the DER subset. */
Packit 549fdc
	result =
Packit 549fdc
	    asn1_der_decoding(&sig, sig_value->data, sig_value->size,
Packit 549fdc
			      NULL);
Packit 549fdc
	if (result != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&sig);
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_read_int(sig, "r", r);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&sig);
Packit 549fdc
		return result;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_read_int(sig, "s", s);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		_gnutls_mpi_release(r);
Packit 549fdc
		asn1_delete_structure(&sig);
Packit 549fdc
		return result;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	asn1_delete_structure(&sig);
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/**
Packit 549fdc
 * gnutls_decode_rs_value:
Packit 549fdc
 * @sig_value: holds a Dss-Sig-Value DER or BER encoded structure
Packit 549fdc
 * @r: will contain the r value
Packit 549fdc
 * @s: will contain the s value
Packit 549fdc
 *
Packit 549fdc
 * This function will decode the provided @sig_value, 
Packit 549fdc
 * into @r and @s elements. The Dss-Sig-Value is used for DSA and ECDSA
Packit 549fdc
 * signatures.
Packit 549fdc
 *
Packit 549fdc
 * The output values may be padded with a zero byte to prevent them
Packit 549fdc
 * from being interpreted as negative values. The value
Packit 549fdc
 * should be deallocated using gnutls_free().
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: 3.6.0
Packit 549fdc
 *
Packit 549fdc
 **/
Packit 549fdc
int gnutls_decode_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t *r,
Packit 549fdc
			   gnutls_datum_t *s)
Packit 549fdc
{
Packit 549fdc
	return _gnutls_decode_ber_rs_raw(sig_value, r, s);
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/* same as gnutls_decode_rs_value(), but kept since it used
Packit 549fdc
 * to be exported for FIPS140 CAVS testing.
Packit 549fdc
 */
Packit 549fdc
int
Packit 549fdc
_gnutls_decode_ber_rs_raw(const gnutls_datum_t * sig_value, gnutls_datum_t *r,
Packit 549fdc
			  gnutls_datum_t *s)
Packit 549fdc
{
Packit 549fdc
	ASN1_TYPE sig;
Packit 549fdc
	int result;
Packit 549fdc
Packit 549fdc
	if ((result =
Packit 549fdc
	     asn1_create_element(_gnutls_get_gnutls_asn(),
Packit 549fdc
				 "GNUTLS.DSASignatureValue",
Packit 549fdc
				 &sig)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* rfc3279 doesn't specify whether Dss-Sig-Value is encoded
Packit 549fdc
	 * as DER or BER. As such we do not restrict to the DER subset. */
Packit 549fdc
	result =
Packit 549fdc
	    asn1_der_decoding(&sig, sig_value->data, sig_value->size,
Packit 549fdc
			      NULL);
Packit 549fdc
	if (result != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&sig);
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_read_value(sig, "r", r);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&sig);
Packit 549fdc
		return result;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_read_value(sig, "s", s);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		gnutls_free(r->data);
Packit 549fdc
		asn1_delete_structure(&sig);
Packit 549fdc
		return result;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	asn1_delete_structure(&sig);
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/* some generic pk functions */
Packit 549fdc
Packit 549fdc
int _gnutls_pk_params_copy(gnutls_pk_params_st * dst,
Packit 549fdc
			   const gnutls_pk_params_st * src)
Packit 549fdc
{
Packit 549fdc
	unsigned int i, j;
Packit 549fdc
	dst->params_nr = 0;
Packit 549fdc
Packit 549fdc
	if (src == NULL || (src->params_nr == 0 && src->raw_pub.size == 0)) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_INVALID_REQUEST;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	dst->pkflags = src->pkflags;
Packit 549fdc
	dst->curve = src->curve;
Packit 549fdc
	dst->qbits = src->qbits;
Packit 549fdc
	dst->algo = src->algo;
Packit 549fdc
Packit 549fdc
	for (i = 0; i < src->params_nr; i++) {
Packit 549fdc
		dst->params[i] = _gnutls_mpi_copy(src->params[i]);
Packit 549fdc
		if (dst->params[i] == NULL) {
Packit 549fdc
			goto fail;
Packit 549fdc
		}
Packit 549fdc
Packit 549fdc
		dst->params_nr++;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (_gnutls_set_datum(&dst->raw_priv, src->raw_priv.data, src->raw_priv.size) < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto fail;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (_gnutls_set_datum(&dst->raw_pub, src->raw_pub.data, src->raw_pub.size) < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto fail;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (src->seed_size) {
Packit 549fdc
		dst->seed_size = src->seed_size;
Packit 549fdc
		memcpy(dst->seed, src->seed, src->seed_size);
Packit 549fdc
	}
Packit 549fdc
	dst->palgo = src->palgo;
Packit 549fdc
Packit 549fdc
	memcpy(&dst->spki, &src->spki, sizeof(gnutls_x509_spki_st));
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
Packit 549fdc
fail:
Packit 549fdc
	for (j = 0; j < i; j++)
Packit 549fdc
		_gnutls_mpi_release(&dst->params[j]);
Packit 549fdc
	return GNUTLS_E_MEMORY_ERROR;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
void gnutls_pk_params_init(gnutls_pk_params_st * p)
Packit 549fdc
{
Packit 549fdc
	memset(p, 0, sizeof(gnutls_pk_params_st));
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
void gnutls_pk_params_release(gnutls_pk_params_st * p)
Packit 549fdc
{
Packit 549fdc
	unsigned int i;
Packit 549fdc
	for (i = 0; i < p->params_nr; i++) {
Packit 549fdc
		_gnutls_mpi_release(&p->params[i]);
Packit 549fdc
	}
Packit 549fdc
	gnutls_free(p->raw_priv.data);
Packit 549fdc
	gnutls_free(p->raw_pub.data);
Packit 549fdc
	p->raw_priv.data = NULL;
Packit 549fdc
	p->raw_pub.data = NULL;
Packit 549fdc
Packit 549fdc
	p->params_nr = 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
void gnutls_pk_params_clear(gnutls_pk_params_st * p)
Packit 549fdc
{
Packit 549fdc
	unsigned int i;
Packit 549fdc
	for (i = 0; i < p->params_nr; i++) {
Packit 549fdc
		if (p->params[i] != NULL)
Packit 549fdc
			_gnutls_mpi_clear(p->params[i]);
Packit 549fdc
	}
Packit 549fdc
	gnutls_memset(p->seed, 0, p->seed_size);
Packit 549fdc
	p->seed_size = 0;
Packit 549fdc
	if (p->raw_priv.data != NULL) {
Packit 549fdc
		gnutls_memset(p->raw_priv.data, 0, p->raw_priv.size);
Packit 549fdc
		p->raw_priv.size = 0;
Packit 549fdc
	}
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
unsigned
Packit 549fdc
_gnutls_find_rsa_pss_salt_size(unsigned bits, const mac_entry_st *me,
Packit 549fdc
			       unsigned salt_size)
Packit 549fdc
{
Packit 549fdc
	unsigned max_salt_size, digest_size;
Packit 549fdc
Packit 549fdc
	digest_size = _gnutls_hash_get_algo_len(me);
Packit 549fdc
	max_salt_size = (bits + 7) / 8 - digest_size - 2;
Packit 549fdc
Packit 549fdc
	if (salt_size < digest_size)
Packit 549fdc
		salt_size = digest_size;
Packit 549fdc
Packit 549fdc
	if (salt_size > max_salt_size)
Packit 549fdc
		salt_size = max_salt_size;
Packit 549fdc
Packit 549fdc
	return salt_size;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/* Writes the digest information and the digest in a DER encoded
Packit 549fdc
 * structure. The digest info is allocated and stored into the info structure.
Packit 549fdc
 */
Packit 549fdc
int
Packit 549fdc
encode_ber_digest_info(const mac_entry_st * e,
Packit 549fdc
			const gnutls_datum_t * digest,
Packit 549fdc
			gnutls_datum_t * output)
Packit 549fdc
{
Packit 549fdc
	ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
Packit 549fdc
	int result;
Packit 549fdc
	const char *algo;
Packit 549fdc
	uint8_t *tmp_output;
Packit 549fdc
	int tmp_output_size;
Packit 549fdc
Packit 549fdc
	algo = _gnutls_x509_mac_to_oid(e);
Packit 549fdc
	if (algo == NULL) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		_gnutls_debug_log("Hash algorithm: %d has no OID\n",
Packit 549fdc
				  e->id);
Packit 549fdc
		return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
Packit 549fdc
					  "GNUTLS.DigestInfo",
Packit 549fdc
					  &dinfo)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result =
Packit 549fdc
	    asn1_write_value(dinfo, "digestAlgorithm.algorithm", algo, 1);
Packit 549fdc
	if (result != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&dinfo);
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* Write an ASN.1 NULL in the parameters field.  This matches RFC
Packit 549fdc
	   3279 and RFC 4055, although is arguable incorrect from a historic
Packit 549fdc
	   perspective (see those documents for more information).
Packit 549fdc
	   Regardless of what is correct, this appears to be what most
Packit 549fdc
	   implementations do.  */
Packit 549fdc
	result = asn1_write_value(dinfo, "digestAlgorithm.parameters",
Packit 549fdc
				  ASN1_NULL, ASN1_NULL_SIZE);
Packit 549fdc
	if (result != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&dinfo);
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result =
Packit 549fdc
	    asn1_write_value(dinfo, "digest", digest->data, digest->size);
Packit 549fdc
	if (result != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&dinfo);
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	tmp_output_size = 0;
Packit 549fdc
	result = asn1_der_coding(dinfo, "", NULL, &tmp_output_size, NULL);
Packit 549fdc
	if (result != ASN1_MEM_ERROR) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&dinfo);
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	tmp_output = gnutls_malloc(tmp_output_size);
Packit 549fdc
	if (tmp_output == NULL) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&dinfo);
Packit 549fdc
		return GNUTLS_E_MEMORY_ERROR;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result =
Packit 549fdc
	    asn1_der_coding(dinfo, "", tmp_output, &tmp_output_size, NULL);
Packit 549fdc
	if (result != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&dinfo);
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	asn1_delete_structure(&dinfo);
Packit 549fdc
Packit 549fdc
	output->size = tmp_output_size;
Packit 549fdc
	output->data = tmp_output;
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/**
Packit 549fdc
 * gnutls_encode_ber_digest_info:
Packit 549fdc
 * @info: an RSA BER encoded DigestInfo structure
Packit 549fdc
 * @hash: the hash algorithm that was used to get the digest
Packit 549fdc
 * @digest: must contain the digest data
Packit 549fdc
 * @output: will contain the allocated DigestInfo BER encoded data
Packit 549fdc
 *
Packit 549fdc
 * This function will encode the provided digest data, and its
Packit 549fdc
 * algorithm into an RSA PKCS#1 1.5 DigestInfo structure. 
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: 3.5.0
Packit 549fdc
 *
Packit 549fdc
 **/
Packit 549fdc
int
Packit 549fdc
gnutls_encode_ber_digest_info(gnutls_digest_algorithm_t hash,
Packit 549fdc
			      const gnutls_datum_t * digest,
Packit 549fdc
			      gnutls_datum_t * output)
Packit 549fdc
{
Packit 549fdc
	const mac_entry_st *e = hash_to_entry(hash);
Packit 549fdc
	if (unlikely(e == NULL))
Packit 549fdc
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
Packit 549fdc
Packit 549fdc
	return encode_ber_digest_info(e , digest, output);
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/**
Packit 549fdc
 * gnutls_decode_ber_digest_info:
Packit 549fdc
 * @info: an RSA BER encoded DigestInfo structure
Packit 549fdc
 * @hash: will contain the hash algorithm of the structure
Packit 549fdc
 * @digest: will contain the hash output of the structure
Packit 549fdc
 * @digest_size: will contain the hash size of the structure; initially must hold the maximum size of @digest
Packit 549fdc
 *
Packit 549fdc
 * This function will parse an RSA PKCS#1 1.5 DigestInfo structure
Packit 549fdc
 * and report the hash algorithm used as well as the digest data.
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: 3.5.0
Packit 549fdc
 *
Packit 549fdc
 **/
Packit 549fdc
int
Packit 549fdc
gnutls_decode_ber_digest_info(const gnutls_datum_t * info,
Packit 549fdc
		       gnutls_digest_algorithm_t * hash,
Packit 549fdc
		       unsigned char * digest, unsigned int *digest_size)
Packit 549fdc
{
Packit 549fdc
	ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
Packit 549fdc
	int result;
Packit 549fdc
	char str[MAX(MAX_OID_SIZE, MAX_HASH_SIZE)];
Packit 549fdc
	int len;
Packit 549fdc
Packit 549fdc
	if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
Packit 549fdc
					  "GNUTLS.DigestInfo",
Packit 549fdc
					  &dinfo)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* rfc2313 required BER encoding of that field, thus
Packit 549fdc
	 * we don't restrict libtasn1 to DER subset */
Packit 549fdc
	result = asn1_der_decoding(&dinfo, info->data, info->size, NULL);
Packit 549fdc
	if (result != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&dinfo);
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	len = sizeof(str) - 1;
Packit 549fdc
	result =
Packit 549fdc
	    asn1_read_value(dinfo, "digestAlgorithm.algorithm", str, &len;;
Packit 549fdc
	if (result != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&dinfo);
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	*hash = gnutls_oid_to_digest(str);
Packit 549fdc
Packit 549fdc
	if (*hash == GNUTLS_DIG_UNKNOWN) {
Packit 549fdc
Packit 549fdc
		_gnutls_debug_log("verify.c: HASH OID: %s\n", str);
Packit 549fdc
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&dinfo);
Packit 549fdc
		return GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	len = sizeof(str) - 1;
Packit 549fdc
	result =
Packit 549fdc
	    asn1_read_value(dinfo, "digestAlgorithm.parameters", str,
Packit 549fdc
			    &len;;
Packit 549fdc
	/* To avoid permitting garbage in the parameters field, either the
Packit 549fdc
	   parameters field is not present, or it contains 0x05 0x00. */
Packit 549fdc
	if (!(result == ASN1_ELEMENT_NOT_FOUND ||
Packit 549fdc
	      (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
Packit 549fdc
	       memcmp(str, ASN1_NULL, ASN1_NULL_SIZE) == 0))) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		asn1_delete_structure(&dinfo);
Packit 549fdc
		return GNUTLS_E_ASN1_GENERIC_ERROR;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	len = *digest_size;
Packit 549fdc
	result = asn1_read_value(dinfo, "digest", digest, &len;;
Packit 549fdc
Packit 549fdc
	if (result != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		*digest_size = len;
Packit 549fdc
		asn1_delete_structure(&dinfo);
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	*digest_size = len;
Packit 549fdc
	asn1_delete_structure(&dinfo);
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
int
Packit 549fdc
_gnutls_params_get_rsa_raw(const gnutls_pk_params_st* params,
Packit 549fdc
				    gnutls_datum_t * m, gnutls_datum_t * e,
Packit 549fdc
				    gnutls_datum_t * d, gnutls_datum_t * p,
Packit 549fdc
				    gnutls_datum_t * q, gnutls_datum_t * u,
Packit 549fdc
				    gnutls_datum_t * e1,
Packit 549fdc
				    gnutls_datum_t * e2,
Packit 549fdc
				    unsigned int flags)
Packit 549fdc
{
Packit 549fdc
	int ret;
Packit 549fdc
	mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
Packit 549fdc
Packit 549fdc
	if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
Packit 549fdc
		dprint = _gnutls_mpi_dprint;
Packit 549fdc
Packit 549fdc
	if (params == NULL) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_INVALID_REQUEST;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (!GNUTLS_PK_IS_RSA(params->algo)) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_INVALID_REQUEST;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (m) {
Packit 549fdc
		ret = dprint(params->params[0], m);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			goto error;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* E */
Packit 549fdc
	if (e) {
Packit 549fdc
		ret = dprint(params->params[1], e);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			goto error;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* D */
Packit 549fdc
	if (d && params->params[2]) {
Packit 549fdc
		ret = dprint(params->params[2], d);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			goto error;
Packit 549fdc
		}
Packit 549fdc
	} else if (d) {
Packit 549fdc
		d->data = NULL;
Packit 549fdc
		d->size = 0;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* P */
Packit 549fdc
	if (p && params->params[3]) {
Packit 549fdc
		ret = dprint(params->params[3], p);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			goto error;
Packit 549fdc
		}
Packit 549fdc
	} else if (p) {
Packit 549fdc
		p->data = NULL;
Packit 549fdc
		p->size = 0;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* Q */
Packit 549fdc
	if (q && params->params[4]) {
Packit 549fdc
		ret = dprint(params->params[4], q);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			goto error;
Packit 549fdc
		}
Packit 549fdc
	} else if (q) {
Packit 549fdc
		q->data = NULL;
Packit 549fdc
		q->size = 0;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* U */
Packit 549fdc
	if (u && params->params[5]) {
Packit 549fdc
		ret = dprint(params->params[5], u);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			goto error;
Packit 549fdc
		}
Packit 549fdc
	} else if (u) {
Packit 549fdc
		u->data = NULL;
Packit 549fdc
		u->size = 0;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* E1 */
Packit 549fdc
	if (e1 && params->params[6]) {
Packit 549fdc
		ret = dprint(params->params[6], e1);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			goto error;
Packit 549fdc
		}
Packit 549fdc
	} else if (e1) {
Packit 549fdc
		e1->data = NULL;
Packit 549fdc
		e1->size = 0;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* E2 */
Packit 549fdc
	if (e2 && params->params[7]) {
Packit 549fdc
		ret = dprint(params->params[7], e2);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			goto error;
Packit 549fdc
		}
Packit 549fdc
	} else if (e2) {
Packit 549fdc
		e2->data = NULL;
Packit 549fdc
		e2->size = 0;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
Packit 549fdc
      error:
Packit 549fdc
	_gnutls_free_datum(m);
Packit 549fdc
	_gnutls_free_datum(d);
Packit 549fdc
	_gnutls_free_datum(e);
Packit 549fdc
	_gnutls_free_datum(e1);
Packit 549fdc
	_gnutls_free_datum(e2);
Packit 549fdc
	_gnutls_free_datum(p);
Packit 549fdc
	_gnutls_free_datum(q);
Packit 549fdc
Packit 549fdc
	return ret;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
int
Packit 549fdc
_gnutls_params_get_dsa_raw(const gnutls_pk_params_st* params,
Packit 549fdc
			     gnutls_datum_t * p, gnutls_datum_t * q,
Packit 549fdc
			     gnutls_datum_t * g, gnutls_datum_t * y,
Packit 549fdc
			     gnutls_datum_t * x, unsigned int flags)
Packit 549fdc
{
Packit 549fdc
	int ret;
Packit 549fdc
	mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
Packit 549fdc
Packit 549fdc
	if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
Packit 549fdc
		dprint = _gnutls_mpi_dprint;
Packit 549fdc
Packit 549fdc
	if (params == NULL) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_INVALID_REQUEST;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (params->algo != GNUTLS_PK_DSA) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_INVALID_REQUEST;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* P */
Packit 549fdc
	if (p) {
Packit 549fdc
		ret = dprint(params->params[0], p);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			return ret;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* Q */
Packit 549fdc
	if (q) {
Packit 549fdc
		ret = dprint(params->params[1], q);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			_gnutls_free_datum(p);
Packit 549fdc
			return ret;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
Packit 549fdc
	/* G */
Packit 549fdc
	if (g) {
Packit 549fdc
		ret = dprint(params->params[2], g);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			_gnutls_free_datum(p);
Packit 549fdc
			_gnutls_free_datum(q);
Packit 549fdc
			return ret;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
Packit 549fdc
	/* Y */
Packit 549fdc
	if (y) {
Packit 549fdc
		ret = dprint(params->params[3], y);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			_gnutls_free_datum(p);
Packit 549fdc
			_gnutls_free_datum(g);
Packit 549fdc
			_gnutls_free_datum(q);
Packit 549fdc
			return ret;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* X */
Packit 549fdc
	if (x) {
Packit 549fdc
		ret = dprint(params->params[4], x);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			_gnutls_free_datum(y);
Packit 549fdc
			_gnutls_free_datum(p);
Packit 549fdc
			_gnutls_free_datum(g);
Packit 549fdc
			_gnutls_free_datum(q);
Packit 549fdc
			return ret;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
int _gnutls_params_get_ecc_raw(const gnutls_pk_params_st* params,
Packit 549fdc
				       gnutls_ecc_curve_t * curve,
Packit 549fdc
				       gnutls_datum_t * x,
Packit 549fdc
				       gnutls_datum_t * y,
Packit 549fdc
				       gnutls_datum_t * k,
Packit 549fdc
				       unsigned int flags)
Packit 549fdc
{
Packit 549fdc
	int ret;
Packit 549fdc
	mpi_dprint_func dprint = _gnutls_mpi_dprint_lz;
Packit 549fdc
Packit 549fdc
	if (flags & GNUTLS_EXPORT_FLAG_NO_LZ)
Packit 549fdc
		dprint = _gnutls_mpi_dprint;
Packit 549fdc
Packit 549fdc
	if (params == NULL) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_INVALID_REQUEST;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (curve)
Packit 549fdc
		*curve = params->curve;
Packit 549fdc
Packit 549fdc
	if (curve_is_eddsa(params->curve)) {
Packit 549fdc
		if (x) {
Packit 549fdc
			ret = _gnutls_set_datum(x, params->raw_pub.data, params->raw_pub.size);
Packit 549fdc
			if (ret < 0) {
Packit 549fdc
				return gnutls_assert_val(ret);
Packit 549fdc
			}
Packit 549fdc
		}
Packit 549fdc
Packit 549fdc
		if (y) {
Packit 549fdc
			y->data = NULL;
Packit 549fdc
			y->size = 0;
Packit 549fdc
		}
Packit 549fdc
Packit 549fdc
		if (k) {
Packit 549fdc
			ret = _gnutls_set_datum(k, params->raw_priv.data, params->raw_priv.size);
Packit 549fdc
			if (ret < 0) {
Packit 549fdc
				_gnutls_free_datum(x);
Packit 549fdc
				return gnutls_assert_val(ret);
Packit 549fdc
			}
Packit 549fdc
		}
Packit 549fdc
Packit 549fdc
		return 0;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
Packit 549fdc
	/* X */
Packit 549fdc
	if (x) {
Packit 549fdc
		ret = dprint(params->params[ECC_X], x);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			return ret;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* Y */
Packit 549fdc
	if (y) {
Packit 549fdc
		ret = dprint(params->params[ECC_Y], y);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			_gnutls_free_datum(x);
Packit 549fdc
			return ret;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
Packit 549fdc
	/* K */
Packit 549fdc
	if (k) {
Packit 549fdc
		ret = dprint(params->params[ECC_K], k);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			_gnutls_free_datum(x);
Packit 549fdc
			_gnutls_free_datum(y);
Packit 549fdc
			return ret;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
int
Packit 549fdc
pk_hash_data(gnutls_pk_algorithm_t pk, const mac_entry_st * hash,
Packit 549fdc
	     gnutls_pk_params_st * params,
Packit 549fdc
	     const gnutls_datum_t * data, gnutls_datum_t * digest)
Packit 549fdc
{
Packit 549fdc
	int ret;
Packit 549fdc
Packit 549fdc
	digest->size = _gnutls_hash_get_algo_len(hash);
Packit 549fdc
	digest->data = gnutls_malloc(digest->size);
Packit 549fdc
	if (digest->data == NULL) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_MEMORY_ERROR;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_hash_fast((gnutls_digest_algorithm_t)hash->id, data->data, data->size,
Packit 549fdc
			      digest->data);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
Packit 549fdc
      cleanup:
Packit 549fdc
	gnutls_free(digest->data);
Packit 549fdc
	return ret;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
Packit 549fdc
/* 
Packit 549fdc
 * This function will do RSA PKCS #1 1.5 encoding
Packit 549fdc
 * on the given digest. The given digest must be allocated
Packit 549fdc
 * and will be freed if replacement is required.
Packit 549fdc
 */
Packit 549fdc
int
Packit 549fdc
pk_prepare_hash(gnutls_pk_algorithm_t pk,
Packit 549fdc
		const mac_entry_st * hash, gnutls_datum_t * digest)
Packit 549fdc
{
Packit 549fdc
	int ret;
Packit 549fdc
	gnutls_datum_t old_digest = { digest->data, digest->size };
Packit 549fdc
Packit 549fdc
	switch (pk) {
Packit 549fdc
	case GNUTLS_PK_RSA:
Packit 549fdc
		if (unlikely(hash == NULL))
Packit 549fdc
			return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
Packit 549fdc
		/* Encode the digest as a DigestInfo
Packit 549fdc
		 */
Packit 549fdc
		if ((ret =
Packit 549fdc
		     encode_ber_digest_info(hash, &old_digest,
Packit 549fdc
					    digest)) != 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			return ret;
Packit 549fdc
		}
Packit 549fdc
Packit 549fdc
		_gnutls_free_datum(&old_digest);
Packit 549fdc
		break;
Packit 549fdc
	case GNUTLS_PK_RSA_PSS:
Packit 549fdc
	case GNUTLS_PK_DSA:
Packit 549fdc
	case GNUTLS_PK_ECDSA:
Packit 549fdc
	case GNUTLS_PK_EDDSA_ED25519:
Packit 549fdc
		break;
Packit 549fdc
	default:
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return GNUTLS_E_UNIMPLEMENTED_FEATURE;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
}