Ejemplo n.º 1
0
std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> TLS::Callbacks::tls_ecdh_agree(
   const std::string& curve_name,
   const std::vector<uint8_t>& peer_public_value,
   const Policy& policy,
   RandomNumberGenerator& rng,
   bool compressed)
   {
   secure_vector<uint8_t> ecdh_secret;
   std::vector<uint8_t> our_public_value;

   if(curve_name == "x25519")
      {
#if defined(BOTAN_HAS_CURVE_25519)
      if(peer_public_value.size() != 32)
         {
         throw TLS_Exception(Alert::HANDSHAKE_FAILURE, "Invalid X25519 key size");
         }

      Curve25519_PublicKey peer_key(peer_public_value);
      policy.check_peer_key_acceptable(peer_key);
      Curve25519_PrivateKey priv_key(rng);
      PK_Key_Agreement ka(priv_key, rng, "Raw");
      ecdh_secret = ka.derive_key(0, peer_key.public_value()).bits_of();

      // X25519 is always compressed but sent as "uncompressed" in TLS
      our_public_value = priv_key.public_value();
#else
      throw Internal_Error("Negotiated X25519 somehow, but it is disabled");
#endif
      }
   else
      {
      EC_Group group(OIDS::lookup(curve_name));
      ECDH_PublicKey peer_key(group, group.OS2ECP(peer_public_value));
      policy.check_peer_key_acceptable(peer_key);
      ECDH_PrivateKey priv_key(rng, group);
      PK_Key_Agreement ka(priv_key, rng, "Raw");
      ecdh_secret = ka.derive_key(0, peer_key.public_value()).bits_of();
      our_public_value = priv_key.public_value(compressed ? PointGFp::COMPRESSED : PointGFp::UNCOMPRESSED);
      }

   return std::make_pair(ecdh_secret, our_public_value);
   }
Ejemplo n.º 2
0
std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> TLS::Callbacks::tls_dh_agree(
   const std::vector<uint8_t>& modulus,
   const std::vector<uint8_t>& generator,
   const std::vector<uint8_t>& peer_public_value,
   const Policy& policy,
   RandomNumberGenerator& rng)
   {
   BigInt p = BigInt::decode(modulus);
   BigInt g = BigInt::decode(generator);
   BigInt Y = BigInt::decode(peer_public_value);

   /*
    * A basic check for key validity. As we do not know q here we
    * cannot check that Y is in the right subgroup. However since
    * our key is ephemeral there does not seem to be any
    * advantage to bogus keys anyway.
    */
   if(Y <= 1 || Y >= p - 1)
      throw TLS_Exception(Alert::ILLEGAL_PARAMETER,
                          "Server sent bad DH key for DHE exchange");

   DL_Group group(p, g);

   if(!group.verify_group(rng, false))
      throw TLS_Exception(Alert::INSUFFICIENT_SECURITY,
                          "DH group validation failed");

   DH_PublicKey peer_key(group, Y);

   policy.check_peer_key_acceptable(peer_key);

   DH_PrivateKey priv_key(rng, group);
   PK_Key_Agreement ka(priv_key, rng, "Raw");
   secure_vector<uint8_t> dh_secret = CT::strip_leading_zeros(
      ka.derive_key(0, peer_key.public_value()).bits_of());

   return std::make_pair(dh_secret, priv_key.public_value());
   }
Ejemplo n.º 3
0
std::string srv_insert_peer(const Ctracker_input& v, bool udp, t_user* user)
{
	if (m_use_sql && m_config.m_log_announce)
	{
		m_announce_log_buffer += Csql_query(m_database, "(?,?,?,?,?,?,?,?,?,?),")
			(ntohl(v.m_ipa))
			(ntohs(v.m_port))
			(v.m_event)
			(v.m_info_hash)
			(v.m_peer_id)
			(v.m_downloaded)
			(v.m_left)
			(v.m_uploaded)
			(user ? user->uid : 0)
			(srv_time())
			.read();
	}
	if (!m_config.m_offline_message.empty())
		return m_config.m_offline_message;
	if (0)
		return bts_banned_client;
	if (!m_config.m_anonymous_announce && !user)
		return bts_unregistered_torrent_pass;
	if (!m_config.m_auto_register && !find_torrent(v.m_info_hash))
		return bts_unregistered_torrent;
	if (v.m_left && user && !user->can_leech)
		return bts_can_not_leech;
	t_torrent& file = m_torrents[to_array<char, 20>(v.m_info_hash)];
	if (!file.ctime)
		file.ctime = srv_time();
	if (v.m_left && user && user->wait_time && file.ctime + user->wait_time > srv_time())
		return bts_wait_time;
	peer_key_c peer_key(v.m_ipa, user ? user->uid : 0);
	t_peer* i = find_ptr(file.peers, peer_key);
	if (i)
		(i->left ? file.leechers : file.seeders)--;
	else if (v.m_left && user && user->peers_limit)
	{
		int c = 0;
		for (auto& j : file.peers)
			c += j.second.left && j.second.uid == user->uid;
		if (c >= user->peers_limit)
			return bts_peers_limit_reached;
	}
	if (m_use_sql && user && file.fid)
	{
		long long downloaded = 0;
		long long uploaded = 0;
		if (i
			&& i->uid == user->uid
			&& boost::equals(i->peer_id, v.m_peer_id)
			&& v.m_downloaded >= i->downloaded
			&& v.m_uploaded >= i->uploaded)
		{
			downloaded = v.m_downloaded - i->downloaded;
			uploaded = v.m_uploaded - i->uploaded;
		}
		m_torrents_users_updates_buffer += Csql_query(m_database, "(?,1,?,?,?,?,?,?,?),")
			(v.m_event != Ctracker_input::e_stopped)
			(v.m_event == Ctracker_input::e_completed)
			(downloaded)
			(v.m_left)
			(uploaded)
			(srv_time())
			(file.fid)
			(user->uid)
			.read();
		if (downloaded || uploaded)
			m_users_updates_buffer += Csql_query(m_database, "(?,?,?),")(downloaded)(uploaded)(user->uid).read();
		if (m_torrents_users_updates_buffer.size() > 255 << 10)
			write_db_users();
	}
	if (v.m_event == Ctracker_input::e_stopped)
		file.peers.erase(peer_key);
	else
	{
		t_peer& peer = i ? *i : file.peers[peer_key];
		peer.downloaded = v.m_downloaded;
		peer.left = v.m_left;
		peer.peer_id = v.m_peer_id;
		peer.port = v.m_port;
		peer.uid = user ? user->uid : 0;
		peer.uploaded = v.m_uploaded;
		(peer.left ? file.leechers : file.seeders)++;
		peer.mtime = srv_time();
	}
	if (v.m_event == Ctracker_input::e_completed)
		file.completed++;
	(udp ? m_stats.announced_udp : m_stats.announced_http)++;
	file.dirty = true;
	return std::string();
}