Compare commits

..

1 commit

Author SHA1 Message Date
self-related
7b7441136a
Merge 32a70562c4 into 0086f8e27a 2024-10-30 12:46:17 +00:00
10 changed files with 221 additions and 57 deletions

View file

@ -240,12 +240,17 @@ namespace crypto
// x25519 // x25519
X25519Keys::X25519Keys () X25519Keys::X25519Keys ()
{ {
#if OPENSSL_X25519
m_Ctx = EVP_PKEY_CTX_new_id (NID_X25519, NULL); m_Ctx = EVP_PKEY_CTX_new_id (NID_X25519, NULL);
m_Pkey = nullptr; m_Pkey = nullptr;
#else
m_Ctx = BN_CTX_new ();
#endif
} }
X25519Keys::X25519Keys (const uint8_t * priv, const uint8_t * pub) X25519Keys::X25519Keys (const uint8_t * priv, const uint8_t * pub)
{ {
#if OPENSSL_X25519
m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32);
m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL);
if (pub) if (pub)
@ -255,16 +260,29 @@ namespace crypto
size_t len = 32; size_t len = 32;
EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len);
} }
#else
m_Ctx = BN_CTX_new ();
memcpy (m_PrivateKey, priv, 32);
if (pub)
memcpy (m_PublicKey, pub, 32);
else
GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx);
#endif
} }
X25519Keys::~X25519Keys () X25519Keys::~X25519Keys ()
{ {
#if OPENSSL_X25519
EVP_PKEY_CTX_free (m_Ctx); EVP_PKEY_CTX_free (m_Ctx);
if (m_Pkey) EVP_PKEY_free (m_Pkey); if (m_Pkey) EVP_PKEY_free (m_Pkey);
#else
BN_CTX_free (m_Ctx);
#endif
} }
void X25519Keys::GenerateKeys () void X25519Keys::GenerateKeys ()
{ {
#if OPENSSL_X25519
if (m_Pkey) if (m_Pkey)
{ {
EVP_PKEY_free (m_Pkey); EVP_PKEY_free (m_Pkey);
@ -276,11 +294,16 @@ namespace crypto
m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); // TODO: do we really need to re-create m_Ctx? m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); // TODO: do we really need to re-create m_Ctx?
size_t len = 32; size_t len = 32;
EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len);
#else
RAND_bytes (m_PrivateKey, 32);
GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx);
#endif
} }
bool X25519Keys::Agree (const uint8_t * pub, uint8_t * shared) bool X25519Keys::Agree (const uint8_t * pub, uint8_t * shared)
{ {
if (!pub || (pub[31] & 0x80)) return false; // not x25519 key if (!pub || (pub[31] & 0x80)) return false; // not x25519 key
#if OPENSSL_X25519
EVP_PKEY_derive_init (m_Ctx); EVP_PKEY_derive_init (m_Ctx);
auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, pub, 32); auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, pub, 32);
if (!pkey) return false; if (!pkey) return false;
@ -288,17 +311,25 @@ namespace crypto
size_t len = 32; size_t len = 32;
EVP_PKEY_derive (m_Ctx, shared, &len); EVP_PKEY_derive (m_Ctx, shared, &len);
EVP_PKEY_free (pkey); EVP_PKEY_free (pkey);
#else
GetEd25519 ()->ScalarMul (pub, m_PrivateKey, shared, m_Ctx);
#endif
return true; return true;
} }
void X25519Keys::GetPrivateKey (uint8_t * priv) const void X25519Keys::GetPrivateKey (uint8_t * priv) const
{ {
#if OPENSSL_X25519
size_t len = 32; size_t len = 32;
EVP_PKEY_get_raw_private_key (m_Pkey, priv, &len); EVP_PKEY_get_raw_private_key (m_Pkey, priv, &len);
#else
memcpy (priv, m_PrivateKey, 32);
#endif
} }
void X25519Keys::SetPrivateKey (const uint8_t * priv, bool calculatePublic) void X25519Keys::SetPrivateKey (const uint8_t * priv, bool calculatePublic)
{ {
#if OPENSSL_X25519
if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx); if (m_Ctx) EVP_PKEY_CTX_free (m_Ctx);
if (m_Pkey) EVP_PKEY_free (m_Pkey); if (m_Pkey) EVP_PKEY_free (m_Pkey);
m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32);
@ -308,6 +339,11 @@ namespace crypto
size_t len = 32; size_t len = 32;
EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len);
} }
#else
memcpy (m_PrivateKey, priv, 32);
if (calculatePublic)
GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx);
#endif
} }
// ElGamal // ElGamal

