Beispiel #1
0
unsigned pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st * params)
{
	switch (pk) {
	case GNUTLS_PK_RSA:
		return _gnutls_mpi_get_nbits(params->params[RSA_MODULUS]);
	case GNUTLS_PK_DSA:
		return _gnutls_mpi_get_nbits(params->params[DSA_P]);
	case GNUTLS_PK_EC:
		return gnutls_ecc_curve_get_size(params->flags) * 8;
	default:
		return 0;
	}
}
Beispiel #2
0
/**
 * cdk_pk_get_nbits:
 * @pk: the public key
 *
 * Return the length of the public key in bits.
 * The meaning of length is actually the size of the 'prime'
 * object in the key. For RSA keys the modulus, for ElG/DSA
 * the size of the public prime.
 **/
int
cdk_pk_get_nbits (cdk_pubkey_t pk)
{
    if (!pk || !pk->mpi[0])
        return 0;
    return _gnutls_mpi_get_nbits (pk->mpi[0]);
}
Beispiel #3
0
/* You can use a NULL buf to get the output size only
 */
static cdk_error_t
mpi_to_buffer (bigint_t a, byte * buf, size_t buflen,
               size_t * r_nwritten, size_t * r_nbits)
{
    size_t nbits;
    int err;

    if (!a || !r_nwritten)
    {
        gnutls_assert ();
        return CDK_Inv_Value;
    }

    nbits = _gnutls_mpi_get_nbits (a);
    if (r_nbits)
        *r_nbits = nbits;

    if (r_nwritten)
        *r_nwritten = (nbits + 7) / 8 + 2;

    if ((nbits + 7) / 8 + 2 > buflen)
        return CDK_Too_Short;

    *r_nwritten = buflen;
    err = _gnutls_mpi_print (a, buf, r_nwritten);
    if (err < 0)
    {
        gnutls_assert ();
        return map_gnutls_error (err);
    }

    return 0;
}
Beispiel #4
0
/* A = g^a % N 
 * returns A and a (which is random)
 */
bigint_t
_gnutls_calc_srp_A (bigint_t * a, bigint_t g, bigint_t n)
{
  bigint_t tmpa;
  bigint_t A;
  int bits;

  bits = _gnutls_mpi_get_nbits (n);
  tmpa = _gnutls_mpi_randomize (NULL, bits, GNUTLS_RND_RANDOM);

  A = _gnutls_mpi_new (bits);
  if (A == NULL)
    {
      gnutls_assert ();
      _gnutls_mpi_release (&tmpa);
      return NULL;
    }
  _gnutls_mpi_powm (A, g, tmpa, n);

  if (a != NULL)
    *a = tmpa;
  else
    _gnutls_mpi_release (&tmpa);

  return A;
}
Beispiel #5
0
/**
 * gnutls_dh_params_export_raw - export the raw DH parameters
 * @params: Holds the DH parameters
 * @prime: will hold the new prime
 * @generator: will hold the new generator
 * @bits: if non null will hold is the prime's number of bits
 *
 * This function will export the pair of prime and generator for use
 * in the Diffie-Hellman key exchange.  The new parameters will be
 * allocated using gnutls_malloc() and will be stored in the
 * appropriate datum.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
 *   otherwise an error code is returned.
 **/
int
gnutls_dh_params_export_raw (gnutls_dh_params_t params,
                             gnutls_datum_t * prime,
                             gnutls_datum_t * generator, unsigned int *bits)
{
    int ret;

    if (params->params[1] == NULL || params->params[0] == NULL)
    {
        gnutls_assert ();
        return GNUTLS_E_INVALID_REQUEST;
    }

    ret = _gnutls_mpi_dprint (params->params[1], generator);
    if (ret < 0)
    {
        gnutls_assert ();
        return ret;
    }

    ret = _gnutls_mpi_dprint (params->params[0], prime);
    if (ret < 0)
    {
        gnutls_assert ();
        _gnutls_free_datum (generator);
        return ret;
    }

    if (bits)
        *bits = _gnutls_mpi_get_nbits (params->params[0]);

    return 0;

}
Beispiel #6
0
/* A = g^a % N 
 * returns A and a (which is random)
 */
