@@ -979,36 +979,56 @@ class V2MessageMap
979
979
980
980
const V2MessageMap V2_MESSAGE_MAP;
981
981
982
- } // namespace
982
+ CKey GenerateRandomKey () noexcept
983
+ {
984
+ CKey key;
985
+ key.MakeNewKey (/* fCompressed=*/ true );
986
+ return key;
987
+ }
983
988
984
- V2Transport::V2Transport (NodeId nodeid, bool initiating, int type_in, int version_in) noexcept :
985
- m_cipher{}, m_initiating{initiating}, m_nodeid{nodeid},
986
- m_v1_fallback{nodeid, type_in, version_in}, m_recv_type{type_in}, m_recv_version{version_in},
987
- m_recv_state{initiating ? RecvState::KEY : RecvState::KEY_MAYBE_V1},
988
- m_send_state{initiating ? SendState::AWAITING_KEY : SendState::MAYBE_V1}
989
+ std::vector<uint8_t > GenerateRandomGarbage () noexcept
989
990
{
990
- // Construct garbage (including its length) using a FastRandomContext.
991
+ std::vector< uint8_t > ret;
991
992
FastRandomContext rng;
992
- size_t garbage_len = rng.randrange (MAX_GARBAGE_LEN + 1 );
993
- // Initialize the send buffer with ellswift pubkey + garbage.
994
- m_send_buffer.resize (EllSwiftPubKey::size () + garbage_len);
993
+ ret.resize (rng.randrange (V2Transport::MAX_GARBAGE_LEN + 1 ));
994
+ rng.fillrand (MakeWritableByteSpan (ret));
995
+ return ret;
996
+ }
997
+
998
+ } // namespace
999
+
1000
+ void V2Transport::StartSendingHandshake () noexcept
1001
+ {
1002
+ AssertLockHeld (m_send_mutex);
1003
+ Assume (m_send_state == SendState::AWAITING_KEY);
1004
+ Assume (m_send_buffer.empty ());
1005
+ // Initialize the send buffer with ellswift pubkey + provided garbage.
1006
+ m_send_buffer.resize (EllSwiftPubKey::size () + m_send_garbage.size ());
995
1007
std::copy (std::begin (m_cipher.GetOurPubKey ()), std::end (m_cipher.GetOurPubKey ()), MakeWritableByteSpan (m_send_buffer).begin ());
996
- rng.fillrand (MakeWritableByteSpan (m_send_buffer).subspan (EllSwiftPubKey::size ()));
1008
+ std::copy (m_send_garbage.begin (), m_send_garbage.end (), m_send_buffer.begin () + EllSwiftPubKey::size ());
1009
+ // We cannot wipe m_send_garbage as it will still be used to construct the garbage
1010
+ // authentication packet.
997
1011
}
998
1012
999
- V2Transport::V2Transport (NodeId nodeid, bool initiating, int type_in, int version_in, const CKey& key, Span<const std::byte> ent32, Span< const uint8_t > garbage) noexcept :
1013
+ V2Transport::V2Transport (NodeId nodeid, bool initiating, int type_in, int version_in, const CKey& key, Span<const std::byte> ent32, std::vector< uint8_t > garbage) noexcept :
1000
1014
m_cipher{key, ent32}, m_initiating{initiating}, m_nodeid{nodeid},
1001
1015
m_v1_fallback{nodeid, type_in, version_in}, m_recv_type{type_in}, m_recv_version{version_in},
1002
1016
m_recv_state{initiating ? RecvState::KEY : RecvState::KEY_MAYBE_V1},
1017
+ m_send_garbage{std::move (garbage)},
1003
1018
m_send_state{initiating ? SendState::AWAITING_KEY : SendState::MAYBE_V1}
1004
1019
{
1005
- assert (garbage.size () <= MAX_GARBAGE_LEN);
1006
- // Initialize the send buffer with ellswift pubkey + provided garbage.
1007
- m_send_buffer.resize (EllSwiftPubKey::size () + garbage.size ());
1008
- std::copy (std::begin (m_cipher.GetOurPubKey ()), std::end (m_cipher.GetOurPubKey ()), MakeWritableByteSpan (m_send_buffer).begin ());
1009
- std::copy (garbage.begin (), garbage.end (), m_send_buffer.begin () + EllSwiftPubKey::size ());
1020
+ Assume (m_send_garbage.size () <= MAX_GARBAGE_LEN);
1021
+ // Start sending immediately if we're the initiator of the connection.
1022
+ if (initiating) {
1023
+ LOCK (m_send_mutex);
1024
+ StartSendingHandshake ();
1025
+ }
1010
1026
}
1011
1027
1028
+ V2Transport::V2Transport (NodeId nodeid, bool initiating, int type_in, int version_in) noexcept :
1029
+ V2Transport{nodeid, initiating, type_in, version_in, GenerateRandomKey (),
1030
+ MakeByteSpan (GetRandHash ()), GenerateRandomGarbage ()} { }
1031
+
1012
1032
void V2Transport::SetReceiveState (RecvState recv_state) noexcept
1013
1033
{
1014
1034
AssertLockHeld (m_recv_mutex);
@@ -1087,9 +1107,10 @@ void V2Transport::ProcessReceivedMaybeV1Bytes() noexcept
1087
1107
if (!std::equal (m_recv_buffer.begin (), m_recv_buffer.end (), v1_prefix.begin ())) {
1088
1108
// Mismatch with v1 prefix, so we can assume a v2 connection.
1089
1109
SetReceiveState (RecvState::KEY); // Convert to KEY state, leaving received bytes around.
1090
- // Transition the sender to AWAITING_KEY state (if not already) .
1110
+ // Transition the sender to AWAITING_KEY state and start sending .
1091
1111
LOCK (m_send_mutex);
1092
1112
SetSendState (SendState::AWAITING_KEY);
1113
+ StartSendingHandshake ();
1093
1114
} else if (m_recv_buffer.size () == v1_prefix.size ()) {
1094
1115
// Full match with the v1 prefix, so fall back to v1 behavior.
1095
1116
LOCK (m_send_mutex);
@@ -1149,7 +1170,6 @@ bool V2Transport::ProcessReceivedKeyBytes() noexcept
1149
1170
SetSendState (SendState::READY);
1150
1171
1151
1172
// Append the garbage terminator to the send buffer.
1152
- size_t garbage_len = m_send_buffer.size () - EllSwiftPubKey::size ();
1153
1173
m_send_buffer.resize (m_send_buffer.size () + BIP324Cipher::GARBAGE_TERMINATOR_LEN);
1154
1174
std::copy (m_cipher.GetSendGarbageTerminator ().begin (),
1155
1175
m_cipher.GetSendGarbageTerminator ().end (),
@@ -1160,9 +1180,12 @@ bool V2Transport::ProcessReceivedKeyBytes() noexcept
1160
1180
m_send_buffer.resize (m_send_buffer.size () + BIP324Cipher::EXPANSION);
1161
1181
m_cipher.Encrypt (
1162
1182
/* contents=*/ {},
1163
- /* aad=*/ MakeByteSpan (m_send_buffer). subspan ( EllSwiftPubKey::size (), garbage_len ),
1183
+ /* aad=*/ MakeByteSpan (m_send_garbage ),
1164
1184
/* ignore=*/ false ,
1165
1185
/* output=*/ MakeWritableByteSpan (m_send_buffer).last (BIP324Cipher::EXPANSION));
1186
+ // We no longer need the garbage.
1187
+ m_send_garbage.clear ();
1188
+ m_send_garbage.shrink_to_fit ();
1166
1189
1167
1190
// Construct version packet in the send buffer.
1168
1191
m_send_buffer.resize (m_send_buffer.size () + BIP324Cipher::EXPANSION + VERSION_CONTENTS.size ());
@@ -1532,9 +1555,7 @@ Transport::BytesToSend V2Transport::GetBytesToSend(bool have_next_message) const
1532
1555
LOCK (m_send_mutex);
1533
1556
if (m_send_state == SendState::V1) return m_v1_fallback.GetBytesToSend (have_next_message);
1534
1557
1535
- // We do not send anything in MAYBE_V1 state (as we don't know if the peer is v1 or v2),
1536
- // despite there being data in the send buffer in that state.
1537
- if (m_send_state == SendState::MAYBE_V1) return {{}, false , m_send_type};
1558
+ if (m_send_state == SendState::MAYBE_V1) Assume (m_send_buffer.empty ());
1538
1559
Assume (m_send_pos <= m_send_buffer.size ());
1539
1560
return {
1540
1561
Span{m_send_buffer}.subspan (m_send_pos),
@@ -1553,10 +1574,8 @@ void V2Transport::MarkBytesSent(size_t bytes_sent) noexcept
1553
1574
1554
1575
m_send_pos += bytes_sent;
1555
1576
Assume (m_send_pos <= m_send_buffer.size ());
1556
- // Only wipe the buffer when everything is sent in the READY state. In the AWAITING_KEY state
1557
- // we still need the garbage that's in the send buffer to construct the garbage authentication
1558
- // packet.
1559
- if (m_send_state == SendState::READY && m_send_pos == m_send_buffer.size ()) {
1577
+ // Wipe the buffer when everything is sent.
1578
+ if (m_send_pos == m_send_buffer.size ()) {
1560
1579
m_send_pos = 0 ;
1561
1580
m_send_buffer = {};
1562
1581
}
0 commit comments