Beispiel #1
0
static void deinit_keys(gnutls_session_t session)
{
	gnutls_pk_params_release(&session->key.ecdh_params);
	gnutls_pk_params_release(&session->key.dh_params);
	zrelease_temp_mpi_key(&session->key.ecdh_x);
	zrelease_temp_mpi_key(&session->key.ecdh_y);
	_gnutls_free_temp_key_datum(&session->key.ecdhx);

	zrelease_temp_mpi_key(&session->key.client_Y);

	/* SRP */
	zrelease_temp_mpi_key(&session->key.srp_p);
	zrelease_temp_mpi_key(&session->key.srp_g);
	zrelease_temp_mpi_key(&session->key.srp_key);

	zrelease_temp_mpi_key(&session->key.u);
	zrelease_temp_mpi_key(&session->key.a);
	zrelease_temp_mpi_key(&session->key.x);
	zrelease_temp_mpi_key(&session->key.A);
	zrelease_temp_mpi_key(&session->key.B);
	zrelease_temp_mpi_key(&session->key.b);

	_gnutls_free_temp_key_datum(&session->key.key);
	_gnutls_free_temp_key_datum(&session->key.key);
}
Beispiel #2
0
/**
 * gnutls_privkey_export_ecc_raw:
 * @key: Holds the public key
 * @curve: will hold the curve
 * @x: will hold the x coordinate
 * @y: will hold the y coordinate
 * @k: will hold the private key
 *
 * This function will export the ECC private key's parameters found
 * in the given structure. The new parameters will be allocated using
 * gnutls_malloc() and will be stored in the appropriate datum.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
 *
 * Since: 3.3.0
 **/
int
gnutls_privkey_export_ecc_raw(gnutls_privkey_t key,
				       gnutls_ecc_curve_t * curve,
				       gnutls_datum_t * x,
				       gnutls_datum_t * y,
				       gnutls_datum_t * k)
{
gnutls_pk_params_st params;
int ret;

	if (key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}
	
	gnutls_pk_params_init(&params);

	ret = _gnutls_privkey_get_mpis(key, &params);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret = _gnutls_params_get_ecc_raw(&params, curve, x, y, k);

	gnutls_pk_params_release(&params);

	return ret;
}
Beispiel #3
0
/**
 * gnutls_privkey_export_dsa_raw:
 * @key: Holds the public key
 * @p: will hold the p
 * @q: will hold the q
 * @g: will hold the g
 * @y: will hold the y
 * @x: will hold the x
 *
 * This function will export the DSA private key's parameters found
 * in the given structure. The new parameters will be allocated using
 * gnutls_malloc() and will be stored in the appropriate datum.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
 *
 * Since: 3.3.0
 **/
int
gnutls_privkey_export_dsa_raw(gnutls_privkey_t key,
			     gnutls_datum_t * p, gnutls_datum_t * q,
			     gnutls_datum_t * g, gnutls_datum_t * y,
			     gnutls_datum_t * x)
{
gnutls_pk_params_st params;
int ret;

	if (key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}
	
	gnutls_pk_params_init(&params);

	ret = _gnutls_privkey_get_mpis(key, &params);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret = _gnutls_params_get_dsa_raw(&params, p, q, g, y, x);

	gnutls_pk_params_release(&params);

	return ret;
}
Beispiel #4
0
/**
 * gnutls_deinit:
 * @session: is a #gnutls_session_t structure.
 *
 * This function clears all buffers associated with the @session.
 * This function will also remove session data from the session
 * database if the session was terminated abnormally.
 **/
