factor encryption handler a bit and add proposal for an authentication extension
This commit is contained in:
parent
fbf2eb6f88
commit
060b849dda
|
@ -0,0 +1,192 @@
|
|||
===================================
|
||||
BitTorrent authentication extension
|
||||
===================================
|
||||
|
||||
:Author: Arvid Norberg, arvid@rasterbar.com
|
||||
:Version: Draft
|
||||
|
||||
.. contents:: Table of contents
|
||||
:depth: 2
|
||||
:backlinks: none
|
||||
|
||||
BitTorrent authentication extension
|
||||
-----------------------------------
|
||||
|
||||
This extension indends to cover any combination of the following use cases:
|
||||
|
||||
1. Verifying that a torrent is published by a trusted source
|
||||
2. Have a swarm be private and having peers authenticate peers they connect to
|
||||
3. Allow peers, with prior knowledge about each other's public key, authenticate in order to set up trusted connections to known peers (i.e. "friends")
|
||||
|
||||
These building blocks could be used for building a web of trust, private
|
||||
swarms and trusted sources for content.
|
||||
|
||||
torrent file extension
|
||||
----------------------
|
||||
|
||||
A .torrent file may have the following new fields (not inside the info-hash):
|
||||
|
||||
"publisher"
|
||||
containing the RSA public key of the publisher of the torrent. Private counterpart
|
||||
of this key that has the authority to allow new peers onto the swarm.
|
||||
|
||||
"signature"
|
||||
The RSA signature of the ``info`` dictionary (specifically, the encrypted SHA-1
|
||||
hash of the ``info`` dictionary).
|
||||
|
||||
These fields serve the purpose of satisfying use case (1), allowing downloaders to
|
||||
verify that the torrent has a trusted source.
|
||||
|
||||
extension handshake
|
||||
-------------------
|
||||
|
||||
In order to satisfy use case (2), any peer supporting this extension MUST verify
|
||||
that each peer on the swarm it connects to and receive an incoming connection from
|
||||
is authenticated by the publisher's public key, if the torrent is *private*.
|
||||
|
||||
A torrent is private if the ``info`` dictionary contains an integer key ``private``
|
||||
set to 1.
|
||||
|
||||
The extension handshake dictionary ("m") SHOULD contain a new extension key "lt_auth".
|
||||
|
||||
For private torrents, the extension handshake dictionary
|
||||
MUST contain the certificate granting this peer access to the torrent. The
|
||||
certificate is a dictionary ``cert`` containing the ``info-hash``,
|
||||
``pubkey`` (the peer's public key), ``expiry`` (posix time of when cert expires).
|
||||
The ``cert`` dictionary MAY be extended with more fields.
|
||||
|
||||
Next to the ``cert`` entry is a string ``sig`` being the signature
|
||||
of the SHA-1 hash of the bencoded representation of the ``cert`` dictionary.
|
||||
The signature is required for private torrents, but not required for non-private
|
||||
torrents.
|
||||
|
||||
An example extension handshake for a private torrent could look like this::
|
||||
|
||||
{
|
||||
"cert": {
|
||||
"expiry": 1333242356,
|
||||
"info-hash": f0fb0ed2d73a28aece3a9e4f91c91cf60e0ea0a6,
|
||||
"pubkey":
|
||||
79eaeecbfc91b129c34880e3113fc9545e7169fed95a7950a335cfcef3dd2989c
|
||||
c80c69d9e66206cdb4e41eeae8b19234804cd55b3eb6dbee15a5362e3fa6eb33b
|
||||
a61297dfc63426832623efdf54816474189ddf1baad1d08cb614ed130f9744671
|
||||
a0c9bdf32747c284955ad9ae65db875f4f74f51e624710fe7c3db5ec8ce55f175
|
||||
b49131cace810d6a61a9fcd0fa4e41e466e09c2a18629f4bebb8dbf4746648122
|
||||
bfc8153e3e76ea16cae62e0e1608effa6bf2f1d1954d2e3ef2ca1db327f75a1aa
|
||||
711ccad6a564821824a2708c20a9184a221554d1228fdaee39ba3ce4134847fab
|
||||
91514d4ed720fabe8082e342dfce15ced93545bdc6
|
||||
},
|
||||
"m": {
|
||||
"lt_auth": 8
|
||||
}
|
||||
"sig":
|
||||
1767303857272cc9133253614712584a3c6be5f81cd777e9e6e99fbf23be27ca9
|
||||
d96c3ad596521f90dd4fb2291d6c9a6108625cf58ca836c3e7f15595306cd9311
|
||||
5c4736276cb4ee08b7f85a5eb26759bfb46b28f36cecfd73e71fac5cad8f22bb6
|
||||
32d07ab4e530587d4fc4d21ae1c52aacbefa0a0dbabb9e24d6c552aaa464a8b94
|
||||
97cc776e3b1b4051dbc9ef26952ab0e74188cbf1ea54f37309ef781d37b59ded7
|
||||
e6ce09a9531cc9916ecbe1fb93369da47ab79457e9709576f737e3d89e3774731
|
||||
d97ac8b1283dc46a382e4ddd5a155b17d6ded6683f508f111c5e974098315c509
|
||||
77d533ddb52f42fa5019342496a217483b622c3a
|
||||
}
|
||||
|
||||
|
||||
This certificate would expire at ``Sat Mar 31 18:05:56 PDT 2012``. The values of ``sig``,
|
||||
``info-hash`` and ``pubkey`` are binary strings, they are printed as hex in this example.
|
||||
The RSA key size SHOULD be 2048 bits (256 bytes).
|
||||
|
||||
Whenconnecting to a peer, or accepting an incoming connection, for a private torrent,
|
||||
the client MUST verify the validity of the incoming certificate. This is done by:
|
||||
|
||||
1. Verifying that the certificate has not expired.
|
||||
2. Verifying that the ``info-hash`` matches the torrent the peers are connected over
|
||||
3. Verifying that the signature ``sig``, is a valid signature made by the private counterpart of the public key of the publisher of the torrent (i.e. the ``publisher`` key in the torrent file)
|
||||
|
||||
If the certificate fails any one of those checks, the peer MUST be
|
||||
disconnected without exchanging any more information. As an exception, before
|
||||
disconnecting, the peer MAY send an ``lt_auto`` message saying the authentication
|
||||
failed.
|
||||
|
||||
An example extension handshake for a non-private torrent could look like this::
|
||||
|
||||
{
|
||||
"cert": {
|
||||
"pubkey":
|
||||
79eaeecbfc91b129c34880e3113fc9545e7169fed95a7950a335cfcef3dd2989c
|
||||
c80c69d9e66206cdb4e41eeae8b19234804cd55b3eb6dbee15a5362e3fa6eb33b
|
||||
a61297dfc63426832623efdf54816474189ddf1baad1d08cb614ed130f9744671
|
||||
a0c9bdf32747c284955ad9ae65db875f4f74f51e624710fe7c3db5ec8ce55f175
|
||||
b49131cace810d6a61a9fcd0fa4e41e466e09c2a18629f4bebb8dbf4746648122
|
||||
bfc8153e3e76ea16cae62e0e1608effa6bf2f1d1954d2e3ef2ca1db327f75a1aa
|
||||
711ccad6a564821824a2708c20a9184a221554d1228fdaee39ba3ce4134847fab
|
||||
91514d4ed720fabe8082e342dfce15ced93545bdc6
|
||||
},
|
||||
"m": {
|
||||
"lt_auth": 8
|
||||
}
|
||||
}
|
||||
|
||||
Note that the only required field in the ``cert`` in this case is the ``pubkey``,
|
||||
The assumption in this case is that the public key is recognized by the client
|
||||
matched by a local directory of trusted peers. This is to support use case (3).
|
||||
|
||||
extension message
|
||||
-----------------
|
||||
|
||||
The ``lt_auth`` extension message is used to protect against man-in-the-middle attacks,
|
||||
and peers trying to assume someone else's identity. To do this, the entire connection
|
||||
is encrypted with RC4 following this message. If the connection is already encrypted
|
||||
with RC4, this overrides that encryption by resetting the encryption state.
|
||||
|
||||
It has the following format:
|
||||
|
||||
============= ============= ======================================================
|
||||
size name description
|
||||
============= ============= ======================================================
|
||||
uint8_t type 0 = encrypt the connection with RC4 using the symmetric
|
||||
key passed in this message.
|
||||
1 = signature verification failed
|
||||
2 = info-hash verification failed
|
||||
3 = certificate expired
|
||||
------------- ------------- ------------------------------------------------------
|
||||
uint8_t[256] rc4_key If type is not 0, this field is not included.
|
||||
The symmetric key the sender of this message will use
|
||||
to encrypt every message following this one. The key
|
||||
is encrypted with the recipient's public key. The
|
||||
length of this field may vary, but for 2048 RSA keys
|
||||
it ends up being 256 bytes.
|
||||
============= ============= ======================================================
|
||||
|
||||
Note that this message is somewhat of a layer violation, since it reaches down and
|
||||
starts encrypting the entire stream below itself. This is illustrated in the figure
|
||||
below.
|
||||
|
||||
::
|
||||
|
||||
+---------------------------+
|
||||
| BitTorrent messages | -----+ lt_auth reaches down
|
||||
+---------------------------+ | to the layer below
|
||||
| (RC4 protocol encryption) | <----+
|
||||
+-------------+-------------+
|
||||
| TCP | uTP |
|
||||
+----------+--+-----+-------+
|
||||
|
||||
applications
|
||||
------------
|
||||
|
||||
This is a low level building block and not a complete system for authenticated or
|
||||
private swarms. It does allow for peers to verify that a torrent comes from a
|
||||
trusted source (assuming their public key is known in advance). It also allows
|
||||
for publishers to limit access to content.
|
||||
|
||||
For privacy reasons, it is possible to apply this extension in a way that each peer
|
||||
uses separate identities (key pairs) for every torrent it participates in.
|
||||
|
||||
Issues not covered by this extension are:
|
||||
|
||||
1. How the distribution of signed certificates are distributed to peers from
|
||||
the signing authority (publisher), for use case (2).
|
||||
2. How peers discover each other and and *pair* by recognizing each other's
|
||||
public keys for future trusted connections, for use case (3).
|
||||
3. How peers learn about the public keys of trusted publishers, for use case (1).
|
||||
|
|
@ -6,6 +6,7 @@ TARGETS = index \
|
|||
udp_tracker_protocol \
|
||||
dht_rss \
|
||||
dht_store \
|
||||
auth \
|
||||
client_test \
|
||||
manual \
|
||||
building \
|
||||
|
|
|
@ -283,8 +283,8 @@ namespace libtorrent
|
|||
|
||||
// stream key (info hash of attached torrent)
|
||||
// secret is the DH shared secret
|
||||
// initializes m_RC4_handler
|
||||
void init_pe_RC4_handler(char const* secret, sha1_hash const& stream_key);
|
||||
// initializes m_rc4_handler
|
||||
void init_pe_rc4_handler(char const* secret, sha1_hash const& stream_key);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -298,7 +298,7 @@ public:
|
|||
{
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
if (m_rc4_encrypted)
|
||||
m_RC4_handler->encrypt(buffer, size);
|
||||
m_rc4_handler->encrypt(buffer, size);
|
||||
#endif
|
||||
peer_connection::append_send_buffer(buffer, size, destructor, true);
|
||||
}
|
||||
|
@ -410,17 +410,17 @@ private:
|
|||
int m_sync_bytes_read;
|
||||
|
||||
// initialized during write_pe1_2_dhkey, and destroyed on
|
||||
// creation of m_RC4_handler. Cannot reinitialize once
|
||||
// creation of m_rc4_handler. Cannot reinitialize once
|
||||
// initialized.
|
||||
boost::scoped_ptr<dh_key_exchange> m_dh_key_exchange;
|
||||
|
||||
// if RC4 is negotiated, this is used for
|
||||
// encryption/decryption during the entire session. Destroyed
|
||||
// if plaintext is selected
|
||||
boost::scoped_ptr<RC4_handler> m_RC4_handler;
|
||||
boost::scoped_ptr<rc4_handler> m_rc4_handler;
|
||||
|
||||
// (outgoing only) synchronize verification constant with
|
||||
// remote peer, this will hold RC4_decrypt(vc). Destroyed
|
||||
// remote peer, this will hold rc4_decrypt(vc). Destroyed
|
||||
// after the sync step.
|
||||
boost::scoped_array<char> m_sync_vc;
|
||||
|
||||
|
|
|
@ -85,33 +85,55 @@ namespace libtorrent
|
|||
sha1_hash m_xor_mask;
|
||||
};
|
||||
|
||||
class RC4_handler // Non copyable
|
||||
class rc4_handler // Non copyable
|
||||
{
|
||||
public:
|
||||
// Input longkeys must be 20 bytes
|
||||
RC4_handler(sha1_hash const& rc4_local_longkey,
|
||||
sha1_hash const& rc4_remote_longkey)
|
||||
rc4_handler()
|
||||
: m_encrypt(false)
|
||||
, m_decrypt(false)
|
||||
{
|
||||
#ifdef TORRENT_USE_GCRYPT
|
||||
gcry_cipher_open(&m_rc4_incoming, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0);
|
||||
gcry_cipher_open(&m_rc4_outgoing, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0);
|
||||
gcry_cipher_setkey(m_rc4_incoming, &rc4_remote_longkey[0], 20);
|
||||
gcry_cipher_setkey(m_rc4_outgoing, &rc4_local_longkey[0], 20);
|
||||
#elif defined TORRENT_USE_OPENSSL
|
||||
RC4_set_key(&m_local_key, 20, &rc4_local_longkey[0]);
|
||||
RC4_set_key(&m_remote_key, 20, &rc4_remote_longkey[0]);
|
||||
#else
|
||||
rc4_init(&rc4_remote_longkey[0], 20, &m_rc4_incoming);
|
||||
rc4_init(&rc4_local_longkey[0], 20, &m_rc4_outgoing);
|
||||
#endif
|
||||
};
|
||||
|
||||
void set_incoming_key(unsigned char const* key, int len)
|
||||
{
|
||||
m_decrypt = true;
|
||||
#ifdef TORRENT_USE_GCRYPT
|
||||
gcry_cipher_close(m_rc4_incoming);
|
||||
gcry_cipher_open(&m_rc4_incoming, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0);
|
||||
gcry_cipher_setkey(m_rc4_incoming, key, len);
|
||||
#elif defined TORRENT_USE_OPENSSL
|
||||
RC4_set_key(&m_remote_key, len, key);
|
||||
#else
|
||||
rc4_init(key, len, &m_rc4_incoming);
|
||||
#endif
|
||||
// Discard first 1024 bytes
|
||||
char buf[1024];
|
||||
decrypt(buf, 1024);
|
||||
}
|
||||
|
||||
void set_outgoing_key(unsigned char const* key, int len)
|
||||
{
|
||||
m_encrypt = true;
|
||||
#ifdef TORRENT_USE_GCRYPT
|
||||
gcry_cipher_close(m_rc4_outgoing);
|
||||
gcry_cipher_open(&m_rc4_outgoing, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0);
|
||||
gcry_cipher_setkey(m_rc4_outgoing, key, len);
|
||||
#elif defined TORRENT_USE_OPENSSL
|
||||
RC4_set_key(&m_local_key, len, key);
|
||||
#else
|
||||
rc4_init(key, len, &m_rc4_outgoing);
|
||||
#endif
|
||||
// Discard first 1024 bytes
|
||||
char buf[1024];
|
||||
encrypt(buf, 1024);
|
||||
decrypt(buf, 1024);
|
||||
};
|
||||
}
|
||||
|
||||
~RC4_handler()
|
||||
~rc4_handler()
|
||||
{
|
||||
#ifdef TORRENT_USE_GCRYPT
|
||||
gcry_cipher_close(m_rc4_incoming);
|
||||
|
@ -121,6 +143,8 @@ namespace libtorrent
|
|||
|
||||
void encrypt(char* pos, int len)
|
||||
{
|
||||
if (!m_encrypt) return;
|
||||
|
||||
TORRENT_ASSERT(len >= 0);
|
||||
TORRENT_ASSERT(pos);
|
||||
|
||||
|
@ -135,6 +159,8 @@ namespace libtorrent
|
|||
|
||||
void decrypt(char* pos, int len)
|
||||
{
|
||||
if (!m_decrypt) return;
|
||||
|
||||
TORRENT_ASSERT(len >= 0);
|
||||
TORRENT_ASSERT(pos);
|
||||
|
||||
|
@ -158,6 +184,9 @@ namespace libtorrent
|
|||
rc4 m_rc4_incoming;
|
||||
rc4 m_rc4_outgoing;
|
||||
#endif
|
||||
// determines whether or not encryption and decryption is enabled
|
||||
bool m_encrypt;
|
||||
bool m_decrypt;
|
||||
};
|
||||
|
||||
} // namespace libtorrent
|
||||
|
|
|
@ -380,9 +380,9 @@ namespace libtorrent
|
|||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
if (m_encrypted)
|
||||
{
|
||||
m_rc4_encrypted ?
|
||||
p.flags |= peer_info::rc4_encrypted :
|
||||
p.flags |= peer_info::plaintext_encrypted;
|
||||
p.flags |= m_rc4_encrypted
|
||||
? peer_info::rc4_encrypted
|
||||
: peer_info::plaintext_encrypted;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -493,7 +493,7 @@ namespace libtorrent
|
|||
ptr += 20;
|
||||
|
||||
// Discard DH key exchange data, setup RC4 keys
|
||||
init_pe_RC4_handler(secret, info_hash);
|
||||
init_pe_rc4_handler(secret, info_hash);
|
||||
m_dh_key_exchange.reset(); // secret should be invalid at this point
|
||||
|
||||
// write the verification constant and crypto field
|
||||
|
@ -516,7 +516,7 @@ namespace libtorrent
|
|||
#endif
|
||||
|
||||
write_pe_vc_cryptofield(ptr, encrypt_size, crypto_provide, pad_size);
|
||||
m_RC4_handler->encrypt(ptr, encrypt_size);
|
||||
m_rc4_handler->encrypt(ptr, encrypt_size);
|
||||
send_buffer(msg, sizeof(msg) - 512 + pad_size);
|
||||
}
|
||||
|
||||
|
@ -536,7 +536,7 @@ namespace libtorrent
|
|||
char msg[512 + 8 + 4 + 2];
|
||||
write_pe_vc_cryptofield(msg, sizeof(msg), crypto_select, pad_size);
|
||||
|
||||
m_RC4_handler->encrypt(msg, buf_size);
|
||||
m_rc4_handler->encrypt(msg, buf_size);
|
||||
send_buffer(msg, buf_size);
|
||||
|
||||
// encryption method has been negotiated
|
||||
|
@ -581,7 +581,7 @@ namespace libtorrent
|
|||
detail::write_uint16(handshake_len, write_buf); // len(IA)
|
||||
}
|
||||
|
||||
void bt_peer_connection::init_pe_RC4_handler(char const* secret, sha1_hash const& stream_key)
|
||||
void bt_peer_connection::init_pe_rc4_handler(char const* secret, sha1_hash const& stream_key)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
|
@ -595,7 +595,7 @@ namespace libtorrent
|
|||
// outgoing connection : hash ('keyA',S,SKEY)
|
||||
// incoming connection : hash ('keyB',S,SKEY)
|
||||
|
||||
is_local() ? h.update(keyA, 4) : h.update(keyB, 4);
|
||||
if (is_local()) h.update(keyA, 4); else h.update(keyB, 4);
|
||||
h.update(secret, dh_key_len);
|
||||
h.update((char const*)stream_key.begin(), 20);
|
||||
const sha1_hash local_key = h.final();
|
||||
|
@ -606,14 +606,16 @@ namespace libtorrent
|
|||
// outgoing connection : hash ('keyB',S,SKEY)
|
||||
// incoming connection : hash ('keyA',S,SKEY)
|
||||
|
||||
is_local() ? h.update(keyB, 4) : h.update(keyA, 4);
|
||||
if (is_local()) h.update(keyB, 4); else h.update(keyA, 4);
|
||||
h.update(secret, dh_key_len);
|
||||
h.update((char const*)stream_key.begin(), 20);
|
||||
const sha1_hash remote_key = h.final();
|
||||
|
||||
TORRENT_ASSERT(!m_RC4_handler.get());
|
||||
m_RC4_handler.reset(new (std::nothrow) RC4_handler(local_key, remote_key));
|
||||
if (!m_RC4_handler)
|
||||
TORRENT_ASSERT(!m_rc4_handler.get());
|
||||
m_rc4_handler.reset(new (std::nothrow) rc4_handler);
|
||||
m_rc4_handler->set_incoming_key(&remote_key[0], 20);
|
||||
m_rc4_handler->set_outgoing_key(&local_key[0], 20);
|
||||
if (!m_rc4_handler)
|
||||
{
|
||||
disconnect(errors::no_memory);
|
||||
return;
|
||||
|
@ -644,7 +646,7 @@ namespace libtorrent
|
|||
|
||||
void encrypt(char* buf, int len, void* userdata)
|
||||
{
|
||||
RC4_handler* rc4 = (RC4_handler*)userdata;
|
||||
rc4_handler* rc4 = (rc4_handler*)userdata;
|
||||
rc4->encrypt(buf, len);
|
||||
}
|
||||
|
||||
|
@ -659,7 +661,7 @@ namespace libtorrent
|
|||
if (m_encrypted && m_rc4_encrypted)
|
||||
{
|
||||
fun = encrypt;
|
||||
userdata = m_RC4_handler.get();
|
||||
userdata = m_rc4_handler.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2322,8 +2324,8 @@ namespace libtorrent
|
|||
if (m_rc4_encrypted && m_encrypted)
|
||||
{
|
||||
std::pair<buffer::interval, buffer::interval> wr_buf = wr_recv_buffers(bytes_transferred);
|
||||
m_RC4_handler->decrypt(wr_buf.first.begin, wr_buf.first.left());
|
||||
if (wr_buf.second.left()) m_RC4_handler->decrypt(wr_buf.second.begin, wr_buf.second.left());
|
||||
m_rc4_handler->decrypt(wr_buf.first.begin, wr_buf.first.left());
|
||||
if (wr_buf.second.left()) m_rc4_handler->decrypt(wr_buf.second.begin, wr_buf.second.left());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2507,7 +2509,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(t);
|
||||
}
|
||||
|
||||
init_pe_RC4_handler(m_dh_key_exchange->get_secret(), ti.info_hash());
|
||||
init_pe_rc4_handler(m_dh_key_exchange->get_secret(), ti.info_hash());
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
peer_log("*** stream key found, torrent located");
|
||||
#endif
|
||||
|
@ -2515,7 +2517,7 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
if (!m_RC4_handler.get())
|
||||
if (!m_rc4_handler.get())
|
||||
{
|
||||
disconnect(errors::invalid_info_hash, 1);
|
||||
return;
|
||||
|
@ -2523,7 +2525,7 @@ namespace libtorrent
|
|||
|
||||
// verify constant
|
||||
buffer::interval wr_recv_buf = wr_recv_buffer();
|
||||
m_RC4_handler->decrypt(wr_recv_buf.begin + 20, 8);
|
||||
m_rc4_handler->decrypt(wr_recv_buf.begin + 20, 8);
|
||||
wr_recv_buf.begin += 28;
|
||||
|
||||
const char sh_vc[] = {0,0,0,0, 0,0,0,0};
|
||||
|
@ -2568,7 +2570,7 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
std::fill(m_sync_vc.get(), m_sync_vc.get() + 8, 0);
|
||||
m_RC4_handler->decrypt(m_sync_vc.get(), 8);
|
||||
m_rc4_handler->decrypt(m_sync_vc.get(), 8);
|
||||
}
|
||||
|
||||
TORRENT_ASSERT(m_sync_vc.get());
|
||||
|
@ -2626,7 +2628,7 @@ namespace libtorrent
|
|||
if (!packet_finished()) return;
|
||||
|
||||
buffer::interval wr_buf = wr_recv_buffer();
|
||||
m_RC4_handler->decrypt(wr_buf.begin, packet_size());
|
||||
m_rc4_handler->decrypt(wr_buf.begin, packet_size());
|
||||
|
||||
recv_buffer = receive_buffer();
|
||||
|
||||
|
@ -2749,7 +2751,7 @@ namespace libtorrent
|
|||
int pad_size = is_local() ? packet_size() : packet_size() - 2;
|
||||
|
||||
buffer::interval wr_buf = wr_recv_buffer();
|
||||
m_RC4_handler->decrypt(wr_buf.begin, packet_size());
|
||||
m_rc4_handler->decrypt(wr_buf.begin, packet_size());
|
||||
|
||||
recv_buffer = receive_buffer();
|
||||
|
||||
|
@ -2798,7 +2800,7 @@ namespace libtorrent
|
|||
|
||||
// ia is always rc4, so decrypt it
|
||||
buffer::interval wr_buf = wr_recv_buffer();
|
||||
m_RC4_handler->decrypt(wr_buf.begin, packet_size());
|
||||
m_rc4_handler->decrypt(wr_buf.begin, packet_size());
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
peer_log("*** decrypted ia : %d bytes", packet_size());
|
||||
|
@ -2806,7 +2808,7 @@ namespace libtorrent
|
|||
|
||||
if (!m_rc4_encrypted)
|
||||
{
|
||||
m_RC4_handler.reset();
|
||||
m_rc4_handler.reset();
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
peer_log("*** destroyed rc4 keys");
|
||||
#endif
|
||||
|
@ -2830,14 +2832,14 @@ namespace libtorrent
|
|||
{
|
||||
buffer::interval wr_buf = wr_recv_buffer();
|
||||
wr_buf.begin += packet_size();
|
||||
m_RC4_handler->decrypt(wr_buf.begin, wr_buf.left());
|
||||
m_rc4_handler->decrypt(wr_buf.begin, wr_buf.left());
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
peer_log("*** decrypted remaining %d bytes", wr_buf.left());
|
||||
#endif
|
||||
}
|
||||
else // !m_rc4_encrypted
|
||||
{
|
||||
m_RC4_handler.reset();
|
||||
m_rc4_handler.reset();
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
peer_log("*** destroyed rc4 keys");
|
||||
#endif
|
||||
|
@ -3301,7 +3303,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT( (bool(m_state != read_pe_dhkey) || m_dh_key_exchange.get())
|
||||
|| !is_local());
|
||||
|
||||
TORRENT_ASSERT(!m_rc4_encrypted || m_RC4_handler.get());
|
||||
TORRENT_ASSERT(!m_rc4_encrypted || m_rc4_handler.get());
|
||||
#endif
|
||||
if (!in_handshake())
|
||||
{
|
||||
|
|
|
@ -156,8 +156,12 @@ int test_main()
|
|||
sha1_hash test1_key = hasher("test1_key",8).final();
|
||||
sha1_hash test2_key = hasher("test2_key",8).final();
|
||||
|
||||
RC4_handler RC41(test2_key, test1_key);
|
||||
RC4_handler RC42(test1_key, test2_key);
|
||||
rc4_handler rc41;
|
||||
rc41.set_incoming_key(&test2_key[0], 20);
|
||||
rc41.set_outgoing_key(&test1_key[0], 20);
|
||||
rc4_handler rc42;
|
||||
rc42.set_incoming_key(&test1_key[0], 20);
|
||||
rc42.set_outgoing_key(&test2_key[0], 20);
|
||||
|
||||
for (int rep = 0; rep < repcount; ++rep)
|
||||
{
|
||||
|
@ -168,12 +172,12 @@ int test_main()
|
|||
std::fill(buf, buf + buf_len, 0);
|
||||
std::fill(zero_buf, zero_buf + buf_len, 0);
|
||||
|
||||
RC41.encrypt(buf, buf_len);
|
||||
RC42.decrypt(buf, buf_len);
|
||||
rc41.encrypt(buf, buf_len);
|
||||
rc42.decrypt(buf, buf_len);
|
||||
TEST_CHECK(std::equal(buf, buf + buf_len, zero_buf));
|
||||
|
||||
RC42.encrypt(buf, buf_len);
|
||||
RC41.decrypt(buf, buf_len);
|
||||
rc42.encrypt(buf, buf_len);
|
||||
rc41.decrypt(buf, buf_len);
|
||||
TEST_CHECK(std::equal(buf, buf + buf_len, zero_buf));
|
||||
|
||||
delete[] buf;
|
||||
|
|
Loading…
Reference in New Issue