Merge pull request #1240 from PurpleI2P/openssl

eddsa from 1.1.1
This commit is contained in:
orignal 2018-09-08 16:22:12 -04:00 committed by GitHub
commit 5ecd04dd4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 188 additions and 39 deletions

View File

@ -130,6 +130,8 @@ doxygen:
.PHONY: deps .PHONY: deps
.PHONY: doxygen .PHONY: doxygen
.PHONY: dist .PHONY: dist
.PHONY: last-dist
.PHONY: api .PHONY: api
.PHONY: api_client .PHONY: api_client
.PHONY: mk_obj_dir .PHONY: mk_obj_dir
.PHONY: install

View File

@ -1,7 +1,7 @@
# root directory holding homebrew # root directory holding homebrew
BREWROOT = /usr/local BREWROOT = /usr/local
BOOSTROOT = ${BREWROOT}/opt/boost BOOSTROOT = ${BREWROOT}/opt/boost
SSLROOT = ${BREWROOT}/opt/libressl SSLROOT = ${BREWROOT}/opt/openssl@1.1
UPNPROOT = ${BREWROOT}/opt/miniupnpc UPNPROOT = ${BREWROOT}/opt/miniupnpc
CXXFLAGS = ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX -Wno-overloaded-virtual CXXFLAGS = ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX -Wno-overloaded-virtual
INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include
@ -41,9 +41,14 @@ ifeq ($(USE_AVX),1)
CXXFLAGS += -mavx CXXFLAGS += -mavx
endif endif
install: all
# Disabled, since it will be the default make rule. I think its better install -d ${PREFIX}/bin ${PREFIX}/etc/i2pd ${PREFIX}/share/doc/i2pd ${PREFIX}/share/i2pd ${PREFIX}/share/man/man1 ${PREFIX}/var/lib/i2pd
# to define the default rule in Makefile and not Makefile.<ostype> - torkel install -m 755 ${I2PD} ${PREFIX}/bin/
#install: all install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd
# test -d ${PREFIX} || mkdir -p ${PREFIX}/ @cp -R contrib/certificates ${PREFIX}/share/i2pd/
# cp -r i2p ${PREFIX}/ install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd
@gzip debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1
@ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/
@ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf
@ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf ${PREFIX}/var/lib/i2pd/tunnels.conf

View File

@ -21,8 +21,10 @@ else ifeq ($(shell expr match ${CXXVER} "4\.6"),3) # = 4.6
NEEDED_CXXFLAGS += -std=c++0x NEEDED_CXXFLAGS += -std=c++0x
else ifeq ($(shell expr match ${CXXVER} "[5-7]\.[0-9]"),3) # gcc >= 5.0 else ifeq ($(shell expr match ${CXXVER} "[5-7]\.[0-9]"),3) # gcc >= 5.0
NEEDED_CXXFLAGS += -std=c++11 NEEDED_CXXFLAGS += -std=c++11
LDLIBS = -latomic
else ifeq ($(shell expr match ${CXXVER} "[7-8]"),1) # gcc 7 ubuntu or gcc 8 arch else ifeq ($(shell expr match ${CXXVER} "[7-8]"),1) # gcc 7 ubuntu or gcc 8 arch
NEEDED_CXXFLAGS += -std=c++11 NEEDED_CXXFLAGS += -std=c++11
LDLIBS = -latomic
else # not supported else # not supported
$(error Compiler too old) $(error Compiler too old)
endif endif
@ -34,7 +36,7 @@ ifeq ($(USE_STATIC),yes)
# Using 'getaddrinfo' in statically linked applications requires at runtime # Using 'getaddrinfo' in statically linked applications requires at runtime
# the shared libraries from the glibc version used for linking # the shared libraries from the glibc version used for linking
LIBDIR := /usr/lib LIBDIR := /usr/lib
LDLIBS = $(LIBDIR)/libboost_system.a LDLIBS += $(LIBDIR)/libboost_system.a
LDLIBS += $(LIBDIR)/libboost_date_time.a LDLIBS += $(LIBDIR)/libboost_date_time.a
LDLIBS += $(LIBDIR)/libboost_filesystem.a LDLIBS += $(LIBDIR)/libboost_filesystem.a
LDLIBS += $(LIBDIR)/libboost_program_options.a LDLIBS += $(LIBDIR)/libboost_program_options.a
@ -44,7 +46,7 @@ ifeq ($(USE_STATIC),yes)
LDLIBS += -lpthread -static-libstdc++ -static-libgcc -lrt -ldl LDLIBS += -lpthread -static-libstdc++ -static-libgcc -lrt -ldl
USE_AESNI := no USE_AESNI := no
else else
LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread LDLIBS += -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
endif endif
# UPNP Support (miniupnpc 1.5 and higher) # UPNP Support (miniupnpc 1.5 and higher)