void
gnutls_deinit (gnutls_session_t session)
{
  unsigned int i;

  if (session == NULL)
    return;

  _gnutls_rnd_refresh();

  /* remove auth info firstly */
  _gnutls_free_auth_info (session);

  _gnutls_handshake_internal_state_clear (session);
  _gnutls_handshake_io_buffer_clear (session);
  _gnutls_ext_free_session_data (session);

  for (i = 0; i < MAX_EPOCH_INDEX; i++)
    if (session->record_parameters[i] != NULL)
      {
        _gnutls_epoch_free (session, session->record_parameters[i]);
        session->record_parameters[i] = NULL;
      }

  _gnutls_buffer_clear (&session->internals.handshake_hash_buffer);
  _gnutls_buffer_clear (&session->internals.hb_remote_data);
  _gnutls_buffer_clear (&session->internals.hb_local_data);
  _gnutls_buffer_clear (&session->internals.record_presend_buffer);

  _mbuffer_head_clear (&session->internals.record_buffer);
  _mbuffer_head_clear (&session->internals.record_recv_buffer);
  _mbuffer_head_clear (&session->internals.record_send_buffer);

  gnutls_credentials_clear (session);
  _gnutls_selected_certs_deinit (session);

  gnutls_pk_params_release(&session->key.ecdh_params);
  _gnutls_mpi_release (&session->key.ecdh_x);
  _gnutls_mpi_release (&session->key.ecdh_y);

  _gnutls_mpi_release (&session->key.KEY);
  _gnutls_mpi_release (&session->key.client_Y);
  _gnutls_mpi_release (&session->key.client_p);
  _gnutls_mpi_release (&session->key.client_g);

  _gnutls_mpi_release (&session->key.u);
  _gnutls_mpi_release (&session->key.a);
  _gnutls_mpi_release (&session->key.x);
  _gnutls_mpi_release (&session->key.A);
  _gnutls_mpi_release (&session->key.B);
  _gnutls_mpi_release (&session->key.b);

  /* RSA */
  _gnutls_mpi_release (&session->key.rsa[0]);
  _gnutls_mpi_release (&session->key.rsa[1]);

  _gnutls_mpi_release (&session->key.dh_secret);
  
  gnutls_free (session);
}
Beispiel #5
0
static
int set_dh_pk_params(gnutls_session_t session, bigint_t g, bigint_t p,
			unsigned q_bits)
{
	/* just in case we are resuming a session */
	gnutls_pk_params_release(&session->key.proto.tls12.dh.params);

	gnutls_pk_params_init(&session->key.proto.tls12.dh.params);

	session->key.proto.tls12.dh.params.params[DH_G] = _gnutls_mpi_copy(g);
	if (session->key.proto.tls12.dh.params.params[DH_G] == NULL)
		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

	session->key.proto.tls12.dh.params.params[DH_P] = _gnutls_mpi_copy(p);
	if (session->key.proto.tls12.dh.params.params[DH_P] == NULL) {
		_gnutls_mpi_release(&session->key.proto.tls12.dh.params.params[DH_G]);
		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
	}

	session->key.proto.tls12.dh.params.params_nr = 3; /* include empty q */
	session->key.proto.tls12.dh.params.algo = GNUTLS_PK_DH;
	session->key.proto.tls12.dh.params.qbits = q_bits;

	return 0;
}
Beispiel #6
0
/* verifies if the certificate is properly signed.
 * returns GNUTLS_E_PK_VERIFY_SIG_FAILED on failure and 1 on success.
 * 
 * 'data' is the signed data
 * 'signature' is the signature!
 */
int
_gnutls_x509_verify_data (gnutls_digest_algorithm_t algo,
                          const gnutls_datum_t * data,
                          const gnutls_datum_t * signature,
                          gnutls_x509_crt_t issuer)
{
  gnutls_pk_params_st issuer_params;
  int ret;

  /* Read the MPI parameters from the issuer's certificate.
   */
  ret =
    _gnutls_x509_crt_get_mpis (issuer, &issuer_params);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  ret =
    pubkey_verify_data (gnutls_x509_crt_get_pk_algorithm (issuer, NULL), algo,
                        data, signature, &issuer_params);
  if (ret < 0)
    {
      gnutls_assert ();
    }

  /* release all allocated MPIs
   */
  gnutls_pk_params_release(&issuer_params);

  return ret;
}
Beispiel #7
0
/**
 * gnutls_pubkey_deinit:
 * @key: The key to be deinitialized
 *
 * This function will deinitialize a public key structure.
 *
 * Since: 2.12.0
 **/
void gnutls_pubkey_deinit(gnutls_pubkey_t key)
{
	if (!key)
		return;
	gnutls_pk_params_release(&key->params);
	gnutls_free(key);
}
Beispiel #8
0
/* some generic pk functions */
static int
_generate_params (int algo, bigint_t * resarr, unsigned int *resarr_len,
                  int bits)
{
  gnutls_pk_params_st params;
  int ret;
  unsigned int i;

  ret = _gnutls_pk_ops.generate (algo, bits, &params);

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

  if (resarr && resarr_len && *resarr_len >= params.params_nr)
    {
      *resarr_len = params.params_nr;
      for (i = 0; i < params.params_nr; i++)
        resarr[i] = params.params[i];
    }
  else
    {
      gnutls_pk_params_release(&params);
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }
  return 0;
}
Beispiel #9
0
void _gnutls_x509_privkey_reinit(gnutls_x509_privkey_t key)
{
	gnutls_pk_params_clear(&key->params);
	gnutls_pk_params_release(&key->params);
	asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);
	key->key = ASN1_TYPE_EMPTY;
}
Beispiel #10
0
/**
 * gnutls_privkey_export_rsa_raw:
 * @key: Holds the certificate
 * @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
 * @e1: will hold e1 = d mod (p-1)
 * @e2: will hold e2 = d mod (q-1)
 *
 * This function will export the RSA private key's parameters found
 * in the given structure. The new parameters will be allocated using
 * gnutls_malloc() and will be stored in the appropriate datum.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
 *
 * Since: 3.3.0
 **/
