diff --git a/ChangeLog b/ChangeLog index d8ab87de..ca30a1ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,20 @@ # for this file format description, # see https://github.com/olivierlacan/keep-a-changelog +## [2.21.0] - 2018-10-04 +### Added +- EdDSA, x25519 and SipHash from openssl 1.1.1 +- NTCP2 ipv6 incoming connections +- Show total number of destination's outgoing tags in the web console +### Changed +- Android build with openssl 1.1.1/boost 1.64 +- Bandwidth classes 'P' and 'X' don't add 'O' anymore +### Fixed +- Update own RouterInfo if no SSU +- Recognize 'P' and 'X' routers as high bandwidth without 'O' +- NTCP address doesn't disappear if NTCP2 enabled +- Android with api 26+ + ## [2.20.0] - 2018-08-23 ### Added - Full implementation of NTCP2 diff --git a/Win32/installer.iss b/Win32/installer.iss index e340c65f..8372a444 100644 --- a/Win32/installer.iss +++ b/Win32/installer.iss @@ -1,5 +1,5 @@ #define I2Pd_AppName "i2pd" -#define I2Pd_ver "2.20.0" +#define I2Pd_ver "2.21.0" #define I2Pd_Publisher "PurpleI2P" [Setup] diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 9a2cffd5..e5a711aa 100755 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -3,7 +3,7 @@ package="org.purplei2p.i2pd" android:installLocation="auto" android:versionCode="1" - android:versionName="2.20.0"> + android:versionName="2.21.0"> + = Build.VERSION_CODES.O) ? createNotificationChannel() : ""; + // Set the info for the views that show in the notification panel. - Notification notification = new Notification.Builder(this) - .setSmallIcon(R.drawable.itoopie_notification_icon) // the status icon - .setTicker(text) // the status text - .setWhen(System.currentTimeMillis()) // the time stamp - .setContentTitle(getText(R.string.app_name)) // the label of the entry - .setContentText(text) // the contents of the entry - .setContentIntent(contentIntent) // The intent to send when the entry is clicked + Notification notification = new NotificationCompat.Builder(this, channelId) + .setOngoing(true) + .setSmallIcon(R.drawable.itoopie_notification_icon) // the status icon + .setPriority(Notification.PRIORITY_DEFAULT) + .setCategory(Notification.CATEGORY_SERVICE) + .setTicker(text) // the status text + .setWhen(System.currentTimeMillis()) // the time stamp + .setContentTitle(getText(R.string.app_name)) // the label of the entry + .setContentText(text) // the contents of the entry + .setContentIntent(contentIntent) // The intent to send when the entry is clicked .build(); // Send the notification. //mNM.notify(NOTIFICATION, notification); startForeground(NOTIFICATION, notification); - shown=true; + shown = true; + } + + @RequiresApi(Build.VERSION_CODES.O) + private synchronized String createNotificationChannel() { + String channelId = getString(R.string.app_name); + CharSequence channelName = "I2Pd service"; + NotificationChannel chan = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW); + //chan.setLightColor(Color.PURPLE); + chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE); + NotificationManager service = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); + service.createNotificationChannel(chan); + return channelId; } - private static final DaemonSingleton daemon = DaemonSingleton.getInstance(); + private static final DaemonSingleton daemon = DaemonSingleton.getInstance(); } diff --git a/android_binary_only/jni/Android.mk b/android_binary_only/jni/Android.mk index fa677c83..645651a5 100755 --- a/android_binary_only/jni/Android.mk +++ b/android_binary_only/jni/Android.mk @@ -26,43 +26,43 @@ include $(BUILD_EXECUTABLE) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := boost_system -LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include +LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_64_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_64_0/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := boost_date_time -LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include +LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_64_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_64_0/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := boost_filesystem -LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include +LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_64_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_64_0/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := boost_program_options -LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a -LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include +LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_64_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_64_0/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := crypto -LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.0e/$(TARGET_ARCH_ABI)/lib/libcrypto.a -LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.0e/include +LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1/$(TARGET_ARCH_ABI)/lib/libcrypto.a +LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1/include include $(PREBUILT_STATIC_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := ssl -LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.0e/$(TARGET_ARCH_ABI)/lib/libssl.a -LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.0e/include +LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.1/$(TARGET_ARCH_ABI)/lib/libssl.a +LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.1/include LOCAL_STATIC_LIBRARIES := crypto include $(PREBUILT_STATIC_LIBRARY) diff --git a/appveyor.yml b/appveyor.yml index e0c09fc1..bcaad455 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.20.{build} +version: 2.21.{build} pull_requests: do_not_increment_build_number: true branches: @@ -18,9 +18,9 @@ environment: install: - c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc" -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu " +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu --force" -- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu" +- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu --force" - if "%MSYSTEM%" == "MINGW64" ( c:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-boost mingw-w64-x86_64-miniupnpc" diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index edad8228..71bc2b31 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -96,6 +96,9 @@ getent passwd i2pd >/dev/null || \ %changelog +* Thu Oct 4 2018 orignal - 2.21.0 +- update to 2.21.0 + * Thu Aug 23 2018 orignal - 2.20.0 - update to 2.20.0 diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 09b00707..b4c3f79b 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -381,10 +381,12 @@ namespace http { s << "
\r\n"; s << "Tags
Incoming: " << dest->GetNumIncomingTags () << "
"; if (!dest->GetSessions ().empty ()) { - s << "
\r\n\r\n

\r\n"; - for (const auto& it: dest->GetSessions ()) - s << i2p::client::context.GetAddressBook ().ToAddress(it.first) << " " << it.second->GetNumOutgoingTags () << "
\r\n"; - s << "

\r\n
\r\n"; + std::stringstream tmp_s; uint32_t out_tags = 0; + for (const auto& it: dest->GetSessions ()) { + tmp_s << i2p::client::context.GetAddressBook ().ToAddress(it.first) << " " << it.second->GetNumOutgoingTags () << "
\r\n"; + out_tags = out_tags + it.second->GetNumOutgoingTags (); + } + s << "
\r\n\r\n

\r\n" << tmp_s.str () << "

