Blame lib/x509/key_encode.c

Packit 549fdc
/*
Packit 549fdc
 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
Packit 549fdc
 * Copyright (C) 2013-2017 Red Hat
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
#include "gnutls_int.h"
Packit 549fdc
#include "errors.h"
Packit 549fdc
#include <global.h>
Packit 549fdc
#include <libtasn1.h>
Packit 549fdc
#include <datum.h>
Packit 549fdc
#include "common.h"
Packit 549fdc
#include "x509_int.h"
Packit 549fdc
#include <num.h>
Packit 549fdc
#include <pk.h>
Packit 549fdc
#include <mpi.h>
Packit 549fdc
#include <ecc.h>
Packit 549fdc
Packit 549fdc
static int _gnutls_x509_write_rsa_pubkey(gnutls_pk_params_st * params,
Packit 549fdc
					 gnutls_datum_t * der);
Packit 549fdc
static int _gnutls_x509_write_dsa_params(gnutls_pk_params_st * params,
Packit 549fdc
					 gnutls_datum_t * der);
Packit 549fdc
static int _gnutls_x509_write_dsa_pubkey(gnutls_pk_params_st * params,
Packit 549fdc
					 gnutls_datum_t * der);
Packit 549fdc
Packit 549fdc
/*
Packit 549fdc
 * some x509 certificate functions that relate to MPI parameter
Packit 549fdc
 * setting. This writes the BIT STRING subjectPublicKey.
Packit 549fdc
 * Needs 2 parameters (m,e).
Packit 549fdc
 *
Packit 549fdc
 * Allocates the space used to store the DER data.
Packit 549fdc
 */
Packit 549fdc
static int
Packit 549fdc
_gnutls_x509_write_rsa_pubkey(gnutls_pk_params_st * params,
Packit 549fdc
			      gnutls_datum_t * der)