int
gnutls_privkey_export_rsa_raw(gnutls_privkey_t key,
				    gnutls_datum_t * m, gnutls_datum_t * e,
				    gnutls_datum_t * d, gnutls_datum_t * p,
				    gnutls_datum_t * q, gnutls_datum_t * u,
				    gnutls_datum_t * e1,
				    gnutls_datum_t * e2)
{
gnutls_pk_params_st params;
int ret;

	if (key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}
	
	gnutls_pk_params_init(&params);

	ret = _gnutls_privkey_get_mpis(key, &params);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret = _gnutls_params_get_rsa_raw(&params, m, e, d, p, q, u, e1, e2);

	gnutls_pk_params_release(&params);

	return ret;
}
Beispiel #11
0
/*-
 * _gnutls_openpgp_privkey_decrypt_data:
 * @key: Holds the key
 * @flags: (0) for now
 * @ciphertext: holds the data to be decrypted
 * @plaintext: will contain newly allocated plaintext
 *
 * This function will sign the given hash using the private key.  You
 * should use gnutls_openpgp_privkey_set_preferred_key_id() before
 * calling this function to set the subkey to use.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 -*/
int
_gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key,
                                     unsigned int flags,
                                     const gnutls_datum_t * ciphertext,
                                     gnutls_datum_t * plaintext)
{
  int result, i;
  gnutls_pk_params_st params;
  int pk_algorithm;
  uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];
  char buf[2*GNUTLS_OPENPGP_KEYID_SIZE+1];

  if (key == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  result = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid);
  if (result == 0)
    {
      uint32_t kid[2];

      KEYID_IMPORT (kid, keyid);

      _gnutls_hard_log("Decrypting using PGP key ID %s\n", _gnutls_bin2hex(keyid, GNUTLS_OPENPGP_KEYID_SIZE, buf, sizeof(buf), NULL));

      result = _gnutls_openpgp_privkey_get_mpis (key, kid, &params);

      i = gnutls_openpgp_privkey_get_subkey_idx (key, keyid);

      pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL);
    }
  else
    {
      _gnutls_hard_log("Decrypting using master PGP key\n");

      pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL);

      result = _gnutls_openpgp_privkey_get_mpis (key, NULL, &params);

    }

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

  result = _gnutls_pk_decrypt (pk_algorithm, plaintext, ciphertext, &params);

  gnutls_pk_params_clear(&params);
  gnutls_pk_params_release(&params);

  if (result < 0)
    return gnutls_assert_val(result);

  return 0;
}
Beispiel #12
0
/**
 * gnutls_x509_privkey_generate:
 * @key: should contain a #gnutls_x509_privkey_t structure
 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
 * @bits: the size of the modulus
 * @flags: unused for now.  Must be 0.
 *
 * This function will generate a random private key. Note that this
 * function must be called on an empty private key.
 *
 * Note that when generating an elliptic curve key, the curve
 * can be substituted in the place of the bits parameter using the
 * GNUTLS_CURVE_TO_BITS() macro.
 *
 * For DSA keys, if the subgroup size needs to be specified check
 * the GNUTLS_SUBGROUP_TO_BITS() macro.
 *
 * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits().
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_privkey_generate(gnutls_x509_privkey_t key,
			     gnutls_pk_algorithm_t algo, unsigned int bits,
			     unsigned int flags)
{
	int ret;

	if (key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	gnutls_pk_params_init(&key->params);

	if (algo == GNUTLS_PK_EC) {
		if (GNUTLS_BITS_ARE_CURVE(bits))
			bits = GNUTLS_BITS_TO_CURVE(bits);
		else
			bits = _gnutls_ecc_bits_to_curve(bits);
	}

	ret = _gnutls_pk_generate_params(algo, bits, &key->params);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	ret = _gnutls_pk_generate_keys(algo, bits, &key->params);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

#ifndef ENABLE_FIPS140
	ret = _gnutls_pk_verify_priv_params(algo, &key->params);
#else
	ret = pct_test(algo, &key->params);
#endif
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	ret = _gnutls_asn1_encode_privkey(algo, &key->key, &key->params);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}
	key->pk_algorithm = algo;

	return 0;

      cleanup:
	key->pk_algorithm = GNUTLS_PK_UNKNOWN;
	gnutls_pk_params_clear(&key->params);
	gnutls_pk_params_release(&key->params);

	return ret;
}
Beispiel #13
0
/* Returns the public key of the private key (if possible)
 */
