From 2aaac1a0d567a0dd721e4ab7587f8990ae12c53a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 21 Aug 2014 21:57:24 -0400 Subject: [PATCH] process extended indetities for LeaseSets --- Identity.cpp | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++ Identity.h | 35 ++++++++++++++- LeaseSet.cpp | 22 +++++----- LeaseSet.h | 7 ++- Signature.h | 8 ++++ 5 files changed, 172 insertions(+), 17 deletions(-) diff --git a/Identity.cpp b/Identity.cpp index e63cdb35..dc26d649 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -33,6 +33,123 @@ namespace data return DEFAULT_IDENTITY_SIZE; } + IdentityEx::IdentityEx (): + m_Verifier (nullptr), m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + { + } + + IdentityEx::IdentityEx (const uint8_t * buf, size_t len): + m_Verifier (nullptr), m_ExtendedLen (0), m_ExtendedBuffer (nullptr) + { + FromBuffer (buf, len); + } + + IdentityEx::IdentityEx (const IdentityEx& other): + m_Verifier (nullptr), m_ExtendedBuffer (nullptr) + { + *this = other; + } + + IdentityEx::~IdentityEx () + { + delete m_Verifier; + delete[] m_ExtendedBuffer; + } + + IdentityEx& IdentityEx::operator=(const IdentityEx& other) + { + memcpy (&m_StandardIdentity, &other.m_StandardIdentity, DEFAULT_IDENTITY_SIZE); + m_IdentHash = other.m_IdentHash; + + delete m_Verifier; + m_Verifier = nullptr; + + delete[] m_ExtendedBuffer; + m_ExtendedLen = other.m_ExtendedLen; + if (m_ExtendedLen > 0) + { + m_ExtendedBuffer = new uint8_t[m_ExtendedLen]; + memcpy (m_ExtendedBuffer, other.m_ExtendedBuffer, m_ExtendedLen); + } + else + m_ExtendedBuffer = nullptr; + + return *this; + } + + size_t IdentityEx::FromBuffer (const uint8_t * buf, size_t len) + { + delete m_Verifier; + m_Verifier = nullptr; + delete[] m_ExtendedBuffer; + + memcpy (&m_StandardIdentity, buf, DEFAULT_IDENTITY_SIZE); + if (m_StandardIdentity.certificate.length) + { + m_ExtendedLen = be16toh (m_StandardIdentity.certificate.length); + m_ExtendedBuffer = new uint8_t[m_ExtendedLen]; + memcpy (m_ExtendedBuffer, buf + DEFAULT_IDENTITY_SIZE, m_ExtendedLen); + } + else + { + m_ExtendedLen = 0; + m_ExtendedBuffer = nullptr; + } + CryptoPP::SHA256().CalculateDigest(m_IdentHash, buf, GetFullLen ()); + return GetFullLen (); + } + + size_t IdentityEx::GetSigningPublicKeyLen () + { + if (!m_Verifier) + CreateVerifier (); + if (m_Verifier) + return m_Verifier->GetPublicKeyLen (); + return 128; + } + + bool IdentityEx::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) + { + if (!m_Verifier) + CreateVerifier (); + if (m_Verifier) + return m_Verifier->Verify (buf, len, signature); + return false; + } + + void IdentityEx::CreateVerifier () + { + switch (m_StandardIdentity.certificate.type) + { + case CERTIFICATE_TYPE_NULL: + m_Verifier = new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey); + break; + case CERTIFICATE_TYPE_KEY: + { + if (m_ExtendedBuffer) + { + uint16_t keyType = be16toh (*(uint16_t *)m_ExtendedBuffer); // sigining key + switch (keyType) + { + case PUBLIC_KEY_TYPE_DSA_SHA1: + m_Verifier = new i2p::crypto::DSAVerifier (m_StandardIdentity.signingKey); + break; + case PUBLIC_KEY_TYPE_ECDSA_SHA256_P256: + m_Verifier = new i2p::crypto::ECDSAP256Verifier (m_StandardIdentity.signingKey); + break; + default: + LogPrint ("Signing key type ", keyType, " is not supported"); + } + } + else + LogPrint ("Missing certificate payload"); + break; + } + default: + LogPrint ("Certificate type ", m_StandardIdentity.certificate.type, " is not supported"); + } + } + IdentHash Identity::Hash() const { IdentHash hash; diff --git a/Identity.h b/Identity.h index d82e225e..631aea71 100644 --- a/Identity.h +++ b/Identity.h @@ -80,7 +80,9 @@ namespace data const uint8_t CERTIFICATE_TYPE_MULTIPLE = 4; const uint8_t CERTIFICATE_TYPE_KEY = 5; - const size_t DEFAULT_IDENTITY_SIZE = 387; + const uint16_t PUBLIC_KEY_TYPE_DSA_SHA1 = 0; + const uint16_t PUBLIC_KEY_TYPE_ECDSA_SHA256_P256 = 1; + struct Identity { uint8_t publicKey[256]; @@ -96,6 +98,37 @@ namespace data size_t FromBuffer (const uint8_t * buf, size_t len); IdentHash Hash() const; }; + const size_t DEFAULT_IDENTITY_SIZE = sizeof (Identity); // 387 bytes + + class IdentityEx + { + public: + + IdentityEx (); + IdentityEx (const uint8_t * buf, size_t len); + IdentityEx (const IdentityEx& other); + ~IdentityEx (); + IdentityEx& operator=(const IdentityEx& other); + + size_t FromBuffer (const uint8_t * buf, size_t len); + const Identity& GetStandardIdentity () const { return m_StandardIdentity; }; + const IdentHash& GetIdentHash () const { return m_IdentHash; }; + size_t GetFullLen () const { return m_ExtendedLen + DEFAULT_IDENTITY_SIZE; }; + size_t GetSigningPublicKeyLen (); + bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature); + + private: + + void CreateVerifier (); + + private: + + Identity m_StandardIdentity; + IdentHash m_IdentHash; + i2p::crypto::Verifier * m_Verifier; + size_t m_ExtendedLen; + uint8_t * m_ExtendedBuffer; + }; struct PrivateKeys // for eepsites { diff --git a/LeaseSet.cpp b/LeaseSet.cpp index 0b79a0ab..43b6ef58 100644 --- a/LeaseSet.cpp +++ b/LeaseSet.cpp @@ -62,15 +62,17 @@ namespace data void LeaseSet::ReadFromBuffer () { - const LeaseSetHeader * header = (const LeaseSetHeader *)m_Buffer; - m_Identity = header->destination; - m_IdentHash = m_Identity.Hash(); - memcpy (m_EncryptionKey, header->encryptionKey, 256); - LogPrint ("LeaseSet num=", (int)header->num); + size_t size = m_Identity.FromBuffer (m_Buffer, m_BufferLen); + memcpy (m_EncryptionKey, m_Buffer + size, 256); + size += 256; // encryption key + size += m_Identity.GetSigningPublicKeyLen (); // unused signing key + uint8_t num = m_Buffer[size]; + size++; // num + LogPrint ("LeaseSet num=", (int)num); // process leases - const uint8_t * leases = m_Buffer + sizeof (LeaseSetHeader); - for (int i = 0; i < header->num; i++) + const uint8_t * leases = m_Buffer + size; + for (int i = 0; i < num; i++) { Lease lease = *(Lease *)leases; lease.tunnelID = be32toh (lease.tunnelID); @@ -88,11 +90,7 @@ namespace data } // verify - CryptoPP::DSA::PublicKey pubKey; - pubKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, - CryptoPP::Integer (m_Identity.signingKey, 128)); - CryptoPP::DSA::Verifier verifier (pubKey); - if (!verifier.VerifyMessage (m_Buffer, leases - m_Buffer, leases, 40)) + if (!m_Identity.Verify (m_Buffer, leases - m_Buffer, leases)) LogPrint ("LeaseSet verification failed"); } diff --git a/LeaseSet.h b/LeaseSet.h index a8e70d43..c02bbfad 100644 --- a/LeaseSet.h +++ b/LeaseSet.h @@ -62,8 +62,8 @@ namespace data void SetUnsolicited (bool unsolicited) { m_IsUnsolicited = unsolicited; }; // implements RoutingDestination - const Identity& GetIdentity () const { return m_Identity; }; - const IdentHash& GetIdentHash () const { return m_IdentHash; }; + const Identity& GetIdentity () const { return m_Identity.GetStandardIdentity (); }; + const IdentHash& GetIdentHash () const { return m_Identity.GetIdentHash (); }; const std::vector& GetLeases () const { return m_Leases; }; const std::vector GetNonExpiredLeases () const; bool HasExpiredLeases () const; @@ -78,8 +78,7 @@ namespace data private: std::vector m_Leases; - Identity m_Identity; - IdentHash m_IdentHash; + IdentityEx m_Identity; uint8_t m_EncryptionKey[256]; uint8_t m_Buffer[MAX_LS_BUFFER_SIZE]; size_t m_BufferLen; diff --git a/Signature.h b/Signature.h index 79bbcb65..594c12ed 100644 --- a/Signature.h +++ b/Signature.h @@ -18,6 +18,8 @@ namespace crypto virtual ~Verifier () {}; virtual bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) = 0; + virtual size_t GetPublicKeyLen () const = 0; + virtual size_t GetSignatureLen () const = 0; }; class DSAVerifier: public Verifier @@ -35,6 +37,9 @@ namespace crypto return verifier.VerifyMessage (buf, len, signature, 40); } + size_t GetPublicKeyLen () const { return 128; }; + size_t GetSignatureLen () const { return 40; }; + private: CryptoPP::DSA::PublicKey m_PublicKey; @@ -57,6 +62,9 @@ namespace crypto return verifier.VerifyMessage (buf, len, signature, 64); } + size_t GetPublicKeyLen () const { return 64; }; + size_t GetSignatureLen () const { return 64; }; + private: CryptoPP::ECDSA::PublicKey m_PublicKey;