mpi_t
_gnutls_calc_srp_A (mpi_t * a, mpi_t g, mpi_t n)
{
  mpi_t tmpa;
  mpi_t A;
  int bits;

  bits = _gnutls_mpi_get_nbits (n);
  tmpa = _gnutls_mpi_snew (bits);
  if (tmpa == NULL)
    {
      gnutls_assert ();
      return NULL;
    }

  _gnutls_mpi_randomize (tmpa, bits, GCRY_STRONG_RANDOM);

  A = _gnutls_mpi_snew (bits);
  if (A == NULL)
    {
      gnutls_assert ();
      _gnutls_mpi_release (&tmpa);
      return NULL;
    }
  _gnutls_mpi_powm (A, g, tmpa, n);

  if (a != NULL)
    *a = tmpa;
  else
    _gnutls_mpi_release (&tmpa);

  return A;
}
Beispiel #7
0
/**
 * gnutls_privkey_get_pk_algorithm:
 * @key: should contain a #gnutls_privkey_t type
 * @bits: If set will return the number of bits of the parameters (may be NULL)
 *
 * This function will return the public key algorithm of a private
 * key and if possible will return a number of bits that indicates
 * the security parameter of the key.
 *
 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
 *   success, or a negative error code on error.
 *
 * Since: 2.12.0
 **/
int gnutls_privkey_get_pk_algorithm(gnutls_privkey_t key, unsigned int *bits)
{
	switch (key->type) {
#ifdef ENABLE_OPENPGP
	case GNUTLS_PRIVKEY_OPENPGP:
		return gnutls_openpgp_privkey_get_pk_algorithm(key->key.openpgp,
							       bits);
#endif
#ifdef ENABLE_PKCS11
	case GNUTLS_PRIVKEY_PKCS11:
		return gnutls_pkcs11_privkey_get_pk_algorithm(key->key.pkcs11,
							      bits);
#endif
	case GNUTLS_PRIVKEY_X509:
		if (bits)
			*bits =
			    _gnutls_mpi_get_nbits(key->key.x509->
						  params.params[0]);
		return gnutls_x509_privkey_get_pk_algorithm(key->key.x509);
	case GNUTLS_PRIVKEY_EXT:
		if (bits)
			*bits = 0;
		return key->pk_algorithm;
	default:
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

}
Beispiel #8
0
/**
 * gnutls_dh_params_import_dsa:
 * @dh_params: The parameters
 * @key: holds a DSA private key
 *
 * This function will import the prime and generator of the DSA key for use 
 * in the Diffie-Hellman key exchange.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
 *   otherwise a negative error code is returned.
 **/
int
gnutls_dh_params_import_dsa(gnutls_dh_params_t dh_params, gnutls_x509_privkey_t key)
{
	gnutls_datum_t p, g, q;
	bigint_t tmp_q;
	int ret;

	ret = gnutls_x509_privkey_export_dsa_raw(key, &p, &q, &g, NULL, NULL);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret = _gnutls_mpi_init_scan_nz(&tmp_q, q.data, q.size);
	if (ret < 0) {
		gnutls_assert();
		ret = GNUTLS_E_MPI_SCAN_FAILED;
		goto cleanup;
	}

	ret = gnutls_dh_params_import_raw2(dh_params, &p, &g, _gnutls_mpi_get_nbits(tmp_q));

	_gnutls_mpi_release(&tmp_q);

 cleanup:
	gnutls_free(p.data);
	gnutls_free(g.data);
	gnutls_free(q.data);

	return ret;
}
Beispiel #9
0
/* This function reads the RSA parameters from the private key
 */
static int
_gnutls_get_private_rsa_params (gnutls_session_t session,
				bigint_t ** params, int *params_size)
{
  int bits;
  gnutls_certificate_credentials_t cred;
  gnutls_rsa_params_t rsa_params;

  cred = (gnutls_certificate_credentials_t)
    _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
  if (cred == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  if (session->internals.selected_cert_list == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  bits =
    _gnutls_mpi_get_nbits (session->internals.selected_cert_list[0].
			   params[0]);

  if (_gnutls_cipher_suite_get_kx_algo
      (&session->security_parameters.current_cipher_suite)
      == GNUTLS_KX_RSA_EXPORT && bits > 512)
    {

      rsa_params =
	_gnutls_certificate_get_rsa_params (cred->rsa_params,
					    cred->params_func, session);
      /* EXPORT case: */
      if (rsa_params == NULL)
	{
	  gnutls_assert ();
	  return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS;
	}

      /* In the export case, we do use temporary RSA params
       * of 512 bits size. The params in the certificate are
       * used to sign this temporary stuff.
       */
      *params_size = RSA_PRIVATE_PARAMS;
      *params = rsa_params->params;

      return 0;
    }

  /* non export cipher suites. */

  *params_size = session->internals.selected_key->params_size;
  *params = session->internals.selected_key->params;

  return 0;
}
Beispiel #10
0
int
_gnutls_gen_dh_common_client_kx_int(gnutls_session_t session,
				    gnutls_buffer_st * data,
				    gnutls_datum_t * pskkey)
{
	int ret;
	gnutls_pk_params_st peer_pub;
	gnutls_datum_t tmp_dh_key = {NULL, 0};
	
	gnutls_pk_params_init(&peer_pub);

	ret =
	    _gnutls_pk_generate_keys(GNUTLS_PK_DH, 0,
				     &session->key.dh_params, 1);
	if (ret < 0)
		return gnutls_assert_val(ret);

	_gnutls_dh_set_secret_bits(session, _gnutls_mpi_get_nbits(session->key.dh_params.params[DH_X]));

	ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_Y], 0);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}
	
	peer_pub.params[DH_Y] = session->key.client_Y;

	/* calculate the key after calculating the message */
	ret = _gnutls_pk_derive(GNUTLS_PK_DH, &tmp_dh_key, &session->key.dh_params, &peer_pub);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	if (_gnutls_cipher_suite_get_kx_algo
	    (session->security_parameters.cipher_suite)
	    != GNUTLS_KX_DHE_PSK) {
		session->key.key.data = tmp_dh_key.data;
		session->key.key.size = tmp_dh_key.size;
	} else {		/* In DHE_PSK the key is set differently */
		ret =
		    _gnutls_set_psk_session_key(session, pskkey,
						&tmp_dh_key);
		_gnutls_free_temp_key_datum(&tmp_dh_key);
	}

	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret = data->length;

 error:
	gnutls_pk_params_clear(&session->key.dh_params);
	return ret;
}
Beispiel #11
0
int
_gnutls_ecc_ansi_x963_export(gnutls_ecc_curve_t curve, bigint_t x,
			     bigint_t y, gnutls_datum_t * out)
{
	int numlen = gnutls_ecc_curve_get_size(curve);
	int byte_size, ret;
	size_t size;

	if (numlen == 0)
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

	out->size = 1 + 2 * numlen;

	out->data = gnutls_malloc(out->size);
	if (out->data == NULL)
		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

	memset(out->data, 0, out->size);

	/* store byte 0x04 */
	out->data[0] = 0x04;

	/* pad and store x */
	byte_size = (_gnutls_mpi_get_nbits(x) + 7) / 8;
	size = out->size - (1 + (numlen - byte_size));
	ret =
	    _gnutls_mpi_print(x, &out->data[1 + (numlen - byte_size)],
			      &size);
	if (ret < 0)
		return gnutls_assert_val(ret);

	byte_size = (_gnutls_mpi_get_nbits(y) + 7) / 8;
	size = out->size - (1 + (numlen + numlen - byte_size));
	ret =
	    _gnutls_mpi_print(y,
			      &out->data[1 + numlen + numlen - byte_size],
			      &size);
	if (ret < 0)
		return gnutls_assert_val(ret);

	/* pad and store y */
	return 0;
}
Beispiel #12
0
static size_t
calc_mpisize (bigint_t mpi[MAX_CDK_PK_PARTS], size_t ncount)
{
  size_t size, i;

  size = 0;
  for (i = 0; i < ncount; i++)
    size += (_gnutls_mpi_get_nbits (mpi[i]) + 7) / 8 + 2;
  return size;
}
Beispiel #13
0
/* returns the public value (X), and the secret (ret_x).
 */
