Browse Source

read offline info

pull/1295/head
orignal 6 years ago
parent
commit
1fa3ba8b42
  1. 58
      libi2pd/Identity.cpp
  2. 7
      libi2pd/Identity.h

58
libi2pd/Identity.cpp

@ -455,11 +455,49 @@ namespace data
memcpy (m_PrivateKey, buf + ret, 256); // private key always 256 memcpy (m_PrivateKey, buf + ret, 256); // private key always 256
ret += 256; ret += 256;
size_t signingPrivateKeySize = m_Public->GetSigningPrivateKeyLen (); size_t signingPrivateKeySize = m_Public->GetSigningPrivateKeyLen ();
if(signingPrivateKeySize + ret > len) return 0; // overflow if(signingPrivateKeySize + ret > len || signingPrivateKeySize > 128) return 0; // overflow
memcpy (m_SigningPrivateKey, buf + ret, signingPrivateKeySize); memcpy (m_SigningPrivateKey, buf + ret, signingPrivateKeySize);
ret += signingPrivateKeySize; ret += signingPrivateKeySize;
m_Signer = nullptr; m_Signer = nullptr;
CreateSigner (); // check if signing private key is all zeros
bool allzeros = true;
for (size_t i = 0; i < signingPrivateKeySize; i++)
if (m_SigningPrivateKey[i])
{
allzeros = false;
break;
}
if (allzeros)
{
// offline information
const uint8_t * offlineInfo = buf + ret;
ret += 4; // expires timestamp
SigningKeyType keyType = bufbe16toh (buf + ret); ret += 2; // key type
std::unique_ptr<i2p::crypto::Verifier> transientVerifier (IdentityEx::CreateVerifier (keyType));
if (!transientVerifier) return 0;
auto keyLen = transientVerifier->GetPublicKeyLen ();
if (keyLen + ret > len) return 0;
transientVerifier->SetPublicKey (buf + ret); ret += keyLen;
if (m_Public->GetSignatureLen () + ret > len) return 0;
if (!m_Public->Verify (offlineInfo, keyLen + 6, buf + ret))
{
LogPrint (eLogError, "Identity: offline signature verification failed");
return 0;
}
ret += m_Public->GetSignatureLen ();
// copy offline signature
size_t offlineInfoLen = buf + ret - offlineInfo;
m_OfflineSignature.resize (offlineInfoLen);
memcpy (m_OfflineSignature.data (), offlineInfo, offlineInfoLen);
// override signing private key
signingPrivateKeySize = transientVerifier->GetPrivateKeyLen ();
if (signingPrivateKeySize + ret > len || signingPrivateKeySize > 128) return 0;
memcpy (m_SigningPrivateKey, buf + ret, signingPrivateKeySize);
ret += signingPrivateKeySize;
CreateSigner (keyType);
}
else
CreateSigner (m_Public->GetSigningKeyType ());
return ret; return ret;
} }
@ -472,6 +510,7 @@ namespace data
if(ret + signingPrivateKeySize > len) return 0; // overflow if(ret + signingPrivateKeySize > len) return 0; // overflow
memcpy (buf + ret, m_SigningPrivateKey, signingPrivateKeySize); memcpy (buf + ret, m_SigningPrivateKey, signingPrivateKeySize);
ret += signingPrivateKeySize; ret += signingPrivateKeySize;
// TODO: implement offline info
return ret; return ret;
} }
@ -505,9 +544,17 @@ namespace data
} }
void PrivateKeys::CreateSigner () const void PrivateKeys::CreateSigner () const
{
if (IsOfflineSignature ())
CreateSigner (bufbe16toh (m_OfflineSignature.data () + 4)); // key type
else
CreateSigner (m_Public->GetSigningKeyType ());
}
void PrivateKeys::CreateSigner (SigningKeyType keyType) const
{ {
if (m_Signer) return; if (m_Signer) return;
switch (m_Public->GetSigningKeyType ()) switch (keyType)
{ {
case SIGNING_KEY_TYPE_DSA_SHA1: case SIGNING_KEY_TYPE_DSA_SHA1:
m_Signer.reset (new i2p::crypto::DSASigner (m_SigningPrivateKey, m_Public->GetStandardIdentity ().signingKey)); m_Signer.reset (new i2p::crypto::DSASigner (m_SigningPrivateKey, m_Public->GetStandardIdentity ().signingKey));
@ -540,6 +587,11 @@ namespace data
} }
} }
size_t PrivateKeys::GetSignatureLen () const
{
return m_Public->GetSignatureLen ();
}
uint8_t * PrivateKeys::GetPadding() uint8_t * PrivateKeys::GetPadding()
{ {
if(m_Public->GetSigningKeyType () == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) if(m_Public->GetSigningKeyType () == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519)

7
libi2pd/Identity.h

@ -6,6 +6,7 @@
#include <string> #include <string>
#include <memory> #include <memory>
#include <atomic> #include <atomic>
#include <vector>
#include "Base.h" #include "Base.h"
#include "Signature.h" #include "Signature.h"
#include "CryptoKey.h" #include "CryptoKey.h"
@ -142,6 +143,8 @@ namespace data
std::shared_ptr<const IdentityEx> GetPublic () const { return m_Public; }; std::shared_ptr<const IdentityEx> GetPublic () const { return m_Public; };
const uint8_t * GetPrivateKey () const { return m_PrivateKey; }; const uint8_t * GetPrivateKey () const { return m_PrivateKey; };
const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; }; const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; };
size_t GetSignatureLen () const; // might not match identity
bool IsOfflineSignature () const { return m_OfflineSignature.size () > 0; };
uint8_t * GetPadding(); uint8_t * GetPadding();
void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); } void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); }
void Sign (const uint8_t * buf, int len, uint8_t * signature) const; void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
@ -162,13 +165,15 @@ namespace data
private: private:
void CreateSigner () const; void CreateSigner () const;
void CreateSigner (SigningKeyType keyType) const;
private: private:
std::shared_ptr<IdentityEx> m_Public; std::shared_ptr<IdentityEx> m_Public;
uint8_t m_PrivateKey[256]; uint8_t m_PrivateKey[256];
uint8_t m_SigningPrivateKey[1024]; // assume private key doesn't exceed 1024 bytes uint8_t m_SigningPrivateKey[128]; // assume private key doesn't exceed 128 bytes
mutable std::unique_ptr<i2p::crypto::Signer> m_Signer; mutable std::unique_ptr<i2p::crypto::Signer> m_Signer;
std::vector<uint8_t> m_OfflineSignature; // non zero length, if applicable
}; };
// kademlia // kademlia

Loading…
Cancel
Save