Exemplo n.º 1
0
/* returns data_size or a negative number on failure
 */
static int
_gnutls_supported_ecc_pf_send_params(gnutls_session_t session,
				     gnutls_buffer_st * extdata)
{
	const uint8_t p[2] = { 0x01, 0x00 };	/* only support uncompressed point format */

	if (session->security_parameters.entity == GNUTLS_SERVER
	    && !_gnutls_session_is_ecc(session))
		return 0;

	if (session->internals.priorities.supported_ecc.algorithms > 0) {
		_gnutls_buffer_append_data(extdata, p, 2);
		return 2;
	}
	return 0;
}
Exemplo n.º 2
0
Arquivo: dhe.c Projeto: intgr/gnutls
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;

}
Exemplo n.º 3
0
Arquivo: dhe.c Projeto: intgr/gnutls
static int
proc_dhe_server_kx (gnutls_session_t session, uint8_t * data,
                    size_t _data_size)
{
  int sigsize;
  uint8_t *sigdata;
  gnutls_datum_t vparams, signature;
  int ret;
  cert_auth_info_t info = _gnutls_get_auth_info (session);
  ssize_t data_size = _data_size;
  gnutls_pcert_st peer_cert;
  gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);

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

  if (!_gnutls_session_is_ecc (session))
    ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size);
  else
    ret = _gnutls_proc_ecdh_common_server_kx (session, data, _data_size);

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

  /* VERIFY SIGNATURE */

  vparams.size = ret;
  vparams.data = data;

  sigdata = &data[vparams.size];
  if (_gnutls_version_has_selectable_sighash (ver))
    {
      sign_algorithm_st aid;

      DECR_LEN (data_size, 1);
      aid.hash_algorithm = *sigdata++;
      DECR_LEN (data_size, 1);
      aid.sign_algorithm = *sigdata++;
      sign_algo = _gnutls_tls_aid_to_sign (&aid);
      if (sign_algo == GNUTLS_SIGN_UNKNOWN)
        {
          _gnutls_debug_log("unknown signature %d.%d\n", aid.sign_algorithm, aid.hash_algorithm);
          gnutls_assert ();
          return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
        }
    }
  DECR_LEN (data_size, 2);
  sigsize = _gnutls_read_uint16 (sigdata);
  sigdata += 2;

  DECR_LEN (data_size, sigsize);
  signature.data = sigdata;
  signature.size = sigsize;

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

  ret =
    _gnutls_handshake_verify_data (session, &peer_cert, &vparams, &signature,
                                   sign_algo);

  gnutls_pcert_deinit (&peer_cert);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  return ret;
}
Exemplo n.º 4
0
Arquivo: dhe.c Projeto: intgr/gnutls
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;

}