mpi_t
gnutls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime)
{
  mpi_t e, x;
  int x_size = _gnutls_mpi_get_nbits (prime) - 1;
  /* The size of the secret key is less than
   * prime/2
   */

  if (x_size > MAX_BITS || x_size <= 0)
    {
      gnutls_assert ();
      return NULL;
    }

  x = _gnutls_mpi_new (x_size);
  if (x == NULL)
    {
      gnutls_assert ();
      if (ret_x)
	*ret_x = NULL;

      return NULL;
    }

  /* FIXME: (x_size/8)*8 is there to overcome a bug in libgcrypt
   * which does not really check the bits given but the bytes.
   */
  do
    {
      _gnutls_mpi_randomize (x, (x_size / 8) * 8, GCRY_STRONG_RANDOM);
      /* Check whether x is zero. 
       */
    }
  while (_gnutls_mpi_cmp_ui (x, 0) == 0);

  e = _gnutls_mpi_alloc_like (prime);
  if (e == NULL)
    {
      gnutls_assert ();
      if (ret_x)
	*ret_x = NULL;

      _gnutls_mpi_release (&x);
      return NULL;
    }

  _gnutls_mpi_powm (e, g, x, prime);

  if (ret_x)
    *ret_x = x;
  else
    _gnutls_mpi_release (&x);
  return e;
}
Beispiel #14
0
/* returns the blinded c and the inverse of a random
 * number r;
 */