int
_gnutls_privkey_get_public_mpis(gnutls_privkey_t key,
				gnutls_pk_params_st * params)
{
	int ret;
	gnutls_pk_algorithm_t pk =
	    gnutls_privkey_get_pk_algorithm(key, NULL);

	switch (key->type) {
#ifdef ENABLE_OPENPGP
	case GNUTLS_PRIVKEY_OPENPGP:
		{
			gnutls_pk_params_st tmp_params;
			uint32_t kid[2];
			uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE];

			ret =
			    gnutls_openpgp_privkey_get_preferred_key_id
			    (key->key.openpgp, keyid);
			if (ret == 0) {
				KEYID_IMPORT(kid, keyid);
				ret =
				    _gnutls_openpgp_privkey_get_mpis(key->
								     key.
								     openpgp,
								     kid,
								     &tmp_params);
			} else
				ret =
				    _gnutls_openpgp_privkey_get_mpis(key->
								     key.
								     openpgp,
								     NULL,
								     &tmp_params);

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

			ret = privkey_to_pubkey(pk, &tmp_params, params);

			gnutls_pk_params_release(&tmp_params);
		}

		break;
#endif
	case GNUTLS_PRIVKEY_X509:
		ret = privkey_to_pubkey(pk,
					&key->key.x509->params, params);
		break;
	default:
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	return ret;
}
Beispiel #14
0
/* If the psk flag is set, then an empty psk_identity_hint will
 * be inserted */
int _gnutls_ecdh_common_print_server_kx(gnutls_session_t session,
					gnutls_buffer_st * data,
					gnutls_ecc_curve_t curve)
{
	uint8_t p;
	int ret;
	gnutls_datum_t out;

	if (curve == GNUTLS_ECC_CURVE_INVALID)
		return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES);

	/* just in case we are resuming a session */
	gnutls_pk_params_release(&session->key.ecdh_params);

	gnutls_pk_params_init(&session->key.ecdh_params);

	/* curve type */
	p = 3;

	ret = _gnutls_buffer_append_data(data, &p, 1);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret =
	    _gnutls_buffer_append_prefix(data, 16,
					 _gnutls_ecc_curve_get_tls_id
					 (curve));
	if (ret < 0)
		return gnutls_assert_val(ret);

	/* generate temporal key */
	ret =
	    _gnutls_pk_generate_keys(GNUTLS_PK_EC, curve,
				     &session->key.ecdh_params);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret =
	    _gnutls_ecc_ansi_x963_export(curve,
					 session->key.ecdh_params.
					 params[ECC_X] /* x */ ,
					 session->key.ecdh_params.
					 params[ECC_Y] /* y */ , &out);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret =
	    _gnutls_buffer_append_data_prefix(data, 8, out.data, out.size);

	_gnutls_free_datum(&out);

	if (ret < 0)
		return gnutls_assert_val(ret);

	return data->length;
}
/**
 * gnutls_x509_privkey_deinit:
 * @key: The structure to be deinitialized
 *
 * This function will deinitialize a private key structure.
 **/
void
gnutls_x509_privkey_deinit (gnutls_x509_privkey_t key)
{
  if (!key)
    return;

  gnutls_pk_params_release(&key->params);
  asn1_delete_structure (&key->key);
  gnutls_free (key);
}
/**
 * gnutls_x509_privkey_import_ecc_raw:
 * @key: The structure to store the parsed key
 * @curve: holds the curve
 * @x: holds the x
 * @y: holds the y
 * @k: holds the k
 *
 * This function will convert the given elliptic curve parameters to the
 * native #gnutls_x509_privkey_t format.  The output will be stored
 * in @key.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.0
 **/
