mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-03-21 16:49:10 +01:00
read offline info
This commit is contained in:
parent
b6bfd66a49
commit
1fa3ba8b42
2 changed files with 63 additions and 6 deletions
|
@ -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)
|
||||||
|
|
|
@ -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,8 +143,10 @@ 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; };
|
||||||
uint8_t * GetPadding();
|
size_t GetSignatureLen () const; // might not match identity
|
||||||
void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); }
|
bool IsOfflineSignature () const { return m_OfflineSignature.size () > 0; };
|
||||||
|
uint8_t * GetPadding();
|
||||||
|
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;
|
||||||
|
|
||||||
size_t GetFullLen () const { return m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); };
|
size_t GetFullLen () const { return m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); };
|
||||||
|
@ -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…
Add table
Reference in a new issue