static bigint_t
rsa_blind (bigint_t c, bigint_t e, bigint_t n, bigint_t * _ri)
{
  bigint_t nc = NULL, r = NULL, ri = NULL;

  /* nc = c*(r^e)
   * ri = r^(-1)
   */
  nc = _gnutls_mpi_alloc_like (n);
  if (nc == NULL)
    {
      gnutls_assert ();
      return NULL;
    }

  ri = _gnutls_mpi_alloc_like (n);
  if (nc == NULL)
    {
      gnutls_assert ();
      goto fail;
    }

  r = _gnutls_mpi_randomize (NULL, _gnutls_mpi_get_nbits (n),
                             GNUTLS_RND_NONCE);
  if (r == NULL)
    {
      gnutls_assert ();
      goto fail;
    }

  /* invert r */
  if (mpz_invert (ri, r, n) == 0)
    {
      gnutls_assert ();
      goto fail;
    }

  /* r = r^e */

  _gnutls_mpi_powm (r, r, e, n);

  _gnutls_mpi_mulm (nc, c, r, n);

  *_ri = ri;

  _gnutls_mpi_release (&r);

  return nc;
fail:
  _gnutls_mpi_release (&nc);
  _gnutls_mpi_release (&r);
  return NULL;
}
Beispiel #15
0
/**
 * gnutls_x509_privkey_sec_param:
 * @key: a key structure
 *
 * This function will return the security parameter appropriate with
 * this private key.
 *
 * Returns: On success, a valid security parameter is returned otherwise
 * %GNUTLS_SEC_PARAM_UNKNOWN is returned.
 **/
