Browse Source

fixed race with identity verifier

pull/1502/head
orignal 5 years ago
parent
commit
f4ca6bbb52
  1. 47
      libi2pd/Identity.cpp
  2. 5
      libi2pd/Identity.h

47
libi2pd/Identity.cpp

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

5
libi2pd/Identity.h

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

Loading…
Cancel
Save