int
gnutls_x509_privkey_import_ecc_raw (gnutls_x509_privkey_t key,
                                    gnutls_ecc_curve_t curve,
                                    const gnutls_datum_t * x,
                                    const gnutls_datum_t * y,
                                    const gnutls_datum_t * k)
{
  int ret;

  if (key == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  key->params.flags = curve;

  ret = _gnutls_ecc_curve_fill_params(curve, &key->params);
  if (ret < 0)
    return gnutls_assert_val(ret);

  if (_gnutls_mpi_scan_nz (&key->params.params[ECC_X], x->data, x->size))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  if (_gnutls_mpi_scan_nz (&key->params.params[ECC_Y], y->data, y->size))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  if (_gnutls_mpi_scan_nz (&key->params.params[ECC_K], k->data, k->size))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  key->pk_algorithm = GNUTLS_PK_EC;

  return 0;

cleanup:
  gnutls_pk_params_release(&key->params);
  return ret;

}
Beispiel #17
0
/**
 * gnutls_pubkey_import_privkey:
 * @key: The public key
 * @pkey: The private key
 * @usage: GNUTLS_KEY_* key usage flags.
 * @flags: should be zero
 *
 * Imports the public key from a private.  This function will import
 * the given public key to the abstract #gnutls_pubkey_t type.
 *
 * Note that in certain keys this operation may not be possible, e.g.,
 * in other than RSA PKCS#11 keys.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 2.12.0
 **/
int
gnutls_pubkey_import_privkey(gnutls_pubkey_t key, gnutls_privkey_t pkey,
			     unsigned int usage, unsigned int flags)
{
	gnutls_pk_params_release(&key->params);
	gnutls_pk_params_init(&key->params);

	key->pk_algorithm =
	    gnutls_privkey_get_pk_algorithm(pkey, &key->bits);

	key->key_usage = usage;

	return _gnutls_privkey_get_public_mpis(pkey, &key->params);
}
Beispiel #18
0
static int calc_ecdh_key( gnutls_session_t session, gnutls_datum_t * psk_key)
{
gnutls_pk_params_st pub;
int ret;

  memset(&pub,0,sizeof(pub));
  pub.params[ECC_PRIME] = session->key.ecdh_params.params[ECC_PRIME];
  pub.params[ECC_ORDER] = session->key.ecdh_params.params[ECC_ORDER];
  pub.params[ECC_A] = session->key.ecdh_params.params[ECC_A];
  pub.params[ECC_B] = session->key.ecdh_params.params[ECC_B];
  pub.params[ECC_GX] = session->key.ecdh_params.params[ECC_GX];
  pub.params[ECC_GY] = session->key.ecdh_params.params[ECC_GY];
  pub.params[ECC_X] = session->key.ecdh_x;
  pub.params[ECC_Y] = session->key.ecdh_y;

  if (psk_key == NULL)
    ret = _gnutls_pk_derive(GNUTLS_PK_EC, &session->key.key, &session->key.ecdh_params, &pub);
  else
    {
      gnutls_datum_t tmp_dh_key;

      ret = _gnutls_pk_derive(GNUTLS_PK_EC, &tmp_dh_key, &session->key.ecdh_params, &pub);
      if (ret < 0)
        {
          ret = gnutls_assert_val(ret);
          goto cleanup;
        }

      ret = _gnutls_set_psk_session_key (session, psk_key, &tmp_dh_key);
      _gnutls_free_datum (&tmp_dh_key);
    }

  
  if (ret < 0)
    {
      ret = gnutls_assert_val(ret);
      goto cleanup;
    }
    
  ret = 0;

cleanup:
  /* no longer needed */
  _gnutls_mpi_release (&session->key.ecdh_x);
  _gnutls_mpi_release (&session->key.ecdh_y);
  gnutls_pk_params_release( &session->key.ecdh_params);
  return ret;

}
Beispiel #19
0
static int calc_ecdh_key(gnutls_session_t session,
			 gnutls_datum_t * psk_key,
			 gnutls_ecc_curve_t curve)
{
	gnutls_pk_params_st pub;
	int ret;

	gnutls_pk_params_init(&pub);
	pub.params[ECC_X] = session->key.ecdh_x;
	pub.params[ECC_Y] = session->key.ecdh_y;
	pub.flags = curve;

	if (psk_key == NULL) {
		ret =
		    _gnutls_pk_derive(GNUTLS_PK_EC, &session->key.key,
				      &session->key.ecdh_params, &pub);
	} else {
		gnutls_datum_t tmp_dh_key;

		ret =
		    _gnutls_pk_derive(GNUTLS_PK_EC, &tmp_dh_key,
				      &session->key.ecdh_params, &pub);
		if (ret < 0) {
			ret = gnutls_assert_val(ret);
			goto cleanup;
		}

		ret =
		    _gnutls_set_psk_session_key(session, psk_key,
						&tmp_dh_key);
		_gnutls_free_temp_key_datum(&tmp_dh_key);
	}

	if (ret < 0) {
		ret = gnutls_assert_val(ret);
		goto cleanup;
	}

	ret = 0;

      cleanup:
	/* no longer needed */
	_gnutls_mpi_release(&session->key.ecdh_x);
	_gnutls_mpi_release(&session->key.ecdh_y);
	gnutls_pk_params_release(&session->key.ecdh_params);
	return ret;
}
Beispiel #20
0
/* Reads and returns the PK algorithm of the given certificate-like
 * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo".
 */
int
_gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
                               unsigned int *bits)
{
  int result;
  int algo;
  char oid[64];
  int len;
  gnutls_pk_params_st params;
  char name[128];

  gnutls_pk_params_init(&params);

  _asnstr_append_name (name, sizeof (name), src_name, ".algorithm.algorithm");
  len = sizeof (oid);
  result = asn1_read_value (src, name, oid, &len);

  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  algo = _gnutls_x509_oid2pk_algorithm (oid);
  if (algo == GNUTLS_PK_UNKNOWN)
    {
      _gnutls_debug_log
        ("%s: unknown public key algorithm: %s\n", __func__, oid);
    }

  if (bits == NULL)
    {
      return algo;
    }

  /* Now read the parameters' bits 
   */
  result = _gnutls_get_asn_mpis(src, src_name, &params);
  if (result < 0)
    return gnutls_assert_val(result);

  bits[0] = pubkey_to_bits(algo, &params);

  gnutls_pk_params_release(&params);
  return algo;
}
Beispiel #21
0
int
_gnutls_proc_ecdh_common_server_kx(gnutls_session_t session,
				   uint8_t * data, size_t _data_size)
{
	int i, ret, point_size;
	gnutls_ecc_curve_t curve;
	ssize_t data_size = _data_size;

	/* just in case we are resuming a session */
	gnutls_pk_params_release(&session->key.ecdh_params);

	gnutls_pk_params_init(&session->key.ecdh_params);

	i = 0;
	DECR_LEN(data_size, 1);
	if (data[i++] != 3)
		return gnutls_assert_val(GNUTLS_E_ECC_NO_SUPPORTED_CURVES);

	DECR_LEN(data_size, 2);
	curve = _gnutls_tls_id_to_ecc_curve(_gnutls_read_uint16(&data[i]));
	i += 2;

	ret = _gnutls_session_supports_ecc_curve(session, curve);
	if (ret < 0)
		return gnutls_assert_val(ret);

	_gnutls_session_ecc_curve_set(session, curve);

	DECR_LEN(data_size, 1);
	point_size = data[i];
	i++;

	DECR_LEN(data_size, point_size);
	ret =
	    _gnutls_ecc_ansi_x963_import(&data[i], point_size,
					 &session->key.ecdh_x,
					 &session->key.ecdh_y);
	if (ret < 0)
		return gnutls_assert_val(ret);

	i += point_size;

	return i;
}
/**
 * gnutls_x509_privkey_generate:
 * @key: should contain a #gnutls_x509_privkey_t structure
 * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
 * @bits: the size of the modulus
 * @flags: unused for now.  Must be 0.
 *
 * This function will generate a random private key. Note that this
 * function must be called on an empty private key.
 *
 * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits().
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_privkey_generate (gnutls_x509_privkey_t key,
                              gnutls_pk_algorithm_t algo, unsigned int bits,
                              unsigned int flags)
{
  int ret;

  if (key == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  gnutls_pk_params_init(&key->params);
  
  if (algo == GNUTLS_PK_EC)
    bits = _gnutls_ecc_bits_to_curve(bits);

  ret = _gnutls_pk_generate (algo, bits, &key->params);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  ret = _gnutls_asn1_encode_privkey (algo, &key->key, &key->params);
  if (ret < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }
  key->pk_algorithm = algo;

  return 0;

cleanup:
  key->pk_algorithm = GNUTLS_PK_UNKNOWN;
  gnutls_pk_params_release(&key->params);

  return ret;
}
Beispiel #23
0
/**
 * gnutls_privkey_verify_params:
 * @key: should contain a #gnutls_privkey_t type
 *
 * This function will verify the private key parameters.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.3.0
 **/