gnutls_sec_param_t
gnutls_x509_privkey_sec_param (gnutls_x509_privkey_t key)
{
  int ret;

  switch (key->pk_algorithm)
    {
    case GNUTLS_PK_RSA:
      ret = gnutls_pk_bits_to_sec_param (GNUTLS_PK_RSA, _gnutls_mpi_get_nbits (key->params[0]   /*m */
                                         ));
      break;
    case GNUTLS_PK_DSA:
      ret = gnutls_pk_bits_to_sec_param (GNUTLS_PK_DSA, _gnutls_mpi_get_nbits (key->params[0]   /*p */
                                         ));
      break;
    default:
      ret = GNUTLS_SEC_PARAM_UNKNOWN;
    }

  return ret;
}
Beispiel #16
0
static int
wrap_gcry_pk_fixup (gnutls_pk_algorithm_t algo,
                    gnutls_direction_t direction,
                    gnutls_pk_params_st * params)
{
  int ret, result;

  /* only for RSA we invert the coefficient --pgp type */

  if (algo != GNUTLS_PK_RSA)
    return 0;

  if (params->params[5] == NULL)
    params->params[5] =
      _gnutls_mpi_new (_gnutls_mpi_get_nbits (params->params[0]));

  if (params->params[5] == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  ret = 1;
  if (direction == GNUTLS_IMPORT)
    {
      /* calculate exp1 [6] and exp2 [7] */
      _gnutls_mpi_release (&params->params[6]);
      _gnutls_mpi_release (&params->params[7]);
      result = _gnutls_calc_rsa_exp (params->params, RSA_PRIVATE_PARAMS);
      if (result < 0)
        {
          gnutls_assert ();
          return result;
        }

      ret =
        gcry_mpi_invm (params->params[5], params->params[3],
                       params->params[4]);

      params->params_nr = RSA_PRIVATE_PARAMS;
    }
  else if (direction == GNUTLS_EXPORT)
    ret =
      gcry_mpi_invm (params->params[5], params->params[4], params->params[3]);
  if (ret == 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  return 0;
}
Beispiel #17
0
/*
 * Copyright (C) 2007-2012 Free Software Foundation, Inc.
 *
 * Author: Nikos Mavrogiannopoulos, Simon Josefsson
 *
 * This file is part of GnuTLS.
 *
 * GnuTLS is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * GnuTLS is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GnuTLS; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>

#include "utils.h"
#include "../lib/gnutls_int.h"
#include "../lib/gnutls_mpi.h"
#include "../lib/gnutls_errors.h"
#include "../lib/debug.h"

static void
tls_log_func (int level, const char *str)
{
  fprintf (stderr, "|<%d>| %s", level, str);
}

#define RND_BITS 510            /* not multiple of 8 */
void
doit (void)
{
  int rc;
  bigint_t n1, n2, n3, n4;

  gnutls_global_init ();

  gnutls_global_set_log_function (tls_log_func);
  if (debug)
    gnutls_global_set_log_level (99);

  n1 = _gnutls_mpi_new (1000);
  if (n1 == NULL)
    fail ("mpi_new failed\n");

  n2 = _gnutls_mpi_set_ui (NULL, 2);
  if (n2 == NULL)
    fail ("mpi_set_ui failed\n");

  n3 = _gnutls_mpi_set_ui (NULL, 5);
  if (n3 == NULL)
    fail ("mpi_set_ui failed\n");

  _gnutls_mpi_randomize (n1, RND_BITS, GNUTLS_RND_NONCE);

  _gnutls_mpi_log ("rand:", n1);

  rc = _gnutls_mpi_get_nbits (n1);
  if (rc > RND_BITS)
    fail ("mpi_get_nbits failed... returned %d\n", rc);

  n4 = _gnutls_mpi_addm (NULL, n1, n3, n2);
  if (n4 == NULL)
    fail ("mpi_set_ui failed\n");

  if (_gnutls_mpi_cmp_ui (n4, 0) != 0 && _gnutls_mpi_cmp_ui (n4, 1) != 0)
    fail ("mpi_cmp_ui failed\n");

  _gnutls_mpi_release (&n1);
  _gnutls_mpi_release (&n2);
  _gnutls_mpi_release (&n3);
  _gnutls_mpi_release (&n4);

  gnutls_global_deinit ();

  if (debug) success ("mpi ops ok\n");
}
Beispiel #18
0
static int mpi_buf2bits(gnutls_datum_t * mpi_buf)
{
	bigint_t mpi;
	int rc;

	rc = _gnutls_mpi_init_scan_nz(&mpi, mpi_buf->data, mpi_buf->size);
	if (rc) {
		gnutls_assert();
		return rc;
	}

	rc = _gnutls_mpi_get_nbits(mpi);
	_gnutls_mpi_release(&mpi);

	return rc;
}
Beispiel #19
0
int
_gnutls_dh_common_print_server_kx (gnutls_session_t session,
                                   bigint_t g, bigint_t p, unsigned int q_bits,
                                   gnutls_buffer_st* data)
{
  bigint_t x, Y;
  int ret;

  /* Y=g^x mod p */
  ret = gnutls_calc_dh_secret (&Y, &x, g, p, q_bits);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  session->key.dh_secret = x;
  _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));

  ret = _gnutls_buffer_append_mpi(data, 16, p, 0);
  if (ret < 0)
    {
      gnutls_assert();
      goto cleanup;
    }

  ret = _gnutls_buffer_append_mpi(data, 16, g, 0);
  if (ret < 0)
    {
      gnutls_assert();
      goto cleanup;
    }

  ret = _gnutls_buffer_append_mpi(data, 16, Y, 0);
  if (ret < 0)
    {
      gnutls_assert();
      goto cleanup;
    }
  
  ret = data->length;
cleanup:
  _gnutls_mpi_release (&Y);

  return ret;
}
Beispiel #20
0
int
_gnutls_dh_common_print_server_kx(gnutls_session_t session,
				  gnutls_buffer_st * data)
{
	int ret;
	unsigned q_bits = session->key.dh_params.flags;

	if (q_bits < 192 && q_bits != 0) {
		gnutls_assert();
		_gnutls_debug_log("too small q_bits value for DH: %u\n", q_bits);
		q_bits = 0; /* auto-detect */
	}

	/* Y=g^x mod p */
	ret =
	    _gnutls_pk_generate_keys(GNUTLS_PK_DH, q_bits,
				     &session->key.dh_params, 1);
	if (ret < 0)
		return gnutls_assert_val(ret);

	_gnutls_dh_set_secret_bits(session, _gnutls_mpi_get_nbits(session->key.dh_params.params[DH_X]));

	ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_P], 0);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_G], 0);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_Y], 0);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = data->length;

