mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-08 22:57:52 +00:00
read offline info
This commit is contained in:
parent
b6bfd66a49
commit
1fa3ba8b42
@ -455,11 +455,49 @@ namespace data
|
||||
memcpy (m_PrivateKey, buf + ret, 256); // private key always 256
|
||||
ret += 256;
|
||||
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);
|
||||
ret += signingPrivateKeySize;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -472,6 +510,7 @@ namespace data
|
||||
if(ret + signingPrivateKeySize > len) return 0; // overflow
|
||||
memcpy (buf + ret, m_SigningPrivateKey, signingPrivateKeySize);
|
||||
ret += signingPrivateKeySize;
|
||||
// TODO: implement offline info
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -505,9 +544,17 @@ namespace data
|
||||
}
|
||||
|
||||
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;
|
||||
switch (m_Public->GetSigningKeyType ())
|
||||
switch (keyType)
|
||||
{
|
||||
case SIGNING_KEY_TYPE_DSA_SHA1:
|
||||
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()
|
||||
{
|
||||
if(m_Public->GetSigningKeyType () == SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519)
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
#include "Base.h"
|
||||
#include "Signature.h"
|
||||
#include "CryptoKey.h"
|
||||
@ -142,8 +143,10 @@ namespace data
|
||||
std::shared_ptr<const IdentityEx> GetPublic () const { return m_Public; };
|
||||
const uint8_t * GetPrivateKey () const { return m_PrivateKey; };
|
||||
const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey; };
|
||||
uint8_t * GetPadding();
|
||||
void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); }
|
||||
size_t GetSignatureLen () const; // might not match identity
|
||||
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;
|
||||
|
||||
size_t GetFullLen () const { return m_Public->GetFullLen () + 256 + m_Public->GetSigningPrivateKeyLen (); };
|
||||
@ -162,13 +165,15 @@ namespace data
|
||||
private:
|
||||
|
||||
void CreateSigner () const;
|
||||
void CreateSigner (SigningKeyType keyType) const;
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<IdentityEx> m_Public;
|
||||
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;
|
||||
std::vector<uint8_t> m_OfflineSignature; // non zero length, if applicable
|
||||
};
|
||||
|
||||
// kademlia
|
||||
|
Loading…
Reference in New Issue
Block a user