refactor: migrate tr_crypto C functions to members (#3430)

This commit is contained in:
Charles Kerr 2022-07-10 21:57:05 -05:00 committed by GitHub
parent 5e4c7f9a1e
commit 0a39cb9302
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 204 additions and 272 deletions

View File

@ -13,14 +13,34 @@
#include "tr-assert.h"
#include "utils.h"
/**
***
**/
///
static auto constexpr PrimeLen = size_t{ 96 };
static auto constexpr DhPrivkeyLen = size_t{ 20 };
tr_crypto::tr_crypto(tr_sha1_digest_t const* torrent_hash, bool is_incoming)
: is_incoming_{ is_incoming }
{
if (torrent_hash != nullptr)
{
this->torrent_hash_ = *torrent_hash;
}
}
static uint8_t constexpr dh_P[PrimeLen] = {
tr_crypto::~tr_crypto()
{
tr_dh_secret_free(my_secret_);
tr_dh_free(dh_);
tr_free(enc_key_);
tr_free(dec_key_);
}
///
namespace
{
auto constexpr PrimeLen = size_t{ 96 };
auto constexpr DhPrivkeyLen = size_t{ 20 };
uint8_t constexpr dh_P[PrimeLen] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, //
0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, //
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, //
@ -31,76 +51,20 @@ static uint8_t constexpr dh_P[PrimeLen] = {
0xA6, 0x3A, 0x36, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x05, 0x63, //
};
static uint8_t constexpr dh_G[] = { 2 };
uint8_t constexpr dh_G[] = { 2 };
/**
***
**/
static void ensureKeyExists(tr_crypto* crypto)
void init_rc4(tr_crypto const* crypto, struct arc4_context** setme, std::string_view key)
{
if (crypto->dh == nullptr)
{
size_t public_key_length = KEY_LEN;
crypto->dh = tr_dh_new(dh_P, sizeof(dh_P), dh_G, sizeof(dh_G));
tr_dh_make_key(crypto->dh, DhPrivkeyLen, crypto->myPublicKey, &public_key_length);
TR_ASSERT(public_key_length == KEY_LEN);
}
}
tr_crypto::tr_crypto(tr_sha1_digest_t const* torrent_hash_in, bool is_incoming_in)
: is_incoming{ is_incoming_in }
{
if (torrent_hash_in != nullptr)
{
this->torrent_hash = *torrent_hash_in;
}
}
tr_crypto::~tr_crypto()
{
tr_dh_secret_free(this->mySecret);
tr_dh_free(this->dh);
tr_free(this->enc_key);
tr_free(this->dec_key);
}
/**
***
**/
bool tr_cryptoComputeSecret(tr_crypto* crypto, uint8_t const* peerPublicKey)
{
ensureKeyExists(crypto);
crypto->mySecret = tr_dh_agree(crypto->dh, peerPublicKey, KEY_LEN);
return crypto->mySecret != nullptr;
}
uint8_t const* tr_cryptoGetMyPublicKey(tr_crypto const* crypto, int* setme_len)
{
ensureKeyExists(const_cast<tr_crypto*>(crypto));
*setme_len = KEY_LEN;
return crypto->myPublicKey;
}
/**
***
**/
static void init_rc4(tr_crypto const* crypto, struct arc4_context** setme, char const* key)
{
TR_ASSERT(crypto->torrent_hash);
TR_ASSERT(crypto->torrentHash());
if (*setme == nullptr)
{
*setme = tr_new0(struct arc4_context, 1);
}
auto const buf = crypto->torrent_hash ?
tr_cryptoSecretKeySha1(crypto, key, 4, std::data(*crypto->torrent_hash), std::size(*crypto->torrent_hash)) :
std::nullopt;
auto const hash = crypto->torrentHash();
auto const buf = hash ? crypto->secretKeySha1(std::data(key), std::size(key), std::data(*hash), std::size(*hash)) :
std::nullopt;
if (buf)
{
arc4_init(*setme, std::data(*buf), std::size(*buf));
@ -108,7 +72,7 @@ static void init_rc4(tr_crypto const* crypto, struct arc4_context** setme, char
}
}
static void crypt_rc4(struct arc4_context* key, size_t buf_len, void const* buf_in, void* buf_out)
void crypt_rc4(struct arc4_context* key, size_t buf_len, void const* buf_in, void* buf_out)
{
if (key == nullptr)
{
@ -123,51 +87,62 @@ static void crypt_rc4(struct arc4_context* key, size_t buf_len, void const* buf_
arc4_process(key, buf_in, buf_out, buf_len);
}
void tr_cryptoDecryptInit(tr_crypto* crypto)
} // namespace
///
bool tr_crypto::computeSecret(void const* peer_public_key, size_t len)
{
init_rc4(crypto, &crypto->dec_key, crypto->is_incoming ? "keyA" : "keyB"); // lgtm[cpp/weak-cryptographic-algorithm]
ensureKeyExists();
my_secret_ = tr_dh_agree(dh_, static_cast<uint8_t const*>(peer_public_key), len);
return my_secret_ != nullptr;
}
void tr_cryptoDecrypt(tr_crypto* crypto, size_t buf_len, void const* buf_in, void* buf_out)
void tr_crypto::ensureKeyExists()
{
crypt_rc4(crypto->dec_key, buf_len, buf_in, buf_out); // lgtm[cpp/weak-cryptographic-algorithm]
if (dh_ == nullptr)
{
size_t public_key_length = KEY_LEN;
dh_ = tr_dh_new(dh_P, sizeof(dh_P), dh_G, sizeof(dh_G));
tr_dh_make_key(dh_, DhPrivkeyLen, my_public_key_, &public_key_length);
TR_ASSERT(public_key_length == KEY_LEN);
}
}
void tr_crypto::decryptInit()
{
init_rc4(this, &dec_key_, is_incoming_ ? "keyA" : "keyB"); // lgtm[cpp/weak-cryptographic-algorithm]
}
void tr_cryptoEncryptInit(tr_crypto* crypto)
void tr_crypto::decrypt(size_t buf_len, void const* buf_in, void* buf_out)
{
init_rc4(crypto, &crypto->enc_key, crypto->is_incoming ? "keyB" : "keyA"); // lgtm[cpp/weak-cryptographic-algorithm]
crypt_rc4(dec_key_, buf_len, buf_in, buf_out); // lgtm[cpp/weak-cryptographic-algorithm]
}
void tr_cryptoEncrypt(tr_crypto* crypto, size_t buf_len, void const* buf_in, void* buf_out)
void tr_crypto::encryptInit()
{
crypt_rc4(crypto->enc_key, buf_len, buf_in, buf_out); // lgtm[cpp/weak-cryptographic-algorithm]
init_rc4(this, &enc_key_, is_incoming_ ? "keyB" : "keyA"); // lgtm[cpp/weak-cryptographic-algorithm]
}
std::optional<tr_sha1_digest_t> tr_cryptoSecretKeySha1(
tr_crypto const* crypto,
void const* prepend_data,
size_t prepend_data_size,
void const* append_data,
size_t append_data_size)
void tr_crypto::encrypt(size_t buf_len, void const* buf_in, void* buf_out)
{
TR_ASSERT(crypto != nullptr);
TR_ASSERT(crypto->mySecret != nullptr);
return tr_dh_secret_derive(crypto->mySecret, prepend_data, prepend_data_size, append_data, append_data_size);
crypt_rc4(enc_key_, buf_len, buf_in, buf_out); // lgtm[cpp/weak-cryptographic-algorithm]
}
/**
***
**/
void tr_cryptoSetTorrentHash(tr_crypto* crypto, tr_sha1_digest_t const& hash)
std::optional<tr_sha1_digest_t> tr_crypto::secretKeySha1(
void const* prepend,
size_t prepend_len,
void const* append,
size_t append_len) const
{
crypto->torrent_hash = hash;
return tr_dh_secret_derive(my_secret_, prepend, prepend_len, append, append_len);
}
std::optional<tr_sha1_digest_t> tr_cryptoGetTorrentHash(tr_crypto const* crypto)
std::vector<uint8_t> tr_crypto::pad(size_t maxlen) const
{
TR_ASSERT(crypto != nullptr);
return crypto->torrent_hash;
auto const len = tr_rand_int(maxlen);
auto ret = std::vector<uint8_t>{};
ret.resize(len);
tr_rand_buffer(std::data(ret), len);
return ret;
}

View File

@ -14,15 +14,12 @@
#include <cstddef> // size_t
#include <cstdint> // uint8_t
#include <optional>
#include <string_view>
#include <vector>
#include "crypto-utils.h"
#include "tr-macros.h"
/**
*** @addtogroup peers
*** @{
**/
enum
{
KEY_LEN = 96
@ -34,38 +31,57 @@ struct tr_crypto
tr_crypto(tr_sha1_digest_t const* torrent_hash = nullptr, bool is_incoming = true);
~tr_crypto();
std::optional<tr_sha1_digest_t> torrent_hash = {};
struct arc4_context* dec_key = nullptr;
struct arc4_context* enc_key = nullptr;
tr_dh_ctx_t dh = {};
uint8_t myPublicKey[KEY_LEN] = {};
tr_dh_secret_t mySecret = {};
bool is_incoming = false;
tr_crypto& operator=(tr_crypto const&) = delete;
tr_crypto& operator=(tr_crypto&&) = delete;
tr_crypto(tr_crypto const&) = delete;
tr_crypto(tr_crypto&&) = delete;
void setTorrentHash(tr_sha1_digest_t hash) noexcept
{
torrent_hash_ = hash;
}
[[nodiscard]] constexpr auto const& torrentHash() const noexcept
{
return torrent_hash_;
}
[[nodiscard]] std::string_view myPublicKey()
{
ensureKeyExists();
return { reinterpret_cast<char const*>(my_public_key_), KEY_LEN };
}
[[nodiscard]] bool computeSecret(void const* peer_public_key, size_t len);
[[nodiscard]] std::optional<tr_sha1_digest_t> secretKeySha1(
void const* prepend,
size_t prepend_len,
void const* append,
size_t append_len) const;
[[nodiscard]] constexpr auto isIncoming() const noexcept
{
return is_incoming_;
}
[[nodiscard]] virtual std::vector<uint8_t> pad(size_t maxlen) const;
void decryptInit();
void decrypt(size_t buflen, void const* buf_in, void* buf_out);
void encryptInit();
void encrypt(size_t buflen, void const* buf_in, void* buf_out);
private:
void ensureKeyExists();
std::optional<tr_sha1_digest_t> torrent_hash_;
struct arc4_context* dec_key_ = nullptr;
struct arc4_context* enc_key_ = nullptr;
tr_dh_ctx_t dh_ = {};
tr_dh_secret_t my_secret_ = {};
uint8_t my_public_key_[KEY_LEN] = {};
bool const is_incoming_;
};
void tr_cryptoSetTorrentHash(tr_crypto* crypto, tr_sha1_digest_t const& torrent_hash);
std::optional<tr_sha1_digest_t> tr_cryptoGetTorrentHash(tr_crypto const* crypto);
bool tr_cryptoComputeSecret(tr_crypto* crypto, uint8_t const* peerPublicKey);
uint8_t const* tr_cryptoGetMyPublicKey(tr_crypto const* crypto, int* setme_len);
void tr_cryptoDecryptInit(tr_crypto* crypto);
void tr_cryptoDecrypt(tr_crypto* crypto, size_t buflen, void const* buf_in, void* buf_out);
void tr_cryptoEncryptInit(tr_crypto* crypto);
void tr_cryptoEncrypt(tr_crypto* crypto, size_t buflen, void const* buf_in, void* buf_out);
std::optional<tr_sha1_digest_t> tr_cryptoSecretKeySha1(
tr_crypto const* crypto,
void const* prepend_data,
size_t prepend_data_size,
void const* append_data,
size_t append_data_size);
/* @} */
#endif // TR_ENCRYPTION_H

View File

@ -173,7 +173,7 @@ static void setReadState(tr_handshake* handshake, handshake_state_t state)
static bool buildHandshakeMessage(tr_handshake* handshake, uint8_t* buf)
{
auto const torrent_hash = tr_cryptoGetTorrentHash(handshake->crypto);
auto const torrent_hash = handshake->crypto->torrentHash();
auto* const tor = torrent_hash ? handshake->session->torrents().get(*torrent_hash) : nullptr;
bool const success = tor != nullptr;
@ -242,7 +242,7 @@ static handshake_parse_err_t parseHandshake(tr_handshake* handshake, struct evbu
/* torrent hash */
auto hash = tr_sha1_digest_t{};
tr_peerIoReadBytes(handshake->io, inbuf, std::data(hash), std::size(hash));
if (auto const torrent_hash = tr_peerIoGetTorrentHash(handshake->io); !torrent_hash || *torrent_hash != hash)
if (auto const torrent_hash = handshake->io->torrentHash(); !torrent_hash || *torrent_hash != hash)
{
tr_logAddTraceHand(handshake, "peer returned the wrong hash. wtf?");
return HANDSHAKE_BAD_TORRENT;
@ -285,19 +285,16 @@ static void sendYa(tr_handshake* handshake)
{
/* add our public key (Ya) */
int len = 0;
uint8_t const* const public_key = tr_cryptoGetMyPublicKey(handshake->crypto, &len);
TR_ASSERT(len == KEY_LEN);
TR_ASSERT(public_key != nullptr);
auto const public_key = handshake->crypto->myPublicKey();
TR_ASSERT(std::size(public_key) == KEY_LEN);
char outbuf[KEY_LEN + PadA_MAXLEN];
char* walk = outbuf;
walk = std::copy_n(public_key, len, walk);
walk = std::copy(std::begin(public_key), std::end(public_key), walk);
/* add some bullshit padding */
len = tr_rand_int(PadA_MAXLEN);
tr_rand_buffer(walk, len);
walk += len;
// add some random padding
auto const pad_a = handshake->crypto->pad(PadA_MAXLEN);
walk = std::copy(std::begin(pad_a), std::end(pad_a), walk);
/* send it */
setReadState(handshake, AWAITING_YB);
@ -358,7 +355,7 @@ static uint32_t getCryptoSelect(tr_handshake const* handshake, uint32_t crypto_p
static auto computeRequestHash(tr_handshake const* handshake, std::string_view name)
{
return tr_cryptoSecretKeySha1(handshake->crypto, std::data(name), std::size(name), "", 0);
return handshake->crypto->secretKeySha1(std::data(name), std::size(name), "", 0);
}
static ReadState readYb(tr_handshake* handshake, struct evbuffer* inbuf)
@ -398,7 +395,7 @@ static ReadState readYb(tr_handshake* handshake, struct evbuffer* inbuf)
/* compute the secret */
evbuffer_remove(inbuf, yb, KEY_LEN);
if (!tr_cryptoComputeSecret(handshake->crypto, yb))
if (!handshake->crypto->computeSecret(yb, KEY_LEN))
{
return tr_handshakeDone(handshake, false);
}
@ -420,7 +417,7 @@ static ReadState readYb(tr_handshake* handshake, struct evbuffer* inbuf)
/* HASH('req2', SKEY) xor HASH('req3', S) */
{
auto const hash = tr_cryptoGetTorrentHash(handshake->crypto);
auto const hash = handshake->crypto->torrentHash();
if (!hash)
{
tr_logAddTraceHand(handshake, "error while computing req2/req3 hash after Yb");
@ -451,7 +448,7 @@ static ReadState readYb(tr_handshake* handshake, struct evbuffer* inbuf)
uint8_t vc[VC_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 };
tr_peerIoWriteBuf(handshake->io, outbuf, false);
tr_cryptoEncryptInit(handshake->crypto);
handshake->crypto->encryptInit();
tr_peerIoSetEncryption(handshake->io, PEER_ENCRYPTION_RC4);
evbuffer_add(outbuf, vc, VC_LENGTH);
@ -475,7 +472,7 @@ static ReadState readYb(tr_handshake* handshake, struct evbuffer* inbuf)
}
/* send it */
tr_cryptoDecryptInit(handshake->crypto);
handshake->crypto->decryptInit();
setReadState(handshake, AWAITING_VC);
tr_peerIoWriteBuf(handshake->io, outbuf, false);
@ -502,8 +499,8 @@ static ReadState readVC(tr_handshake* handshake, struct evbuffer* inbuf)
}
memcpy(tmp, evbuffer_pullup(inbuf, key_len), key_len);
tr_cryptoDecryptInit(handshake->crypto);
tr_cryptoDecrypt(handshake->crypto, key_len, tmp, tmp);
handshake->crypto->decryptInit();
handshake->crypto->decrypt(key_len, tmp, tmp);
if (memcmp(tmp, key, key_len) == 0)
{
@ -614,7 +611,7 @@ static ReadState readHandshake(tr_handshake* handshake, struct evbuffer* inbuf)
return READ_NOW;
}
tr_cryptoDecrypt(handshake->crypto, 1, &pstrlen, &pstrlen);
handshake->crypto->decrypt(1, &pstrlen, &pstrlen);
if (pstrlen != 19)
{
@ -660,11 +657,12 @@ static ReadState readHandshake(tr_handshake* handshake, struct evbuffer* inbuf)
return tr_handshakeDone(handshake, false);
}
tr_peerIoSetTorrentHash(handshake->io, hash);
handshake->io->setTorrentHash(hash);
}
else /* outgoing */
{
auto const torrent_hash = tr_peerIoGetTorrentHash(handshake->io);
auto const torrent_hash = handshake->io->torrentHash();
if (!torrent_hash || *torrent_hash != hash)
{
tr_logAddTraceHand(handshake, "peer returned the wrong hash. wtf?");
@ -709,7 +707,7 @@ static ReadState readPeerId(tr_handshake* handshake, struct evbuffer* inbuf)
tr_logAddTraceHand(handshake, fmt::format("peer-id is '{}' ... isIncoming is {}", client, handshake->isIncoming()));
// if we've somehow connected to ourselves, don't keep the connection
auto const hash = tr_peerIoGetTorrentHash(handshake->io);
auto const hash = handshake->io->torrentHash();
auto* const tor = hash ? handshake->session->torrents().get(*hash) : nullptr;
bool const connected_to_self = tor != nullptr && peer_id == tr_torrentGetPeerId(tor);
@ -729,7 +727,7 @@ static ReadState readYa(tr_handshake* handshake, struct evbuffer* inbuf)
uint8_t ya[KEY_LEN];
evbuffer_remove(inbuf, ya, KEY_LEN);
if (!tr_cryptoComputeSecret(handshake->crypto, ya))
if (!handshake->crypto->computeSecret(ya, KEY_LEN))
{
return tr_handshakeDone(handshake, false);
}
@ -746,12 +744,10 @@ static ReadState readYa(tr_handshake* handshake, struct evbuffer* inbuf)
tr_logAddTraceHand(handshake, "sending B->A: Diffie Hellman Yb, PadB");
uint8_t outbuf[KEY_LEN + PadB_MAXLEN];
uint8_t* walk = outbuf;
int len = 0;
uint8_t const* const myKey = tr_cryptoGetMyPublicKey(handshake->crypto, &len);
walk = std::copy_n(myKey, len, walk);
len = tr_rand_int(PadB_MAXLEN);
tr_rand_buffer(walk, len);
walk += len;
auto const public_key = handshake->crypto->myPublicKey();
walk = std::copy(std::begin(public_key), std::end(public_key), walk);
auto const pad_b = handshake->crypto->pad(PadB_MAXLEN);
walk = std::copy(std::begin(pad_b), std::end(pad_b), walk);
setReadState(handshake, AWAITING_PAD_A);
tr_peerIoWriteBytes(handshake->io, outbuf, walk - outbuf, false);
@ -829,7 +825,7 @@ static ReadState readCryptoProvide(tr_handshake* handshake, struct evbuffer* inb
tr_logAddTraceHand(
handshake,
fmt::format("got INCOMING connection's encrypted handshake for torrent [{}]", tor->name()));
tr_peerIoSetTorrentHash(handshake->io, tor->infoHash());
handshake->io->setTorrentHash(tor->infoHash());
if (clientIsSeed && peerIsSeed)
{
@ -845,7 +841,7 @@ static ReadState readCryptoProvide(tr_handshake* handshake, struct evbuffer* inb
/* next part: ENCRYPT(VC, crypto_provide, len(PadC), */
tr_cryptoDecryptInit(handshake->crypto);
handshake->crypto->decryptInit();
tr_peerIoReadBytes(handshake->io, inbuf, vc_in, VC_LENGTH);
@ -897,7 +893,7 @@ static ReadState readIA(tr_handshake* handshake, struct evbuffer const* inbuf)
*** B->A: ENCRYPT(VC, crypto_select, len(padD), padD), ENCRYPT2(Payload Stream)
**/
tr_cryptoEncryptInit(handshake->crypto);
handshake->crypto->encryptInit();
evbuffer* const outbuf = evbuffer_new();
{
@ -1144,7 +1140,7 @@ static void gotError(tr_peerIo* io, short what, void* vhandshake)
{
/* This peer probably doesn't speak uTP. */
auto const hash = tr_peerIoGetTorrentHash(io);
auto const hash = io->torrentHash();
auto* const tor = hash ? handshake->session->torrents().get(*hash) : nullptr;
/* Don't mark a peer as non-uTP unless it's really a connect failure. */

View File

@ -861,24 +861,6 @@ int tr_peerIoReconnect(tr_peerIo* io)
***
**/
void tr_peerIoSetTorrentHash(tr_peerIo* io, tr_sha1_digest_t const& info_hash)
{
TR_ASSERT(tr_isPeerIo(io));
tr_cryptoSetTorrentHash(&io->crypto, info_hash);
}
std::optional<tr_sha1_digest_t> tr_peerIoGetTorrentHash(tr_peerIo const* io)
{
TR_ASSERT(tr_isPeerIo(io));
return tr_cryptoGetTorrentHash(&io->crypto);
}
/**
***
**/
static unsigned int getDesiredOutputBufferSize(tr_peerIo const* io, uint64_t now)
{
/* this is all kind of arbitrary, but what seems to work well is
@ -922,12 +904,7 @@ void tr_peerIoSetEncryption(tr_peerIo* io, tr_encryption_type encryption_type)
***
**/
static inline void processBuffer(
tr_crypto* crypto,
struct evbuffer* buffer,
size_t offset,
size_t size,
void (*callback)(tr_crypto*, size_t, void const*, void*))
static inline void processBuffer(tr_crypto& crypto, evbuffer* buffer, size_t offset, size_t size)
{
struct evbuffer_ptr pos;
struct evbuffer_iovec iovec;
@ -941,7 +918,7 @@ static inline void processBuffer(
break;
}
callback(crypto, iovec.iov_len, iovec.iov_base, iovec.iov_base);
crypto.encrypt(iovec.iov_len, iovec.iov_base, iovec.iov_base);
TR_ASSERT(size >= iovec.iov_len);
size -= iovec.iov_len;
@ -950,18 +927,15 @@ static inline void processBuffer(
TR_ASSERT(size == 0);
}
static inline void maybeEncryptBuffer(tr_peerIo* io, struct evbuffer* buf, size_t offset, size_t size)
{
if (io->encryption_type == PEER_ENCRYPTION_RC4)
{
processBuffer(&io->crypto, buf, offset, size, &tr_cryptoEncrypt);
}
}
void tr_peerIoWriteBuf(tr_peerIo* io, struct evbuffer* buf, bool isPieceData)
{
size_t const byteCount = evbuffer_get_length(buf);
maybeEncryptBuffer(io, buf, 0, byteCount);
if (io->encryption_type == PEER_ENCRYPTION_RC4)
{
processBuffer(io->crypto, buf, 0, byteCount);
}
evbuffer_add_buffer(io->outbuf.get(), buf);
io->outbuf_info.emplace_back(byteCount, isPieceData);
}
@ -975,7 +949,7 @@ void tr_peerIoWriteBytes(tr_peerIo* io, void const* bytes, size_t byteCount, boo
if (io->encryption_type == PEER_ENCRYPTION_RC4)
{
tr_cryptoEncrypt(&io->crypto, iovec.iov_len, bytes, iovec.iov_base);
io->crypto.encrypt(iovec.iov_len, bytes, iovec.iov_base);
}
else
{
@ -1031,7 +1005,7 @@ void tr_peerIoReadBytes(tr_peerIo* io, struct evbuffer* inbuf, void* bytes, size
case PEER_ENCRYPTION_RC4:
evbuffer_remove(inbuf, bytes, byteCount);
tr_cryptoDecrypt(&io->crypto, byteCount, bytes, bytes);
io->crypto.decrypt(byteCount, bytes, bytes);
break;
default:

View File

@ -107,11 +107,6 @@ public:
std::string addrStr() const;
[[nodiscard]] constexpr bool isIncoming() noexcept
{
return crypto.is_incoming;
}
[[nodiscard]] auto getReadBuffer() noexcept
{
return inbuf.get();
@ -184,6 +179,21 @@ public:
tr_crypto crypto;
[[nodiscard]] constexpr auto isIncoming() noexcept
{
return crypto.isIncoming();
}
void setTorrentHash(tr_sha1_digest_t hash) noexcept
{
crypto.setTorrentHash(hash);
}
[[nodiscard]] constexpr auto const& torrentHash() const noexcept
{
return crypto.torrentHash();
}
// TODO(ckerr): yikes, unlike other class' magic_numbers it looks
// like this one isn't being used just for assertions, but also in
// didWriteWrapper() to see if the tr_peerIo got freed during the
@ -285,10 +295,6 @@ constexpr tr_session* tr_peerIoGetSession(tr_peerIo* io)
return io->session;
}
std::optional<tr_sha1_digest_t> tr_peerIoGetTorrentHash(tr_peerIo const* io);
void tr_peerIoSetTorrentHash(tr_peerIo* io, tr_sha1_digest_t const& info_hash);
int tr_peerIoReconnect(tr_peerIo* io);
/**

View File

@ -1084,7 +1084,7 @@ static bool on_handshake_done(tr_handshake_result const& result)
bool success = false;
auto* manager = static_cast<tr_peerMgr*>(result.userData);
auto const hash = tr_peerIoGetTorrentHash(result.io);
auto const hash = result.io->torrentHash();
tr_swarm* const s = hash ? getExistingSwarm(manager, *hash) : nullptr;
auto const [addr, port] = result.io->socketAddress();
@ -2771,7 +2771,7 @@ void initiateConnection(tr_peerMgr* mgr, tr_swarm* s, peer_atom& atom)
{
tr_handshake* handshake = tr_handshakeNew(io, mgr->session->encryptionMode, on_handshake_done, mgr);
TR_ASSERT(tr_peerIoGetTorrentHash(io));
TR_ASSERT(io->torrentHash());
tr_peerIoUnref(io); /* balanced by the initial ref in tr_peerIoNewOutgoing() */

View File

@ -19,18 +19,6 @@
#define tr_x509_store_t tr_x509_store_t_
#define tr_x509_cert_t tr_x509_cert_t_
#define tr_crypto tr_crypto_
#define tr_cryptoConstruct tr_cryptoConstruct_
#define tr_cryptoDestruct tr_cryptoDestruct_
#define tr_cryptoSetTorrentHash tr_cryptoSetTorrentHash_
#define tr_cryptoGetTorrentHash tr_cryptoGetTorrentHash_
#define tr_cryptoHasTorrentHash tr_cryptoHasTorrentHash_
#define tr_cryptoComputeSecret tr_cryptoComputeSecret_
#define tr_cryptoGetMyPublicKey tr_cryptoGetMyPublicKey_
#define tr_cryptoDecryptInit tr_cryptoDecryptInit_
#define tr_cryptoDecrypt tr_cryptoDecrypt_
#define tr_cryptoEncryptInit tr_cryptoEncryptInit_
#define tr_cryptoEncrypt tr_cryptoEncrypt_
#define tr_cryptoSecretKeySha1 tr_cryptoSecretKeySha1_
#define tr_sha1 tr_sha1_
#define tr_sha1_init tr_sha1_init_
#define tr_sha1_update tr_sha1_update_
@ -84,18 +72,6 @@
#undef tr_x509_store_t
#undef tr_x509_cert_t
#undef tr_crypto
#undef tr_cryptoConstruct
#undef tr_cryptoDestruct
#undef tr_cryptoSetTorrentHash
#undef tr_cryptoGetTorrentHash
#undef tr_cryptoHasTorrentHash
#undef tr_cryptoComputeSecret
#undef tr_cryptoGetMyPublicKey
#undef tr_cryptoDecryptInit
#undef tr_cryptoDecrypt
#undef tr_cryptoEncryptInit
#undef tr_cryptoEncrypt
#undef tr_cryptoSecretKeySha1
#undef tr_sha1
#undef tr_sha1_init
#undef tr_sha1_update
@ -142,18 +118,6 @@
#define tr_x509_store_t_ tr_x509_store_t
#define tr_x509_cert_t_ tr_x509_cert_t
#define tr_crypto_ tr_crypto
#define tr_cryptoConstruct_ tr_cryptoConstruct
#define tr_cryptoDestruct_ tr_cryptoDestruct
#define tr_cryptoSetTorrentHash_ tr_cryptoSetTorrentHash
#define tr_cryptoGetTorrentHash_ tr_cryptoGetTorrentHash
#define tr_cryptoHasTorrentHash_ tr_cryptoHasTorrentHash
#define tr_cryptoComputeSecret_ tr_cryptoComputeSecret
#define tr_cryptoGetMyPublicKey_ tr_cryptoGetMyPublicKey
#define tr_cryptoDecryptInit_ tr_cryptoDecryptInit
#define tr_cryptoDecrypt_ tr_cryptoDecrypt
#define tr_cryptoEncryptInit_ tr_cryptoEncryptInit
#define tr_cryptoEncrypt_ tr_cryptoEncrypt
#define tr_cryptoSecretKeySha1_ tr_cryptoSecretKeySha1
#define tr_sha1_ tr_sha1
#define tr_sha1_init_ tr_sha1_init
#define tr_sha1_update_ tr_sha1_update

View File

@ -37,15 +37,15 @@ TEST(Crypto, torrentHash)
{
auto a = tr_crypto{};
EXPECT_FALSE(tr_cryptoGetTorrentHash(&a));
EXPECT_FALSE(a.torrentHash());
tr_cryptoSetTorrentHash(&a, SomeHash);
EXPECT_TRUE(tr_cryptoGetTorrentHash(&a));
EXPECT_EQ(SomeHash, *tr_cryptoGetTorrentHash(&a));
a.setTorrentHash(SomeHash);
EXPECT_TRUE(a.torrentHash());
EXPECT_EQ(SomeHash, *a.torrentHash());
a = tr_crypto{ &SomeHash, false };
EXPECT_TRUE(tr_cryptoGetTorrentHash(&a));
EXPECT_EQ(SomeHash, *tr_cryptoGetTorrentHash(&a));
auto b = tr_crypto{ &SomeHash, false };
EXPECT_TRUE(b.torrentHash());
EXPECT_EQ(SomeHash, *b.torrentHash());
}
TEST(Crypto, encryptDecrypt)
@ -53,29 +53,30 @@ TEST(Crypto, encryptDecrypt)
auto a = tr_crypto{ &SomeHash, false };
auto b = tr_crypto_{ &SomeHash, true };
auto public_key_length = int{};
EXPECT_TRUE(tr_cryptoComputeSecret(&a, tr_cryptoGetMyPublicKey_(&b, &public_key_length)));
EXPECT_TRUE(tr_cryptoComputeSecret_(&b, tr_cryptoGetMyPublicKey(&a, &public_key_length)));
auto public_key = b.myPublicKey();
EXPECT_TRUE(a.computeSecret(std::data(public_key), std::size(public_key)));
public_key = a.myPublicKey();
EXPECT_TRUE(b.computeSecret(std::data(public_key), std::size(public_key)));
auto const input1 = std::string{ "test1" };
auto constexpr Input1 = "test1"sv;
auto encrypted1 = std::array<char, 128>{};
auto decrypted1 = std::array<char, 128>{};
tr_cryptoEncryptInit(&a);
tr_cryptoEncrypt(&a, input1.size(), input1.data(), encrypted1.data());
tr_cryptoDecryptInit_(&b);
tr_cryptoDecrypt_(&b, input1.size(), encrypted1.data(), decrypted1.data());
EXPECT_EQ(input1, std::string(decrypted1.data(), input1.size()));
a.encryptInit();
a.encrypt(std::size(Input1), std::data(Input1), std::data(encrypted1));
b.decryptInit();
b.decrypt(std::size(Input1), std::data(encrypted1), std::data(decrypted1));
EXPECT_EQ(Input1, std::data(decrypted1));
auto const input2 = std::string{ "@#)C$@)#(*%bvkdjfhwbc039bc4603756VB3)" };
auto constexpr Input2 = "@#)C$@)#(*%bvkdjfhwbc039bc4603756VB3)"sv;
auto encrypted2 = std::array<char, 128>{};
auto decrypted2 = std::array<char, 128>{};
tr_cryptoEncryptInit_(&b);
tr_cryptoEncrypt_(&b, input2.size(), input2.data(), encrypted2.data());
tr_cryptoDecryptInit(&a);
tr_cryptoDecrypt(&a, input2.size(), encrypted2.data(), decrypted2.data());
EXPECT_EQ(input2, std::string(decrypted2.data(), input2.size()));
b.encryptInit();
b.encrypt(std::size(Input2), std::data(Input2), std::data(encrypted2));
a.decryptInit();
a.decrypt(std::size(Input2), std::data(encrypted2), std::data(decrypted2));
EXPECT_EQ(Input2, std::data(decrypted2));
}
TEST(Crypto, sha1)