cleanup:
	return ret;
}
Beispiel #21
0
gnutls_digest_algorithm_t
_gnutls_dsa_q_to_hash (bigint_t q)
{
    int bits = _gnutls_mpi_get_nbits (q);

    if (bits <= 160)
    {
        return GNUTLS_DIG_SHA1;
    }
    else if (bits <= 224)
    {
        return GNUTLS_DIG_SHA224;
    }
    else
    {
        return GNUTLS_DIG_SHA256;
    }
}
Beispiel #22
0
static int
write_mpi (cdk_stream_t out, bigint_t m)
{
  byte buf[MAX_MPI_BYTES + 2];
  size_t nbits, nread;
  int err;

  if (!out || !m)
    return CDK_Inv_Value;
  nbits = _gnutls_mpi_get_nbits (m);
  if (nbits > MAX_MPI_BITS || nbits < 1)
    return CDK_MPI_Error;

  nread = MAX_MPI_BYTES + 2;
  err = _gnutls_mpi_print_pgp (m, buf, &nread);
  if (err < 0)
    return map_gnutls_error (err);
  return stream_write (out, buf, nread);
}
Beispiel #23
0
mpi_t
gnutls_calc_dh_key (mpi_t f, mpi_t x, mpi_t prime)
{
  mpi_t k;
  int bits;

  bits = _gnutls_mpi_get_nbits (prime);
  if (bits <= 0 || bits > MAX_BITS)
    {
      gnutls_assert ();
      return NULL;
    }

  k = _gnutls_mpi_alloc_like (prime);
  if (k == NULL)
    return NULL;
  _gnutls_mpi_powm (k, f, x, prime);
  return k;
}
Beispiel #24
0
/**
 * gnutls_dh_params_generate2:
 * @dparams: The parameters
 * @bits: is the prime's number of bits
 *
 * This function will generate a new pair of prime and generator for use in
 * the Diffie-Hellman key exchange. This may take long time.
 *
 * It is recommended not to set the number of bits directly, but 
 * use gnutls_sec_param_to_pk_bits() instead.

 * Also note that the DH parameters are only useful to servers.
 * Since clients use the parameters sent by the server, it's of
 * no use to call this in client side.
 *
 * The parameters generated are of the DSA form. It also is possible
 * to generate provable parameters (following the Shawe-Taylor
 * algorithm), using gnutls_x509_privkey_generate2() with DSA option
 * and the %GNUTLS_PRIVKEY_FLAG_PROVABLE flag set. These can the
 * be imported with gnutls_dh_params_import_dsa().
 *
 * It is no longer recommended for applications to generate parameters.
 * See the "Parameter generation" section in the manual.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
 *   otherwise a negative error code is returned.
 **/
int
gnutls_dh_params_generate2(gnutls_dh_params_t dparams, unsigned int bits)
{
	int ret;
	gnutls_pk_params_st params;

	gnutls_pk_params_init(&params);

	ret = _gnutls_pk_generate_params(GNUTLS_PK_DH, bits, &params);
	if (ret < 0)
		return gnutls_assert_val(ret);

	dparams->params[0] = params.params[DSA_P];
	dparams->params[1] = params.params[DSA_G];
	dparams->q_bits = _gnutls_mpi_get_nbits(params.params[DSA_Q]);

	_gnutls_mpi_release(&params.params[DSA_Q]);

	return 0;
}
Beispiel #25
0
gnutls_digest_algorithm_t
_gnutls_dsa_q_to_hash (bigint_t q, unsigned int* hash_len)
{
  int bits = _gnutls_mpi_get_nbits (q);

  if (bits <= 160)
    {
      if (hash_len) *hash_len = 20;
      return GNUTLS_DIG_SHA1;
    }
  else if (bits <= 224)
    {
      if (hash_len) *hash_len = 28;
      return GNUTLS_DIG_SHA256;
    }
  else
    {
      if (hash_len) *hash_len = 32;
      return GNUTLS_DIG_SHA256;
    }
}
Beispiel #26
0
/* if the peer's certificate is of 512 bits or less, returns non zero.
 */
int
_gnutls_peers_cert_less_512 (gnutls_session_t session)
{
  gnutls_cert peer_cert;
  int ret;
  cert_auth_info_t info = _gnutls_get_auth_info (session);

  if (info == NULL || info->ncerts == 0)
    {
      gnutls_assert ();
      /* we need this in order to get peer's certificate */
      return 0;
    }

  if ((ret =
       _gnutls_get_auth_info_gcert (&peer_cert,
				    session->security_parameters.cert_type,
				    info, CERT_NO_COPY)) < 0)
    {
      gnutls_assert ();
      return 0;
    }

  if (peer_cert.subject_pk_algorithm != GNUTLS_PK_RSA)
    {
      gnutls_assert ();
      _gnutls_gcert_deinit (&peer_cert);
      return 0;
    }

  if (_gnutls_mpi_get_nbits (peer_cert.params[0]) <= 512)
    {
      _gnutls_gcert_deinit (&peer_cert);
      return 1;
    }

  _gnutls_gcert_deinit (&peer_cert);

  return 0;
}
Beispiel #27
0
/**
  * gnutls_rsa_params_export_raw - This function will export the RSA parameters
  * @params: a structure that holds the rsa parameters
  * @m: will hold the modulus
  * @e: will hold the public exponent
  * @d: will hold the private exponent
  * @p: will hold the first prime (p)
  * @q: will hold the second prime (q)
  * @u: will hold the coefficient
  * @bits: if non null will hold the prime's number of bits
  *
  * This function will export the RSA parameters found in the given
  * structure. The new parameters will be allocated using
  * gnutls_malloc() and will be stored in the appropriate datum.
  * 
  **/
