* Add LeaseSetBufferValidate which checks lease validity and extracts timestamp

* check for leases with LeaseSetBufferValidate before update in floodfill code as to prevent malicous nodes removing good LS
This commit is contained in:
Jeff Becker 2018-01-24 10:16:51 -05:00
parent 3820b51960
commit 4a77a03033
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05
3 changed files with 46 additions and 8 deletions

View File

@ -265,5 +265,39 @@ namespace data
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
return ts > m_ExpirationTime;
}
bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires)
{
IdentityEx ident(ptr, sz);
size_t size = ident.GetFullLen ();
if (size > sz)
{
LogPrint (eLogError, "LeaseSet: identity length ", size, " exceeds buffer size ", sz);
return false;
}
// encryption key
size += 256;
// signing key (unused)
size += ident.GetSigningPublicKeyLen ();
uint8_t numLeases = ptr[size];
++size;
if (!numLeases || numLeases > MAX_NUM_LEASES)
{
LogPrint (eLogError, "LeaseSet: incorrect number of leases", (int)numLeases);
return false;
}
const uint8_t * leases = ptr + size;
expires = 0;
/** find lease with the max expiration timestamp */
for (int i = 0; i < numLeases; i++)
{
leases += 36; // gateway + tunnel ID
uint64_t endDate = bufbe64toh (leases);
leases += 8; // end date
if(endDate > expires)
expires = endDate;
}
return ident.Verify(ptr, leases - ptr, leases);
}
}
}

View File

@ -95,6 +95,12 @@ namespace data
size_t m_BufferLen;
};
/**
validate lease set buffer signature and extract expiration timestamp
@returns true if the leaseset is well formed and signature is valid
*/
bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires);
class LocalLeaseSet
{
public:

View File

@ -237,22 +237,20 @@ namespace data
auto it = m_LeaseSets.find(ident);
if (it != m_LeaseSets.end ())
{
if (it->second->IsNewer (buf, len))
uint64_t expires;
if(LeaseSetBufferValidate(buf, len, expires))
{
it->second->Update (buf, len);
if (it->second->IsValid ())
if(it->second->GetExpirationTime() < expires)
{
it->second->Update (buf, len);
LogPrint (eLogInfo, "NetDb: LeaseSet updated: ", ident.ToBase32());
updated = true;
}
else
{
LogPrint (eLogWarning, "NetDb: LeaseSet update failed: ", ident.ToBase32());
m_LeaseSets.erase (it);
}
LogPrint(eLogDebug, "NetDb: LeaseSet is older: ", ident.ToBase32());
}
else
LogPrint (eLogDebug, "NetDb: LeaseSet is older: ", ident.ToBase32());
LogPrint(eLogError, "NetDb: LeaseSet is invalid: ", ident.ToBase32());
}
else
{