diff --git a/contrib/i2pd.conf b/contrib/i2pd.conf
index fa6b1f8b..c26f8af0 100644
--- a/contrib/i2pd.conf
+++ b/contrib/i2pd.conf
@@ -246,9 +246,9 @@ verify = true
# subscriptions = http://reg.i2p/hosts.txt,http://identiguy.i2p/hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt
[limits]
-## Maximum active transit sessions (default: 10000)
+## Maximum active transit sessions (default: 5000)
## This value is doubled if floodfill mode is enabled!
-# transittunnels = 10000
+# transittunnels = 5000
## Limit number of open file descriptors (0 - use system limit)
# openfiles = 0
## Maximum size of corefile in Kb (0 - use system limit)
diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec
index d9393f47..fd431347 100644
--- a/contrib/rpm/i2pd-git.spec
+++ b/contrib/rpm/i2pd-git.spec
@@ -10,7 +10,11 @@ License: BSD
URL: https://github.com/PurpleI2P/i2pd
Source0: https://github.com/PurpleI2P/i2pd/archive/openssl/i2pd-openssl.tar.gz
+%if 0%{?rhel} == 7
+BuildRequires: cmake3
+%else
BuildRequires: cmake
+%endif
BuildRequires: chrpath
BuildRequires: gcc-c++
@@ -39,18 +43,26 @@ C++ implementation of I2P.
%build
cd build
-%cmake \
- -DWITH_LIBRARY=OFF \
- -DWITH_UPNP=ON \
- -DWITH_HARDENING=ON \
-%if 0%{?fedora} > 29
- -DBUILD_SHARED_LIBS:BOOL=OFF \
- .
+%if 0%{?rhel} == 7
+ %cmake3 \
+ -DWITH_LIBRARY=OFF \
+ -DWITH_UPNP=ON \
+ -DWITH_HARDENING=ON \
+ -DBUILD_SHARED_LIBS:BOOL=OFF
%else
- -DBUILD_SHARED_LIBS:BOOL=OFF
+ %cmake \
+ -DWITH_LIBRARY=OFF \
+ -DWITH_UPNP=ON \
+ -DWITH_HARDENING=ON \
+ %if 0%{?fedora} > 29
+ -DBUILD_SHARED_LIBS:BOOL=OFF \
+ .
+ %else
+ -DBUILD_SHARED_LIBS:BOOL=OFF
+ %endif
%endif
-%if 0%{?rhel} >= 9 || 0%{?fedora} >= 35 || 0%{?eln}
+%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln}
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
@@ -64,7 +76,7 @@ cd build
make %{?_smp_mflags}
-%if 0%{?rhel} >= 9 || 0%{?fedora} >= 33 || 0%{?mageia} > 7
+%if 0%{?rhel} == 9 || 0%{?fedora} >= 33 || 0%{?mageia} > 7
popd
%endif
@@ -72,7 +84,7 @@ make %{?_smp_mflags}
%install
pushd build
-%if 0%{?rhel} >= 9 || 0%{?fedora} >= 35 || 0%{?eln}
+%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln}
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec
index e094c3b7..2d3d4cbb 100644
--- a/contrib/rpm/i2pd.spec
+++ b/contrib/rpm/i2pd.spec
@@ -8,7 +8,11 @@ License: BSD
URL: https://github.com/PurpleI2P/i2pd
Source0: https://github.com/PurpleI2P/i2pd/archive/%{version}/%name-%version.tar.gz
+%if 0%{?rhel} == 7
+BuildRequires: cmake3
+%else
BuildRequires: cmake
+%endif
BuildRequires: chrpath
BuildRequires: gcc-c++
@@ -37,18 +41,26 @@ C++ implementation of I2P.
%build
cd build
-%cmake \
- -DWITH_LIBRARY=OFF \
- -DWITH_UPNP=ON \
- -DWITH_HARDENING=ON \
-%if 0%{?fedora} > 29
- -DBUILD_SHARED_LIBS:BOOL=OFF \
- .
+%if 0%{?rhel} == 7
+ %cmake3 \
+ -DWITH_LIBRARY=OFF \
+ -DWITH_UPNP=ON \
+ -DWITH_HARDENING=ON \
+ -DBUILD_SHARED_LIBS:BOOL=OFF
%else
- -DBUILD_SHARED_LIBS:BOOL=OFF
+ %cmake \
+ -DWITH_LIBRARY=OFF \
+ -DWITH_UPNP=ON \
+ -DWITH_HARDENING=ON \
+ %if 0%{?fedora} > 29
+ -DBUILD_SHARED_LIBS:BOOL=OFF \
+ .
+ %else
+ -DBUILD_SHARED_LIBS:BOOL=OFF
+ %endif
%endif
-%if 0%{?rhel} >= 9 || 0%{?fedora} >= 35 || 0%{?eln}
+%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln}
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
@@ -62,7 +74,7 @@ cd build
make %{?_smp_mflags}
-%if 0%{?rhel} >= 9 || 0%{?fedora} >= 33 || 0%{?mageia} > 7
+%if 0%{?rhel} == 9 || 0%{?fedora} >= 33 || 0%{?mageia} > 7
popd
%endif
@@ -70,7 +82,7 @@ make %{?_smp_mflags}
%install
pushd build
-%if 0%{?rhel} >= 9 || 0%{?fedora} >= 35 || 0%{?eln}
+%if 0%{?rhel} == 9 || 0%{?fedora} >= 35 || 0%{?eln}
pushd redhat-linux-build
%else
%if 0%{?fedora} >= 33
diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp
index 167b8c95..be1ec4ac 100644
--- a/daemon/HTTPServer.cpp
+++ b/daemon/HTTPServer.cpp
@@ -661,7 +661,7 @@ namespace http {
else
{
ls.reset (new i2p::data::LeaseSet2 (storeType));
- ls->Update (leaseSet->GetBuffer(), leaseSet->GetBufferLen(), nullptr, false);
+ ls->Update (leaseSet->GetBuffer(), leaseSet->GetBufferLen(), false);
}
if (!ls) return;
s << "
= 0x030000000) // since 3.0.0
- EVP_PKEY * pkey = EVP_RSA_gen(4096); // e = 65537
-#else
EVP_PKEY * pkey = EVP_PKEY_new ();
RSA * rsa = RSA_new ();
BIGNUM * e = BN_dup (i2p::crypto::GetRSAE ());
RSA_generate_key_ex (rsa, 4096, e, NULL);
- BN_free (e);
- if (rsa) EVP_PKEY_assign_RSA (pkey, rsa);
- else
- {
- LogPrint (eLogError, "I2PControl: Can't create RSA key for certificate");
- EVP_PKEY_free (pkey);
- return;
- }
-#endif
- X509 * x509 = X509_new ();
- ASN1_INTEGER_set (X509_get_serialNumber (x509), 1);
- X509_gmtime_adj (X509_getm_notBefore (x509), 0);
- X509_gmtime_adj (X509_getm_notAfter (x509), I2P_CONTROL_CERTIFICATE_VALIDITY*24*60*60); // expiration
- X509_set_pubkey (x509, pkey); // public key
- X509_NAME * name = X509_get_subject_name (x509);
- X509_NAME_add_entry_by_txt (name, "C", MBSTRING_ASC, (unsigned char *)"A1", -1, -1, 0); // country (Anonymous proxy)
- 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, last param must be NULL for EdDSA
+ BN_free (e);
+ if (rsa)
+ {
+ EVP_PKEY_assign_RSA (pkey, rsa);
+ X509 * x509 = X509_new ();
+ ASN1_INTEGER_set (X509_get_serialNumber (x509), 1);
+ X509_gmtime_adj (X509_getm_notBefore (x509), 0);
+ X509_gmtime_adj (X509_getm_notAfter (x509), I2P_CONTROL_CERTIFICATE_VALIDITY*24*60*60); // expiration
+ X509_set_pubkey (x509, pkey); // public key
+ X509_NAME * name = X509_get_subject_name (x509);
+ X509_NAME_add_entry_by_txt (name, "C", MBSTRING_ASC, (unsigned char *)"A1", -1, -1, 0); // country (Anonymous proxy)
+ 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, last param must be NULL for EdDSA
- // save cert
- if ((f = fopen (crt_path, "wb")) != NULL)
- {
- LogPrint (eLogInfo, "I2PControl: Saving new cert to ", crt_path);
- PEM_write_X509 (f, x509);
- fclose (f);
- }
- else
- LogPrint (eLogError, "I2PControl: Can't write cert: ", strerror(errno));
- X509_free (x509);
-
- // save key
- if ((f = fopen (key_path, "wb")) != NULL)
- {
- LogPrint (eLogInfo, "I2PControl: saving cert key to ", key_path);
- PEM_write_PrivateKey (f, pkey, NULL, NULL, 0, NULL, NULL);
- fclose (f);
+ // save cert
+ if ((f = fopen (crt_path, "wb")) != NULL) {
+ LogPrint (eLogInfo, "I2PControl: Saving new cert to ", crt_path);
+ PEM_write_X509 (f, x509);
+ fclose (f);
+ } else {
+ LogPrint (eLogError, "I2PControl: Can't write cert: ", strerror(errno));
+ }
+
+ // save key
+ if ((f = fopen (key_path, "wb")) != NULL) {
+ LogPrint (eLogInfo, "I2PControl: saving cert key to ", key_path);
+ PEM_write_PrivateKey (f, pkey, NULL, NULL, 0, NULL, NULL);
+ fclose (f);
+ } else {
+ LogPrint (eLogError, "I2PControl: Can't write key: ", strerror(errno));
+ }
+
+ X509_free (x509);
+ } else {
+ LogPrint (eLogError, "I2PControl: Can't create RSA key for certificate");
}
- else
- LogPrint (eLogError, "I2PControl: Can't write key: ", strerror(errno));
EVP_PKEY_free (pkey);
}
}
diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp
index 3d88ff21..939cd9ff 100644
--- a/libi2pd/Config.cpp
+++ b/libi2pd/Config.cpp
@@ -305,8 +305,6 @@ namespace config {
("ssu2.mtu4", value()->default_value(0), "MTU for ipv4 address (default: detect)")
("ssu2.mtu6", value()->default_value(0), "MTU for ipv6 address (default: detect)")
("ssu2.proxy", value()->default_value(""), "Socks5 proxy URL for SSU2 transport")
- ("ssu2.firewalled4", value()->default_value(false), "Set ipv4 network status to Firewalled even if OK (default: disabled)")
- ("ssu2.firewalled6", value()->default_value(false), "Set ipv6 network status to Firewalled even if OK (default: disabled)")
;
options_description nettime("Time sync options");
diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp
index 94f47ca9..c41b4c10 100644
--- a/libi2pd/Crypto.cpp
+++ b/libi2pd/Crypto.cpp
@@ -16,7 +16,9 @@
#include
#include "TunnelBase.h"
#include
+#if OPENSSL_HKDF
#include
+#endif
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0
#include
#include
@@ -782,6 +784,7 @@ namespace crypto
void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info,
uint8_t * out, size_t outLen)
{
+#if OPENSSL_HKDF
EVP_PKEY_CTX * pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF, nullptr);
EVP_PKEY_derive_init (pctx);
EVP_PKEY_CTX_set_hkdf_md (pctx, EVP_sha256());
@@ -802,6 +805,18 @@ namespace crypto
EVP_PKEY_CTX_add1_hkdf_info (pctx, (const uint8_t *)info.c_str (), info.length ());
EVP_PKEY_derive (pctx, out, &outLen);
EVP_PKEY_CTX_free (pctx);
+#else
+ uint8_t prk[32]; unsigned int len;
+ HMAC(EVP_sha256(), salt, 32, key, keyLen, prk, &len);
+ auto l = info.length ();
+ memcpy (out, info.c_str (), l); out[l] = 0x01;
+ HMAC(EVP_sha256(), prk, 32, out, l + 1, out, &len);
+ if (outLen > 32) // 64
+ {
+ memcpy (out + 32, info.c_str (), l); out[l + 32] = 0x02;
+ HMAC(EVP_sha256(), prk, 32, out, l + 33, out + 32, &len);
+ }
+#endif
}
// Noise
diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h
index 5bf4d534..80650098 100644
--- a/libi2pd/Crypto.h
+++ b/libi2pd/Crypto.h
@@ -27,11 +27,15 @@
#include "Tag.h"
// recognize openssl version and features
-#if (!defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER != 0x030000000)) // 3.0.0, regression in SipHash, not implemented in LibreSSL
-# define OPENSSL_SIPHASH 1
-#endif
-#if (OPENSSL_VERSION_NUMBER >= 0x030500000) // 3.5.0
-# define OPENSSL_PQ 1
+#if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
+# define OPENSSL_HKDF 1
+# define OPENSSL_EDDSA 1
+# if (!defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER != 0x030000000)) // 3.0.0, regression in SipHash, not implemented in LibreSSL
+# define OPENSSL_SIPHASH 1
+# endif
+//# if (OPENSSL_VERSION_NUMBER >= 0x030500000) // 3.5.0
+//# define OPENSSL_PQ 1
+//# endif
#endif
namespace i2p
diff --git a/libi2pd/Datagram.cpp b/libi2pd/Datagram.cpp
index 029ab42d..732efca7 100644
--- a/libi2pd/Datagram.cpp
+++ b/libi2pd/Datagram.cpp
@@ -58,35 +58,25 @@ namespace datagram
{
if (session)
{
- if (session->GetVersion () == eDatagramV3)
+ if (m_Owner->GetIdentity ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
{
- constexpr uint8_t flags[] = { 0x00, 0x03 }; // datagram3, no options
- auto msg = CreateDataMessage ({{m_Owner->GetIdentity ()->GetIdentHash (), 32},
- {flags, 2}, {payload, len}}, fromPort, toPort, i2p::client::PROTOCOL_TYPE_DATAGRAM3, false); // datagram3
- session->SendMsg(msg);
+ uint8_t hash[32];
+ SHA256(payload, len, hash);
+ m_Owner->Sign (hash, 32, m_Signature.data ());
}
else
- {
- if (m_Owner->GetIdentity ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
- {
- uint8_t hash[32];
- SHA256(payload, len, hash);
- m_Owner->Sign (hash, 32, m_Signature.data ());
- }
- else
- m_Owner->Sign (payload, len, m_Signature.data ());
+ m_Owner->Sign (payload, len, m_Signature.data ());
- auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}},
- fromPort, toPort, i2p::client::PROTOCOL_TYPE_DATAGRAM, !session->IsRatchets ()); // datagram1
- session->SendMsg(msg);
- }
+ auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}},
+ fromPort, toPort, false, !session->IsRatchets ()); // datagram
+ session->SendMsg(msg);
}
}
void DatagramDestination::SendRawDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort)
{
if (session)
- session->SendMsg(CreateDataMessage ({{payload, len}}, fromPort, toPort, i2p::client::PROTOCOL_TYPE_RAW, !session->IsRatchets ())); // raw
+ session->SendMsg(CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ())); // raw
}
void DatagramDestination::FlushSendQueue (std::shared_ptr session)
@@ -95,50 +85,26 @@ namespace datagram
session->FlushSendQueue ();
}
- void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,
- const uint8_t * buf, size_t len, i2p::garlic::ECIESX25519AEADRatchetSession * from)
+ void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len)
{
i2p::data::IdentityEx identity;
size_t identityLen = identity.FromBuffer (buf, len);
- if (!identityLen) return;
const uint8_t * signature = buf + identityLen;
size_t headerLen = identityLen + identity.GetSignatureLen ();
- std::shared_ptr ls;
bool verified = false;
- if (from)
+ if (identity.GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
{
- ls = m_Owner->FindLeaseSet (identity.GetIdentHash ());
- if (ls)
- {
- uint8_t staticKey[32];
- ls->Encrypt (nullptr, staticKey);
- if (!memcmp (from->GetRemoteStaticKey (), staticKey, 32))
- verified = true;
- else
- {
- LogPrint (eLogError, "Datagram: Remote LeaseSet static key mismatch for datagram from ",
- identity.GetIdentHash ().ToBase32 ());
- return;
- }
- }
- }
- if (!verified)
- {
- if (identity.GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1)
- {
- uint8_t hash[32];
- SHA256(buf + headerLen, len - headerLen, hash);
- verified = identity.Verify (hash, 32, signature);
- }
- else
- verified = identity.Verify (buf + headerLen, len - headerLen, signature);
- }
+ uint8_t hash[32];
+ SHA256(buf + headerLen, len - headerLen, hash);
+ verified = identity.Verify (hash, 32, signature);
+ }
+ else
+ verified = identity.Verify (buf + headerLen, len - headerLen, signature);
if (verified)
{
auto session = ObtainSession (identity.GetIdentHash());
- if (ls) session->SetRemoteLeaseSet (ls);
session->Ack();
auto r = FindReceiver(toPort);
if(r)
@@ -160,55 +126,6 @@ namespace datagram
LogPrint (eLogWarning, "DatagramDestination: no receiver for raw datagram");
}
- void DatagramDestination::HandleDatagram3 (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len,
- i2p::garlic::ECIESX25519AEADRatchetSession * from)
- {
- if (len < 34)
- {
- LogPrint (eLogWarning, "Datagram: datagram3 is too short ", len);
- return;
- }
- if (from)
- {
- i2p::data::IdentHash ident(buf);
- auto ls = m_Owner->FindLeaseSet (ident);
- if (ls)
- {
- uint8_t staticKey[32];
- ls->Encrypt (nullptr, staticKey);
- if (!memcmp (from->GetRemoteStaticKey (), staticKey, 32))
- {
- auto session = ObtainSession (ident);
- session->SetVersion (eDatagramV3);
- session->SetRemoteLeaseSet (ls);
- session->Ack ();
- auto r = FindReceiver(toPort);
- if (r)
- {
- uint16_t flags = bufbe16toh (buf + 32);
- size_t offset = 34;
- if (flags & DATAGRAM3_FLAG_OPTIONS)
- offset += bufbe16toh (buf + offset) + 2;
- if (offset > len)
- {
- LogPrint (eLogWarning, "Datagram: datagram3 is too short ", len, " expected ", offset);
- return;
- }
- r(*ls->GetIdentity (), fromPort, toPort, buf + offset, len - offset);
- }
- else
- LogPrint (eLogWarning, "Datagram: no receiver for port ", toPort);
- }
- else
- LogPrint (eLogError, "Datagram: Remote LeaseSet static key mismatch for datagram3 from ", ident.ToBase32 ());
- }
- else
- LogPrint (eLogError, "Datagram: No remote LeaseSet for ", ident.ToBase32 ());
- }
- else
- LogPrint (eLogInfo, "Datagram: datagram3 received from non-ratchets session");
- }
-
void DatagramDestination::SetReceiver (const Receiver& receiver, uint16_t port)
{
std::lock_guard lock(m_ReceiversMutex);
@@ -277,31 +194,17 @@ namespace datagram
return r;
}
- void DatagramDestination::HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort,
- const uint8_t * buf, size_t len, uint8_t protocolType, i2p::garlic::ECIESX25519AEADRatchetSession * from)
+ void DatagramDestination::HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw)
{
// unzip it
uint8_t uncompressed[MAX_DATAGRAM_SIZE];
size_t uncompressedLen = m_Inflator.Inflate (buf, len, uncompressed, MAX_DATAGRAM_SIZE);
if (uncompressedLen)
{
- switch (protocolType)
- {
- case i2p::client::PROTOCOL_TYPE_RAW:
- HandleRawDatagram (fromPort, toPort, uncompressed, uncompressedLen);
- break;
- case i2p::client::PROTOCOL_TYPE_DATAGRAM3:
- HandleDatagram3 (fromPort, toPort, uncompressed, uncompressedLen, from);
- break;
- case i2p::client::PROTOCOL_TYPE_DATAGRAM:
- HandleDatagram (fromPort, toPort, uncompressed, uncompressedLen, from);
- break;
- case i2p::client::PROTOCOL_TYPE_DATAGRAM2:
- // TODO:
- break;
- default:
- LogPrint (eLogInfo, "Datagram: unknown protocol type ", protocolType);
- };
+ if (isRaw)
+ HandleRawDatagram (fromPort, toPort, uncompressed, uncompressedLen);
+ else
+ HandleDatagram (fromPort, toPort, uncompressed, uncompressedLen);
}
else
LogPrint (eLogWarning, "Datagram: decompression failed");
@@ -309,7 +212,7 @@ namespace datagram
std::shared_ptr DatagramDestination::CreateDataMessage (
const std::vector >& payloads,
- uint16_t fromPort, uint16_t toPort, uint8_t protocolType, bool checksum)
+ uint16_t fromPort, uint16_t toPort, bool isRaw, bool checksum)
{
size_t size;
auto msg = m_I2NPMsgsPool.AcquireShared ();
@@ -325,8 +228,8 @@ namespace datagram
{
htobe32buf (msg->GetPayload (), size); // length
htobe16buf (buf + 4, fromPort); // source port
- htobe16buf (buf + 6, toPort); // destination port
- buf[9] = protocolType; // raw or datagram protocol
+ htobe16buf (buf + 6, toPort); // destination port
+ buf[9] = isRaw ? i2p::client::PROTOCOL_TYPE_RAW : i2p::client::PROTOCOL_TYPE_DATAGRAM; // raw or datagram protocol
msg->len += size + 4;
msg->FillI2NPMessageHeader (eI2NPData, 0, checksum);
}
@@ -385,7 +288,8 @@ namespace datagram
DatagramSession::DatagramSession(std::shared_ptr localDestination,
const i2p::data::IdentHash & remoteIdent) :
m_LocalDestination(localDestination), m_RemoteIdent(remoteIdent),
- m_LastUse (0), m_LastFlush (0), m_RequestingLS (false), m_Version (eDatagramV1)
+ m_LastUse (0), m_LastFlush (0),
+ m_RequestingLS(false)
{
}
diff --git a/libi2pd/Datagram.h b/libi2pd/Datagram.h
index 4ff2ef00..dd358434 100644
--- a/libi2pd/Datagram.h
+++ b/libi2pd/Datagram.h
@@ -20,7 +20,6 @@
#include "LeaseSet.h"
#include "I2NPProtocol.h"
#include "Garlic.h"
-#include "ECIESX25519AEADRatchetSession.h"
namespace i2p
{
@@ -45,15 +44,6 @@ namespace datagram
const uint64_t DATAGRAM_MAX_FLUSH_INTERVAL = 5; // in milliseconds
const int DATAGRAM_SESSION_ACK_REQUEST_INTERVAL = 5500; // in milliseconds
- enum DatagramVersion
- {
- eDatagramV1 = 1,
- eDatagramV2 = 2,
- eDatagramV3 = 3,
- };
-
- constexpr uint16_t DATAGRAM3_FLAG_OPTIONS = 0x10;
-
class DatagramSession : public std::enable_shared_from_this
{
@@ -74,12 +64,8 @@ namespace datagram
/** get the last time in milliseconds for when we used this datagram session */
uint64_t LastActivity() const { return m_LastUse; }
- bool IsRatchets () const { return m_RoutingSession && m_RoutingSession->IsRatchets (); }
- void SetRemoteLeaseSet (std::shared_ptr ls) { m_RemoteLeaseSet = ls; }
+ bool IsRatchets () const { return m_RoutingSession && m_RoutingSession->IsRatchets (); }
- DatagramVersion GetVersion () const { return m_Version; }
- void SetVersion (DatagramVersion version) { m_Version = version; }
-
struct Info
{
std::shared_ptr IBGW;
@@ -114,7 +100,6 @@ namespace datagram
std::vector > m_SendQueue;
uint64_t m_LastUse, m_LastFlush; // milliseconds
bool m_RequestingLS;
- DatagramVersion m_Version;
};
typedef std::shared_ptr DatagramSession_ptr;
@@ -139,8 +124,8 @@ namespace datagram
void SendRawDatagram (std::shared_ptr session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort);
void FlushSendQueue (std::shared_ptr session);
- void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort,
- const uint8_t * buf, size_t len, uint8_t protocolType, i2p::garlic::ECIESX25519AEADRatchetSession * from);
+ void HandleDataMessagePayload (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len, bool isRaw = false);
+
void SetReceiver (const Receiver& receiver, uint16_t port);
void ResetReceiver (uint16_t port);
@@ -158,13 +143,10 @@ namespace datagram
std::shared_ptr ObtainSession(const i2p::data::IdentHash & ident);
std::shared_ptr CreateDataMessage (const std::vector >& payloads,
- uint16_t fromPort, uint16_t toPort, uint8_t protocolType, bool checksum = true);
+ uint16_t fromPort, uint16_t toPort, bool isRaw = false, bool checksum = true);
- void HandleDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len,
- i2p::garlic::ECIESX25519AEADRatchetSession * from);
+ void HandleDatagram (uint16_t fromPort, uint16_t toPort, uint8_t *const& buf, size_t len);
void HandleRawDatagram (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
- void HandleDatagram3 (uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len,
- i2p::garlic::ECIESX25519AEADRatchetSession * from);
Receiver FindReceiver(uint16_t port);
RawReceiver FindRawReceiver(uint16_t port);
diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp
index 394435c5..b243ba0a 100644
--- a/libi2pd/Destination.cpp
+++ b/libi2pd/Destination.cpp
@@ -388,7 +388,7 @@ namespace client
switch (typeID)
{
case eI2NPData:
- HandleDataMessage (payload, len, from);
+ HandleDataMessage (payload, len);
break;
case eI2NPDeliveryStatus:
HandleDeliveryStatusMessage (bufbe32toh (payload + DELIVERY_STATUS_MSGID_OFFSET));
@@ -450,7 +450,7 @@ namespace client
leaseSet = it->second;
if (leaseSet->IsNewer (buf + offset, len - offset))
{
- leaseSet->Update (buf + offset, len - offset, shared_from_this(), true);
+ leaseSet->Update (buf + offset, len - offset);
if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key && !leaseSet->IsExpired ())
LogPrint (eLogDebug, "Destination: Remote LeaseSet updated");
else
@@ -471,8 +471,7 @@ namespace client
else
{
leaseSet = std::make_shared (buf[DATABASE_STORE_TYPE_OFFSET],
- buf + offset, len - offset, true, shared_from_this (),
- from ? from->GetRemoteStaticKeyType () : GetPreferredCryptoType () ); // LeaseSet2
+ buf + offset, len - offset, true, from ? from->GetRemoteStaticKeyType () : GetPreferredCryptoType () ); // LeaseSet2
if (from)
{
uint8_t pub[32];
@@ -489,9 +488,7 @@ namespace client
if (leaseSet->GetIdentHash () != GetIdentHash ())
{
LogPrint (eLogDebug, "Destination: New remote LeaseSet added");
- m_RemoteLeaseSets.insert_or_assign (key, leaseSet);
- if (from)
- from->SetDestination (key);
+ m_RemoteLeaseSets[key] = leaseSet;
}
else
LogPrint (eLogDebug, "Destination: Own remote LeaseSet dropped");
@@ -514,8 +511,8 @@ namespace client
if (request->requestedBlindedKey)
{
auto ls2 = std::make_shared (buf + offset, len - offset,
- request->requestedBlindedKey, shared_from_this (),
- m_LeaseSetPrivKey ? ((const uint8_t *)*m_LeaseSetPrivKey) : nullptr, GetPreferredCryptoType ());
+ request->requestedBlindedKey, m_LeaseSetPrivKey ? ((const uint8_t *)*m_LeaseSetPrivKey) : nullptr,
+ GetPreferredCryptoType ());
if (ls2->IsValid () && !ls2->IsExpired ())
{
leaseSet = ls2;
@@ -1160,8 +1157,7 @@ namespace client
LogPrint(eLogDebug, "Destination: -> Stopping done");
}
- void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len,
- i2p::garlic::ECIESX25519AEADRatchetSession * from)
+ void ClientDestination::HandleDataMessage (const uint8_t * buf, size_t len)
{
uint32_t length = bufbe32toh (buf);
if(length > len - 4)
@@ -1186,21 +1182,25 @@ namespace client
m_LastPort = toPort;
}
if (m_LastStreamingDestination)
- m_LastStreamingDestination->HandleDataMessagePayload (buf, length, from);
+ m_LastStreamingDestination->HandleDataMessagePayload (buf, length);
else
LogPrint (eLogError, "Destination: Missing streaming destination");
}
break;
case PROTOCOL_TYPE_DATAGRAM:
- case PROTOCOL_TYPE_RAW:
- case PROTOCOL_TYPE_DATAGRAM2:
- case PROTOCOL_TYPE_DATAGRAM3:
// datagram protocol
if (m_DatagramDestination)
- m_DatagramDestination->HandleDataMessagePayload (fromPort, toPort, buf, length, buf[9], from);
+ m_DatagramDestination->HandleDataMessagePayload (fromPort, toPort, buf, length);
else
LogPrint (eLogError, "Destination: Missing datagram destination");
break;
+ case PROTOCOL_TYPE_RAW:
+ // raw datagram
+ if (m_DatagramDestination)
+ m_DatagramDestination->HandleDataMessagePayload (fromPort, toPort, buf, length, true);
+ else
+ LogPrint (eLogError, "Destination: Missing raw datagram destination");
+ break;
default:
LogPrint (eLogError, "Destination: Data: Unexpected protocol ", buf[9]);
}
diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h
index 717f35ce..35557859 100644
--- a/libi2pd/Destination.h
+++ b/libi2pd/Destination.h
@@ -37,8 +37,6 @@ namespace client
const uint8_t PROTOCOL_TYPE_STREAMING = 6;
const uint8_t PROTOCOL_TYPE_DATAGRAM = 17;
const uint8_t PROTOCOL_TYPE_RAW = 18;
- const uint8_t PROTOCOL_TYPE_DATAGRAM2 = 19;
- const uint8_t PROTOCOL_TYPE_DATAGRAM3 = 20;
const int PUBLISH_CONFIRMATION_TIMEOUT = 1800; // in milliseconds
const int PUBLISH_VERIFICATION_TIMEOUT = 5; // in seconds after successful publish
const int PUBLISH_VERIFICATION_TIMEOUT_VARIANCE = 3; // in seconds
@@ -176,7 +174,7 @@ namespace client
virtual void CleanupDestination () {}; // additional clean up in derived classes
virtual i2p::data::CryptoKeyType GetPreferredCryptoType () const = 0;
// I2CP
- virtual void HandleDataMessage (const uint8_t * buf, size_t len, i2p::garlic::ECIESX25519AEADRatchetSession * from) = 0;
+ virtual void HandleDataMessage (const uint8_t * buf, size_t len) = 0;
virtual void CreateNewLeaseSet (const std::vector >& tunnels) = 0;
private:
@@ -290,7 +288,7 @@ namespace client
void CleanupDestination () override;
i2p::data::CryptoKeyType GetPreferredCryptoType () const override { return m_PreferredCryptoType; }
// I2CP
- void HandleDataMessage (const uint8_t * buf, size_t len, i2p::garlic::ECIESX25519AEADRatchetSession * from) override;
+ void HandleDataMessage (const uint8_t * buf, size_t len) override;
void CreateNewLeaseSet (const std::vector >& tunnels) override;
private:
diff --git a/libi2pd/Ed25519.cpp b/libi2pd/Ed25519.cpp
index 55d7711d..47edb755 100644
--- a/libi2pd/Ed25519.cpp
+++ b/libi2pd/Ed25519.cpp
@@ -1,12 +1,12 @@
/*
-* Copyright (c) 2013-2025, 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
+#include
#include "Log.h"
#include "Crypto.h"
#include "Ed25519.h"
@@ -134,27 +134,22 @@ namespace crypto
{
BN_CTX * bnCtx = BN_CTX_new ();
// calculate r
- EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
- EVP_DigestInit_ex (ctx, EVP_sha512(), NULL);
- EVP_DigestUpdate (ctx, expandedPrivateKey + EDDSA25519_PRIVATE_KEY_LENGTH, EDDSA25519_PRIVATE_KEY_LENGTH); // right half of expanded key
- EVP_DigestUpdate (ctx, buf, len); // data
+ SHA512_CTX ctx;
+ SHA512_Init (&ctx);
+ SHA512_Update (&ctx, expandedPrivateKey + EDDSA25519_PRIVATE_KEY_LENGTH, EDDSA25519_PRIVATE_KEY_LENGTH); // right half of expanded key
+ SHA512_Update (&ctx, buf, len); // data
uint8_t digest[64];
- unsigned int dl = 64;
- EVP_DigestFinal_ex (ctx, digest, &dl);
- EVP_MD_CTX_destroy (ctx);
+ SHA512_Final (digest, &ctx);
BIGNUM * r = DecodeBN<32> (digest); // DecodeBN<64> (digest); // for test vectors
// calculate R
uint8_t R[EDDSA25519_SIGNATURE_LENGTH/2]; // we must use separate buffer because signature might be inside buf
EncodePoint (Normalize (MulB (digest, bnCtx), bnCtx), R); // EncodePoint (Mul (B, r, bnCtx), R); // for test vectors
// calculate S
- ctx = EVP_MD_CTX_create ();
- EVP_DigestInit_ex (ctx, EVP_sha512(), NULL);
- EVP_DigestUpdate (ctx, R, EDDSA25519_SIGNATURE_LENGTH/2); // R
- EVP_DigestUpdate (ctx, publicKeyEncoded, EDDSA25519_PUBLIC_KEY_LENGTH); // public key
- EVP_DigestUpdate (ctx, buf, len); // data
- dl = 64;
- EVP_DigestFinal_ex (ctx, digest, &dl);
- EVP_MD_CTX_destroy (ctx);
+ SHA512_Init (&ctx);
+ SHA512_Update (&ctx, R, EDDSA25519_SIGNATURE_LENGTH/2); // R
+ SHA512_Update (&ctx, publicKeyEncoded, EDDSA25519_PUBLIC_KEY_LENGTH); // public key
+ SHA512_Update (&ctx, buf, len); // data
+ SHA512_Final (digest, &ctx);
BIGNUM * h = DecodeBN<64> (digest);
// S = (r + h*a) % l
BIGNUM * a = DecodeBN (expandedPrivateKey); // left half of expanded key
@@ -174,15 +169,13 @@ namespace crypto
uint8_t T[80];
RAND_bytes (T, 80);
// calculate r = H*(T || publickey || data)
- EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
- EVP_DigestInit_ex (ctx, EVP_sha512(), NULL);
- EVP_DigestUpdate (ctx, T, 80);
- EVP_DigestUpdate (ctx, publicKeyEncoded, 32);
- EVP_DigestUpdate (ctx, buf, len); // data
+ SHA512_CTX ctx;
+ SHA512_Init (&ctx);
+ SHA512_Update (&ctx, T, 80);
+ SHA512_Update (&ctx, publicKeyEncoded, 32);
+ SHA512_Update (&ctx, buf, len); // data
uint8_t digest[64];
- unsigned int dl = 64;
- EVP_DigestFinal_ex (ctx, digest, &dl);
- EVP_MD_CTX_destroy (ctx);
+ SHA512_Final (digest, &ctx);
BIGNUM * r = DecodeBN<64> (digest);
BN_mod (r, r, l, bnCtx); // % l
EncodeBN (r, digest, 32);
@@ -190,14 +183,11 @@ namespace crypto
uint8_t R[EDDSA25519_SIGNATURE_LENGTH/2]; // we must use separate buffer because signature might be inside buf
EncodePoint (Normalize (MulB (digest, bnCtx), bnCtx), R);
// calculate S
- ctx = EVP_MD_CTX_create ();
- EVP_DigestInit_ex (ctx, EVP_sha512(), NULL);
- EVP_DigestUpdate (ctx, R, EDDSA25519_SIGNATURE_LENGTH/2); // R
- EVP_DigestUpdate (ctx, publicKeyEncoded, EDDSA25519_PUBLIC_KEY_LENGTH); // public key
- EVP_DigestUpdate (ctx, buf, len); // data
- dl = 64;
- EVP_DigestFinal_ex (ctx, digest, &dl);
- EVP_MD_CTX_destroy (ctx);
+ SHA512_Init (&ctx);
+ SHA512_Update (&ctx, R, EDDSA25519_SIGNATURE_LENGTH/2); // R
+ SHA512_Update (&ctx, publicKeyEncoded, EDDSA25519_PUBLIC_KEY_LENGTH); // public key
+ SHA512_Update (&ctx, buf, len); // data
+ SHA512_Final (digest, &ctx);
BIGNUM * h = DecodeBN<64> (digest);
// S = (r + h*a) % l
BIGNUM * a = DecodeBN (privateKey);
diff --git a/libi2pd/Family.cpp b/libi2pd/Family.cpp
index 3a4e8890..300a50ab 100644
--- a/libi2pd/Family.cpp
+++ b/libi2pd/Family.cpp
@@ -51,24 +51,11 @@ namespace data
auto pkey = X509_get_pubkey (cert);
if (pkey)
{
- int curve = 0;
-#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0
- char groupName[20];
- if (EVP_PKEY_get_group_name(pkey, groupName, sizeof(groupName), NULL) == 1)
- curve = OBJ_txt2nid (groupName);
- else
- curve = -1;
-#endif
- if (!curve || curve == NID_X9_62_prime256v1)
- {
- if (!m_SigningKeys.emplace (cn, std::make_pair(pkey, (int)m_SigningKeys.size () + 1)).second)
- {
- EVP_PKEY_free (pkey);
- LogPrint (eLogError, "Family: Duplicated family name ", cn);
- }
- }
- else
- LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
+ if (!m_SigningKeys.emplace (cn, std::make_pair(pkey, (int)m_SigningKeys.size () + 1)).second)
+ {
+ EVP_PKEY_free (pkey);
+ LogPrint (eLogError, "Family: Duplicated family name ", cn);
+ }
}
}
}
@@ -119,17 +106,11 @@ namespace data
memcpy (buf + len, (const uint8_t *)ident, 32);
len += 32;
auto signatureBufLen = Base64ToByteStream (signature, signatureBuf, 64);
- if (signatureBufLen == 64)
+ if (signatureBufLen)
{
- ECDSA_SIG * sig = ECDSA_SIG_new();
- ECDSA_SIG_set0 (sig, BN_bin2bn (signatureBuf, 32, NULL), BN_bin2bn (signatureBuf + 32, 32, NULL));
- uint8_t sign[72];
- uint8_t * s = sign;
- auto l = i2d_ECDSA_SIG (sig, &s);
- ECDSA_SIG_free(sig);
EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
- EVP_DigestVerifyInit (ctx, NULL, EVP_sha256(), NULL, it->second.first);
- auto ret = EVP_DigestVerify (ctx, sign, l, buf, len) == 1;
+ 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;
}
@@ -156,40 +137,29 @@ namespace data
{
SSL * ssl = SSL_new (ctx);
EVP_PKEY * pkey = SSL_get_privatekey (ssl);
- int curve = 0;
-#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0
- char groupName[20];
- if (EVP_PKEY_get_group_name(pkey, groupName, sizeof(groupName), NULL) == 1)
- curve = OBJ_txt2nid (groupName);
- else
- curve = -1;
-#endif
- if (!curve || curve == NID_X9_62_prime256v1)
+ EC_KEY * ecKey = EVP_PKEY_get1_EC_KEY (pkey);
+ if (ecKey)
{
- uint8_t buf[100], sign[72], signature[64];
- size_t len = family.length ();
- memcpy (buf, family.c_str (), len);
- memcpy (buf + len, (const uint8_t *)ident, 32);
- len += 32;
-
- size_t l = 72;
- EVP_MD_CTX * mdctx = EVP_MD_CTX_create ();
- EVP_DigestSignInit (mdctx, NULL, EVP_sha256(), NULL, pkey);
- EVP_DigestSign (mdctx, sign, &l, buf, len);
- EVP_MD_CTX_destroy (mdctx);
-
- const uint8_t * s1 = sign;
- ECDSA_SIG * sig1 = d2i_ECDSA_SIG (NULL, &s1, l);
- const BIGNUM * r, * s;
- ECDSA_SIG_get0 (sig1, &r, &s);
- i2p::crypto::bn2buf (r, signature, 32);
- i2p::crypto::bn2buf (s, signature + 32, 32);
- ECDSA_SIG_free(sig1);
- sig = ByteStreamToBase64 (signature, 64);
- }
- else
- LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
-
+ 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 signingPrivateKey[32], buf[50], signature[64];
+ i2p::crypto::bn2buf (EC_KEY_get0_private_key (ecKey), signingPrivateKey, 32);
+ i2p::crypto::ECDSAP256Signer signer (signingPrivateKey);
+ size_t len = family.length ();
+ memcpy (buf, family.c_str (), len);
+ memcpy (buf + len, (const uint8_t *)ident, 32);
+ len += 32;
+ signer.Sign (buf, len, signature);
+ sig = ByteStreamToBase64 (signature, 64);
+ }
+ else
+ LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
+ }
+ }
SSL_free (ssl);
}
else
diff --git a/libi2pd/HTTP.cpp b/libi2pd/HTTP.cpp
index 8c7c8491..3cd5c193 100644
--- a/libi2pd/HTTP.cpp
+++ b/libi2pd/HTTP.cpp
@@ -55,7 +55,7 @@ namespace http
static void strsplit(std::string_view line, std::vector &tokens, char delim, std::size_t limit = 0)
{
- size_t count = 1, pos;
+ size_t count = 0, pos;
while ((pos = line.find (delim)) != line.npos)
{
count++;
diff --git a/libi2pd/LeaseSet.cpp b/libi2pd/LeaseSet.cpp
index 3001bdfb..fc0e722d 100644
--- a/libi2pd/LeaseSet.cpp
+++ b/libi2pd/LeaseSet.cpp
@@ -36,7 +36,7 @@ namespace data
ReadFromBuffer ();
}
- void LeaseSet::Update (const uint8_t * buf, size_t len, std::shared_ptr dest, bool verifySignature)
+ void LeaseSet::Update (const uint8_t * buf, size_t len, bool verifySignature)
{
SetBuffer (buf, len);
ReadFromBuffer (false, verifySignature);
@@ -281,29 +281,28 @@ namespace data
LogPrint (eLogError, "LeaseSet2: Actual buffer size ", int(len) , " exceeds full buffer size ", int(m_BufferLen));
}
- LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len,
- bool storeLeases, std::shared_ptr dest, CryptoKeyType preferredCrypto):
+ LeaseSet2::LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases, CryptoKeyType preferredCrypto):
LeaseSet (storeLeases), m_StoreType (storeType), m_EncryptionType (preferredCrypto)
{
SetBuffer (buf, len);
if (storeType == NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
- ReadFromBufferEncrypted (buf, len, nullptr, dest, nullptr);
+ ReadFromBufferEncrypted (buf, len, nullptr, nullptr);
else
- ReadFromBuffer (buf, len, dest);
+ ReadFromBuffer (buf, len);
}
LeaseSet2::LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key,
- std::shared_ptr dest, const uint8_t * secret, CryptoKeyType preferredCrypto):
+ const uint8_t * secret, CryptoKeyType preferredCrypto):
LeaseSet (true), m_StoreType (NETDB_STORE_TYPE_ENCRYPTED_LEASESET2), m_EncryptionType (preferredCrypto)
{
- ReadFromBufferEncrypted (buf, len, key, dest, secret);
+ ReadFromBufferEncrypted (buf, len, key, secret);
}
- void LeaseSet2::Update (const uint8_t * buf, size_t len, std::shared_ptr dest, bool verifySignature)
+ void LeaseSet2::Update (const uint8_t * buf, size_t len, bool verifySignature)
{
SetBuffer (buf, len);
if (GetStoreType () != NETDB_STORE_TYPE_ENCRYPTED_LEASESET2)
- ReadFromBuffer (buf, len, dest, false, verifySignature);
+ ReadFromBuffer (buf, len, false, verifySignature);
// TODO: implement encrypted
}
@@ -313,8 +312,7 @@ namespace data
return ExtractPublishedTimestamp (buf, len, expiration) > m_PublishedTimestamp;
}
- void LeaseSet2::ReadFromBuffer (const uint8_t * buf, size_t len, std::shared_ptr dest,
- bool readIdentity, bool verifySignature)
+ void LeaseSet2::ReadFromBuffer (const uint8_t * buf, size_t len, bool readIdentity, bool verifySignature)
{
// standard LS2 header
std::shared_ptr identity;
@@ -352,7 +350,7 @@ namespace data
switch (m_StoreType)
{
case NETDB_STORE_TYPE_STANDARD_LEASESET2:
- s = ReadStandardLS2TypeSpecificPart (buf + offset, len - offset, dest);
+ s = ReadStandardLS2TypeSpecificPart (buf + offset, len - offset);
break;
case NETDB_STORE_TYPE_META_LEASESET2:
s = ReadMetaLS2TypeSpecificPart (buf + offset, len - offset);
@@ -394,8 +392,7 @@ namespace data
return verified;
}
- size_t LeaseSet2::ReadStandardLS2TypeSpecificPart (const uint8_t * buf, size_t len,
- std::shared_ptr dest)
+ size_t LeaseSet2::ReadStandardLS2TypeSpecificPart (const uint8_t * buf, size_t len)
{
size_t offset = 0;
// properties
@@ -420,8 +417,7 @@ namespace data
if (keyType <= i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) // skip PQ keys if not supported
#endif
{
- if ((keyType == preferredKeyType || !m_Encryptor || keyType > m_EncryptionType) &&
- (!dest || dest->SupportsEncryptionType (keyType)))
+ if (keyType == preferredKeyType || !m_Encryptor || keyType > m_EncryptionType)
{
auto encryptor = i2p::data::IdentityEx::CreateEncryptor (keyType, buf + offset);
if (encryptor)
@@ -502,8 +498,7 @@ namespace data
return offset;
}
- void LeaseSet2::ReadFromBufferEncrypted (const uint8_t * buf, size_t len,
- std::shared_ptr key, std::shared_ptr dest, const uint8_t * secret)
+ void LeaseSet2::ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret)
{
size_t offset = 0;
// blinded key
@@ -606,7 +601,7 @@ namespace data
m_StoreType = innerPlainText[0];
SetBuffer (innerPlainText.data () + 1, lenInnerPlaintext - 1);
// parse and verify Layer 2
- ReadFromBuffer (innerPlainText.data () + 1, lenInnerPlaintext - 1, dest);
+ ReadFromBuffer (innerPlainText.data () + 1, lenInnerPlaintext - 1);
}
else
LogPrint (eLogError, "LeaseSet2: Unexpected LeaseSet type ", (int)innerPlainText[0], " inside encrypted LeaseSet");
diff --git a/libi2pd/LeaseSet.h b/libi2pd/LeaseSet.h
index 46f40cb5..f5197eb5 100644
--- a/libi2pd/LeaseSet.h
+++ b/libi2pd/LeaseSet.h
@@ -76,7 +76,7 @@ namespace data
LeaseSet (const uint8_t * buf, size_t len, bool storeLeases = true);
virtual ~LeaseSet () { delete[] m_EncryptionKey; delete[] m_Buffer; };
- virtual void Update (const uint8_t * buf, size_t len, std::shared_ptr dest, bool verifySignature);
+ virtual void Update (const uint8_t * buf, size_t len, bool verifySignature = true);
virtual bool IsNewer (const uint8_t * buf, size_t len) const;
void PopulateLeases (); // from buffer
@@ -155,35 +155,31 @@ namespace data
public:
LeaseSet2 (uint8_t storeType): LeaseSet (true), m_StoreType (storeType) {}; // for update
- LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true,
- std::shared_ptr dest = nullptr, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ECIES_X25519_AEAD);
- LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key,
- std::shared_ptr dest = nullptr, const uint8_t * secret = nullptr, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // store type 5, called from local netdb only
- uint8_t GetStoreType () const override { return m_StoreType; };
- uint32_t GetPublishedTimestamp () const override { return m_PublishedTimestamp; };
+ LeaseSet2 (uint8_t storeType, const uint8_t * buf, size_t len, bool storeLeases = true, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ECIES_X25519_AEAD);
+ LeaseSet2 (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret = nullptr, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ECIES_X25519_AEAD); // store type 5, called from local netdb only
+ uint8_t GetStoreType () const { return m_StoreType; };
+ uint32_t GetPublishedTimestamp () const { return m_PublishedTimestamp; };
bool IsPublic () const { return m_IsPublic; };
- bool IsPublishedEncrypted () const override { return m_IsPublishedEncrypted; };
- std::shared_ptr GetTransientVerifier () const override { return m_TransientVerifier; };
- void Update (const uint8_t * buf, size_t len, std::shared_ptr dest, bool verifySignature) override;
- bool IsNewer (const uint8_t * buf, size_t len) const override;
+ bool IsPublishedEncrypted () const { return m_IsPublishedEncrypted; };
+ std::shared_ptr GetTransientVerifier () const { return m_TransientVerifier; };
+ void Update (const uint8_t * buf, size_t len, bool verifySignature);
+ bool IsNewer (const uint8_t * buf, size_t len) const;
// implements RoutingDestination
- void Encrypt (const uint8_t * data, uint8_t * encrypted) const override;
- CryptoKeyType GetEncryptionType () const override { return m_EncryptionType; };
+ void Encrypt (const uint8_t * data, uint8_t * encrypted) const;
+ CryptoKeyType GetEncryptionType () const { return m_EncryptionType; };
private:
- void ReadFromBuffer (const uint8_t * buf, size_t len, std::shared_ptr dest,
- bool readIdentity = true, bool verifySignature = true);
- void ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr key,
- std::shared_ptr dest, const uint8_t * secret);
- size_t ReadStandardLS2TypeSpecificPart (const uint8_t * buf, size_t len, std::shared_ptr dest);
+ void ReadFromBuffer (const uint8_t * buf, size_t len, bool readIdentity = true, bool verifySignature = true);
+ void ReadFromBufferEncrypted (const uint8_t * buf, size_t len, std::shared_ptr key, const uint8_t * secret);
+ size_t ReadStandardLS2TypeSpecificPart (const uint8_t * buf, size_t len);
size_t ReadMetaLS2TypeSpecificPart (const uint8_t * buf, size_t len);
template
bool VerifySignature (Verifier& verifier, const uint8_t * buf, size_t len, size_t signatureOffset);
- uint64_t ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const override;
+ uint64_t ExtractExpirationTimestamp (const uint8_t * buf, size_t len) const;
uint64_t ExtractPublishedTimestamp (const uint8_t * buf, size_t len, uint64_t& expiration) const;
size_t ExtractClientAuthData (const uint8_t * buf, size_t len, const uint8_t * secret, const uint8_t * subcredential, uint8_t * authCookie) const; // subcredential is subcredential + timestamp, return length of autData without flag
diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp
index cab40e43..e53738e5 100644
--- a/libi2pd/NetDb.cpp
+++ b/libi2pd/NetDb.cpp
@@ -361,7 +361,7 @@ namespace data
{
if(it->second->GetExpirationTime() < expires)
{
- it->second->Update (buf, len, nullptr, false); // signature is verified already
+ it->second->Update (buf, len, false); // signature is verified already
if (CheckLogLevel (eLogInfo))
LogPrint (eLogInfo, "NetDb: LeaseSet updated: ", ident.ToBase32());
updated = true;
diff --git a/libi2pd/NetDb.hpp b/libi2pd/NetDb.hpp
index 8d17628f..f2a7019b 100644
--- a/libi2pd/NetDb.hpp
+++ b/libi2pd/NetDb.hpp
@@ -41,7 +41,7 @@ namespace data
const int NETDB_MIN_ROUTERS = 90;
const int NETDB_MIN_FLOODFILLS = 5;
const int NETDB_MIN_TRANSPORTS = 10 ; // otherwise assume offline
- const int NETDB_NUM_FLOODFILLS_THRESHOLD = 1500;
+ const int NETDB_NUM_FLOODFILLS_THRESHOLD = 1200;
const int NETDB_NUM_ROUTERS_THRESHOLD = 4*NETDB_NUM_FLOODFILLS_THRESHOLD;
const int NETDB_TUNNEL_CREATION_RATE_THRESHOLD = 10; // in %
const int NETDB_CHECK_FOR_EXPIRATION_UPTIME = 600; // 10 minutes, in seconds
diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp
index 23dae8ff..e58e898b 100644
--- a/libi2pd/Reseed.cpp
+++ b/libi2pd/Reseed.cpp
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2013-2025, The PurpleI2P Project
+* Copyright (c) 2013-2024, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -14,9 +14,6 @@
#include
#include
#include
-#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0
-#include
-#endif
#include
#include "Crypto.h"
@@ -483,31 +480,15 @@ namespace data
if (terminator) terminator[0] = 0;
}
// extract RSA key (we need n only, e = 65537)
- EVP_PKEY * pubKey = X509_get_pubkey (cert);
- const BIGNUM * n = nullptr;
-#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0
- BIGNUM * n1 = BN_new ();
- if (EVP_PKEY_get_bn_param (pubKey, OSSL_PKEY_PARAM_RSA_N, &n1) > 0)
- n = n1;
-#else
- const RSA * key = EVP_PKEY_get0_RSA (pubKey);
- const BIGNUM * e, * d;
+ const RSA * key = EVP_PKEY_get0_RSA (X509_get_pubkey (cert));
+ const BIGNUM * n, * e, * d;
RSA_get0_key(key, &n, &e, &d);
-#endif
- if (n)
- {
- PublicKey value;
- i2p::crypto::bn2buf (n, value, 512);
- if (cn)
- m_SigningKeys[cn] = value;
- else
- LogPrint (eLogError, "Reseed: Can't find CN field in ", filename);
- }
+ PublicKey value;
+ i2p::crypto::bn2buf (n, value, 512);
+ if (cn)
+ m_SigningKeys[cn] = value;
else
- LogPrint (eLogError, "Reseed: Can't extract RSA key from ", filename);
-#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0
- BN_free (n1);
-#endif
+ LogPrint (eLogError, "Reseed: Can't find CN field in ", filename);
}
SSL_free (ssl);
}
diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp
index 4540b4d2..fc2355a5 100644
--- a/libi2pd/SSU2.cpp
+++ b/libi2pd/SSU2.cpp
@@ -25,8 +25,7 @@ namespace transport
m_TerminationTimer (GetService ()), m_CleanupTimer (GetService ()), m_ResendTimer (GetService ()),
m_IntroducersUpdateTimer (GetService ()), m_IntroducersUpdateTimerV6 (GetService ()),
m_IsPublished (true), m_IsSyncClockFromPeers (true), m_PendingTimeOffset (0),
- m_Rng(i2p::util::GetMonotonicMicroseconds ()%1000000LL), m_IsForcedFirewalled4 (false),
- m_IsForcedFirewalled6 (false), m_IsThroughProxy (false)
+ m_Rng(i2p::util::GetMonotonicMicroseconds ()%1000000LL), m_IsThroughProxy (false)
{
}
@@ -80,7 +79,6 @@ namespace transport
if (address->IsV4 ())
{
found = true;
- i2p::config::GetOption ("ssu2.firewalled4", m_IsForcedFirewalled4);
LogPrint (eLogDebug, "SSU2: Opening IPv4 socket at Start");
OpenSocket (boost::asio::ip::udp::endpoint (m_AddressV4, port));
boost::asio::post (m_ReceiveService.GetService (),
@@ -93,7 +91,6 @@ namespace transport
if (address->IsV6 ())
{
found = true;
- i2p::config::GetOption ("ssu2.firewalled6", m_IsForcedFirewalled6);
LogPrint (eLogDebug, "SSU2: Opening IPv6 socket at Start");
OpenSocket (boost::asio::ip::udp::endpoint (m_AddressV6, port));
boost::asio::post (m_ReceiveService.GetService (),
diff --git a/libi2pd/SSU2.h b/libi2pd/SSU2.h
index b7214480..a8598ce3 100644
--- a/libi2pd/SSU2.h
+++ b/libi2pd/SSU2.h
@@ -79,7 +79,6 @@ namespace transport
bool UsesProxy () const { return m_IsThroughProxy; };
bool IsSupported (const boost::asio::ip::address& addr) const;
uint16_t GetPort (bool v4) const;
- bool IsForcedFirewalled (bool v4) const { return v4 ? m_IsForcedFirewalled4 : m_IsForcedFirewalled6; }
bool IsConnectedRecently (const boost::asio::ip::udp::endpoint& ep, bool max = true);
void AddConnectedRecently (const boost::asio::ip::udp::endpoint& ep, uint64_t ts);
std::mt19937& GetRng () { return m_Rng; }
@@ -209,7 +208,6 @@ namespace transport
i2p::crypto::AEADChaCha20Poly1305Encryptor m_Encryptor;
i2p::crypto::AEADChaCha20Poly1305Decryptor m_Decryptor;
i2p::crypto::ChaCha20Context m_ChaCha20;
- bool m_IsForcedFirewalled4, m_IsForcedFirewalled6;
// proxy
bool m_IsThroughProxy;
diff --git a/libi2pd/SSU2OutOfSession.cpp b/libi2pd/SSU2OutOfSession.cpp
index dc626b16..3760e329 100644
--- a/libi2pd/SSU2OutOfSession.cpp
+++ b/libi2pd/SSU2OutOfSession.cpp
@@ -90,9 +90,6 @@ namespace transport
if (htobe64 (((uint64_t)nonce << 32) | nonce) == GetSourceConnID ())
{
m_PeerTestResendTimer.cancel (); // cancel delayed msg 6 if any
- if (GetServer ().IsForcedFirewalled (GetRemoteEndpoint ().address().is_v4()))
- // we assume that msg 5 was not received if forced firewalled
- return;
m_IsConnectedRecently = GetServer ().IsConnectedRecently (GetRemoteEndpoint ());
if (GetAddress ())
{
diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp
index cad7d484..3e4b451b 100644
--- a/libi2pd/Signature.cpp
+++ b/libi2pd/Signature.cpp
@@ -10,7 +10,6 @@
#include
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0
#include
-#include
#endif
#include "Log.h"
#include "Signature.h"
@@ -42,19 +41,22 @@ namespace crypto
bool DSAVerifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
{
+ // calculate SHA1 digest
+ uint8_t digest[20], sign[48];
+ SHA1 (buf, len, digest);
// signature
DSA_SIG * sig = DSA_SIG_new();
DSA_SIG_set0 (sig, BN_bin2bn (signature, DSA_SIGNATURE_LENGTH/2, NULL), BN_bin2bn (signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2, NULL));
// to DER format
- uint8_t sign[DSA_SIGNATURE_LENGTH + 8];
uint8_t * s = sign;
auto l = i2d_DSA_SIG (sig, &s);
DSA_SIG_free(sig);
// verify
- EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
- EVP_DigestVerifyInit (ctx, NULL, EVP_sha1(), NULL, m_PublicKey);
- auto ret = EVP_DigestVerify (ctx, sign, l, buf, len) == 1;
- EVP_MD_CTX_destroy (ctx);
+ auto ctx = EVP_PKEY_CTX_new (m_PublicKey, NULL);
+ EVP_PKEY_verify_init(ctx);
+ EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha1());
+ bool ret = EVP_PKEY_verify(ctx, sign, l, digest, 20);
+ EVP_PKEY_CTX_free(ctx);
return ret;
}
@@ -73,13 +75,13 @@ namespace crypto
void DSASigner::Sign (const uint8_t * buf, int len, uint8_t * signature) const
{
- uint8_t sign[DSA_SIGNATURE_LENGTH + 8];
- size_t l = DSA_SIGNATURE_LENGTH + 8;
- EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
- EVP_DigestSignInit (ctx, NULL, EVP_sha1(), NULL, m_PrivateKey);
- EVP_DigestSign (ctx, sign, &l, buf, len);
- EVP_MD_CTX_destroy (ctx);
- // decode r and s
+ uint8_t digest[20], sign[48];
+ SHA1 (buf, len, digest);
+ auto ctx = EVP_PKEY_CTX_new (m_PrivateKey, NULL);
+ EVP_PKEY_sign_init(ctx);
+ EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha1());
+ size_t l = 48;
+ EVP_PKEY_sign(ctx, sign, &l, digest, 20);
const uint8_t * s1 = sign;
DSA_SIG * sig = d2i_DSA_SIG (NULL, &s1, l);
const BIGNUM * r, * s;
@@ -87,6 +89,7 @@ namespace crypto
bn2buf (r, signature, DSA_SIGNATURE_LENGTH/2);
bn2buf (s, signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2);
DSA_SIG_free(sig);
+ EVP_PKEY_CTX_free(ctx);
}
void CreateDSARandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
@@ -132,7 +135,7 @@ namespace crypto
DSA_SIG * sig = DSA_SIG_new();
DSA_SIG_set0 (sig, BN_bin2bn (signature, DSA_SIGNATURE_LENGTH/2, NULL), BN_bin2bn (signature + DSA_SIGNATURE_LENGTH/2, DSA_SIGNATURE_LENGTH/2, NULL));
// DSA verification
- int ret = DSA_do_verify (digest, 20, sig, m_PublicKey) == 1;
+ int ret = DSA_do_verify (digest, 20, sig, m_PublicKey);
DSA_SIG_free(sig);
return ret;
}
@@ -171,138 +174,8 @@ namespace crypto
DSA_free (dsa);
}
#endif
-
-#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0
- ECDSAVerifier::ECDSAVerifier (int curve, size_t keyLen, const EVP_MD * hash):
- m_Curve(curve), m_KeyLen (keyLen), m_Hash (hash), m_PublicKey (nullptr)
- {
- }
-
- ECDSAVerifier::~ECDSAVerifier ()
- {
- if (m_PublicKey)
- EVP_PKEY_free (m_PublicKey);
- }
-
- void ECDSAVerifier::SetPublicKey (const uint8_t * signingKey)
- {
- if (m_PublicKey)
- {
- EVP_PKEY_free (m_PublicKey);
- m_PublicKey = nullptr;
- }
- auto plen = GetPublicKeyLen ();
- std::vector pub(plen + 1);
- pub[0] = POINT_CONVERSION_UNCOMPRESSED;
- memcpy (pub.data() + 1, signingKey, plen); // 0x04|x|y
- OSSL_PARAM_BLD * paramBld = OSSL_PARAM_BLD_new ();
- OSSL_PARAM_BLD_push_utf8_string (paramBld, OSSL_PKEY_PARAM_GROUP_NAME, OBJ_nid2ln(m_Curve), 0);
- OSSL_PARAM_BLD_push_octet_string (paramBld, OSSL_PKEY_PARAM_PUB_KEY, pub.data (), pub.size ());
- OSSL_PARAM * params = OSSL_PARAM_BLD_to_param(paramBld);
-
- EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name (NULL, "EC", NULL);
- if (ctx)
- {
- if (EVP_PKEY_fromdata_init (ctx) <= 0 ||
- EVP_PKEY_fromdata (ctx, &m_PublicKey, EVP_PKEY_PUBLIC_KEY, params) <= 0)
- LogPrint (eLogError, "ECDSA can't create PKEY from params");
- EVP_PKEY_CTX_free (ctx);
- }
- else
- LogPrint (eLogError, "ECDSA can't create PKEY context");
-
- OSSL_PARAM_free (params);
- OSSL_PARAM_BLD_free (paramBld);
- }
-
- bool ECDSAVerifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
- {
- // signature
- ECDSA_SIG * sig = ECDSA_SIG_new();
- ECDSA_SIG_set0 (sig, BN_bin2bn (signature, GetSignatureLen ()/2, NULL),
- BN_bin2bn (signature + GetSignatureLen ()/2, GetSignatureLen ()/2, NULL));
- // to DER format
- std::vector sign(GetSignatureLen () + 8);
- uint8_t * s = sign.data ();
- auto l = i2d_ECDSA_SIG (sig, &s);
- ECDSA_SIG_free(sig);
- // verify
- EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
- EVP_DigestVerifyInit (ctx, NULL, m_Hash, NULL, m_PublicKey);
- auto ret = EVP_DigestVerify (ctx, sign.data (), l, buf, len) == 1;
- EVP_MD_CTX_destroy (ctx);
- return ret;
- }
-
- ECDSASigner::ECDSASigner (int curve, size_t keyLen, const EVP_MD * hash, const uint8_t * signingPrivateKey):
- m_KeyLen (keyLen), m_Hash(hash), m_PrivateKey (nullptr)
- {
- BIGNUM * priv = BN_bin2bn (signingPrivateKey, keyLen/2, NULL);
- OSSL_PARAM_BLD * paramBld = OSSL_PARAM_BLD_new ();
- OSSL_PARAM_BLD_push_utf8_string (paramBld, OSSL_PKEY_PARAM_GROUP_NAME, OBJ_nid2ln(curve), 0);
- OSSL_PARAM_BLD_push_BN (paramBld, OSSL_PKEY_PARAM_PRIV_KEY, priv);
- OSSL_PARAM * params = OSSL_PARAM_BLD_to_param(paramBld);
-
- EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name (NULL, "EC", NULL);
- if (ctx)
- {
- if (EVP_PKEY_fromdata_init (ctx) <= 0 ||
- EVP_PKEY_fromdata (ctx, &m_PrivateKey, EVP_PKEY_KEYPAIR, params) <= 0)
- LogPrint (eLogError, "ECDSA can't create PKEY from params");
- EVP_PKEY_CTX_free (ctx);
- }
- else
- LogPrint (eLogError, "ECDSA can't create PKEY context");
-
- OSSL_PARAM_free (params);
- OSSL_PARAM_BLD_free (paramBld);
- BN_free (priv);
- }
-
- ECDSASigner::~ECDSASigner ()
- {
- if (m_PrivateKey)
- EVP_PKEY_free (m_PrivateKey);
- }
-
- void ECDSASigner::Sign (const uint8_t * buf, int len, uint8_t * signature) const
- {
- std::vector sign(m_KeyLen + 8);
- size_t l = sign.size ();
- EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
- EVP_DigestSignInit (ctx, NULL, m_Hash, NULL, m_PrivateKey);
- EVP_DigestSign (ctx, sign.data(), &l, buf, len);
- EVP_MD_CTX_destroy (ctx);
- // decode r and s
- const uint8_t * s1 = sign.data ();
- ECDSA_SIG * sig = d2i_ECDSA_SIG (NULL, &s1, l);
- const BIGNUM * r, * s;
- ECDSA_SIG_get0 (sig, &r, &s);
- bn2buf (r, signature, m_KeyLen/2);
- bn2buf (s, signature + m_KeyLen/2, m_KeyLen/2);
- ECDSA_SIG_free(sig);
- }
-
- void CreateECDSARandomKeys (int curve, size_t keyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
- {
- EVP_PKEY * pkey = EVP_EC_gen (OBJ_nid2ln(curve));
- // private
- BIGNUM * priv = BN_new ();
- EVP_PKEY_get_bn_param (pkey, OSSL_PKEY_PARAM_PRIV_KEY, &priv);
- bn2buf (priv, signingPrivateKey, keyLen/2);
- BN_free (priv);
- // public
- BIGNUM * x = BN_new (), * y = BN_new ();
- EVP_PKEY_get_bn_param (pkey, OSSL_PKEY_PARAM_EC_PUB_X, &x);
- EVP_PKEY_get_bn_param (pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &y);
- bn2buf (x, signingPublicKey, keyLen/2);
- bn2buf (y, signingPublicKey + keyLen/2, keyLen/2);
- BN_free (x); BN_free (y);
- EVP_PKEY_free (pkey);
- }
-
-#endif
-
+
+#if OPENSSL_EDDSA
EDDSA25519Verifier::EDDSA25519Verifier ():
m_Pkey (nullptr)
{
@@ -325,7 +198,7 @@ namespace crypto
{
EVP_MD_CTX * ctx = EVP_MD_CTX_create ();
EVP_DigestVerifyInit (ctx, NULL, NULL, NULL, m_Pkey);
- auto ret = EVP_DigestVerify (ctx, signature, 64, buf, len) == 1;
+ auto ret = EVP_DigestVerify (ctx, signature, 64, buf, len);
EVP_MD_CTX_destroy (ctx);
return ret;
}
@@ -334,6 +207,37 @@ namespace crypto
return false;
}
+#else
+ EDDSA25519Verifier::EDDSA25519Verifier ()
+ {
+ }
+
+ EDDSA25519Verifier::~EDDSA25519Verifier ()
+ {
+ }
+
+ void EDDSA25519Verifier::SetPublicKey (const uint8_t * signingKey)
+ {
+ memcpy (m_PublicKeyEncoded, signingKey, EDDSA25519_PUBLIC_KEY_LENGTH);
+ BN_CTX * ctx = BN_CTX_new ();
+ m_PublicKey = GetEd25519 ()->DecodePublicKey (m_PublicKeyEncoded, ctx);
+ BN_CTX_free (ctx);
+ }
+
+ bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const
+ {
+ uint8_t digest[64];
+ SHA512_CTX ctx;
+ SHA512_Init (&ctx);
+ SHA512_Update (&ctx, signature, EDDSA25519_SIGNATURE_LENGTH/2); // R
+ SHA512_Update (&ctx, m_PublicKeyEncoded, EDDSA25519_PUBLIC_KEY_LENGTH); // public key
+ SHA512_Update (&ctx, buf, len); // data
+ SHA512_Final (digest, &ctx);
+
+ return GetEd25519 ()->Verify (m_PublicKey, digest, signature);
+ }
+#endif
+
EDDSA25519SignerCompat::EDDSA25519SignerCompat (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey)
{
// expand key
@@ -363,6 +267,7 @@ namespace crypto
GetEd25519 ()->Sign (m_ExpandedPrivateKey, m_PublicKeyEncoded, buf, len, signature);
}
+#if OPENSSL_EDDSA
EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey):
m_Pkey (nullptr), m_Fallback (nullptr)
{
@@ -404,6 +309,7 @@ namespace crypto
else
LogPrint (eLogError, "EdDSA signing key is not set");
}
+#endif
#if (OPENSSL_VERSION_NUMBER >= 0x030000000)
static const OSSL_PARAM EDDSA25519phParams[] =
@@ -509,7 +415,7 @@ namespace crypto
OSSL_PARAM_END
};
EVP_PKEY_verify_message_init (vctx, sig, params);
- ret = EVP_PKEY_verify (vctx, signature, GetSignatureLen (), buf, len) == 1;
+ ret = EVP_PKEY_verify (vctx, signature, GetSignatureLen (), buf, len);
EVP_SIGNATURE_free (sig);
}
EVP_PKEY_CTX_free (vctx);
diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h
index 43f706bd..20c7e11b 100644
--- a/libi2pd/Signature.h
+++ b/libi2pd/Signature.h
@@ -91,116 +91,7 @@ namespace crypto
void CreateDSARandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey);
- // ECDSA
- constexpr size_t ECDSAP256_KEY_LENGTH = 64;
- constexpr size_t ECDSAP384_KEY_LENGTH = 96;
- constexpr size_t ECDSAP521_KEY_LENGTH = 132;
-
-#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0
- class ECDSAVerifier: public Verifier
- {
- public:
-
- ECDSAVerifier (int curve, size_t keyLen, const EVP_MD * hash);
- ~ECDSAVerifier ();
-
- void SetPublicKey (const uint8_t * signingKey);
- bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const;
-
- size_t GetPublicKeyLen () const { return m_KeyLen; };
- size_t GetSignatureLen () const { return m_KeyLen; }; // signature length = key length
-
- private:
-
- int m_Curve;
- size_t m_KeyLen;
- const EVP_MD * m_Hash;
- EVP_PKEY * m_PublicKey;
- };
-
- class ECDSASigner: public Signer
- {
- public:
-
- ECDSASigner (int curve, size_t keyLen, const EVP_MD * hash, const uint8_t * signingPrivateKey);
- ~ECDSASigner ();
-
- void Sign (const uint8_t * buf, int len, uint8_t * signature) const;
-
- private:
-
- size_t m_KeyLen;
- const EVP_MD * m_Hash;
- EVP_PKEY * m_PrivateKey;
- };
-
- void CreateECDSARandomKeys (int curve, size_t keyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey);
-
-// ECDSA_SHA256_P256
- class ECDSAP256Verifier: public ECDSAVerifier
- {
- public:
-
- ECDSAP256Verifier (): ECDSAVerifier (NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH, EVP_sha256()) {};
- };
-
- class ECDSAP256Signer: public ECDSASigner
- {
- public:
-
- ECDSAP256Signer (const uint8_t * signingPrivateKey):
- ECDSASigner (NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH, EVP_sha256(), signingPrivateKey) {};
- };
-
- inline void CreateECDSAP256RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
- {
- CreateECDSARandomKeys (NID_X9_62_prime256v1, ECDSAP256_KEY_LENGTH, signingPrivateKey, signingPublicKey);
- }
-
-// ECDSA_SHA384_P384
- class ECDSAP384Verifier: public ECDSAVerifier
- {
- public:
-
- ECDSAP384Verifier (): ECDSAVerifier (NID_secp384r1, ECDSAP384_KEY_LENGTH, EVP_sha384()) {};
- };
-
- class ECDSAP384Signer: public ECDSASigner
- {
- public:
-
- ECDSAP384Signer (const uint8_t * signingPrivateKey):
- ECDSASigner (NID_secp384r1, ECDSAP384_KEY_LENGTH, EVP_sha384(), signingPrivateKey) {};
- };
-
- inline void CreateECDSAP384RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
- {
- CreateECDSARandomKeys (NID_secp384r1, ECDSAP384_KEY_LENGTH, signingPrivateKey, signingPublicKey);
- }
-
-// ECDSA_SHA512_P521
- class ECDSAP521Verifier: public ECDSAVerifier
- {
- public:
-
- ECDSAP521Verifier (): ECDSAVerifier (NID_secp521r1, ECDSAP521_KEY_LENGTH, EVP_sha512()) {};
- };
-
- class ECDSAP521Signer: public ECDSASigner
- {
- public:
-
- ECDSAP521Signer (const uint8_t * signingPrivateKey):
- ECDSASigner (NID_secp521r1, ECDSAP521_KEY_LENGTH, EVP_sha512(), signingPrivateKey) {};
- };
-
- inline void CreateECDSAP521RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey)
- {
- CreateECDSARandomKeys (NID_secp521r1, ECDSAP521_KEY_LENGTH, signingPrivateKey, signingPublicKey);
- }
-
-#else
-
+ // ECDSA
struct SHA256Hash
{
static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest)
@@ -263,7 +154,7 @@ namespace crypto
auto s = BN_bin2bn (signature + GetSignatureLen ()/2, GetSignatureLen ()/2, NULL);
ECDSA_SIG_set0(sig, r, s);
// ECDSA verification
- int ret = ECDSA_do_verify (digest, Hash::hashLen, sig, m_PublicKey) == 1;
+ int ret = ECDSA_do_verify (digest, Hash::hashLen, sig, m_PublicKey);
ECDSA_SIG_free(sig);
return ret;
}
@@ -326,6 +217,7 @@ namespace crypto
}
// ECDSA_SHA256_P256
+ const size_t ECDSAP256_KEY_LENGTH = 64;
typedef ECDSAVerifier ECDSAP256Verifier;
typedef ECDSASigner ECDSAP256Signer;
@@ -335,6 +227,7 @@ namespace crypto
}
// ECDSA_SHA384_P384
+ const size_t ECDSAP384_KEY_LENGTH = 96;
typedef ECDSAVerifier ECDSAP384Verifier;
typedef ECDSASigner ECDSAP384Signer;
@@ -344,6 +237,7 @@ namespace crypto
}
// ECDSA_SHA512_P521
+ const size_t ECDSAP521_KEY_LENGTH = 132;
typedef ECDSAVerifier ECDSAP521Verifier;
typedef ECDSASigner ECDSAP521Signer;
@@ -351,8 +245,7 @@ namespace crypto
{
CreateECDSARandomKeys (NID_secp521r1, ECDSAP521_KEY_LENGTH, signingPrivateKey, signingPublicKey);
}
-
-#endif
+
// EdDSA
class EDDSA25519Verifier: public Verifier
@@ -369,12 +262,18 @@ namespace crypto
size_t GetSignatureLen () const { return EDDSA25519_SIGNATURE_LENGTH; };
private:
+
+#if OPENSSL_EDDSA
EVP_PKEY * m_Pkey;
protected:
EVP_PKEY * GetPkey () const { return m_Pkey; };
+#else
+ EDDSAPoint m_PublicKey;
+ uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH];
+#endif
};
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0
@@ -403,6 +302,7 @@ namespace crypto
uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH];
};
+#if OPENSSL_EDDSA
class EDDSA25519Signer: public Signer
{
public:
@@ -422,6 +322,11 @@ namespace crypto
EVP_PKEY * m_Pkey;
EDDSA25519SignerCompat * m_Fallback;
};
+#else
+
+ typedef EDDSA25519SignerCompat EDDSA25519Signer;
+
+#endif
#if (OPENSSL_VERSION_NUMBER >= 0x030000000) // since 3.0.0
class EDDSA25519phSigner: public EDDSA25519Signer
@@ -437,6 +342,7 @@ namespace crypto
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);
@@ -447,6 +353,11 @@ namespace crypto
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);
+ EDDSA25519Signer signer (signingPrivateKey);
+ memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH);
+#endif
}
diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp
index 66c8919d..1f849925 100644
--- a/libi2pd/Streaming.cpp
+++ b/libi2pd/Streaming.cpp
@@ -187,7 +187,7 @@ namespace stream
if (!m_SendStreamID)
{
m_SendStreamID = packet->GetReceiveStreamID ();
- if (!m_RemoteIdentity && !packet->from && packet->GetNACKCount () == 8 && // first incoming packet
+ if (!m_RemoteIdentity && packet->GetNACKCount () == 8 && // first incoming packet
memcmp (packet->GetNACKs (), m_LocalDestination.GetOwner ()->GetIdentHash (), 32))
{
LogPrint (eLogWarning, "Streaming: Destination mismatch for ", m_LocalDestination.GetOwner ()->GetIdentHash ().ToBase32 ());
@@ -397,7 +397,6 @@ namespace stream
optionData += 2;
}
- bool sessionVerified = false;
if (flags & PACKET_FLAG_FROM_INCLUDED)
{
if (m_RemoteLeaseSet) m_RemoteIdentity = m_RemoteLeaseSet->GetIdentity ();
@@ -410,24 +409,7 @@ namespace stream
}
optionData += m_RemoteIdentity->GetFullLen ();
if (!m_RemoteLeaseSet)
- {
- LogPrint (eLogDebug, "Streaming: Incoming stream from ", m_RemoteIdentity->GetIdentHash ().ToBase32 (), ", sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID);
- if (packet->from) // try to obtain LeaseSet if came from ratchets session
- m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());
- }
- if (packet->from && m_RemoteLeaseSet)
- {
- // stream came from ratchets session and static key must match one from LeaseSet
- uint8_t staticKey[32];
- m_RemoteLeaseSet->Encrypt (nullptr, staticKey);
- if (memcmp (packet->from->GetRemoteStaticKey (), staticKey, 32))
- {
- LogPrint (eLogError, "Streaming: Remote LeaseSet static key mismatch for stream from ",
- m_RemoteIdentity->GetIdentHash ().ToBase32 ());
- return false;
- }
- sessionVerified = true;
- }
+ LogPrint (eLogDebug, "Streaming: Incoming stream from ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), ", sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID);
}
if (flags & PACKET_FLAG_MAX_PACKET_SIZE_INCLUDED)
@@ -444,81 +426,60 @@ namespace stream
LogPrint (eLogInfo, "Streaming: offline signature without identity");
return false;
}
- if (sessionVerified)
+ // if we have it in LeaseSet already we don't need to parse it again
+ if (m_RemoteLeaseSet) m_TransientVerifier = m_RemoteLeaseSet->GetTransientVerifier ();
+ if (m_TransientVerifier)
{
- // skip offline signature
- optionData += 4; // timestamp
- uint16_t keyType = bufbe16toh (optionData); optionData += 2; // key type
- std::unique_ptr transientVerifier (i2p::data::IdentityEx::CreateVerifier (keyType));
- if (!transientVerifier)
- {
- LogPrint (eLogInfo, "Streaming: Unknown offline signature key type ", (int)keyType);
- return false;
- }
- optionData += transientVerifier->GetPublicKeyLen (); // public key
+ // skip option data
+ optionData += 6; // timestamp and key type
+ optionData += m_TransientVerifier->GetPublicKeyLen (); // public key
optionData += m_RemoteIdentity->GetSignatureLen (); // signature
}
else
- {
- // if we have it in LeaseSet already we don't need to parse it again
- if (m_RemoteLeaseSet) m_TransientVerifier = m_RemoteLeaseSet->GetTransientVerifier ();
- if (m_TransientVerifier)
+ {
+ // transient key
+ size_t offset = 0;
+ m_TransientVerifier = i2p::data::ProcessOfflineSignature (m_RemoteIdentity, optionData, optionSize - (optionData - packet->GetOptionData ()), offset);
+ optionData += offset;
+ if (!m_TransientVerifier)
{
- // skip option data
- optionData += 6; // timestamp and key type
- optionData += m_TransientVerifier->GetPublicKeyLen (); // public key
- optionData += m_RemoteIdentity->GetSignatureLen (); // signature
+ LogPrint (eLogError, "Streaming: offline signature failed");
+ return false;
}
- else
- {
- // transient key
- size_t offset = 0;
- m_TransientVerifier = i2p::data::ProcessOfflineSignature (m_RemoteIdentity, optionData, optionSize - (optionData - packet->GetOptionData ()), offset);
- optionData += offset;
- if (!m_TransientVerifier)
- {
- LogPrint (eLogError, "Streaming: offline signature failed");
- return false;
- }
- }
- }
+ }
}
if (flags & PACKET_FLAG_SIGNATURE_INCLUDED)
{
+ bool verified = false;
auto signatureLen = m_TransientVerifier ? m_TransientVerifier->GetSignatureLen () : m_RemoteIdentity->GetSignatureLen ();
if (signatureLen > packet->GetLength ())
{
LogPrint (eLogError, "Streaming: Signature too big, ", signatureLen, " bytes");
return false;
}
- bool verified = sessionVerified;
- if (!verified) // packet was not verified through session
- {
- // verify actual signature
- if (signatureLen <= 256)
- {
- // standard
- uint8_t signature[256];
- memcpy (signature, optionData, signatureLen);
- memset (const_cast(optionData), 0, signatureLen);
- verified = m_TransientVerifier ?
- m_TransientVerifier->Verify (packet->GetBuffer (), packet->GetLength (), signature) :
- m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature);
- if (verified)
- memcpy (const_cast(optionData), signature, signatureLen);
- }
- else
- {
- // post quantum
- std::vector signature(signatureLen);
- memcpy (signature.data (), optionData, signatureLen);
- memset (const_cast(optionData), 0, signatureLen);
- verified = m_TransientVerifier ?
- m_TransientVerifier->Verify (packet->GetBuffer (), packet->GetLength (), signature.data ()) :
- m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature.data ());
- }
- }
+ if(signatureLen <= 256)
+ {
+ // standard
+ uint8_t signature[256];
+ memcpy (signature, optionData, signatureLen);
+ memset (const_cast(optionData), 0, signatureLen);
+ verified = m_TransientVerifier ?
+ m_TransientVerifier->Verify (packet->GetBuffer (), packet->GetLength (), signature) :
+ m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature);
+ if (verified)
+ memcpy (const_cast(optionData), signature, signatureLen);
+ }
+ else
+ {
+ // post quantum
+ std::vector signature(signatureLen);
+ memcpy (signature.data (), optionData, signatureLen);
+ memset (const_cast(optionData), 0, signatureLen);
+ verified = m_TransientVerifier ?
+ m_TransientVerifier->Verify (packet->GetBuffer (), packet->GetLength (), signature.data ()) :
+ m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature.data ());
+ }
if (verified)
optionData += signatureLen;
else
@@ -851,7 +812,7 @@ namespace stream
{
// initial packet
m_Status = eStreamStatusOpen;
- if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());
+ if (!m_RemoteLeaseSet) m_RemoteLeaseSet = m_LocalDestination.GetOwner ()->FindLeaseSet (m_RemoteIdentity->GetIdentHash ());;
if (m_RemoteLeaseSet)
{
m_RoutingSession = m_LocalDestination.GetOwner ()->GetRoutingSession (m_RemoteLeaseSet, true, !m_IsIncoming);
@@ -1455,7 +1416,6 @@ namespace stream
m_SendTimer.cancel (); // if no ack's in RTO, disable fast retransmit
m_IsTimeOutResend = true;
m_IsNAcked = false;
- m_IsClientChoked = false;
m_IsResendNeeded = false;
m_NumPacketsToSend = 1;
ResendPacket (); // send one packet per RTO, waiting for ack
@@ -1578,7 +1538,7 @@ namespace stream
}
else if (!m_IsClientChoked)
SendBuffer ();
- if (!m_IsNAcked && !m_IsResendNeeded && !m_IsClientChoked) ScheduleResend ();
+ if (!m_IsNAcked && !m_IsResendNeeded) ScheduleResend ();
if (m_IsClientChoked) ScheduleSend ();
}
@@ -2093,18 +2053,14 @@ namespace stream
}
}
- void StreamingDestination::HandleDataMessagePayload (const uint8_t * buf, size_t len,
- i2p::garlic::ECIESX25519AEADRatchetSession * from)
+ void StreamingDestination::HandleDataMessagePayload (const uint8_t * buf, size_t len)
{
// unzip it
Packet * uncompressed = NewPacket ();
uncompressed->offset = 0;
uncompressed->len = m_Inflator.Inflate (buf, len, uncompressed->buf, MAX_PACKET_SIZE);
if (uncompressed->len)
- {
- uncompressed->from = from;
HandleNextPacket (uncompressed);
- }
else
DeletePacket (uncompressed);
}
diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h
index eae43c0e..9fbcb178 100644
--- a/libi2pd/Streaming.h
+++ b/libi2pd/Streaming.h
@@ -27,7 +27,6 @@
#include "Garlic.h"
#include "Tunnel.h"
#include "util.h" // MemoryPool
-#include "ECIESX25519AEADRatchetSession.h"
namespace i2p
{
@@ -89,9 +88,8 @@ namespace stream
uint8_t buf[MAX_PACKET_SIZE];
uint64_t sendTime;
bool resent;
- i2p::garlic::ECIESX25519AEADRatchetSession * from;
- Packet (): len (0), offset (0), sendTime (0), resent (false), from (nullptr) {};
+ Packet (): len (0), offset (0), sendTime (0), resent (false) {};
uint8_t * GetBuffer () { return buf + offset; };
size_t GetLength () const { return len > offset ? len - offset : 0; };
@@ -342,7 +340,7 @@ namespace stream
void SetOwner (std::shared_ptr owner) { m_Owner = owner; };
uint16_t GetLocalPort () const { return m_LocalPort; };
- void HandleDataMessagePayload (const uint8_t * buf, size_t len, i2p::garlic::ECIESX25519AEADRatchetSession * from);
+ void HandleDataMessagePayload (const uint8_t * buf, size_t len);
std::shared_ptr CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort, bool checksum = true, bool gzip = false);
Packet * NewPacket () { return m_PacketsPool.Acquire(); }
diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp
index 85c58c48..11278e7a 100644
--- a/libi2pd_client/I2CP.cpp
+++ b/libi2pd_client/I2CP.cpp
@@ -86,8 +86,7 @@ namespace client
return i2p::data::CRYPTO_KEY_TYPE_ELGAMAL;
}
- void I2CPDestination::HandleDataMessage (const uint8_t * buf, size_t len,
- i2p::garlic::ECIESX25519AEADRatchetSession * from)
+ void I2CPDestination::HandleDataMessage (const uint8_t * buf, size_t len)
{
uint32_t length = bufbe32toh (buf);
if (length > len - 4) length = len - 4;
@@ -624,14 +623,17 @@ namespace client
void I2CPSession::GetDateMessageHandler (const uint8_t * buf, size_t len)
{
- constexpr std::string_view version(I2P_VERSION);
- std::array payload;
+ // get version
+ auto version = ExtractString (buf, len);
+ auto l = version.length () + 1 + 8;
+ uint8_t * payload = new uint8_t[l];
// set date
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
- htobe64buf (payload.data(), ts);
- // send our version back
- PutString (payload.data() + 8, payload.size() - 8, version);
- SendI2CPMessage (I2CP_SET_DATE_MESSAGE, payload.data(), payload.size());
+ htobe64buf (payload, ts);
+ // echo vesrion back
+ PutString (payload + 8, l - 8, version);
+ SendI2CPMessage (I2CP_SET_DATE_MESSAGE, payload, l);
+ delete[] payload;
}
void I2CPSession::CreateSessionMessageHandler (const uint8_t * buf, size_t len)
diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h
index 0bfa49f2..37c14dbb 100644
--- a/libi2pd_client/I2CP.h
+++ b/libi2pd_client/I2CP.h
@@ -117,7 +117,7 @@ namespace client
void CleanupDestination () override;
i2p::data::CryptoKeyType GetPreferredCryptoType () const override;
// I2CP
- void HandleDataMessage (const uint8_t * buf, size_t len, i2p::garlic::ECIESX25519AEADRatchetSession * from) override;
+ void HandleDataMessage (const uint8_t * buf, size_t len) override;
void CreateNewLeaseSet (const std::vector >& tunnels) override;
private:
diff --git a/tests/test-base-64.cpp b/tests/test-base-64.cpp
index 63817bf4..0ab46c06 100644
--- a/tests/test-base-64.cpp
+++ b/tests/test-base-64.cpp
@@ -11,7 +11,8 @@ int main() {
char out[16];
/* bytes -> b64 */
- assert(ByteStreamToBase64(NULL, 0) == "");
+ assert(ByteStreamToBase64(NULL, 0, NULL, 0) == 0);
+ assert(ByteStreamToBase64(NULL, 0, out, sizeof(out)) == 0);
assert(Base64EncodingBufferSize(2) == 4);
assert(Base64EncodingBufferSize(4) == 8);
@@ -22,20 +23,19 @@ int main() {
assert(Base64EncodingBufferSize(12) == 16);
assert(Base64EncodingBufferSize(13) == 20);
- const std::string out_str(ByteStreamToBase64((uint8_t *) in, in_len));
- assert(out_str.size() == 8);
- assert(out_str == "dGVzdA==");
+ assert(ByteStreamToBase64((uint8_t *) in, in_len, out, sizeof(out)) == 8);
+ assert(memcmp(out, "dGVzdA==", 8) == 0);
/* b64 -> bytes */
- assert(Base64ToByteStream("", NULL, 0) == 0);
- assert(Base64ToByteStream("", (uint8_t *) out, sizeof(out)) == 0);
+ assert(Base64ToByteStream(NULL, 0, NULL, 0) == 0);
+ assert(Base64ToByteStream(NULL, 0, (uint8_t *) out, sizeof(out)) == 0);
in = "dGVzdA=="; /* valid b64 */
- assert(Base64ToByteStream(in, (uint8_t *) out, sizeof(out)) == 4);
+ assert(Base64ToByteStream(in, strlen(in), (uint8_t *) out, sizeof(out)) == 4);
assert(memcmp(out, "test", 4) == 0);
in = "dGVzdA="; /* invalid b64 : not padded */
- assert(Base64ToByteStream(in, (uint8_t *) out, sizeof(out)) == 0);
+ assert(Base64ToByteStream(in, strlen(in), (uint8_t *) out, sizeof(out)) == 0);
in = "dG/z.A=="; /* invalid b64 : char not from alphabet */
// assert(Base64ToByteStream(in, strlen(in), (uint8_t *) out, sizeof(out)) == 0);
diff --git a/tests/test-eddsa.cpp b/tests/test-eddsa.cpp
index 9de2c088..b3895e2b 100644
--- a/tests/test-eddsa.cpp
+++ b/tests/test-eddsa.cpp
@@ -58,7 +58,9 @@ int main ()
uint8_t s[64];
i2p::crypto::EDDSA25519Signer signer (key);
signer.Sign (msg, 1023, s);
+#if OPENSSL_EDDSA
assert(memcmp (s, sig, 64) == 0);
+#endif
i2p::crypto::EDDSA25519Verifier verifier;
verifier.SetPublicKey (pub);