int gnutls_privkey_verify_params(gnutls_privkey_t key)
{
	gnutls_pk_params_st params;
	int ret;

	gnutls_pk_params_init(&params);

	ret = _gnutls_privkey_get_mpis(key, &params);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret = _gnutls_pk_verify_priv_params(key->pk_algorithm, &params);

	gnutls_pk_params_release(&params);

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

	return 0;
}
Beispiel #24
0
int
_gnutls_privkey_get_public_mpis(gnutls_privkey_t key,
				gnutls_pk_params_st * params)
{
	int ret;
	gnutls_pk_params_st tmp1;

	gnutls_pk_params_init(&tmp1);

	ret = _gnutls_privkey_get_mpis(key, &tmp1);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret = privkey_to_pubkey(key->pk_algorithm, &tmp1, params);

	gnutls_pk_params_release(&tmp1);

	if (ret < 0)
		gnutls_assert();

	return ret;
}
Beispiel #25
0
/**
 * gnutls_pubkey_import_x509_crq:
 * @key: The public key
 * @crq: The certificate to be imported
 * @flags: should be zero
 *
 * This function will import the given public key to the abstract
 * #gnutls_pubkey_t type.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.1.5
 **/
int
gnutls_pubkey_import_x509_crq(gnutls_pubkey_t key, gnutls_x509_crq_t crq,
			      unsigned int flags)
{
	int ret;

	gnutls_pk_params_release(&key->params);
	/* params initialized in _gnutls_x509_crq_get_mpis */

	key->pk_algorithm =
	    gnutls_x509_crq_get_pk_algorithm(crq, &key->bits);

	ret = gnutls_x509_crq_get_key_usage(crq, &key->key_usage, NULL);
	if (ret < 0)
		key->key_usage = 0;

	ret = _gnutls_x509_crq_get_mpis(crq, &key->params);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	return 0;
}
/**
 * gnutls_x509_privkey_import_dsa_raw:
 * @key: The structure to store the parsed key
 * @p: holds the p
 * @q: holds the q
 * @g: holds the g
 * @y: holds the y
 * @x: holds the x
 *
 * This function will convert the given DSA raw parameters to the
 * native #gnutls_x509_privkey_t format.  The output will be stored
 * in @key.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key,
                                    const gnutls_datum_t * p,
                                    const gnutls_datum_t * q,
                                    const gnutls_datum_t * g,
                                    const gnutls_datum_t * y,
                                    const gnutls_datum_t * x)
{
  int ret;
  size_t siz = 0;

  if (key == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  siz = p->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[0], p->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }

  siz = q->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[1], q->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }

  siz = g->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[2], g->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }

  siz = y->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[3], y->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }

  siz = x->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[4], x->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }

  ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_DSA, &key->key, &key->params);
  if (ret < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  key->params.params_nr = DSA_PRIVATE_PARAMS;
  key->pk_algorithm = GNUTLS_PK_DSA;

  return 0;

cleanup:
  gnutls_pk_params_release(&key->params);
  return ret;

}
/**
 * gnutls_x509_privkey_import_rsa_raw2:
 * @key: The structure to store the parsed key
 * @m: holds the modulus
 * @e: holds the public exponent
 * @d: holds the private exponent
 * @p: holds the first prime (p)
 * @q: holds the second prime (q)
 * @u: holds the coefficient
 * @e1: holds e1 = d mod (p-1)
 * @e2: holds e2 = d mod (q-1)
 *
 * This function will convert the given RSA raw parameters to the
 * native #gnutls_x509_privkey_t format.  The output will be stored in
 * @key.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key,
                                     const gnutls_datum_t * m,
                                     const gnutls_datum_t * e,
                                     const gnutls_datum_t * d,
                                     const gnutls_datum_t * p,
                                     const gnutls_datum_t * q,
                                     const gnutls_datum_t * u,
                                     const gnutls_datum_t * e1,
                                     const gnutls_datum_t * e2)
{
  int ret;
  size_t siz = 0;

  if (key == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  gnutls_pk_params_init(&key->params);

  siz = m->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  siz = e->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  siz = d->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[2], d->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  siz = p->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[3], p->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  siz = q->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[4], q->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  siz = u->size;
  if (_gnutls_mpi_scan_nz (&key->params.params[5], u->data, siz))
    {
      gnutls_assert ();
      ret = GNUTLS_E_MPI_SCAN_FAILED;
      goto cleanup;
    }
  key->params.params_nr++;

  if (e1 && e2)
    {
      siz = e1->size;
      if (_gnutls_mpi_scan_nz (&key->params.params[6], e1->data, siz))
        {
          gnutls_assert ();
          ret = GNUTLS_E_MPI_SCAN_FAILED;
          goto cleanup;
        }
      key->params.params_nr++;

      siz = e2->size;
      if (_gnutls_mpi_scan_nz (&key->params.params[7], e2->data, siz))
        {
          gnutls_assert ();
          ret = GNUTLS_E_MPI_SCAN_FAILED;
          goto cleanup;
        }
      key->params.params_nr++;
    }

  ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &key->params);
  if (ret < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_RSA, &key->key, &key->params);
  if (ret < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  key->params.params_nr = RSA_PRIVATE_PARAMS;
  key->pk_algorithm = GNUTLS_PK_RSA;

  return 0;

cleanup:
  gnutls_pk_params_release(&key->params);
  return ret;

}
static ASN1_TYPE
decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey)
{
  int result;
  ASN1_TYPE dsa_asn;

  if ((result =
       asn1_create_element (_gnutls_get_gnutls_asn (),
                            "GNUTLS.DSAPrivateKey",
                            &dsa_asn)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return NULL;
    }

  pkey->params.params_nr = 0;

  result = asn1_der_decoding (&dsa_asn, raw_key->data, raw_key->size, NULL);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      goto error;
    }

  if ((result = _gnutls_x509_read_int (dsa_asn, "p", &pkey->params.params[0])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params.params[1])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params.params[2])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params.params[3])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (dsa_asn, "priv",
                                       &pkey->params.params[4])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  return dsa_asn;

error:
  asn1_delete_structure (&dsa_asn);
  gnutls_pk_params_release(&pkey->params);
  return NULL;

}
/* Converts an ECC key to
 * an internal structure (gnutls_private_key)
 */