View File

@ -1,7 +1,7 @@
CXX = clang++ CXX = clang++
CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX
INCFLAGS = -I/usr/local/include INCFLAGS = -I/usr/local/include
LDFLAGS := ${LD_DEBUG} -Wl,-rpath,/usr/local/lib -L/usr/local/lib LDFLAGS := -Wl,-rpath,/usr/local/lib -L/usr/local/lib
ifeq ($(USE_STATIC),yes) ifeq ($(USE_STATIC),yes)
LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread
@ -28,17 +28,3 @@ endif
ifeq ($(USE_AVX),1) ifeq ($(USE_AVX),1)
CXXFLAGS += -mavx CXXFLAGS += -mavx
endif endif
# Disabled, since it will be the default make rule. I think its better
# to define the default rule in Makefile and not Makefile.<ostype> - torkel
install-brew: all
install -d ${PREFIX}/bin ${PREFIX}/etc/i2pd ${PREFIX}/share/doc/i2pd ${PREFIX}/share/i2pd ${PREFIX}/share/man/man1 ${PREFIX}/var/lib/i2pd
install -m 755 ${I2PD} ${PREFIX}/bin/
install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd
@cp -R contrib/certificates ${PREFIX}/share/i2pd/
install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd
@gzip debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1
@ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/
@ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf
@ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt
@ln -sf ${PREFIX}/etc/i2pd/tunnels.conf ${PREFIX}/var/lib/i2pd/tunnels.conf

View File

@ -1,5 +1,5 @@
## Configuration file for a typical i2pd user ## Configuration file for a typical i2pd user
## See https://i2pd.readthedocs.org/en/latest/configuration.html ## See https://i2pd.readthedocs.io/en/latest/user-guide/configuration/
## for more options you can use in this file. ## for more options you can use in this file.
#logfile = /sdcard/i2pd/i2pd.log #logfile = /sdcard/i2pd/i2pd.log

View File

@ -1,5 +1,5 @@
## Configuration file for a typical i2pd user ## Configuration file for a typical i2pd user
## See https://i2pd.readthedocs.org/en/latest/configuration.html ## See https://i2pd.readthedocs.io/en/latest/user-guide/configuration/
## for more options you can use in this file. ## for more options you can use in this file.
## Lines that begin with "## " try to explain what's going on. Lines ## Lines that begin with "## " try to explain what's going on. Lines

View File

@ -266,6 +266,10 @@ namespace crypto
# define LEGACY_OPENSSL 1 # define LEGACY_OPENSSL 1
#else #else
# define LEGACY_OPENSSL 0 # define LEGACY_OPENSSL 0
# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
# define OPENSSL_EDDSA 1
# define OPENSSL_X25519 1
# endif
#endif #endif
#if LEGACY_OPENSSL #if LEGACY_OPENSSL

View File

