fixed race with identity verifier

This commit is contained in:
orignal 2020-03-30 19:27:10 -04:00
parent 869d0156ce
commit f4ca6bbb52
2 changed files with 25 additions and 29 deletions

View File

@ -34,12 +34,11 @@ namespace data
}
IdentityEx::IdentityEx ():
m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
{
}
IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type, CryptoKeyType cryptoType):
m_IsVerifierCreated (false)
IdentityEx::IdentityEx(const uint8_t * publicKey, const uint8_t * signingKey, SigningKeyType type, CryptoKeyType cryptoType)
{
memcpy (m_StandardIdentity.publicKey, publicKey, 256); // publicKey in awlays assumed 256 regardless actual size, padding must be taken care of
if (type != SIGNING_KEY_TYPE_DSA_SHA1)
@ -141,19 +140,19 @@ namespace data
}
IdentityEx::IdentityEx (const uint8_t * buf, size_t len):
m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
{
FromBuffer (buf, len);
}
IdentityEx::IdentityEx (const IdentityEx& other):
m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
{
*this = other;
}
IdentityEx::IdentityEx (const Identity& standard):
m_IsVerifierCreated (false), m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
m_ExtendedLen (0), m_ExtendedBuffer (nullptr)
{
*this = standard;
}
@ -161,6 +160,7 @@ namespace data
IdentityEx::~IdentityEx ()
{
delete[] m_ExtendedBuffer;
delete m_Verifier;
}
IdentityEx& IdentityEx::operator=(const IdentityEx& other)
@ -178,8 +178,8 @@ namespace data
else
m_ExtendedBuffer = nullptr;
delete m_Verifier;
m_Verifier = nullptr;
m_IsVerifierCreated = false;
return *this;
}
@ -193,8 +193,8 @@ namespace data
m_ExtendedBuffer = nullptr;
m_ExtendedLen = 0;
delete m_Verifier;
m_Verifier = nullptr;
m_IsVerifierCreated = false;
return *this;
}
@ -233,6 +233,7 @@ namespace data
}
SHA256(buf, GetFullLen (), m_IdentHash);
delete m_Verifier;
m_Verifier = nullptr;
return GetFullLen ();
@ -381,33 +382,27 @@ namespace data
void IdentityEx::UpdateVerifier (i2p::crypto::Verifier * verifier) const
{
if (!m_Verifier)
bool del = false;
{
auto created = m_IsVerifierCreated.exchange (true);
if (!created)
m_Verifier.reset (verifier);
std::lock_guard<std::mutex> l(m_VerifierMutex);
if (!m_Verifier)
m_Verifier = verifier;
else
{
delete verifier;
int count = 0;
while (!m_Verifier && count < 500) // 5 seconds
{
std::this_thread::sleep_for (std::chrono::milliseconds(10));
count++;
}
if (!m_Verifier)
LogPrint (eLogError, "Identity: couldn't get verifier in 5 seconds");
}
del = true;
}
else
if (del)
delete verifier;
}
void IdentityEx::DropVerifier () const
{
// TODO: potential race condition with Verify
m_IsVerifierCreated = false;
m_Verifier = nullptr;
i2p::crypto::Verifier * verifier;
{
std::lock_guard<std::mutex> l(m_VerifierMutex);
verifier = m_Verifier;
m_Verifier = nullptr;
}
delete verifier;
}
std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> IdentityEx::CreateEncryptor (CryptoKeyType keyType, const uint8_t * key)

View File

@ -7,6 +7,7 @@
#include <memory>
#include <atomic>
#include <vector>
#include <mutex>
#include "Base.h"
#include "Signature.h"
#include "CryptoKey.h"
@ -125,8 +126,8 @@ namespace data
Identity m_StandardIdentity;
IdentHash m_IdentHash;
mutable std::unique_ptr<i2p::crypto::Verifier> m_Verifier;
mutable std::atomic_bool m_IsVerifierCreated; // make sure we don't create twice
mutable i2p::crypto::Verifier * m_Verifier = nullptr;
mutable std::mutex m_VerifierMutex;
size_t m_ExtendedLen;
uint8_t * m_ExtendedBuffer;
};