Packit 549fdc
{
Packit 549fdc
	int result;
Packit 549fdc
	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
Packit 549fdc
Packit 549fdc
	der->data = NULL;
Packit 549fdc
	der->size = 0;
Packit 549fdc
Packit 549fdc
	if (params->params_nr < RSA_PUBLIC_PARAMS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		result = GNUTLS_E_INVALID_REQUEST;
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result = asn1_create_element
Packit 549fdc
	     (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPublicKey", &spk))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result =
Packit 549fdc
	    _gnutls_x509_write_int(spk, "modulus", params->params[0], 1);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result =
Packit 549fdc
	    _gnutls_x509_write_int(spk, "publicExponent",
Packit 549fdc
				   params->params[1], 1);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_der_encode(spk, "", der, 0);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = 0;
Packit 549fdc
Packit 549fdc
      cleanup:
Packit 549fdc
	asn1_delete_structure(&spk;;
Packit 549fdc
Packit 549fdc
	return result;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/*
Packit 549fdc
 * some x509 certificate functions that relate to MPI parameter
Packit 549fdc
 * setting. This writes an ECPoint.
Packit 549fdc
 *
Packit 549fdc
 * Allocates the space used to store the DER data.
Packit 549fdc
 */
Packit 549fdc
int
Packit 549fdc
_gnutls_x509_write_ecc_pubkey(gnutls_pk_params_st * params,
Packit 549fdc
			      gnutls_datum_t * der)
Packit 549fdc
{
Packit 549fdc
	int result;
Packit 549fdc
Packit 549fdc
	der->data = NULL;
Packit 549fdc
	der->size = 0;
Packit 549fdc
Packit 549fdc
	if (params->params_nr < ECC_PUBLIC_PARAMS)
Packit 549fdc
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
Packit 549fdc
Packit 549fdc
	result =
Packit 549fdc
	    _gnutls_ecc_ansi_x962_export(params->curve,
Packit 549fdc
					 params->params[ECC_X],
Packit 549fdc
					 params->params[ECC_Y], /*&out */
Packit 549fdc
					 der);
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
 * some x509 certificate functions that relate to MPI parameter
Packit 549fdc
 * setting. This writes a raw public key.
Packit 549fdc
 *
Packit 549fdc
 * Allocates the space used to store the data.
Packit 549fdc
 */
Packit 549fdc
int
Packit 549fdc
_gnutls_x509_write_eddsa_pubkey(gnutls_pk_params_st * params,
Packit 549fdc
			      gnutls_datum_t * raw)
Packit 549fdc
{
Packit 549fdc
	int ret;
Packit 549fdc
Packit 549fdc
	raw->data = NULL;
Packit 549fdc
	raw->size = 0;
Packit 549fdc
Packit 549fdc
	if (params->raw_pub.size == 0)
Packit 549fdc
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
Packit 549fdc
Packit 549fdc
	if (params->curve != GNUTLS_ECC_CURVE_ED25519)
Packit 549fdc
		return gnutls_assert_val(GNUTLS_E_ECC_UNSUPPORTED_CURVE);
Packit 549fdc
Packit 549fdc
	ret = _gnutls_set_datum(raw, params->raw_pub.data, params->raw_pub.size);
Packit 549fdc
	if (ret < 0)
Packit 549fdc
		return gnutls_assert_val(ret);
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
int
Packit 549fdc
_gnutls_x509_write_pubkey_params(gnutls_pk_params_st * params,
Packit 549fdc
				 gnutls_datum_t * der)
Packit 549fdc
{
Packit 549fdc
	switch (params->algo) {
Packit 549fdc
	case GNUTLS_PK_DSA:
Packit 549fdc
		return _gnutls_x509_write_dsa_params(params, der);
Packit 549fdc
	case GNUTLS_PK_RSA:
Packit 549fdc
		der->data = gnutls_malloc(ASN1_NULL_SIZE);
Packit 549fdc
		if (der->data == NULL)
Packit 549fdc
			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
Packit 549fdc
Packit 549fdc
		memcpy(der->data, ASN1_NULL, ASN1_NULL_SIZE);
Packit 549fdc
		der->size = ASN1_NULL_SIZE;
Packit 549fdc
		return 0;
Packit 549fdc
	case GNUTLS_PK_RSA_PSS:
Packit 549fdc
		return _gnutls_x509_write_rsa_pss_params(&params->spki, der);
Packit 549fdc
	case GNUTLS_PK_ECDSA:
Packit 549fdc
		return _gnutls_x509_write_ecc_params(params->curve, der);
Packit 549fdc
	case GNUTLS_PK_EDDSA_ED25519:
Packit 549fdc
		der->data = NULL;
Packit 549fdc
		der->size = 0;
Packit 549fdc
Packit 549fdc
		return 0;
Packit 549fdc
	default:
Packit 549fdc
		return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
Packit 549fdc
	}
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
int
Packit 549fdc
_gnutls_x509_write_pubkey(gnutls_pk_params_st * params,
Packit 549fdc
			  gnutls_datum_t * der)
Packit 549fdc
{
Packit 549fdc
	switch (params->algo) {
Packit 549fdc
	case GNUTLS_PK_DSA:
Packit 549fdc
		return _gnutls_x509_write_dsa_pubkey(params, der);
Packit 549fdc
	case GNUTLS_PK_RSA:
Packit 549fdc
	case GNUTLS_PK_RSA_PSS:
Packit 549fdc
		return _gnutls_x509_write_rsa_pubkey(params, der);
Packit 549fdc
	case GNUTLS_PK_ECDSA:
Packit 549fdc
		return _gnutls_x509_write_ecc_pubkey(params, der);
Packit 549fdc
	case GNUTLS_PK_EDDSA_ED25519:
Packit 549fdc
		return _gnutls_x509_write_eddsa_pubkey(params, der);
Packit 549fdc
	default:
Packit 549fdc
		return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
Packit 549fdc
	}
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/*
Packit 549fdc
 * This function writes the parameters for DSS keys.
Packit 549fdc
 * Needs 3 parameters (p,q,g).
Packit 549fdc
 *
Packit 549fdc
 * Allocates the space used to store the DER data.
Packit 549fdc
 */
Packit 549fdc
static int
Packit 549fdc
_gnutls_x509_write_dsa_params(gnutls_pk_params_st * params,
Packit 549fdc
			      gnutls_datum_t * der)
Packit 549fdc
{
Packit 549fdc
	int result;
Packit 549fdc
	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
Packit 549fdc
Packit 549fdc
	der->data = NULL;
Packit 549fdc
	der->size = 0;
Packit 549fdc
Packit 549fdc
	if (params->params_nr < DSA_PUBLIC_PARAMS - 1) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		result = GNUTLS_E_INVALID_REQUEST;
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result = asn1_create_element
Packit 549fdc
	     (_gnutls_get_gnutls_asn(), "GNUTLS.DSAParameters", &spk))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_write_int(spk, "p", params->params[0], 1);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_write_int(spk, "q", params->params[1], 1);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_write_int(spk, "g", params->params[2], 1);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_der_encode(spk, "", der, 0);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = 0;
Packit 549fdc
Packit 549fdc
      cleanup:
Packit 549fdc
	asn1_delete_structure(&spk;;
Packit 549fdc
	return result;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/*
Packit 549fdc
 * This function writes the parameters for ECC keys.
Packit 549fdc
 * That is the ECParameters struct.
Packit 549fdc
 *
Packit 549fdc
 * Allocates the space used to store the DER data.
Packit 549fdc
 */
Packit 549fdc
int
Packit 549fdc
_gnutls_x509_write_ecc_params(gnutls_ecc_curve_t curve,
Packit 549fdc
			      gnutls_datum_t * der)
Packit 549fdc
{
Packit 549fdc
	int result;
Packit 549fdc
	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
Packit 549fdc
	const char *oid;
Packit 549fdc
Packit 549fdc
	der->data = NULL;
Packit 549fdc
	der->size = 0;
Packit 549fdc
Packit 549fdc
	oid = gnutls_ecc_curve_get_oid(curve);
Packit 549fdc
	if (oid == NULL)
Packit 549fdc
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
Packit 549fdc
Packit 549fdc
Packit 549fdc
	if ((result = asn1_create_element
Packit 549fdc
	     (_gnutls_get_gnutls_asn(), "GNUTLS.ECParameters", &spk))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result =
Packit 549fdc
	     asn1_write_value(spk, "", "namedCurve", 1)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		result = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result =
Packit 549fdc
	     asn1_write_value(spk, "namedCurve", oid,
Packit 549fdc
			      1)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		result = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_der_encode(spk, "", der, 0);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = 0;
Packit 549fdc
Packit 549fdc
      cleanup:
Packit 549fdc
	asn1_delete_structure(&spk;;
Packit 549fdc
	return result;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
int
Packit 549fdc
_gnutls_x509_write_rsa_pss_params(gnutls_x509_spki_st *params,
Packit 549fdc
				  gnutls_datum_t *der)
Packit 549fdc
{
Packit 549fdc
	int result;
Packit 549fdc
	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
Packit 549fdc
	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
Packit 549fdc
	const char *oid;
Packit 549fdc
	gnutls_datum_t tmp = { NULL, 0 };
Packit 549fdc
Packit 549fdc
	der->data = NULL;
Packit 549fdc
	der->size = 0;
Packit 549fdc
Packit 549fdc
	if (params->pk != GNUTLS_PK_RSA_PSS)
Packit 549fdc
		return 0;
Packit 549fdc
Packit 549fdc
	/* refuse to write parameters we cannot read */
Packit 549fdc
	if (gnutls_pk_to_sign(GNUTLS_PK_RSA_PSS, params->rsa_pss_dig) == GNUTLS_SIGN_UNKNOWN)
Packit 549fdc
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
Packit 549fdc
Packit 549fdc
	if ((result = asn1_create_element
Packit 549fdc
	     (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPSSParameters", &spk))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		result = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	oid = gnutls_digest_get_oid(params->rsa_pss_dig);
Packit 549fdc
Packit 549fdc
	if ((result = asn1_write_value(spk, "hashAlgorithm.algorithm", oid, 1))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		result = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result = asn1_write_value(spk, "hashAlgorithm.parameters", NULL, 0))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		result = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result =
Packit 549fdc
	     asn1_write_value(spk, "maskGenAlgorithm.algorithm",
Packit 549fdc
			      PKIX1_RSA_PSS_MGF1_OID, 1))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		result = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result = asn1_create_element
Packit 549fdc
	     (_gnutls_get_pkix(), "PKIX1.AlgorithmIdentifier", &c2))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		result = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result = asn1_write_value(c2, "algorithm", oid, 1))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		result = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result = asn1_write_value(c2, "parameters", NULL, 0))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		result = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_der_encode(c2, "", &tmp, 0);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result =
Packit 549fdc
	     asn1_write_value(spk, "maskGenAlgorithm.parameters",
Packit 549fdc
			      tmp.data, tmp.size))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		result = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_write_uint32(spk, "saltLength",
Packit 549fdc
					   params->salt_size);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_write_uint32(spk, "trailerField", 1);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_der_encode(spk, "", der, 0);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = 0;
Packit 549fdc
Packit 549fdc
      cleanup:
Packit 549fdc
	_gnutls_free_datum(&tmp);
Packit 549fdc
	asn1_delete_structure(&c2;;
Packit 549fdc
	asn1_delete_structure(&spk;;
Packit 549fdc
	return result;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/*
Packit 549fdc
 * This function writes the public parameters for DSS keys.
Packit 549fdc
 * Needs 1 parameter (y).
Packit 549fdc
 *
Packit 549fdc
 * Allocates the space used to store the DER data.
Packit 549fdc
 */
Packit 549fdc
static int
Packit 549fdc
_gnutls_x509_write_dsa_pubkey(gnutls_pk_params_st * params,
Packit 549fdc
			      gnutls_datum_t * der)
Packit 549fdc
{
Packit 549fdc
	int result;
Packit 549fdc
	ASN1_TYPE spk = ASN1_TYPE_EMPTY;
Packit 549fdc
Packit 549fdc
	der->data = NULL;
Packit 549fdc
	der->size = 0;
Packit 549fdc
Packit 549fdc
	if (params->params_nr < DSA_PUBLIC_PARAMS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		result = GNUTLS_E_INVALID_REQUEST;
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result = asn1_create_element
Packit 549fdc
	     (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey", &spk))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_write_int(spk, "", params->params[3], 1);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = _gnutls_x509_der_encode(spk, "", der, 0);
Packit 549fdc
	if (result < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	result = 0;
Packit 549fdc
Packit 549fdc
      cleanup:
Packit 549fdc
	asn1_delete_structure(&spk;;
Packit 549fdc
	return result;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
Packit 549fdc
 */
Packit 549fdc
static int
Packit 549fdc
_gnutls_asn1_encode_rsa(ASN1_TYPE * c2, gnutls_pk_params_st * params)
Packit 549fdc
{
Packit 549fdc
	int result, ret;
Packit 549fdc
	uint8_t null = '\0';
Packit 549fdc
	gnutls_pk_params_st pk_params;
Packit 549fdc
Packit 549fdc
	/* we do copy the parameters into a new structure to run _gnutls_pk_fixup,
Packit 549fdc
	 * i.e., regenerate some parameters in case they were broken */
Packit 549fdc
	gnutls_pk_params_init(&pk_params);
Packit 549fdc
Packit 549fdc
	ret = _gnutls_pk_params_copy(&pk_params, params);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return ret;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* Ok. Now we have the data. Create the asn1 structures
Packit 549fdc
	 */
Packit 549fdc
Packit 549fdc
	/* first make sure that no previously allocated data are leaked */
Packit 549fdc
	if (*c2 != ASN1_TYPE_EMPTY) {
Packit 549fdc
		asn1_delete_structure(c2);
Packit 549fdc
		*c2 = ASN1_TYPE_EMPTY;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result = asn1_create_element
Packit 549fdc
	     (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPrivateKey", c2))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		ret = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* Write PRIME 
Packit 549fdc
	 */
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_x509_write_int(*c2, "modulus",
Packit 549fdc
				   params->params[RSA_MODULUS], 1);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_x509_write_int(*c2, "publicExponent",
Packit 549fdc
				   params->params[RSA_PUB], 1);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_x509_write_key_int(*c2, "privateExponent",
Packit 549fdc
				   params->params[RSA_PRIV], 1);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_x509_write_key_int(*c2, "prime1",
Packit 549fdc
				   params->params[RSA_PRIME1], 1);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_x509_write_key_int(*c2, "prime2",
Packit 549fdc
				   params->params[RSA_PRIME2], 1);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_x509_write_key_int(*c2, "coefficient",
Packit 549fdc
				   params->params[RSA_COEF], 1);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_x509_write_key_int(*c2, "exponent1",
Packit 549fdc
				   params->params[RSA_E1], 1);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_x509_write_key_int(*c2, "exponent2",
Packit 549fdc
				   params->params[RSA_E2], 1);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result = asn1_write_value(*c2, "otherPrimeInfos",
Packit 549fdc
				       NULL, 0)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		ret = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result =
Packit 549fdc
	     asn1_write_value(*c2, "version", &null, 1)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		ret = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret = 0;
Packit 549fdc
Packit 549fdc
      cleanup:
Packit 549fdc
	if (ret < 0)
Packit 549fdc
		asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
Packit 549fdc
Packit 549fdc
	gnutls_pk_params_clear(&pk_params);
Packit 549fdc
	gnutls_pk_params_release(&pk_params);
Packit 549fdc
	return ret;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/* Encodes the ECC parameters into an ASN.1 ECPrivateKey structure.
Packit 549fdc
 */
Packit 549fdc
static int
Packit 549fdc
_gnutls_asn1_encode_ecc(ASN1_TYPE * c2, gnutls_pk_params_st * params)
Packit 549fdc
{
Packit 549fdc
	int ret;
Packit 549fdc
	uint8_t one = '\x01';
Packit 549fdc
	gnutls_datum_t pubkey = { NULL, 0 };
Packit 549fdc
	const char *oid;
Packit 549fdc
Packit 549fdc
	oid = gnutls_ecc_curve_get_oid(params->curve);
Packit 549fdc
	if (oid == NULL)
Packit 549fdc
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
Packit 549fdc
Packit 549fdc
	/* first make sure that no previously allocated data are leaked */
Packit 549fdc
	if (*c2 != ASN1_TYPE_EMPTY) {
Packit 549fdc
		asn1_delete_structure(c2);
Packit 549fdc
		*c2 = ASN1_TYPE_EMPTY;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((ret = asn1_create_element
Packit 549fdc
	     (_gnutls_get_gnutls_asn(), "GNUTLS.ECPrivateKey", c2))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		ret = _gnutls_asn2err(ret);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((ret =
Packit 549fdc
	     asn1_write_value(*c2, "Version", &one, 1)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		ret = _gnutls_asn2err(ret);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if (curve_is_eddsa(params->curve)) {
Packit 549fdc
		if (params->raw_pub.size == 0 || params->raw_priv.size == 0)
Packit 549fdc
			return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
Packit 549fdc
		ret =
Packit 549fdc
		    asn1_write_value(*c2, "privateKey", params->raw_priv.data, params->raw_priv.size);
Packit 549fdc
		if (ret != ASN1_SUCCESS) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			ret = _gnutls_asn2err(ret);
Packit 549fdc
			goto cleanup;
Packit 549fdc
		}
Packit 549fdc
Packit 549fdc
		ret =
Packit 549fdc
		    asn1_write_value(*c2, "publicKey", params->raw_pub.data, params->raw_pub.size*8);
Packit 549fdc
		if (ret != ASN1_SUCCESS) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			ret = _gnutls_asn2err(ret);
Packit 549fdc
			goto cleanup;
Packit 549fdc
		}
Packit 549fdc
	} else {
Packit 549fdc
		if (params->params_nr != ECC_PRIVATE_PARAMS)
Packit 549fdc
			return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
Packit 549fdc
Packit 549fdc
		ret =
Packit 549fdc
		    _gnutls_ecc_ansi_x962_export(params->curve,
Packit 549fdc
						 params->params[ECC_X],
Packit 549fdc
						 params->params[ECC_Y], &pubkey);
Packit 549fdc
		if (ret < 0)
Packit 549fdc
			return gnutls_assert_val(ret);
Packit 549fdc
Packit 549fdc
		ret =
Packit 549fdc
		    _gnutls_x509_write_key_int(*c2, "privateKey",
Packit 549fdc
					   params->params[ECC_K], 1);
Packit 549fdc
		if (ret < 0) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			goto cleanup;
Packit 549fdc
		}
Packit 549fdc
Packit 549fdc
		if ((ret =
Packit 549fdc
		     asn1_write_value(*c2, "publicKey", pubkey.data,
Packit 549fdc
				      pubkey.size * 8)) != ASN1_SUCCESS) {
Packit 549fdc
			gnutls_assert();
Packit 549fdc
			ret = _gnutls_asn2err(ret);
Packit 549fdc
			goto cleanup;
Packit 549fdc
		}
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* write our choice */
Packit 549fdc
	if ((ret =
Packit 549fdc
	     asn1_write_value(*c2, "parameters", "namedCurve",
Packit 549fdc
			      1)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		ret = _gnutls_asn2err(ret);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((ret =
Packit 549fdc
	     asn1_write_value(*c2, "parameters.namedCurve", oid,
Packit 549fdc
			      1)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		ret = _gnutls_asn2err(ret);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	_gnutls_free_datum(&pubkey);
Packit 549fdc
	return 0;
Packit 549fdc
Packit 549fdc
cleanup:
Packit 549fdc
	asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
Packit 549fdc
	_gnutls_free_datum(&pubkey);
Packit 549fdc
Packit 549fdc
	return ret;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
Packit 549fdc
/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
Packit 549fdc
 */
Packit 549fdc
static int
Packit 549fdc
_gnutls_asn1_encode_dsa(ASN1_TYPE * c2, gnutls_pk_params_st * params)
Packit 549fdc
{
Packit 549fdc
	int result, ret;
Packit 549fdc
	const uint8_t null = '\0';
Packit 549fdc
Packit 549fdc
	/* first make sure that no previously allocated data are leaked */
Packit 549fdc
	if (*c2 != ASN1_TYPE_EMPTY) {
Packit 549fdc
		asn1_delete_structure(c2);
Packit 549fdc
		*c2 = ASN1_TYPE_EMPTY;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result = asn1_create_element
Packit 549fdc
	     (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPrivateKey", c2))
Packit 549fdc
	    != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		return _gnutls_asn2err(result);
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	/* Write PRIME 
Packit 549fdc
	 */
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_x509_write_int(*c2, "p",
Packit 549fdc
				   params->params[DSA_P], 1);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_x509_write_int(*c2, "q",
Packit 549fdc
				   params->params[DSA_Q], 1);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_x509_write_int(*c2, "g",
Packit 549fdc
				   params->params[DSA_G], 1);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_x509_write_int(*c2, "Y",
Packit 549fdc
				   params->params[DSA_Y], 1);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	ret =
Packit 549fdc
	    _gnutls_x509_write_key_int(*c2, "priv",
Packit 549fdc
				   params->params[DSA_X], 1);
Packit 549fdc
	if (ret < 0) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	if ((result =
Packit 549fdc
	     asn1_write_value(*c2, "version", &null, 1)) != ASN1_SUCCESS) {
Packit 549fdc
		gnutls_assert();
Packit 549fdc
		ret = _gnutls_asn2err(result);
Packit 549fdc
		goto cleanup;
Packit 549fdc
	}
Packit 549fdc
Packit 549fdc
	return 0;
Packit 549fdc
Packit 549fdc
cleanup:
Packit 549fdc
	asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
Packit 549fdc
Packit 549fdc
	return ret;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
int _gnutls_asn1_encode_privkey(ASN1_TYPE * c2,
Packit 549fdc
				gnutls_pk_params_st * params)
Packit 549fdc
{
Packit 549fdc
	switch (params->algo) {
Packit 549fdc
	case GNUTLS_PK_RSA:
Packit 549fdc
	case GNUTLS_PK_RSA_PSS:
Packit 549fdc
		return _gnutls_asn1_encode_rsa(c2, params);
Packit 549fdc
	case GNUTLS_PK_DSA:
Packit 549fdc
		return _gnutls_asn1_encode_dsa(c2, params);
Packit 549fdc
	case GNUTLS_PK_ECDSA:
Packit 549fdc
	case GNUTLS_PK_EDDSA_ED25519:
Packit 549fdc
		return _gnutls_asn1_encode_ecc(c2, params);
Packit 549fdc
	default:
Packit 549fdc
		return GNUTLS_E_UNIMPLEMENTED_FEATURE;
Packit 549fdc
	}
Packit 549fdc
}