@ -41,6 +41,9 @@ namespace transport
delete[] m_SessionRequestBuffer; delete[] m_SessionRequestBuffer;
delete[] m_SessionCreatedBuffer; delete[] m_SessionCreatedBuffer;
delete[] m_SessionConfirmedBuffer; delete[] m_SessionConfirmedBuffer;
#if OPENSSL_X25519
EVP_PKEY_free (m_EphemeralPkey);
#endif
} }
void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived) void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived)
@ -119,7 +122,18 @@ namespace transport
// x25519 between remote pub and priv // x25519 between remote pub and priv
uint8_t inputKeyMaterial[32]; uint8_t inputKeyMaterial[32];
i2p::crypto::GetEd25519 ()->ScalarMul (GetRemotePub (), GetPriv (), inputKeyMaterial, m_Ctx); #if OPENSSL_X25519
auto pctx = EVP_PKEY_CTX_new (m_EphemeralPkey, NULL);
EVP_PKEY_derive_init (pctx);
auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, GetRemotePub (), 32);
EVP_PKEY_derive_set_peer (pctx, pkey);
size_t len = 32;
EVP_PKEY_derive (pctx, inputKeyMaterial, &len);
EVP_PKEY_free (pkey);
EVP_PKEY_CTX_free (pctx);
#else
i2p::crypto::GetEd25519 ()->ScalarMul (GetRemotePub (), GetPriv (), inputKeyMaterial, m_Ctx);
#endif
MixKey (inputKeyMaterial, m_K); MixKey (inputKeyMaterial, m_K);
} }
@ -149,8 +163,21 @@ namespace transport
void NTCP2Establisher::CreateEphemeralKey () void NTCP2Establisher::CreateEphemeralKey ()
{ {
#if OPENSSL_X25519
m_EphemeralPkey = nullptr;
EVP_PKEY_CTX * pctx = EVP_PKEY_CTX_new_id (NID_X25519, NULL);
EVP_PKEY_keygen_init (pctx);
EVP_PKEY_keygen (pctx, &m_EphemeralPkey);
EVP_PKEY_CTX_free (pctx);
// TODO: remove, after switch to m_EphemeralPkey
size_t len = 32;
EVP_PKEY_get_raw_public_key (m_EphemeralPkey, m_EphemeralPublicKey, &len);
len = 32;
EVP_PKEY_get_raw_private_key (m_EphemeralPkey, m_EphemeralPrivateKey, &len);
#else
RAND_bytes (m_EphemeralPrivateKey, 32); RAND_bytes (m_EphemeralPrivateKey, 32);
i2p::crypto::GetEd25519 ()->ScalarMulB (m_EphemeralPrivateKey, m_EphemeralPublicKey, m_Ctx); i2p::crypto::GetEd25519 ()->ScalarMulB (m_EphemeralPrivateKey, m_EphemeralPublicKey, m_Ctx);
#endif
} }
void NTCP2Establisher::CreateSessionRequestMessage () void NTCP2Establisher::CreateSessionRequestMessage ()
@ -1179,6 +1206,8 @@ namespace transport
else else
{ {
LogPrint (eLogDebug, "NTCP2: Connected to ", conn->GetSocket ().remote_endpoint ()); LogPrint (eLogDebug, "NTCP2: Connected to ", conn->GetSocket ().remote_endpoint ());
if (conn->GetSocket ().local_endpoint ().protocol () == boost::asio::ip::tcp::v6()) // ipv6
context.UpdateNTCP2V6Address (conn->GetSocket ().local_endpoint ().address ());
conn->ClientLogin (); conn->ClientLogin ();
} }
} }

View File

@ -18,6 +18,7 @@
#include <map> #include <map>
#include <array> #include <array>
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/evp.h>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include "util.h" #include "util.h"
#include "RouterInfo.h" #include "RouterInfo.h"
@ -110,6 +111,9 @@ namespace transport
BN_CTX * m_Ctx; BN_CTX * m_Ctx;
uint8_t m_EphemeralPrivateKey[32], m_EphemeralPublicKey[32], m_RemoteEphemeralPublicKey[32]; // x25519 uint8_t m_EphemeralPrivateKey[32], m_EphemeralPublicKey[32], m_RemoteEphemeralPublicKey[32]; // x25519
#if OPENSSL_X25519
EVP_PKEY * m_EphemeralPkey;
#endif
uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[33] /*ck*/, m_K[32] /*k*/; uint8_t m_RemoteStaticKey[32], m_IV[16], m_H[32] /*h*/, m_CK[33] /*ck*/, m_K[32] /*k*/;
i2p::data::IdentHash m_RemoteIdentHash; i2p::data::IdentHash m_RemoteIdentHash;
uint16_t m3p2Len; uint16_t m3p2Len;

