|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* Copyright (C) 2000-2012 Free Software Foundation, Inc.
|
|
Packit Service |
4684c1 |
* Copyright (C) 2017 Red Hat, Inc.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Author: Nikos Mavrogiannopoulos
|
|
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 "errors.h"
|
|
Packit Service |
4684c1 |
#include <datum.h>
|
|
Packit Service |
4684c1 |
#include <x509_b64.h> /* for PKCS3 PEM decoding */
|
|
Packit Service |
4684c1 |
#include <global.h>
|
|
Packit Service |
4684c1 |
#include <dh.h>
|
|
Packit Service |
4684c1 |
#include <pk.h>
|
|
Packit Service |
4684c1 |
#include <x509/common.h>
|
|
Packit Service |
4684c1 |
#include <gnutls/crypto.h>
|
|
Packit Service |
4684c1 |
#include "x509/x509_int.h"
|
|
Packit Service |
4684c1 |
#include <mpi.h>
|
|
Packit Service |
4684c1 |
#include "debug.h"
|
|
Packit Service |
4684c1 |
#include "state.h"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static
|
|
Packit Service |
4684c1 |
int set_dh_pk_params(gnutls_session_t session, bigint_t g, bigint_t p,
|
|
Packit Service |
4684c1 |
bigint_t q, unsigned q_bits)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
/* just in case we are resuming a session */
|
|
Packit Service |
4684c1 |
gnutls_pk_params_release(&session->key.proto.tls12.dh.params);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_pk_params_init(&session->key.proto.tls12.dh.params);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session->key.proto.tls12.dh.params.params[DH_G] = _gnutls_mpi_copy(g);
|
|
Packit Service |
4684c1 |
if (session->key.proto.tls12.dh.params.params[DH_G] == NULL)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session->key.proto.tls12.dh.params.params[DH_P] = _gnutls_mpi_copy(p);
|
|
Packit Service |
4684c1 |
if (session->key.proto.tls12.dh.params.params[DH_P] == NULL) {
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(&session->key.proto.tls12.dh.params.params[DH_G]);
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (q) {
|
|
Packit Service |
4684c1 |
session->key.proto.tls12.dh.params.params[DH_Q] = _gnutls_mpi_copy(q);
|
|
Packit Service |
4684c1 |
if (session->key.proto.tls12.dh.params.params[DH_Q] == NULL) {
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(&session->key.proto.tls12.dh.params.params[DH_P]);
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(&session->key.proto.tls12.dh.params.params[DH_G]);
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
/* include, possibly empty, q */
|
|
Packit Service |
4684c1 |
session->key.proto.tls12.dh.params.params_nr = 3;
|
|
Packit Service |
4684c1 |
session->key.proto.tls12.dh.params.algo = GNUTLS_PK_DH;
|
|
Packit Service |
4684c1 |
session->key.proto.tls12.dh.params.qbits = q_bits;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Use all available information to decide the DH parameters to use,
|
|
Packit Service |
4684c1 |
* that being the negotiated RFC7919 group, the callback, and the
|
|
Packit Service |
4684c1 |
* provided parameters structure.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
_gnutls_figure_dh_params(gnutls_session_t session, gnutls_dh_params_t dh_params,
|
|
Packit Service |
4684c1 |
gnutls_params_function * func, gnutls_sec_param_t sec_param)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_params_st params;
|
|
Packit Service |
4684c1 |
bigint_t p, g, q = NULL;
|
|
Packit Service |
4684c1 |
unsigned free_pg = 0;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
unsigned q_bits = 0, i;
|
|
Packit Service |
4684c1 |
const gnutls_group_entry_st *group;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
group = get_group(session);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
params.deinit = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* if we negotiated RFC7919 FFDHE */
|
|
Packit Service |
4684c1 |
if (group && group->pk == GNUTLS_PK_DH) {
|
|
Packit Service |
4684c1 |
for (i=0;i<session->internals.priorities->groups.size;i++) {
|
|
Packit Service |
4684c1 |
if (session->internals.priorities->groups.entry[i] == group) {
|
|
Packit Service |
4684c1 |
ret = _gnutls_mpi_init_scan_nz(&p,
|
|
Packit Service |
4684c1 |
session->internals.priorities->groups.entry[i]->prime->data,
|
|
Packit Service |
4684c1 |
session->internals.priorities->groups.entry[i]->prime->size);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
free_pg = 1;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_mpi_init_scan_nz(&g,
|
|
Packit Service |
4684c1 |
session->internals.priorities->groups.entry[i]->generator->data,
|
|
Packit Service |
4684c1 |
session->internals.priorities->groups.entry[i]->generator->size);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_mpi_init_scan_nz(&q,
|
|
Packit Service |
4684c1 |
session->internals.priorities->groups.entry[i]->q->data,
|
|
Packit Service |
4684c1 |
session->internals.priorities->groups.entry[i]->q->size);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session->internals.hsk_flags |= HSK_USED_FFDHE;
|
|
Packit Service |
4684c1 |
q_bits = *session->internals.priorities->groups.entry[i]->q_bits;
|
|
Packit Service |
4684c1 |
goto finished;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* didn't find anything, that shouldn't have occurred
|
|
Packit Service |
4684c1 |
* as we received that extension */
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
|
|
Packit Service |
4684c1 |
} else if (sec_param) {
|
|
Packit Service |
4684c1 |
unsigned bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, sec_param)/8;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
for (i=0;i<session->internals.priorities->groups.size;i++) {
|
|
Packit Service |
4684c1 |
if (!session->internals.priorities->groups.entry[i]->prime)
|
|
Packit Service |
4684c1 |
continue;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (bits <= session->internals.priorities->groups.entry[i]->prime->size) {
|
|
Packit Service |
4684c1 |
ret = _gnutls_mpi_init_scan_nz(&p,
|
|
Packit Service |
4684c1 |
session->internals.priorities->groups.entry[i]->prime->data,
|
|
Packit Service |
4684c1 |
session->internals.priorities->groups.entry[i]->prime->size);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
free_pg = 1;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_mpi_init_scan_nz(&g,
|
|
Packit Service |
4684c1 |
session->internals.priorities->groups.entry[i]->generator->data,
|
|
Packit Service |
4684c1 |
session->internals.priorities->groups.entry[i]->generator->size);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
goto cleanup;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
q_bits = *session->internals.priorities->groups.entry[i]->q_bits;
|
|
Packit Service |
4684c1 |
goto finished;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (dh_params) {
|
|
Packit Service |
4684c1 |
p = dh_params->params[0];
|
|
Packit Service |
4684c1 |
g = dh_params->params[1];
|
|
Packit Service |
4684c1 |
q_bits = dh_params->q_bits;
|
|
Packit Service |
4684c1 |
} else if (func) {
|
|
Packit Service |
4684c1 |
ret = func(session, GNUTLS_PARAMS_DH, ¶ms);
|
|
Packit Service |
4684c1 |
if (ret == 0 && params.type == GNUTLS_PARAMS_DH) {
|
|
Packit Service |
4684c1 |
p = params.params.dh->params[0];
|
|
Packit Service |
4684c1 |
g = params.params.dh->params[1];
|
|
Packit Service |
4684c1 |
q_bits = params.params.dh->q_bits;
|
|
Packit Service |
4684c1 |
} else
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_NO_TEMPORARY_DH_PARAMS);
|
|
Packit Service |
4684c1 |
} else
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_NO_TEMPORARY_DH_PARAMS);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
finished:
|
|
Packit Service |
4684c1 |
_gnutls_dh_save_group(session, g, p);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = set_dh_pk_params(session, g, p, q, q_bits);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
cleanup:
|
|
Packit Service |
4684c1 |
if (free_pg) {
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(&p);
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(&q);
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(&g);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (params.deinit && params.type == GNUTLS_PARAMS_DH)
|
|
Packit Service |
4684c1 |
gnutls_dh_params_deinit(params.params.dh);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* returns the prime and the generator of DH params.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
const bigint_t *_gnutls_dh_params_to_mpi(gnutls_dh_params_t dh_primes)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (dh_primes == NULL || dh_primes->params[1] == NULL ||
|
|
Packit Service |
4684c1 |
dh_primes->params[0] == NULL) {
|
|
Packit Service |
4684c1 |
return NULL;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return dh_primes->params;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_dh_params_import_raw:
|
|
Packit Service |
4684c1 |
* @dh_params: The parameters
|
|
Packit Service |
4684c1 |
* @prime: holds the new prime
|
|
Packit Service |
4684c1 |
* @generator: holds the new generator
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will replace the pair of prime and generator for use
|
|
Packit Service |
4684c1 |
* in the Diffie-Hellman key exchange. The new parameters should be
|
|
Packit Service |
4684c1 |
* stored in the appropriate gnutls_datum.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
Packit Service |
4684c1 |
* otherwise a negative error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_dh_params_import_raw(gnutls_dh_params_t dh_params,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * prime,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * generator)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return gnutls_dh_params_import_raw2(dh_params, prime, generator, 0);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_dh_params_import_dsa:
|
|
Packit Service |
4684c1 |
* @dh_params: The parameters
|
|
Packit Service |
4684c1 |
* @key: holds a DSA private key
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will import the prime and generator of the DSA key for use
|
|
Packit Service |
4684c1 |
* in the Diffie-Hellman key exchange.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
Packit Service |
4684c1 |
* otherwise a negative error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_dh_params_import_dsa(gnutls_dh_params_t dh_params, gnutls_x509_privkey_t key)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_datum_t p, g, q;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_x509_privkey_export_dsa_raw(key, &p, &q, &g, NULL, NULL);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_dh_params_import_raw3(dh_params, &p, &q, &g);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(p.data);
|
|
Packit Service |
4684c1 |
gnutls_free(g.data);
|
|
Packit Service |
4684c1 |
gnutls_free(q.data);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_dh_params_import_raw2:
|
|
Packit Service |
4684c1 |
* @dh_params: The parameters
|
|
Packit Service |
4684c1 |
* @prime: holds the new prime
|
|
Packit Service |
4684c1 |
* @generator: holds the new generator
|
|
Packit Service |
4684c1 |
* @key_bits: the private key bits (set to zero when unknown)
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will replace the pair of prime and generator for use
|
|
Packit Service |
4684c1 |
* in the Diffie-Hellman key exchange. The new parameters should be
|
|
Packit Service |
4684c1 |
* stored in the appropriate gnutls_datum.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
Packit Service |
4684c1 |
* otherwise a negative error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_dh_params_import_raw2(gnutls_dh_params_t dh_params,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * prime,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * generator,
|
|
Packit Service |
4684c1 |
unsigned key_bits)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
bigint_t tmp_prime, tmp_g;
|
|
Packit Service |
4684c1 |
size_t siz;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
siz = prime->size;
|
|
Packit Service |
4684c1 |
if (_gnutls_mpi_init_scan_nz(&tmp_prime, prime->data, siz)) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MPI_SCAN_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
siz = generator->size;
|
|
Packit Service |
4684c1 |
if (_gnutls_mpi_init_scan_nz(&tmp_g, generator->data, siz)) {
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(&tmp_prime);
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MPI_SCAN_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* store the generated values
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
dh_params->params[0] = tmp_prime;
|
|
Packit Service |
4684c1 |
dh_params->params[1] = tmp_g;
|
|
Packit Service |
4684c1 |
dh_params->q_bits = key_bits;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_dh_params_import_raw3:
|
|
Packit Service |
4684c1 |
* @dh_params: The parameters
|
|
Packit Service |
4684c1 |
* @prime: holds the new prime
|
|
Packit Service |
4684c1 |
* @q: holds the subgroup if available, otherwise NULL
|
|
Packit Service |
4684c1 |
* @generator: holds the new generator
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will replace the pair of prime and generator for use
|
|
Packit Service |
4684c1 |
* in the Diffie-Hellman key exchange. The new parameters should be
|
|
Packit Service |
4684c1 |
* stored in the appropriate gnutls_datum.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
Packit Service |
4684c1 |
* otherwise a negative error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_dh_params_import_raw3(gnutls_dh_params_t dh_params,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * prime,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * q,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * generator)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
bigint_t tmp_p, tmp_g, tmp_q = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (_gnutls_mpi_init_scan_nz(&tmp_p, prime->data, prime->size)) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MPI_SCAN_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (_gnutls_mpi_init_scan_nz(&tmp_g, generator->data,
|
|
Packit Service |
4684c1 |
generator->size)) {
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(&tmp_p);
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MPI_SCAN_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (q) {
|
|
Packit Service |
4684c1 |
if (_gnutls_mpi_init_scan_nz(&tmp_q, q->data, q->size)) {
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(&tmp_p);
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(&tmp_g);
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MPI_SCAN_FAILED;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else if (_gnutls_fips_mode_enabled()) {
|
|
Packit Service |
4684c1 |
/* Mandatory in FIPS mode */
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_DH_PRIME_UNACCEPTABLE;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* store the generated values
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
dh_params->params[0] = tmp_p;
|
|
Packit Service |
4684c1 |
dh_params->params[1] = tmp_g;
|
|
Packit Service |
4684c1 |
dh_params->params[2] = tmp_q;
|
|
Packit Service |
4684c1 |
if (tmp_q)
|
|
Packit Service |
4684c1 |
dh_params->q_bits = _gnutls_mpi_get_nbits(tmp_q);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_dh_params_init:
|
|
Packit Service |
4684c1 |
* @dh_params: The parameters
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will initialize the DH parameters type.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
Packit Service |
4684c1 |
* otherwise a negative error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int gnutls_dh_params_init(gnutls_dh_params_t * dh_params)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
(*dh_params) = gnutls_calloc(1, sizeof(dh_params_st));
|
|
Packit Service |
4684c1 |
if (*dh_params == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_dh_params_deinit:
|
|
Packit Service |
4684c1 |
* @dh_params: The parameters
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will deinitialize the DH parameters type.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
void gnutls_dh_params_deinit(gnutls_dh_params_t dh_params)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (dh_params == NULL)
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(&dh_params->params[0]);
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(&dh_params->params[1]);
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(&dh_params->params[2]);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(dh_params);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_dh_params_cpy:
|
|
Packit Service |
4684c1 |
* @dst: Is the destination parameters, which should be initialized.
|
|
Packit Service |
4684c1 |
* @src: Is the source parameters
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will copy the DH parameters structure from source
|
|
Packit Service |
4684c1 |
* to destination. The destination should be already initialized.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
Packit Service |
4684c1 |
* otherwise a negative error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int gnutls_dh_params_cpy(gnutls_dh_params_t dst, gnutls_dh_params_t src)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (src == NULL)
|
|
Packit Service |
4684c1 |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
dst->params[0] = _gnutls_mpi_copy(src->params[0]);
|
|
Packit Service |
4684c1 |
dst->params[1] = _gnutls_mpi_copy(src->params[1]);
|
|
Packit Service |
4684c1 |
if (src->params[2])
|
|
Packit Service |
4684c1 |
dst->params[2] = _gnutls_mpi_copy(src->params[2]);
|
|
Packit Service |
4684c1 |
dst->q_bits = src->q_bits;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (dst->params[0] == NULL || dst->params[1] == NULL)
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_dh_params_generate2:
|
|
Packit Service |
4684c1 |
* @dparams: The parameters
|
|
Packit Service |
4684c1 |
* @bits: is the prime's number of bits
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will generate a new pair of prime and generator for use in
|
|
Packit Service |
4684c1 |
* the Diffie-Hellman key exchange. This may take long time.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* It is recommended not to set the number of bits directly, but
|
|
Packit Service |
4684c1 |
* use gnutls_sec_param_to_pk_bits() instead.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
* Also note that the DH parameters are only useful to servers.
|
|
Packit Service |
4684c1 |
* Since clients use the parameters sent by the server, it's of
|
|
Packit Service |
4684c1 |
* no use to call this in client side.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The parameters generated are of the DSA form. It also is possible
|
|
Packit Service |
4684c1 |
* to generate provable parameters (following the Shawe-Taylor
|
|
Packit Service |
4684c1 |
* algorithm), using gnutls_x509_privkey_generate2() with DSA option
|
|
Packit Service |
4684c1 |
* and the %GNUTLS_PRIVKEY_FLAG_PROVABLE flag set. These can the
|
|
Packit Service |
4684c1 |
* be imported with gnutls_dh_params_import_dsa().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* It is no longer recommended for applications to generate parameters.
|
|
Packit Service |
4684c1 |
* See the "Parameter generation" section in the manual.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
Packit Service |
4684c1 |
* otherwise a negative error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_dh_params_generate2(gnutls_dh_params_t dparams, unsigned int bits)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
gnutls_pk_params_st params;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_pk_params_init(¶ms);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_pk_generate_params(GNUTLS_PK_DH, bits, ¶ms);
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
dparams->params[0] = params.params[DSA_P];
|
|
Packit Service |
4684c1 |
dparams->params[1] = params.params[DSA_G];
|
|
Packit Service |
4684c1 |
dparams->q_bits = _gnutls_mpi_get_nbits(params.params[DSA_Q]);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(¶ms.params[DSA_Q]);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_dh_params_import_pkcs3:
|
|
Packit Service |
4684c1 |
* @params: The parameters
|
|
Packit Service |
4684c1 |
* @pkcs3_params: should contain a PKCS3 DHParams structure PEM or DER encoded
|
|
Packit Service |
4684c1 |
* @format: the format of params. PEM or DER.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will extract the DHParams found in a PKCS3 formatted
|
|
Packit Service |
4684c1 |
* structure. This is the format generated by "openssl dhparam" tool.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* If the structure is PEM encoded, it should have a header
|
|
Packit Service |
4684c1 |
* of "BEGIN DH PARAMETERS".
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
Packit Service |
4684c1 |
* otherwise a negative error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_dh_params_import_pkcs3(gnutls_dh_params_t params,
|
|
Packit Service |
4684c1 |
const gnutls_datum_t * pkcs3_params,
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_fmt_t format)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
ASN1_TYPE c2;
|
|
Packit Service |
4684c1 |
int result, need_free = 0;
|
|
Packit Service |
4684c1 |
unsigned int q_bits;
|
|
Packit Service |
4684c1 |
gnutls_datum_t _params;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (format == GNUTLS_X509_FMT_PEM) {
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
result = _gnutls_fbase64_decode("DH PARAMETERS",
|
|
Packit Service |
4684c1 |
pkcs3_params->data,
|
|
Packit Service |
4684c1 |
pkcs3_params->size,
|
|
Packit Service |
4684c1 |
&_params);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (result < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return result;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
need_free = 1;
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
_params.data = pkcs3_params->data;
|
|
Packit Service |
4684c1 |
_params.size = pkcs3_params->size;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if ((result = asn1_create_element
|
|
Packit Service |
4684c1 |
(_gnutls_get_gnutls_asn(), "GNUTLS.DHParameter", &c2))
|
|
Packit Service |
4684c1 |
!= ASN1_SUCCESS) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
if (need_free != 0) {
|
|
Packit Service |
4684c1 |
gnutls_free(_params.data);
|
|
Packit Service |
4684c1 |
_params.data = NULL;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
return _gnutls_asn2err(result);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* PKCS#3 doesn't specify whether DHParameter is encoded as
|
|
Packit Service |
4684c1 |
* BER or DER, thus we don't restrict libtasn1 to DER subset */
|
|
Packit Service |
4684c1 |
result = asn1_der_decoding(&c2, _params.data, _params.size, NULL);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (need_free != 0) {
|
|
Packit Service |
4684c1 |
gnutls_free(_params.data);
|
|
Packit Service |
4684c1 |
_params.data = NULL;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (result != ASN1_SUCCESS) {
|
|
Packit Service |
4684c1 |
/* couldn't decode DER */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_debug_log("DHParams: Decoding error %d\n", result);
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
asn1_delete_structure(&c2;;
|
|
Packit Service |
4684c1 |
return _gnutls_asn2err(result);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Read q length */
|
|
Packit Service |
4684c1 |
result = _gnutls_x509_read_uint(c2, "privateValueLength", &q_bits);
|
|
Packit Service |
4684c1 |
if (result < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
params->q_bits = 0;
|
|
Packit Service |
4684c1 |
} else
|
|
Packit Service |
4684c1 |
params->q_bits = q_bits;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Read PRIME
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
result = _gnutls_x509_read_int(c2, "prime", ¶ms->params[0]);
|
|
Packit Service |
4684c1 |
if (result < 0) {
|
|
Packit Service |
4684c1 |
asn1_delete_structure(&c2;;
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return result;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (_gnutls_mpi_cmp_ui(params->params[0], 0) == 0) {
|
|
Packit Service |
4684c1 |
asn1_delete_structure(&c2;;
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* read the generator
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
result = _gnutls_x509_read_int(c2, "base", ¶ms->params[1]);
|
|
Packit Service |
4684c1 |
if (result < 0) {
|
|
Packit Service |
4684c1 |
asn1_delete_structure(&c2;;
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(¶ms->params[0]);
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return result;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (_gnutls_mpi_cmp_ui(params->params[1], 0) == 0) {
|
|
Packit Service |
4684c1 |
asn1_delete_structure(&c2;;
|
|
Packit Service |
4684c1 |
_gnutls_mpi_release(¶ms->params[0]);
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
asn1_delete_structure(&c2;;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_dh_params_export_pkcs3:
|
|
Packit Service |
4684c1 |
* @params: Holds the DH parameters
|
|
Packit Service |
4684c1 |
* @format: the format of output params. One of PEM or DER.
|
|
Packit Service |
4684c1 |
* @params_data: will contain a PKCS3 DHParams structure PEM or DER encoded
|
|
Packit Service |
4684c1 |
* @params_data_size: holds the size of params_data (and will be replaced by the actual size of parameters)
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will export the given dh parameters to a PKCS3
|
|
Packit Service |
4684c1 |
* DHParams structure. This is the format generated by "openssl dhparam" tool.
|
|
Packit Service |
4684c1 |
* If the buffer provided is not long enough to hold the output, then
|
|
Packit Service |
4684c1 |
* GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* If the structure is PEM encoded, it will have a header
|
|
Packit Service |
4684c1 |
* of "BEGIN DH PARAMETERS".
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
Packit Service |
4684c1 |
* otherwise a negative error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_dh_params_export_pkcs3(gnutls_dh_params_t params,
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_fmt_t format,
|
|
Packit Service |
4684c1 |
unsigned char *params_data,
|
|
Packit Service |
4684c1 |
size_t * params_data_size)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_datum_t out = {NULL, 0};
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_dh_params_export2_pkcs3(params, format, &out;;
|
|
Packit Service |
4684c1 |
if (ret < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(ret);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (*params_data_size < (unsigned) out.size + 1) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
gnutls_free(out.data);
|
|
Packit Service |
4684c1 |
*params_data_size = out.size + 1;
|
|
Packit Service |
4684c1 |
return GNUTLS_E_SHORT_MEMORY_BUFFER;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
assert(out.data != NULL);
|
|
Packit Service |
4684c1 |
*params_data_size = out.size;
|
|
Packit Service |
4684c1 |
if (params_data) {
|
|
Packit Service |
4684c1 |
memcpy(params_data, out.data, out.size);
|
|
Packit Service |
4684c1 |
params_data[out.size] = 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(out.data);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_dh_params_export2_pkcs3:
|
|
Packit Service |
4684c1 |
* @params: Holds the DH parameters
|
|
Packit Service |
4684c1 |
* @format: the format of output params. One of PEM or DER.
|
|
Packit Service |
4684c1 |
* @out: will contain a PKCS3 DHParams structure PEM or DER encoded
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will export the given dh parameters to a PKCS3
|
|
Packit Service |
4684c1 |
* DHParams structure. This is the format generated by "openssl dhparam" tool.
|
|
Packit Service |
4684c1 |
* The data in @out will be allocated using gnutls_malloc().
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* If the structure is PEM encoded, it will have a header
|
|
Packit Service |
4684c1 |
* of "BEGIN DH PARAMETERS".
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
Packit Service |
4684c1 |
* otherwise a negative error code is returned.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Since: 3.1.3
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_dh_params_export2_pkcs3(gnutls_dh_params_t params,
|
|
Packit Service |
4684c1 |
gnutls_x509_crt_fmt_t format,
|
|
Packit Service |
4684c1 |
gnutls_datum_t * out)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
ASN1_TYPE c2;
|
|
Packit Service |
4684c1 |
int result;
|
|
Packit Service |
4684c1 |
size_t g_size, p_size;
|
|
Packit Service |
4684c1 |
uint8_t *p_data, *g_data;
|
|
Packit Service |
4684c1 |
uint8_t *all_data;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
_gnutls_mpi_print_lz(params->params[1], NULL, &g_size);
|
|
Packit Service |
4684c1 |
_gnutls_mpi_print_lz(params->params[0], NULL, &p_size);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
all_data = gnutls_malloc(g_size + p_size);
|
|
Packit Service |
4684c1 |
if (all_data == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
p_data = &all_data[0];
|
|
Packit Service |
4684c1 |
_gnutls_mpi_print_lz(params->params[0], p_data, &p_size);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
g_data = &all_data[p_size];
|
|
Packit Service |
4684c1 |
_gnutls_mpi_print_lz(params->params[1], g_data, &g_size);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Ok. Now we have the data. Create the asn1 structures
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if ((result = asn1_create_element
|
|
Packit Service |
4684c1 |
(_gnutls_get_gnutls_asn(), "GNUTLS.DHParameter", &c2))
|
|
Packit Service |
4684c1 |
!= ASN1_SUCCESS) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
gnutls_free(all_data);
|
|
Packit Service |
4684c1 |
return _gnutls_asn2err(result);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Write PRIME
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if ((result = asn1_write_value(c2, "prime",
|
|
Packit Service |
4684c1 |
p_data, p_size)) != ASN1_SUCCESS) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
gnutls_free(all_data);
|
|
Packit Service |
4684c1 |
asn1_delete_structure(&c2;;
|
|
Packit Service |
4684c1 |
return _gnutls_asn2err(result);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (params->q_bits > 0)
|
|
Packit Service |
4684c1 |
result =
|
|
Packit Service |
4684c1 |
_gnutls_x509_write_uint32(c2, "privateValueLength",
|
|
Packit Service |
4684c1 |
params->q_bits);
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
result =
|
|
Packit Service |
4684c1 |
asn1_write_value(c2, "privateValueLength", NULL, 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (result < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
gnutls_free(all_data);
|
|
Packit Service |
4684c1 |
asn1_delete_structure(&c2;;
|
|
Packit Service |
4684c1 |
return _gnutls_asn2err(result);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Write the GENERATOR
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
if ((result = asn1_write_value(c2, "base",
|
|
Packit Service |
4684c1 |
g_data, g_size)) != ASN1_SUCCESS) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
gnutls_free(all_data);
|
|
Packit Service |
4684c1 |
asn1_delete_structure(&c2;;
|
|
Packit Service |
4684c1 |
return _gnutls_asn2err(result);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(all_data);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (format == GNUTLS_X509_FMT_DER) {
|
|
Packit Service |
4684c1 |
result = _gnutls_x509_der_encode(c2, "", out, 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
asn1_delete_structure(&c2;;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (result < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(result);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
} else { /* PEM */
|
|
Packit Service |
4684c1 |
gnutls_datum_t t;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
result = _gnutls_x509_der_encode(c2, "", &t, 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
asn1_delete_structure(&c2;;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (result < 0)
|
|
Packit Service |
4684c1 |
return gnutls_assert_val(result);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
result =
|
|
Packit Service |
4684c1 |
_gnutls_fbase64_encode("DH PARAMETERS", t.data, t.size,
|
|
Packit Service |
4684c1 |
out);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_free(t.data);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (result < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return result;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/**
|
|
Packit Service |
4684c1 |
* gnutls_dh_params_export_raw:
|
|
Packit Service |
4684c1 |
* @params: Holds the DH parameters
|
|
Packit Service |
4684c1 |
* @prime: will hold the new prime
|
|
Packit Service |
4684c1 |
* @generator: will hold the new generator
|
|
Packit Service |
4684c1 |
* @bits: if non null will hold the secret key's number of bits
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This function will export the pair of prime and generator for use
|
|
Packit Service |
4684c1 |
* in the Diffie-Hellman key exchange. The new parameters will be
|
|
Packit Service |
4684c1 |
* allocated using gnutls_malloc() and will be stored in the
|
|
Packit Service |
4684c1 |
* appropriate datum.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
|
|
Packit Service |
4684c1 |
* otherwise a negative error code is returned.
|
|
Packit Service |
4684c1 |
**/
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
gnutls_dh_params_export_raw(gnutls_dh_params_t params,
|
|
Packit Service |
4684c1 |
gnutls_datum_t * prime,
|
|
Packit Service |
4684c1 |
gnutls_datum_t * generator, unsigned int *bits)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (params->params[1] == NULL || params->params[0] == NULL) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_mpi_dprint(params->params[1], generator);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = _gnutls_mpi_dprint(params->params[0], prime);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
gnutls_assert();
|
|
Packit Service |
4684c1 |
_gnutls_free_datum(generator);
|
|
Packit Service |
4684c1 |
return ret;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (bits)
|
|
Packit Service |
4684c1 |
*bits = params->q_bits;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|