Skip to content

Commit

Permalink
Merge pull request #2118 from PurpleI2P/openssl
Browse files Browse the repository at this point in the history
recent changes
  • Loading branch information
orignal authored Oct 29, 2024
2 parents ecc635e + ec67f48 commit e695f1e
Show file tree
Hide file tree
Showing 34 changed files with 1,037 additions and 675 deletions.
26 changes: 20 additions & 6 deletions daemon/I2PControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,29 @@ namespace client
i2pcp_crt = i2p::fs::DataDirPath(i2pcp_crt);
if (i2pcp_key.at(0) != '/')
i2pcp_key = i2p::fs::DataDirPath(i2pcp_key);
if (!i2p::fs::Exists (i2pcp_crt) || !i2p::fs::Exists (i2pcp_key)) {
if (!i2p::fs::Exists (i2pcp_crt) || !i2p::fs::Exists (i2pcp_key))
{
LogPrint (eLogInfo, "I2PControl: Creating new certificate for control connection");
CreateCertificate (i2pcp_crt.c_str(), i2pcp_key.c_str());
} else {
}
else
LogPrint(eLogDebug, "I2PControl: Using cert from ", i2pcp_crt);
}
m_SSLContext.set_options (boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::single_dh_use);
m_SSLContext.use_certificate_file (i2pcp_crt, boost::asio::ssl::context::pem);
m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem);
boost::system::error_code ec;
m_SSLContext.use_certificate_file (i2pcp_crt, boost::asio::ssl::context::pem, ec);
if (!ec)
m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem, ec);
if (ec)
{
LogPrint (eLogInfo, "I2PControl: Failed to load ceritifcate: ", ec.message (), ". Recreating");
CreateCertificate (i2pcp_crt.c_str(), i2pcp_key.c_str());
m_SSLContext.use_certificate_file (i2pcp_crt, boost::asio::ssl::context::pem, ec);
if (!ec)
m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem, ec);
if (ec)
// give up
LogPrint (eLogError, "I2PControl: Can't load certificates");
}

// handlers
m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler;
Expand Down Expand Up @@ -403,7 +417,7 @@ namespace client
X509_NAME_add_entry_by_txt (name, "O", MBSTRING_ASC, (unsigned char *)I2P_CONTROL_CERTIFICATE_ORGANIZATION, -1, -1, 0); // organization
X509_NAME_add_entry_by_txt (name, "CN", MBSTRING_ASC, (unsigned char *)I2P_CONTROL_CERTIFICATE_COMMON_NAME, -1, -1, 0); // common name
X509_set_issuer_name (x509, name); // set issuer to ourselves
X509_sign (x509, pkey, EVP_sha1 ()); // sign
X509_sign (x509, pkey, EVP_sha1 ()); // sign, last param must be NULL for EdDSA

// save cert
if ((f = fopen (crt_path, "wb")) != NULL) {
Expand Down
4 changes: 3 additions & 1 deletion daemon/UnixDaemon.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2020, The PurpleI2P Project
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
Expand All @@ -25,6 +25,7 @@
#include "RouterContext.h"
#include "ClientContext.h"
#include "Transports.h"
#include "util.h"

void handle_signal(int sig)
{
Expand Down Expand Up @@ -220,6 +221,7 @@ namespace i2p

void DaemonLinux::run ()
{
i2p::util::SetThreadName ("i2pd-daemon");
while (running)
{
std::this_thread::sleep_for (std::chrono::seconds(1));
Expand Down
2 changes: 1 addition & 1 deletion libi2pd/Crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,7 @@ namespace crypto
}
else
{
#if defined(LIBRESSL_VERSION_NUMBER)
#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x4000000fL
std::vector<uint8_t> m(msgLen + 16);
if (msg == buf)
{
Expand Down
7 changes: 5 additions & 2 deletions libi2pd/Destination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -588,9 +588,12 @@ namespace client
i2p::garlic::GarlicDestination::HandleDeliveryStatusMessage (msgID);
}

void LeaseSetDestination::SetLeaseSetUpdated ()
void LeaseSetDestination::SetLeaseSetUpdated (bool post)
{
UpdateLeaseSet ();
if (post)
m_Service.post([s = shared_from_this ()]() { s->UpdateLeaseSet (); });
else
UpdateLeaseSet ();
}

void LeaseSetDestination::Publish ()
Expand Down
18 changes: 9 additions & 9 deletions libi2pd/Destination.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,24 +142,24 @@ namespace client
void CancelDestinationRequestWithEncryptedLeaseSet (std::shared_ptr<const i2p::data::BlindedPublicKey> dest, bool notify = true);

// implements GarlicDestination
std::shared_ptr<const i2p::data::LocalLeaseSet> GetLeaseSet ();
std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () const { return m_Pool; }
std::shared_ptr<const i2p::data::LocalLeaseSet> GetLeaseSet () override;
std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () const override { return m_Pool; }

// override GarlicDestination
bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag);
void SubmitECIESx25519Key (const uint8_t * key, uint64_t tag);
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
void SetLeaseSetUpdated ();
bool SubmitSessionKey (const uint8_t * key, const uint8_t * tag) override;
void SubmitECIESx25519Key (const uint8_t * key, uint64_t tag) override;
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg) override;
void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg) override;
void SetLeaseSetUpdated (bool post) override;

bool IsPublic () const { return m_IsPublic; };
void SetPublic (bool pub) { m_IsPublic = pub; };

protected:

// implements GarlicDestination
void HandleI2NPMessage (const uint8_t * buf, size_t len);
bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID);
void HandleI2NPMessage (const uint8_t * buf, size_t len) override;
bool HandleCloveI2NPMessage (I2NPMessageType typeID, const uint8_t * payload, size_t len, uint32_t msgID) override;

