示例#1
0
/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
 */
static int
_encode_rsa (ASN1_TYPE * c2, mpi_t * params)
{
  int result, i;
  size_t size[8], total;
  opaque *m_data, *pube_data, *prie_data;
  opaque *p1_data, *p2_data, *u_data, *exp1_data, *exp2_data;
  opaque *all_data = NULL, *p;
  mpi_t exp1 = NULL, exp2 = NULL, q1 = NULL, p1 = NULL, u = NULL;
  opaque null = '\0';

  /* Read all the sizes */
  total = 0;
  for (i = 0; i < 5; i++)
    {
      _gnutls_mpi_print_lz (NULL, &size[i], params[i]);
      total += size[i];
    }

  /* Now generate exp1 and exp2
   */
  exp1 = _gnutls_mpi_salloc_like (params[0]);	/* like modulus */
  if (exp1 == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  exp2 = _gnutls_mpi_salloc_like (params[0]);
  if (exp2 == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  q1 = _gnutls_mpi_salloc_like (params[4]);
  if (q1 == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  p1 = _gnutls_mpi_salloc_like (params[3]);
  if (p1 == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  u = _gnutls_mpi_salloc_like (params[3]);
  if (u == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  _gnutls_mpi_invm (u, params[4], params[3]);
  /* inverse of q mod p */
  _gnutls_mpi_print_lz (NULL, &size[5], u);
  total += size[5];

  _gnutls_mpi_sub_ui (p1, params[3], 1);
  _gnutls_mpi_sub_ui (q1, params[4], 1);

  _gnutls_mpi_mod (exp1, params[2], p1);
  _gnutls_mpi_mod (exp2, params[2], q1);


  /* calculate exp's size */
  _gnutls_mpi_print_lz (NULL, &size[6], exp1);
  total += size[6];

  _gnutls_mpi_print_lz (NULL, &size[7], exp2);
  total += size[7];

  /* Encoding phase.
   * allocate data enough to hold everything
   */
  all_data = gnutls_secure_malloc (total);
  if (all_data == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  p = all_data;
  m_data = p;
  p += size[0];
  pube_data = p;
  p += size[1];
  prie_data = p;
  p += size[2];
  p1_data = p;
  p += size[3];
  p2_data = p;
  p += size[4];
  u_data = p;
  p += size[5];
  exp1_data = p;
  p += size[6];
  exp2_data = p;

  _gnutls_mpi_print_lz (m_data, &size[0], params[0]);
  _gnutls_mpi_print_lz (pube_data, &size[1], params[1]);
  _gnutls_mpi_print_lz (prie_data, &size[2], params[2]);
  _gnutls_mpi_print_lz (p1_data, &size[3], params[3]);
  _gnutls_mpi_print_lz (p2_data, &size[4], params[4]);
  _gnutls_mpi_print_lz (u_data, &size[5], u);
  _gnutls_mpi_print_lz (exp1_data, &size[6], exp1);
  _gnutls_mpi_print_lz (exp2_data, &size[7], exp2);

  /* Ok. Now we have the data. Create the asn1 structures
   */

  if ((result = asn1_create_element
       (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPrivateKey", c2))
      != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* Write PRIME 
   */
  if ((result = asn1_write_value (*c2, "modulus",
				  m_data, size[0])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "publicExponent",
				  pube_data, size[1])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "privateExponent",
				  prie_data, size[2])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "prime1",
				  p1_data, size[3])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "prime2",
				  p2_data, size[4])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "exponent1",
				  exp1_data, size[6])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "exponent2",
				  exp2_data, size[7])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "coefficient",
				  u_data, size[5])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  _gnutls_mpi_release (&exp1);
  _gnutls_mpi_release (&exp2);
  _gnutls_mpi_release (&q1);
  _gnutls_mpi_release (&p1);
  _gnutls_mpi_release (&u);
  gnutls_free (all_data);

  if ((result = asn1_write_value (*c2, "otherPrimeInfos",
				  NULL, 0)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  return 0;

cleanup:
  _gnutls_mpi_release (&u);
  _gnutls_mpi_release (&exp1);
  _gnutls_mpi_release (&exp2);
  _gnutls_mpi_release (&q1);
  _gnutls_mpi_release (&p1);
  asn1_delete_structure (c2);
  gnutls_free (all_data);

  return result;
}
示例#2
0
/* This function is to be called after handshake, when master_secret,
 *  client_random and server_random have been initialized. 
 * This function creates the keys and stores them into pending session.
 * (session->cipher_specs)
 */
int
_gnutls_set_keys (gnutls_session_t session, int hash_size, int IV_size,
		  int key_size, int export_flag)
{

/* FIXME: This function is too long
 */
  opaque *key_block;
  opaque rnd[2 * TLS_RANDOM_SIZE];
  opaque rrnd[2 * TLS_RANDOM_SIZE];
  int pos, ret;
  int block_size;
  char buf[65];

  if (session->cipher_specs.generated_keys != 0)
    {
      /* keys have already been generated.
       * reset generated_keys and exit normally.
       */
      session->cipher_specs.generated_keys = 0;
      return 0;
    }

  block_size = 2 * hash_size + 2 * key_size;
  if (export_flag == 0)
    block_size += 2 * IV_size;

  key_block = gnutls_secure_malloc (block_size);
  if (key_block == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  memcpy (rnd, session->security_parameters.server_random, TLS_RANDOM_SIZE);
  memcpy (&rnd[TLS_RANDOM_SIZE],
	  session->security_parameters.client_random, TLS_RANDOM_SIZE);

  memcpy (rrnd, session->security_parameters.client_random, TLS_RANDOM_SIZE);
  memcpy (&rrnd[TLS_RANDOM_SIZE],
	  session->security_parameters.server_random, TLS_RANDOM_SIZE);

  if (session->security_parameters.version == GNUTLS_SSL3)
    {				/* SSL 3 */
      ret =
	_gnutls_ssl3_generate_random (session->
				      security_parameters.
				      master_secret,
				      TLS_MASTER_SIZE, rnd,
				      2 * TLS_RANDOM_SIZE,
				      block_size, key_block);
    }
  else
    {				/* TLS 1.0 */
      ret =
	_gnutls_PRF (session, session->security_parameters.master_secret,
		     TLS_MASTER_SIZE, keyexp, keyexp_length,
		     rnd, 2 * TLS_RANDOM_SIZE, block_size, key_block);
    }

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

  _gnutls_hard_log ("INT: KEY BLOCK[%d]: %s\n", block_size,
		    _gnutls_bin2hex (key_block, block_size, buf,
				     sizeof (buf)));

  pos = 0;
  if (hash_size > 0)
    {
      if (_gnutls_sset_datum
	  (&session->cipher_specs.client_write_mac_secret,
	   &key_block[pos], hash_size) < 0)
	{
	  gnutls_free (key_block);
	  return GNUTLS_E_MEMORY_ERROR;
	}
      pos += hash_size;

      if (_gnutls_sset_datum
	  (&session->cipher_specs.server_write_mac_secret,
	   &key_block[pos], hash_size) < 0)
	{
	  gnutls_free (key_block);
	  return GNUTLS_E_MEMORY_ERROR;
	}
      pos += hash_size;
    }

  if (key_size > 0)
    {
      opaque *client_write_key, *server_write_key;
      int client_write_key_size, server_write_key_size;
      int free_keys = 0;

      if (export_flag == 0)
	{
	  client_write_key = &key_block[pos];
	  client_write_key_size = key_size;

	  pos += key_size;

	  server_write_key = &key_block[pos];
	  server_write_key_size = key_size;

	  pos += key_size;

	}
      else
	{			/* export */
	  free_keys = 1;

	  client_write_key = gnutls_secure_malloc (EXPORT_FINAL_KEY_SIZE);
	  if (client_write_key == NULL)
	    {
	      gnutls_assert ();
	      gnutls_free (key_block);
	      return GNUTLS_E_MEMORY_ERROR;
	    }

	  server_write_key = gnutls_secure_malloc (EXPORT_FINAL_KEY_SIZE);
	  if (server_write_key == NULL)
	    {
	      gnutls_assert ();
	      gnutls_free (key_block);
	      gnutls_free (client_write_key);
	      return GNUTLS_E_MEMORY_ERROR;
	    }

	  /* generate the final keys */

	  if (session->security_parameters.version == GNUTLS_SSL3)
	    {			/* SSL 3 */
	      ret =
		_gnutls_ssl3_hash_md5 (&key_block[pos],
				       key_size, rrnd,
				       2 * TLS_RANDOM_SIZE,
				       EXPORT_FINAL_KEY_SIZE,
				       client_write_key);

	    }
	  else
	    {			/* TLS 1.0 */
	      ret =
		_gnutls_PRF (session, &key_block[pos], key_size,
			     cliwrite, cliwrite_length,
			     rrnd,
			     2 * TLS_RANDOM_SIZE,
			     EXPORT_FINAL_KEY_SIZE, client_write_key);
	    }

	  if (ret < 0)
	    {
	      gnutls_assert ();
	      gnutls_free (key_block);
	      gnutls_free (server_write_key);
	      gnutls_free (client_write_key);
	      return ret;
	    }

	  client_write_key_size = EXPORT_FINAL_KEY_SIZE;
	  pos += key_size;

	  if (session->security_parameters.version == GNUTLS_SSL3)
	    {			/* SSL 3 */
	      ret =
		_gnutls_ssl3_hash_md5 (&key_block[pos], key_size,
				       rnd, 2 * TLS_RANDOM_SIZE,
				       EXPORT_FINAL_KEY_SIZE,
				       server_write_key);
	    }
	  else
	    {			/* TLS 1.0 */
	      ret =
		_gnutls_PRF (session, &key_block[pos], key_size,
			     servwrite, servwrite_length,
			     rrnd, 2 * TLS_RANDOM_SIZE,
			     EXPORT_FINAL_KEY_SIZE, server_write_key);
	    }

	  if (ret < 0)
	    {
	      gnutls_assert ();
	      gnutls_free (key_block);
	      gnutls_free (server_write_key);
	      gnutls_free (client_write_key);
	      return ret;
	    }

	  server_write_key_size = EXPORT_FINAL_KEY_SIZE;
	  pos += key_size;
	}

      if (_gnutls_sset_datum
	  (&session->cipher_specs.client_write_key,
	   client_write_key, client_write_key_size) < 0)
	{
	  gnutls_free (key_block);
	  gnutls_free (server_write_key);
	  gnutls_free (client_write_key);
	  return GNUTLS_E_MEMORY_ERROR;
	}
      _gnutls_hard_log ("INT: CLIENT WRITE KEY [%d]: %s\n",
			client_write_key_size,
			_gnutls_bin2hex (client_write_key,
					 client_write_key_size, buf,
					 sizeof (buf)));

      if (_gnutls_sset_datum
	  (&session->cipher_specs.server_write_key,
	   server_write_key, server_write_key_size) < 0)
	{
	  gnutls_free (key_block);
	  gnutls_free (server_write_key);
	  gnutls_free (client_write_key);
	  return GNUTLS_E_MEMORY_ERROR;
	}

      _gnutls_hard_log ("INT: SERVER WRITE KEY [%d]: %s\n",
			server_write_key_size,
			_gnutls_bin2hex (server_write_key,
					 server_write_key_size, buf,
					 sizeof (buf)));

      if (free_keys != 0)
	{
	  gnutls_free (server_write_key);
	  gnutls_free (client_write_key);
	}
    }


  /* IV generation in export and non export ciphers.
   */
  if (IV_size > 0 && export_flag == 0)
    {
      if (_gnutls_sset_datum
	  (&session->cipher_specs.client_write_IV, &key_block[pos],
	   IV_size) < 0)
	{
	  gnutls_free (key_block);
	  return GNUTLS_E_MEMORY_ERROR;
	}
      pos += IV_size;

      if (_gnutls_sset_datum
	  (&session->cipher_specs.server_write_IV, &key_block[pos],
	   IV_size) < 0)
	{
	  gnutls_free (key_block);
	  return GNUTLS_E_MEMORY_ERROR;
	}
      pos += IV_size;

    }
  else if (IV_size > 0 && export_flag != 0)
    {
      opaque *iv_block = gnutls_alloca (IV_size * 2);
      if (iv_block == NULL)
	{
	  gnutls_assert ();
	  gnutls_free (key_block);
	  return GNUTLS_E_MEMORY_ERROR;
	}

      if (session->security_parameters.version == GNUTLS_SSL3)
	{			/* SSL 3 */
	  ret = _gnutls_ssl3_hash_md5 ("", 0,
				       rrnd, TLS_RANDOM_SIZE * 2,
				       IV_size, iv_block);

	  if (ret < 0)
	    {
	      gnutls_assert ();
	      gnutls_free (key_block);
	      gnutls_afree (iv_block);
	      return ret;
	    }

	  ret = _gnutls_ssl3_hash_md5 ("", 0, rnd,
				       TLS_RANDOM_SIZE * 2,
				       IV_size, &iv_block[IV_size]);

	}
      else
	{			/* TLS 1.0 */
	  ret = _gnutls_PRF (session, "", 0,
			     ivblock, ivblock_length, rrnd,
			     2 * TLS_RANDOM_SIZE, IV_size * 2, iv_block);
	}

      if (ret < 0)
	{
	  gnutls_assert ();
	  gnutls_afree (iv_block);
	  gnutls_free (key_block);
	  return ret;
	}

      if (_gnutls_sset_datum
	  (&session->cipher_specs.client_write_IV, iv_block, IV_size) < 0)
	{
	  gnutls_afree (iv_block);
	  gnutls_free (key_block);
	  return GNUTLS_E_MEMORY_ERROR;
	}

      if (_gnutls_sset_datum
	  (&session->cipher_specs.server_write_IV,
	   &iv_block[IV_size], IV_size) < 0)
	{
	  gnutls_afree (iv_block);
	  gnutls_free (key_block);
	  return GNUTLS_E_MEMORY_ERROR;
	}

      gnutls_afree (iv_block);
    }

  gnutls_free (key_block);

  session->cipher_specs.generated_keys = 1;

  return 0;
}
示例#3
0
/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
 */
static int
_encode_dsa (ASN1_TYPE * c2, mpi_t * params)
{
  int result, i;
  size_t size[DSA_PRIVATE_PARAMS], total;
  opaque *p_data, *q_data, *g_data, *x_data, *y_data;
  opaque *all_data = NULL, *p;
  opaque null = '\0';

  /* Read all the sizes */
  total = 0;
  for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
    {
      _gnutls_mpi_print_lz (NULL, &size[i], params[i]);
      total += size[i];
    }

  /* Encoding phase.
   * allocate data enough to hold everything
   */
  all_data = gnutls_secure_malloc (total);
  if (all_data == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  p = all_data;
  p_data = p;
  p += size[0];
  q_data = p;
  p += size[1];
  g_data = p;
  p += size[2];
  y_data = p;
  p += size[3];
  x_data = p;

  _gnutls_mpi_print_lz (p_data, &size[0], params[0]);
  _gnutls_mpi_print_lz (q_data, &size[1], params[1]);
  _gnutls_mpi_print_lz (g_data, &size[2], params[2]);
  _gnutls_mpi_print_lz (y_data, &size[3], params[3]);
  _gnutls_mpi_print_lz (x_data, &size[4], params[4]);

  /* Ok. Now we have the data. Create the asn1 structures
   */

  if ((result = asn1_create_element
       (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPrivateKey", c2))
      != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* Write PRIME 
   */
  if ((result = asn1_write_value (*c2, "p", p_data, size[0])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "q", q_data, size[1])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "g", g_data, size[2])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "Y", y_data, size[3])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if ((result = asn1_write_value (*c2, "priv",
				  x_data, size[4])) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  gnutls_free (all_data);

  if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  return 0;

cleanup:
  asn1_delete_structure (c2);
  gnutls_free (all_data);

  return result;
}
示例#4
0
/* return RSA(random) using the peers public key 
 */
int
_gnutls_gen_rsa_client_kx (gnutls_session_t session, opaque ** data)
{
  cert_auth_info_t auth = session->key->auth_info;
  gnutls_datum_t sdata;		/* data to send */
  bigint_t params[MAX_PUBLIC_PARAMS_SIZE];
  int params_len = MAX_PUBLIC_PARAMS_SIZE;
  int ret, i;
  gnutls_protocol_t ver;

  if (auth == NULL)
    {
      /* this shouldn't have happened. The proc_certificate
       * function should have detected that.
       */
      gnutls_assert ();
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  session->key->key.size = GNUTLS_MASTER_SIZE;
  session->key->key.data = gnutls_secure_malloc (session->key->key.size);

  if (session->key->key.data == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  ret = _gnutls_rnd (GNUTLS_RND_RANDOM, session->key->key.data,
		     session->key->key.size);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  ver = _gnutls_get_adv_version (session);

  if (session->internals.rsa_pms_version[0] == 0)
    {
      session->key->key.data[0] = _gnutls_version_get_major (ver);
      session->key->key.data[1] = _gnutls_version_get_minor (ver);
    }
  else
    {				/* use the version provided */
      session->key->key.data[0] = session->internals.rsa_pms_version[0];
      session->key->key.data[1] = session->internals.rsa_pms_version[1];
    }

  /* move RSA parameters to key (session).
   */
  if ((ret =
       _gnutls_get_public_rsa_params (session, params, &params_len)) < 0)
    {
      gnutls_assert ();
      return ret;
    }

  if ((ret =
       _gnutls_pkcs1_rsa_encrypt (&sdata, &session->key->key,
				  params, params_len, 2)) < 0)
    {
      gnutls_assert ();
      return ret;
    }

  for (i = 0; i < params_len; i++)
    _gnutls_mpi_release (&params[i]);

  if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
    {
      /* SSL 3.0 */
      *data = sdata.data;
      return sdata.size;
    }
  else
    {				/* TLS 1 */
      *data = gnutls_malloc (sdata.size + 2);
      if (*data == NULL)
	{
	  _gnutls_free_datum (&sdata);
	  return GNUTLS_E_MEMORY_ERROR;
	}
      _gnutls_write_datum16 (*data, sdata);
      ret = sdata.size + 2;
      _gnutls_free_datum (&sdata);
      return ret;
    }

}