ASN1_TYPE
_gnutls_privkey_decode_ecc_key (const gnutls_datum_t * raw_key,
                                      gnutls_x509_privkey_t pkey)
{
  int ret;
  ASN1_TYPE pkey_asn;
  unsigned int version;
  char oid[MAX_OID_SIZE];
  int oid_size;
  gnutls_datum out;

  gnutls_pk_params_init(&pkey->params);

  if ((ret =
       asn1_create_element (_gnutls_get_gnutls_asn (),
                            "GNUTLS.ECPrivateKey",
                            &pkey_asn)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return NULL;
    }

  ret = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL);
  if (ret != ASN1_SUCCESS)
    {
      gnutls_assert ();
      goto error;
    }

  ret = _gnutls_x509_read_uint (pkey_asn, "Version", &version);
  if (ret < 0)
    {
      gnutls_assert();
      goto error;
    }

  if (version != 1)
    {
      _gnutls_debug_log("ECC private key version %u is not supported\n", version);
      gnutls_assert();
      goto error;
    }

  /* read the curve */
  oid_size = sizeof(oid);
  ret = asn1_read_value(pkey_asn, "parameters.namedCurve", oid, &oid_size);
  if (ret != ASN1_SUCCESS)
    {
      gnutls_assert ();
      goto error;
    }
    
  pkey->params.flags = _gnutls_oid_to_ecc_curve(oid);
  if (pkey->params.flags == GNUTLS_ECC_CURVE_INVALID)
    {
      _gnutls_debug_log("Curve %s is not supported\n", oid);
      gnutls_assert();
      goto error;
    }
    
  ret = _gnutls_ecc_curve_fill_params(pkey->params.flags, &pkey->params);
  if (ret < 0)
    {
      gnutls_assert();
      goto error;
    }

  /* read the public key */
  ret = _gnutls_x509_read_value(pkey_asn, "publicKey", &out, 2);
  if (ret < 0)
    {
      gnutls_assert();
      goto error;
    }

  ret = _gnutls_ecc_ansi_x963_import (out.data, out.size, &pkey->params.params[ECC_X],
                                         &pkey->params.params[ECC_Y]);
  
  _gnutls_free_datum(&out);
  if (ret < 0)
    {
      gnutls_assert();
      goto error;
    }
  pkey->params.params_nr += 2;

  /* read the private key */
  ret = _gnutls_x509_read_int (pkey_asn, "privateKey", &pkey->params.params[ECC_K]);
  if (ret < 0)
    {
      gnutls_assert();
      goto error;
    }
  pkey->params.params_nr ++;

  return pkey_asn;

error:
  asn1_delete_structure (&pkey_asn);
  gnutls_pk_params_release (&pkey->params);
  return NULL;

}
/* Converts an RSA PKCS#1 key to
 * an internal structure (gnutls_private_key)
 */
