Beispiel #1
0
int
_gnutls_gen_ecdh_common_client_kx_int (gnutls_session_t session, 
                                   gnutls_buffer_st* data, 
                                   gnutls_datum_t * psk_key)
{
  int ret;
  gnutls_datum_t out;
  int curve = _gnutls_session_ecc_curve_get(session);

  /* generate temporal key */
  ret = _gnutls_pk_generate(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[6] /* x */,
    session->key.ecdh_params.params[7] /* 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);

  /* generate pre-shared key */
  ret = calc_ecdh_key(session, psk_key);
  if (ret < 0)
    return gnutls_assert_val(ret);

  return data->length;
}
Beispiel #2
0
static int
gen_ecdhe_server_kx(gnutls_session_t session, gnutls_buffer_st * data)
{
	int ret = 0;
	gnutls_certificate_credentials_t cred;

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

	if ((ret = _gnutls_auth_info_set(session, GNUTLS_CRD_CERTIFICATE,
					 sizeof(cert_auth_info_st),
					 0)) < 0) {
		gnutls_assert();
		return ret;
	}

	ret =
	    _gnutls_ecdh_common_print_server_kx(session, data,
						_gnutls_session_ecc_curve_get
						(session));
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	/* Generate the signature. */
	return _gnutls_gen_dhe_signature(session, data, data->data,
					 data->length);
}
Beispiel #3
0
static int
proc_ecdhe_client_kx(gnutls_session_t session,
		     uint8_t * data, size_t _data_size)
{
	gnutls_certificate_credentials_t cred;

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

	return _gnutls_proc_ecdh_common_client_kx(session, data,
						  _data_size,
						  _gnutls_session_ecc_curve_get
						  (session), NULL);
}
Beispiel #4
0
static int
proc_dhe_client_kx (gnutls_session_t session, uint8_t * data,
                    size_t _data_size)
{
  gnutls_certificate_credentials_t cred;
  int ret;
  bigint_t p, g;
  const bigint_t *mpis;
  gnutls_dh_params_t dh_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 (!_gnutls_session_is_ecc (session))
    {
      dh_params =
        _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
      mpis = _gnutls_dh_params_to_mpi (dh_params);
      if (mpis == NULL)
        return gnutls_assert_val(GNUTLS_E_NO_TEMPORARY_DH_PARAMS);

      p = mpis[0];
      g = mpis[1];

      ret = _gnutls_proc_dh_common_client_kx (session, data, _data_size, g, p, NULL);
    }
  else
    ret = _gnutls_proc_ecdh_common_client_kx (session, data, _data_size, 
                                              _gnutls_session_ecc_curve_get(session), NULL);

  return ret;

}
Beispiel #5
0
static int
gen_ecdhe_psk_server_kx(gnutls_session_t session, gnutls_buffer_st * data)
{
	int ret;

	if ((ret =
	     _gnutls_auth_info_set(session, GNUTLS_CRD_PSK,
				   sizeof(psk_auth_info_st), 1)) < 0) {
		gnutls_assert();
		return ret;
	}

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

	ret = _gnutls_ecdh_common_print_server_kx(session, data,
						  _gnutls_session_ecc_curve_get
						  (session));
	if (ret < 0)
		gnutls_assert();

	return ret;
}
Beispiel #6
0
static int
proc_ecdhe_psk_client_kx(gnutls_session_t session, uint8_t * data,
			 size_t _data_size)
{
	int ret;
	gnutls_psk_server_credentials_t cred;
	gnutls_datum_t psk_key;
	psk_auth_info_t info;
	gnutls_datum_t username;
	ssize_t data_size = _data_size;

	cred = (gnutls_psk_server_credentials_t)
	    _gnutls_get_cred(session, GNUTLS_CRD_PSK, NULL);

	if (cred == NULL) {
		gnutls_assert();
		return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
	}

	if ((ret =
	     _gnutls_auth_info_set(session, GNUTLS_CRD_PSK,
				   sizeof(psk_auth_info_st), 1)) < 0) {
		gnutls_assert();
		return ret;
	}

	DECR_LEN(data_size, 2);
	username.size = _gnutls_read_uint16(&data[0]);

	DECR_LEN(data_size, username.size);

	username.data = &data[2];

	/* copy the username to the auth info structures
	 */
	info = _gnutls_get_auth_info(session);

	if (username.size > MAX_USERNAME_SIZE) {
		gnutls_assert();
		return GNUTLS_E_ILLEGAL_SRP_USERNAME;
	}

	memcpy(info->username, username.data, username.size);
	info->username[username.size] = 0;

	/* Adjust the data */
	data += username.size + 2;

	/* should never fail. It will always return a key even if it is
	 * a random one */
	ret =
	    _gnutls_psk_pwd_find_entry(session, info->username, &psk_key);
	if (ret < 0)
		return gnutls_assert_val(ret);

	ret = _gnutls_proc_ecdh_common_client_kx(session, data, data_size,
						 _gnutls_session_ecc_curve_get
						 (session), &psk_key);

	_gnutls_free_datum(&psk_key);

	return ret;
}
Beispiel #7
0
static int
gen_dhe_server_kx (gnutls_session_t session, gnutls_buffer_st* data)
{
  bigint_t g, p;
  const bigint_t *mpis;
  int ret = 0, data_size;
  gnutls_pcert_st *apr_cert_list;
  gnutls_privkey_t apr_pkey;
  int apr_cert_list_length;
  gnutls_datum_t signature = { NULL, 0 }, ddata;
  gnutls_certificate_credentials_t cred;
  gnutls_dh_params_t dh_params;
  gnutls_sign_algorithm_t sign_algo;
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);

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

  /* find the appropriate certificate */
  if ((ret =
       _gnutls_get_selected_cert (session, &apr_cert_list,
                                  &apr_cert_list_length, &apr_pkey)) < 0)
    {
      gnutls_assert ();
      return ret;
    }

  if ((ret = _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
                                    sizeof (cert_auth_info_st), 0)) < 0)
    {
      gnutls_assert ();
      return ret;
    }

  if (!_gnutls_session_is_ecc (session))
    {
      dh_params =
        _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
      mpis = _gnutls_dh_params_to_mpi (dh_params);
      if (mpis == NULL)
        {
          gnutls_assert ();
          return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
        }

      p = mpis[0];
      g = mpis[1];

      _gnutls_dh_set_group (session, g, p);

      ret = _gnutls_dh_common_print_server_kx (session, g, p, dh_params->q_bits, data);
    }
  else
    {
      ret = _gnutls_ecdh_common_print_server_kx (session, data, _gnutls_session_ecc_curve_get(session));
    }

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

  /* Generate the signature. */

  ddata.data = data->data;
  ddata.size = data->length;

  if (apr_cert_list_length > 0)
    {
      if ((ret =
           _gnutls_handshake_sign_data (session, &apr_cert_list[0],
                                        apr_pkey, &ddata, &signature,
                                        &sign_algo)) < 0)
        {
          gnutls_assert ();
          goto cleanup;
        }
    }
  else
    {
      gnutls_assert ();
      ret = data_size;         /* do not put a signature - ILLEGAL! */
      goto cleanup;
    }

  if (_gnutls_version_has_selectable_sighash (ver))
    {
      const sign_algorithm_st *aid;
      uint8_t p[2];

      if (sign_algo == GNUTLS_SIGN_UNKNOWN)
        {
          ret = GNUTLS_E_UNKNOWN_ALGORITHM;
          goto cleanup;
        }

      aid = _gnutls_sign_to_tls_aid (sign_algo);
      if (aid == NULL)
        {
          gnutls_assert();
          ret = GNUTLS_E_UNKNOWN_ALGORITHM;
          goto cleanup;
        }
      
      p[0] = aid->hash_algorithm;
      p[1] = aid->sign_algorithm;
      
      ret = _gnutls_buffer_append_data(data, p, 2);
      if (ret < 0)
        {
          gnutls_assert();
          goto cleanup;
        }
    }

  ret = _gnutls_buffer_append_data_prefix(data, 16, signature.data, signature.size);
  if (ret < 0)
    {
      gnutls_assert();
    }

  ret = data->length;

cleanup:
  _gnutls_free_datum (&signature);
  return ret;

}