View File

@ -453,6 +453,39 @@ namespace i2p
UpdateRouterInfo (); UpdateRouterInfo ();
} }
void RouterContext::UpdateNTCP2V6Address (const boost::asio::ip::address& host)
{
bool updated = false, found = false;
int port = 0;
auto& addresses = m_RouterInfo.GetAddresses ();
for (auto& addr: addresses)
{
if (addr->IsPublishedNTCP2 ())
{
if (addr->host.is_v6 ())
{
if (addr->host != host)
{
addr->host = host;
updated = true;
}
found = true;
break;
}
else
port = addr->port; // NTCP2 v4
}
}
if (!found && port) // we have found NTCP2 v4 but not v6
{
m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port);
updated = true;
}
if (updated)
UpdateRouterInfo ();
}
void RouterContext::UpdateStats () void RouterContext::UpdateStats ()
{ {
if (m_IsFloodfill) if (m_IsFloodfill)

View File

@ -100,6 +100,7 @@ namespace i2p
void SetSupportsV4 (bool supportsV4); void SetSupportsV4 (bool supportsV4);
void UpdateNTCPV6Address (const boost::asio::ip::address& host); // called from NTCP session void UpdateNTCPV6Address (const boost::asio::ip::address& host); // called from NTCP session
void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from NTCP2 session
void UpdateStats (); void UpdateStats ();
void CleanupDestination (); // garlic destination void CleanupDestination (); // garlic destination

View File

@ -696,17 +696,17 @@ namespace data
m_Caps |= eSSUIntroducer; m_Caps |= eSSUIntroducer;
} }
void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv) void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host, int port)
{ {
for (const auto& it: *m_Addresses) // don't insert one more NTCP2
if (it->ntcp2) return;
auto addr = std::make_shared<Address>(); auto addr = std::make_shared<Address>();
addr->port = 0; addr->host = host;
addr->port = port;
addr->transportStyle = eTransportNTCP; addr->transportStyle = eTransportNTCP;
addr->cost = 3; addr->cost = 3;
addr->date = 0; addr->date = 0;
addr->ntcp2.reset (new NTCP2Ext ()); addr->ntcp2.reset (new NTCP2Ext ());
addr->ntcp2->isNTCP2Only = true; // NTCP2 only address addr->ntcp2->isNTCP2Only = true; // NTCP2 only address
if (port) addr->ntcp2->isPublished = true;
memcpy (addr->ntcp2->staticKey, staticKey, 32); memcpy (addr->ntcp2->staticKey, staticKey, 32);
memcpy (addr->ntcp2->iv, iv, 16); memcpy (addr->ntcp2->iv, iv, 16);
m_Addresses->push_back(std::move(addr)); m_Addresses->push_back(std::move(addr));

View File

@ -117,7 +117,8 @@ namespace data
bool operator==(const Address& other) const bool operator==(const Address& other) const
{ {
return transportStyle == other.transportStyle && host == other.host && port == other.port; return transportStyle == other.transportStyle && IsNTCP2 () == other.IsNTCP2 () &&
host == other.host && port == other.port;
} }
bool operator!=(const Address& other) const bool operator!=(const Address& other) const
@ -150,7 +151,7 @@ namespace data
void AddNTCPAddress (const char * host, int port); void AddNTCPAddress (const char * host, int port);
void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0); void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0);
void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv); void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0);
bool AddIntroducer (const Introducer& introducer); bool AddIntroducer (const Introducer& introducer);
bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e); bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e);
void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only

View File

