mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 13:27:17 +01:00
common code for offline signatures
This commit is contained in:
parent
f5f4190803
commit
2cac9b03ff
|
@ -285,27 +285,15 @@ namespace data
|
|||
uint16_t expires = bufbe16toh (buf + offset); offset += 2; // expires (seconds)
|
||||
SetExpirationTime ((timestamp + expires)*1000LL); // in milliseconds
|
||||
uint16_t flags = bufbe16toh (buf + offset); offset += 2; // flags
|
||||
std::unique_ptr<i2p::crypto::Verifier> transientVerifier;
|
||||
if (flags & 0x0001)
|
||||
{
|
||||
// transient key
|
||||
if (offset + 6 >= len) return;
|
||||
const uint8_t * signedData = buf + offset;
|
||||
uint32_t expiresTimestamp = bufbe32toh (buf + offset); offset += 4; // expires timestamp
|
||||
if (expiresTimestamp < i2p::util::GetSecondsSinceEpoch ())
|
||||
{
|
||||
LogPrint (eLogWarning, "LeaseSet2: transient key expired");
|
||||
m_TransientVerifier = ProcessOfflineSignature (identity, buf, len, offset);
|
||||
if (!m_TransientVerifier)
|
||||
{
|
||||
LogPrint (eLogError, "LeaseSet2: offline signature failed");
|
||||
return;
|
||||
}
|
||||
uint16_t keyType = bufbe16toh (buf + offset); offset += 2;
|
||||
transientVerifier.reset (i2p::data::IdentityEx::CreateVerifier (keyType));
|
||||
if (!transientVerifier) return;
|
||||
auto keyLen = transientVerifier->GetPublicKeyLen ();
|
||||
if (offset + keyLen >= len) return;
|
||||
transientVerifier->SetPublicKey (buf + offset); offset += keyLen;
|
||||
if (offset + identity->GetSignatureLen () >= len) return;
|
||||
if (!identity->Verify (signedData, keyLen + 6, buf + offset)) return;
|
||||
offset += identity->GetSignatureLen ();
|
||||
}
|
||||
}
|
||||
// type specific part
|
||||
size_t s = 0;
|
||||
|
@ -322,10 +310,10 @@ namespace data
|
|||
}
|
||||
if (!s) return;
|
||||
offset += s;
|
||||
if (verifySignature || transientVerifier)
|
||||
if (verifySignature || m_TransientVerifier)
|
||||
{
|
||||
// verify signature
|
||||
bool verified = transientVerifier ? VerifySignature (transientVerifier, buf, len, offset) :
|
||||
bool verified = m_TransientVerifier ? VerifySignature (m_TransientVerifier, buf, len, offset) :
|
||||
VerifySignature (identity, buf, len, offset);
|
||||
SetIsValid (verified);
|
||||
}
|
||||
|
@ -443,33 +431,21 @@ namespace data
|
|||
uint16_t expires = bufbe16toh (buf + offset); offset += 2; // expires (seconds)
|
||||
SetExpirationTime ((timestamp + expires)*1000LL); // in milliseconds
|
||||
uint16_t flags = bufbe16toh (buf + offset); offset += 2; // flags
|
||||
std::unique_ptr<i2p::crypto::Verifier> transientVerifier;
|
||||
if (flags & 0x0001)
|
||||
{
|
||||
// transient key
|
||||
if (offset + 6 >= len) return;
|
||||
const uint8_t * signedData = buf + offset;
|
||||
uint32_t expiresTimestamp = bufbe32toh (buf + offset); offset += 4; // expires timestamp
|
||||
if (expiresTimestamp < i2p::util::GetSecondsSinceEpoch ())
|
||||
m_TransientVerifier = ProcessOfflineSignature (blindedVerifier, buf, len, offset);
|
||||
if (!m_TransientVerifier)
|
||||
{
|
||||
LogPrint (eLogWarning, "LeaseSet2: transient key expired");
|
||||
LogPrint (eLogError, "LeaseSet2: offline signature failed");
|
||||
return;
|
||||
}
|
||||
uint16_t keyType = bufbe16toh (buf + offset); offset += 2;
|
||||
transientVerifier.reset (i2p::data::IdentityEx::CreateVerifier (keyType));
|
||||
if (!transientVerifier) return;
|
||||
auto keyLen = transientVerifier->GetPublicKeyLen ();
|
||||
if (offset + keyLen >= len) return;
|
||||
transientVerifier->SetPublicKey (buf + offset); offset += keyLen;
|
||||
if (offset + blindedVerifier->GetSignatureLen () >= len) return;
|
||||
if (!blindedVerifier->Verify (signedData, keyLen + 6, buf + offset)) return;
|
||||
offset += blindedVerifier->GetSignatureLen ();
|
||||
}
|
||||
}
|
||||
// outer ciphertext
|
||||
if (offset + 2 > len) return;
|
||||
uint16_t lenOuterCiphertext = bufbe16toh (buf + offset); offset += 2 + lenOuterCiphertext;
|
||||
// verify signature
|
||||
bool verified = transientVerifier ? VerifySignature (transientVerifier, buf, len, offset) :
|
||||
bool verified = m_TransientVerifier ? VerifySignature (m_TransientVerifier, buf, len, offset) :
|
||||
VerifySignature (blindedVerifier, buf, len, offset);
|
||||
SetIsValid (verified);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <memory>
|
||||
#include "Identity.h"
|
||||
#include "Timestamp.h"
|
||||
#include "I2PEndian.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
|
@ -77,7 +78,8 @@ namespace data
|
|||
bool operator== (const LeaseSet& other) const
|
||||
{ return m_BufferLen == other.m_BufferLen && !memcmp (m_Buffer, other.m_Buffer, m_BufferLen); };
|
||||
virtual uint8_t GetStoreType () const { return NETDB_STORE_TYPE_LEASESET; };
|
||||
|
||||
virtual std::shared_ptr<const i2p::crypto::Verifier> GetTransientVerifier () const { return nullptr; };
|
||||
|
||||
// implements RoutingDestination
|
||||
std::shared_ptr<const IdentityEx> GetIdentity () const { return m_Identity; };
|
||||
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const;
|
||||
|
@ -128,8 +130,9 @@ namespace data
|
|||
|
||||
LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true);
|
||||
uint8_t GetStoreType () const { return m_StoreType; };
|
||||
std::shared_ptr<const i2p::crypto::Verifier> GetTransientVerifier () const { return m_TransientVerifier; };
|
||||
void Update (const uint8_t * buf, size_t len, bool verifySignature);
|
||||
|
||||
|
||||
// implements RoutingDestination
|
||||
void Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx) const;
|
||||
|
||||
|
@ -148,9 +151,31 @@ namespace data
|
|||
private:
|
||||
|
||||
uint8_t m_StoreType;
|
||||
std::shared_ptr<i2p::crypto::Verifier> m_TransientVerifier;
|
||||
std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> m_Encryptor; // for standardLS2
|
||||
};
|
||||
|
||||
// also called from Streaming.cpp
|
||||
template<typename Verifier>
|
||||
std::shared_ptr<i2p::crypto::Verifier> ProcessOfflineSignature (const Verifier& verifier, const uint8_t * buf, size_t len, size_t& offset)
|
||||
{
|
||||
if (offset + 6 >= len) return nullptr;
|
||||
const uint8_t * signedData = buf + offset;
|
||||
uint32_t expiresTimestamp = bufbe32toh (buf + offset); offset += 4; // expires timestamp
|
||||
if (expiresTimestamp < i2p::util::GetSecondsSinceEpoch ()) return nullptr;
|
||||
uint16_t keyType = bufbe16toh (buf + offset); offset += 2;
|
||||
std::shared_ptr<i2p::crypto::Verifier> transientVerifier (i2p::data::IdentityEx::CreateVerifier (keyType));
|
||||
if (!transientVerifier) return nullptr;
|
||||
auto keyLen = transientVerifier->GetPublicKeyLen ();
|
||||
if (offset + keyLen >= len) return nullptr;
|
||||
transientVerifier->SetPublicKey (buf + offset); offset += keyLen;
|
||||
if (offset + verifier->GetSignatureLen () >= len) return nullptr;
|
||||
if (!verifier->Verify (signedData, keyLen + 6, buf + offset)) return nullptr;
|
||||
offset += verifier->GetSignatureLen ();
|
||||
return transientVerifier;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
class LocalLeaseSet
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -288,33 +288,27 @@ namespace stream
|
|||
LogPrint (eLogInfo, "Streaming: offline signature without identity");
|
||||
return false;
|
||||
}
|
||||
const uint8_t * signedData = optionData;
|
||||
uint32_t expiresTimestamp = bufbe32toh (optionData); optionData += 4; // expires timestamp
|
||||
if (expiresTimestamp < i2p::util::GetSecondsSinceEpoch ())
|
||||
// if we have it in LeaseSet already we don't neet parse it again
|
||||
if (m_RemoteLeaseSet) m_TransientVerifier = m_RemoteLeaseSet->GetTransientVerifier ();
|
||||
if (m_TransientVerifier)
|
||||
{
|
||||
LogPrint (eLogInfo, "Streaming: offline signature transient key expired");
|
||||
return false;
|
||||
// skip option data
|
||||
optionData += 6; // timestamp and key type
|
||||
optionData += m_TransientVerifier->GetPublicKeyLen (); // public key
|
||||
optionData += m_RemoteIdentity->GetSignatureLen (); // signature
|
||||
}
|
||||
uint16_t keyType = bufbe16toh (optionData); optionData += 2; // key type
|
||||
m_TransientVerifier.reset (i2p::data::IdentityEx::CreateVerifier (keyType));
|
||||
if (!m_TransientVerifier)
|
||||
else
|
||||
{
|
||||
LogPrint (eLogInfo, "Streaming: Unknown transient key type ", (int)keyType);
|
||||
return false;
|
||||
// transient key
|
||||
size_t offset = 0;
|
||||
m_TransientVerifier = i2p::data::ProcessOfflineSignature (m_RemoteIdentity, optionData, optionSize - (optionData - packet->GetOptionData ()), offset);
|
||||
optionData += offset;
|
||||
if (!m_TransientVerifier)
|
||||
{
|
||||
LogPrint (eLogError, "Streaming: offline signature failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
auto keyLen = m_TransientVerifier->GetPublicKeyLen ();
|
||||
if ((optionData - packet->GetOptionData ()) + keyLen + m_RemoteIdentity->GetSignatureLen () > optionSize)
|
||||
{
|
||||
LogPrint (eLogInfo, "Streaming: Option data is too short ", (int)optionSize);
|
||||
return false;
|
||||
}
|
||||
m_TransientVerifier->SetPublicKey (optionData); optionData += keyLen; // key
|
||||
if (!m_RemoteIdentity->Verify (signedData, keyLen + 6, optionData))
|
||||
{
|
||||
LogPrint (eLogError, "Streaming: Transient key signature verification failed");
|
||||
return false;
|
||||
}
|
||||
optionData += m_RemoteIdentity->GetSignatureLen (); // signature
|
||||
}
|
||||
|
||||
if (flags & PACKET_FLAG_SIGNATURE_INCLUDED)
|
||||
|
|
|
@ -218,7 +218,7 @@ namespace stream
|
|||
bool m_IsAckSendScheduled;
|
||||
StreamingDestination& m_LocalDestination;
|
||||
std::shared_ptr<const i2p::data::IdentityEx> m_RemoteIdentity;
|
||||
std::unique_ptr<i2p::crypto::Verifier> m_TransientVerifier; // in case of offline key
|
||||
std::shared_ptr<const i2p::crypto::Verifier> m_TransientVerifier; // in case of offline key
|
||||
std::shared_ptr<const i2p::data::LeaseSet> m_RemoteLeaseSet;
|
||||
std::shared_ptr<i2p::garlic::GarlicRoutingSession> m_RoutingSession;
|
||||
std::shared_ptr<const i2p::data::Lease> m_CurrentRemoteLease;
|
||||
|
|
Loading…
Reference in a new issue