|
|
@ -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) |
|
|
|