optimized encryption
This commit is contained in:
parent
42b5cad1f8
commit
e58485822b
|
@ -58,7 +58,9 @@ namespace libtorrent
|
||||||
// m_dh_secret.
|
// m_dh_secret.
|
||||||
int compute_secret(const char* remote_pubkey);
|
int compute_secret(const char* remote_pubkey);
|
||||||
|
|
||||||
const char* get_secret() const;
|
char const* get_secret() const { return m_dh_secret; }
|
||||||
|
|
||||||
|
sha1_hash const& get_hash_xor_mask() const { return m_xor_mask; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int get_local_key_size() const
|
int get_local_key_size() const
|
||||||
|
@ -71,6 +73,7 @@ namespace libtorrent
|
||||||
|
|
||||||
char m_dh_local_key[96];
|
char m_dh_local_key[96];
|
||||||
char m_dh_secret[96];
|
char m_dh_secret[96];
|
||||||
|
sha1_hash m_xor_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RC4_handler // Non copyable
|
class RC4_handler // Non copyable
|
||||||
|
|
|
@ -132,6 +132,14 @@ namespace libtorrent
|
||||||
|
|
||||||
void parse_resume_data(std::vector<char>* resume_data);
|
void parse_resume_data(std::vector<char>* resume_data);
|
||||||
|
|
||||||
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
|
sha1_hash const& obfuscated_hash() const
|
||||||
|
{ return m_obfuscated_hash; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sha1_hash const& info_hash() const
|
||||||
|
{ return m_torrent_file->info_hash(); }
|
||||||
|
|
||||||
// starts the announce timer
|
// starts the announce timer
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
|
@ -821,6 +829,11 @@ namespace libtorrent
|
||||||
// longer be used and will be reset
|
// longer be used and will be reset
|
||||||
boost::scoped_ptr<std::string> m_name;
|
boost::scoped_ptr<std::string> m_name;
|
||||||
|
|
||||||
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
|
// this is SHA1("req2" + info-hash), used for
|
||||||
|
// encrypted hand shakes
|
||||||
|
sha1_hash m_obfuscated_hash;
|
||||||
|
#endif
|
||||||
session_settings const& m_settings;
|
session_settings const& m_settings;
|
||||||
|
|
||||||
storage_constructor_type m_storage_constructor;
|
storage_constructor_type m_storage_constructor;
|
||||||
|
|
|
@ -1841,7 +1841,8 @@ namespace libtorrent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cut_receive_buffer(bytes_processed, (std::min)(packet_size(), (512+20) - m_sync_bytes_read));
|
cut_receive_buffer(bytes_processed, (std::min)(packet_size()
|
||||||
|
, (512+20) - m_sync_bytes_read));
|
||||||
|
|
||||||
TORRENT_ASSERT(!packet_finished());
|
TORRENT_ASSERT(!packet_finished());
|
||||||
return;
|
return;
|
||||||
|
@ -1872,51 +1873,32 @@ namespace libtorrent
|
||||||
|
|
||||||
recv_buffer = receive_buffer();
|
recv_buffer = receive_buffer();
|
||||||
|
|
||||||
// only calls info_hash() on the torrent_handle's, which
|
aux::session_impl::torrent_map::const_iterator i;
|
||||||
// never throws.
|
|
||||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
|
||||||
|
|
||||||
std::vector<torrent_handle> active_torrents = m_ses.get_torrents();
|
for (i = m_ses.m_torrents.begin(); i != m_ses.m_torrents.end(); ++i)
|
||||||
std::vector<torrent_handle>::const_iterator i;
|
|
||||||
hasher h;
|
|
||||||
sha1_hash skey_hash, obfs_hash;
|
|
||||||
|
|
||||||
for (i = active_torrents.begin(); i != active_torrents.end(); ++i)
|
|
||||||
{
|
{
|
||||||
torrent_handle const& t_h = *i; // TODO possible errors
|
torrent const& ti = *i->second;
|
||||||
sha1_hash const& info_hash = t_h.info_hash();
|
sha1_hash const& skey_hash = ti.obfuscated_hash();
|
||||||
// TODO Does info_hash need to be checked for validity?
|
sha1_hash obfs_hash = m_dh_key_exchange->get_hash_xor_mask();
|
||||||
|
|
||||||
h.reset();
|
|
||||||
h.update("req2", 4);
|
|
||||||
h.update((char*)info_hash.begin(), 20);
|
|
||||||
|
|
||||||
skey_hash = h.final();
|
|
||||||
|
|
||||||
h.reset();
|
|
||||||
h.update("req3", 4);
|
|
||||||
h.update(m_dh_key_exchange->get_secret(), dh_key_len);
|
|
||||||
|
|
||||||
obfs_hash = h.final();
|
|
||||||
obfs_hash ^= skey_hash;
|
obfs_hash ^= skey_hash;
|
||||||
|
|
||||||
if (std::equal (recv_buffer.begin, recv_buffer.begin + 20,
|
if (std::equal(recv_buffer.begin, recv_buffer.begin + 20,
|
||||||
(char*)obfs_hash.begin()))
|
(char*)&obfs_hash[0]))
|
||||||
{
|
{
|
||||||
if (!t)
|
if (!t)
|
||||||
{
|
{
|
||||||
attach_to_torrent(info_hash);
|
attach_to_torrent(ti.info_hash());
|
||||||
if (is_disconnecting()) return;
|
if (is_disconnecting()) return;
|
||||||
|
|
||||||
t = associated_torrent().lock();
|
t = associated_torrent().lock();
|
||||||
TORRENT_ASSERT(t);
|
TORRENT_ASSERT(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
init_pe_RC4_handler(m_dh_key_exchange->get_secret(), info_hash);
|
init_pe_RC4_handler(m_dh_key_exchange->get_secret(), ti.info_hash());
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
(*m_logger) << " stream key found, torrent located.\n";
|
(*m_logger) << " stream key found, torrent located.\n";
|
||||||
#endif
|
#endif
|
||||||
continue; // TODO Check flow control with multiple torrents
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
|
|
||||||
#include "libtorrent/pe_crypto.hpp"
|
#include "libtorrent/pe_crypto.hpp"
|
||||||
|
#include "libtorrent/hasher.hpp"
|
||||||
#include "libtorrent/assert.hpp"
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
|
@ -144,12 +145,14 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
std::copy(dh_secret, dh_secret + secret_size, m_dh_secret + 96 - secret_size);
|
std::copy(dh_secret, dh_secret + secret_size, m_dh_secret + 96 - secret_size);
|
||||||
BN_free(bn_remote_pubkey);
|
BN_free(bn_remote_pubkey);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char const* dh_key_exchange::get_secret() const
|
// calculate the xor mask for the obfuscated hash
|
||||||
{
|
hasher h;
|
||||||
return m_dh_secret;
|
h.update("req3", 4);
|
||||||
|
h.update(m_dh_secret, 96);
|
||||||
|
m_xor_mask = h.final();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace libtorrent
|
} // namespace libtorrent
|
||||||
|
|
|
@ -206,6 +206,13 @@ namespace libtorrent
|
||||||
, m_complete_sent(false)
|
, m_complete_sent(false)
|
||||||
{
|
{
|
||||||
parse_resume_data(resume_data);
|
parse_resume_data(resume_data);
|
||||||
|
|
||||||
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
|
hasher h;
|
||||||
|
h.update("req2", 4);
|
||||||
|
h.update((char*)&tf->info_hash()[0], 20);
|
||||||
|
m_obfuscated_hash = h.final();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent::torrent(
|
torrent::torrent(
|
||||||
|
@ -280,6 +287,14 @@ namespace libtorrent
|
||||||
, m_complete_sent(false)
|
, m_complete_sent(false)
|
||||||
{
|
{
|
||||||
parse_resume_data(resume_data);
|
parse_resume_data(resume_data);
|
||||||
|
|
||||||
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
|
hasher h;
|
||||||
|
h.update("req2", 4);
|
||||||
|
h.update((char*)&info_hash[0], 20);
|
||||||
|
m_obfuscated_hash = h.final();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
m_files_checked = false;
|
m_files_checked = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue