mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2026-08-22 16:40:26 +00:00
chore: fix memory safety issues
This commit is contained in:
+15
-3
@@ -276,9 +276,21 @@ namespace client
|
||||
auto it = m_MethodHandlers.find (method);
|
||||
if (it != m_MethodHandlers.end ())
|
||||
{
|
||||
response << "{\"id\":" << id << ",\"result\":{";
|
||||
(this->*(it->second))(pt.get_child ("params"), response);
|
||||
response << "},\"jsonrpc\":\"2.0\"}\n";
|
||||
auto params = pt.get_child ("params");
|
||||
if (method != "Authenticate" &&
|
||||
!m_Tokens.count (params.get<std::string> ("Token", "")))
|
||||
{
|
||||
LogPrint (eLogWarning, "I2PControl: Invalid or missing token for method ", method);
|
||||
response << "{\"id\":null,\"error\":";
|
||||
response << "{\"code\":-32602,\"message\":\"Invalid or missing token\"},";
|
||||
response << "\"jsonrpc\":\"2.0\"}\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
response << "{\"id\":" << id << ",\"result\":{";
|
||||
(this->*(it->second))(params, response);
|
||||
response << "},\"jsonrpc\":\"2.0\"}\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+13
-1
@@ -81,6 +81,18 @@ namespace data
|
||||
LogPrint (eLogError, "Blinding: Unknown signature type ", (int)m_SigType, " in b33");
|
||||
}
|
||||
|
||||
bool BlindedPublicKey::IsValid () const
|
||||
{
|
||||
switch (m_SigType)
|
||||
{
|
||||
case i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519:
|
||||
case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string BlindedPublicKey::ToB33 () const
|
||||
{
|
||||
if (m_PublicKey.size () > 32) return ""; // assume 25519
|
||||
@@ -183,7 +195,7 @@ namespace data
|
||||
|
||||
i2p::data::IdentHash BlindedPublicKey::GetStoreHash (const char * date) const
|
||||
{
|
||||
i2p::data::IdentHash hash;
|
||||
i2p::data::IdentHash hash{};
|
||||
uint8_t blinded[i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH]; // 32 max
|
||||
size_t publicKeyLength = 0;
|
||||
if (date)
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ namespace data
|
||||
size_t GetPublicKeyLen () const { return m_PublicKey.size (); };
|
||||
SigningKeyType GetSigType () const { return m_SigType; };
|
||||
SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; };
|
||||
bool IsValid () const { return GetSigType (); }; // signature type 0 means invalid
|
||||
bool IsValid () const; // signature type must be blindable
|
||||
|
||||
void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes
|
||||
size_t GetBlindedKey (const char * date, uint8_t * blindedKey) const; // date is 8 chars "YYYYMMDD", return public key length
|
||||
|
||||
+23
-6
@@ -575,6 +575,11 @@ namespace garlic
|
||||
void GarlicDestination::HandleAESBlock (uint8_t * buf, size_t len, std::shared_ptr<AESDecryption> decryption,
|
||||
std::shared_ptr<i2p::tunnel::InboundTunnel> from)
|
||||
{
|
||||
if (len < 2)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: AES block length ", len, " is too short");
|
||||
return;
|
||||
}
|
||||
uint16_t tagCount = bufbe16toh (buf);
|
||||
buf += 2; len -= 2;
|
||||
if (tagCount > 0)
|
||||
@@ -590,18 +595,30 @@ namespace garlic
|
||||
}
|
||||
buf += tagCount*32;
|
||||
len -= tagCount*32;
|
||||
if (len < 37) // 4 (payload size) + 32 (payload hash) + 1 (flag)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: AES block is too short for payload header, length ", len);
|
||||
return;
|
||||
}
|
||||
uint32_t payloadSize = bufbe32toh (buf);
|
||||
buf += 4; len -= 4;
|
||||
uint8_t * payloadHash = buf;
|
||||
buf += 32; len -= 32; // payload hash.
|
||||
if (*buf) // session key?
|
||||
{
|
||||
if (len < 33) // 32 (new session key) + 1 (flag)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: AES block is too short for session key, length ", len);
|
||||
return;
|
||||
}
|
||||
buf += 32; len -= 32; // new session key
|
||||
}
|
||||
buf++; len--; // flag
|
||||
if (payloadSize > len)
|
||||
{
|
||||
LogPrint (eLogError, "Garlic: Unexpected payload size ", payloadSize);
|
||||
return;
|
||||
}
|
||||
buf += 4;
|
||||
uint8_t * payloadHash = buf;
|
||||
buf += 32;// payload hash.
|
||||
if (*buf) // session key?
|
||||
buf += 32; // new session key
|
||||
buf++; // flag
|
||||
|
||||
// payload
|
||||
uint8_t digest[32];
|
||||
|
||||
@@ -661,12 +661,18 @@ namespace data
|
||||
|
||||
size_t LeaseSet2::ExtractClientAuthData (const uint8_t * buf, size_t len, const uint8_t * secret, const uint8_t * subcredential, uint8_t * authCookie) const
|
||||
{
|
||||
if (len < 1) return 0;
|
||||
size_t offset = 0;
|
||||
uint8_t flag = buf[offset]; offset++; // flag
|
||||
if (flag & 0x01) // client auth
|
||||
{
|
||||
if (!(flag & 0x0E)) // DH, bit 1-3 all zeroes
|
||||
{
|
||||
if (offset + 34 > len) // ephemeralPublicKey(32) + numClients(2)
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet2: Buffer too short for DH auth data header");
|
||||
return 0;
|
||||
}
|
||||
const uint8_t * ephemeralPublicKey = buf + offset; offset += 32; // ephemeralPublicKey
|
||||
uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients
|
||||
const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients
|
||||
@@ -693,6 +699,11 @@ namespace data
|
||||
}
|
||||
else if (flag & 0x02) // PSK, bit 1 is set to 1
|
||||
{
|
||||
if (offset + 34 > len) // authSalt(32) + numClients(2)
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet2: Buffer too short for PSK auth data header");
|
||||
return 0;
|
||||
}
|
||||
const uint8_t * authSalt = buf + offset; offset += 32; // authSalt
|
||||
uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients
|
||||
const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients
|
||||
@@ -854,6 +865,11 @@ namespace data
|
||||
size += 256;
|
||||
// signing key (unused)
|
||||
size += ident.GetSigningPublicKeyLen ();
|
||||
if (size + 1 > sz)
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet: ", size, " exceeds buffer size ", sz);
|
||||
return false;
|
||||
}
|
||||
uint8_t numLeases = ptr[size];
|
||||
++size;
|
||||
if (!numLeases || numLeases > MAX_NUM_LEASES)
|
||||
@@ -861,6 +877,11 @@ namespace data
|
||||
LogPrint (eLogError, "LeaseSet: Incorrect number of leases", (int)numLeases);
|
||||
return false;
|
||||
}
|
||||
if (size + numLeases*LEASE_SIZE > sz)
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet: ", size, " exceeds buffer size ", sz);
|
||||
return false;
|
||||
}
|
||||
const uint8_t * leases = ptr + size;
|
||||
expires = 0;
|
||||
/** find lease with the max expiration timestamp */
|
||||
@@ -872,6 +893,11 @@ namespace data
|
||||
if(endDate > expires)
|
||||
expires = endDate;
|
||||
}
|
||||
if ((size_t)(leases - ptr) + ident.GetSignatureLen () > sz)
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet: Signature exceeds buffer size ", sz);
|
||||
return false;
|
||||
}
|
||||
return ident.Verify(ptr, leases - ptr, leases);
|
||||
}
|
||||
|
||||
|
||||
@@ -2283,7 +2283,8 @@ namespace transport
|
||||
if (!r) LogPrint (eLogWarning, "SSU2: RelayRequest Alice's router info not found");
|
||||
|
||||
auto packet = m_Server.GetSentPacketsPool ().AcquireShared ();
|
||||
packet->payloadSize = r ? CreateRouterInfoBlock (packet->payload, m_MaxPayloadSize - len - 32, r) : 0;
|
||||
size_t riMaxLen = (len + 32 < m_MaxPayloadSize) ? m_MaxPayloadSize - len - 32 : 0;
|
||||
packet->payloadSize = r ? CreateRouterInfoBlock (packet->payload, riMaxLen, r) : 0;
|
||||
if (!packet->payloadSize && r)
|
||||
session->SendFragmentedMessage (CreateDatabaseStoreMsg (r));
|
||||
packet->payloadSize += CreateRelayIntroBlock (packet->payload + packet->payloadSize, m_MaxPayloadSize - packet->payloadSize, buf + 1, len - 1);
|
||||
@@ -2526,7 +2527,8 @@ namespace transport
|
||||
// Alice's RouterInfo
|
||||
auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ());
|
||||
if (r && (r->IsUnreachable () || !i2p::data::netdb.PopulateRouterInfoBuffer (r))) r = nullptr;
|
||||
packet->payloadSize = r ? CreateRouterInfoBlock (packet->payload, m_MaxPayloadSize - len - 32, r) : 0;
|
||||
size_t riMaxLen = (len + 32 < m_MaxPayloadSize) ? m_MaxPayloadSize - len - 32 : 0;
|
||||
packet->payloadSize = r ? CreateRouterInfoBlock (packet->payload, riMaxLen, r) : 0;
|
||||
if (!packet->payloadSize && r)
|
||||
session->SendFragmentedMessage (CreateDatabaseStoreMsg (r));
|
||||
if (packet->payloadSize + len + 48 > m_MaxPayloadSize)
|
||||
@@ -2645,7 +2647,8 @@ namespace transport
|
||||
// Charlie's RouterInfo
|
||||
auto r = i2p::data::netdb.FindRouter (GetRemoteIdentity ()->GetIdentHash ());
|
||||
if (r && (r->IsUnreachable () || !i2p::data::netdb.PopulateRouterInfoBuffer (r))) r = nullptr;
|
||||
packet->payloadSize = r ? CreateRouterInfoBlock (packet->payload, m_MaxPayloadSize - len - 32, r) : 0;
|
||||
size_t riMaxLen = (len + 32 < m_MaxPayloadSize) ? m_MaxPayloadSize - len - 32 : 0;
|
||||
packet->payloadSize = r ? CreateRouterInfoBlock (packet->payload, riMaxLen, r) : 0;
|
||||
if (!packet->payloadSize && r)
|
||||
aliceSession->SendFragmentedMessage (CreateDatabaseStoreMsg (r));
|
||||
if (packet->payloadSize + len + 16 > m_MaxPayloadSize)
|
||||
|
||||
@@ -779,7 +779,7 @@ namespace client
|
||||
auto res = std::from_chars(sizeStr.data(), sizeStr.data() + sizeStr.size(), size);
|
||||
if (res.ec != std::errc()) size = 0;
|
||||
size_t offset = data - buf;
|
||||
if (offset + size <= len)
|
||||
if (offset <= len && size <= len - offset)
|
||||
{
|
||||
auto session = m_Owner.FindSession(m_ID);
|
||||
if (session)
|
||||
|
||||
Reference in New Issue
Block a user