View file

@ -31,6 +31,7 @@
#if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 #if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
# define OPENSSL_HKDF 1 # define OPENSSL_HKDF 1
# define OPENSSL_EDDSA 1 # define OPENSSL_EDDSA 1
# define OPENSSL_X25519 1
# if (!defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER != 0x030000000)) // 3.0.0, regression in SipHash, not implemented in LibreSSL # if (!defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER != 0x030000000)) // 3.0.0, regression in SipHash, not implemented in LibreSSL
# define OPENSSL_SIPHASH 1 # define OPENSSL_SIPHASH 1
# endif # endif
@ -69,8 +70,13 @@ namespace crypto
private: private:
uint8_t m_PublicKey[32]; uint8_t m_PublicKey[32];
#if OPENSSL_X25519
EVP_PKEY_CTX * m_Ctx; EVP_PKEY_CTX * m_Ctx;
EVP_PKEY * m_Pkey; EVP_PKEY * m_Pkey;
#else
BN_CTX * m_Ctx;
uint8_t m_PrivateKey[32];
#endif
bool m_IsElligatorIneligible = false; // true if definitely ineligible bool m_IsElligatorIneligible = false; // true if definitely ineligible
}; };

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2024, The PurpleI2P Project * Copyright (c) 2013-2023, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -457,6 +457,86 @@ namespace crypto
} }
} }
#if !OPENSSL_X25519
BIGNUM * Ed25519::ScalarMul (const BIGNUM * u, const BIGNUM * k, BN_CTX * ctx) const
{
BN_CTX_start (ctx);
auto x1 = BN_CTX_get (ctx); BN_copy (x1, u);
auto x2 = BN_CTX_get (ctx); BN_one (x2);
auto z2 = BN_CTX_get (ctx); BN_zero (z2);
auto x3 = BN_CTX_get (ctx); BN_copy (x3, u);
auto z3 = BN_CTX_get (ctx); BN_one (z3);
auto c121666 = BN_CTX_get (ctx); BN_set_word (c121666, 121666);
auto tmp0 = BN_CTX_get (ctx); auto tmp1 = BN_CTX_get (ctx);
unsigned int swap = 0;
auto bits = BN_num_bits (k);
while(bits)
{
--bits;
auto k_t = BN_is_bit_set(k, bits) ? 1 : 0;
swap ^= k_t;
if (swap)
{
std::swap (x2, x3);
std::swap (z2, z3);
}
swap = k_t;
BN_mod_sub(tmp0, x3, z3, q, ctx);
BN_mod_sub(tmp1, x2, z2, q, ctx);
BN_mod_add(x2, x2, z2, q, ctx);
BN_mod_add(z2, x3, z3, q, ctx);
BN_mod_mul(z3, tmp0, x2, q, ctx);
BN_mod_mul(z2, z2, tmp1, q, ctx);
BN_mod_sqr(tmp0, tmp1, q, ctx);
BN_mod_sqr(tmp1, x2, q, ctx);
BN_mod_add(x3, z3, z2, q, ctx);
BN_mod_sub(z2, z3, z2, q, ctx);
BN_mod_mul(x2, tmp1, tmp0, q, ctx);
BN_mod_sub(tmp1, tmp1, tmp0, q, ctx);
BN_mod_sqr(z2, z2, q, ctx);
BN_mod_mul(z3, tmp1, c121666, q, ctx);
BN_mod_sqr(x3, x3, q, ctx);
BN_mod_add(tmp0, tmp0, z3, q, ctx);
BN_mod_mul(z3, x1, z2, q, ctx);
BN_mod_mul(z2, tmp1, tmp0, q, ctx);
}
if (swap)
{
std::swap (x2, x3);
std::swap (z2, z3);
}
BN_mod_inverse (z2, z2, q, ctx);
BIGNUM * res = BN_new (); // not from ctx
BN_mod_mul(res, x2, z2, q, ctx);
BN_CTX_end (ctx);
return res;
}
void Ed25519::ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
{
BIGNUM * p1 = DecodeBN<32> (p);
uint8_t k[32];
memcpy (k, e, 32);
k[0] &= 248; k[31] &= 127; k[31] |= 64;
BIGNUM * n = DecodeBN<32> (k);
BIGNUM * q1 = ScalarMul (p1, n, ctx);
EncodeBN (q1, buf, 32);
BN_free (p1); BN_free (n); BN_free (q1);
}
void Ed25519::ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
{
BIGNUM *p1 = BN_new (); BN_set_word (p1, 9);
uint8_t k[32];
memcpy (k, e, 32);
k[0] &= 248; k[31] &= 127; k[31] |= 64;
BIGNUM * n = DecodeBN<32> (k);
BIGNUM * q1 = ScalarMul (p1, n, ctx);
EncodeBN (q1, buf, 32);
BN_free (p1); BN_free (n); BN_free (q1);
}
#endif
void Ed25519::BlindPublicKey (const uint8_t * pub, const uint8_t * seed, uint8_t * blinded) void Ed25519::BlindPublicKey (const uint8_t * pub, const uint8_t * seed, uint8_t * blinded)
{ {
BN_CTX * ctx = BN_CTX_new (); BN_CTX * ctx = BN_CTX_new ();

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2024, The PurpleI2P Project * Copyright (c) 2013-2020, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -84,7 +84,10 @@ namespace crypto
EDDSAPoint GeneratePublicKey (const uint8_t * expandedPrivateKey, BN_CTX * ctx) const; EDDSAPoint GeneratePublicKey (const uint8_t * expandedPrivateKey, BN_CTX * ctx) const;
EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const; EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const;
void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const; void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const;
#if !OPENSSL_X25519
void ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const; // p is point, e is number for x25519
void ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const;
#endif
void BlindPublicKey (const uint8_t * pub, const uint8_t * seed, uint8_t * blinded); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32 void BlindPublicKey (const uint8_t * pub, const uint8_t * seed, uint8_t * blinded); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
void BlindPrivateKey (const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32 void BlindPrivateKey (const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
@ -112,6 +115,11 @@ namespace crypto
BIGNUM * DecodeBN (const uint8_t * buf) const; BIGNUM * DecodeBN (const uint8_t * buf) const;
void EncodeBN (const BIGNUM * bn, uint8_t * buf, size_t len) const; void EncodeBN (const BIGNUM * bn, uint8_t * buf, size_t len) const;
#if !OPENSSL_X25519
// for x25519
BIGNUM * ScalarMul (const BIGNUM * p, const BIGNUM * e, BN_CTX * ctx) const;
#endif
private: private:
BIGNUM * q, * l, * d, * I; BIGNUM * q, * l, * d, * I;

View file

@ -111,6 +111,7 @@ namespace transport
SendPeerTest (7, buf + offset, len - offset); SendPeerTest (7, buf + offset, len - offset);
else else
LogPrint (eLogWarning, "SSU2: Unknown address for peer test 6"); LogPrint (eLogWarning, "SSU2: Unknown address for peer test 6");
GetServer ().AddConnectedRecently (GetRemoteEndpoint (), i2p::util::GetSecondsSinceEpoch ());
GetServer ().RequestRemoveSession (GetConnID ()); GetServer ().RequestRemoveSession (GetConnID ());
break; break;
} }
@ -140,6 +141,7 @@ namespace transport
} }
} }
} }
GetServer ().AddConnectedRecently (GetRemoteEndpoint (), i2p::util::GetSecondsSinceEpoch ());
GetServer ().RequestRemoveSession (GetConnID ()); GetServer ().RequestRemoveSession (GetConnID ());
break; break;
} }
@ -186,7 +188,6 @@ namespace transport
i2p::crypto::ChaCha20 (h + 16, 16, addr->i, n, h + 16); i2p::crypto::ChaCha20 (h + 16, 16, addr->i, n, h + 16);
// send // send
GetServer ().Send (header.buf, 16, h + 16, 16, payload, payloadSize, GetRemoteEndpoint ()); GetServer ().Send (header.buf, 16, h + 16, 16, payload, payloadSize, GetRemoteEndpoint ());
UpdateNumSentBytes (payloadSize + 32);
} }
void SSU2PeerTestSession::SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, bool delayed) void SSU2PeerTestSession::SendPeerTest (uint8_t msg, const uint8_t * signedData, size_t signedDataLen, bool delayed)
@ -308,7 +309,6 @@ namespace transport
i2p::crypto::ChaCha20 (h + 16, 16, addr->i, n, h + 16); i2p::crypto::ChaCha20 (h + 16, 16, addr->i, n, h + 16);
// send // send
GetServer ().Send (header.buf, 16, h + 16, 16, payload, payloadSize, ep); GetServer ().Send (header.buf, 16, h + 16, 16, payload, payloadSize, ep);
UpdateNumSentBytes (payloadSize + 32);
} }
void SSU2HolePunchSession::SendHolePunch (const uint8_t * relayResponseBlock, size_t relayResponseBlockLen) void SSU2HolePunchSession::SendHolePunch (const uint8_t * relayResponseBlock, size_t relayResponseBlockLen)