void SetLeaseSet (std::shared_ptr<const i2p::data::LocalLeaseSet> newLeaseSet);
int GetLeaseSetType () const { return m_LeaseSetType; };
Expand Down
75 changes: 26 additions & 49 deletions libi2pd/Family.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
/*
* Copyright (c) 2013-2023, The PurpleI2P Project
* Copyright (c) 2013-2024, 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 <string.h>
#include <openssl/evp.h>
#include <openssl/ssl.h>
#include "Crypto.h"
#include "FS.h"
Expand All @@ -25,6 +24,8 @@ namespace data

Families::~Families ()
{
for (auto it : m_SigningKeys)
if (it.second.first) EVP_PKEY_free (it.second.first);
}

void Families::LoadCertificate (const std::string& filename)
Expand All @@ -47,48 +48,16 @@ namespace data
cn += 3;
char * family = strstr (cn, ".family");
if (family) family[0] = 0;
}
auto pkey = X509_get_pubkey (cert);
int keyType = EVP_PKEY_base_id (pkey);
switch (keyType)
{
case EVP_PKEY_DSA:
// TODO:
break;
case EVP_PKEY_EC:
{
EC_KEY * ecKey = EVP_PKEY_get1_EC_KEY (pkey);
if (ecKey)
auto pkey = X509_get_pubkey (cert);
if (pkey)
{
if (!m_SigningKeys.emplace (cn, std::make_pair(pkey, (int)m_SigningKeys.size () + 1)).second)
{
auto group = EC_KEY_get0_group (ecKey);
if (group)
{
int curve = EC_GROUP_get_curve_name (group);
if (curve == NID_X9_62_prime256v1)
{
uint8_t signingKey[64];
BIGNUM * x = BN_new(), * y = BN_new();
EC_POINT_get_affine_coordinates_GFp (group,
EC_KEY_get0_public_key (ecKey), x, y, NULL);
i2p::crypto::bn2buf (x, signingKey, 32);
i2p::crypto::bn2buf (y, signingKey + 32, 32);
BN_free (x); BN_free (y);
verifier = std::make_shared<i2p::crypto::ECDSAP256Verifier>();
verifier->SetPublicKey (signingKey);
}
else
LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
}
EC_KEY_free (ecKey);
}
break;
}
default:
LogPrint (eLogWarning, "Family: Certificate key type ", keyType, " is not supported");
EVP_PKEY_free (pkey);
LogPrint (eLogError, "Family: Duplicated family name ", cn);
}
}
}
EVP_PKEY_free (pkey);
if (verifier && cn)
m_SigningKeys.emplace (cn, std::make_pair(verifier, (int)m_SigningKeys.size () + 1));
}
SSL_free (ssl);
}
Expand Down Expand Up @@ -130,14 +99,22 @@ namespace data
LogPrint (eLogError, "Family: ", family, " is too long");
return false;
}

memcpy (buf, family.c_str (), len);
memcpy (buf + len, (const uint8_t *)ident, 32);
len += 32;
Base64ToByteStream (signature, signatureLen, signatureBuf, 64);
auto it = m_SigningKeys.find (family);
if (it != m_SigningKeys.end ())
return it->second.first->Verify (buf, len, signatureBuf);
if (it != m_SigningKeys.end () && it->second.first)
{
memcpy (buf, family.c_str (), len);
memcpy (buf + len, (const uint8_t *)ident, 32);
len += 32;
auto signatureBufLen = Base64ToByteStream (signature, signatureLen, signatureBuf, 64);
if (signatureBufLen)
{
EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
EVP_DigestVerifyInit (ctx, NULL, NULL, NULL, it->second.first);
auto ret = EVP_DigestVerify (ctx, signatureBuf, signatureBufLen, buf, len);
EVP_MD_CTX_destroy (ctx);
return ret;
}
}
// TODO: process key
return true;
}
Expand Down
6 changes: 3 additions & 3 deletions libi2pd/Family.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2022, The PurpleI2P Project
* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
Expand All @@ -12,7 +12,7 @@
#include <map>
#include <string>
#include <memory>
#include "Signature.h"
#include <openssl/evp.h>
#include "Identity.h"

namespace i2p
Expand All @@ -37,7 +37,7 @@ namespace data

private:

std::map<std::string, std::pair<std::shared_ptr<i2p::crypto::Verifier>, FamilyID> > m_SigningKeys; // family -> (verifier, id)
std::map<std::string, std::pair<EVP_PKEY *, FamilyID> > m_SigningKeys; // family -> (verification pkey, id)
};

std::string CreateFamilySignature (const std::string& family, const IdentHash& ident);
Expand Down
2 changes: 1 addition & 1 deletion libi2pd/Garlic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,7 @@ namespace garlic
}
}

void GarlicDestination::SetLeaseSetUpdated ()
void GarlicDestination::SetLeaseSetUpdated (bool post)
{
{
std::unique_lock<std::mutex> l(m_SessionsMutex);
Expand Down
2 changes: 1 addition & 1 deletion libi2pd/Garlic.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ namespace garlic

virtual void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
virtual void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
virtual void SetLeaseSetUpdated ();
virtual void SetLeaseSetUpdated (bool post = false);

virtual std::shared_ptr<const i2p::data::LocalLeaseSet> GetLeaseSet () = 0; // TODO
virtual std::shared_ptr<i2p::tunnel::TunnelPool> GetTunnelPool () const = 0;
Expand Down
26 changes: 19 additions & 7 deletions libi2pd/I2NPProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,26 @@ namespace i2p
return false;
}
uint8_t retCode = 0;
// decide if we should accept tunnel
bool accept = i2p::context.AcceptsTunnels ();
if (accept)
{
auto congestionLevel = i2p::context.GetCongestionLevel (false);
if (congestionLevel >= CONGESTION_LEVEL_MEDIUM)
{
if (congestionLevel < CONGESTION_LEVEL_FULL)
{
// random reject depending on congestion level
int level = i2p::tunnel::tunnels.GetRng ()() % (CONGESTION_LEVEL_FULL - CONGESTION_LEVEL_MEDIUM) + CONGESTION_LEVEL_MEDIUM;
if (congestionLevel > level)
accept = false;
}
else
accept = false;
}
}
// replace record to reply
if (i2p::context.AcceptsTunnels () && i2p::context.GetCongestionLevel (false) < CONGESTION_LEVEL_FULL)
if (accept)
{
auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
Expand Down Expand Up @@ -932,14 +950,8 @@ namespace i2p
void I2NPMessagesHandler::Flush ()
{
if (!m_TunnelMsgs.empty ())
{
i2p::tunnel::tunnels.PostTunnelData (m_TunnelMsgs);
m_TunnelMsgs.clear ();
}
if (!m_TunnelGatewayMsgs.empty ())
{
i2p::tunnel::tunnels.PostTunnelData (m_TunnelGatewayMsgs);
m_TunnelGatewayMsgs.clear ();
}
}
}
3 changes: 2 additions & 1 deletion libi2pd/I2NPProtocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <string.h>
#include <unordered_set>
#include <memory>
#include <list>
#include <functional>
#include "Crypto.h"
#include "I2PEndian.h"
Expand Down Expand Up @@ -328,7 +329,7 @@ namespace tunnel

private:

std::vector<std::shared_ptr<I2NPMessage> > m_TunnelMsgs, m_TunnelGatewayMsgs;
std::list<std::shared_ptr<I2NPMessage> > m_TunnelMsgs, m_TunnelGatewayMsgs;
};
}

Expand Down
4 changes: 1 addition & 3 deletions libi2pd/NTCP2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1822,7 +1822,7 @@ namespace transport
LogPrint(eLogError, "NTCP2: HTTP proxy write error ", ec.message());
});

boost::asio::streambuf * readbuff = new boost::asio::streambuf;
auto readbuff = std::make_shared<boost::asio::streambuf>();
boost::asio::async_read_until(conn->GetSocket(), *readbuff, "\r\n\r\n",
[readbuff, timer, conn] (const boost::system::error_code & ec, std::size_t transferred)
{
Expand All @@ -1842,7 +1842,6 @@ namespace transport
{
timer->cancel();
conn->ClientLogin();
delete readbuff;
return;
}
else
Expand All @@ -1852,7 +1851,6 @@ namespace transport
LogPrint(eLogError, "NTCP2: HTTP proxy gave malformed response");
timer->cancel();
conn->Terminate();
delete readbuff;
}
});
break;
Expand Down
Loading

0 comments on commit e695f1e

Please sign in to comment.