mirror of
https://github.com/transmission/transmission
synced 2025-03-12 23:23:54 +00:00
refactor: save outgoing len(PadA)
, len(PadB)
and len(IA)
(#6973)
* refactor: save length of PadA and PadB sent * refactor: log outgoing `len(PadA)` and `len(PadB)` * refactor: set `ia_len_` as the MSE handshake initiator
This commit is contained in:
parent
088232f69c
commit
40814a3195
2 changed files with 22 additions and 24 deletions
|
@ -40,8 +40,8 @@ using key_bigend_t = tr_message_stream_encryption::DH::key_bigend_t;
|
|||
// 1 A->B: our public key (Ya) and some padding (PadA)
|
||||
void tr_handshake::send_ya(tr_peerIo* io)
|
||||
{
|
||||
tr_logAddTraceHand(this, "sending MSE handshake (Ya)");
|
||||
send_public_key_and_pad<PadaMaxlen>(io);
|
||||
pad_a_len_ = send_public_key_and_pad<PadaMaxlen>(io);
|
||||
tr_logAddTraceHand(this, fmt::format("sent MSE handshake (Ya)... len(PadA) = {}", pad_a_len_));
|
||||
set_state(tr_handshake::State::AwaitingYb);
|
||||
}
|
||||
|
||||
|
@ -77,12 +77,12 @@ ReadState tr_handshake::read_yb(tr_peerIo* peer_io)
|
|||
|
||||
// everything received so far is Yb+PadB; peer has not yet sent VC for resync.
|
||||
// so throw away buffer, and do early exit check: we know it's not legit MSE if > max PadB
|
||||
pad_b_recv_len_ = peer_io->read_buffer_size();
|
||||
if (pad_b_recv_len_ > PadbMaxlen)
|
||||
pad_b_len_ = peer_io->read_buffer_size();
|
||||
if (pad_b_len_ > PadbMaxlen)
|
||||
{
|
||||
return done(false);
|
||||
}
|
||||
peer_io->read_buffer_discard(pad_b_recv_len_);
|
||||
peer_io->read_buffer_discard(pad_b_len_);
|
||||
|
||||
/* now send these: HASH('req1', S), HASH('req2', SKEY) xor HASH('req3', S),
|
||||
* ENCRYPT(VC, crypto_provide, len(PadC), PadC, len(IA)), ENCRYPT(IA) */
|
||||
|
@ -119,6 +119,7 @@ ReadState tr_handshake::read_yb(tr_peerIo* peer_io)
|
|||
outbuf.add_uint16(0);
|
||||
|
||||
/* ENCRYPT len(IA)), ENCRYPT(IA) */
|
||||
ia_len_ = HandshakeSize;
|
||||
outbuf.add_uint16(HandshakeSize);
|
||||
if (build_handshake_message(peer_io, outbuf))
|
||||
{
|
||||
|
@ -155,14 +156,14 @@ ReadState tr_handshake::read_vc(tr_peerIo* peer_io)
|
|||
filter.encrypt(std::data(VC), std::size(VC), std::data(*encrypted_vc_));
|
||||
}
|
||||
|
||||
for (; pad_b_recv_len_ <= PadbMaxlen; ++pad_b_recv_len_)
|
||||
for (; pad_b_len_ <= PadbMaxlen; ++pad_b_len_)
|
||||
{
|
||||
static auto constexpr Needlen = std::size(VC);
|
||||
if (peer_io->read_buffer_size() < Needlen)
|
||||
{
|
||||
tr_logAddTraceHand(
|
||||
this,
|
||||
fmt::format("in read_vc... need {}, read {}, have {}", Needlen, pad_b_recv_len_, peer_io->read_buffer_size()));
|
||||
fmt::format("in read_vc... need {}, read {}, have {}", Needlen, pad_b_len_, peer_io->read_buffer_size()));
|
||||
return ReadState::Later;
|
||||
}
|
||||
|
||||
|
@ -244,7 +245,7 @@ ReadState tr_handshake::read_handshake(tr_peerIo* peer_io)
|
|||
return ReadState::Later;
|
||||
}
|
||||
|
||||
if (ia_len_ > 0U)
|
||||
if (is_incoming() && ia_len_ > 0U)
|
||||
{
|
||||
// do nothing, the check below won't work correctly
|
||||
}
|
||||
|
@ -382,16 +383,16 @@ ReadState tr_handshake::read_ya(tr_peerIo* peer_io)
|
|||
|
||||
// everything received so far is Ya+PadA; haven't sent Yb and peer has not yet sent HASH('req1').
|
||||
// so throw away buffer, and do early exit check: we know it's not legit MSE if > max PadA
|
||||
pad_a_recv_len_ = peer_io->read_buffer_size();
|
||||
if (pad_a_recv_len_ > PadaMaxlen)
|
||||
pad_a_len_ = peer_io->read_buffer_size();
|
||||
if (pad_a_len_ > PadaMaxlen)
|
||||
{
|
||||
return done(false);
|
||||
}
|
||||
peer_io->read_buffer_discard(pad_a_recv_len_);
|
||||
peer_io->read_buffer_discard(pad_a_len_);
|
||||
|
||||
// send our public key to the peer
|
||||
tr_logAddTraceHand(this, "sending B->A: Diffie Hellman Yb, PadB");
|
||||
send_public_key_and_pad<PadbMaxlen>(peer_io);
|
||||
pad_b_len_ = send_public_key_and_pad<PadbMaxlen>(peer_io);
|
||||
tr_logAddTraceHand(this, fmt::format("sent B->A: Diffie Hellman Yb, PadB... len(PadB) = {}", pad_b_len_));
|
||||
|
||||
set_state(State::AwaitingPadA);
|
||||
// LATER, not NOW: recv buffer was just drained and peer was blocking
|
||||
|
@ -403,18 +404,14 @@ ReadState tr_handshake::read_pad_a(tr_peerIo* peer_io)
|
|||
// find the end of PadA by looking for HASH('req1', S)
|
||||
auto const needle = tr_sha1::digest("req1"sv, get_dh().secret());
|
||||
|
||||
for (; pad_a_recv_len_ <= PadaMaxlen; ++pad_a_recv_len_)
|
||||
for (; pad_a_len_ <= PadaMaxlen; ++pad_a_len_)
|
||||
{
|
||||
static auto constexpr Needlen = std::size(needle);
|
||||
if (peer_io->read_buffer_size() < Needlen)
|
||||
{
|
||||
tr_logAddTraceHand(
|
||||
this,
|
||||
fmt::format(
|
||||
"in read_pad_a... need {}, read {}, have {}",
|
||||
Needlen,
|
||||
pad_a_recv_len_,
|
||||
peer_io->read_buffer_size()));
|
||||
fmt::format("in read_pad_a... need {}, read {}, have {}", Needlen, pad_a_len_, peer_io->read_buffer_size()));
|
||||
return ReadState::Later;
|
||||
}
|
||||
|
||||
|
|
|
@ -235,15 +235,17 @@ private:
|
|||
bool send_handshake(tr_peerIo* io);
|
||||
|
||||
template<size_t PadMax>
|
||||
void send_public_key_and_pad(tr_peerIo* io)
|
||||
auto send_public_key_and_pad(tr_peerIo* io)
|
||||
{
|
||||
auto const public_key = get_dh().publicKey();
|
||||
auto outbuf = std::array<std::byte, std::size(public_key) + PadMax>{};
|
||||
auto const data = std::data(outbuf);
|
||||
auto walk = data;
|
||||
walk = std::copy(std::begin(public_key), std::end(public_key), walk);
|
||||
walk += mediator_->pad(walk, PadMax);
|
||||
auto const pad_len = mediator_->pad(walk, PadMax);
|
||||
walk += pad_len;
|
||||
io->write_bytes(data, walk - data, false);
|
||||
return pad_len;
|
||||
}
|
||||
|
||||
[[nodiscard]] uint32_t crypto_provide() const noexcept;
|
||||
|
@ -334,13 +336,12 @@ private:
|
|||
|
||||
uint32_t crypto_select_ = {};
|
||||
uint32_t crypto_provide_ = {};
|
||||
uint16_t pad_a_len_ = {};
|
||||
uint16_t pad_b_len_ = {};
|
||||
uint16_t pad_c_len_ = {};
|
||||
uint16_t pad_d_len_ = {};
|
||||
uint16_t ia_len_ = {};
|
||||
|
||||
uint16_t pad_a_recv_len_ = {};
|
||||
uint16_t pad_b_recv_len_ = {};
|
||||
|
||||
bool have_read_anything_from_peer_ = false;
|
||||
|
||||
bool have_sent_bittorrent_handshake_ = false;
|
||||
|
|
Loading…
Add table
Reference in a new issue