@ -6,6 +6,26 @@ namespace i2p
{ {
namespace crypto namespace crypto
{ {
#if OPENSSL_EDDSA
EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey)
{
m_Pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32);
m_MDCtx = EVP_MD_CTX_create ();
EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, m_Pkey);
}
EDDSA25519Verifier::~EDDSA25519Verifier ()
{
EVP_MD_CTX_destroy (m_MDCtx);
EVP_PKEY_free (m_Pkey);
}
bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
return EVP_DigestVerify (m_MDCtx, signature, 64, buf, len);
}
#else
EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey) EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey)
{ {
memcpy (m_PublicKeyEncoded, signingKey, EDDSA25519_PUBLIC_KEY_LENGTH); memcpy (m_PublicKeyEncoded, signingKey, EDDSA25519_PUBLIC_KEY_LENGTH);
@ -14,6 +34,10 @@ namespace crypto
BN_CTX_free (ctx); BN_CTX_free (ctx);
} }
EDDSA25519Verifier::~EDDSA25519Verifier ()
{
}
bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{ {
uint8_t digest[64]; uint8_t digest[64];
@ -26,7 +50,30 @@ namespace crypto
return GetEd25519 ()->Verify (m_PublicKey, digest, signature); return GetEd25519 ()->Verify (m_PublicKey, digest, signature);
} }
#endif
#if OPENSSL_EDDSA
EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey)
{
m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32);
// TODO: check public key
m_MDCtx = EVP_MD_CTX_create ();
EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, m_Pkey);
}
EDDSA25519Signer::~EDDSA25519Signer ()
{
EVP_MD_CTX_destroy (m_MDCtx);
EVP_PKEY_free (m_Pkey);
}
void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const
{
size_t l = 64;
EVP_DigestSign (m_MDCtx, signature, &l, buf, len);
}
#else
EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey)
{ {
// expand key // expand key
@ -47,10 +94,15 @@ namespace crypto
BN_CTX_free (ctx); BN_CTX_free (ctx);
} }
EDDSA25519Signer::~EDDSA25519Signer ()
{
}
void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const
{ {
GetEd25519 ()->Sign (m_ExpandedPrivateKey, m_PublicKeyEncoded, buf, len, signature); GetEd25519 ()->Sign (m_ExpandedPrivateKey, m_PublicKeyEncoded, buf, len, signature);
} }
#endif
} }
} }

View File

@ -367,6 +367,8 @@ namespace crypto
public: public:
EDDSA25519Verifier (const uint8_t * signingKey); EDDSA25519Verifier (const uint8_t * signingKey);
~EDDSA25519Verifier ();
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const;
size_t GetPublicKeyLen () const { return EDDSA25519_PUBLIC_KEY_LENGTH; }; size_t GetPublicKeyLen () const { return EDDSA25519_PUBLIC_KEY_LENGTH; };
@ -374,8 +376,13 @@ namespace crypto
private: private:
#if OPENSSL_EDDSA
EVP_PKEY * m_Pkey;
EVP_MD_CTX * m_MDCtx;
#else
EDDSAPoint m_PublicKey; EDDSAPoint m_PublicKey;
uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH];
#endif
}; };
class EDDSA25519Signer: public Signer class EDDSA25519Signer: public Signer
@ -384,20 +391,41 @@ namespace crypto
EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr);
// we pass signingPublicKey to check if it matches private key // we pass signingPublicKey to check if it matches private key
~EDDSA25519Signer ();
void Sign (const uint8_t * buf, int len, uint8_t * signature) const; void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; #if !OPENSSL_EDDSA
const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation
#endif
private: private:
#if OPENSSL_EDDSA
EVP_PKEY * m_Pkey;
EVP_MD_CTX * m_MDCtx;
#else
uint8_t m_ExpandedPrivateKey[64]; uint8_t m_ExpandedPrivateKey[64];
uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH];
#endif
}; };
inline void CreateEDDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) inline void CreateEDDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
{ {
#if OPENSSL_EDDSA
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_ED25519, NULL);
EVP_PKEY_keygen_init (pctx);
EVP_PKEY_keygen (pctx, &pkey);
EVP_PKEY_CTX_free (pctx);
size_t len = EDDSA25519_PUBLIC_KEY_LENGTH;
EVP_PKEY_get_raw_public_key (pkey, signingPublicKey, &len);
len = EDDSA25519_PRIVATE_KEY_LENGTH;
EVP_PKEY_get_raw_private_key (pkey, signingPrivateKey, &len);
EVP_PKEY_free (pkey);
#else
RAND_bytes (signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH); RAND_bytes (signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH);
EDDSA25519Signer signer (signingPrivateKey); EDDSA25519Signer signer (signingPrivateKey);
memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH); memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH);
#endif
} }