int
gnutls_rsa_params_export_raw (gnutls_rsa_params_t params,
			      gnutls_datum_t * m, gnutls_datum_t * e,
			      gnutls_datum_t * d, gnutls_datum_t * p,
			      gnutls_datum_t * q, gnutls_datum_t * u,
			      unsigned int *bits)
{
  int ret;

  ret = gnutls_x509_privkey_export_rsa_raw (params, m, e, d, p, q, u);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  if (bits)
    *bits = _gnutls_mpi_get_nbits (params->params[3]);

  return 0;

}
Beispiel #28
0
/* Hash an entire public key PK with the given message digest context
   MD. The @usefpr param is only valid for version 3 keys because of
   the different way to calculate the fingerprint. */
cdk_error_t
_cdk_hash_pubkey (cdk_pubkey_t pk, digest_hd_st * md, int usefpr)
{
  byte buf[12];
  size_t i, n, npkey;

  if (!pk || !md)
    return CDK_Inv_Value;

  if (usefpr && pk->version < 4 && is_RSA (pk->pubkey_algo))
    return hash_mpibuf (pk, md, 1);

  /* The version 4 public key packet does not have the 2 octets for
     the expiration date. */
  n = pk->version < 4 ? 8 : 6;
  npkey = cdk_pk_get_npkey (pk->pubkey_algo);
  for (i = 0; i < npkey; i++)
    n = n + (_gnutls_mpi_get_nbits (pk->mpi[i]) + 7) / 8 + 2;

  i = 0;
  buf[i++] = 0x99;
  buf[i++] = n >> 8;
  buf[i++] = n >> 0;
  buf[i++] = pk->version;
  buf[i++] = pk->timestamp >> 24;
  buf[i++] = pk->timestamp >> 16;
  buf[i++] = pk->timestamp >> 8;
  buf[i++] = pk->timestamp >> 0;

  if (pk->version < 4)
    {
      u16 a = 0;

      /* Convert the expiration date into days. */
      if (pk->expiredate)
	a = (u16) ((pk->expiredate - pk->timestamp) / 86400L);
      buf[i++] = a >> 8;
      buf[i++] = a;
    }
Beispiel #29
0
/* Do PKCS-1 RSA encryption. 
 * params is modulus, public exp.
 */
int
_gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
			   const gnutls_datum_t * plaintext,
			   mpi_t * params, unsigned params_len,
			   unsigned btype)
{
  unsigned int i, pad;
  int ret;
  mpi_t m, res;
  opaque *edata, *ps;
  size_t k, psize;
  size_t mod_bits;

  mod_bits = _gnutls_mpi_get_nbits (params[0]);
  k = mod_bits / 8;
  if (mod_bits % 8 != 0)
    k++;

  if (plaintext->size > k - 11)
    {
      gnutls_assert ();
      return GNUTLS_E_PK_ENCRYPTION_FAILED;
    }

  edata = gnutls_alloca (k);
  if (edata == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  /* EB = 00||BT||PS||00||D 
   * (use block type 'btype')
   */

  edata[0] = 0;
  edata[1] = btype;
  psize = k - 3 - plaintext->size;

  ps = &edata[2];
  switch (btype)
    {
    case 2:
      /* using public key */
      if (params_len < RSA_PUBLIC_PARAMS)
	{
	  gnutls_assert ();
	  gnutls_afree (edata);
	  return GNUTLS_E_INTERNAL_ERROR;
	}

      if (gc_pseudo_random (ps, psize) != GC_OK)
	{
	  gnutls_assert ();
	  gnutls_afree (edata);
	  return GNUTLS_E_RANDOM_FAILED;
	}
      for (i = 0; i < psize; i++)
	while (ps[i] == 0)
	  {
	    if (gc_pseudo_random (&ps[i], 1) != GC_OK)
	      {
		gnutls_assert ();
		gnutls_afree (edata);
		return GNUTLS_E_RANDOM_FAILED;
	      }
	  }
      break;
    case 1:
      /* using private key */

      if (params_len < RSA_PRIVATE_PARAMS)
	{
	  gnutls_assert ();
	  gnutls_afree (edata);
	  return GNUTLS_E_INTERNAL_ERROR;
	}

      for (i = 0; i < psize; i++)
	ps[i] = 0xff;
      break;
    default:
      gnutls_assert ();
      gnutls_afree (edata);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ps[psize] = 0;
  memcpy (&ps[psize + 1], plaintext->data, plaintext->size);

  if (_gnutls_mpi_scan_nz (&m, edata, &k) != 0)
    {
      gnutls_assert ();
      gnutls_afree (edata);
      return GNUTLS_E_MPI_SCAN_FAILED;
    }
  gnutls_afree (edata);

  if (btype == 2)		/* encrypt */
    ret = _gnutls_pk_encrypt (GCRY_PK_RSA, &res, m, params, params_len);
  else				/* sign */
    ret = _gnutls_pk_sign (GCRY_PK_RSA, &res, m, params, params_len);

  _gnutls_mpi_release (&m);

  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  _gnutls_mpi_print (NULL, &psize, res);

  if (psize < k)
    {
      /* padding psize */
      pad = k - psize;
      psize = k;
    }
  else if (psize == k)
    {
      pad = 0;
    }
  else
    {				/* psize > k !!! */
      /* This is an impossible situation */
      gnutls_assert ();
      _gnutls_mpi_release (&res);
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ciphertext->data = gnutls_malloc (psize);
  if (ciphertext->data == NULL)
    {
      gnutls_assert ();
      _gnutls_mpi_release (&res);
      return GNUTLS_E_MEMORY_ERROR;
    }
  _gnutls_mpi_print (&ciphertext->data[pad], &psize, res);
  for (i = 0; i < pad; i++)
    ciphertext->data[i] = 0;

  ciphertext->size = k;

  _gnutls_mpi_release (&res);

  return 0;
}
Beispiel #30
0
/* Do PKCS-1 RSA decryption. 
 * params is modulus, public exp., private key
 * Can decrypt block type 1 and type 2 packets.
 */
int
_gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
			   const gnutls_datum_t * ciphertext,
			   mpi_t * params, unsigned params_len,
			   unsigned btype)
{
  unsigned k, i;
  int ret;
  mpi_t c, res;
  opaque *edata;
  size_t esize, mod_bits;

  mod_bits = _gnutls_mpi_get_nbits (params[0]);
  k = mod_bits / 8;
  if (mod_bits % 8 != 0)
    k++;

  esize = ciphertext->size;

  if (esize != k)
    {
      gnutls_assert ();
      return GNUTLS_E_PK_DECRYPTION_FAILED;
    }

  if (_gnutls_mpi_scan_nz (&c, ciphertext->data, &esize) != 0)
    {
      gnutls_assert ();
      return GNUTLS_E_MPI_SCAN_FAILED;
    }

  /* we can use btype to see if the private key is
   * available.
   */
  if (btype == 2)
    ret = _gnutls_pk_decrypt (GCRY_PK_RSA, &res, c, params, params_len);
  else
    {
      ret = _gnutls_pk_encrypt (GCRY_PK_RSA, &res, c, params, params_len);
    }
  _gnutls_mpi_release (&c);

  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  _gnutls_mpi_print (NULL, &esize, res);
  edata = gnutls_alloca (esize + 1);
  if (edata == NULL)
    {
      gnutls_assert ();
      _gnutls_mpi_release (&res);
      return GNUTLS_E_MEMORY_ERROR;
    }
  _gnutls_mpi_print (&edata[1], &esize, res);

  _gnutls_mpi_release (&res);

  /* EB = 00||BT||PS||00||D
   * (use block type 'btype')
   *
   * From now on, return GNUTLS_E_DECRYPTION_FAILED on errors, to
   * avoid attacks similar to the one described by Bleichenbacher in:
   * "Chosen Ciphertext Attacks against Protocols Based on RSA
   * Encryption Standard PKCS #1".
   */


  edata[0] = 0;
  esize++;

  if (edata[0] != 0 || edata[1] != btype)
    {
      gnutls_assert ();
      gnutls_afree (edata);
      return GNUTLS_E_DECRYPTION_FAILED;
    }

  ret = GNUTLS_E_DECRYPTION_FAILED;
  switch (btype)
    {
    case 2:
      for (i = 2; i < esize; i++)
	{
	  if (edata[i] == 0)
	    {
	      ret = 0;
	      break;
	    }
	}
      break;
    case 1:
      for (i = 2; i < esize; i++)
	{
	  if (edata[i] == 0 && i > 2)
	    {
	      ret = 0;
	      break;
	    }
	  if (edata[i] != 0xff)
	    {
	      _gnutls_handshake_log ("PKCS #1 padding error");
	      /* PKCS #1 padding error.  Don't use
		 GNUTLS_E_PKCS1_WRONG_PAD here.  */
	      break;
	    }
	}
      break;
    default:
      gnutls_assert ();
      gnutls_afree (edata);
      break;
    }
  i++;

  if (ret < 0)
    {
      gnutls_assert ();
      gnutls_afree (edata);
      return GNUTLS_E_DECRYPTION_FAILED;
    }

  if (_gnutls_sset_datum (plaintext, &edata[i], esize - i) < 0)
    {
      gnutls_assert ();
      gnutls_afree (edata);
      return GNUTLS_E_MEMORY_ERROR;
    }

  gnutls_afree (edata);

  return 0;
}