Browse Source

Merge branch 'openssl' of https://github.com/PurpleI2P/i2pd into openssl

pull/1564/head
user 4 years ago
parent
commit
d9b87e877d
  1. 1
      build/CMakeLists.txt
  2. 88
      libi2pd/CryptoWorker.h
  3. 11
      libi2pd/Destination.cpp
  4. 3
      libi2pd/Garlic.cpp
  5. 114
      libi2pd/TunnelConfig.cpp
  6. 92
      libi2pd/TunnelConfig.h
  7. 2
      qt/i2pd_qt/i2pd_qt.pro

1
build/CMakeLists.txt

@ -85,6 +85,7 @@ set(LIBI2PD_SRC @@ -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"
)

88
libi2pd/CryptoWorker.h

@ -1,88 +0,0 @@ @@ -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 <condition_variable>
#include <mutex>
#include <deque>
#include <thread>
#include <vector>
#include <memory>
namespace i2p
{
namespace worker
{
template<typename Caller>
struct ThreadPool
{
typedef std::function<void(void)> ResultFunc;
typedef std::function<ResultFunc(void)> WorkFunc;
typedef std::pair<std::shared_ptr<Caller>, WorkFunc> Job;
typedef std::mutex mtx_t;
typedef std::unique_lock<mtx_t> 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<std::thread> threads;
std::deque<Job> jobs;
mtx_t queue_mutex;
cond_t condition;
bool stop;
};
}
}
#endif

11
libi2pd/Destination.cpp

@ -559,7 +559,9 @@ namespace client @@ -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 @@ -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

3
libi2pd/Garlic.cpp

@ -740,7 +740,8 @@ namespace garlic @@ -740,7 +740,8 @@ namespace garlic
session = std::make_shared<ECIESX25519AEADRatchetSession> (this, true);
session->SetRemoteStaticKey (staticKey);
}
session->SetDestination (destination->GetIdentHash ()); // TODO: remove
if (destination->IsDestination ())
session->SetDestination (destination->GetIdentHash ()); // TODO: remove
return session;
}
else

114
libi2pd/TunnelConfig.cpp

@ -0,0 +1,114 @@ @@ -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 <memory>
#include <openssl/rand.h>
#include "Transports.h"
#include "Timestamp.h"
#include "I2PEndian.h"
#include "I2NPProtocol.h"
#include "TunnelConfig.h"
namespace i2p
{
namespace tunnel
{
TunnelHopConfig::TunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> 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<i2p::crypto::CryptoKeyEncryptor>& encryptor,
const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx) const
{
memset (encrypted, 0, 512); // TODO: implement
}
}
}

92
libi2pd/TunnelConfig.h

@ -9,13 +9,9 @@ @@ -9,13 +9,9 @@
#ifndef TUNNEL_CONFIG_H__
#define TUNNEL_CONFIG_H__
#include <inttypes.h>
#include <sstream>
#include <vector>
#include <memory>
#include "Identity.h"
#include "RouterContext.h"
#include "Timestamp.h"
namespace i2p
{
@ -35,86 +31,16 @@ namespace tunnel @@ -35,86 +31,16 @@ namespace tunnel
TunnelHopConfig * next, * prev;
int recordIndex; // record # in tunnel build message
TunnelHopConfig (std::shared_ptr<const i2p::data::IdentityEx> 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<const i2p::data::IdentityEx> 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)
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<i2p::crypto::CryptoKeyEncryptor>& encryptor,
const uint8_t * clearText, uint8_t * encrypted, BN_CTX * ctx) const;
};
class TunnelConfig

2
qt/i2pd_qt/i2pd_qt.pro

@ -60,6 +60,7 @@ SOURCES += DaemonQT.cpp mainwindow.cpp \ @@ -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 \ @@ -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 \

Loading…
Cancel
Save