From 49bf735c22947f57c4dfad4aaa8536895a804d96 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Oct 2020 18:59:16 -0400 Subject: [PATCH 1/4] don't set destination to routers --- libi2pd/Garlic.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libi2pd/Garlic.cpp b/libi2pd/Garlic.cpp index 429a2092..5f76bca1 100644 --- a/libi2pd/Garlic.cpp +++ b/libi2pd/Garlic.cpp @@ -740,7 +740,8 @@ namespace garlic session = std::make_shared (this, true); session->SetRemoteStaticKey (staticKey); } - session->SetDestination (destination->GetIdentHash ()); // TODO: remove + if (destination->IsDestination ()) + session->SetDestination (destination->GetIdentHash ()); // TODO: remove return session; } else From 801ecaa41c988537b4abd54965c443e9fc060544 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 21 Oct 2020 19:03:51 -0400 Subject: [PATCH 2/4] temporary exclude routers with non ElGamal crypto types --- libi2pd/RouterInfo.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 12f81a42..8420044d 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -153,6 +153,12 @@ namespace data m_IsUnreachable = true; return; } + if (m_RouterIdentity->GetCryptoKeyType () != CRYPTO_KEY_TYPE_ELGAMAL) + { + // we support ElGamal only. TODO: remove later + m_IsUnreachable = true; + return; + } if (verifySignature) { // reject RSA signatures From d65a282e9d788a524b688a168859eb4d14735e09 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 22 Oct 2020 18:34:15 -0400 Subject: [PATCH 3/4] check routers with non ElGamal encryptions for lookup, publish and tunnel build --- libi2pd/Destination.cpp | 11 +++++++---- libi2pd/RouterInfo.cpp | 6 ------ libi2pd/TunnelConfig.h | 13 ++++++++++++- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 669fd791..927e98a0 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -559,7 +559,9 @@ namespace client m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); - auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound)); + auto msg = i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound); + if (floodfill->GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) // TODO: remove when implemented + msg = WrapMessage (floodfill, msg); m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT)); m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer, shared_from_this (), std::placeholders::_1)); @@ -754,9 +756,10 @@ namespace client else AddSessionKey (replyKey, replyTag); - auto msg = WrapMessage (nextFloodfill, - CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, - request->replyTunnel, replyKey, replyTag, isECIES)); + auto msg = CreateLeaseSetDatabaseLookupMsg (dest, request->excluded, + request->replyTunnel, replyKey, replyTag, isECIES); + if (nextFloodfill->GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL) // TODO: remove when implemented + msg = WrapMessage (nextFloodfill, msg); request->outboundTunnel->SendTunnelDataMsg ( { i2p::tunnel::TunnelMessageBlock diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index 8420044d..12f81a42 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -153,12 +153,6 @@ namespace data m_IsUnreachable = true; return; } - if (m_RouterIdentity->GetCryptoKeyType () != CRYPTO_KEY_TYPE_ELGAMAL) - { - // we support ElGamal only. TODO: remove later - m_IsUnreachable = true; - return; - } if (verifySignature) { // reject RSA signatures diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 0bd8a842..3a2fa44b 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -112,9 +112,20 @@ namespace tunnel RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); auto encryptor = ident->CreateEncryptor (nullptr); if (encryptor) - encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); + { + if (ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + EncryptECIES (encryptor, clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); + else + encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); + } memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); } + + void EncryptECIES (std::shared_ptr& encryptor, + const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx) const + { + memset (encrypted, 0, 512); // TODO: implement + } }; class TunnelConfig From 57d6c7a3b3c30d9b12492b18960f0de94e7d7bde Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 22 Oct 2020 21:06:23 -0400 Subject: [PATCH 4/4] Added TunnelConfig.cpp. Removed CryptoWroker.h --- build/CMakeLists.txt | 1 + libi2pd/CryptoWorker.h | 88 ------------------------------ libi2pd/TunnelConfig.cpp | 114 +++++++++++++++++++++++++++++++++++++++ libi2pd/TunnelConfig.h | 99 +++------------------------------- qt/i2pd_qt/i2pd_qt.pro | 2 +- 5 files changed, 123 insertions(+), 181 deletions(-) delete mode 100644 libi2pd/CryptoWorker.h create mode 100644 libi2pd/TunnelConfig.cpp diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index 4825855b..827e20d3 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -85,6 +85,7 @@ set(LIBI2PD_SRC "${LIBI2PD_SRC_DIR}/TunnelEndpoint.cpp" "${LIBI2PD_SRC_DIR}/TunnelGateway.cpp" "${LIBI2PD_SRC_DIR}/TunnelPool.cpp" + "${LIBI2PD_SRC_DIR}/TunnelConfig.cpp" "${LIBI2PD_SRC_DIR}/util.cpp" ) diff --git a/libi2pd/CryptoWorker.h b/libi2pd/CryptoWorker.h deleted file mode 100644 index 27b012e7..00000000 --- a/libi2pd/CryptoWorker.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -* Copyright (c) 2013-2020, The PurpleI2P Project -* -* This file is part of Purple i2pd project and licensed under BSD3 -* -* See full license text in LICENSE file at top of project tree -*/ - -#ifndef CRYPTO_WORKER_H_ -#define CRYPTO_WORKER_H_ - -#include -#include -#include -#include -#include -#include - -namespace i2p -{ -namespace worker -{ - template - struct ThreadPool - { - typedef std::function ResultFunc; - typedef std::function WorkFunc; - typedef std::pair, WorkFunc> Job; - typedef std::mutex mtx_t; - typedef std::unique_lock lock_t; - typedef std::condition_variable cond_t; - ThreadPool(int workers) - { - stop = false; - if(workers > 0) - { - while(workers--) - { - threads.emplace_back([this] { - for (;;) - { - Job job; - { - lock_t lock(this->queue_mutex); - this->condition.wait( - lock, [this] { return this->stop || !this->jobs.empty(); }); - if (this->stop && this->jobs.empty()) return; - job = std::move(this->jobs.front()); - this->jobs.pop_front(); - } - ResultFunc result = job.second(); - job.first->GetService().post(result); - } - }); - } - } - }; - - void Offer(const Job & job) - { - { - lock_t lock(queue_mutex); - if (stop) return; - jobs.emplace_back(job); - } - condition.notify_one(); - } - - ~ThreadPool() - { - { - lock_t lock(queue_mutex); - stop = true; - } - condition.notify_all(); - for(auto &t: threads) t.join(); - } - - std::vector threads; - std::deque jobs; - mtx_t queue_mutex; - cond_t condition; - bool stop; - }; -} -} - -#endif diff --git a/libi2pd/TunnelConfig.cpp b/libi2pd/TunnelConfig.cpp new file mode 100644 index 00000000..3b7955d4 --- /dev/null +++ b/libi2pd/TunnelConfig.cpp @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2013-2020, The PurpleI2P Project +* +* This file is part of Purple i2pd project and licensed under BSD3 +* +* See full license text in LICENSE file at top of project tree +* +*/ + +#include +#include +#include "Transports.h" +#include "Timestamp.h" +#include "I2PEndian.h" +#include "I2NPProtocol.h" +#include "TunnelConfig.h" + +namespace i2p +{ +namespace tunnel +{ + TunnelHopConfig::TunnelHopConfig (std::shared_ptr r) + { + RAND_bytes (layerKey, 32); + RAND_bytes (ivKey, 32); + RAND_bytes (replyKey, 32); + RAND_bytes (replyIV, 16); + RAND_bytes ((uint8_t *)&tunnelID, 4); + if (!tunnelID) tunnelID = 1; // tunnelID can't be zero + isGateway = true; + isEndpoint = true; + ident = r; + //nextRouter = nullptr; + nextTunnelID = 0; + + next = nullptr; + prev = nullptr; + } + + void TunnelHopConfig::SetNextIdent (const i2p::data::IdentHash& ident) + { + nextIdent = ident; + isEndpoint = false; + RAND_bytes ((uint8_t *)&nextTunnelID, 4); + if (!nextTunnelID) nextTunnelID = 1; // tunnelID can't be zero + } + + void TunnelHopConfig::SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent) + { + nextIdent = replyIdent; + nextTunnelID = replyTunnelID; + isEndpoint = true; + } + + void TunnelHopConfig::SetNext (TunnelHopConfig * n) + { + next = n; + if (next) + { + next->prev = this; + next->isGateway = false; + isEndpoint = false; + nextIdent = next->ident->GetIdentHash (); + nextTunnelID = next->tunnelID; + } + } + + void TunnelHopConfig::SetPrev (TunnelHopConfig * p) + { + prev = p; + if (prev) + { + prev->next = this; + prev->isEndpoint = false; + isGateway = false; + } + } + + void TunnelHopConfig::CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) const + { + uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; + htobe32buf (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); + memcpy (clearText + BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET, ident->GetIdentHash (), 32); + htobe32buf (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); + memcpy (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); + memcpy (clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, layerKey, 32); + memcpy (clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, ivKey, 32); + memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET, replyKey, 32); + memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, replyIV, 16); + uint8_t flag = 0; + if (isGateway) flag |= 0x80; + if (isEndpoint) flag |= 0x40; + clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] = flag; + htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ()); + htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); + RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); + auto encryptor = ident->CreateEncryptor (nullptr); + if (encryptor) + { + if (ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) + EncryptECIES (encryptor, clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); + else + encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); + } + memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); + } + + void TunnelHopConfig::EncryptECIES (std::shared_ptr& encryptor, + const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx) const + { + memset (encrypted, 0, 512); // TODO: implement + } +} +} \ No newline at end of file diff --git a/libi2pd/TunnelConfig.h b/libi2pd/TunnelConfig.h index 3a2fa44b..24e6f836 100644 --- a/libi2pd/TunnelConfig.h +++ b/libi2pd/TunnelConfig.h @@ -9,13 +9,9 @@ #ifndef TUNNEL_CONFIG_H__ #define TUNNEL_CONFIG_H__ -#include -#include #include -#include #include "Identity.h" #include "RouterContext.h" -#include "Timestamp.h" namespace i2p { @@ -35,97 +31,16 @@ namespace tunnel TunnelHopConfig * next, * prev; int recordIndex; // record # in tunnel build message - TunnelHopConfig (std::shared_ptr r) - { - RAND_bytes (layerKey, 32); - RAND_bytes (ivKey, 32); - RAND_bytes (replyKey, 32); - RAND_bytes (replyIV, 16); - RAND_bytes ((uint8_t *)&tunnelID, 4); - if (!tunnelID) tunnelID = 1; // tunnelID can't be zero - isGateway = true; - isEndpoint = true; - ident = r; - //nextRouter = nullptr; - nextTunnelID = 0; - - next = nullptr; - prev = nullptr; - } - - void SetNextIdent (const i2p::data::IdentHash& ident) - { - nextIdent = ident; - isEndpoint = false; - RAND_bytes ((uint8_t *)&nextTunnelID, 4); - if (!nextTunnelID) nextTunnelID = 1; // tunnelID can't be zero - } - - void SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent) - { - nextIdent = replyIdent; - nextTunnelID = replyTunnelID; - isEndpoint = true; - } - - void SetNext (TunnelHopConfig * n) - { - next = n; - if (next) - { - next->prev = this; - next->isGateway = false; - isEndpoint = false; - nextIdent = next->ident->GetIdentHash (); - nextTunnelID = next->tunnelID; - } - } + TunnelHopConfig (std::shared_ptr r); - void SetPrev (TunnelHopConfig * p) - { - prev = p; - if (prev) - { - prev->next = this; - prev->isEndpoint = false; - isGateway = false; - } - } - - void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) const - { - uint8_t clearText[BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE]; - htobe32buf (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET, tunnelID); - memcpy (clearText + BUILD_REQUEST_RECORD_OUR_IDENT_OFFSET, ident->GetIdentHash (), 32); - htobe32buf (clearText + BUILD_REQUEST_RECORD_NEXT_TUNNEL_OFFSET, nextTunnelID); - memcpy (clearText + BUILD_REQUEST_RECORD_NEXT_IDENT_OFFSET, nextIdent, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_LAYER_KEY_OFFSET, layerKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_IV_KEY_OFFSET, ivKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_KEY_OFFSET, replyKey, 32); - memcpy (clearText + BUILD_REQUEST_RECORD_REPLY_IV_OFFSET, replyIV, 16); - uint8_t flag = 0; - if (isGateway) flag |= 0x80; - if (isEndpoint) flag |= 0x40; - clearText[BUILD_REQUEST_RECORD_FLAG_OFFSET] = flag; - htobe32buf (clearText + BUILD_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetHoursSinceEpoch ()); - htobe32buf (clearText + BUILD_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID); - RAND_bytes (clearText + BUILD_REQUEST_RECORD_PADDING_OFFSET, BUILD_REQUEST_RECORD_CLEAR_TEXT_SIZE - BUILD_REQUEST_RECORD_PADDING_OFFSET); - auto encryptor = ident->CreateEncryptor (nullptr); - if (encryptor) - { - if (ident->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD_RATCHET) - EncryptECIES (encryptor, clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx); - else - encryptor->Encrypt (clearText, record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, ctx, false); - } - memcpy (record + BUILD_REQUEST_RECORD_TO_PEER_OFFSET, (const uint8_t *)ident->GetIdentHash (), 16); - } + void SetNextIdent (const i2p::data::IdentHash& ident); + void SetReplyHop (uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent); + void SetNext (TunnelHopConfig * n); + void SetPrev (TunnelHopConfig * p); + void CreateBuildRequestRecord (uint8_t * record, uint32_t replyMsgID, BN_CTX * ctx) const; void EncryptECIES (std::shared_ptr& encryptor, - const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx) const - { - memset (encrypted, 0, 512); // TODO: implement - } + const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx) const; }; class TunnelConfig diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 2f44b814..534d5f5a 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -60,6 +60,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/TunnelEndpoint.cpp \ ../../libi2pd/TunnelGateway.cpp \ ../../libi2pd/TunnelPool.cpp \ + ../../libi2pd/TunnelConfig.cpp \ ../../libi2pd/util.cpp \ ../../libi2pd/Elligator.cpp \ ../../libi2pd/ECIESX25519AEADRatchetSession.cpp \ @@ -104,7 +105,6 @@ HEADERS += DaemonQT.h mainwindow.h \ ../../libi2pd/CPU.h \ ../../libi2pd/Crypto.h \ ../../libi2pd/CryptoKey.h \ - ../../libi2pd/CryptoWorker.h \ ../../libi2pd/Datagram.h \ ../../libi2pd/Destination.h \ ../../libi2pd/Ed25519.h \