\r\n
\r\n"; } else s << "Outgoing: 0
\r\n"; s << "
\r\n"; diff --git a/debian/changelog b/debian/changelog index 9d721eb8..f16fb10d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +i2pd (2.21.0-1) unstable; urgency=medium + + * updated to version 2.21.0/0.9.37 + + -- orignal Thu, 4 Oct 2018 16:00:00 +0000 + i2pd (2.20.0-1) unstable; urgency=medium * updated to version 2.20.0/0.9.36 diff --git a/libi2pd/Crypto.cpp b/libi2pd/Crypto.cpp index 7a947d34..4393b2cc 100644 --- a/libi2pd/Crypto.cpp +++ b/libi2pd/Crypto.cpp @@ -12,9 +12,8 @@ #if LEGACY_OPENSSL #include "ChaCha20.h" #include "Poly1305.h" -#else -#include #endif +#include "Ed25519.h" #include "I2PEndian.h" #include "Log.h" @@ -278,6 +277,70 @@ namespace crypto BN_free (pk); } +// x25519 + X25519Keys::X25519Keys () + { +#if OPENSSL_X25519 + m_Ctx = EVP_PKEY_CTX_new_id (NID_X25519, NULL); +#else + m_Ctx = BN_CTX_new (); +#endif + } + + X25519Keys::X25519Keys (const uint8_t * priv, const uint8_t * pub) + { +#if OPENSSL_X25519 + m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_X25519, NULL, priv, 32); + m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); + memcpy (m_PublicKey, pub, 32); // TODO: verify against m_Pkey +#else + memcpy (m_PrivateKey, priv, 32); + memcpy (m_PublicKey, pub, 32); + m_Ctx = BN_CTX_new (); +#endif + } + + X25519Keys::~X25519Keys () + { +#if OPENSSL_X25519 + EVP_PKEY_CTX_free (m_Ctx); + if (m_Pkey) + EVP_PKEY_free (m_Pkey); +#else + BN_CTX_free (m_Ctx); +#endif + } + + void X25519Keys::GenerateKeys () + { +#if OPENSSL_X25519 + m_Pkey = nullptr; + EVP_PKEY_keygen_init (m_Ctx); + EVP_PKEY_keygen (m_Ctx, &m_Pkey); + EVP_PKEY_CTX_free (m_Ctx); + m_Ctx = EVP_PKEY_CTX_new (m_Pkey, NULL); // TODO: do we really need to re-create m_Ctx? + size_t len = 32; + EVP_PKEY_get_raw_public_key (m_Pkey, m_PublicKey, &len); +#else + RAND_bytes (m_PrivateKey, 32); + GetEd25519 ()->ScalarMulB (m_PrivateKey, m_PublicKey, m_Ctx); +#endif + } + + void X25519Keys::Agree (const uint8_t * pub, uint8_t * shared) + { +#if OPENSSL_X25519 + EVP_PKEY_derive_init (m_Ctx); + auto pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_X25519, NULL, pub, 32); + EVP_PKEY_derive_set_peer (m_Ctx, pkey); + size_t len = 32; + EVP_PKEY_derive (m_Ctx, shared, &len); + EVP_PKEY_free (pkey); +#else + GetEd25519 ()->ScalarMul (pub, m_PrivateKey, shared, m_Ctx); +#endif + } + // ElGamal void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding) { diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 30d00d76..c2da1f4d 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -13,11 +13,24 @@ #include #include #include +#include #include "Base.h" #include "Tag.h" #include "CPU.h" +// recognize openssl version and features +#if ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL +# define LEGACY_OPENSSL 1 +#else +# define LEGACY_OPENSSL 0 +# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 +# define OPENSSL_EDDSA 1 +# define OPENSSL_X25519 1 +# define OPENSSL_SIPHASH 1 +# endif +#endif + namespace i2p { namespace crypto @@ -48,6 +61,31 @@ namespace crypto uint8_t m_PublicKey[256]; }; + // x25519 + class X25519Keys + { + public: + + X25519Keys (); + X25519Keys (const uint8_t * priv, const uint8_t * pub); // for RouterContext + ~X25519Keys (); + + void GenerateKeys (); + const uint8_t * GetPublicKey () const { return m_PublicKey; }; + void Agree (const uint8_t * pub, uint8_t * shared); + + private: + + uint8_t m_PublicKey[32]; +#if OPENSSL_X25519 + EVP_PKEY_CTX * m_Ctx; + EVP_PKEY * m_Pkey; +#else + BN_CTX * m_Ctx; + uint8_t m_PrivateKey[32]; +#endif + }; + // ElGamal void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding = false); bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding = false); @@ -260,18 +298,7 @@ namespace crypto } } -// take care about openssl version -#include -#if ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL -# define LEGACY_OPENSSL 1 -#else -# define LEGACY_OPENSSL 0 -# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 -# define OPENSSL_EDDSA 1 -# define OPENSSL_X25519 1 -# endif -#endif - +// take care about openssl below 1.1.0 #if LEGACY_OPENSSL // define getters and setters introduced in 1.1.0 inline int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) diff --git a/libi2pd/Identity.cpp b/libi2pd/Identity.cpp index 7f64d931..0e49b8ad 100644 --- a/libi2pd/Identity.cpp +++ b/libi2pd/Identity.cpp @@ -72,29 +72,10 @@ namespace data break; } case SIGNING_KEY_TYPE_RSA_SHA256_2048: - { - memcpy (m_StandardIdentity.signingKey, signingKey, 128); - excessLen = i2p::crypto::RSASHA2562048_KEY_LENGTH - 128; // 128 = 256 - 128 - excessBuf = new uint8_t[excessLen]; - memcpy (excessBuf, signingKey + 128, excessLen); - break; - } case SIGNING_KEY_TYPE_RSA_SHA384_3072: - { - memcpy (m_StandardIdentity.signingKey, signingKey, 128); - excessLen = i2p::crypto::RSASHA3843072_KEY_LENGTH - 128; // 256 = 384 - 128 - excessBuf = new uint8_t[excessLen]; - memcpy (excessBuf, signingKey + 128, excessLen); - break; - } case SIGNING_KEY_TYPE_RSA_SHA512_4096: - { - memcpy (m_StandardIdentity.signingKey, signingKey, 128); - excessLen = i2p::crypto::RSASHA5124096_KEY_LENGTH - 128; // 384 = 512 - 128 - excessBuf = new uint8_t[excessLen]; - memcpy (excessBuf, signingKey + 128, excessLen); - break; - } + LogPrint (eLogError, "Identity: RSA signing key type ", (int)type, " is not supported"); + break; case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: { size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32 @@ -368,32 +349,10 @@ namespace data break; } case SIGNING_KEY_TYPE_RSA_SHA256_2048: - { - uint8_t signingKey[i2p::crypto::RSASHA2562048_KEY_LENGTH]; - memcpy (signingKey, m_StandardIdentity.signingKey, 128); - size_t excessLen = i2p::crypto::RSASHA2562048_KEY_LENGTH - 128; // 128 = 256- 128 - memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - UpdateVerifier (new i2p::crypto:: RSASHA2562048Verifier (signingKey)); - break; - } case SIGNING_KEY_TYPE_RSA_SHA384_3072: - { - uint8_t signingKey[i2p::crypto::RSASHA3843072_KEY_LENGTH]; - memcpy (signingKey, m_StandardIdentity.signingKey, 128); - size_t excessLen = i2p::crypto::RSASHA3843072_KEY_LENGTH - 128; // 256 = 384- 128 - memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - UpdateVerifier (new i2p::crypto:: RSASHA3843072Verifier (signingKey)); - break; - } case SIGNING_KEY_TYPE_RSA_SHA512_4096: - { - uint8_t signingKey[i2p::crypto::RSASHA5124096_KEY_LENGTH]; - memcpy (signingKey, m_StandardIdentity.signingKey, 128); - size_t excessLen = i2p::crypto::RSASHA5124096_KEY_LENGTH - 128; // 384 = 512- 128 - memcpy (signingKey + 128, m_ExtendedBuffer + 4, excessLen); // right after signing and crypto key types - UpdateVerifier (new i2p::crypto:: RSASHA5124096Verifier (signingKey)); - break; - } + LogPrint (eLogError, "Identity: RSA signing key type ", (int)keyType, " is not supported"); + break; case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: { size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32 @@ -564,13 +523,9 @@ namespace data m_Signer.reset (new i2p::crypto::ECDSAP521Signer (m_SigningPrivateKey)); break; case SIGNING_KEY_TYPE_RSA_SHA256_2048: - m_Signer.reset (new i2p::crypto::RSASHA2562048Signer (m_SigningPrivateKey)); - break; case SIGNING_KEY_TYPE_RSA_SHA384_3072: - m_Signer.reset (new i2p::crypto::RSASHA3843072Signer (m_SigningPrivateKey)); - break; case SIGNING_KEY_TYPE_RSA_SHA512_4096: - m_Signer.reset (new i2p::crypto::RSASHA5124096Signer (m_SigningPrivateKey)); + LogPrint (eLogError, "Identity: RSA signing key type ", (int)m_Public->GetSigningKeyType (), " is not supported"); break; case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: m_Signer.reset (new i2p::crypto::EDDSA25519Signer (m_SigningPrivateKey, m_Public->GetStandardIdentity ().certificate - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH)); @@ -642,7 +597,7 @@ namespace data case SIGNING_KEY_TYPE_RSA_SHA256_2048: case SIGNING_KEY_TYPE_RSA_SHA384_3072: case SIGNING_KEY_TYPE_RSA_SHA512_4096: - LogPrint (eLogWarning, "Identity: RSA signature type is not supported. Create EdDSA"); + LogPrint (eLogWarning, "Identity: RSA signature type is not supported. Creating EdDSA"); // no break here case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: i2p::crypto::CreateEDDSA25519RandomKeys (keys.m_SigningPrivateKey, signingPublicKey); diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 6a319115..ca6dc858 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -17,7 +17,6 @@ #include "Log.h" #include "I2PEndian.h" #include "Crypto.h" -#include "Ed25519.h" #include "Siphash.h" #include "RouterContext.h" #include "Transports.h" @@ -31,19 +30,14 @@ namespace transport NTCP2Establisher::NTCP2Establisher (): m_SessionRequestBuffer (nullptr), m_SessionCreatedBuffer (nullptr), m_SessionConfirmedBuffer (nullptr) { - m_Ctx = BN_CTX_new (); CreateEphemeralKey (); } NTCP2Establisher::~NTCP2Establisher () { - BN_CTX_free (m_Ctx); delete[] m_SessionRequestBuffer; delete[] m_SessionCreatedBuffer; delete[] m_SessionConfirmedBuffer; -#if OPENSSL_X25519 - EVP_PKEY_free (m_EphemeralPkey); -#endif } void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived) @@ -59,7 +53,7 @@ namespace transport HMAC(EVP_sha256(), tempKey, 32, m_CK, 33, derived, &len); } - void NTCP2Establisher::KeyDerivationFunction1 (const uint8_t * pub, const uint8_t * priv, const uint8_t * rs, const uint8_t * epub) + void NTCP2Establisher::KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub) { static const uint8_t protocolNameHash[] = { @@ -83,20 +77,20 @@ namespace transport SHA256_Update (&ctx, m_H, 32); SHA256_Update (&ctx, epub, 32); SHA256_Final (m_H, &ctx); - // x25519 between rs and priv + // x25519 between pub and priv uint8_t inputKeyMaterial[32]; - i2p::crypto::GetEd25519 ()->ScalarMul (pub, priv, inputKeyMaterial, m_Ctx); // rs*priv + priv.Agree (pub, inputKeyMaterial); MixKey (inputKeyMaterial, m_K); } void NTCP2Establisher::KDF1Alice () { - KeyDerivationFunction1 (m_RemoteStaticKey, GetPriv (), m_RemoteStaticKey, GetPub ()); + KeyDerivationFunction1 (m_RemoteStaticKey, m_EphemeralKeys, m_RemoteStaticKey, GetPub ()); } void NTCP2Establisher::KDF1Bob () { - KeyDerivationFunction1 (GetRemotePub (), i2p::context.GetNTCP2StaticPrivateKey (), i2p::context.GetNTCP2StaticPublicKey (), GetRemotePub ()); + KeyDerivationFunction1 (GetRemotePub (), i2p::context.GetStaticKeys (), i2p::context.GetNTCP2StaticPublicKey (), GetRemotePub ()); } void NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub) @@ -120,20 +114,10 @@ namespace transport SHA256_Update (&ctx, epub, 32); SHA256_Final (m_H, &ctx); - // x25519 between remote pub and priv + // x25519 between remote pub and ephemaral priv uint8_t inputKeyMaterial[32]; -#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 + m_EphemeralKeys.Agree (GetRemotePub (), inputKeyMaterial); + MixKey (inputKeyMaterial, m_K); } @@ -150,34 +134,20 @@ namespace transport void NTCP2Establisher::KDF3Alice () { uint8_t inputKeyMaterial[32]; - i2p::crypto::GetEd25519 ()->ScalarMul (GetRemotePub (), i2p::context.GetNTCP2StaticPrivateKey (), inputKeyMaterial, m_Ctx); + i2p::context.GetStaticKeys ().Agree (GetRemotePub (), inputKeyMaterial); MixKey (inputKeyMaterial, m_K); } void NTCP2Establisher::KDF3Bob () { uint8_t inputKeyMaterial[32]; - i2p::crypto::GetEd25519 ()->ScalarMul (m_RemoteStaticKey, m_EphemeralPrivateKey, inputKeyMaterial, m_Ctx); + m_EphemeralKeys.Agree (m_RemoteStaticKey, inputKeyMaterial); MixKey (inputKeyMaterial, m_K); } 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); - i2p::crypto::GetEd25519 ()->ScalarMulB (m_EphemeralPrivateKey, m_EphemeralPublicKey, m_Ctx); -#endif + m_EphemeralKeys.GenerateKeys (); } void NTCP2Establisher::CreateSessionRequestMessage () @@ -420,6 +390,10 @@ namespace transport TransportSession (in_RemoteRouter, NTCP2_ESTABLISH_TIMEOUT), m_Server (server), m_Socket (m_Server.GetService ()), m_IsEstablished (false), m_IsTerminated (false), + m_SendSipKey (nullptr), m_ReceiveSipKey (nullptr), +#if OPENSSL_SIPHASH + m_SendMDCtx(nullptr), m_ReceiveMDCtx (nullptr), +#endif m_NextReceivedLen (0), m_NextReceivedBuffer (nullptr), m_NextSendBuffer (nullptr), m_ReceiveSequenceNumber (0), m_SendSequenceNumber (0), m_IsSending (false) { @@ -442,6 +416,12 @@ namespace transport { delete[] m_NextReceivedBuffer; delete[] m_NextSendBuffer; +#if OPENSSL_SIPHASH + if (m_SendSipKey) EVP_PKEY_free (m_SendSipKey); + if (m_ReceiveSipKey) EVP_PKEY_free (m_ReceiveSipKey); + if (m_SendMDCtx) EVP_MD_CTX_destroy (m_SendMDCtx); + if (m_ReceiveMDCtx) EVP_MD_CTX_destroy (m_ReceiveMDCtx); +#endif } void NTCP2Session::Terminate () @@ -651,8 +631,7 @@ namespace transport // Alice data phase keys m_SendKey = m_Kab; m_ReceiveKey = m_Kba; - m_SendSipKey = m_Sipkeysab; - m_ReceiveSipKey = m_Sipkeysba; + SetSipKeys (m_Sipkeysab, m_Sipkeysba); memcpy (m_ReceiveIV.buf, m_Sipkeysba + 16, 8); memcpy (m_SendIV.buf, m_Sipkeysab + 16, 8); Established (); @@ -704,8 +683,7 @@ namespace transport // Bob data phase keys m_SendKey = m_Kba; m_ReceiveKey = m_Kab; - m_SendSipKey = m_Sipkeysba; - m_ReceiveSipKey = m_Sipkeysab; + SetSipKeys (m_Sipkeysba, m_Sipkeysab); memcpy (m_ReceiveIV.buf, m_Sipkeysab + 16, 8); memcpy (m_SendIV.buf, m_Sipkeysba + 16, 8); // payload @@ -731,6 +709,12 @@ namespace transport SendTerminationAndTerminate (eNTCP2RouterInfoSignatureVerificationFail); return; } + if (i2p::util::GetMillisecondsSinceEpoch () > ri.GetTimestamp () + i2p::data::NETDB_MIN_EXPIRATION_TIMEOUT*1000LL) // 90 minutes + { + LogPrint (eLogError, "NTCP2: RouterInfo is too old in SessionConfirmed"); + SendTerminationAndTerminate (eNTCP2Message3Error); + return; + } auto addr = ri.GetNTCP2Address (false); // any NTCP2 address if (!addr) { @@ -763,6 +747,26 @@ namespace transport } } + void NTCP2Session::SetSipKeys (const uint8_t * sendSipKey, const uint8_t * receiveSipKey) + { +#if OPENSSL_SIPHASH + m_SendSipKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_SIPHASH, nullptr, sendSipKey, 16); + m_SendMDCtx = EVP_MD_CTX_create (); + EVP_PKEY_CTX *ctx = nullptr; + EVP_DigestSignInit (m_SendMDCtx, &ctx, nullptr, nullptr, m_SendSipKey); + EVP_PKEY_CTX_ctrl (ctx, -1, EVP_PKEY_OP_SIGNCTX, EVP_PKEY_CTRL_SET_DIGEST_SIZE, 8, nullptr); + + m_ReceiveSipKey = EVP_PKEY_new_raw_private_key (EVP_PKEY_SIPHASH, nullptr, receiveSipKey, 16); + m_ReceiveMDCtx = EVP_MD_CTX_create (); + ctx = nullptr; + EVP_DigestSignInit (m_ReceiveMDCtx, &ctx, NULL, NULL, m_ReceiveSipKey); + EVP_PKEY_CTX_ctrl (ctx, -1, EVP_PKEY_OP_SIGNCTX, EVP_PKEY_CTRL_SET_DIGEST_SIZE, 8, nullptr); +#else + m_SendSipKey = sendSipKey; + m_ReceiveSipKey = receiveSipKey; +#endif + } + void NTCP2Session::ClientLogin () { SendSessionRequest (); @@ -793,7 +797,14 @@ namespace transport } else { +#if OPENSSL_SIPHASH + EVP_DigestSignInit (m_ReceiveMDCtx, nullptr, nullptr, nullptr, nullptr); + EVP_DigestSignUpdate (m_ReceiveMDCtx, m_ReceiveIV.buf, 8); + size_t l = 8; + EVP_DigestSignFinal (m_ReceiveMDCtx, m_ReceiveIV.buf, &l); +#else i2p::crypto::Siphash<8> (m_ReceiveIV.buf, m_ReceiveIV.buf, 8, m_ReceiveSipKey); +#endif // m_NextReceivedLen comes from the network in BigEndian m_NextReceivedLen = be16toh (m_NextReceivedLen) ^ le16toh (m_ReceiveIV.key); LogPrint (eLogDebug, "NTCP2: received length ", m_NextReceivedLen); @@ -801,7 +812,16 @@ namespace transport { if (m_NextReceivedBuffer) delete[] m_NextReceivedBuffer; m_NextReceivedBuffer = new uint8_t[m_NextReceivedLen]; - Receive (); + boost::system::error_code ec; + size_t moreBytes = m_Socket.available(ec); + if (!ec && moreBytes >= m_NextReceivedLen) + { + // read and process messsage immediately if avaliable + moreBytes = boost::asio::read (m_Socket, boost::asio::buffer(m_NextReceivedBuffer, m_NextReceivedLen), boost::asio::transfer_all (), ec); + HandleReceived (ec, moreBytes); + } + else + Receive (); } else { @@ -914,7 +934,14 @@ namespace transport CreateNonce (m_SendSequenceNumber, nonce); m_SendSequenceNumber++; m_NextSendBuffer = new uint8_t[len + 16 + 2]; i2p::crypto::AEADChaCha20Poly1305 (payload, len, nullptr, 0, m_SendKey, nonce, m_NextSendBuffer + 2, len + 16, true); +#if OPENSSL_SIPHASH + EVP_DigestSignInit (m_SendMDCtx, nullptr, nullptr, nullptr, nullptr); + EVP_DigestSignUpdate (m_SendMDCtx, m_SendIV.buf, 8); + size_t l = 8; + EVP_DigestSignFinal (m_SendMDCtx, m_SendIV.buf, &l); +#else i2p::crypto::Siphash<8> (m_SendIV.buf, m_SendIV.buf, 8, m_SendSipKey); +#endif // length must be in BigEndian htobe16buf (m_NextSendBuffer, (len + 16) ^ le16toh (m_SendIV.key)); LogPrint (eLogDebug, "NTCP2: sent length ", len + 16); @@ -1028,7 +1055,12 @@ namespace transport for (auto it: msgs) m_SendQueue.push_back (it); if (!m_IsSending) - SendQueue (); + SendQueue (); + else if (m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE) + { + LogPrint (eLogWarning, "NTCP2: outgoing messages queue size exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE); + Terminate (); + } } void NTCP2Session::SendLocalRouterInfo () diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 10874abb..7db6e8bf 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -20,6 +20,7 @@ #include #include #include +#include "Crypto.h" #include "util.h" #include "RouterInfo.h" #include "TransportSession.h" @@ -38,6 +39,7 @@ namespace transport const int NTCP2_TERMINATION_CHECK_TIMEOUT = 30; // 30 seconds const int NTCP2_CLOCK_SKEW = 60; // in seconds + const int NTCP2_MAX_OUTGOING_QUEUE_SIZE = 500; // how many messages we can queue up enum NTCP2BlockType { @@ -78,8 +80,7 @@ namespace transport NTCP2Establisher (); ~NTCP2Establisher (); - const uint8_t * GetPub () const { return m_EphemeralPublicKey; }; - const uint8_t * GetPriv () const { return m_EphemeralPrivateKey; }; + const uint8_t * GetPub () const { return m_EphemeralKeys.GetPublicKey (); }; const uint8_t * GetRemotePub () const { return m_RemoteEphemeralPublicKey; }; // Y for Alice and X for Bob uint8_t * GetRemotePub () { return m_RemoteEphemeralPublicKey; }; // to set @@ -95,7 +96,7 @@ namespace transport void KDF3Bob (); void MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived); - void KeyDerivationFunction1 (const uint8_t * pub, const uint8_t * priv, const uint8_t * rs, const uint8_t * epub); // for SessionRequest, (pub, priv) for DH + void KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub); // for SessionRequest, (pub, priv) for DH void KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub); // for SessionCreate void CreateEphemeralKey (); @@ -109,11 +110,8 @@ namespace transport bool ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce); bool ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf); - BN_CTX * m_Ctx; - uint8_t m_EphemeralPrivateKey[32], m_EphemeralPublicKey[32], m_RemoteEphemeralPublicKey[32]; // x25519 -#if OPENSSL_X25519 - EVP_PKEY * m_EphemeralPkey; -#endif + i2p::crypto::X25519Keys m_EphemeralKeys; + uint8_t m_RemoteEphemeralPublicKey[32]; // x25519 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; uint16_t m3p2Len; @@ -151,6 +149,7 @@ namespace transport void CreateNonce (uint64_t seqn, uint8_t * nonce); void KeyDerivationFunctionDataPhase (); + void SetSipKeys (const uint8_t * sendSipKey, const uint8_t * receiveSipKey); // establish void SendSessionRequest (); @@ -190,7 +189,13 @@ namespace transport std::unique_ptr m_Establisher; // data phase uint8_t m_Kab[33], m_Kba[32], m_Sipkeysab[33], m_Sipkeysba[32]; - const uint8_t * m_SendKey, * m_ReceiveKey, * m_SendSipKey, * m_ReceiveSipKey; + const uint8_t * m_SendKey, * m_ReceiveKey; +#if OPENSSL_SIPHASH + EVP_PKEY * m_SendSipKey, * m_ReceiveSipKey; + EVP_MD_CTX * m_SendMDCtx, * m_ReceiveMDCtx; +#else + const uint8_t * m_SendSipKey, * m_ReceiveSipKey; +#endif uint16_t m_NextReceivedLen; uint8_t * m_NextReceivedBuffer, * m_NextSendBuffer; union diff --git a/libi2pd/NetDb.cpp b/libi2pd/NetDb.cpp index 410b71e6..0add6f91 100644 --- a/libi2pd/NetDb.cpp +++ b/libi2pd/NetDb.cpp @@ -130,18 +130,17 @@ namespace data lastDestinationCleanup = ts; } - if (ts - lastPublish >= NETDB_PUBLISH_INTERVAL && !m_HiddenMode) // publish + if (ts - lastPublish >= NETDB_PUBLISH_INTERVAL) // update timestamp and publish { - Publish (); + i2p::context.UpdateTimestamp (ts); + if (!m_HiddenMode) Publish (); lastPublish = ts; } if (ts - lastExploratory >= 30) // exploratory every 30 seconds { auto numRouters = m_RouterInfos.size (); - if (numRouters == 0) - { - throw std::runtime_error("No known routers, reseed seems to be totally failed"); - } + if (!numRouters) + throw std::runtime_error("No known routers, reseed seems to be totally failed"); else // we have peers now m_FloodfillBootstrap = nullptr; if (numRouters < 2500 || ts - lastExploratory >= 90) diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index eebe9b38..40a0b740 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -219,7 +219,7 @@ namespace data BN_CTX * bnctx = BN_CTX_new (); BIGNUM * s = BN_new (), * n = BN_new (); BN_bin2bn (signature, signatureLength, s); - BN_bin2bn (it->second, i2p::crypto::RSASHA5124096_KEY_LENGTH, n); + BN_bin2bn (it->second, 512, n); // RSA 4096 assumed BN_mod_exp (s, s, i2p::crypto::GetRSAE (), n, bnctx); // s = s^e mod n uint8_t * enSigBuf = new uint8_t[signatureLength]; i2p::crypto::bn2buf (s, enSigBuf, signatureLength); diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 6ad3d159..0d3c707b 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -497,6 +497,12 @@ namespace i2p } } + void RouterContext::UpdateTimestamp (uint64_t ts) + { + if (ts > m_LastUpdateTime + ROUTER_INFO_UPDATE_INTERVAL) + UpdateRouterInfo (); + } + bool RouterContext::Load () { std::ifstream fk (i2p::fs::DataDirPath (ROUTER_KEYS), std::ifstream::in | std::ifstream::binary); @@ -620,4 +626,18 @@ namespace i2p { return m_Decryptor ? m_Decryptor->Decrypt (encrypted, data, ctx, false) : false; } + + i2p::crypto::X25519Keys& RouterContext::GetStaticKeys () + { + if (!m_StaticKeys) + { + if (!m_NTCP2Keys) NewNTCP2Keys (); + auto x = new i2p::crypto::X25519Keys (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey); + if (!m_StaticKeys) + m_StaticKeys.reset (x); + else + delete x; + } + return *m_StaticKeys; + } } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 3f3a18c5..f65bc702 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -62,6 +62,7 @@ namespace i2p const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; }; const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; }; const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; }; + i2p::crypto::X25519Keys& GetStaticKeys (); uint32_t GetUptime () const; uint32_t GetStartupTime () const { return m_StartupTime; }; @@ -102,6 +103,7 @@ namespace i2p 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 UpdateTimestamp (uint64_t ts); // in seconds, called from NetDb before publishing void CleanupDestination (); // garlic destination // implements LocalDestination @@ -133,7 +135,7 @@ namespace i2p i2p::data::RouterInfo m_RouterInfo; i2p::data::PrivateKeys m_Keys; std::shared_ptr m_Decryptor; - uint64_t m_LastUpdateTime; + uint64_t m_LastUpdateTime; // in seconds bool m_AcceptsTunnels, m_IsFloodfill; uint64_t m_StartupTime; // in seconds since epoch uint64_t m_BandwidthLimit; // allowed bandwidth @@ -143,6 +145,7 @@ namespace i2p int m_NetID; std::mutex m_GarlicMutex; std::unique_ptr m_NTCP2Keys; + std::unique_ptr m_StaticKeys; }; extern RouterContext context; diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index b8bc5c11..d2bfc7ce 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -375,7 +375,7 @@ namespace data break; case CAPS_FLAG_EXTRA_BANDWIDTH1: case CAPS_FLAG_EXTRA_BANDWIDTH2: - m_Caps |= Caps::eExtraBandwidth; + m_Caps |= Caps::eExtraBandwidth | Caps::eHighBandwidth; break; case CAPS_FLAG_HIDDEN: m_Caps |= Caps::eHidden; @@ -406,16 +406,14 @@ namespace data if (m_Caps & eExtraBandwidth) caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_EXTRA_BANDWIDTH2 : // 'X' CAPS_FLAG_EXTRA_BANDWIDTH1; // 'P' - caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O' + else + caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O' caps += CAPS_FLAG_FLOODFILL; // floodfill } else { if (m_Caps & eExtraBandwidth) - { caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_EXTRA_BANDWIDTH2 /* 'X' */ : CAPS_FLAG_EXTRA_BANDWIDTH1; /*'P' */ - caps += CAPS_FLAG_HIGH_BANDWIDTH3; // 'O' - } else caps += (m_Caps & eHighBandwidth) ? CAPS_FLAG_HIGH_BANDWIDTH3 /* 'O' */: CAPS_FLAG_LOW_BANDWIDTH2 /* 'L' */; // bandwidth } diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index f5164e9f..1facccbc 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -52,29 +52,7 @@ namespace crypto } #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) + EDDSA25519SignerCompat::EDDSA25519SignerCompat (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) { // expand key Ed25519::ExpandPrivateKey (signingPrivateKey, m_ExpandedPrivateKey); @@ -94,14 +72,57 @@ namespace crypto BN_CTX_free (ctx); } - EDDSA25519Signer::~EDDSA25519Signer () + EDDSA25519SignerCompat::~EDDSA25519SignerCompat () { } - void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const + void EDDSA25519SignerCompat::Sign (const uint8_t * buf, int len, uint8_t * signature) const { GetEd25519 ()->Sign (m_ExpandedPrivateKey, m_PublicKeyEncoded, buf, len, signature); } + +#if OPENSSL_EDDSA + EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey): + m_Fallback (nullptr) + { + m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32); + uint8_t publicKey[EDDSA25519_PUBLIC_KEY_LENGTH]; + size_t len = EDDSA25519_PUBLIC_KEY_LENGTH; + EVP_PKEY_get_raw_public_key (m_Pkey, publicKey, &len); + if (memcmp (publicKey, signingPublicKey, EDDSA25519_PUBLIC_KEY_LENGTH)) + { + LogPrint (eLogWarning, "EdDSA public key mismatch. Fallback"); + EVP_PKEY_free (m_Pkey); + m_Fallback = new EDDSA25519SignerCompat (signingPrivateKey, signingPublicKey); + } + else + { + m_MDCtx = EVP_MD_CTX_create (); + EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); + } + } + + EDDSA25519Signer::~EDDSA25519Signer () + { + if (m_Fallback) delete m_Fallback; + else + { + EVP_MD_CTX_destroy (m_MDCtx); + EVP_PKEY_free (m_Pkey); + } + } + + void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const + { + if (m_Fallback) return m_Fallback->Sign (buf, len, signature); + else + { + size_t l = 64; + uint8_t sig[64]; // temporary buffer for signature. openssl issue #7232 + EVP_DigestSign (m_MDCtx, sig, &l, buf, len); + memcpy (signature, sig, 64); + } + } #endif } } diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h index 7f5a53b9..a51f8955 100644 --- a/libi2pd/Signature.h +++ b/libi2pd/Signature.h @@ -6,7 +6,6 @@ #include #include #include -#include #include #include "Crypto.h" #include "Ed25519.h" @@ -149,6 +148,7 @@ namespace crypto enum { hashLen = 64 }; }; + // EcDSA template class ECDSAVerifier: public Verifier { @@ -269,97 +269,6 @@ namespace crypto CreateECDSARandomKeys (NID_secp521r1, ECDSAP521_KEY_LENGTH, signingPrivateKey, signingPublicKey); } -// RSA - template - class RSAVerifier: public Verifier - { - public: - - RSAVerifier (const uint8_t * signingKey) - { - m_PublicKey = RSA_new (); - RSA_set0_key (m_PublicKey, BN_bin2bn (signingKey, keyLen, NULL) /* n */ , BN_dup (GetRSAE ()) /* d */, NULL); - } - - ~RSAVerifier () - { - RSA_free (m_PublicKey); - } - - bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const - { - uint8_t digest[Hash::hashLen]; - Hash::CalculateHash (buf, len, digest); - return RSA_verify (type, digest, Hash::hashLen, signature, GetSignatureLen (), m_PublicKey); - } - size_t GetPublicKeyLen () const { return keyLen; } - size_t GetSignatureLen () const { return keyLen; } - size_t GetPrivateKeyLen () const { return GetSignatureLen ()*2; }; - - private: - - RSA * m_PublicKey; - }; - - - template - class RSASigner: public Signer - { - public: - - RSASigner (const uint8_t * signingPrivateKey) - { - m_PrivateKey = RSA_new (); - RSA_set0_key (m_PrivateKey, BN_bin2bn (signingPrivateKey, keyLen, NULL), /* n */ - BN_dup (GetRSAE ()) /* e */, BN_bin2bn (signingPrivateKey + keyLen, keyLen, NULL) /* d */); - } - - ~RSASigner () - { - RSA_free (m_PrivateKey); - } - - void Sign (const uint8_t * buf, int len, uint8_t * signature) const - { - uint8_t digest[Hash::hashLen]; - Hash::CalculateHash (buf, len, digest); - unsigned int signatureLen = keyLen; - RSA_sign (type, digest, Hash::hashLen, signature, &signatureLen, m_PrivateKey); - } - - private: - - RSA * m_PrivateKey; - }; - - inline void CreateRSARandomKeys (size_t publicKeyLen, uint8_t * signingPrivateKey, uint8_t * signingPublicKey) - { - RSA * rsa = RSA_new (); - BIGNUM * e = BN_dup (GetRSAE ()); // make it non-const - RSA_generate_key_ex (rsa, publicKeyLen*8, e, NULL); - const BIGNUM * n, * d, * e1; - RSA_get0_key (rsa, &n, &e1, &d); - bn2buf (n, signingPrivateKey, publicKeyLen); - bn2buf (d, signingPrivateKey + publicKeyLen, publicKeyLen); - bn2buf (n, signingPublicKey, publicKeyLen); - BN_free (e); // this e is not assigned to rsa->e - RSA_free (rsa); - } - -// RSA_SHA256_2048 - const size_t RSASHA2562048_KEY_LENGTH = 256; - typedef RSAVerifier RSASHA2562048Verifier; - typedef RSASigner RSASHA2562048Signer; - -// RSA_SHA384_3072 - const size_t RSASHA3843072_KEY_LENGTH = 384; - typedef RSAVerifier RSASHA3843072Verifier; - typedef RSASigner RSASHA3843072Signer; - -// RSA_SHA512_4096 - const size_t RSASHA5124096_KEY_LENGTH = 512; - typedef RSAVerifier RSASHA5124096Verifier; - typedef RSASigner RSASHA5124096Signer; // EdDSA class EDDSA25519Verifier: public Verifier @@ -385,6 +294,24 @@ namespace crypto #endif }; + class EDDSA25519SignerCompat: public Signer + { + public: + + EDDSA25519SignerCompat (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); + // we pass signingPublicKey to check if it matches private key + ~EDDSA25519SignerCompat (); + + void Sign (const uint8_t * buf, int len, uint8_t * signature) const; + const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation + + private: + + uint8_t m_ExpandedPrivateKey[64]; + uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; + }; + +#if OPENSSL_EDDSA class EDDSA25519Signer: public Signer { public: @@ -394,20 +321,18 @@ namespace crypto ~EDDSA25519Signer (); void Sign (const uint8_t * buf, int len, uint8_t * signature) const; -#if !OPENSSL_EDDSA - const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; // for keys creation -#endif private: -#if OPENSSL_EDDSA EVP_PKEY * m_Pkey; - EVP_MD_CTX * m_MDCtx; -#else - uint8_t m_ExpandedPrivateKey[64]; - uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; -#endif + EVP_MD_CTX * m_MDCtx; + EDDSA25519SignerCompat * m_Fallback; }; +#else + typedef EDDSA25519SignerCompat EDDSA25519Signer; + +#endif + inline void CreateEDDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) { #if OPENSSL_EDDSA diff --git a/libi2pd/version.h b/libi2pd/version.h index 7c015e84..3f09928c 100644 --- a/libi2pd/version.h +++ b/libi2pd/version.h @@ -7,7 +7,7 @@ #define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c) #define I2PD_VERSION_MAJOR 2 -#define I2PD_VERSION_MINOR 20 +#define I2PD_VERSION_MINOR 21 #define I2PD_VERSION_MICRO 0 #define I2PD_VERSION_PATCH 0 #define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO) @@ -21,7 +21,7 @@ #define I2P_VERSION_MAJOR 0 #define I2P_VERSION_MINOR 9 -#define I2P_VERSION_MICRO 36 +#define I2P_VERSION_MICRO 37 #define I2P_VERSION_PATCH 0 #define I2P_VERSION MAKE_VERSION(I2P_VERSION_MAJOR, I2P_VERSION_MINOR, I2P_VERSION_MICRO) diff --git a/qt/i2pd_qt/TunnelConfig.cpp b/qt/i2pd_qt/TunnelConfig.cpp index e4354b62..8ed72930 100644 --- a/qt/i2pd_qt/TunnelConfig.cpp +++ b/qt/i2pd_qt/TunnelConfig.cpp @@ -31,16 +31,15 @@ void ClientTunnelConfig::saveToStringStream(std::stringstream& out) { out << "address=" << address << "\n" << "port=" << port << "\n" << "destination=" << dest << "\n" - << "keys=" << keys << "\n" << "destinationport=" << destinationPort << "\n" << "signaturetype=" << sigType << "\n"; + if(!keys.empty()) out << "keys=" << keys << "\n"; } void ServerTunnelConfig::saveToStringStream(std::stringstream& out) { out << "host=" << host << "\n" << "port=" << port << "\n" - << "keys=" << keys << "\n" << "signaturetype=" << sigType << "\n" << "inport=" << inPort << "\n" << "accesslist=" << accessList << "\n" @@ -49,5 +48,6 @@ void ServerTunnelConfig::saveToStringStream(std::stringstream& out) { << "address=" << address << "\n" << "hostoverride=" << hostOverride << "\n" << "webircpassword=" << webircpass << "\n"; + if(!keys.empty()) out << "keys=" << keys << "\n"; } diff --git a/qt/i2pd_qt/android/AndroidManifest.xml b/qt/i2pd_qt/android/AndroidManifest.xml index c62e118e..ddb6aeb1 100644 --- a/qt/i2pd_qt/android/AndroidManifest.xml +++ b/qt/i2pd_qt/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 0488f289..879efc95 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -1,318 +1,319 @@ -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = i2pd_qt -TEMPLATE = app -QMAKE_CXXFLAGS *= -std=c++11 -ggdb -DEFINES += USE_UPNP - -# change to your own path, where you will store all needed libraries with 'git clone' commands below. -MAIN_PATH = /path/to/libraries - -# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git -# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git -# git clone https://github.com/PurpleI2P/android-ifaddrs.git -BOOST_PATH = $$MAIN_PATH/Boost-for-Android-Prebuilt -OPENSSL_PATH = $$MAIN_PATH/OpenSSL-for-Android-Prebuilt -MINIUPNP_PATH = $$MAIN_PATH/MiniUPnP-for-Android-Prebuilt -IFADDRS_PATH = $$MAIN_PATH/android-ifaddrs - -# Steps in Android SDK manager: -# 1) Check Extras/Google Support Library https://developer.android.com/topic/libraries/support-library/setup.html -# 2) Check API 11 -# Finally, click Install. - -SOURCES += DaemonQT.cpp mainwindow.cpp \ - ../../libi2pd/api.cpp \ - ../../libi2pd/Base.cpp \ - ../../libi2pd/BloomFilter.cpp \ - ../../libi2pd/Config.cpp \ - ../../libi2pd/CPU.cpp \ - ../../libi2pd/Crypto.cpp \ - ../../libi2pd/CryptoKey.cpp \ - ../../libi2pd/Datagram.cpp \ - ../../libi2pd/Destination.cpp \ - ../../libi2pd/Event.cpp \ - ../../libi2pd/Family.cpp \ - ../../libi2pd/FS.cpp \ - ../../libi2pd/Garlic.cpp \ - ../../libi2pd/Gost.cpp \ - ../../libi2pd/Gzip.cpp \ - ../../libi2pd/HTTP.cpp \ - ../../libi2pd/I2NPProtocol.cpp \ - ../../libi2pd/I2PEndian.cpp \ - ../../libi2pd/Identity.cpp \ - ../../libi2pd/LeaseSet.cpp \ - ../../libi2pd/Log.cpp \ - ../../libi2pd/NetDb.cpp \ - ../../libi2pd/NetDbRequests.cpp \ - ../../libi2pd/NTCPSession.cpp \ - ../../libi2pd/Profiling.cpp \ - ../../libi2pd/Reseed.cpp \ - ../../libi2pd/RouterContext.cpp \ - ../../libi2pd/RouterInfo.cpp \ - ../../libi2pd/Signature.cpp \ - ../../libi2pd/SSU.cpp \ - ../../libi2pd/SSUData.cpp \ - ../../libi2pd/SSUSession.cpp \ - ../../libi2pd/Streaming.cpp \ - ../../libi2pd/Timestamp.cpp \ - ../../libi2pd/TransitTunnel.cpp \ - ../../libi2pd/Transports.cpp \ - ../../libi2pd/Tunnel.cpp \ - ../../libi2pd/TunnelEndpoint.cpp \ - ../../libi2pd/TunnelGateway.cpp \ - ../../libi2pd/TunnelPool.cpp \ - ../../libi2pd/util.cpp \ - ../../libi2pd/Ed25519.cpp \ - ../../libi2pd/Chacha20.cpp \ - ../../libi2pd/Poly1305.cpp \ - ../../libi2pd_client/AddressBook.cpp \ - ../../libi2pd_client/BOB.cpp \ - ../../libi2pd_client/ClientContext.cpp \ - ../../libi2pd_client/HTTPProxy.cpp \ - ../../libi2pd_client/I2CP.cpp \ - ../../libi2pd_client/I2PService.cpp \ - ../../libi2pd_client/I2PTunnel.cpp \ - ../../libi2pd_client/MatchedDestination.cpp \ - ../../libi2pd_client/SAM.cpp \ - ../../libi2pd_client/SOCKS.cpp \ - ../../libi2pd_client/Websocket.cpp \ - ../../libi2pd_client/WebSocks.cpp \ - ClientTunnelPane.cpp \ - MainWindowItems.cpp \ - ServerTunnelPane.cpp \ - SignatureTypeComboboxFactory.cpp \ - TunnelConfig.cpp \ - TunnelPane.cpp \ - ../../daemon/Daemon.cpp \ - ../../daemon/HTTPServer.cpp \ - ../../daemon/i2pd.cpp \ - ../../daemon/I2PControl.cpp \ - ../../daemon/UnixDaemon.cpp \ - ../../daemon/UPnP.cpp \ - textbrowsertweaked1.cpp \ - pagewithbackbutton.cpp \ - widgetlock.cpp \ - widgetlockregistry.cpp \ - logviewermanager.cpp - -#qt creator does not handle this well -#SOURCES += $$files(../../libi2pd/*.cpp) -#SOURCES += $$files(../../libi2pd_client/*.cpp) -#SOURCES += $$files(../../daemon/*.cpp) -#SOURCES += $$files(./*.cpp) - -SOURCES -= ../../daemon/UnixDaemon.cpp - -HEADERS += DaemonQT.h mainwindow.h \ - ../../libi2pd/api.h \ - ../../libi2pd/Base.h \ - ../../libi2pd/BloomFilter.h \ - ../../libi2pd/Config.h \ - ../../libi2pd/Crypto.h \ - ../../libi2pd/CryptoKey.h \ - ../../libi2pd/Datagram.h \ - ../../libi2pd/Destination.h \ - ../../libi2pd/Event.h \ - ../../libi2pd/Family.h \ - ../../libi2pd/FS.h \ - ../../libi2pd/Garlic.h \ - ../../libi2pd/Gost.h \ - ../../libi2pd/Gzip.h \ - ../../libi2pd/HTTP.h \ - ../../libi2pd/I2NPProtocol.h \ - ../../libi2pd/I2PEndian.h \ - ../../libi2pd/Identity.h \ - ../../libi2pd/LeaseSet.h \ - ../../libi2pd/LittleBigEndian.h \ - ../../libi2pd/Log.h \ - ../../libi2pd/NetDb.hpp \ - ../../libi2pd/NetDbRequests.h \ - ../../libi2pd/NTCPSession.h \ - ../../libi2pd/Profiling.h \ - ../../libi2pd/Queue.h \ - ../../libi2pd/Reseed.h \ - ../../libi2pd/RouterContext.h \ - ../../libi2pd/RouterInfo.h \ - ../../libi2pd/Signature.h \ - ../../libi2pd/SSU.h \ - ../../libi2pd/SSUData.h \ - ../../libi2pd/SSUSession.h \ - ../../libi2pd/Streaming.h \ - ../../libi2pd/Tag.h \ - ../../libi2pd/Timestamp.h \ - ../../libi2pd/TransitTunnel.h \ - ../../libi2pd/Transports.h \ - ../../libi2pd/TransportSession.h \ - ../../libi2pd/Tunnel.h \ - ../../libi2pd/TunnelBase.h \ - ../../libi2pd/TunnelConfig.h \ - ../../libi2pd/TunnelEndpoint.h \ - ../../libi2pd/TunnelGateway.h \ - ../../libi2pd/TunnelPool.h \ - ../../libi2pd/util.h \ - ../../libi2pd/version.h \ - ../../libi2pd_client/AddressBook.h \ - ../../libi2pd_client/BOB.h \ - ../../libi2pd_client/ClientContext.h \ - ../../libi2pd_client/HTTPProxy.h \ - ../../libi2pd_client/I2CP.h \ - ../../libi2pd_client/I2PService.h \ - ../../libi2pd_client/I2PTunnel.h \ - ../../libi2pd_client/MatchedDestination.h \ - ../../libi2pd_client/SAM.h \ - ../../libi2pd_client/SOCKS.h \ - ../../libi2pd_client/Websocket.h \ - ../../libi2pd_client/WebSocks.h \ - ClientTunnelPane.h \ - MainWindowItems.h \ - ServerTunnelPane.h \ - SignatureTypeComboboxFactory.h \ - TunnelConfig.h \ - TunnelPane.h \ - TunnelsPageUpdateListener.h \ - ../../daemon/Daemon.h \ - ../../daemon/HTTPServer.h \ - ../../daemon/I2PControl.h \ - ../../daemon/UPnP.h \ - textbrowsertweaked1.h \ - pagewithbackbutton.h \ - widgetlock.h \ - widgetlockregistry.h \ - i2pd.rc \ - i2pd.rc \ - logviewermanager.h - -INCLUDEPATH += ../../libi2pd -INCLUDEPATH += ../../libi2pd_client -INCLUDEPATH += ../../daemon -INCLUDEPATH += . - -FORMS += mainwindow.ui \ - tunnelform.ui \ - statusbuttons.ui \ - routercommandswidget.ui \ - generalsettingswidget.ui - -LIBS += -lz - -macx { - message("using mac os x target") - BREWROOT=/usr/local - BOOSTROOT=$$BREWROOT/opt/boost - SSLROOT=$$BREWROOT/opt/libressl - UPNPROOT=$$BREWROOT/opt/miniupnpc - INCLUDEPATH += $$BOOSTROOT/include - INCLUDEPATH += $$SSLROOT/include - INCLUDEPATH += $$UPNPROOT/include - LIBS += $$SSLROOT/lib/libcrypto.a - LIBS += $$SSLROOT/lib/libssl.a - LIBS += $$BOOSTROOT/lib/libboost_system.a - LIBS += $$BOOSTROOT/lib/libboost_date_time.a - LIBS += $$BOOSTROOT/lib/libboost_filesystem.a - LIBS += $$BOOSTROOT/lib/libboost_program_options.a - LIBS += $$UPNPROOT/lib/libminiupnpc.a -} - -android { - message("Using Android settings") - DEFINES += ANDROID=1 - DEFINES += __ANDROID__ - - CONFIG += mobility - - MOBILITY = - - INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \ - $$OPENSSL_PATH/openssl-1.0.2/include \ - $$MINIUPNP_PATH/miniupnp-2.0/include \ - $$IFADDRS_PATH - DISTFILES += android/AndroidManifest.xml - - ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android - - SOURCES += $$IFADDRS_PATH/ifaddrs.c - HEADERS += $$IFADDRS_PATH/ifaddrs.h - - equals(ANDROID_TARGET_ARCH, armeabi-v7a){ - DEFINES += ANDROID_ARM7A - # http://stackoverflow.com/a/30235934/529442 - LIBS += -L$$BOOST_PATH/boost_1_53_0/armeabi-v7a/lib \ - -lboost_system-gcc-mt-1_53 -lboost_date_time-gcc-mt-1_53 \ - -lboost_filesystem-gcc-mt-1_53 -lboost_program_options-gcc-mt-1_53 \ - -L$$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/ -lcrypto -lssl \ - -L$$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/ -lminiupnpc - - PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto.a \ - $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl.a - DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include - - ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto_1_0_0.so \ - $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl_1_0_0.so \ - $$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/libminiupnpc.so - } - - equals(ANDROID_TARGET_ARCH, x86){ - # http://stackoverflow.com/a/30235934/529442 - LIBS += -L$$BOOST_PATH/boost_1_53_0/x86/lib \ - -lboost_system-gcc-mt-1_53 -lboost_date_time-gcc-mt-1_53 \ - -lboost_filesystem-gcc-mt-1_53 -lboost_program_options-gcc-mt-1_53 \ - -L$$OPENSSL_PATH/openssl-1.0.2/x86/lib/ -lcrypto -lssl \ - -L$$MINIUPNP_PATH/miniupnp-2.0/x86/lib/ -lminiupnpc - - PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto.a \ - $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl.a - - DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include - - ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto_1_0_0.so \ - $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl_1_0_0.so \ - $$MINIUPNP_PATH/miniupnp-2.0/x86/lib/libminiupnpc.so - } -} - -linux:!android { - message("Using Linux settings") - LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc -} - -windows { - message("Using Windows settings") - RC_FILE = i2pd.rc - DEFINES += BOOST_USE_WINDOWS_H WINDOWS _WINDOWS WIN32_LEAN_AND_MEAN MINIUPNP_STATICLIB - DEFINES -= UNICODE _UNICODE - BOOST_SUFFIX = -mt - QMAKE_CXXFLAGS_RELEASE = -Os - QMAKE_LFLAGS = -Wl,-Bstatic -static-libgcc -static-libstdc++ -mwindows - - #linker's -s means "strip" - QMAKE_LFLAGS_RELEASE += -s - - LIBS = -lminiupnpc \ - -lboost_system$$BOOST_SUFFIX \ - -lboost_date_time$$BOOST_SUFFIX \ - -lboost_filesystem$$BOOST_SUFFIX \ - -lboost_program_options$$BOOST_SUFFIX \ - -lssl \ - -lcrypto \ - -lz \ - -lwsock32 \ - -lws2_32 \ - -lgdi32 \ - -liphlpapi \ - -lstdc++ \ - -lpthread -} - -!android:!symbian:!maemo5:!simulator { - message("Build with a system tray icon") - # see also http://doc.qt.io/qt-4.8/qt-desktop-systray-systray-pro.html for example on wince* - #sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS i2pd_qt.pro resources images - RESOURCES = i2pd.qrc - QT += xml - #INSTALLS += sources -} - +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = i2pd_qt +TEMPLATE = app +QMAKE_CXXFLAGS *= -std=c++11 -ggdb +DEFINES += USE_UPNP + +# change to your own path, where you will store all needed libraries with 'git clone' commands below. +MAIN_PATH = /path/to/libraries + +# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git +# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git +# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git +# git clone https://github.com/PurpleI2P/android-ifaddrs.git +BOOST_PATH = $$MAIN_PATH/Boost-for-Android-Prebuilt +OPENSSL_PATH = $$MAIN_PATH/OpenSSL-for-Android-Prebuilt +MINIUPNP_PATH = $$MAIN_PATH/MiniUPnP-for-Android-Prebuilt +IFADDRS_PATH = $$MAIN_PATH/android-ifaddrs + +# Steps in Android SDK manager: +# 1) Check Extras/Google Support Library https://developer.android.com/topic/libraries/support-library/setup.html +# 2) Check API 11 +# Finally, click Install. + +SOURCES += DaemonQT.cpp mainwindow.cpp \ + ../../libi2pd/api.cpp \ + ../../libi2pd/Base.cpp \ + ../../libi2pd/BloomFilter.cpp \ + ../../libi2pd/Config.cpp \ + ../../libi2pd/CPU.cpp \ + ../../libi2pd/Crypto.cpp \ + ../../libi2pd/CryptoKey.cpp \ + ../../libi2pd/Datagram.cpp \ + ../../libi2pd/Destination.cpp \ + ../../libi2pd/Event.cpp \ + ../../libi2pd/Family.cpp \ + ../../libi2pd/FS.cpp \ + ../../libi2pd/Garlic.cpp \ + ../../libi2pd/Gost.cpp \ + ../../libi2pd/Gzip.cpp \ + ../../libi2pd/HTTP.cpp \ + ../../libi2pd/I2NPProtocol.cpp \ + ../../libi2pd/I2PEndian.cpp \ + ../../libi2pd/Identity.cpp \ + ../../libi2pd/LeaseSet.cpp \ + ../../libi2pd/Log.cpp \ + ../../libi2pd/NetDb.cpp \ + ../../libi2pd/NetDbRequests.cpp \ + ../../libi2pd/NTCPSession.cpp \ + ../../libi2pd/Profiling.cpp \ + ../../libi2pd/Reseed.cpp \ + ../../libi2pd/RouterContext.cpp \ + ../../libi2pd/RouterInfo.cpp \ + ../../libi2pd/Signature.cpp \ + ../../libi2pd/SSU.cpp \ + ../../libi2pd/SSUData.cpp \ + ../../libi2pd/SSUSession.cpp \ + ../../libi2pd/Streaming.cpp \ + ../../libi2pd/Timestamp.cpp \ + ../../libi2pd/TransitTunnel.cpp \ + ../../libi2pd/Transports.cpp \ + ../../libi2pd/Tunnel.cpp \ + ../../libi2pd/TunnelEndpoint.cpp \ + ../../libi2pd/TunnelGateway.cpp \ + ../../libi2pd/TunnelPool.cpp \ + ../../libi2pd/util.cpp \ + ../../libi2pd/Ed25519.cpp \ + ../../libi2pd/Chacha20.cpp \ + ../../libi2pd/Poly1305.cpp \ + ../../libi2pd_client/AddressBook.cpp \ + ../../libi2pd_client/BOB.cpp \ + ../../libi2pd_client/ClientContext.cpp \ + ../../libi2pd_client/HTTPProxy.cpp \ + ../../libi2pd_client/I2CP.cpp \ + ../../libi2pd_client/I2PService.cpp \ + ../../libi2pd_client/I2PTunnel.cpp \ + ../../libi2pd_client/MatchedDestination.cpp \ + ../../libi2pd_client/SAM.cpp \ + ../../libi2pd_client/SOCKS.cpp \ + ../../libi2pd_client/Websocket.cpp \ + ../../libi2pd_client/WebSocks.cpp \ + ClientTunnelPane.cpp \ + MainWindowItems.cpp \ + ServerTunnelPane.cpp \ + SignatureTypeComboboxFactory.cpp \ + TunnelConfig.cpp \ + TunnelPane.cpp \ + ../../daemon/Daemon.cpp \ + ../../daemon/HTTPServer.cpp \ + ../../daemon/i2pd.cpp \ + ../../daemon/I2PControl.cpp \ + ../../daemon/UnixDaemon.cpp \ + ../../daemon/UPnP.cpp \ + textbrowsertweaked1.cpp \ + pagewithbackbutton.cpp \ + widgetlock.cpp \ + widgetlockregistry.cpp \ + logviewermanager.cpp \ + ../../libi2pd/NTCP2.cpp + +#qt creator does not handle this well +#SOURCES += $$files(../../libi2pd/*.cpp) +#SOURCES += $$files(../../libi2pd_client/*.cpp) +#SOURCES += $$files(../../daemon/*.cpp) +#SOURCES += $$files(./*.cpp) + +SOURCES -= ../../daemon/UnixDaemon.cpp + +HEADERS += DaemonQT.h mainwindow.h \ + ../../libi2pd/api.h \ + ../../libi2pd/Base.h \ + ../../libi2pd/BloomFilter.h \ + ../../libi2pd/Config.h \ + ../../libi2pd/Crypto.h \ + ../../libi2pd/CryptoKey.h \ + ../../libi2pd/Datagram.h \ + ../../libi2pd/Destination.h \ + ../../libi2pd/Event.h \ + ../../libi2pd/Family.h \ + ../../libi2pd/FS.h \ + ../../libi2pd/Garlic.h \ + ../../libi2pd/Gost.h \ + ../../libi2pd/Gzip.h \ + ../../libi2pd/HTTP.h \ + ../../libi2pd/I2NPProtocol.h \ + ../../libi2pd/I2PEndian.h \ + ../../libi2pd/Identity.h \ + ../../libi2pd/LeaseSet.h \ + ../../libi2pd/LittleBigEndian.h \ + ../../libi2pd/Log.h \ + ../../libi2pd/NetDb.hpp \ + ../../libi2pd/NetDbRequests.h \ + ../../libi2pd/NTCPSession.h \ + ../../libi2pd/Profiling.h \ + ../../libi2pd/Queue.h \ + ../../libi2pd/Reseed.h \ + ../../libi2pd/RouterContext.h \ + ../../libi2pd/RouterInfo.h \ + ../../libi2pd/Signature.h \ + ../../libi2pd/SSU.h \ + ../../libi2pd/SSUData.h \ + ../../libi2pd/SSUSession.h \ + ../../libi2pd/Streaming.h \ + ../../libi2pd/Tag.h \ + ../../libi2pd/Timestamp.h \ + ../../libi2pd/TransitTunnel.h \ + ../../libi2pd/Transports.h \ + ../../libi2pd/TransportSession.h \ + ../../libi2pd/Tunnel.h \ + ../../libi2pd/TunnelBase.h \ + ../../libi2pd/TunnelConfig.h \ + ../../libi2pd/TunnelEndpoint.h \ + ../../libi2pd/TunnelGateway.h \ + ../../libi2pd/TunnelPool.h \ + ../../libi2pd/util.h \ + ../../libi2pd/version.h \ + ../../libi2pd_client/AddressBook.h \ + ../../libi2pd_client/BOB.h \ + ../../libi2pd_client/ClientContext.h \ + ../../libi2pd_client/HTTPProxy.h \ + ../../libi2pd_client/I2CP.h \ + ../../libi2pd_client/I2PService.h \ + ../../libi2pd_client/I2PTunnel.h \ + ../../libi2pd_client/MatchedDestination.h \ + ../../libi2pd_client/SAM.h \ + ../../libi2pd_client/SOCKS.h \ + ../../libi2pd_client/Websocket.h \ + ../../libi2pd_client/WebSocks.h \ + ClientTunnelPane.h \ + MainWindowItems.h \ + ServerTunnelPane.h \ + SignatureTypeComboboxFactory.h \ + TunnelConfig.h \ + TunnelPane.h \ + TunnelsPageUpdateListener.h \ + ../../daemon/Daemon.h \ + ../../daemon/HTTPServer.h \ + ../../daemon/I2PControl.h \ + ../../daemon/UPnP.h \ + textbrowsertweaked1.h \ + pagewithbackbutton.h \ + widgetlock.h \ + widgetlockregistry.h \ + i2pd.rc \ + i2pd.rc \ + logviewermanager.h + +INCLUDEPATH += ../../libi2pd +INCLUDEPATH += ../../libi2pd_client +INCLUDEPATH += ../../daemon +INCLUDEPATH += . + +FORMS += mainwindow.ui \ + tunnelform.ui \ + statusbuttons.ui \ + routercommandswidget.ui \ + generalsettingswidget.ui + +LIBS += -lz + +macx { + message("using mac os x target") + BREWROOT=/usr/local + BOOSTROOT=$$BREWROOT/opt/boost + SSLROOT=$$BREWROOT/opt/libressl + UPNPROOT=$$BREWROOT/opt/miniupnpc + INCLUDEPATH += $$BOOSTROOT/include + INCLUDEPATH += $$SSLROOT/include + INCLUDEPATH += $$UPNPROOT/include + LIBS += $$SSLROOT/lib/libcrypto.a + LIBS += $$SSLROOT/lib/libssl.a + LIBS += $$BOOSTROOT/lib/libboost_system.a + LIBS += $$BOOSTROOT/lib/libboost_date_time.a + LIBS += $$BOOSTROOT/lib/libboost_filesystem.a + LIBS += $$BOOSTROOT/lib/libboost_program_options.a + LIBS += $$UPNPROOT/lib/libminiupnpc.a +} + +android { + message("Using Android settings") + DEFINES += ANDROID=1 + DEFINES += __ANDROID__ + + CONFIG += mobility + + MOBILITY = + + INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \ + $$OPENSSL_PATH/openssl-1.0.2/include \ + $$MINIUPNP_PATH/miniupnp-2.0/include \ + $$IFADDRS_PATH + DISTFILES += android/AndroidManifest.xml + + ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android + + SOURCES += $$IFADDRS_PATH/ifaddrs.c + HEADERS += $$IFADDRS_PATH/ifaddrs.h + + equals(ANDROID_TARGET_ARCH, armeabi-v7a){ + DEFINES += ANDROID_ARM7A + # http://stackoverflow.com/a/30235934/529442 + LIBS += -L$$BOOST_PATH/boost_1_53_0/armeabi-v7a/lib \ + -lboost_system-gcc-mt-1_53 -lboost_date_time-gcc-mt-1_53 \ + -lboost_filesystem-gcc-mt-1_53 -lboost_program_options-gcc-mt-1_53 \ + -L$$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/ -lcrypto -lssl \ + -L$$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/ -lminiupnpc + + PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto.a \ + $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl.a + DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include + + ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto_1_0_0.so \ + $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl_1_0_0.so \ + $$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/libminiupnpc.so + } + + equals(ANDROID_TARGET_ARCH, x86){ + # http://stackoverflow.com/a/30235934/529442 + LIBS += -L$$BOOST_PATH/boost_1_53_0/x86/lib \ + -lboost_system-gcc-mt-1_53 -lboost_date_time-gcc-mt-1_53 \ + -lboost_filesystem-gcc-mt-1_53 -lboost_program_options-gcc-mt-1_53 \ + -L$$OPENSSL_PATH/openssl-1.0.2/x86/lib/ -lcrypto -lssl \ + -L$$MINIUPNP_PATH/miniupnp-2.0/x86/lib/ -lminiupnpc + + PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto.a \ + $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl.a + + DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include + + ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto_1_0_0.so \ + $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl_1_0_0.so \ + $$MINIUPNP_PATH/miniupnp-2.0/x86/lib/libminiupnpc.so + } +} + +linux:!android { + message("Using Linux settings") + LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc +} + +windows { + message("Using Windows settings") + RC_FILE = i2pd.rc + DEFINES += BOOST_USE_WINDOWS_H WINDOWS _WINDOWS WIN32_LEAN_AND_MEAN MINIUPNP_STATICLIB + DEFINES -= UNICODE _UNICODE + BOOST_SUFFIX = -mt + QMAKE_CXXFLAGS_RELEASE = -Os + QMAKE_LFLAGS = -Wl,-Bstatic -static-libgcc -static-libstdc++ -mwindows + + #linker's -s means "strip" + QMAKE_LFLAGS_RELEASE += -s + + LIBS = -lminiupnpc \ + -lboost_system$$BOOST_SUFFIX \ + -lboost_date_time$$BOOST_SUFFIX \ + -lboost_filesystem$$BOOST_SUFFIX \ + -lboost_program_options$$BOOST_SUFFIX \ + -lssl \ + -lcrypto \ + -lz \ + -lwsock32 \ + -lws2_32 \ + -lgdi32 \ + -liphlpapi \ + -lstdc++ \ + -lpthread +} + +!android:!symbian:!maemo5:!simulator { + message("Build with a system tray icon") + # see also http://doc.qt.io/qt-4.8/qt-desktop-systray-systray-pro.html for example on wince* + #sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS i2pd_qt.pro resources images + RESOURCES = i2pd.qrc + QT += xml + #INSTALLS += sources +} + diff --git a/qt/i2pd_qt/mainwindow.h b/qt/i2pd_qt/mainwindow.h index 51384f51..048f44af 100644 --- a/qt/i2pd_qt/mainwindow.h +++ b/qt/i2pd_qt/mainwindow.h @@ -726,8 +726,8 @@ private: // mandatory params std::string host = section.second.get (I2P_SERVER_TUNNEL_HOST); int port = section.second.get (I2P_SERVER_TUNNEL_PORT); - std::string keys = section.second.get (I2P_SERVER_TUNNEL_KEYS); // optional params + std::string keys = section.second.get (I2P_SERVER_TUNNEL_KEYS, ""); int inPort = section.second.get (I2P_SERVER_TUNNEL_INPORT, 0); std::string accessList = section.second.get (I2P_SERVER_TUNNEL_ACCESS_LIST, ""); std::string hostOverride = section.second.get (I2P_SERVER_TUNNEL_HOST_OVERRIDE, "");