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/Makefile b/Makefile index c51018f9..ce1ad51f 100644 --- a/Makefile +++ b/Makefile @@ -130,6 +130,8 @@ doxygen: .PHONY: deps .PHONY: doxygen .PHONY: dist +.PHONY: last-dist .PHONY: api .PHONY: api_client .PHONY: mk_obj_dir +.PHONY: install diff --git a/Makefile.homebrew b/Makefile.homebrew index 688fdaea..64301c02 100644 --- a/Makefile.homebrew +++ b/Makefile.homebrew @@ -1,7 +1,7 @@ # root directory holding homebrew BREWROOT = /usr/local BOOSTROOT = ${BREWROOT}/opt/boost -SSLROOT = ${BREWROOT}/opt/libressl +SSLROOT = ${BREWROOT}/opt/openssl@1.1 UPNPROOT = ${BREWROOT}/opt/miniupnpc CXXFLAGS = ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX -Wno-overloaded-virtual INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include @@ -41,9 +41,14 @@ ifeq ($(USE_AVX),1) CXXFLAGS += -mavx endif - -# Disabled, since it will be the default make rule. I think its better -# to define the default rule in Makefile and not Makefile. - torkel -#install: all -# test -d ${PREFIX} || mkdir -p ${PREFIX}/ -# cp -r i2p ${PREFIX}/ +install: all + install -d ${PREFIX}/bin ${PREFIX}/etc/i2pd ${PREFIX}/share/doc/i2pd ${PREFIX}/share/i2pd ${PREFIX}/share/man/man1 ${PREFIX}/var/lib/i2pd + install -m 755 ${I2PD} ${PREFIX}/bin/ + install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd + @cp -R contrib/certificates ${PREFIX}/share/i2pd/ + install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd + @gzip debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1 + @ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/ + @ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf + @ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt + @ln -sf ${PREFIX}/etc/i2pd/tunnels.conf ${PREFIX}/var/lib/i2pd/tunnels.conf \ No newline at end of file diff --git a/Makefile.linux b/Makefile.linux index b9a740ad..cb376e77 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -21,8 +21,10 @@ else ifeq ($(shell expr match ${CXXVER} "4\.6"),3) # = 4.6 NEEDED_CXXFLAGS += -std=c++0x else ifeq ($(shell expr match ${CXXVER} "[5-7]\.[0-9]"),3) # gcc >= 5.0 NEEDED_CXXFLAGS += -std=c++11 + LDLIBS = -latomic else ifeq ($(shell expr match ${CXXVER} "[7-8]"),1) # gcc 7 ubuntu or gcc 8 arch NEEDED_CXXFLAGS += -std=c++11 + LDLIBS = -latomic else # not supported $(error Compiler too old) endif @@ -34,7 +36,7 @@ ifeq ($(USE_STATIC),yes) # Using 'getaddrinfo' in statically linked applications requires at runtime # the shared libraries from the glibc version used for linking LIBDIR := /usr/lib - LDLIBS = $(LIBDIR)/libboost_system.a + LDLIBS += $(LIBDIR)/libboost_system.a LDLIBS += $(LIBDIR)/libboost_date_time.a LDLIBS += $(LIBDIR)/libboost_filesystem.a LDLIBS += $(LIBDIR)/libboost_program_options.a @@ -44,7 +46,7 @@ ifeq ($(USE_STATIC),yes) LDLIBS += -lpthread -static-libstdc++ -static-libgcc -lrt -ldl USE_AESNI := no else - LDLIBS = -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread + LDLIBS += -lcrypto -lssl -lz -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread endif # UPNP Support (miniupnpc 1.5 and higher) diff --git a/Makefile.osx b/Makefile.osx index 13376040..d673d3ef 100644 --- a/Makefile.osx +++ b/Makefile.osx @@ -1,7 +1,7 @@ CXX = clang++ CXXFLAGS := ${CXX_DEBUG} -Wall -std=c++11 -DMAC_OSX INCFLAGS = -I/usr/local/include -LDFLAGS := ${LD_DEBUG} -Wl,-rpath,/usr/local/lib -L/usr/local/lib +LDFLAGS := -Wl,-rpath,/usr/local/lib -L/usr/local/lib ifeq ($(USE_STATIC),yes) LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread @@ -28,17 +28,3 @@ endif ifeq ($(USE_AVX),1) CXXFLAGS += -mavx endif - -# Disabled, since it will be the default make rule. I think its better -# to define the default rule in Makefile and not Makefile. - torkel -install-brew: all - install -d ${PREFIX}/bin ${PREFIX}/etc/i2pd ${PREFIX}/share/doc/i2pd ${PREFIX}/share/i2pd ${PREFIX}/share/man/man1 ${PREFIX}/var/lib/i2pd - install -m 755 ${I2PD} ${PREFIX}/bin/ - install -m 644 contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/etc/i2pd - @cp -R contrib/certificates ${PREFIX}/share/i2pd/ - install -m 644 ChangeLog LICENSE README.md contrib/i2pd.conf contrib/subscriptions.txt contrib/tunnels.conf ${PREFIX}/share/doc/i2pd - @gzip debian/i2pd.1 && install debian/i2pd.1.gz ${PREFIX}/share/man/man1 - @ln -sf ${PREFIX}/share/i2pd/certificates ${PREFIX}/var/lib/i2pd/ - @ln -sf ${PREFIX}/etc/i2pd/i2pd.conf ${PREFIX}/var/lib/i2pd/i2pd.conf - @ln -sf ${PREFIX}/etc/i2pd/subscriptions.txt ${PREFIX}/var/lib/i2pd/subscriptions.txt - @ln -sf ${PREFIX}/etc/i2pd/tunnels.conf ${PREFIX}/var/lib/i2pd/tunnels.conf 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/i2pd.conf b/contrib/i2pd.conf index 123df754..92abf496 100644 --- a/contrib/i2pd.conf +++ b/contrib/i2pd.conf @@ -1,5 +1,5 @@ ## Configuration file for a typical i2pd user -## See https://i2pd.readthedocs.org/en/latest/configuration.html +## See https://i2pd.readthedocs.io/en/latest/user-guide/configuration/ ## for more options you can use in this file. ## Lines that begin with "## " try to explain what's going on. Lines diff --git a/contrib/rpm/i2pd-git.spec b/contrib/rpm/i2pd-git.spec index 3539c19b..627b81ae 100644 --- a/contrib/rpm/i2pd-git.spec +++ b/contrib/rpm/i2pd-git.spec @@ -1,7 +1,7 @@ %define git_hash %(git rev-parse HEAD | cut -c -7) Name: i2pd-git -Version: 2.20.0 +Version: 2.21.0 Release: git%{git_hash}%{?dist} Summary: I2P router written in C++ Conflicts: i2pd diff --git a/contrib/rpm/i2pd.spec b/contrib/rpm/i2pd.spec index edad8228..2deeecab 100644 --- a/contrib/rpm/i2pd.spec +++ b/contrib/rpm/i2pd.spec @@ -1,5 +1,5 @@ Name: i2pd -Version: 2.20.0 +Version: 2.21.0 Release: 1%{?dist} Summary: I2P router written in C++ Conflicts: i2pd-git @@ -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/debian/control b/debian/control index 8ef0b08c..843a153c 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ Source: i2pd Section: net Priority: optional -Maintainer: R4SAS +Maintainer: r4sas Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.17.2~), gcc (>= 4.7) | clang (>= 3.3), libboost-system-dev (>= 1.46), libboost-date-time-dev (>= 1.46), libboost-filesystem-dev (>= 1.46), libboost-program-options-dev (>= 1.46), libminiupnpc-dev, libssl-dev, zlib1g-dev Standards-Version: 3.9.6 Homepage: http://i2pd.website/ diff --git a/debian/patches/01-tune-build-opts.patch b/debian/patches/01-tune-build-opts.patch index 2dff9e09..dd2b4638 100644 --- a/debian/patches/01-tune-build-opts.patch +++ b/debian/patches/01-tune-build-opts.patch @@ -13,5 +13,5 @@ index bdadfe0..2f71eec 100644 USE_STATIC := no USE_MESHNET := no USE_UPNP := no - - ifeq ($(WEBSOCKETS),1) + DEBUG := yes + diff --git a/debian/patches/fix-#1210 b/debian/patches/fix-#1210 new file mode 100644 index 00000000..7e68135c --- /dev/null +++ b/debian/patches/fix-#1210 @@ -0,0 +1,25 @@ +Description: fix #1210 + Disables two options, which not presented in old systemd versions +Author: r4sas + +Bug: https://github.com/PurpleI2P/i2pd/issues/1210 +Reviewed-By: r4sas +Last-Update: 2018-08-25 + +--- i2pd-2.20.0.orig/contrib/i2pd.service ++++ i2pd-2.20.0/contrib/i2pd.service +@@ -6,10 +6,10 @@ After=network.target + [Service] + User=i2pd + Group=i2pd +-RuntimeDirectory=i2pd +-RuntimeDirectoryMode=0700 +-LogsDirectory=i2pd +-LogsDirectoryMode=0700 ++#RuntimeDirectory=i2pd ++#RuntimeDirectoryMode=0700 ++#LogsDirectory=i2pd ++#LogsDirectoryMode=0700 + Type=forking + ExecStart=/usr/sbin/i2pd --conf=/etc/i2pd/i2pd.conf --tunconf=/etc/i2pd/tunnels.conf --pidfile=/var/run/i2pd/i2pd.pid --logfile=/var/log/i2pd/i2pd.log --daemon --service + ExecReload=/bin/kill -HUP $MAINPID diff --git a/debian/patches/series b/debian/patches/series index 972d2a10..5a9712bd 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1 +1,2 @@ 01-tune-build-opts.patch +fix-#1210 diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 9eaaf068..3a3d6c09 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -34,6 +34,7 @@ namespace config { ("help", "Show this message") ("conf", value()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)") ("tunconf", value()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)") + ("tunnelsdir", value()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d") ("pidfile", value()->default_value(""), "Path to pidfile (default: ~/i2pd/i2pd.pid or /var/lib/i2pd/i2pd.pid)") ("log", value()->default_value(""), "Logs destination: stdout, file, syslog (stdout if not set)") ("logfile", value()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)") 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 43f1def9..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,14 +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 -#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/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index c91bfdb3..7f4d1ca3 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -36,7 +36,7 @@ namespace i2p std::shared_ptr NewI2NPMessage (size_t len) { - return (len < I2NP_MAX_SHORT_MESSAGE_SIZE/2) ? NewI2NPShortMessage () : NewI2NPMessage (); + return (len < I2NP_MAX_SHORT_MESSAGE_SIZE - I2NP_HEADER_SIZE - 2) ? NewI2NPShortMessage () : NewI2NPMessage (); } void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID) diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index deaa2292..15e3a32c 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -106,7 +106,7 @@ namespace tunnel class TunnelPool; } - const size_t I2NP_MAX_MESSAGE_SIZE = 32768; + const size_t I2NP_MAX_MESSAGE_SIZE = 62708; const size_t I2NP_MAX_SHORT_MESSAGE_SIZE = 4096; const unsigned int I2NP_MESSAGE_EXPIRATION_TIMEOUT = 8000; // in milliseconds (as initial RTT) const unsigned int I2NP_MESSAGE_CLOCK_SKEW = 60*1000; // 1 minute in milliseconds 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 58f928b4..1d60fef5 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,13 +30,11 @@ 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; @@ -56,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[] = { @@ -80,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) @@ -117,9 +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]; - i2p::crypto::GetEd25519 ()->ScalarMul (GetRemotePub (), GetPriv (), inputKeyMaterial, m_Ctx); + m_EphemeralKeys.Agree (GetRemotePub (), inputKeyMaterial); + MixKey (inputKeyMaterial, m_K); } @@ -136,21 +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 () { - RAND_bytes (m_EphemeralPrivateKey, 32); - i2p::crypto::GetEd25519 ()->ScalarMulB (m_EphemeralPrivateKey, m_EphemeralPublicKey, m_Ctx); + m_EphemeralKeys.GenerateKeys (); } void NTCP2Establisher::CreateSessionRequestMessage () @@ -393,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) { @@ -415,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 () @@ -624,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 (); @@ -677,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 @@ -704,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) { @@ -736,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 (); @@ -766,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); @@ -774,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 { @@ -853,6 +900,11 @@ namespace transport case eNTCP2BlkI2NPMessage: { LogPrint (eLogDebug, "NTCP2: I2NP"); + if (size > I2NP_MAX_MESSAGE_SIZE) + { + LogPrint (eLogError, "NTCP2: I2NP block is too long ", size); + break; + } auto nextMsg = NewI2NPMessage (size); nextMsg->len = nextMsg->offset + size + 7; // 7 more bytes for full I2NP header memcpy (nextMsg->GetNTCP2Header (), frame + offset, size); @@ -887,7 +939,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); @@ -939,6 +998,11 @@ namespace transport s += len; m_SendQueue.pop_front (); } + else if (len + 3 > NTCP2_UNENCRYPTED_FRAME_MAX_SIZE) + { + LogPrint (eLogError, "NTCP2: I2NP message of size ", len, " can't be sent. Dropped"); + m_SendQueue.pop_front (); + } else break; } @@ -1001,7 +1065,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 () @@ -1063,7 +1132,7 @@ namespace transport auto conn = std::make_shared (*this); m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, conn, std::placeholders::_1)); } catch ( std::exception & ex ) { - LogPrint(eLogError, "NTCP: failed to bind to ip6 port ", address->port); + LogPrint(eLogError, "NTCP2: failed to bind to ip6 port ", address->port); continue; } } @@ -1179,6 +1248,8 @@ namespace transport else { LogPrint (eLogDebug, "NTCP2: Connected to ", conn->GetSocket ().remote_endpoint ()); + if (conn->GetSocket ().local_endpoint ().protocol () == boost::asio::ip::tcp::v6()) // ipv6 + context.UpdateNTCP2V6Address (conn->GetSocket ().local_endpoint ().address ()); conn->ClientLogin (); } } diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 2b6748ab..7db6e8bf 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -18,7 +18,9 @@ #include #include #include +#include #include +#include "Crypto.h" #include "util.h" #include "RouterInfo.h" #include "TransportSession.h" @@ -37,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 { @@ -77,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 @@ -94,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 (); @@ -108,8 +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 + 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; @@ -147,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 (); @@ -186,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 a3d33113..9c1acfcc 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -173,6 +173,7 @@ namespace i2p if (address->IsNTCP2 () && (address->port != port || address->ntcp2->isPublished != publish)) { address->port = port; + address->cost = publish ? 3 : 14; address->ntcp2->isPublished = publish; address->ntcp2->iv = m_NTCP2Keys->iv; updated = true; @@ -453,6 +454,39 @@ namespace i2p UpdateRouterInfo (); } + void RouterContext::UpdateNTCP2V6Address (const boost::asio::ip::address& host) + { + bool updated = false, found = false; + int port = 0; + auto& addresses = m_RouterInfo.GetAddresses (); + for (auto& addr: addresses) + { + if (addr->IsPublishedNTCP2 ()) + { + if (addr->host.is_v6 ()) + { + if (addr->host != host) + { + addr->host = host; + updated = true; + } + found = true; + break; + } + else + port = addr->port; // NTCP2 v4 + } + } + + if (!found && port) // we have found NTCP2 v4 but not v6 + { + m_RouterInfo.AddNTCP2Address (m_NTCP2Keys->staticPublicKey, m_NTCP2Keys->iv, host, port); + updated = true; + } + if (updated) + UpdateRouterInfo (); + } + void RouterContext::UpdateStats () { if (m_IsFloodfill) @@ -464,6 +498,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); @@ -587,4 +627,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 f1a62c5a..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; }; @@ -100,7 +101,9 @@ namespace i2p void SetSupportsV4 (bool supportsV4); 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 @@ -132,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 @@ -142,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 79a70462..de7cd0be 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 } @@ -696,17 +694,17 @@ namespace data m_Caps |= eSSUIntroducer; } - void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv) + void RouterInfo::AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host, int port) { - for (const auto& it: *m_Addresses) // don't insert one more NTCP2 - if (it->ntcp2) return; auto addr = std::make_shared
(); - addr->port = 0; + addr->host = host; + addr->port = port; addr->transportStyle = eTransportNTCP; - addr->cost = 3; + addr->cost = port ? 3 : 14; // override from RouterContext::PublishNTCP2Address addr->date = 0; addr->ntcp2.reset (new NTCP2Ext ()); addr->ntcp2->isNTCP2Only = true; // NTCP2 only address + if (port) addr->ntcp2->isPublished = true; memcpy (addr->ntcp2->staticKey, staticKey, 32); memcpy (addr->ntcp2->iv, iv, 16); m_Addresses->push_back(std::move(addr)); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 47a5d680..f66a73fa 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -117,7 +117,8 @@ namespace data bool operator==(const Address& other) const { - return transportStyle == other.transportStyle && host == other.host && port == other.port; + return transportStyle == other.transportStyle && IsNTCP2 () == other.IsNTCP2 () && + host == other.host && port == other.port; } bool operator!=(const Address& other) const @@ -150,7 +151,7 @@ namespace data void AddNTCPAddress (const char * host, int port); void AddSSUAddress (const char * host, int port, const uint8_t * key, int mtu = 0); - void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv); + void AddNTCP2Address (const uint8_t * staticKey, const uint8_t * iv, const boost::asio::ip::address& host = boost::asio::ip::address(), int port = 0); bool AddIntroducer (const Introducer& introducer); bool RemoveIntroducer (const boost::asio::ip::udp::endpoint& e); void SetProperty (const std::string& key, const std::string& value); // called from RouterContext only diff --git a/libi2pd/SSUData.cpp b/libi2pd/SSUData.cpp index d789e70e..3ad5e769 100644 --- a/libi2pd/SSUData.cpp +++ b/libi2pd/SSUData.cpp @@ -320,7 +320,7 @@ namespace transport uint8_t * msgBuf = msg->GetSSUHeader (); uint32_t fragmentNum = 0; - while (len > 0) + while (len > 0 && fragmentNum <= 127) { Fragment * fragment = new Fragment; fragment->fragmentNum = fragmentNum; @@ -332,7 +332,7 @@ namespace transport payload++; htobe32buf (payload, msgID); payload += 4; - bool isLast = (len <= payloadSize); + bool isLast = (len <= payloadSize) || fragmentNum == 127; // 127 fragments max size_t size = isLast ? len : payloadSize; uint32_t fragmentInfo = (fragmentNum << 17); if (isLast) diff --git a/libi2pd/SSUSession.cpp b/libi2pd/SSUSession.cpp index 2a8cd2d5..255adf42 100644 --- a/libi2pd/SSUSession.cpp +++ b/libi2pd/SSUSession.cpp @@ -929,7 +929,13 @@ namespace transport if (m_State == eSessionStateEstablished) { for (const auto& it: msgs) - if (it) m_Data.Send (it); + if (it) + { + if (it->GetLength () <= SSU_MAX_I2NP_MESSAGE_SIZE) + m_Data.Send (it); + else + LogPrint (eLogError, "SSU: I2NP message of size ", it->GetLength (), " can't be sent. Dropped"); + } } } diff --git a/libi2pd/SSUSession.h b/libi2pd/SSUSession.h index 8247c420..7f053d37 100644 --- a/libi2pd/SSUSession.h +++ b/libi2pd/SSUSession.h @@ -28,6 +28,7 @@ namespace transport const int SSU_CONNECT_TIMEOUT = 5; // 5 seconds const int SSU_TERMINATION_TIMEOUT = 330; // 5.5 minutes const int SSU_CLOCK_SKEW = 60; // in seconds + const size_t SSU_MAX_I2NP_MESSAGE_SIZE = 32768; // payload types (4 bits) const uint8_t PAYLOAD_TYPE_SESSION_REQUEST = 0; diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index baa265bc..1facccbc 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -6,6 +6,26 @@ namespace i2p { namespace crypto { +#if OPENSSL_EDDSA + EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey) + { + m_Pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32); + m_MDCtx = EVP_MD_CTX_create (); + EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); + } + + EDDSA25519Verifier::~EDDSA25519Verifier () + { + EVP_MD_CTX_destroy (m_MDCtx); + EVP_PKEY_free (m_Pkey); + } + + bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const + { + return EVP_DigestVerify (m_MDCtx, signature, 64, buf, len); + } + +#else EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey) { memcpy (m_PublicKeyEncoded, signingKey, EDDSA25519_PUBLIC_KEY_LENGTH); @@ -14,6 +34,10 @@ namespace crypto BN_CTX_free (ctx); } + EDDSA25519Verifier::~EDDSA25519Verifier () + { + } + bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const { uint8_t digest[64]; @@ -26,8 +50,9 @@ namespace crypto return GetEd25519 ()->Verify (m_PublicKey, digest, signature); } +#endif - 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); @@ -47,10 +72,58 @@ namespace crypto BN_CTX_free (ctx); } - void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const + EDDSA25519SignerCompat::~EDDSA25519SignerCompat () + { + } + + 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 8b30a8e8..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 @@ -367,6 +276,8 @@ namespace crypto public: EDDSA25519Verifier (const uint8_t * signingKey); + ~EDDSA25519Verifier (); + bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; size_t GetPublicKeyLen () const { return EDDSA25519_PUBLIC_KEY_LENGTH; }; @@ -374,30 +285,72 @@ namespace crypto private: +#if OPENSSL_EDDSA + EVP_PKEY * m_Pkey; + EVP_MD_CTX * m_MDCtx; +#else EDDSAPoint m_PublicKey; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; +#endif }; - class EDDSA25519Signer: public Signer + class EDDSA25519SignerCompat: public Signer { public: - EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); + 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; }; + 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: + + EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); + // we pass signingPublicKey to check if it matches private key + ~EDDSA25519Signer (); + + void Sign (const uint8_t * buf, int len, uint8_t * signature) const; + + private: + EVP_PKEY * m_Pkey; + 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 + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_ED25519, NULL); + EVP_PKEY_keygen_init (pctx); + EVP_PKEY_keygen (pctx, &pkey); + EVP_PKEY_CTX_free (pctx); + size_t len = EDDSA25519_PUBLIC_KEY_LENGTH; + EVP_PKEY_get_raw_public_key (pkey, signingPublicKey, &len); + len = EDDSA25519_PRIVATE_KEY_LENGTH; + EVP_PKEY_get_raw_private_key (pkey, signingPrivateKey, &len); + EVP_PKEY_free (pkey); +#else RAND_bytes (signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH); EDDSA25519Signer signer (signingPrivateKey); memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH); +#endif } 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/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index e745ceaf..30ae7172 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -741,7 +741,7 @@ namespace client std::string response; uint8_t recv_buf[4096]; bool end = false; - int numAttempts = 5; + int numAttempts = 0; while (!end) { stream->AsyncReceive (boost::asio::buffer (recv_buf, 4096), diff --git a/libi2pd_client/ClientContext.cpp b/libi2pd_client/ClientContext.cpp index b58677c8..257087ee 100644 --- a/libi2pd_client/ClientContext.cpp +++ b/libi2pd_client/ClientContext.cpp @@ -410,18 +410,44 @@ namespace client void ClientContext::ReadTunnels () { - boost::property_tree::ptree pt; + int numClientTunnels = 0, numServerTunnels = 0; std::string tunConf; i2p::config::GetOption("tunconf", tunConf); - if (tunConf == "") { + if (tunConf.empty ()) + { // TODO: cleanup this in 2.8.0 tunConf = i2p::fs::DataDirPath ("tunnels.cfg"); - if (i2p::fs::Exists(tunConf)) { - LogPrint(eLogWarning, "FS: please rename tunnels.cfg -> tunnels.conf here: ", tunConf); - } else { + if (i2p::fs::Exists(tunConf)) + LogPrint(eLogWarning, "Clients: please rename tunnels.cfg -> tunnels.conf here: ", tunConf); + else tunConf = i2p::fs::DataDirPath ("tunnels.conf"); + } + LogPrint(eLogDebug, "Clients: tunnels config file: ", tunConf); + ReadTunnels (tunConf, numClientTunnels, numServerTunnels); + + std::string tunDir; i2p::config::GetOption("tunnelsdir", tunDir); + if (tunDir.empty ()) + tunDir = i2p::fs::DataDirPath ("tunnels.d"); + if (i2p::fs::Exists (tunDir)) + { + std::vector files; + if (i2p::fs::ReadDir (tunDir, files)) + { + for (auto& it: files) + { + LogPrint(eLogDebug, "Clients: tunnels extra config file: ", it); + ReadTunnels (it, numClientTunnels, numServerTunnels); + } } } - LogPrint(eLogDebug, "FS: tunnels config file: ", tunConf); + + LogPrint (eLogInfo, "Clients: ", numClientTunnels, " I2P client tunnels created"); + LogPrint (eLogInfo, "Clients: ", numServerTunnels, " I2P server tunnels created"); + } + + + void ClientContext::ReadTunnels (const std::string& tunConf, int& numClientTunnels, int& numServerTunnels) + { + boost::property_tree::ptree pt; try { boost::property_tree::read_ini (tunConf, pt); @@ -432,7 +458,6 @@ namespace client return; } - int numClientTunnels = 0, numServerTunnels = 0; for (auto& section: pt) { std::string name = section.first; @@ -672,8 +697,6 @@ namespace client LogPrint (eLogError, "Clients: Can't read tunnel ", name, " params: ", ex.what ()); } } - LogPrint (eLogInfo, "Clients: ", numClientTunnels, " I2P client tunnels created"); - LogPrint (eLogInfo, "Clients: ", numServerTunnels, " I2P server tunnels created"); } void ClientContext::ReadHttpProxy () diff --git a/libi2pd_client/ClientContext.h b/libi2pd_client/ClientContext.h index 06aab3b1..a0c92045 100644 --- a/libi2pd_client/ClientContext.h +++ b/libi2pd_client/ClientContext.h @@ -87,6 +87,7 @@ namespace client private: void ReadTunnels (); + void ReadTunnels (const std::string& tunConf, int& numClientTunnels, int& numServerTunnels); void ReadHttpProxy (); void ReadSocksProxy (); template diff --git a/libi2pd_client/SAM.cpp b/libi2pd_client/SAM.cpp index ac2dd853..b7bf6002 100644 --- a/libi2pd_client/SAM.cpp +++ b/libi2pd_client/SAM.cpp @@ -1027,11 +1027,29 @@ namespace client { auto it = params->find (SAM_PARAM_SIGNATURE_TYPE); if (it != params->end ()) + { // TODO: extract string values - signatureType = std::stoi(it->second); + try + { + signatureType = std::stoi(it->second); + } + catch (const std::exception& ex) + { + LogPrint (eLogWarning, "SAM: ", SAM_PARAM_SIGNATURE_TYPE, "error: ", ex.what ()); + } + } it = params->find (SAM_PARAM_CRYPTO_TYPE); if (it != params->end ()) - cryptoType = std::stoi(it->second); + { + try + { + cryptoType = std::stoi(it->second); + } + catch (const std::exception& ex) + { + LogPrint (eLogWarning, "SAM: ", SAM_PARAM_CRYPTO_TYPE, "error: ", ex.what ()); + } + } } localDestination = i2p::client::context.CreateNewLocalDestination (true, signatureType, cryptoType, params); } diff --git a/libi2pd_client/SAM.h b/libi2pd_client/SAM.h index 953af1cd..dde6e675 100644 --- a/libi2pd_client/SAM.h +++ b/libi2pd_client/SAM.h @@ -46,7 +46,7 @@ namespace client const char SAM_NAMING_REPLY[] = "NAMING REPLY RESULT=OK NAME=ME VALUE=%s\n"; const char SAM_DATAGRAM_RECEIVED[] = "DATAGRAM RECEIVED DESTINATION=%s SIZE=%lu\n"; const char SAM_NAMING_REPLY_INVALID_KEY[] = "NAMING REPLY RESULT=INVALID_KEY NAME=%s\n"; - const char SAM_NAMING_REPLY_KEY_NOT_FOUND[] = "NAMING REPLY RESULT=INVALID_KEY_NOT_FOUND NAME=%s\n"; + const char SAM_NAMING_REPLY_KEY_NOT_FOUND[] = "NAMING REPLY RESULT=KEY_NOT_FOUND NAME=%s\n"; const char SAM_PARAM_MIN[] = "MIN"; const char SAM_PARAM_MAX[] = "MAX"; const char SAM_PARAM_STYLE[] = "STYLE"; 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, "");