View File

@ -741,7 +741,7 @@ namespace client
std::string response; std::string response;
uint8_t recv_buf[4096]; uint8_t recv_buf[4096];
bool end = false; bool end = false;
int numAttempts = 5; int numAttempts = 0;
while (!end) while (!end)
{ {
stream->AsyncReceive (boost::asio::buffer (recv_buf, 4096), stream->AsyncReceive (boost::asio::buffer (recv_buf, 4096),
@ -755,7 +755,8 @@ namespace client
}, },
SUBSCRIPTION_REQUEST_TIMEOUT); SUBSCRIPTION_REQUEST_TIMEOUT);
std::unique_lock<std::mutex> l(newDataReceivedMutex); std::unique_lock<std::mutex> l(newDataReceivedMutex);
if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT)) == std::cv_status::timeout) // wait 1 more second
if (newDataReceived.wait_for (l, std::chrono::seconds (SUBSCRIPTION_REQUEST_TIMEOUT + 1)) == std::cv_status::timeout)
{ {
LogPrint (eLogError, "Addressbook: subscriptions request timeout expired"); LogPrint (eLogError, "Addressbook: subscriptions request timeout expired");
numAttempts++; numAttempts++;

View File

@ -500,7 +500,8 @@ namespace client
if (type == I2P_TUNNELS_SECTION_TYPE_SOCKS) if (type == I2P_TUNNELS_SECTION_TYPE_SOCKS)
{ {
// socks proxy // socks proxy
auto tun = std::make_shared<i2p::proxy::SOCKSProxy>(name, address, port, false, "", destinationPort, localDestination); std::string outproxy = section.second.get("outproxy", "");
auto tun = std::make_shared<i2p::proxy::SOCKSProxy>(name, address, port, !outproxy.empty(), outproxy, destinationPort, localDestination);
clientTunnel = tun; clientTunnel = tun;
clientEndpoint = tun->GetLocalEndpoint (); clientEndpoint = tun->GetLocalEndpoint ();
} }

View File

@ -46,7 +46,7 @@ namespace client
const char SAM_NAMING_REPLY[] = "NAMING REPLY RESULT=OK NAME=ME VALUE=%s\n"; const char SAM_NAMING_REPLY[] = "NAMING REPLY RESULT=OK NAME=ME VALUE=%s\n";
const char SAM_DATAGRAM_RECEIVED[] = "DATAGRAM RECEIVED DESTINATION=%s SIZE=%lu\n"; const char SAM_DATAGRAM_RECEIVED[] = "DATAGRAM RECEIVED DESTINATION=%s SIZE=%lu\n";
const char SAM_NAMING_REPLY_INVALID_KEY[] = "NAMING REPLY RESULT=INVALID_KEY NAME=%s\n"; const char SAM_NAMING_REPLY_INVALID_KEY[] = "NAMING REPLY RESULT=INVALID_KEY NAME=%s\n";
const char SAM_NAMING_REPLY_KEY_NOT_FOUND[] = "NAMING REPLY RESULT=INVALID_KEY_NOT_FOUND NAME=%s\n"; const char SAM_NAMING_REPLY_KEY_NOT_FOUND[] = "NAMING REPLY RESULT=KEY_NOT_FOUND NAME=%s\n";
const char SAM_PARAM_MIN[] = "MIN"; const char SAM_PARAM_MIN[] = "MIN";
const char SAM_PARAM_MAX[] = "MAX"; const char SAM_PARAM_MAX[] = "MAX";
const char SAM_PARAM_STYLE[] = "STYLE"; const char SAM_PARAM_STYLE[] = "STYLE";