View file

@ -66,12 +66,12 @@ namespace transport
while (m_IsRunning) while (m_IsRunning)
{ {
int num, total = 0; int num, total = 0;
while ((num = m_QueueSize - (int)m_Queue.size ()) > 0 && total < m_QueueSize) while ((num = m_QueueSize - (int)m_Queue.size ()) > 0 && total < 10)
{ {
CreateEphemeralKeys (num); CreateEphemeralKeys (num);
total += num; total += num;
} }
if (total > m_QueueSize) if (total >= 10)
{ {
LogPrint (eLogWarning, "Transports: ", total, " ephemeral keys generated at the time"); LogPrint (eLogWarning, "Transports: ", total, " ephemeral keys generated at the time");
std::this_thread::sleep_for (std::chrono::seconds(1)); // take a break std::this_thread::sleep_for (std::chrono::seconds(1)); // take a break
@ -124,12 +124,12 @@ namespace transport
{ {
if (pair) if (pair)
{ {
std::unique_lock<std::mutex> l(m_AcquiredMutex); std::unique_lock<std::mutex>l(m_AcquiredMutex);
if ((int)m_Queue.size () < 2*m_QueueSize) if ((int)m_Queue.size () < 2*m_QueueSize)
m_Queue.push (pair); m_Queue.push (pair);
} }
else else
LogPrint(eLogError, "Transports: Return null keys"); LogPrint(eLogError, "Transports: Return null DHKeys");
} }
void Peer::UpdateParams (std::shared_ptr<const i2p::data::RouterInfo> router) void Peer::UpdateParams (std::shared_ptr<const i2p::data::RouterInfo> router)
@ -149,7 +149,7 @@ namespace transport
m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_CheckReserved(true), m_Thread (nullptr), m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_CheckReserved(true), m_Thread (nullptr),
m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr),
m_UpdateBandwidthTimer (nullptr), m_SSU2Server (nullptr), m_NTCP2Server (nullptr), m_UpdateBandwidthTimer (nullptr), m_SSU2Server (nullptr), m_NTCP2Server (nullptr),
m_X25519KeysPairSupplier (NUM_X25519_PRE_GENERATED_KEYS), m_X25519KeysPairSupplier (15), // 15 pre-generated keys
m_TotalSentBytes (0), m_TotalReceivedBytes (0), m_TotalTransitTransmittedBytes (0), m_TotalSentBytes (0), m_TotalReceivedBytes (0), m_TotalTransitTransmittedBytes (0),
m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth (0), m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth (0),
m_InBandwidth15s (0), m_OutBandwidth15s (0), m_TransitBandwidth15s (0), m_InBandwidth15s (0), m_OutBandwidth15s (0), m_TransitBandwidth15s (0),
@ -480,13 +480,8 @@ namespace transport
} }
if(RoutesRestricted() && !IsRestrictedPeer(ident)) return; if(RoutesRestricted() && !IsRestrictedPeer(ident)) return;
std::shared_ptr<Peer> peer; std::shared_ptr<Peer> peer;
{ auto it = m_Peers.find (ident);
std::lock_guard<std::mutex> l(m_PeersMutex); if (it == m_Peers.end ())
auto it = m_Peers.find (ident);
if (it != m_Peers.end ())
peer = it->second;
}
if (!peer)
{ {
// check if not banned // check if not banned
if (i2p::data::IsRouterBanned (ident)) return; // don't create peer to unreachable router if (i2p::data::IsRouterBanned (ident)) return; // don't create peer to unreachable router
@ -496,10 +491,10 @@ namespace transport
{ {
auto r = netdb.FindRouter (ident); auto r = netdb.FindRouter (ident);
if (r && (r->IsUnreachable () || !r->IsReachableFrom (i2p::context.GetRouterInfo ()))) return; // router found but non-reachable if (r && (r->IsUnreachable () || !r->IsReachableFrom (i2p::context.GetRouterInfo ()))) return; // router found but non-reachable
{
peer = std::make_shared<Peer>(r, i2p::util::GetSecondsSinceEpoch ()); auto ts = i2p::util::GetSecondsSinceEpoch ();
{ peer = std::make_shared<Peer>(r, ts);
std::lock_guard<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
peer = m_Peers.emplace (ident, peer).first->second; peer = m_Peers.emplace (ident, peer).first->second;
} }
if (peer) if (peer)
@ -511,6 +506,8 @@ namespace transport
} }
if (!connected) return; if (!connected) return;
} }
else
peer = it->second;
if (!peer) return; if (!peer) return;
if (peer->IsConnected ()) if (peer->IsConnected ())
@ -525,7 +522,7 @@ namespace transport
if (i2p::data::IsRouterBanned (ident)) if (i2p::data::IsRouterBanned (ident))
{ {
LogPrint (eLogWarning, "Transports: Router ", ident.ToBase64 (), " is banned. Peer dropped"); LogPrint (eLogWarning, "Transports: Router ", ident.ToBase64 (), " is banned. Peer dropped");
std::lock_guard<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.erase (ident); m_Peers.erase (ident);
return; return;
} }
@ -545,7 +542,7 @@ namespace transport
{ {
LogPrint (eLogWarning, "Transports: Delayed messages queue size to ", LogPrint (eLogWarning, "Transports: Delayed messages queue size to ",
ident.ToBase64 (), " exceeds ", MAX_NUM_DELAYED_MESSAGES); ident.ToBase64 (), " exceeds ", MAX_NUM_DELAYED_MESSAGES);
std::lock_guard<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.erase (ident); m_Peers.erase (ident);
} }
} }
@ -620,7 +617,7 @@ namespace transport
if (!i2p::context.IsLimitedConnectivity () && peer->router->IsReachableFrom (i2p::context.GetRouterInfo ())) if (!i2p::context.IsLimitedConnectivity () && peer->router->IsReachableFrom (i2p::context.GetRouterInfo ()))
i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed but router claimed them i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed but router claimed them
peer->Done (); peer->Done ();
std::lock_guard<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.erase (ident); m_Peers.erase (ident);
return false; return false;
} }
@ -628,7 +625,7 @@ namespace transport
{ {
LogPrint (eLogWarning, "Transports: Router ", ident.ToBase64 (), " is banned. Peer dropped"); LogPrint (eLogWarning, "Transports: Router ", ident.ToBase64 (), " is banned. Peer dropped");
peer->Done (); peer->Done ();
std::lock_guard<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.erase (ident); m_Peers.erase (ident);
return false; return false;
} }
@ -724,29 +721,23 @@ namespace transport
void Transports::HandleRequestComplete (std::shared_ptr<const i2p::data::RouterInfo> r, i2p::data::IdentHash ident) void Transports::HandleRequestComplete (std::shared_ptr<const i2p::data::RouterInfo> r, i2p::data::IdentHash ident)
{ {
std::shared_ptr<Peer> peer; auto it = m_Peers.find (ident);
if (it != m_Peers.end ())
{ {
std::lock_guard<std::mutex> l(m_PeersMutex); if (r)
auto it = m_Peers.find (ident);
if (it != m_Peers.end ())
{ {
if (r) LogPrint (eLogDebug, "Transports: RouterInfo for ", ident.ToBase64 (), " found, trying to connect");
peer = it->second; it->second->SetRouter (r);
else if (!it->second->IsConnected ())
m_Peers.erase (it); ConnectToPeer (ident, it->second);
} }
else
{
LogPrint (eLogWarning, "Transports: RouterInfo not found, failed to send messages");
std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.erase (it);
}
} }
if (peer && !peer->router && r)
{
LogPrint (eLogDebug, "Transports: RouterInfo for ", ident.ToBase64 (), " found, trying to connect");
peer->SetRouter (r);
if (!peer->IsConnected ())
ConnectToPeer (ident, peer);
}
else if (!r)
LogPrint (eLogInfo, "Transports: RouterInfo not found, failed to send messages");
} }
void Transports::DetectExternalIP () void Transports::DetectExternalIP ()
@ -920,7 +911,7 @@ namespace transport
auto peer = std::make_shared<Peer>(r, ts); auto peer = std::make_shared<Peer>(r, ts);
peer->sessions.push_back (session); peer->sessions.push_back (session);
peer->router = nullptr; peer->router = nullptr;
std::lock_guard<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.emplace (ident, peer); m_Peers.emplace (ident, peer);
} }
}); });
@ -949,7 +940,7 @@ namespace transport
} }
else else
{ {
std::lock_guard<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.erase (it); m_Peers.erase (it);
} }
} }
@ -959,13 +950,9 @@ namespace transport
bool Transports::IsConnected (const i2p::data::IdentHash& ident) const bool Transports::IsConnected (const i2p::data::IdentHash& ident) const
{ {
std::lock_guard<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
#if __cplusplus >= 202002L // C++20
return m_Peers.contains (ident);
#else
auto it = m_Peers.find (ident); auto it = m_Peers.find (ident);
return it != m_Peers.end (); return it != m_Peers.end ();
#endif
} }
void Transports::HandlePeerCleanupTimer (const boost::system::error_code& ecode) void Transports::HandlePeerCleanupTimer (const boost::system::error_code& ecode)
@ -989,7 +976,7 @@ namespace transport
auto profile = i2p::data::GetRouterProfile (it->first); auto profile = i2p::data::GetRouterProfile (it->first);
if (profile) profile->Unreachable (); if (profile) profile->Unreachable ();
} */ } */
std::lock_guard<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
it = m_Peers.erase (it); it = m_Peers.erase (it);
} }
else else
@ -1039,7 +1026,7 @@ namespace transport
{ {
uint16_t inds[3]; uint16_t inds[3];
RAND_bytes ((uint8_t *)inds, sizeof (inds)); RAND_bytes ((uint8_t *)inds, sizeof (inds));
std::lock_guard<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
auto count = m_Peers.size (); auto count = m_Peers.size ();
if(count == 0) return nullptr; if(count == 0) return nullptr;
inds[0] %= count; inds[0] %= count;

View file

@ -108,8 +108,7 @@ namespace transport
const int PEER_TEST_DELAY_INTERVAL_VARIANCE = 30; // in milliseconds const int PEER_TEST_DELAY_INTERVAL_VARIANCE = 30; // in milliseconds
const int MAX_NUM_DELAYED_MESSAGES = 150; const int MAX_NUM_DELAYED_MESSAGES = 150;
const int CHECK_PROFILE_NUM_DELAYED_MESSAGES = 15; // check profile after const int CHECK_PROFILE_NUM_DELAYED_MESSAGES = 15; // check profile after
const int NUM_X25519_PRE_GENERATED_KEYS = 25; // pre-generated x25519 keys pairs
const int TRAFFIC_SAMPLE_COUNT = 301; // seconds const int TRAFFIC_SAMPLE_COUNT = 301; // seconds
struct TrafficSample struct TrafficSample

View file

@ -49,6 +49,10 @@ set(test-gost-sig_SRCS
test-gost-sig.cpp test-gost-sig.cpp
) )
set(test-x25519_SRCS
test-x25519.cpp
)
set(test-aeadchacha20poly1305_SRCS set(test-aeadchacha20poly1305_SRCS
test-aeadchacha20poly1305.cpp test-aeadchacha20poly1305.cpp
) )
@ -73,6 +77,7 @@ add_executable(test-http-url ${test-http-url_SRCS})
add_executable(test-base-64 ${test-base-64_SRCS}) add_executable(test-base-64 ${test-base-64_SRCS})
add_executable(test-gost ${test-gost_SRCS}) add_executable(test-gost ${test-gost_SRCS})
add_executable(test-gost-sig ${test-gost-sig_SRCS}) add_executable(test-gost-sig ${test-gost-sig_SRCS})
add_executable(test-x25519 ${test-x25519_SRCS})
add_executable(test-aeadchacha20poly1305 ${test-aeadchacha20poly1305_SRCS}) add_executable(test-aeadchacha20poly1305 ${test-aeadchacha20poly1305_SRCS})
add_executable(test-blinding ${test-blinding_SRCS}) add_executable(test-blinding ${test-blinding_SRCS})
add_executable(test-elligator ${test-elligator_SRCS}) add_executable(test-elligator ${test-elligator_SRCS})
@ -97,6 +102,7 @@ target_link_libraries(test-http-url ${LIBS})
target_link_libraries(test-base-64 ${LIBS}) target_link_libraries(test-base-64 ${LIBS})
target_link_libraries(test-gost ${LIBS}) target_link_libraries(test-gost ${LIBS})
target_link_libraries(test-gost-sig ${LIBS}) target_link_libraries(test-gost-sig ${LIBS})
target_link_libraries(test-x25519 ${LIBS})
target_link_libraries(test-aeadchacha20poly1305 ${LIBS}) target_link_libraries(test-aeadchacha20poly1305 ${LIBS})
target_link_libraries(test-blinding ${LIBS}) target_link_libraries(test-blinding ${LIBS})
target_link_libraries(test-elligator ${LIBS}) target_link_libraries(test-elligator ${LIBS})
@ -110,6 +116,7 @@ add_test(test-http-url ${TEST_PATH}/test-http-url)
add_test(test-base-64 ${TEST_PATH}/test-base-64) add_test(test-base-64 ${TEST_PATH}/test-base-64)
add_test(test-gost ${TEST_PATH}/test-gost) add_test(test-gost ${TEST_PATH}/test-gost)
add_test(test-gost-sig ${TEST_PATH}/test-gost-sig) add_test(test-gost-sig ${TEST_PATH}/test-gost-sig)
add_test(test-x25519 ${TEST_PATH}/test-x25519)
add_test(test-aeadchacha20poly1305 ${TEST_PATH}/test-aeadchacha20poly1305) add_test(test-aeadchacha20poly1305 ${TEST_PATH}/test-aeadchacha20poly1305)
add_test(test-blinding ${TEST_PATH}/test-blinding) add_test(test-blinding ${TEST_PATH}/test-blinding)
add_test(test-elligator ${TEST_PATH}/test-elligator) add_test(test-elligator ${TEST_PATH}/test-elligator)

View file

@ -7,7 +7,7 @@ LIBI2PD = ../libi2pd.a
TESTS = \ TESTS = \
test-http-merge_chunked test-http-req test-http-res test-http-url test-http-url_decode \ test-http-merge_chunked test-http-req test-http-res test-http-url test-http-url_decode \
test-gost test-gost-sig test-base-64 test-aeadchacha20poly1305 test-blinding \ test-gost test-gost-sig test-base-64 test-x25519 test-aeadchacha20poly1305 test-blinding \
test-elligator test-eddsa test-elligator test-eddsa
ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS))) ifneq (, $(findstring mingw, $(SYS))$(findstring windows-gnu, $(SYS))$(findstring cygwin, $(SYS)))
@ -44,6 +44,9 @@ test-gost: test-gost.cpp $(LIBI2PD)
test-gost-sig: test-gost-sig.cpp $(LIBI2PD) test-gost-sig: test-gost-sig.cpp $(LIBI2PD)
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
test-x25519: test-x25519.cpp $(LIBI2PD)
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
test-aeadchacha20poly1305: test-aeadchacha20poly1305.cpp $(LIBI2PD) test-aeadchacha20poly1305: test-aeadchacha20poly1305.cpp $(LIBI2PD)
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)

38
tests/test-x25519.cpp Normal file
View file

@ -0,0 +1,38 @@
#include <cassert>
#include <inttypes.h>
#include <string.h>
#include "Ed25519.h"
const uint8_t k[32] =
{
0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15,
0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc,
0x5a, 0x18, 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4
};
const uint8_t u[32] =
{
0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1,
0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3,
0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c
};
uint8_t p[32] =
{
0xc3, 0xda, 0x55, 0x37, 0x9d, 0xe9, 0xc6, 0x90, 0x8e, 0x94, 0xea,
0x4d, 0xf2, 0x8d, 0x08, 0x4f, 0x32, 0xec, 0xcf, 0x03, 0x49, 0x1c,
0x71, 0xf7, 0x54, 0xb4, 0x07, 0x55, 0x77, 0xa2, 0x85, 0x52
};
int main ()
{
#if !OPENSSL_X25519
// we test it for openssl < 1.1.0
uint8_t buf[32];
BN_CTX * ctx = BN_CTX_new ();
i2p::crypto::GetEd25519 ()->ScalarMul (u, k, buf, ctx);
BN_CTX_free (ctx);
assert(memcmp (buf, p, 32) == 0);
#endif
}