ASN1_TYPE
_gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key,
                                      gnutls_x509_privkey_t pkey)
{
  int result;
  ASN1_TYPE pkey_asn;

  gnutls_pk_params_init(&pkey->params);

  if ((result =
       asn1_create_element (_gnutls_get_gnutls_asn (),
                            "GNUTLS.RSAPrivateKey",
                            &pkey_asn)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return NULL;
    }

  result = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      goto error;
    }

  if ((result = _gnutls_x509_read_int (pkey_asn, "modulus",
                                       &pkey->params.params[0])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result =
       _gnutls_x509_read_int (pkey_asn, "publicExponent",
                              &pkey->params.params[1])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result =
       _gnutls_x509_read_int (pkey_asn, "privateExponent",
                              &pkey->params.params[2])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (pkey_asn, "prime1",
                                       &pkey->params.params[3])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (pkey_asn, "prime2",
                                       &pkey->params.params[4])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient",
                                       &pkey->params.params[5])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (pkey_asn, "exponent1",
                                       &pkey->params.params[6])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  if ((result = _gnutls_x509_read_int (pkey_asn, "exponent2",
                                       &pkey->params.params[7])) < 0)
    {
      gnutls_assert ();
      goto error;
    }
  pkey->params.params_nr++;

  result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pkey->params);
  if (result < 0)
    {
      gnutls_assert ();
      goto error;
    }

  pkey->params.params_nr = RSA_PRIVATE_PARAMS;

  return pkey_asn;

error:
  asn1_delete_structure (&pkey_asn);
  gnutls_pk_params_release (&pkey->params);
  return NULL;

}