mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 08:14:15 +00:00
keep sending new session reply until first established session message received
This commit is contained in:
parent
8872d1f389
commit
aa7750bfd3
@ -298,7 +298,8 @@ namespace garlic
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MixHash (out + offset, 16); // h = SHA256(h || ciphertext)
|
MixHash (out + offset, 16); // h = SHA256(h || ciphertext)
|
||||||
out += 16;
|
offset += 16;
|
||||||
|
memcpy (m_NSRHeader, out, 56); // for possible next NSR
|
||||||
// KDF for payload
|
// KDF for payload
|
||||||
uint8_t keydata[64];
|
uint8_t keydata[64];
|
||||||
i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
|
i2p::crypto::HKDF (m_CK, nullptr, 0, "", keydata); // keydata = HKDF(chainKey, ZEROLEN, "", 64)
|
||||||
@ -308,18 +309,33 @@ namespace garlic
|
|||||||
m_SendTagset.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba)
|
m_SendTagset.DHInitialize (m_CK, keydata + 32); // tagset_ba = DH_INITIALIZE(chainKey, k_ba)
|
||||||
m_SendTagset.NextSessionTagRatchet ();
|
m_SendTagset.NextSessionTagRatchet ();
|
||||||
GenerateMoreReceiveTags (GetOwner ()->GetNumTags ());
|
GenerateMoreReceiveTags (GetOwner ()->GetNumTags ());
|
||||||
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32)
|
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32)
|
||||||
// encrypt payload
|
// encrypt payload
|
||||||
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, keydata, nonce, out + offset, len + 16, true)) // encrypt
|
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed");
|
LogPrint (eLogWarning, "Garlic: NSR payload section AEAD encryption failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_State = eSessionStateEstablished;
|
m_State = eSessionStateNewSessionReplySent;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ECIESX25519AEADRatchetSession::NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
|
||||||
|
{
|
||||||
|
// we are Bob and sent NSR already
|
||||||
|
memcpy (out, m_NSRHeader, 56);
|
||||||
|
uint8_t nonce[12];
|
||||||
|
CreateNonce (0, nonce);
|
||||||
|
// encrypt payload
|
||||||
|
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + 56, len + 16, true)) // encrypt
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Garlic: Next NSR payload section AEAD encryption failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len)
|
bool ECIESX25519AEADRatchetSession::HandleNewOutgoingSessionReply (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
// we are Alice
|
// we are Alice
|
||||||
@ -419,6 +435,11 @@ namespace garlic
|
|||||||
m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch ();
|
m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch ();
|
||||||
switch (m_State)
|
switch (m_State)
|
||||||
{
|
{
|
||||||
|
case eSessionStateNewSessionReplySent:
|
||||||
|
m_State = eSessionStateEstablished;
|
||||||
|
#if (__cplusplus >= 201703L) // C++ 17 or higher
|
||||||
|
[[fallthrough]];
|
||||||
|
#endif
|
||||||
case eSessionStateEstablished:
|
case eSessionStateEstablished:
|
||||||
return HandleExistingSessionMessage (buf, len, index);
|
return HandleExistingSessionMessage (buf, len, index);
|
||||||
case eSessionStateNew:
|
case eSessionStateNew:
|
||||||
@ -456,6 +477,11 @@ namespace garlic
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
len += 72;
|
len += 72;
|
||||||
break;
|
break;
|
||||||
|
case eSessionStateNewSessionReplySent:
|
||||||
|
if (!NextNewSessionReplyMessage (payload.data (), payload.size (), buf, m->maxLen))
|
||||||
|
return nullptr;
|
||||||
|
len += 72;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,7 @@ namespace garlic
|
|||||||
eSessionStateNew =0,
|
eSessionStateNew =0,
|
||||||
eSessionStateNewSessionReceived,
|
eSessionStateNewSessionReceived,
|
||||||
eSessionStateNewSessionSent,
|
eSessionStateNewSessionSent,
|
||||||
|
eSessionStateNewSessionReplySent,
|
||||||
eSessionStateEstablished
|
eSessionStateEstablished
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -106,6 +107,7 @@ namespace garlic
|
|||||||
|
|
||||||
bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
bool NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||||
bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
bool NewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||||
|
bool NextNewSessionReplyMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||||
bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
bool NewExistingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen);
|
||||||
|
|
||||||
std::vector<uint8_t> CreatePayload (std::shared_ptr<const I2NPMessage> msg);
|
std::vector<uint8_t> CreatePayload (std::shared_ptr<const I2NPMessage> msg);
|
||||||
@ -117,7 +119,8 @@ namespace garlic
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32];
|
uint8_t m_H[32], m_CK[64] /* [chainkey, key] */, m_RemoteStaticKey[32];
|
||||||
uint8_t m_Aepk[32]; // Alice's ephemeral keys TODO: for incoming only
|
uint8_t m_Aepk[32]; // Alice's ephemeral keys, for incoming only
|
||||||
|
uint8_t m_NSRHeader[56], m_NSRKey[32]; // new session reply, for incoming only
|
||||||
i2p::crypto::X25519Keys m_EphemeralKeys;
|
i2p::crypto::X25519Keys m_EphemeralKeys;
|
||||||
SessionState m_State = eSessionStateNew;
|
SessionState m_State = eSessionStateNew;
|
||||||
uint64_t m_LastActivityTimestamp = 0; // incoming
|
uint64_t m_LastActivityTimestamp = 0; // incoming
|
||||||
|
Loading…
x
Reference in New Issue
Block a user