separate the configuration of crypto library and whether protocol encryption is enabled or not. make protocol encryption always use the built-in rc4 and tommath code. SHA-1 hashing is done by the crypto library
This commit is contained in:
parent
ae47823970
commit
e9414894e2
|
@ -1,3 +1,7 @@
|
||||||
|
* separate crypto library configuration <crypto> and whether to support
|
||||||
|
bittorrent protocol encryption <encryption>
|
||||||
|
* simplify bittorrent protocol encryption by just using internal RC4
|
||||||
|
implementation.
|
||||||
* optimize copying torrent_info and file_storage objects
|
* optimize copying torrent_info and file_storage objects
|
||||||
* cancel non-critical DNS lookups when shutting down, to cut down on
|
* cancel non-critical DNS lookups when shutting down, to cut down on
|
||||||
shutdown delay.
|
shutdown delay.
|
||||||
|
|
28
Jamfile
28
Jamfile
|
@ -54,7 +54,7 @@ rule linking ( properties * )
|
||||||
local result ;
|
local result ;
|
||||||
|
|
||||||
# openssl libraries, if enabled
|
# openssl libraries, if enabled
|
||||||
if <encryption>openssl in $(properties)
|
if <crypto>openssl in $(properties)
|
||||||
{
|
{
|
||||||
# exclude gcc from a regular windows build to make mingw
|
# exclude gcc from a regular windows build to make mingw
|
||||||
# link against the regular unix library name
|
# link against the regular unix library name
|
||||||
|
@ -94,7 +94,7 @@ rule linking ( properties * )
|
||||||
}
|
}
|
||||||
|
|
||||||
# gcrypt libraries, if enabled
|
# gcrypt libraries, if enabled
|
||||||
if <encryption>gcrypt in $(properties)
|
if <crypto>gcrypt in $(properties)
|
||||||
{
|
{
|
||||||
# on mac os x, adding the /opt/local/include path
|
# on mac os x, adding the /opt/local/include path
|
||||||
# would include openssl headers incompatible with
|
# would include openssl headers incompatible with
|
||||||
|
@ -254,27 +254,22 @@ rule building ( properties * )
|
||||||
result += <source>src/assert.cpp ;
|
result += <source>src/assert.cpp ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if <encryption>openssl in $(properties)
|
if <crypto>openssl in $(properties)
|
||||||
{
|
{
|
||||||
result += <source>src/asio_ssl.cpp ;
|
result += <source>src/asio_ssl.cpp ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if <encryption>tommath in $(properties)
|
if <encryption>on in $(properties)
|
||||||
{
|
{
|
||||||
result += <source>src/mpi.c ;
|
result += <source>src/mpi.c ;
|
||||||
|
result += <source>src/pe_crypto.cpp ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if <encryption>off in $(properties)
|
if <crypo>built-in in $(properties)
|
||||||
|| <encryption>tommath in $(properties)
|
|
||||||
{
|
{
|
||||||
result += <source>src/sha1.cpp ;
|
result += <source>src/sha1.cpp ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ! <encryption>off in $(properties)
|
|
||||||
{
|
|
||||||
result += <source>src/pe_crypto.cpp ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( <toolset>darwin in $(properties)
|
if ( <toolset>darwin in $(properties)
|
||||||
|| <toolset>gcc in $(properties)
|
|| <toolset>gcc in $(properties)
|
||||||
|| <toolset>clang in $(propertoes)
|
|| <toolset>clang in $(propertoes)
|
||||||
|
@ -406,12 +401,13 @@ feature dht : on off logging : composite propagated link-incompatible ;
|
||||||
feature.compose <dht>off : <define>TORRENT_DISABLE_DHT ;
|
feature.compose <dht>off : <define>TORRENT_DISABLE_DHT ;
|
||||||
feature.compose <dht>logging : <define>TORRENT_DHT_VERBOSE_LOGGING ;
|
feature.compose <dht>logging : <define>TORRENT_DHT_VERBOSE_LOGGING ;
|
||||||
|
|
||||||
feature encryption : tommath off openssl gcrypt : composite propagated link-incompatible ;
|
feature encryption : on off : composite propagated link-incompatible ;
|
||||||
feature.compose <encryption>openssl : <define>TORRENT_USE_OPENSSL ;
|
|
||||||
feature.compose <encryption>gcrypt : <define>TORRENT_USE_GCRYPT ;
|
|
||||||
feature.compose <encryption>tommath : <define>TORRENT_USE_TOMMATH ;
|
|
||||||
feature.compose <encryption>off : <define>TORRENT_DISABLE_ENCRYPTION ;
|
feature.compose <encryption>off : <define>TORRENT_DISABLE_ENCRYPTION ;
|
||||||
|
|
||||||
|
feature crypto : built-in openssl gcrypt : composite ;
|
||||||
|
feature.compose <crypto>openssl : <define>TORRENT_USE_OPENSSL ;
|
||||||
|
feature.compose <crypto>gcrypt : <define>TORRENT_USE_GCRYPT ;
|
||||||
|
|
||||||
feature resolve-countries : on off : composite propagated link-incompatible ;
|
feature resolve-countries : on off : composite propagated link-incompatible ;
|
||||||
feature.compose <resolve-countries>off : <define>TORRENT_DISABLE_RESOLVE_COUNTRIES ;
|
feature.compose <resolve-countries>off : <define>TORRENT_DISABLE_RESOLVE_COUNTRIES ;
|
||||||
|
|
||||||
|
@ -453,7 +449,7 @@ variant test_release
|
||||||
<export-extra>on <debug-iterators>on <boost>source <threading>multi
|
<export-extra>on <debug-iterators>on <boost>source <threading>multi
|
||||||
;
|
;
|
||||||
variant test_debug : debug
|
variant test_debug : debug
|
||||||
: <encryption>openssl <logging>on <disk-stats>on
|
: <crypto>openssl <logging>on <disk-stats>on
|
||||||
<dht>logging <request-log>on <allocator>debug <debug-iterators>on
|
<dht>logging <request-log>on <allocator>debug <debug-iterators>on
|
||||||
<invariant-checks>full <boost-link>shared
|
<invariant-checks>full <boost-link>shared
|
||||||
<export-extra>on <debug-iterators>on <boost>source <threading>multi
|
<export-extra>on <debug-iterators>on <boost>source <threading>multi
|
||||||
|
|
|
@ -283,19 +283,19 @@ Build features:
|
||||||
| | * ``on`` - creates "upnp.log" with the messages |
|
| | * ``on`` - creates "upnp.log" with the messages |
|
||||||
| | sent to and received from UPnP devices. |
|
| | sent to and received from UPnP devices. |
|
||||||
+--------------------------+----------------------------------------------------+
|
+--------------------------+----------------------------------------------------+
|
||||||
| ``encryption`` | * ``openssl`` - links against openssl and |
|
| ``encryption`` | * ``on`` - encrypted bittorrent connections |
|
||||||
| | libcrypto to enable https and encrypted |
|
| | enabled. (Message Stream encryption). |
|
||||||
| | bittorrent connections. |
|
|
||||||
| | * ``gcrypt`` - links against libgcrypt to enable |
|
|
||||||
| | encrypted bittorrent connections. |
|
|
||||||
| | * ``tommath`` - uses a shipped version of |
|
|
||||||
| | libtommath and a custom rc4 implementation |
|
|
||||||
| | (based on libtomcrypt). This is the default |
|
|
||||||
| | option. |
|
|
||||||
| | * ``off`` - turns off support for encrypted |
|
| | * ``off`` - turns off support for encrypted |
|
||||||
| | connections. The shipped public domain SHA-1 |
|
| | connections. The shipped public domain SHA-1 |
|
||||||
| | implementation is used. |
|
| | implementation is used. |
|
||||||
+--------------------------+----------------------------------------------------+
|
+--------------------------+----------------------------------------------------+
|
||||||
|
| ``crypto`` | * ``built-in`` - (default) uses built-in SHA-1 |
|
||||||
|
| | implementation. |
|
||||||
|
| | * ``openssl`` - links against openssl and |
|
||||||
|
| | libcrypto to use for SHA-1 hashing. |
|
||||||
|
| | * ``gcrypt`` - links against libgcrypt to use for |
|
||||||
|
| | SHA-1 hashing. |
|
||||||
|
+--------------------------+----------------------------------------------------+
|
||||||
| ``allocator`` | * ``pool`` - default, uses pool allocators for |
|
| ``allocator`` | * ``pool`` - default, uses pool allocators for |
|
||||||
| | send buffers. |
|
| | send buffers. |
|
||||||
| | * ``system`` - uses ``malloc()`` and ``free()`` |
|
| | * ``system`` - uses ``malloc()`` and ``free()`` |
|
||||||
|
|
|
@ -162,7 +162,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_USE_PURGABLE_CONTROL 1
|
#define TORRENT_USE_PURGABLE_CONTROL 1
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
|
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
|
||||||
# ifdef TORRENT_USE_OPENSSL
|
// on OSX, use the built-in common crypto for built-in
|
||||||
|
# if !defined TORRENT_USE_OPENSSL && !defined TORRENT_USE_GCRYPT
|
||||||
# define TORRENT_USE_COMMONCRYPTO 1
|
# define TORRENT_USE_COMMONCRYPTO 1
|
||||||
# endif // TORRENT_USE_OPENSSL
|
# endif // TORRENT_USE_OPENSSL
|
||||||
#endif // MAC_OS_X_VERSION_MIN_REQUIRED
|
#endif // MAC_OS_X_VERSION_MIN_REQUIRED
|
||||||
|
|
|
@ -37,11 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
|
||||||
#ifdef TORRENT_USE_GCRYPT
|
|
||||||
#include <gcrypt.h>
|
|
||||||
#elif defined TORRENT_USE_OPENSSL
|
|
||||||
#include <openssl/rc4.h>
|
|
||||||
#else
|
|
||||||
// RC4 state from libtomcrypt
|
// RC4 state from libtomcrypt
|
||||||
struct rc4 {
|
struct rc4 {
|
||||||
int x, y;
|
int x, y;
|
||||||
|
@ -50,7 +45,6 @@ struct rc4 {
|
||||||
|
|
||||||
void TORRENT_EXTRA_EXPORT rc4_init(const unsigned char* in, unsigned long len, rc4 *state);
|
void TORRENT_EXTRA_EXPORT rc4_init(const unsigned char* in, unsigned long len, rc4 *state);
|
||||||
unsigned long TORRENT_EXTRA_EXPORT rc4_encrypt(unsigned char *out, unsigned long outlen, rc4 *state);
|
unsigned long TORRENT_EXTRA_EXPORT rc4_encrypt(unsigned char *out, unsigned long outlen, rc4 *state);
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/asio/buffer.hpp>
|
#include <boost/asio/buffer.hpp>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -131,24 +125,11 @@ namespace libtorrent
|
||||||
rc4_handler()
|
rc4_handler()
|
||||||
: m_encrypt(false)
|
: m_encrypt(false)
|
||||||
, m_decrypt(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);
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
void set_incoming_key(unsigned char const* key, int len);
|
void set_incoming_key(unsigned char const* key, int len);
|
||||||
void set_outgoing_key(unsigned char const* key, int len);
|
void set_outgoing_key(unsigned char const* key, int len);
|
||||||
|
|
||||||
~rc4_handler()
|
|
||||||
{
|
|
||||||
#ifdef TORRENT_USE_GCRYPT
|
|
||||||
gcry_cipher_close(m_rc4_incoming);
|
|
||||||
gcry_cipher_close(m_rc4_outgoing);
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
int encrypt(std::vector<boost::asio::mutable_buffer>& buf);
|
int encrypt(std::vector<boost::asio::mutable_buffer>& buf);
|
||||||
void decrypt(std::vector<boost::asio::mutable_buffer>& buf
|
void decrypt(std::vector<boost::asio::mutable_buffer>& buf
|
||||||
, int& consume
|
, int& consume
|
||||||
|
@ -156,16 +137,9 @@ namespace libtorrent
|
||||||
, int& packet_size);
|
, int& packet_size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef TORRENT_USE_GCRYPT
|
|
||||||
gcry_cipher_hd_t m_rc4_incoming;
|
|
||||||
gcry_cipher_hd_t m_rc4_outgoing;
|
|
||||||
#elif defined TORRENT_USE_OPENSSL
|
|
||||||
RC4_KEY m_local_key; // Key to encrypt outgoing data
|
|
||||||
RC4_KEY m_remote_key; // Key to decrypt incoming data
|
|
||||||
#else
|
|
||||||
rc4 m_rc4_incoming;
|
rc4 m_rc4_incoming;
|
||||||
rc4 m_rc4_outgoing;
|
rc4 m_rc4_outgoing;
|
||||||
#endif
|
|
||||||
// determines whether or not encryption and decryption is enabled
|
// determines whether or not encryption and decryption is enabled
|
||||||
bool m_encrypt;
|
bool m_encrypt;
|
||||||
bool m_decrypt;
|
bool m_decrypt;
|
||||||
|
|
|
@ -35,18 +35,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#if defined TORRENT_USE_GCRYPT
|
|
||||||
#include <gcrypt.h>
|
|
||||||
#elif defined TORRENT_USE_OPENSSL
|
|
||||||
#include <openssl/bn.h>
|
|
||||||
#include "libtorrent/random.hpp"
|
|
||||||
#elif defined TORRENT_USE_TOMMATH
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "libtorrent/tommath.h"
|
#include "libtorrent/tommath.h"
|
||||||
}
|
}
|
||||||
#include "libtorrent/random.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#include "libtorrent/random.hpp"
|
||||||
#include "libtorrent/pe_crypto.hpp"
|
#include "libtorrent/pe_crypto.hpp"
|
||||||
#include "libtorrent/hasher.hpp"
|
#include "libtorrent/hasher.hpp"
|
||||||
#include "libtorrent/assert.hpp"
|
#include "libtorrent/assert.hpp"
|
||||||
|
@ -67,238 +60,81 @@ namespace libtorrent
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mp_bigint
|
||||||
|
{
|
||||||
|
mp_bigint()
|
||||||
|
{ mp_init(&v); }
|
||||||
|
mp_int* operator&() { return &v; }
|
||||||
|
~mp_bigint() { mp_clear(&v); }
|
||||||
|
private:
|
||||||
|
// non-copyable
|
||||||
|
mp_bigint(mp_bigint const&);
|
||||||
|
mp_bigint const& operator=(mp_bigint const&);
|
||||||
|
mp_int v;
|
||||||
|
};
|
||||||
|
|
||||||
// Set the prime P and the generator, generate local public key
|
// Set the prime P and the generator, generate local public key
|
||||||
dh_key_exchange::dh_key_exchange()
|
dh_key_exchange::dh_key_exchange()
|
||||||
{
|
{
|
||||||
#ifdef TORRENT_USE_GCRYPT
|
|
||||||
// create local key
|
|
||||||
gcry_randomize(m_dh_local_secret, sizeof(m_dh_local_secret), GCRY_STRONG_RANDOM);
|
|
||||||
|
|
||||||
// build gcrypt big ints from the prime and the secret
|
|
||||||
gcry_mpi_t prime = 0;
|
|
||||||
gcry_mpi_t secret = 0;
|
|
||||||
gcry_mpi_t key = 0;
|
|
||||||
gcry_error_t e;
|
|
||||||
|
|
||||||
e = gcry_mpi_scan(&prime, GCRYMPI_FMT_USG, dh_prime, sizeof(dh_prime), 0);
|
|
||||||
if (e) goto get_out;
|
|
||||||
e = gcry_mpi_scan(&secret, GCRYMPI_FMT_USG, m_dh_local_secret, sizeof(m_dh_local_secret), 0);
|
|
||||||
if (e) goto get_out;
|
|
||||||
|
|
||||||
key = gcry_mpi_new(8);
|
|
||||||
|
|
||||||
// generator is 2
|
|
||||||
gcry_mpi_set_ui(key, 2);
|
|
||||||
// key = (2 ^ secret) % prime
|
|
||||||
gcry_mpi_powm(key, key, secret, prime);
|
|
||||||
|
|
||||||
// key is now our local key
|
|
||||||
size_t written;
|
|
||||||
gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char*)m_dh_local_key
|
|
||||||
, sizeof(m_dh_local_key), &written, key);
|
|
||||||
if (written < 96)
|
|
||||||
{
|
|
||||||
memmove(m_dh_local_key + (sizeof(m_dh_local_key) - written), m_dh_local_key, written);
|
|
||||||
memset(m_dh_local_key, 0, sizeof(m_dh_local_key) - written);
|
|
||||||
}
|
|
||||||
|
|
||||||
get_out:
|
|
||||||
if (key) gcry_mpi_release(key);
|
|
||||||
if (prime) gcry_mpi_release(prime);
|
|
||||||
if (secret) gcry_mpi_release(secret);
|
|
||||||
|
|
||||||
#elif defined TORRENT_USE_OPENSSL
|
|
||||||
// create local key
|
|
||||||
for (int i = 0; i < sizeof(m_dh_local_secret); ++i)
|
|
||||||
m_dh_local_secret[i] = random() & 0xff;
|
|
||||||
|
|
||||||
BIGNUM* prime = 0;
|
|
||||||
BIGNUM* secret = 0;
|
|
||||||
BIGNUM* key = 0;
|
|
||||||
BN_CTX* ctx = 0;
|
|
||||||
int size;
|
|
||||||
|
|
||||||
prime = BN_bin2bn(dh_prime, sizeof(dh_prime), 0);
|
|
||||||
if (prime == 0) goto get_out;
|
|
||||||
secret = BN_bin2bn((unsigned char*)m_dh_local_secret, sizeof(m_dh_local_secret), 0);
|
|
||||||
if (secret == 0) goto get_out;
|
|
||||||
|
|
||||||
key = BN_new();
|
|
||||||
if (key == 0) goto get_out;
|
|
||||||
// generator is 2
|
|
||||||
BN_set_word(key, 2);
|
|
||||||
|
|
||||||
ctx = BN_CTX_new();
|
|
||||||
if (ctx == 0) goto get_out;
|
|
||||||
BN_mod_exp(key, key, secret, prime, ctx);
|
|
||||||
BN_CTX_free(ctx);
|
|
||||||
|
|
||||||
// print key to m_dh_local_key
|
|
||||||
size = BN_num_bytes(key);
|
|
||||||
memset(m_dh_local_key, 0, sizeof(m_dh_local_key) - size);
|
|
||||||
BN_bn2bin(key, (unsigned char*)m_dh_local_key + sizeof(m_dh_local_key) - size);
|
|
||||||
|
|
||||||
get_out:
|
|
||||||
if (key) BN_free(key);
|
|
||||||
if (secret) BN_free(secret);
|
|
||||||
if (prime) BN_free(prime);
|
|
||||||
#elif defined TORRENT_USE_TOMMATH
|
|
||||||
// create local key
|
// create local key
|
||||||
for (int i = 0; i < int(sizeof(m_dh_local_secret)); ++i)
|
for (int i = 0; i < int(sizeof(m_dh_local_secret)); ++i)
|
||||||
m_dh_local_secret[i] = random() & 0xff;
|
m_dh_local_secret[i] = random() & 0xff;
|
||||||
|
|
||||||
mp_int prime;
|
mp_bigint prime;
|
||||||
mp_int secret;
|
mp_bigint secret;
|
||||||
mp_int key;
|
mp_bigint key;
|
||||||
int e;
|
|
||||||
int size;
|
|
||||||
|
|
||||||
mp_init(&prime);
|
if (mp_read_unsigned_bin(&prime, dh_prime, sizeof(dh_prime)))
|
||||||
mp_init(&secret);
|
return;
|
||||||
mp_init(&key);
|
if (mp_read_unsigned_bin(&secret, (unsigned char*)m_dh_local_secret, sizeof(m_dh_local_secret)))
|
||||||
|
return;
|
||||||
e = mp_read_unsigned_bin(&prime, dh_prime, sizeof(dh_prime));
|
|
||||||
if (e) goto get_out;
|
|
||||||
e = mp_read_unsigned_bin(&secret, (unsigned char*)m_dh_local_secret, sizeof(m_dh_local_secret));
|
|
||||||
if (e) goto get_out;
|
|
||||||
|
|
||||||
// generator is 2
|
// generator is 2
|
||||||
mp_set_int(&key, 2);
|
mp_set_int(&key, 2);
|
||||||
// key = (2 ^ secret) % prime
|
// key = (2 ^ secret) % prime
|
||||||
e = mp_exptmod(&key, &secret, &prime, &key);
|
if (mp_exptmod(&key, &secret, &prime, &key))
|
||||||
if (e) goto get_out;
|
return;
|
||||||
|
|
||||||
// key is now our local key
|
// key is now our local key
|
||||||
size = mp_unsigned_bin_size(&key);
|
int size = mp_unsigned_bin_size(&key);
|
||||||
memset(m_dh_local_key, 0, sizeof(m_dh_local_key) - size);
|
memset(m_dh_local_key, 0, sizeof(m_dh_local_key) - size);
|
||||||
mp_to_unsigned_bin(&key, (unsigned char*)m_dh_local_key + sizeof(m_dh_local_key) - size);
|
mp_to_unsigned_bin(&key, (unsigned char*)m_dh_local_key + sizeof(m_dh_local_key) - size);
|
||||||
|
|
||||||
get_out:
|
|
||||||
mp_clear(&key);
|
|
||||||
mp_clear(&prime);
|
|
||||||
mp_clear(&secret);
|
|
||||||
#else
|
|
||||||
#error you must define which bigint library to use
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char const* dh_key_exchange::get_local_key() const
|
char const* dh_key_exchange::get_local_key() const
|
||||||
{
|
{
|
||||||
return m_dh_local_key;
|
return m_dh_local_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// compute shared secret given remote public key
|
// compute shared secret given remote public key
|
||||||
int dh_key_exchange::compute_secret(char const* remote_pubkey)
|
int dh_key_exchange::compute_secret(char const* remote_pubkey)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(remote_pubkey);
|
TORRENT_ASSERT(remote_pubkey);
|
||||||
int ret = 0;
|
mp_bigint prime;
|
||||||
#ifdef TORRENT_USE_GCRYPT
|
mp_bigint secret;
|
||||||
|
mp_bigint remote_key;
|
||||||
|
|
||||||
gcry_mpi_t prime = 0;
|
if (mp_read_unsigned_bin(&prime, dh_prime, sizeof(dh_prime)))
|
||||||
gcry_mpi_t remote_key = 0;
|
return -1;
|
||||||
gcry_mpi_t secret = 0;
|
if (mp_read_unsigned_bin(&secret, (unsigned char*)m_dh_local_secret, sizeof(m_dh_local_secret)))
|
||||||
size_t written;
|
return -1;
|
||||||
gcry_error_t e;
|
if (mp_read_unsigned_bin(&remote_key, (unsigned char*)remote_pubkey, 96))
|
||||||
|
return -1;
|
||||||
|
|
||||||
e = gcry_mpi_scan(&prime, GCRYMPI_FMT_USG, dh_prime, sizeof(dh_prime), 0);
|
if (mp_exptmod(&remote_key, &secret, &prime, &remote_key))
|
||||||
if (e != 0) { ret = 1; goto get_out; }
|
return -1;
|
||||||
e = gcry_mpi_scan(&remote_key, GCRYMPI_FMT_USG, remote_pubkey, 96, 0);
|
|
||||||
if (e != 0) { ret = 1; goto get_out; }
|
|
||||||
e = gcry_mpi_scan(&secret, GCRYMPI_FMT_USG, (unsigned char const*)m_dh_local_secret
|
|
||||||
, sizeof(m_dh_local_secret), 0);
|
|
||||||
if (e != 0) { ret = 1; goto get_out; }
|
|
||||||
|
|
||||||
gcry_mpi_powm(remote_key, remote_key, secret, prime);
|
|
||||||
|
|
||||||
// remote_key is now the shared secret
|
// remote_key is now the shared secret
|
||||||
e = gcry_mpi_print(GCRYMPI_FMT_USG, (unsigned char*)m_dh_shared_secret
|
int size = mp_unsigned_bin_size(&remote_key);
|
||||||
, sizeof(m_dh_shared_secret), &written, remote_key);
|
|
||||||
if (e != 0) { ret = 1; goto get_out; }
|
|
||||||
|
|
||||||
if (written < 96)
|
|
||||||
{
|
|
||||||
memmove(m_dh_shared_secret, m_dh_shared_secret
|
|
||||||
+ (sizeof(m_dh_shared_secret) - written), written);
|
|
||||||
memset(m_dh_shared_secret, 0, sizeof(m_dh_shared_secret) - written);
|
|
||||||
}
|
|
||||||
|
|
||||||
get_out:
|
|
||||||
// TODO: 3 clean this up using destructors instead
|
|
||||||
if (prime) gcry_mpi_release(prime);
|
|
||||||
if (remote_key) gcry_mpi_release(remote_key);
|
|
||||||
if (secret) gcry_mpi_release(secret);
|
|
||||||
|
|
||||||
#elif defined TORRENT_USE_OPENSSL
|
|
||||||
|
|
||||||
BIGNUM* prime = 0;
|
|
||||||
BIGNUM* secret = 0;
|
|
||||||
BIGNUM* remote_key = 0;
|
|
||||||
BN_CTX* ctx = 0;
|
|
||||||
int size;
|
|
||||||
|
|
||||||
prime = BN_bin2bn(dh_prime, sizeof(dh_prime), 0);
|
|
||||||
if (prime == 0) { ret = 1; goto get_out; }
|
|
||||||
secret = BN_bin2bn((unsigned char*)m_dh_local_secret, sizeof(m_dh_local_secret), 0);
|
|
||||||
if (secret == 0) { ret = 1; goto get_out; }
|
|
||||||
remote_key = BN_bin2bn((unsigned char*)remote_pubkey, 96, 0);
|
|
||||||
if (remote_key == 0) { ret = 1; goto get_out; }
|
|
||||||
|
|
||||||
ctx = BN_CTX_new();
|
|
||||||
if (ctx == 0) { ret = 1; goto get_out; }
|
|
||||||
BN_mod_exp(remote_key, remote_key, secret, prime, ctx);
|
|
||||||
BN_CTX_free(ctx);
|
|
||||||
|
|
||||||
// remote_key is now the shared secret
|
|
||||||
size = BN_num_bytes(remote_key);
|
|
||||||
memset(m_dh_shared_secret, 0, sizeof(m_dh_shared_secret) - size);
|
|
||||||
BN_bn2bin(remote_key, (unsigned char*)m_dh_shared_secret + sizeof(m_dh_shared_secret) - size);
|
|
||||||
|
|
||||||
get_out:
|
|
||||||
BN_free(remote_key);
|
|
||||||
BN_free(secret);
|
|
||||||
BN_free(prime);
|
|
||||||
#elif defined TORRENT_USE_TOMMATH
|
|
||||||
mp_int prime;
|
|
||||||
mp_int secret;
|
|
||||||
mp_int remote_key;
|
|
||||||
int size;
|
|
||||||
int e;
|
|
||||||
|
|
||||||
mp_init(&prime);
|
|
||||||
mp_init(&secret);
|
|
||||||
mp_init(&remote_key);
|
|
||||||
|
|
||||||
e = mp_read_unsigned_bin(&prime, dh_prime, sizeof(dh_prime));
|
|
||||||
if (e) { ret = 1; goto get_out; }
|
|
||||||
e = mp_read_unsigned_bin(&secret, (unsigned char*)m_dh_local_secret, sizeof(m_dh_local_secret));
|
|
||||||
if (e) { ret = 1; goto get_out; }
|
|
||||||
e = mp_read_unsigned_bin(&remote_key, (unsigned char*)remote_pubkey, 96);
|
|
||||||
if (e) { ret = 1; goto get_out; }
|
|
||||||
|
|
||||||
e = mp_exptmod(&remote_key, &secret, &prime, &remote_key);
|
|
||||||
if (e) goto get_out;
|
|
||||||
|
|
||||||
// remote_key is now the shared secret
|
|
||||||
size = mp_unsigned_bin_size(&remote_key);
|
|
||||||
memset(m_dh_shared_secret, 0, sizeof(m_dh_shared_secret) - size);
|
memset(m_dh_shared_secret, 0, sizeof(m_dh_shared_secret) - size);
|
||||||
mp_to_unsigned_bin(&remote_key, (unsigned char*)m_dh_shared_secret + sizeof(m_dh_shared_secret) - size);
|
mp_to_unsigned_bin(&remote_key, (unsigned char*)m_dh_shared_secret + sizeof(m_dh_shared_secret) - size);
|
||||||
|
|
||||||
get_out:
|
|
||||||
mp_clear(&remote_key);
|
|
||||||
mp_clear(&secret);
|
|
||||||
mp_clear(&prime);
|
|
||||||
#else
|
|
||||||
#error you must define which bigint library to use
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// calculate the xor mask for the obfuscated hash
|
// calculate the xor mask for the obfuscated hash
|
||||||
hasher h;
|
hasher h;
|
||||||
h.update("req3", 4);
|
h.update("req3", 4);
|
||||||
h.update(m_dh_shared_secret, sizeof(m_dh_shared_secret));
|
h.update(m_dh_shared_secret, sizeof(m_dh_shared_secret));
|
||||||
m_xor_mask = h.final();
|
m_xor_mask = h.final();
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int encryption_handler::encrypt(std::vector<asio::mutable_buffer>& iovec)
|
int encryption_handler::encrypt(std::vector<asio::mutable_buffer>& iovec)
|
||||||
|
@ -431,15 +267,7 @@ get_out:
|
||||||
void rc4_handler::set_incoming_key(unsigned char const* key, int len)
|
void rc4_handler::set_incoming_key(unsigned char const* key, int len)
|
||||||
{
|
{
|
||||||
m_decrypt = true;
|
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);
|
rc4_init(key, len, &m_rc4_incoming);
|
||||||
#endif
|
|
||||||
// Discard first 1024 bytes
|
// Discard first 1024 bytes
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
std::vector<boost::asio::mutable_buffer> vec(1, boost::asio::mutable_buffer(buf, 1024));
|
std::vector<boost::asio::mutable_buffer> vec(1, boost::asio::mutable_buffer(buf, 1024));
|
||||||
|
@ -452,15 +280,7 @@ get_out:
|
||||||
void rc4_handler::set_outgoing_key(unsigned char const* key, int len)
|
void rc4_handler::set_outgoing_key(unsigned char const* key, int len)
|
||||||
{
|
{
|
||||||
m_encrypt = true;
|
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);
|
rc4_init(key, len, &m_rc4_outgoing);
|
||||||
#endif
|
|
||||||
// Discard first 1024 bytes
|
// Discard first 1024 bytes
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
std::vector<boost::asio::mutable_buffer> vec(1, boost::asio::mutable_buffer(buf, 1024));
|
std::vector<boost::asio::mutable_buffer> vec(1, boost::asio::mutable_buffer(buf, 1024));
|
||||||
|
@ -483,13 +303,7 @@ get_out:
|
||||||
TORRENT_ASSERT(pos);
|
TORRENT_ASSERT(pos);
|
||||||
|
|
||||||
bytes_processed += len;
|
bytes_processed += len;
|
||||||
#ifdef TORRENT_USE_GCRYPT
|
|
||||||
gcry_cipher_encrypt(m_rc4_outgoing, pos, len, 0, 0);
|
|
||||||
#elif defined TORRENT_USE_OPENSSL
|
|
||||||
RC4(&m_local_key, len, (const unsigned char*)pos, (unsigned char*)pos);
|
|
||||||
#else
|
|
||||||
rc4_encrypt((unsigned char*)pos, len, &m_rc4_outgoing);
|
rc4_encrypt((unsigned char*)pos, len, &m_rc4_outgoing);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
buf.clear();
|
buf.clear();
|
||||||
return bytes_processed;
|
return bytes_processed;
|
||||||
|
@ -513,13 +327,7 @@ get_out:
|
||||||
TORRENT_ASSERT(pos);
|
TORRENT_ASSERT(pos);
|
||||||
|
|
||||||
bytes_processed += len;
|
bytes_processed += len;
|
||||||
#ifdef TORRENT_USE_GCRYPT
|
|
||||||
gcry_cipher_decrypt(m_rc4_incoming, pos, len, 0, 0);
|
|
||||||
#elif defined TORRENT_USE_OPENSSL
|
|
||||||
RC4(&m_remote_key, len, (const unsigned char*)pos, (unsigned char*)pos);
|
|
||||||
#else
|
|
||||||
rc4_encrypt((unsigned char*)pos, len, &m_rc4_incoming);
|
rc4_encrypt((unsigned char*)pos, len, &m_rc4_incoming);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
buf.clear();
|
buf.clear();
|
||||||
produce = bytes_processed;
|
produce = bytes_processed;
|
||||||
|
@ -527,8 +335,6 @@ get_out:
|
||||||
|
|
||||||
} // namespace libtorrent
|
} // namespace libtorrent
|
||||||
|
|
||||||
#if !defined TORRENT_USE_OPENSSL && !defined TORRENT_USE_GCRYPT
|
|
||||||
|
|
||||||
// All this code is based on libTomCrypt (http://www.libtomcrypt.com/)
|
// All this code is based on libTomCrypt (http://www.libtomcrypt.com/)
|
||||||
// this library is public domain and has been specially
|
// this library is public domain and has been specially
|
||||||
// tailored for libtorrent by Arvid Norberg
|
// tailored for libtorrent by Arvid Norberg
|
||||||
|
@ -591,7 +397,5 @@ unsigned long rc4_encrypt(unsigned char *out, unsigned long outlen, rc4 *state)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // #if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
#endif // #if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue