mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-04-23 17:36:37 +02:00
commit
276a78cb2e
42 changed files with 752 additions and 465 deletions
69
.travis.yml
69
.travis.yml
|
@ -2,34 +2,53 @@ language: cpp
|
||||||
cache:
|
cache:
|
||||||
apt: true
|
apt: true
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
sudo: required
|
- osx
|
||||||
dist: trusty
|
dist: trusty
|
||||||
|
sudo: required
|
||||||
|
compiler:
|
||||||
|
- g++
|
||||||
|
- clang++
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- MAKEFLAGS="-j 2"
|
||||||
|
matrix:
|
||||||
|
- BUILD_TYPE=make UPNP=ON MAKE_UPNP=yes
|
||||||
|
- BUILD_TYPE=make UPNP=OFF MAKE_UPNP=no
|
||||||
|
- BUILD_TYPE=cmake UPNP=ON MAKE_UPNP=yes
|
||||||
|
- BUILD_TYPE=cmake UPNP=OFF MAKE_UPNP=no
|
||||||
|
matrix:
|
||||||
|
exclude:
|
||||||
|
- os: osx
|
||||||
|
env: BUILD_TYPE=cmake UPNP=ON MAKE_UPNP=yes
|
||||||
|
- os: osx
|
||||||
|
env: BUILD_TYPE=cmake UPNP=OFF MAKE_UPNP=no
|
||||||
|
- os: linux
|
||||||
|
compiler: clang++
|
||||||
|
env: BUILD_TYPE=make UPNP=ON MAKE_UPNP=yes
|
||||||
|
- os: linux
|
||||||
|
compiler: clang++
|
||||||
|
env: BUILD_TYPE=make UPNP=OFF MAKE_UPNP=no
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- build-essential
|
- build-essential
|
||||||
- cmake
|
- cmake
|
||||||
- g++
|
- g++
|
||||||
- clang
|
- clang
|
||||||
- libboost-chrono-dev
|
- libboost-chrono-dev
|
||||||
- libboost-date-time-dev
|
- libboost-date-time-dev
|
||||||
- libboost-filesystem-dev
|
- libboost-filesystem-dev
|
||||||
- libboost-program-options-dev
|
- libboost-program-options-dev
|
||||||
- libboost-system-dev
|
- libboost-system-dev
|
||||||
- libboost-thread-dev
|
- libboost-thread-dev
|
||||||
- libminiupnpc-dev
|
- libminiupnpc-dev
|
||||||
- libssl-dev
|
- libssl-dev
|
||||||
compiler:
|
|
||||||
- gcc
|
|
||||||
- clang
|
|
||||||
before_install:
|
before_install:
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openssl miniupnpc ; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libressl miniupnpc ; fi
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew unlink boost openssl && brew link boost openssl -f ; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated boost || brew upgrade boost ; fi
|
||||||
env:
|
|
||||||
matrix:
|
|
||||||
- BUILD_TYPE=Release UPNP=ON
|
|
||||||
- BUILD_TYPE=Release UPNP=OFF
|
|
||||||
script:
|
script:
|
||||||
- cd build && cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DWITH_UPNP=${UPNP} && make
|
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_TYPE" == "cmake" ]]; then cd build && cmake -DCMAKE_BUILD_TYPE=Release -DWITH_UPNP=${UPNP} && make ; fi
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$BUILD_TYPE" == "make" ]]; then make USE_UPNP=${MAKE_UPNP} ; fi
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then make HOMEBREW=1 USE_UPNP=${MAKE_UPNP} ; fi
|
||||||
|
|
17
ChangeLog
17
ChangeLog
|
@ -1,6 +1,23 @@
|
||||||
# for this file format description,
|
# for this file format description,
|
||||||
# see https://github.com/olivierlacan/keep-a-changelog
|
# see https://github.com/olivierlacan/keep-a-changelog
|
||||||
|
|
||||||
|
## [2.16.0] - 2017-11-13
|
||||||
|
### Added
|
||||||
|
- https and "Connect" method for HTTP proxy
|
||||||
|
- outproxy for HTTP proxy
|
||||||
|
- initial support of ECIES crypto
|
||||||
|
- NTCP soft and hard descriptors limits
|
||||||
|
- Support full timestamps in logs
|
||||||
|
### Changed
|
||||||
|
- Faster implmentation of GOST R 34.11 hash
|
||||||
|
- Reject routers with RSA signtures
|
||||||
|
- Reload config and shudown from Windows GUI
|
||||||
|
- Update tunnels address(destination) without restart
|
||||||
|
### Fixed
|
||||||
|
- BOB crashes if destination is not set
|
||||||
|
- Correct SAM tunnel name
|
||||||
|
- QT GUI issues
|
||||||
|
|
||||||
## [2.15.0] - 2017-08-17
|
## [2.15.0] - 2017-08-17
|
||||||
### Added
|
### Added
|
||||||
- QT GUI
|
- QT GUI
|
||||||
|
|
|
@ -3,27 +3,30 @@ BREWROOT = /usr/local
|
||||||
BOOSTROOT = ${BREWROOT}/opt/boost
|
BOOSTROOT = ${BREWROOT}/opt/boost
|
||||||
SSLROOT = ${BREWROOT}/opt/libressl
|
SSLROOT = ${BREWROOT}/opt/libressl
|
||||||
UPNPROOT = ${BREWROOT}/opt/miniupnpc
|
UPNPROOT = ${BREWROOT}/opt/miniupnpc
|
||||||
CXX = clang++
|
|
||||||
CXXFLAGS = -g -Wall -std=c++11 -DMAC_OSX -Wno-overloaded-virtual
|
CXXFLAGS = -g -Wall -std=c++11 -DMAC_OSX -Wno-overloaded-virtual
|
||||||
INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include
|
INCFLAGS = -I${SSLROOT}/include -I${BOOSTROOT}/include
|
||||||
|
|
||||||
|
ifndef TRAVIS
|
||||||
|
CXX = clang++
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_STATIC),yes)
|
ifeq ($(USE_STATIC),yes)
|
||||||
LDLIBS = -lz ${SSLROOT}/lib/libcrypto.a ${SSLROOT}/lib/libssl.a ${BOOSTROOT}/lib/libboost_system.a ${BOOSTROOT}/lib/libboost_date_time.a ${BOOSTROOT}/lib/libboost_filesystem.a ${BOOSTROOT}/lib/libboost_program_options.a -lpthread
|
LDLIBS = -lz ${SSLROOT}/lib/libcrypto.a ${SSLROOT}/lib/libssl.a ${BOOSTROOT}/lib/libboost_system.a ${BOOSTROOT}/lib/libboost_date_time.a ${BOOSTROOT}/lib/libboost_filesystem.a ${BOOSTROOT}/lib/libboost_program_options.a -lpthread
|
||||||
else
|
else
|
||||||
LDFLAGS = -L${SSLROOT}/lib -L${BOOSTROOT}/lib
|
LDFLAGS = -L${SSLROOT}/lib -L${BOOSTROOT}/lib
|
||||||
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_UPNP),yes)
|
ifeq ($(USE_UPNP),yes)
|
||||||
LDFLAGS += -ldl
|
LDFLAGS += -ldl
|
||||||
CXXFLAGS += -DUSE_UPNP
|
CXXFLAGS += -DUSE_UPNP
|
||||||
INCFLAGS += -I${UPNPROOT}/include
|
INCFLAGS += -I${UPNPROOT}/include
|
||||||
ifeq ($(USE_STATIC),yes)
|
ifeq ($(USE_STATIC),yes)
|
||||||
LDLIBS += ${UPNPROOT}/lib/libminiupnpc.a
|
LDLIBS += ${UPNPROOT}/lib/libminiupnpc.a
|
||||||
else
|
else
|
||||||
LDFLAGS += -L${UPNPROOT}/lib
|
LDFLAGS += -L${UPNPROOT}/lib
|
||||||
LDLIBS += -lminiupnpc
|
LDLIBS += -lminiupnpc
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# OSX Notes
|
# OSX Notes
|
||||||
|
|
24
Makefile.osx
24
Makefile.osx
|
@ -5,29 +5,29 @@ INCFLAGS = -I/usr/local/include
|
||||||
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
LDFLAGS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib
|
||||||
|
|
||||||
ifeq ($(USE_STATIC),yes)
|
ifeq ($(USE_STATIC),yes)
|
||||||
LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread
|
LDLIBS = -lz /usr/local/lib/libcrypto.a /usr/local/lib/libssl.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_date_time.a /usr/local/lib/libboost_filesystem.a /usr/local/lib/libboost_program_options.a -lpthread
|
||||||
else
|
else
|
||||||
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
LDLIBS = -lz -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_UPNP),yes)
|
ifeq ($(USE_UPNP),yes)
|
||||||
LDFLAGS += -ldl
|
LDFLAGS += -ldl
|
||||||
CXXFLAGS += -DUSE_UPNP
|
CXXFLAGS += -DUSE_UPNP
|
||||||
ifeq ($(USE_STATIC),yes)
|
ifeq ($(USE_STATIC),yes)
|
||||||
LDLIBS += /usr/local/lib/libminiupnpc.a
|
LDLIBS += /usr/local/lib/libminiupnpc.a
|
||||||
else
|
else
|
||||||
LDLIBS += -lminiupnpc
|
LDLIBS += -lminiupnpc
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_AESNI),1)
|
ifeq ($(USE_AESNI),1)
|
||||||
CXXFLAGS += -maes -DAESNI
|
CXXFLAGS += -maes -DAESNI
|
||||||
else
|
else
|
||||||
CXXFLAGS += -msse
|
CXXFLAGS += -msse
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(USE_AVX),1)
|
ifeq ($(USE_AVX),1)
|
||||||
CXXFLAGS += -mavx
|
CXXFLAGS += -mavx
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Disabled, since it will be the default make rule. I think its better
|
# Disabled, since it will be the default make rule. I think its better
|
||||||
|
|
|
@ -54,9 +54,9 @@ Build instructions:
|
||||||
|
|
||||||
**Supported systems:**
|
**Supported systems:**
|
||||||
|
|
||||||
* GNU/Linux x86/x64 - [](https://travis-ci.org/PurpleI2P/i2pd)
|
* GNU/Linux x86/x64 - [](https://travis-ci.org/PurpleI2P/i2pd)
|
||||||
* Windows - [](https://ci.appveyor.com/project/PurpleI2P/i2pd)
|
* Windows - [](https://ci.appveyor.com/project/PurpleI2P/i2pd)
|
||||||
* Mac OS X
|
* Mac OS X - [](https://travis-ci.org/PurpleI2P/i2pd)
|
||||||
* FreeBSD
|
* FreeBSD
|
||||||
* Android
|
* Android
|
||||||
* iOS
|
* iOS
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#define I2Pd_AppName "i2pd"
|
#define I2Pd_AppName "i2pd"
|
||||||
#define I2Pd_ver "2.15.0"
|
#define I2Pd_ver "2.16.0"
|
||||||
#define I2Pd_Publisher "PurpleI2P"
|
#define I2Pd_Publisher "PurpleI2P"
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.purplei2p.i2pd"
|
package="org.purplei2p.i2pd"
|
||||||
android:versionCode="1"
|
android:versionCode="1"
|
||||||
android:versionName="2.15.0"
|
android:versionName="2.16.0"
|
||||||
android:installLocation="auto">
|
android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="25"/>
|
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="25"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
version: 2.15.{build}
|
version: 2.16.{build}
|
||||||
pull_requests:
|
pull_requests:
|
||||||
do_not_increment_build_number: true
|
do_not_increment_build_number: true
|
||||||
branches:
|
branches:
|
||||||
|
|
|
@ -150,7 +150,7 @@ else()
|
||||||
if (MSYS OR MINGW)
|
if (MSYS OR MINGW)
|
||||||
add_definitions( -DWIN32_LEAN_AND_MEAN )
|
add_definitions( -DWIN32_LEAN_AND_MEAN )
|
||||||
endif ()
|
endif ()
|
||||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch" )
|
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Winvalid-pch -Wno-unused-parameter" )
|
||||||
set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic" )
|
set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -pedantic" )
|
||||||
# TODO: The following is incompatible with static build and enabled hardening for OpenWRT.
|
# TODO: The following is incompatible with static build and enabled hardening for OpenWRT.
|
||||||
# Multiple definitions of __stack_chk_fail (libssp & libc)
|
# Multiple definitions of __stack_chk_fail (libssp & libc)
|
||||||
|
@ -180,7 +180,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
# more tweaks
|
# more tweaks
|
||||||
if (NOT (MSVC OR MSYS OR APPLE))
|
if (NOT (MSVC OR MSYS OR APPLE))
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++" )
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-const-variable -Wno-overloaded-virtual -Wno-c99-extensions" )
|
||||||
endif()
|
endif()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIFezCCA2OgAwIBAgIEb8xTzzANBgkqhkiG9w0BAQ0FADBuMQswCQYDVQQGEwJY
|
|
||||||
WDELMAkGA1UECBMCWFgxHjAcBgNVBAcTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEL
|
|
||||||
MAkGA1UEChMCWFgxDDAKBgNVBAsTA0kyUDEXMBUGA1UEAwwOcjRzYXNAbWFpbC5p
|
|
||||||
MnAwHhcNMTYwODExMjIyNDM2WhcNMjYwODExMjIyNDM2WjBuMQswCQYDVQQGEwJY
|
|
||||||
WDELMAkGA1UECBMCWFgxHjAcBgNVBAcTFUkyUCBBbm9ueW1vdXMgTmV0d29yazEL
|
|
||||||
MAkGA1UEChMCWFgxDDAKBgNVBAsTA0kyUDEXMBUGA1UEAwwOcjRzYXNAbWFpbC5p
|
|
||||||
MnAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDjUMy/aYd0i6Oc3rdc
|
|
||||||
24V/fM2vhviH+cNhAOXsMSrwDSVbFQkuDPIfq4fo1A25rsyULR57vy7XKA51OstX
|
|
||||||
GvREPDhth4cMZjthq0f8AVzPq2vIk8Po65uvKR190yupPQ4FhvGeRkHkqp+SqoIJ
|
|
||||||
lClD8xZEHrUHSYZotm5TLWIgSwa4DuO1q3bMRI8oIWzqhv99FtlmHlC8fjVUN4mR
|
|
||||||
2czhABr0u6RMPOtJwTVxWgT1PKXiLWfmeHb63TcPYGgpJ39iMDOjtgY9jYueoO8J
|
|
||||||
uGJJtkGRIRjOuhDFE9NUlNnljUxUDWvMU7zCO4ozaKMZgoxr1WoIO6ubI/003I53
|
|
||||||
sZ0Q5h8yfz+QreEw3wzjxnQSkejG5c3NIvJSiu0ylOqDWmnj0v1Jv/P0qAMU4bt/
|
|
||||||
ZWj0GOrYfPn9STg0VxMOQwQ2o15GAcbr6PFI56U2IJhZAeER3hIe2kOl6591jQ67
|
|
||||||
zvOjPRRh2q05Ss8yo7nEpYUiB/FrE6RssJ5tVwX6e6Tq4Z1frINanIkUkToTkypP
|
|
||||||
Fn2T/KV2lak9rLuxzvhiDobu5iGCR323zFcFEpGq4Wsopx1uRT9+71G/ejw8pKTf
|
|
||||||
kQ7XiGaaxFyZuMuOz3bFkTuoTmAkUQTlRjGw2DmKZi/apcN+VQgpq9tQpS10pEUy
|
|
||||||
DCVdtw1AdlOnwb+Hf3X0Uz6OjwIDAQABoyEwHzAdBgNVHQ4EFgQUqLBlSlnqCo25
|
|
||||||
sIduMPm4iROMqkAwDQYJKoZIhvcNAQENBQADggIBAGWv8rDTzqhHkjqDOT+Ba2bs
|
|
||||||
gVddpCNa94RQoOn2DUSu4c+yuWJLSctjpX7gswB6qvWk5Ojfafop8jJW8zuozJrO
|
|
||||||
76b9345S/VnnbHVSoVfIpF9Fve1Xc8nvU4ylRcAMwhf8N3Md5Yc1kb+P7NtTTwMZ
|
|
||||||
TBR3xY3fVxv3qTpKApWQKkUiqM7yJKOfS8xcK/pjO/3oRUwfA9DHugCUpgSidlN+
|
|
||||||
JkZmgwAcA3/WMlDdNKmKnWLGB2Ea+W6kIx5TDFfjf11rbjuwXhDLyaOK88qlN0W2
|
|
||||||
hYa31UDSEYYQd3gMG1gjVc+9vZA/Vr0+SF5ULN9QLjB18CVIdPv92mBjJQRmJSVW
|
|
||||||
b1qwZI0jf/V+1fu9H9r7sE4CId3+WGOek3UNRNZLOVZCSiFq/b9cswcQZGjw6aE+
|
|
||||||
1FNjw1HW9CLoNcg74Kr98QouOoeRSofQYZiYqaM9Sz/MsinYMIRGRGw3Uq1uNRo0
|
|
||||||
WgoOngmZSKGaW5PFR19uuuNIVB4fCShqBVyrguW4xIskta1JVFoggFeOeTwk6/kH
|
|
||||||
S5roMzyB/kzv83A2IB0VxqbiDj8khgdm1Us6HCCmU+iTRVyG28gFklCJ8dQfxgGH
|
|
||||||
W2gpIwvxYLyNP14/7E1oF7/NfHmyjAVzYnR5Xw2wE4tvSHuIrHhj6Q26VB3vze6j
|
|
||||||
E/w1AJEepnw/KfHqS3bw
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -23,7 +23,8 @@
|
||||||
# log = file
|
# log = file
|
||||||
## Path to logfile (default - autodetect)
|
## Path to logfile (default - autodetect)
|
||||||
# logfile = /var/log/i2pd.log
|
# logfile = /var/log/i2pd.log
|
||||||
## Log messages above this level (debug, *info, warn, error)
|
## Log messages above this level (debug, *info, warn, error, none)
|
||||||
|
## If you set it to none, logging will be disabled
|
||||||
# loglevel = info
|
# loglevel = info
|
||||||
|
|
||||||
## Path to storage of i2pd data (RI, keys, peer profiles, ...)
|
## Path to storage of i2pd data (RI, keys, peer profiles, ...)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
%define build_timestamp %(date +"%Y%m%d")
|
%define build_timestamp %(date +"%Y%m%d")
|
||||||
|
|
||||||
Name: i2pd
|
Name: i2pd
|
||||||
Version: 2.15.0
|
Version: 2.16.0
|
||||||
Release: %{build_timestamp}git%{?dist}
|
Release: %{build_timestamp}git%{?dist}
|
||||||
Summary: I2P router written in C++
|
Summary: I2P router written in C++
|
||||||
|
|
||||||
|
@ -103,6 +103,20 @@ getent passwd i2pd >/dev/null || \
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Nov 13 2017 orignal <i2porignal@yandex.ru> - 2.16.0
|
||||||
|
- Added https and "Connect" method for HTTP proxy
|
||||||
|
- Added outproxy for HTTP proxy
|
||||||
|
- Added initial support of ECIES crypto
|
||||||
|
- Added NTCP soft and hard descriptors limits
|
||||||
|
- Added support full timestamps in logs
|
||||||
|
- Changed faster implmentation of GOST R 34.11 hash
|
||||||
|
- Changed reject routers with RSA signtures
|
||||||
|
- Changed reload config and shudown from Windows GUI
|
||||||
|
- Changed update tunnels address(destination) without restart
|
||||||
|
- Fixed BOB crashes if destination is not set
|
||||||
|
- Fixed correct SAM tunnel name
|
||||||
|
- Fixed QT GUI issues
|
||||||
|
|
||||||
* Thu Aug 17 2017 orignal <i2porignal@yandex.ru> - 2.15.0
|
* Thu Aug 17 2017 orignal <i2porignal@yandex.ru> - 2.15.0
|
||||||
- Added QT GUI
|
- Added QT GUI
|
||||||
- Added ability add and remove I2P tunnels without restart
|
- Added ability add and remove I2P tunnels without restart
|
||||||
|
|
|
@ -60,12 +60,14 @@ namespace http {
|
||||||
" .tunnel.established { color: #56B734; }\r\n"
|
" .tunnel.established { color: #56B734; }\r\n"
|
||||||
" .tunnel.expiring { color: #D3AE3F; }\r\n"
|
" .tunnel.expiring { color: #D3AE3F; }\r\n"
|
||||||
" .tunnel.failed { color: #D33F3F; }\r\n"
|
" .tunnel.failed { color: #D33F3F; }\r\n"
|
||||||
" .tunnel.another { color: #434343; }\r\n"
|
" .tunnel.building { color: #434343; }\r\n"
|
||||||
" caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n"
|
" caption { font-size: 1.5em; text-align: center; color: #894C84; }\r\n"
|
||||||
" table { width: 100%; border-collapse: collapse; text-align: center; }\r\n"
|
" table { width: 100%; border-collapse: collapse; text-align: center; }\r\n"
|
||||||
" .private { background: black; color: black; } .private:hover { background: black; color: white } \r\n"
|
" .slide label { color: #894C84 }\r\n"
|
||||||
" .slide p, .slide [type='checkbox']{ display:none; } \r\n"
|
" .slide p, .slide [type='checkbox']{ display:none; }\r\n"
|
||||||
" .slide [type='checkbox']:checked ~ p { display:block; } \r\n"
|
" .slide [type='checkbox']:checked ~ p { display:block; margin-top: 0; padding: 0; }\r\n"
|
||||||
|
" .disabled:after { color: #D33F3F; content: \"Disabled\" }\r\n"
|
||||||
|
" .enabled:after { color: #56B734; content: \"Enabled\" }\r\n"
|
||||||
"</style>\r\n";
|
"</style>\r\n";
|
||||||
|
|
||||||
const char HTTP_PAGE_TUNNELS[] = "tunnels";
|
const char HTTP_PAGE_TUNNELS[] = "tunnels";
|
||||||
|
@ -270,7 +272,17 @@ namespace http {
|
||||||
size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels();
|
size_t transitTunnelCount = i2p::tunnel::tunnels.CountTransitTunnels();
|
||||||
|
|
||||||
s << "<b>Client Tunnels:</b> " << std::to_string(clientTunnelCount) << " ";
|
s << "<b>Client Tunnels:</b> " << std::to_string(clientTunnelCount) << " ";
|
||||||
s << "<b>Transit Tunnels:</b> " << std::to_string(transitTunnelCount) << "<br>\r\n";
|
s << "<b>Transit Tunnels:</b> " << std::to_string(transitTunnelCount) << "<br>\r\n<br>\r\n";
|
||||||
|
|
||||||
|
s << "<table><caption>Services</caption><tr><th>Service</th><th>State</th></tr>\r\n";
|
||||||
|
s << "<tr><td>" << "HTTP Proxy" << "</td><td><div class='" << ((i2p::client::context.GetHttpProxy ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||||
|
s << "<tr><td>" << "SOCKS Proxy" << "</td><td><div class='" << ((i2p::client::context.GetSocksProxy ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||||
|
s << "<tr><td>" << "BOB" << "</td><td><div class='" << ((i2p::client::context.GetBOBCommandChannel ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||||
|
s << "<tr><td>" << "SAM" << "</td><td><div class='" << ((i2p::client::context.GetSAMBridge ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||||
|
s << "<tr><td>" << "I2CP" << "</td><td><div class='" << ((i2p::client::context.GetI2CPServer ()) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||||
|
bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
|
||||||
|
s << "<tr><td>" << "I2PControl" << "</td><td><div class='" << ((i2pcontrol) ? "enabled" : "disabled") << "'></div></td></tr>\r\n";
|
||||||
|
s << "</table>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowLocalDestinations (std::stringstream& s)
|
void ShowLocalDestinations (std::stringstream& s)
|
||||||
|
@ -284,7 +296,7 @@ namespace http {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
auto i2cpServer = i2p::client::context.GetI2CPServer ();
|
||||||
if (i2cpServer)
|
if (i2cpServer && !(i2cpServer->GetSessions ().empty ()))
|
||||||
{
|
{
|
||||||
s << "<br><b>I2CP Local Destinations:</b><br>\r\n<br>\r\n";
|
s << "<br><b>I2CP Local Destinations:</b><br>\r\n<br>\r\n";
|
||||||
for (auto& it: i2cpServer->GetSessions ())
|
for (auto& it: i2cpServer->GetSessions ())
|
||||||
|
@ -304,14 +316,14 @@ namespace http {
|
||||||
{
|
{
|
||||||
s << "<b>Base64:</b><br>\r\n<textarea readonly=\"readonly\" cols=\"64\" rows=\"11\" wrap=\"on\">";
|
s << "<b>Base64:</b><br>\r\n<textarea readonly=\"readonly\" cols=\"64\" rows=\"11\" wrap=\"on\">";
|
||||||
s << dest->GetIdentity ()->ToBase64 () << "</textarea><br>\r\n<br>\r\n";
|
s << dest->GetIdentity ()->ToBase64 () << "</textarea><br>\r\n<br>\r\n";
|
||||||
s << "<b>LeaseSets:</b> <i>" << dest->GetNumRemoteLeaseSets () << "</i><br>\r\n";
|
|
||||||
if(dest->GetNumRemoteLeaseSets())
|
if(dest->GetNumRemoteLeaseSets())
|
||||||
{
|
{
|
||||||
s << "<div class='slide'\r\n><label for='slide1'>Hidden content. Press on text to see.</label>\r\n<input type='checkbox' id='slide1'/>\r\n<p class='content'>\r\n";
|
s << "<div class='slide'\r\n><label for='slide1'><b>LeaseSets:</b> <i>" << dest->GetNumRemoteLeaseSets () << "</i></label>\r\n<input type='checkbox' id='slide1'/>\r\n<p class='content'>\r\n";
|
||||||
for(auto& it: dest->GetLeaseSets ())
|
for(auto& it: dest->GetLeaseSets ())
|
||||||
s << it.second->GetIdentHash ().ToBase32 () << "<br>\r\n";
|
s << it.second->GetIdentHash ().ToBase32 () << "<br>\r\n";
|
||||||
s << "</p>\r\n</div>\r\n";
|
s << "</p>\r\n</div>\r\n";
|
||||||
}
|
} else
|
||||||
|
s << "<b>LeaseSets:</b> <i>0</i><br>\r\n";
|
||||||
auto pool = dest->GetTunnelPool ();
|
auto pool = dest->GetTunnelPool ();
|
||||||
if (pool)
|
if (pool)
|
||||||
{
|
{
|
||||||
|
@ -401,7 +413,7 @@ namespace http {
|
||||||
|
|
||||||
void ShowLeasesSets(std::stringstream& s)
|
void ShowLeasesSets(std::stringstream& s)
|
||||||
{
|
{
|
||||||
s << "<div id='leasesets'><b>LeaseSets (click on to show info):</b></div><br>\r\n";
|
s << "<b>LeaseSets:</b><br>\r\n<br>\r\n";
|
||||||
int counter = 1;
|
int counter = 1;
|
||||||
// for each lease set
|
// for each lease set
|
||||||
i2p::data::netdb.VisitLeaseSets(
|
i2p::data::netdb.VisitLeaseSets(
|
||||||
|
@ -434,6 +446,7 @@ namespace http {
|
||||||
|
|
||||||
void ShowTunnels (std::stringstream& s)
|
void ShowTunnels (std::stringstream& s)
|
||||||
{
|
{
|
||||||
|
s << "<b>Tunnels:</b><br>\r\n<br>\r\n";
|
||||||
s << "<b>Queue size:</b> " << i2p::tunnel::tunnels.GetQueueSize () << "<br>\r\n";
|
s << "<b>Queue size:</b> " << i2p::tunnel::tunnels.GetQueueSize () << "<br>\r\n";
|
||||||
|
|
||||||
s << "<b>Inbound tunnels:</b><br>\r\n";
|
s << "<b>Inbound tunnels:</b><br>\r\n";
|
||||||
|
@ -457,7 +470,7 @@ namespace http {
|
||||||
static void ShowCommands (std::stringstream& s, uint32_t token)
|
static void ShowCommands (std::stringstream& s, uint32_t token)
|
||||||
{
|
{
|
||||||
/* commands */
|
/* commands */
|
||||||
s << "<b>Router Commands</b><br>\r\n";
|
s << "<b>Router Commands</b><br>\r\n<br>\r\n";
|
||||||
s << " <a href=\"/?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << "&token=" << token << "\">Run peer test</a><br>\r\n";
|
s << " <a href=\"/?cmd=" << HTTP_COMMAND_RUN_PEER_TEST << "&token=" << token << "\">Run peer test</a><br>\r\n";
|
||||||
//s << " <a href=\"/?cmd=" << HTTP_COMMAND_RELOAD_CONFIG << "\">Reload config</a><br>\r\n";
|
//s << " <a href=\"/?cmd=" << HTTP_COMMAND_RELOAD_CONFIG << "\">Reload config</a><br>\r\n";
|
||||||
if (i2p::context.AcceptsTunnels ())
|
if (i2p::context.AcceptsTunnels ())
|
||||||
|
@ -529,13 +542,13 @@ namespace http {
|
||||||
}
|
}
|
||||||
if (!tmp_s.str ().empty ())
|
if (!tmp_s.str ().empty ())
|
||||||
{
|
{
|
||||||
s << "<b>NTCP</b> ( " << cnt << " )<br>\r\n";
|
s << "<div class='slide'\r\n><label for='slide_ntcp'><b>NTCP</b> ( " << cnt << " )</label>\r\n<input type='checkbox' id='slide_ntcp'/>\r\n<p class='content'>";
|
||||||
s << tmp_s.str () << "<br>\r\n";
|
s << tmp_s.str () << "</p>\r\n</div>\r\n";
|
||||||
}
|
}
|
||||||
if (!tmp_s6.str ().empty ())
|
if (!tmp_s6.str ().empty ())
|
||||||
{
|
{
|
||||||
s << "<b>NTCP6</b> ( " << cnt6 << " )<br>\r\n";
|
s << "<div class='slide'\r\n><label for='slide_ntcp6'><b>NTCP6</b> ( " << cnt6 << " )</label>\r\n<input type='checkbox' id='slide_ntcp6'/>\r\n<p class='content'>";
|
||||||
s << tmp_s6.str () << "<br>\r\n";
|
s << tmp_s6.str () << "</p>\r\n</div>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -545,7 +558,7 @@ namespace http {
|
||||||
auto sessions = ssuServer->GetSessions ();
|
auto sessions = ssuServer->GetSessions ();
|
||||||
if (!sessions.empty ())
|
if (!sessions.empty ())
|
||||||
{
|
{
|
||||||
s << "<b>SSU</b> ( " << (int) sessions.size() << " )<br>\r\n";
|
s << "<div class='slide'\r\n><label for='slide_ssu'><b>SSU</b> ( " << (int) sessions.size() << " )</label>\r\n<input type='checkbox' id='slide_ssu'/>\r\n<p class='content'>";
|
||||||
for (const auto& it: sessions)
|
for (const auto& it: sessions)
|
||||||
{
|
{
|
||||||
auto endpoint = it.second->GetRemoteEndpoint ();
|
auto endpoint = it.second->GetRemoteEndpoint ();
|
||||||
|
@ -557,12 +570,12 @@ namespace http {
|
||||||
s << " [itag:" << it.second->GetRelayTag () << "]";
|
s << " [itag:" << it.second->GetRelayTag () << "]";
|
||||||
s << "<br>\r\n" << std::endl;
|
s << "<br>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
s << "<br>\r\n";
|
s << "</p>\r\n</div>\r\n";
|
||||||
}
|
}
|
||||||
auto sessions6 = ssuServer->GetSessionsV6 ();
|
auto sessions6 = ssuServer->GetSessionsV6 ();
|
||||||
if (!sessions6.empty ())
|
if (!sessions6.empty ())
|
||||||
{
|
{
|
||||||
s << "<b>SSU6</b> ( " << (int) sessions6.size() << " )<br>\r\n";
|
s << "<div class='slide'\r\n><label for='slide_ssu6'><b>SSU6</b> ( " << (int) sessions6.size() << " )</label>\r\n<input type='checkbox' id='slide_ssu6'/>\r\n<p class='content'>";
|
||||||
for (const auto& it: sessions6)
|
for (const auto& it: sessions6)
|
||||||
{
|
{
|
||||||
auto endpoint = it.second->GetRemoteEndpoint ();
|
auto endpoint = it.second->GetRemoteEndpoint ();
|
||||||
|
@ -574,7 +587,7 @@ namespace http {
|
||||||
s << " [itag:" << it.second->GetRelayTag () << "]";
|
s << " [itag:" << it.second->GetRelayTag () << "]";
|
||||||
s << "<br>\r\n" << std::endl;
|
s << "<br>\r\n" << std::endl;
|
||||||
}
|
}
|
||||||
s << "<br>\r\n";
|
s << "</p>\r\n</div>\r\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,11 +79,14 @@ namespace transport
|
||||||
|
|
||||||
void UPnP::Discover ()
|
void UPnP::Discover ()
|
||||||
{
|
{
|
||||||
int nerror = 0;
|
|
||||||
#if MINIUPNPC_API_VERSION >= 14
|
#if MINIUPNPC_API_VERSION >= 14
|
||||||
|
int nerror = 0;
|
||||||
m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, 2, &nerror);
|
m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, 2, &nerror);
|
||||||
#else
|
#elif ( MINIUPNPC_API_VERSION >= 8 || defined(UPNPDISCOVER_SUCCESS) )
|
||||||
|
int nerror = 0;
|
||||||
m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror);
|
m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0, 0, &nerror);
|
||||||
|
#else
|
||||||
|
m_Devlist = upnpDiscover (2000, m_MulticastIf, m_Minissdpdpath, 0);
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// notify satrting thread
|
// notify satrting thread
|
||||||
|
@ -155,7 +158,11 @@ namespace transport
|
||||||
std::string strType (GetProto (address)), strPort (std::to_string (address->port));
|
std::string strType (GetProto (address)), strPort (std::to_string (address->port));
|
||||||
int r;
|
int r;
|
||||||
std::string strDesc; i2p::config::GetOption("upnp.name", strDesc);
|
std::string strDesc; i2p::config::GetOption("upnp.name", strDesc);
|
||||||
|
#ifdef UPNPDISCOVER_SUCCESS
|
||||||
r = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0, "0");
|
r = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0, "0");
|
||||||
|
#else
|
||||||
|
r = UPNP_AddPortMapping (m_upnpUrls.controlURL, m_upnpData.first.servicetype, strPort.c_str (), strPort.c_str (), m_NetworkAddr, strDesc.c_str (), strType.c_str (), 0);
|
||||||
|
#endif
|
||||||
if (r!=UPNPCOMMAND_SUCCESS)
|
if (r!=UPNPCOMMAND_SUCCESS)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "UPnP: AddPortMapping (", m_NetworkAddr, ":", strPort, ") failed with code ", r);
|
LogPrint (eLogError, "UPnP: AddPortMapping (", m_NetworkAddr, ":", strPort, ") failed with code ", r);
|
||||||
|
|
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -1,3 +1,9 @@
|
||||||
|
i2pd (2.16.0-1) unstable; urgency=low
|
||||||
|
|
||||||
|
* updated to version 2.16.0/0.9.32
|
||||||
|
|
||||||
|
-- orignal <orignal@i2pmail.org> Mon, 13 Nov 2017 18:00:00 +0000
|
||||||
|
|
||||||
i2pd (2.15.0-1) unstable; urgency=low
|
i2pd (2.15.0-1) unstable; urgency=low
|
||||||
|
|
||||||
* updated to version 2.15.0/0.9.31
|
* updated to version 2.15.0/0.9.31
|
||||||
|
|
|
@ -179,6 +179,7 @@ namespace config {
|
||||||
("reseed.floodfill", value<std::string>()->default_value(""), "Path to router info of floodfill to reseed from")
|
("reseed.floodfill", value<std::string>()->default_value(""), "Path to router info of floodfill to reseed from")
|
||||||
("reseed.file", value<std::string>()->default_value(""), "Path to local .su3 file or HTTPS URL to reseed from")
|
("reseed.file", value<std::string>()->default_value(""), "Path to local .su3 file or HTTPS URL to reseed from")
|
||||||
("reseed.zipfile", value<std::string>()->default_value(""), "Path to local .zip file to reseed from")
|
("reseed.zipfile", value<std::string>()->default_value(""), "Path to local .zip file to reseed from")
|
||||||
|
("reseed.proxy", value<std::string>()->default_value(""), "url for reseed proxy, supports http/socks")
|
||||||
("reseed.urls", value<std::string>()->default_value(
|
("reseed.urls", value<std::string>()->default_value(
|
||||||
"https://reseed.i2p-projekt.de/,"
|
"https://reseed.i2p-projekt.de/,"
|
||||||
"https://i2p.mooo.com/netDb/,"
|
"https://i2p.mooo.com/netDb/,"
|
||||||
|
|
|
@ -14,20 +14,20 @@
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
namespace crypto
|
namespace crypto
|
||||||
{
|
{
|
||||||
const uint8_t elgp_[256]=
|
const uint8_t elgp_[256]=
|
||||||
{
|
{
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
|
||||||
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
|
0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
|
||||||
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
|
0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
|
||||||
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
|
0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
|
||||||
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
|
0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
|
||||||
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
|
0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
|
||||||
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
|
0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
|
||||||
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
|
0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
|
||||||
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
|
0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
|
||||||
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
|
0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
|
||||||
0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
|
0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
|
||||||
0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
|
0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
|
||||||
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
|
0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
|
||||||
0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
|
0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
|
||||||
|
@ -36,7 +36,7 @@ namespace crypto
|
||||||
};
|
};
|
||||||
|
|
||||||
const int elgg_ = 2;
|
const int elgg_ = 2;
|
||||||
|
|
||||||
const uint8_t dsap_[128]=
|
const uint8_t dsap_[128]=
|
||||||
{
|
{
|
||||||
0x9c, 0x05, 0xb2, 0xaa, 0x96, 0x0d, 0x9b, 0x97, 0xb8, 0x93, 0x19, 0x63, 0xc9, 0xcc, 0x9e, 0x8c,
|
0x9c, 0x05, 0xb2, 0xaa, 0x96, 0x0d, 0x9b, 0x97, 0xb8, 0x93, 0x19, 0x63, 0xc9, 0xcc, 0x9e, 0x8c,
|
||||||
|
@ -45,7 +45,7 @@ namespace crypto
|
||||||
0x76, 0x55, 0xc4, 0x96, 0x4a, 0xfa, 0xa2, 0xb3, 0x37, 0xe9, 0x6a, 0xd3, 0x16, 0xb9, 0xfb, 0x1c,
|
0x76, 0x55, 0xc4, 0x96, 0x4a, 0xfa, 0xa2, 0xb3, 0x37, 0xe9, 0x6a, 0xd3, 0x16, 0xb9, 0xfb, 0x1c,
|
||||||
0xc5, 0x64, 0xb5, 0xae, 0xc5, 0xb6, 0x9a, 0x9f, 0xf6, 0xc3, 0xe4, 0x54, 0x87, 0x07, 0xfe, 0xf8,
|
0xc5, 0x64, 0xb5, 0xae, 0xc5, 0xb6, 0x9a, 0x9f, 0xf6, 0xc3, 0xe4, 0x54, 0x87, 0x07, 0xfe, 0xf8,
|
||||||
0x50, 0x3d, 0x91, 0xdd, 0x86, 0x02, 0xe8, 0x67, 0xe6, 0xd3, 0x5d, 0x22, 0x35, 0xc1, 0x86, 0x9c,
|
0x50, 0x3d, 0x91, 0xdd, 0x86, 0x02, 0xe8, 0x67, 0xe6, 0xd3, 0x5d, 0x22, 0x35, 0xc1, 0x86, 0x9c,
|
||||||
0xe2, 0x47, 0x9c, 0x3b, 0x9d, 0x54, 0x01, 0xde, 0x04, 0xe0, 0x72, 0x7f, 0xb3, 0x3d, 0x65, 0x11,
|
0xe2, 0x47, 0x9c, 0x3b, 0x9d, 0x54, 0x01, 0xde, 0x04, 0xe0, 0x72, 0x7f, 0xb3, 0x3d, 0x65, 0x11,
|
||||||
0x28, 0x5d, 0x4c, 0xf2, 0x95, 0x38, 0xd9, 0xe3, 0xb6, 0x05, 0x1f, 0x5b, 0x22, 0xcc, 0x1c, 0x93
|
0x28, 0x5d, 0x4c, 0xf2, 0x95, 0x38, 0xd9, 0xe3, 0xb6, 0x05, 0x1f, 0x5b, 0x22, 0xcc, 0x1c, 0x93
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -63,27 +63,27 @@ namespace crypto
|
||||||
0x3c, 0x43, 0x1f, 0x46, 0x98, 0x59, 0x9d, 0xda, 0x02, 0x45, 0x18, 0x24, 0xff, 0x36, 0x97, 0x52,
|
0x3c, 0x43, 0x1f, 0x46, 0x98, 0x59, 0x9d, 0xda, 0x02, 0x45, 0x18, 0x24, 0xff, 0x36, 0x97, 0x52,
|
||||||
0x59, 0x36, 0x47, 0xcc, 0x3d, 0xdc, 0x19, 0x7d, 0xe9, 0x85, 0xe4, 0x3d, 0x13, 0x6c, 0xdc, 0xfc,
|
0x59, 0x36, 0x47, 0xcc, 0x3d, 0xdc, 0x19, 0x7d, 0xe9, 0x85, 0xe4, 0x3d, 0x13, 0x6c, 0xdc, 0xfc,
|
||||||
0x6b, 0xd5, 0x40, 0x9c, 0xd2, 0xf4, 0x50, 0x82, 0x11, 0x42, 0xa5, 0xe6, 0xf8, 0xeb, 0x1c, 0x3a,
|
0x6b, 0xd5, 0x40, 0x9c, 0xd2, 0xf4, 0x50, 0x82, 0x11, 0x42, 0xa5, 0xe6, 0xf8, 0xeb, 0x1c, 0x3a,
|
||||||
0xb5, 0xd0, 0x48, 0x4b, 0x81, 0x29, 0xfc, 0xf1, 0x7b, 0xce, 0x4f, 0x7f, 0x33, 0x32, 0x1c, 0x3c,
|
0xb5, 0xd0, 0x48, 0x4b, 0x81, 0x29, 0xfc, 0xf1, 0x7b, 0xce, 0x4f, 0x7f, 0x33, 0x32, 0x1c, 0x3c,
|
||||||
0xb3, 0xdb, 0xb1, 0x4a, 0x90, 0x5e, 0x7b, 0x2b, 0x3e, 0x93, 0xbe, 0x47, 0x08, 0xcb, 0xcc, 0x82
|
0xb3, 0xdb, 0xb1, 0x4a, 0x90, 0x5e, 0x7b, 0x2b, 0x3e, 0x93, 0xbe, 0x47, 0x08, 0xcb, 0xcc, 0x82
|
||||||
};
|
};
|
||||||
|
|
||||||
const int rsae_ = 65537;
|
const int rsae_ = 65537;
|
||||||
|
|
||||||
struct CryptoConstants
|
struct CryptoConstants
|
||||||
{
|
{
|
||||||
// DH/ElGamal
|
// DH/ElGamal
|
||||||
BIGNUM * elgp;
|
BIGNUM * elgp;
|
||||||
BIGNUM * elgg;
|
BIGNUM * elgg;
|
||||||
|
|
||||||
// DSA
|
// DSA
|
||||||
BIGNUM * dsap;
|
BIGNUM * dsap;
|
||||||
BIGNUM * dsaq;
|
BIGNUM * dsaq;
|
||||||
BIGNUM * dsag;
|
BIGNUM * dsag;
|
||||||
|
|
||||||
// RSA
|
// RSA
|
||||||
BIGNUM * rsae;
|
BIGNUM * rsae;
|
||||||
|
|
||||||
CryptoConstants (const uint8_t * elgp_, int elgg_, const uint8_t * dsap_,
|
CryptoConstants (const uint8_t * elgp_, int elgg_, const uint8_t * dsap_,
|
||||||
const uint8_t * dsaq_, const uint8_t * dsag_, int rsae_)
|
const uint8_t * dsaq_, const uint8_t * dsag_, int rsae_)
|
||||||
{
|
{
|
||||||
elgp = BN_new ();
|
elgp = BN_new ();
|
||||||
|
@ -99,18 +99,18 @@ namespace crypto
|
||||||
rsae = BN_new ();
|
rsae = BN_new ();
|
||||||
BN_set_word (rsae, rsae_);
|
BN_set_word (rsae, rsae_);
|
||||||
}
|
}
|
||||||
|
|
||||||
~CryptoConstants ()
|
~CryptoConstants ()
|
||||||
{
|
{
|
||||||
BN_free (elgp); BN_free (elgg); BN_free (dsap); BN_free (dsaq); BN_free (dsag); BN_free (rsae);
|
BN_free (elgp); BN_free (elgg); BN_free (dsap); BN_free (dsaq); BN_free (dsag); BN_free (rsae);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const CryptoConstants& GetCryptoConstants ()
|
static const CryptoConstants& GetCryptoConstants ()
|
||||||
{
|
{
|
||||||
static CryptoConstants cryptoConstants (elgp_, elgg_, dsap_, dsaq_, dsag_, rsae_);
|
static CryptoConstants cryptoConstants (elgp_, elgg_, dsap_, dsaq_, dsag_, rsae_);
|
||||||
return cryptoConstants;
|
return cryptoConstants;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bn2buf (const BIGNUM * bn, uint8_t * buf, size_t len)
|
bool bn2buf (const BIGNUM * bn, uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
|
@ -119,34 +119,34 @@ namespace crypto
|
||||||
BN_bn2bin (bn, buf + offset);
|
BN_bn2bin (bn, buf + offset);
|
||||||
memset (buf, 0, offset);
|
memset (buf, 0, offset);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RSA
|
// RSA
|
||||||
#define rsae GetCryptoConstants ().rsae
|
#define rsae GetCryptoConstants ().rsae
|
||||||
const BIGNUM * GetRSAE ()
|
const BIGNUM * GetRSAE ()
|
||||||
{
|
{
|
||||||
return rsae;
|
return rsae;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DSA
|
// DSA
|
||||||
#define dsap GetCryptoConstants ().dsap
|
#define dsap GetCryptoConstants ().dsap
|
||||||
#define dsaq GetCryptoConstants ().dsaq
|
#define dsaq GetCryptoConstants ().dsaq
|
||||||
#define dsag GetCryptoConstants ().dsag
|
#define dsag GetCryptoConstants ().dsag
|
||||||
DSA * CreateDSA ()
|
DSA * CreateDSA ()
|
||||||
{
|
{
|
||||||
DSA * dsa = DSA_new ();
|
DSA * dsa = DSA_new ();
|
||||||
DSA_set0_pqg (dsa, BN_dup (dsap), BN_dup (dsaq), BN_dup (dsag));
|
DSA_set0_pqg (dsa, BN_dup (dsap), BN_dup (dsaq), BN_dup (dsag));
|
||||||
DSA_set0_key (dsa, NULL, NULL);
|
DSA_set0_key (dsa, NULL, NULL);
|
||||||
return dsa;
|
return dsa;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DH/ElGamal
|
// DH/ElGamal
|
||||||
|
|
||||||
const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226;
|
const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226;
|
||||||
const int ELGAMAL_SHORT_EXPONENT_NUM_BYTES = ELGAMAL_SHORT_EXPONENT_NUM_BITS/8+1;
|
const int ELGAMAL_SHORT_EXPONENT_NUM_BYTES = ELGAMAL_SHORT_EXPONENT_NUM_BITS/8+1;
|
||||||
const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048;
|
const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048;
|
||||||
const int ELGAMAL_FULL_EXPONENT_NUM_BYTES = ELGAMAL_FULL_EXPONENT_NUM_BITS/8;
|
const int ELGAMAL_FULL_EXPONENT_NUM_BYTES = ELGAMAL_FULL_EXPONENT_NUM_BITS/8;
|
||||||
|
|
||||||
#define elgp GetCryptoConstants ().elgp
|
#define elgp GetCryptoConstants ().elgp
|
||||||
#define elgg GetCryptoConstants ().elgg
|
#define elgg GetCryptoConstants ().elgg
|
||||||
|
|
||||||
|
@ -156,14 +156,14 @@ namespace crypto
|
||||||
if (len <= 0) return;
|
if (len <= 0) return;
|
||||||
BN_CTX * ctx = BN_CTX_new ();
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
g_MontCtx = BN_MONT_CTX_new ();
|
g_MontCtx = BN_MONT_CTX_new ();
|
||||||
BN_MONT_CTX_set (g_MontCtx, elgp, ctx);
|
BN_MONT_CTX_set (g_MontCtx, elgp, ctx);
|
||||||
auto montCtx = BN_MONT_CTX_new ();
|
auto montCtx = BN_MONT_CTX_new ();
|
||||||
BN_MONT_CTX_copy (montCtx, g_MontCtx);
|
BN_MONT_CTX_copy (montCtx, g_MontCtx);
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
table[i][0] = BN_new ();
|
table[i][0] = BN_new ();
|
||||||
if (!i)
|
if (!i)
|
||||||
BN_to_montgomery (table[0][0], elgg, montCtx, ctx);
|
BN_to_montgomery (table[0][0], elgg, montCtx, ctx);
|
||||||
else
|
else
|
||||||
BN_mod_mul_montgomery (table[i][0], table[i-1][254], table[i-1][0], montCtx, ctx);
|
BN_mod_mul_montgomery (table[i][0], table[i-1][254], table[i-1][0], montCtx, ctx);
|
||||||
for (int j = 1; j < 255; j++)
|
for (int j = 1; j < 255; j++)
|
||||||
|
@ -174,7 +174,7 @@ namespace crypto
|
||||||
}
|
}
|
||||||
BN_MONT_CTX_free (montCtx);
|
BN_MONT_CTX_free (montCtx);
|
||||||
BN_CTX_free (ctx);
|
BN_CTX_free (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DestroyElggTable (BIGNUM * table[][255], int len)
|
static void DestroyElggTable (BIGNUM * table[][255], int len)
|
||||||
{
|
{
|
||||||
|
@ -186,9 +186,9 @@ namespace crypto
|
||||||
}
|
}
|
||||||
BN_MONT_CTX_free (g_MontCtx);
|
BN_MONT_CTX_free (g_MontCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BIGNUM * ElggPow (const uint8_t * exp, int len, BIGNUM * table[][255], BN_CTX * ctx)
|
static BIGNUM * ElggPow (const uint8_t * exp, int len, BIGNUM * table[][255], BN_CTX * ctx)
|
||||||
// exp is in Big Endian
|
// exp is in Big Endian
|
||||||
{
|
{
|
||||||
if (len <= 0) return nullptr;
|
if (len <= 0) return nullptr;
|
||||||
auto montCtx = BN_MONT_CTX_new ();
|
auto montCtx = BN_MONT_CTX_new ();
|
||||||
|
@ -200,15 +200,15 @@ namespace crypto
|
||||||
{
|
{
|
||||||
if (exp[i])
|
if (exp[i])
|
||||||
BN_mod_mul_montgomery (res, res, table[len-1-i][exp[i]-1], montCtx, ctx);
|
BN_mod_mul_montgomery (res, res, table[len-1-i][exp[i]-1], montCtx, ctx);
|
||||||
}
|
}
|
||||||
else if (exp[i])
|
else if (exp[i])
|
||||||
res = BN_dup (table[len-i-1][exp[i]-1]);
|
res = BN_dup (table[len-i-1][exp[i]-1]);
|
||||||
}
|
}
|
||||||
if (res)
|
if (res)
|
||||||
BN_from_montgomery (res, res, montCtx, ctx);
|
BN_from_montgomery (res, res, montCtx, ctx);
|
||||||
BN_MONT_CTX_free (montCtx);
|
BN_MONT_CTX_free (montCtx);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BIGNUM * ElggPow (const BIGNUM * exp, BIGNUM * table[][255], BN_CTX * ctx)
|
static BIGNUM * ElggPow (const BIGNUM * exp, BIGNUM * table[][255], BN_CTX * ctx)
|
||||||
{
|
{
|
||||||
|
@ -218,64 +218,64 @@ namespace crypto
|
||||||
auto ret = ElggPow (buf, len, table, ctx);
|
auto ret = ElggPow (buf, len, table, ctx);
|
||||||
delete[] buf;
|
delete[] buf;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BIGNUM * (* g_ElggTable)[255] = nullptr;
|
||||||
|
|
||||||
static BIGNUM * (* g_ElggTable)[255] = nullptr;
|
|
||||||
|
|
||||||
// DH
|
// DH
|
||||||
|
|
||||||
DHKeys::DHKeys ()
|
DHKeys::DHKeys ()
|
||||||
{
|
{
|
||||||
m_DH = DH_new ();
|
m_DH = DH_new ();
|
||||||
DH_set0_pqg (m_DH, BN_dup (elgp), NULL, BN_dup (elgg));
|
DH_set0_pqg (m_DH, BN_dup (elgp), NULL, BN_dup (elgg));
|
||||||
DH_set0_key (m_DH, NULL, NULL);
|
DH_set0_key (m_DH, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
DHKeys::~DHKeys ()
|
DHKeys::~DHKeys ()
|
||||||
{
|
{
|
||||||
DH_free (m_DH);
|
DH_free (m_DH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DHKeys::GenerateKeys ()
|
void DHKeys::GenerateKeys ()
|
||||||
{
|
{
|
||||||
BIGNUM * priv_key = NULL, * pub_key = NULL;
|
BIGNUM * priv_key = NULL, * pub_key = NULL;
|
||||||
#if !defined(__x86_64__) // use short exponent for non x64
|
#if !defined(__x86_64__) // use short exponent for non x64
|
||||||
priv_key = BN_new ();
|
priv_key = BN_new ();
|
||||||
BN_rand (priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1);
|
BN_rand (priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1);
|
||||||
#endif
|
#endif
|
||||||
if (g_ElggTable)
|
if (g_ElggTable)
|
||||||
{
|
{
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
priv_key = BN_new ();
|
priv_key = BN_new ();
|
||||||
BN_rand (priv_key, ELGAMAL_FULL_EXPONENT_NUM_BITS, 0, 1);
|
BN_rand (priv_key, ELGAMAL_FULL_EXPONENT_NUM_BITS, 0, 1);
|
||||||
#endif
|
#endif
|
||||||
auto ctx = BN_CTX_new ();
|
auto ctx = BN_CTX_new ();
|
||||||
pub_key = ElggPow (priv_key, g_ElggTable, ctx);
|
pub_key = ElggPow (priv_key, g_ElggTable, ctx);
|
||||||
DH_set0_key (m_DH, pub_key, priv_key);
|
DH_set0_key (m_DH, pub_key, priv_key);
|
||||||
BN_CTX_free (ctx);
|
BN_CTX_free (ctx);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DH_set0_key (m_DH, NULL, priv_key);
|
DH_set0_key (m_DH, NULL, priv_key);
|
||||||
DH_generate_key (m_DH);
|
DH_generate_key (m_DH);
|
||||||
DH_get0_key (m_DH, (const BIGNUM **)&pub_key, (const BIGNUM **)&priv_key);
|
DH_get0_key (m_DH, (const BIGNUM **)&pub_key, (const BIGNUM **)&priv_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
bn2buf (pub_key, m_PublicKey, 256);
|
bn2buf (pub_key, m_PublicKey, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DHKeys::Agree (const uint8_t * pub, uint8_t * shared)
|
void DHKeys::Agree (const uint8_t * pub, uint8_t * shared)
|
||||||
{
|
{
|
||||||
BIGNUM * pk = BN_bin2bn (pub, 256, NULL);
|
BIGNUM * pk = BN_bin2bn (pub, 256, NULL);
|
||||||
DH_compute_key (shared, pk, m_DH);
|
DH_compute_key (shared, pk, m_DH);
|
||||||
BN_free (pk);
|
BN_free (pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ElGamal
|
// ElGamal
|
||||||
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
|
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
|
||||||
{
|
{
|
||||||
BN_CTX_start (ctx);
|
BN_CTX_start (ctx);
|
||||||
// everything, but a, because a might come from table
|
// everything, but a, because a might come from table
|
||||||
BIGNUM * k = BN_CTX_get (ctx);
|
BIGNUM * k = BN_CTX_get (ctx);
|
||||||
BIGNUM * y = BN_CTX_get (ctx);
|
BIGNUM * y = BN_CTX_get (ctx);
|
||||||
BIGNUM * b1 = BN_CTX_get (ctx);
|
BIGNUM * b1 = BN_CTX_get (ctx);
|
||||||
|
@ -285,13 +285,13 @@ namespace crypto
|
||||||
BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64
|
BN_rand (k, ELGAMAL_FULL_EXPONENT_NUM_BITS, -1, 1); // full exponent for x64
|
||||||
#else
|
#else
|
||||||
BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits
|
BN_rand (k, ELGAMAL_SHORT_EXPONENT_NUM_BITS, -1, 1); // short exponent of 226 bits
|
||||||
#endif
|
#endif
|
||||||
// calculate a
|
// calculate a
|
||||||
BIGNUM * a;
|
BIGNUM * a;
|
||||||
if (g_ElggTable)
|
if (g_ElggTable)
|
||||||
a = ElggPow (k, g_ElggTable, ctx);
|
a = ElggPow (k, g_ElggTable, ctx);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a = BN_new ();
|
a = BN_new ();
|
||||||
BN_mod_exp (a, elgg, k, elgp, ctx);
|
BN_mod_exp (a, elgg, k, elgp, ctx);
|
||||||
}
|
}
|
||||||
|
@ -315,17 +315,17 @@ namespace crypto
|
||||||
bn2buf (a, encrypted + 1, 256);
|
bn2buf (a, encrypted + 1, 256);
|
||||||
encrypted[257] = 0;
|
encrypted[257] = 0;
|
||||||
bn2buf (b, encrypted + 258, 256);
|
bn2buf (b, encrypted + 258, 256);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bn2buf (a, encrypted, 256);
|
bn2buf (a, encrypted, 256);
|
||||||
bn2buf (b, encrypted + 256, 256);
|
bn2buf (b, encrypted + 256, 256);
|
||||||
}
|
}
|
||||||
BN_free (a);
|
BN_free (a);
|
||||||
BN_CTX_end (ctx);
|
BN_CTX_end (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted,
|
bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted,
|
||||||
uint8_t * data, BN_CTX * ctx, bool zeroPadding)
|
uint8_t * data, BN_CTX * ctx, bool zeroPadding)
|
||||||
{
|
{
|
||||||
BN_CTX_start (ctx);
|
BN_CTX_start (ctx);
|
||||||
|
@ -334,11 +334,11 @@ namespace crypto
|
||||||
BN_sub (x, elgp, x); BN_sub_word (x, 1); // x = elgp - x- 1
|
BN_sub (x, elgp, x); BN_sub_word (x, 1); // x = elgp - x- 1
|
||||||
BN_bin2bn (zeroPadding ? encrypted + 1 : encrypted, 256, a);
|
BN_bin2bn (zeroPadding ? encrypted + 1 : encrypted, 256, a);
|
||||||
BN_bin2bn (zeroPadding ? encrypted + 258 : encrypted + 256, 256, b);
|
BN_bin2bn (zeroPadding ? encrypted + 258 : encrypted + 256, 256, b);
|
||||||
// m = b*(a^x mod p) mod p
|
// m = b*(a^x mod p) mod p
|
||||||
BN_mod_exp (x, a, x, elgp, ctx);
|
BN_mod_exp (x, a, x, elgp, ctx);
|
||||||
BN_mod_mul (b, b, x, elgp, ctx);
|
BN_mod_mul (b, b, x, elgp, ctx);
|
||||||
uint8_t m[255];
|
uint8_t m[255];
|
||||||
bn2buf (b, m, 255);
|
bn2buf (b, m, 255);
|
||||||
BN_CTX_end (ctx);
|
BN_CTX_end (ctx);
|
||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
SHA256 (m + 33, 222, hash);
|
SHA256 (m + 33, 222, hash);
|
||||||
|
@ -346,14 +346,14 @@ namespace crypto
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "ElGamal decrypt hash doesn't match");
|
LogPrint (eLogError, "ElGamal decrypt hash doesn't match");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memcpy (data, m + 33, 222);
|
memcpy (data, m + 33, 222);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub)
|
void GenerateElGamalKeyPair (uint8_t * priv, uint8_t * pub)
|
||||||
{
|
{
|
||||||
#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER)
|
#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER)
|
||||||
RAND_bytes (priv, 256);
|
RAND_bytes (priv, 256);
|
||||||
#else
|
#else
|
||||||
// lower 226 bits (28 bytes and 2 bits) only. short exponent
|
// lower 226 bits (28 bytes and 2 bits) only. short exponent
|
||||||
|
@ -364,10 +364,10 @@ namespace crypto
|
||||||
priv[numZeroBytes] &= 0x03;
|
priv[numZeroBytes] &= 0x03;
|
||||||
#endif
|
#endif
|
||||||
BN_CTX * ctx = BN_CTX_new ();
|
BN_CTX * ctx = BN_CTX_new ();
|
||||||
BIGNUM * p = BN_new ();
|
BIGNUM * p = BN_new ();
|
||||||
BN_bin2bn (priv, 256, p);
|
BN_bin2bn (priv, 256, p);
|
||||||
BN_mod_exp (p, elgg, p, elgp, ctx);
|
BN_mod_exp (p, elgg, p, elgp, ctx);
|
||||||
bn2buf (p, pub, 256);
|
bn2buf (p, pub, 256);
|
||||||
BN_free (p);
|
BN_free (p);
|
||||||
BN_CTX_free (ctx);
|
BN_CTX_free (ctx);
|
||||||
}
|
}
|
||||||
|
@ -385,15 +385,15 @@ namespace crypto
|
||||||
auto p = EC_POINT_new (curve);
|
auto p = EC_POINT_new (curve);
|
||||||
EC_POINT_mul (curve, p, k, nullptr, nullptr, ctx);
|
EC_POINT_mul (curve, p, k, nullptr, nullptr, ctx);
|
||||||
BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx);
|
BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx);
|
||||||
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr);
|
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr);
|
||||||
encrypted[0] = 0;
|
encrypted[0] = 0;
|
||||||
bn2buf (x, encrypted + 1, len);
|
bn2buf (x, encrypted + 1, len);
|
||||||
bn2buf (y, encrypted + 1 + len, len);
|
bn2buf (y, encrypted + 1 + len, len);
|
||||||
RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len);
|
RAND_bytes (encrypted + 1 + 2*len, 256 - 2*len);
|
||||||
// ecryption key and iv
|
// ecryption key and iv
|
||||||
EC_POINT_mul (curve, p, nullptr, key, k, ctx);
|
EC_POINT_mul (curve, p, nullptr, key, k, ctx);
|
||||||
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr);
|
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, nullptr);
|
||||||
uint8_t keyBuf[64], iv[64], shared[32];
|
uint8_t keyBuf[64], iv[64], shared[32];
|
||||||
bn2buf (x, keyBuf, len);
|
bn2buf (x, keyBuf, len);
|
||||||
bn2buf (y, iv, len);
|
bn2buf (y, iv, len);
|
||||||
SHA256 (keyBuf, len, shared);
|
SHA256 (keyBuf, len, shared);
|
||||||
|
@ -421,16 +421,16 @@ namespace crypto
|
||||||
int len = BN_num_bytes (q);
|
int len = BN_num_bytes (q);
|
||||||
// point for shared secret
|
// point for shared secret
|
||||||
BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx);
|
BIGNUM * x = BN_CTX_get (ctx), * y = BN_CTX_get (ctx);
|
||||||
BN_bin2bn (encrypted + 1, len, x);
|
BN_bin2bn (encrypted + 1, len, x);
|
||||||
BN_bin2bn (encrypted + 1 + len, len, y);
|
BN_bin2bn (encrypted + 1 + len, len, y);
|
||||||
auto p = EC_POINT_new (curve);
|
auto p = EC_POINT_new (curve);
|
||||||
if (EC_POINT_set_affine_coordinates_GFp (curve, p, x, y, nullptr))
|
if (EC_POINT_set_affine_coordinates_GFp (curve, p, x, y, nullptr))
|
||||||
{
|
{
|
||||||
auto s = EC_POINT_new (curve);
|
auto s = EC_POINT_new (curve);
|
||||||
EC_POINT_mul (curve, s, nullptr, p, key, ctx);
|
EC_POINT_mul (curve, s, nullptr, p, key, ctx);
|
||||||
EC_POINT_get_affine_coordinates_GFp (curve, s, x, y, nullptr);
|
EC_POINT_get_affine_coordinates_GFp (curve, s, x, y, nullptr);
|
||||||
EC_POINT_free (s);
|
EC_POINT_free (s);
|
||||||
uint8_t keyBuf[64], iv[64], shared[32];
|
uint8_t keyBuf[64], iv[64], shared[32];
|
||||||
bn2buf (x, keyBuf, len);
|
bn2buf (x, keyBuf, len);
|
||||||
bn2buf (y, iv, len);
|
bn2buf (y, iv, len);
|
||||||
SHA256 (keyBuf, len, shared);
|
SHA256 (keyBuf, len, shared);
|
||||||
|
@ -442,21 +442,21 @@ namespace crypto
|
||||||
decryption.Decrypt (encrypted + 258, 256, m);
|
decryption.Decrypt (encrypted + 258, 256, m);
|
||||||
// verify and copy
|
// verify and copy
|
||||||
uint8_t hash[32];
|
uint8_t hash[32];
|
||||||
SHA256 (m + 33, 222, hash);
|
SHA256 (m + 33, 222, hash);
|
||||||
if (!memcmp (m + 1, hash, 32))
|
if (!memcmp (m + 1, hash, 32))
|
||||||
memcpy (data, m + 33, 222);
|
memcpy (data, m + 33, 222);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "ECICS decrypt hash doesn't match");
|
LogPrint (eLogError, "ECIES decrypt hash doesn't match");
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "ECICS decrypt point is invalid");
|
LogPrint (eLogError, "ECIES decrypt point is invalid");
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EC_POINT_free (p);
|
EC_POINT_free (p);
|
||||||
BN_CTX_end (ctx);
|
BN_CTX_end (ctx);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -468,7 +468,7 @@ namespace crypto
|
||||||
BIGNUM * q = BN_new ();
|
BIGNUM * q = BN_new ();
|
||||||
EC_GROUP_get_order(curve, q, ctx);
|
EC_GROUP_get_order(curve, q, ctx);
|
||||||
priv = BN_new ();
|
priv = BN_new ();
|
||||||
BN_rand_range (priv, q);
|
BN_rand_range (priv, q);
|
||||||
pub = EC_POINT_new (curve);
|
pub = EC_POINT_new (curve);
|
||||||
EC_POINT_mul (curve, pub, priv, nullptr, nullptr, ctx);
|
EC_POINT_mul (curve, pub, priv, nullptr, nullptr, ctx);
|
||||||
BN_free (q);
|
BN_free (q);
|
||||||
|
@ -477,17 +477,17 @@ namespace crypto
|
||||||
|
|
||||||
// HMAC
|
// HMAC
|
||||||
const uint64_t IPAD = 0x3636363636363636;
|
const uint64_t IPAD = 0x3636363636363636;
|
||||||
const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C;
|
const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C;
|
||||||
|
|
||||||
#if defined(__AVX__)
|
#if defined(__AVX__)
|
||||||
static const uint64_t ipads[] = { IPAD, IPAD, IPAD, IPAD };
|
static const uint64_t ipads[] = { IPAD, IPAD, IPAD, IPAD };
|
||||||
static const uint64_t opads[] = { OPAD, OPAD, OPAD, OPAD };
|
static const uint64_t opads[] = { OPAD, OPAD, OPAD, OPAD };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void HMACMD5Digest (uint8_t * msg, size_t len, const MACKey& key, uint8_t * digest)
|
void HMACMD5Digest (uint8_t * msg, size_t len, const MACKey& key, uint8_t * digest)
|
||||||
// key is 32 bytes
|
// key is 32 bytes
|
||||||
// digest is 16 bytes
|
// digest is 16 bytes
|
||||||
// block size is 64 bytes
|
// block size is 64 bytes
|
||||||
{
|
{
|
||||||
uint64_t buf[256];
|
uint64_t buf[256];
|
||||||
uint64_t hash[12]; // 96 bytes
|
uint64_t hash[12]; // 96 bytes
|
||||||
|
@ -498,53 +498,53 @@ namespace crypto
|
||||||
"vmovups %[ipad], %%ymm1 \n"
|
"vmovups %[ipad], %%ymm1 \n"
|
||||||
"vmovups %%ymm1, 32(%[buf]) \n"
|
"vmovups %%ymm1, 32(%[buf]) \n"
|
||||||
"vxorps %%ymm0, %%ymm1, %%ymm1 \n"
|
"vxorps %%ymm0, %%ymm1, %%ymm1 \n"
|
||||||
"vmovups %%ymm1, (%[buf]) \n"
|
"vmovups %%ymm1, (%[buf]) \n"
|
||||||
"vmovups %[opad], %%ymm1 \n"
|
"vmovups %[opad], %%ymm1 \n"
|
||||||
"vmovups %%ymm1, 32(%[hash]) \n"
|
"vmovups %%ymm1, 32(%[hash]) \n"
|
||||||
"vxorps %%ymm0, %%ymm1, %%ymm1 \n"
|
"vxorps %%ymm0, %%ymm1, %%ymm1 \n"
|
||||||
"vmovups %%ymm1, (%[hash]) \n"
|
"vmovups %%ymm1, (%[hash]) \n"
|
||||||
"vzeroall \n" // end of AVX
|
"vzeroall \n" // end of AVX
|
||||||
"movups %%xmm0, 80(%[hash]) \n" // zero last 16 bytes
|
"movups %%xmm0, 80(%[hash]) \n" // zero last 16 bytes
|
||||||
:
|
:
|
||||||
: [key]"m"(*(const uint8_t *)key), [ipad]"m"(*ipads), [opad]"m"(*opads),
|
: [key]"m"(*(const uint8_t *)key), [ipad]"m"(*ipads), [opad]"m"(*opads),
|
||||||
[buf]"r"(buf), [hash]"r"(hash)
|
[buf]"r"(buf), [hash]"r"(hash)
|
||||||
: "memory", "%xmm0" // TODO: change to %ymm0 later
|
: "memory", "%xmm0" // TODO: change to %ymm0 later
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
// ikeypad
|
// ikeypad
|
||||||
buf[0] = key.GetLL ()[0] ^ IPAD;
|
buf[0] = key.GetLL ()[0] ^ IPAD;
|
||||||
buf[1] = key.GetLL ()[1] ^ IPAD;
|
buf[1] = key.GetLL ()[1] ^ IPAD;
|
||||||
buf[2] = key.GetLL ()[2] ^ IPAD;
|
buf[2] = key.GetLL ()[2] ^ IPAD;
|
||||||
buf[3] = key.GetLL ()[3] ^ IPAD;
|
buf[3] = key.GetLL ()[3] ^ IPAD;
|
||||||
buf[4] = IPAD;
|
buf[4] = IPAD;
|
||||||
buf[5] = IPAD;
|
buf[5] = IPAD;
|
||||||
buf[6] = IPAD;
|
buf[6] = IPAD;
|
||||||
buf[7] = IPAD;
|
buf[7] = IPAD;
|
||||||
// okeypad
|
// okeypad
|
||||||
hash[0] = key.GetLL ()[0] ^ OPAD;
|
hash[0] = key.GetLL ()[0] ^ OPAD;
|
||||||
hash[1] = key.GetLL ()[1] ^ OPAD;
|
hash[1] = key.GetLL ()[1] ^ OPAD;
|
||||||
hash[2] = key.GetLL ()[2] ^ OPAD;
|
hash[2] = key.GetLL ()[2] ^ OPAD;
|
||||||
hash[3] = key.GetLL ()[3] ^ OPAD;
|
hash[3] = key.GetLL ()[3] ^ OPAD;
|
||||||
hash[4] = OPAD;
|
hash[4] = OPAD;
|
||||||
hash[5] = OPAD;
|
hash[5] = OPAD;
|
||||||
hash[6] = OPAD;
|
hash[6] = OPAD;
|
||||||
hash[7] = OPAD;
|
hash[7] = OPAD;
|
||||||
// fill last 16 bytes with zeros (first hash size assumed 32 bytes in I2P)
|
// fill last 16 bytes with zeros (first hash size assumed 32 bytes in I2P)
|
||||||
memset (hash + 10, 0, 16);
|
memset (hash + 10, 0, 16);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// concatenate with msg
|
// concatenate with msg
|
||||||
memcpy (buf + 8, msg, len);
|
memcpy (buf + 8, msg, len);
|
||||||
// calculate first hash
|
// calculate first hash
|
||||||
MD5((uint8_t *)buf, len + 64, (uint8_t *)(hash + 8)); // 16 bytes
|
MD5((uint8_t *)buf, len + 64, (uint8_t *)(hash + 8)); // 16 bytes
|
||||||
|
|
||||||
// calculate digest
|
// calculate digest
|
||||||
MD5((uint8_t *)hash, 96, digest);
|
MD5((uint8_t *)hash, 96, digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AES
|
// AES
|
||||||
#ifdef AESNI
|
#ifdef AESNI
|
||||||
|
|
||||||
#define KeyExpansion256(round0,round1) \
|
#define KeyExpansion256(round0,round1) \
|
||||||
"pshufd $0xff, %%xmm2, %%xmm2 \n" \
|
"pshufd $0xff, %%xmm2, %%xmm2 \n" \
|
||||||
"movaps %%xmm1, %%xmm4 \n" \
|
"movaps %%xmm1, %%xmm4 \n" \
|
||||||
|
@ -566,7 +566,7 @@ namespace crypto
|
||||||
"pslldq $4, %%xmm4 \n" \
|
"pslldq $4, %%xmm4 \n" \
|
||||||
"pxor %%xmm4, %%xmm3 \n" \
|
"pxor %%xmm4, %%xmm3 \n" \
|
||||||
"pxor %%xmm2, %%xmm3 \n" \
|
"pxor %%xmm2, %%xmm3 \n" \
|
||||||
"movaps %%xmm3, "#round1"(%[sched]) \n"
|
"movaps %%xmm3, "#round1"(%[sched]) \n"
|
||||||
|
|
||||||
void ECBCryptoAESNI::ExpandKey (const AESKey& key)
|
void ECBCryptoAESNI::ExpandKey (const AESKey& key)
|
||||||
{
|
{
|
||||||
|
@ -591,7 +591,7 @@ namespace crypto
|
||||||
"aeskeygenassist $64, %%xmm3, %%xmm2 \n"
|
"aeskeygenassist $64, %%xmm3, %%xmm2 \n"
|
||||||
// key expansion final
|
// key expansion final
|
||||||
"pshufd $0xff, %%xmm2, %%xmm2 \n"
|
"pshufd $0xff, %%xmm2, %%xmm2 \n"
|
||||||
"movaps %%xmm1, %%xmm4 \n"
|
"movaps %%xmm1, %%xmm4 \n"
|
||||||
"pslldq $4, %%xmm4 \n"
|
"pslldq $4, %%xmm4 \n"
|
||||||
"pxor %%xmm4, %%xmm1 \n"
|
"pxor %%xmm4, %%xmm1 \n"
|
||||||
"pslldq $4, %%xmm4 \n"
|
"pslldq $4, %%xmm4 \n"
|
||||||
|
@ -622,17 +622,17 @@ namespace crypto
|
||||||
"aesenc 192(%["#sched"]), %%xmm0 \n" \
|
"aesenc 192(%["#sched"]), %%xmm0 \n" \
|
||||||
"aesenc 208(%["#sched"]), %%xmm0 \n" \
|
"aesenc 208(%["#sched"]), %%xmm0 \n" \
|
||||||
"aesenclast 224(%["#sched"]), %%xmm0 \n"
|
"aesenclast 224(%["#sched"]), %%xmm0 \n"
|
||||||
|
|
||||||
void ECBEncryptionAESNI::Encrypt (const ChipherBlock * in, ChipherBlock * out)
|
void ECBEncryptionAESNI::Encrypt (const ChipherBlock * in, ChipherBlock * out)
|
||||||
{
|
{
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
EncryptAES256(sched)
|
EncryptAES256(sched)
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
|
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DecryptAES256(sched) \
|
#define DecryptAES256(sched) \
|
||||||
"pxor 224(%["#sched"]), %%xmm0 \n" \
|
"pxor 224(%["#sched"]), %%xmm0 \n" \
|
||||||
|
@ -650,22 +650,22 @@ namespace crypto
|
||||||
"aesdec 32(%["#sched"]), %%xmm0 \n" \
|
"aesdec 32(%["#sched"]), %%xmm0 \n" \
|
||||||
"aesdec 16(%["#sched"]), %%xmm0 \n" \
|
"aesdec 16(%["#sched"]), %%xmm0 \n" \
|
||||||
"aesdeclast (%["#sched"]), %%xmm0 \n"
|
"aesdeclast (%["#sched"]), %%xmm0 \n"
|
||||||
|
|
||||||
void ECBDecryptionAESNI::Decrypt (const ChipherBlock * in, ChipherBlock * out)
|
void ECBDecryptionAESNI::Decrypt (const ChipherBlock * in, ChipherBlock * out)
|
||||||
{
|
{
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
DecryptAES256(sched)
|
DecryptAES256(sched)
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
|
: : [sched]"r"(GetKeySchedule ()), [in]"r"(in), [out]"r"(out) : "%xmm0", "memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CallAESIMC(offset) \
|
#define CallAESIMC(offset) \
|
||||||
"movaps "#offset"(%[shed]), %%xmm0 \n" \
|
"movaps "#offset"(%[shed]), %%xmm0 \n" \
|
||||||
"aesimc %%xmm0, %%xmm0 \n" \
|
"aesimc %%xmm0, %%xmm0 \n" \
|
||||||
"movaps %%xmm0, "#offset"(%[shed]) \n"
|
"movaps %%xmm0, "#offset"(%[shed]) \n"
|
||||||
|
|
||||||
void ECBDecryptionAESNI::SetKey (const AESKey& key)
|
void ECBDecryptionAESNI::SetKey (const AESKey& key)
|
||||||
{
|
{
|
||||||
|
@ -690,7 +690,7 @@ namespace crypto
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
|
void CBCEncryption::Encrypt (int numBlocks, const ChipherBlock * in, ChipherBlock * out)
|
||||||
|
@ -698,31 +698,31 @@ namespace crypto
|
||||||
#ifdef AESNI
|
#ifdef AESNI
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
"movups (%[iv]), %%xmm1 \n"
|
||||||
"1: \n"
|
"1: \n"
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
"pxor %%xmm1, %%xmm0 \n"
|
||||||
EncryptAES256(sched)
|
EncryptAES256(sched)
|
||||||
"movaps %%xmm0, %%xmm1 \n"
|
"movaps %%xmm0, %%xmm1 \n"
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
"add $16, %[in] \n"
|
"add $16, %[in] \n"
|
||||||
"add $16, %[out] \n"
|
"add $16, %[out] \n"
|
||||||
"dec %[num] \n"
|
"dec %[num] \n"
|
||||||
"jnz 1b \n"
|
"jnz 1b \n"
|
||||||
"movups %%xmm1, (%[iv]) \n"
|
"movups %%xmm1, (%[iv]) \n"
|
||||||
:
|
:
|
||||||
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
|
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
|
||||||
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
||||||
: "%xmm0", "%xmm1", "cc", "memory"
|
: "%xmm0", "%xmm1", "cc", "memory"
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
for (int i = 0; i < numBlocks; i++)
|
for (int i = 0; i < numBlocks; i++)
|
||||||
{
|
{
|
||||||
*m_LastBlock.GetChipherBlock () ^= in[i];
|
*m_LastBlock.GetChipherBlock () ^= in[i];
|
||||||
m_ECBEncryption.Encrypt (m_LastBlock.GetChipherBlock (), m_LastBlock.GetChipherBlock ());
|
m_ECBEncryption.Encrypt (m_LastBlock.GetChipherBlock (), m_LastBlock.GetChipherBlock ());
|
||||||
out[i] = *m_LastBlock.GetChipherBlock ();
|
out[i] = *m_LastBlock.GetChipherBlock ();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBCEncryption::Encrypt (const uint8_t * in, std::size_t len, uint8_t * out)
|
void CBCEncryption::Encrypt (const uint8_t * in, std::size_t len, uint8_t * out)
|
||||||
|
@ -730,7 +730,7 @@ namespace crypto
|
||||||
// len/16
|
// len/16
|
||||||
int numBlocks = len >> 4;
|
int numBlocks = len >> 4;
|
||||||
if (numBlocks > 0)
|
if (numBlocks > 0)
|
||||||
Encrypt (numBlocks, (const ChipherBlock *)in, (ChipherBlock *)out);
|
Encrypt (numBlocks, (const ChipherBlock *)in, (ChipherBlock *)out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBCEncryption::Encrypt (const uint8_t * in, uint8_t * out)
|
void CBCEncryption::Encrypt (const uint8_t * in, uint8_t * out)
|
||||||
|
@ -740,17 +740,17 @@ namespace crypto
|
||||||
(
|
(
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
"movups (%[iv]), %%xmm1 \n"
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
"pxor %%xmm1, %%xmm0 \n"
|
||||||
EncryptAES256(sched)
|
EncryptAES256(sched)
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
"movups %%xmm0, (%[iv]) \n"
|
"movups %%xmm0, (%[iv]) \n"
|
||||||
:
|
:
|
||||||
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
|
: [iv]"r"((uint8_t *)m_LastBlock), [sched]"r"(m_ECBEncryption.GetKeySchedule ()),
|
||||||
[in]"r"(in), [out]"r"(out)
|
[in]"r"(in), [out]"r"(out)
|
||||||
: "%xmm0", "%xmm1", "memory"
|
: "%xmm0", "%xmm1", "memory"
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
Encrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
|
Encrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -760,23 +760,23 @@ namespace crypto
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
"movups (%[iv]), %%xmm1 \n"
|
||||||
"1: \n"
|
"1: \n"
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
"movaps %%xmm0, %%xmm2 \n"
|
"movaps %%xmm0, %%xmm2 \n"
|
||||||
DecryptAES256(sched)
|
DecryptAES256(sched)
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
"pxor %%xmm1, %%xmm0 \n"
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
"movaps %%xmm2, %%xmm1 \n"
|
"movaps %%xmm2, %%xmm1 \n"
|
||||||
"add $16, %[in] \n"
|
"add $16, %[in] \n"
|
||||||
"add $16, %[out] \n"
|
"add $16, %[out] \n"
|
||||||
"dec %[num] \n"
|
"dec %[num] \n"
|
||||||
"jnz 1b \n"
|
"jnz 1b \n"
|
||||||
"movups %%xmm1, (%[iv]) \n"
|
"movups %%xmm1, (%[iv]) \n"
|
||||||
:
|
:
|
||||||
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
|
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
|
||||||
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
[in]"r"(in), [out]"r"(out), [num]"r"(numBlocks)
|
||||||
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
|
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
for (int i = 0; i < numBlocks; i++)
|
for (int i = 0; i < numBlocks; i++)
|
||||||
{
|
{
|
||||||
|
@ -792,7 +792,7 @@ namespace crypto
|
||||||
{
|
{
|
||||||
int numBlocks = len >> 4;
|
int numBlocks = len >> 4;
|
||||||
if (numBlocks > 0)
|
if (numBlocks > 0)
|
||||||
Decrypt (numBlocks, (const ChipherBlock *)in, (ChipherBlock *)out);
|
Decrypt (numBlocks, (const ChipherBlock *)in, (ChipherBlock *)out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBCDecryption::Decrypt (const uint8_t * in, uint8_t * out)
|
void CBCDecryption::Decrypt (const uint8_t * in, uint8_t * out)
|
||||||
|
@ -801,18 +801,18 @@ namespace crypto
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"movups (%[iv]), %%xmm1 \n"
|
"movups (%[iv]), %%xmm1 \n"
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
"movups %%xmm0, (%[iv]) \n"
|
"movups %%xmm0, (%[iv]) \n"
|
||||||
DecryptAES256(sched)
|
DecryptAES256(sched)
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
"pxor %%xmm1, %%xmm0 \n"
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
:
|
:
|
||||||
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
|
: [iv]"r"((uint8_t *)m_IV), [sched]"r"(m_ECBDecryption.GetKeySchedule ()),
|
||||||
[in]"r"(in), [out]"r"(out)
|
[in]"r"(in), [out]"r"(out)
|
||||||
: "%xmm0", "%xmm1", "memory"
|
: "%xmm0", "%xmm1", "memory"
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
Decrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
|
Decrypt (1, (const ChipherBlock *)in, (ChipherBlock *)out);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -821,7 +821,7 @@ namespace crypto
|
||||||
#ifdef AESNI
|
#ifdef AESNI
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
// encrypt IV
|
// encrypt IV
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
EncryptAES256(sched_iv)
|
EncryptAES256(sched_iv)
|
||||||
"movaps %%xmm0, %%xmm1 \n"
|
"movaps %%xmm0, %%xmm1 \n"
|
||||||
|
@ -831,16 +831,16 @@ namespace crypto
|
||||||
// encrypt data, IV is xmm1
|
// encrypt data, IV is xmm1
|
||||||
"1: \n"
|
"1: \n"
|
||||||
"add $16, %[in] \n"
|
"add $16, %[in] \n"
|
||||||
"add $16, %[out] \n"
|
"add $16, %[out] \n"
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
"pxor %%xmm1, %%xmm0 \n"
|
||||||
EncryptAES256(sched_l)
|
EncryptAES256(sched_l)
|
||||||
"movaps %%xmm0, %%xmm1 \n"
|
"movaps %%xmm0, %%xmm1 \n"
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
"dec %[num] \n"
|
"dec %[num] \n"
|
||||||
"jnz 1b \n"
|
"jnz 1b \n"
|
||||||
:
|
:
|
||||||
: [sched_iv]"r"(m_IVEncryption.GetKeySchedule ()), [sched_l]"r"(m_LayerEncryption.GetKeySchedule ()),
|
: [sched_iv]"r"(m_IVEncryption.GetKeySchedule ()), [sched_l]"r"(m_LayerEncryption.GetKeySchedule ()),
|
||||||
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
|
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
|
||||||
: "%xmm0", "%xmm1", "cc", "memory"
|
: "%xmm0", "%xmm1", "cc", "memory"
|
||||||
);
|
);
|
||||||
|
@ -857,7 +857,7 @@ namespace crypto
|
||||||
#ifdef AESNI
|
#ifdef AESNI
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
// decrypt IV
|
// decrypt IV
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
DecryptAES256(sched_iv)
|
DecryptAES256(sched_iv)
|
||||||
"movaps %%xmm0, %%xmm1 \n"
|
"movaps %%xmm0, %%xmm1 \n"
|
||||||
|
@ -867,27 +867,27 @@ namespace crypto
|
||||||
// decrypt data, IV is xmm1
|
// decrypt data, IV is xmm1
|
||||||
"1: \n"
|
"1: \n"
|
||||||
"add $16, %[in] \n"
|
"add $16, %[in] \n"
|
||||||
"add $16, %[out] \n"
|
"add $16, %[out] \n"
|
||||||
"movups (%[in]), %%xmm0 \n"
|
"movups (%[in]), %%xmm0 \n"
|
||||||
"movaps %%xmm0, %%xmm2 \n"
|
"movaps %%xmm0, %%xmm2 \n"
|
||||||
DecryptAES256(sched_l)
|
DecryptAES256(sched_l)
|
||||||
"pxor %%xmm1, %%xmm0 \n"
|
"pxor %%xmm1, %%xmm0 \n"
|
||||||
"movups %%xmm0, (%[out]) \n"
|
"movups %%xmm0, (%[out]) \n"
|
||||||
"movaps %%xmm2, %%xmm1 \n"
|
"movaps %%xmm2, %%xmm1 \n"
|
||||||
"dec %[num] \n"
|
"dec %[num] \n"
|
||||||
"jnz 1b \n"
|
"jnz 1b \n"
|
||||||
:
|
:
|
||||||
: [sched_iv]"r"(m_IVDecryption.GetKeySchedule ()), [sched_l]"r"(m_LayerDecryption.GetKeySchedule ()),
|
: [sched_iv]"r"(m_IVDecryption.GetKeySchedule ()), [sched_l]"r"(m_LayerDecryption.GetKeySchedule ()),
|
||||||
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
|
[in]"r"(in), [out]"r"(out), [num]"r"(63) // 63 blocks = 1008 bytes
|
||||||
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
|
: "%xmm0", "%xmm1", "%xmm2", "cc", "memory"
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
m_IVDecryption.Decrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv
|
m_IVDecryption.Decrypt ((const ChipherBlock *)in, (ChipherBlock *)out); // iv
|
||||||
m_LayerDecryption.SetIV (out);
|
m_LayerDecryption.SetIV (out);
|
||||||
m_LayerDecryption.Decrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
|
m_LayerDecryption.Decrypt (in + 16, i2p::tunnel::TUNNEL_DATA_ENCRYPTED_SIZE, out + 16); // data
|
||||||
m_IVDecryption.Decrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv
|
m_IVDecryption.Decrypt ((ChipherBlock *)out, (ChipherBlock *)out); // double iv
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;
|
/* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;
|
||||||
static void OpensslLockingCallback(int mode, int type, const char * file, int line)
|
static void OpensslLockingCallback(int mode, int type, const char * file, int line)
|
||||||
|
@ -898,45 +898,44 @@ namespace crypto
|
||||||
m_OpenSSLMutexes[type]->lock ();
|
m_OpenSSLMutexes[type]->lock ();
|
||||||
else
|
else
|
||||||
m_OpenSSLMutexes[type]->unlock ();
|
m_OpenSSLMutexes[type]->unlock ();
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
||||||
void InitCrypto (bool precomputation)
|
void InitCrypto (bool precomputation)
|
||||||
{
|
{
|
||||||
SSL_library_init ();
|
SSL_library_init ();
|
||||||
/* auto numLocks = CRYPTO_num_locks();
|
/* auto numLocks = CRYPTO_num_locks();
|
||||||
for (int i = 0; i < numLocks; i++)
|
for (int i = 0; i < numLocks; i++)
|
||||||
m_OpenSSLMutexes.emplace_back (new std::mutex);
|
m_OpenSSLMutexes.emplace_back (new std::mutex);
|
||||||
CRYPTO_set_locking_callback (OpensslLockingCallback);*/
|
CRYPTO_set_locking_callback (OpensslLockingCallback);*/
|
||||||
if (precomputation)
|
if (precomputation)
|
||||||
{
|
{
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
g_ElggTable = new BIGNUM * [ELGAMAL_FULL_EXPONENT_NUM_BYTES][255];
|
g_ElggTable = new BIGNUM * [ELGAMAL_FULL_EXPONENT_NUM_BYTES][255];
|
||||||
PrecalculateElggTable (g_ElggTable, ELGAMAL_FULL_EXPONENT_NUM_BYTES);
|
PrecalculateElggTable (g_ElggTable, ELGAMAL_FULL_EXPONENT_NUM_BYTES);
|
||||||
#else
|
#else
|
||||||
g_ElggTable = new BIGNUM * [ELGAMAL_SHORT_EXPONENT_NUM_BYTES][255];
|
g_ElggTable = new BIGNUM * [ELGAMAL_SHORT_EXPONENT_NUM_BYTES][255];
|
||||||
PrecalculateElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES);
|
PrecalculateElggTable (g_ElggTable, ELGAMAL_SHORT_EXPONENT_NUM_BYTES);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminateCrypto ()
|
void TerminateCrypto ()
|
||||||
{
|
{
|
||||||
if (g_ElggTable)
|
if (g_ElggTable)
|
||||||
{
|
{
|
||||||
DestroyElggTable (g_ElggTable,
|
DestroyElggTable (g_ElggTable,
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
ELGAMAL_FULL_EXPONENT_NUM_BYTES
|
ELGAMAL_FULL_EXPONENT_NUM_BYTES
|
||||||
#else
|
#else
|
||||||
ELGAMAL_SHORT_EXPONENT_NUM_BYTES
|
ELGAMAL_SHORT_EXPONENT_NUM_BYTES
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
delete[] g_ElggTable; g_ElggTable = nullptr;
|
delete[] g_ElggTable; g_ElggTable = nullptr;
|
||||||
}
|
}
|
||||||
/* CRYPTO_set_locking_callback (nullptr);
|
/* CRYPTO_set_locking_callback (nullptr);
|
||||||
m_OpenSSLMutexes.clear ();*/
|
m_OpenSSLMutexes.clear ();*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -483,9 +483,22 @@ namespace client
|
||||||
{
|
{
|
||||||
if (m_PublishReplyToken)
|
if (m_PublishReplyToken)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again");
|
|
||||||
m_PublishReplyToken = 0;
|
m_PublishReplyToken = 0;
|
||||||
Publish ();
|
if (GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds, will try again");
|
||||||
|
Publish ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "Destination: Publish confirmation was not received in ", PUBLISH_CONFIRMATION_TIMEOUT, " seconds from Java floodfill for crypto type ", (int)GetIdentity ()->GetCryptoKeyType ());
|
||||||
|
// Java floodfill never sends confirmantion back for unknown crypto type
|
||||||
|
// assume it successive and try to verify
|
||||||
|
m_PublishVerificationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_VERIFICATION_TIMEOUT));
|
||||||
|
m_PublishVerificationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishVerificationTimer,
|
||||||
|
shared_from_this (), std::placeholders::_1));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -702,8 +715,8 @@ namespace client
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map<std::string, std::string> * params):
|
ClientDestination::ClientDestination (const i2p::data::PrivateKeys& keys, bool isPublic, const std::map<std::string, std::string> * params):
|
||||||
LeaseSetDestination (isPublic, params),
|
LeaseSetDestination (isPublic, params), m_Keys (keys), m_StreamingAckDelay (DEFAULT_INITIAL_ACK_DELAY),
|
||||||
m_Keys (keys), m_DatagramDestination (nullptr), m_RefCounter (0),
|
m_DatagramDestination (nullptr), m_RefCounter (0),
|
||||||
m_ReadyChecker(GetService())
|
m_ReadyChecker(GetService())
|
||||||
{
|
{
|
||||||
if (isPublic)
|
if (isPublic)
|
||||||
|
@ -714,6 +727,14 @@ namespace client
|
||||||
m_Decryptor = m_Keys.CreateDecryptor (m_EncryptionPrivateKey);
|
m_Decryptor = m_Keys.CreateDecryptor (m_EncryptionPrivateKey);
|
||||||
if (isPublic)
|
if (isPublic)
|
||||||
LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created");
|
LogPrint (eLogInfo, "Destination: Local address ", GetIdentHash().ToBase32 (), " created");
|
||||||
|
|
||||||
|
// extract streaming params
|
||||||
|
if (params)
|
||||||
|
{
|
||||||
|
auto it = params->find (I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY);
|
||||||
|
if (it != params->end ())
|
||||||
|
m_StreamingAckDelay = std::stoi(it->second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientDestination::~ClientDestination ()
|
ClientDestination::~ClientDestination ()
|
||||||
|
|
|
@ -58,6 +58,10 @@ namespace client
|
||||||
const char I2CP_PARAM_MAX_TUNNEL_LATENCY[] = "latency.max";
|
const char I2CP_PARAM_MAX_TUNNEL_LATENCY[] = "latency.max";
|
||||||
const int DEFAULT_MAX_TUNNEL_LATENCY = 0;
|
const int DEFAULT_MAX_TUNNEL_LATENCY = 0;
|
||||||
|
|
||||||
|
// streaming
|
||||||
|
const char I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY[] = "i2p.streaming.initialAckDelay";
|
||||||
|
const int DEFAULT_INITIAL_ACK_DELAY = 200; // milliseconds
|
||||||
|
|
||||||
typedef std::function<void (std::shared_ptr<i2p::stream::Stream> stream)> StreamRequestComplete;
|
typedef std::function<void (std::shared_ptr<i2p::stream::Stream> stream)> StreamRequestComplete;
|
||||||
|
|
||||||
class LeaseSetDestination: public i2p::garlic::GarlicDestination,
|
class LeaseSetDestination: public i2p::garlic::GarlicDestination,
|
||||||
|
@ -199,6 +203,7 @@ namespace client
|
||||||
void StopAcceptingStreams ();
|
void StopAcceptingStreams ();
|
||||||
bool IsAcceptingStreams () const;
|
bool IsAcceptingStreams () const;
|
||||||
void AcceptOnce (const i2p::stream::StreamingDestination::Acceptor& acceptor);
|
void AcceptOnce (const i2p::stream::StreamingDestination::Acceptor& acceptor);
|
||||||
|
int GetStreamingAckDelay () const { return m_StreamingAckDelay; }
|
||||||
|
|
||||||
// datagram
|
// datagram
|
||||||
i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; };
|
i2p::datagram::DatagramDestination * GetDatagramDestination () const { return m_DatagramDestination; };
|
||||||
|
@ -230,6 +235,7 @@ namespace client
|
||||||
uint8_t m_EncryptionPublicKey[256], m_EncryptionPrivateKey[256];
|
uint8_t m_EncryptionPublicKey[256], m_EncryptionPrivateKey[256];
|
||||||
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor;
|
std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> m_Decryptor;
|
||||||
|
|
||||||
|
int m_StreamingAckDelay;
|
||||||
std::shared_ptr<i2p::stream::StreamingDestination> m_StreamingDestination; // default
|
std::shared_ptr<i2p::stream::StreamingDestination> m_StreamingDestination; // default
|
||||||
std::map<uint16_t, std::shared_ptr<i2p::stream::StreamingDestination> > m_StreamingDestinationsByPorts;
|
std::map<uint16_t, std::shared_ptr<i2p::stream::StreamingDestination> > m_StreamingDestinationsByPorts;
|
||||||
i2p::datagram::DatagramDestination * m_DatagramDestination;
|
i2p::datagram::DatagramDestination * m_DatagramDestination;
|
||||||
|
|
|
@ -324,6 +324,12 @@ namespace data
|
||||||
return SIGNING_KEY_TYPE_DSA_SHA1;
|
return SIGNING_KEY_TYPE_DSA_SHA1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IdentityEx::IsRSA () const
|
||||||
|
{
|
||||||
|
auto sigType = GetSigningKeyType ();
|
||||||
|
return sigType <= SIGNING_KEY_TYPE_RSA_SHA512_4096 && sigType >= SIGNING_KEY_TYPE_RSA_SHA256_2048;
|
||||||
|
}
|
||||||
|
|
||||||
CryptoKeyType IdentityEx::GetCryptoKeyType () const
|
CryptoKeyType IdentityEx::GetCryptoKeyType () const
|
||||||
{
|
{
|
||||||
if (m_StandardIdentity.certificate[0] == CERTIFICATE_TYPE_KEY && m_ExtendedLen >= 4)
|
if (m_StandardIdentity.certificate[0] == CERTIFICATE_TYPE_KEY && m_ExtendedLen >= 4)
|
||||||
|
@ -451,6 +457,7 @@ namespace data
|
||||||
return std::make_shared<i2p::crypto::ElGamalEncryptor>(key);
|
return std::make_shared<i2p::crypto::ElGamalEncryptor>(key);
|
||||||
break;
|
break;
|
||||||
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC:
|
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC:
|
||||||
|
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST:
|
||||||
return std::make_shared<i2p::crypto::ECIESP256Encryptor>(key);
|
return std::make_shared<i2p::crypto::ECIESP256Encryptor>(key);
|
||||||
break;
|
break;
|
||||||
case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC:
|
case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC:
|
||||||
|
@ -602,6 +609,7 @@ namespace data
|
||||||
return std::make_shared<i2p::crypto::ElGamalDecryptor>(key);
|
return std::make_shared<i2p::crypto::ElGamalDecryptor>(key);
|
||||||
break;
|
break;
|
||||||
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC:
|
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC:
|
||||||
|
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST:
|
||||||
return std::make_shared<i2p::crypto::ECIESP256Decryptor>(key);
|
return std::make_shared<i2p::crypto::ECIESP256Decryptor>(key);
|
||||||
break;
|
break;
|
||||||
case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC:
|
case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC:
|
||||||
|
@ -632,14 +640,10 @@ namespace data
|
||||||
i2p::crypto::CreateECDSAP521RandomKeys (keys.m_SigningPrivateKey, signingPublicKey);
|
i2p::crypto::CreateECDSAP521RandomKeys (keys.m_SigningPrivateKey, signingPublicKey);
|
||||||
break;
|
break;
|
||||||
case SIGNING_KEY_TYPE_RSA_SHA256_2048:
|
case SIGNING_KEY_TYPE_RSA_SHA256_2048:
|
||||||
i2p::crypto::CreateRSARandomKeys (i2p::crypto::RSASHA2562048_KEY_LENGTH, keys.m_SigningPrivateKey, signingPublicKey);
|
|
||||||
break;
|
|
||||||
case SIGNING_KEY_TYPE_RSA_SHA384_3072:
|
case SIGNING_KEY_TYPE_RSA_SHA384_3072:
|
||||||
i2p::crypto::CreateRSARandomKeys (i2p::crypto::RSASHA3843072_KEY_LENGTH, keys.m_SigningPrivateKey, signingPublicKey);
|
|
||||||
break;
|
|
||||||
case SIGNING_KEY_TYPE_RSA_SHA512_4096:
|
case SIGNING_KEY_TYPE_RSA_SHA512_4096:
|
||||||
i2p::crypto::CreateRSARandomKeys (i2p::crypto::RSASHA5124096_KEY_LENGTH, keys.m_SigningPrivateKey, signingPublicKey);
|
LogPrint (eLogWarning, "Identity: RSA signature type is not supported. Create EdDSA");
|
||||||
break;
|
// no break here
|
||||||
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
||||||
i2p::crypto::CreateEDDSA25519RandomKeys (keys.m_SigningPrivateKey, signingPublicKey);
|
i2p::crypto::CreateEDDSA25519RandomKeys (keys.m_SigningPrivateKey, signingPublicKey);
|
||||||
break;
|
break;
|
||||||
|
@ -650,7 +654,7 @@ namespace data
|
||||||
i2p::crypto::CreateGOSTR3410RandomKeys (i2p::crypto::eGOSTR3410TC26A512, keys.m_SigningPrivateKey, signingPublicKey);
|
i2p::crypto::CreateGOSTR3410RandomKeys (i2p::crypto::eGOSTR3410TC26A512, keys.m_SigningPrivateKey, signingPublicKey);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LogPrint (eLogError, "Identity: Signing key type ", (int)type, " is not supported. Create DSA-SHA1");
|
LogPrint (eLogWarning, "Identity: Signing key type ", (int)type, " is not supported. Create DSA-SHA1");
|
||||||
return PrivateKeys (i2p::data::CreateRandomKeys ()); // DSA-SHA1
|
return PrivateKeys (i2p::data::CreateRandomKeys ()); // DSA-SHA1
|
||||||
}
|
}
|
||||||
// encryption
|
// encryption
|
||||||
|
@ -673,6 +677,7 @@ namespace data
|
||||||
i2p::crypto::GenerateElGamalKeyPair(priv, pub);
|
i2p::crypto::GenerateElGamalKeyPair(priv, pub);
|
||||||
break;
|
break;
|
||||||
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC:
|
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC:
|
||||||
|
case CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST:
|
||||||
i2p::crypto::CreateECIESP256RandomKeys (priv, pub);
|
i2p::crypto::CreateECIESP256RandomKeys (priv, pub);
|
||||||
break;
|
break;
|
||||||
case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC:
|
case CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC:
|
||||||
|
|
|
@ -53,7 +53,8 @@ namespace data
|
||||||
const size_t DEFAULT_IDENTITY_SIZE = sizeof (Identity); // 387 bytes
|
const size_t DEFAULT_IDENTITY_SIZE = sizeof (Identity); // 387 bytes
|
||||||
|
|
||||||
const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0;
|
const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0;
|
||||||
const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 65280; // TODO: change to actual code
|
const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 1;
|
||||||
|
const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST = 65280; // TODO: remove later
|
||||||
const uint16_t CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC = 65281; // TODO: use GOST R 34.11 instead SHA256 and GOST 28147-89 instead AES
|
const uint16_t CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC = 65281; // TODO: use GOST R 34.11 instead SHA256 and GOST 28147-89 instead AES
|
||||||
|
|
||||||
const uint16_t SIGNING_KEY_TYPE_DSA_SHA1 = 0;
|
const uint16_t SIGNING_KEY_TYPE_DSA_SHA1 = 0;
|
||||||
|
@ -102,6 +103,7 @@ namespace data
|
||||||
size_t GetSignatureLen () const;
|
size_t GetSignatureLen () const;
|
||||||
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const;
|
bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const;
|
||||||
SigningKeyType GetSigningKeyType () const;
|
SigningKeyType GetSigningKeyType () const;
|
||||||
|
bool IsRSA () const; // signing key type
|
||||||
CryptoKeyType GetCryptoKeyType () const;
|
CryptoKeyType GetCryptoKeyType () const;
|
||||||
void DropVerifier () const; // to save memory
|
void DropVerifier () const; // to save memory
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,11 @@ namespace log {
|
||||||
*/
|
*/
|
||||||
static const char * g_LogLevelStr[eNumLogLevels] =
|
static const char * g_LogLevelStr[eNumLogLevels] =
|
||||||
{
|
{
|
||||||
|
"none", // eLogNone
|
||||||
"error", // eLogError
|
"error", // eLogError
|
||||||
"warn", // eLogWarn
|
"warn", // eLogWarn
|
||||||
"info", // eLogInfo
|
"info", // eLogInfo
|
||||||
"debug" // eLogDebug
|
"debug" // eLogDebug
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,9 +28,10 @@ namespace log {
|
||||||
* @note Using ISO 6429 (ANSI) color sequences
|
* @note Using ISO 6429 (ANSI) color sequences
|
||||||
*/
|
*/
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static const char *LogMsgColors[] = { "", "", "", "", "" };
|
static const char *LogMsgColors[] = { "", "", "", "", "", "" };
|
||||||
#else /* UNIX */
|
#else /* UNIX */
|
||||||
static const char *LogMsgColors[] = {
|
static const char *LogMsgColors[] = {
|
||||||
|
[eLogNone] = "\033[0m", /* reset */
|
||||||
[eLogError] = "\033[1;31m", /* red */
|
[eLogError] = "\033[1;31m", /* red */
|
||||||
[eLogWarning] = "\033[1;33m", /* yellow */
|
[eLogWarning] = "\033[1;33m", /* yellow */
|
||||||
[eLogInfo] = "\033[1;36m", /* cyan */
|
[eLogInfo] = "\033[1;36m", /* cyan */
|
||||||
|
@ -46,6 +48,7 @@ namespace log {
|
||||||
static inline int GetSyslogPrio (enum LogLevel l) {
|
static inline int GetSyslogPrio (enum LogLevel l) {
|
||||||
int priority = LOG_DEBUG;
|
int priority = LOG_DEBUG;
|
||||||
switch (l) {
|
switch (l) {
|
||||||
|
case eLogNone : priority = LOG_CRIT; break;
|
||||||
case eLogError : priority = LOG_ERR; break;
|
case eLogError : priority = LOG_ERR; break;
|
||||||
case eLogWarning : priority = LOG_WARNING; break;
|
case eLogWarning : priority = LOG_WARNING; break;
|
||||||
case eLogInfo : priority = LOG_INFO; break;
|
case eLogInfo : priority = LOG_INFO; break;
|
||||||
|
@ -71,15 +74,15 @@ namespace log {
|
||||||
void Log::Start ()
|
void Log::Start ()
|
||||||
{
|
{
|
||||||
if (!m_IsRunning)
|
if (!m_IsRunning)
|
||||||
{
|
{
|
||||||
m_IsRunning = true;
|
m_IsRunning = true;
|
||||||
m_Thread = new std::thread (std::bind (&Log::Run, this));
|
m_Thread = new std::thread (std::bind (&Log::Run, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Log::Stop ()
|
void Log::Stop ()
|
||||||
{
|
{
|
||||||
switch (m_Destination)
|
switch (m_Destination)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
case eLogSyslog :
|
case eLogSyslog :
|
||||||
|
@ -97,15 +100,16 @@ namespace log {
|
||||||
m_IsRunning = false;
|
m_IsRunning = false;
|
||||||
m_Queue.WakeUp ();
|
m_Queue.WakeUp ();
|
||||||
if (m_Thread)
|
if (m_Thread)
|
||||||
{
|
{
|
||||||
m_Thread->join ();
|
m_Thread->join ();
|
||||||
delete m_Thread;
|
delete m_Thread;
|
||||||
m_Thread = nullptr;
|
m_Thread = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Log::SetLogLevel (const std::string& level) {
|
void Log::SetLogLevel (const std::string& level) {
|
||||||
if (level == "error") { m_MinLevel = eLogError; }
|
if (level == "none") { m_MinLevel = eLogNone; }
|
||||||
|
else if (level == "error") { m_MinLevel = eLogError; }
|
||||||
else if (level == "warn") { m_MinLevel = eLogWarning; }
|
else if (level == "warn") { m_MinLevel = eLogWarning; }
|
||||||
else if (level == "info") { m_MinLevel = eLogInfo; }
|
else if (level == "info") { m_MinLevel = eLogInfo; }
|
||||||
else if (level == "debug") { m_MinLevel = eLogDebug; }
|
else if (level == "debug") { m_MinLevel = eLogDebug; }
|
||||||
|
@ -115,7 +119,7 @@ namespace log {
|
||||||
}
|
}
|
||||||
LogPrint(eLogInfo, "Log: min messages level set to ", level);
|
LogPrint(eLogInfo, "Log: min messages level set to ", level);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * Log::TimeAsString(std::time_t t) {
|
const char * Log::TimeAsString(std::time_t t) {
|
||||||
if (t != m_LastTimestamp) {
|
if (t != m_LastTimestamp) {
|
||||||
strftime(m_LastDateTime, sizeof(m_LastDateTime), m_TimeFormat.c_str(), localtime(&t));
|
strftime(m_LastDateTime, sizeof(m_LastDateTime), m_TimeFormat.c_str(), localtime(&t));
|
||||||
|
@ -129,7 +133,7 @@ namespace log {
|
||||||
* Unfortunately, with current startup process with late fork() this
|
* Unfortunately, with current startup process with late fork() this
|
||||||
* will give us nothing but pain. Maybe later. See in NetDb as example.
|
* will give us nothing but pain. Maybe later. See in NetDb as example.
|
||||||
*/
|
*/
|
||||||
void Log::Process(std::shared_ptr<LogMsg> msg)
|
void Log::Process(std::shared_ptr<LogMsg> msg)
|
||||||
{
|
{
|
||||||
if (!msg) return;
|
if (!msg) return;
|
||||||
std::hash<std::thread::id> hasher;
|
std::hash<std::thread::id> hasher;
|
||||||
|
@ -165,25 +169,26 @@ namespace log {
|
||||||
while (m_IsRunning)
|
while (m_IsRunning)
|
||||||
{
|
{
|
||||||
std::shared_ptr<LogMsg> msg;
|
std::shared_ptr<LogMsg> msg;
|
||||||
while (msg = m_Queue.Get ())
|
while ((msg = m_Queue.Get ()))
|
||||||
Process (msg);
|
Process (msg);
|
||||||
if (m_LogStream) m_LogStream->flush();
|
if (m_LogStream) m_LogStream->flush();
|
||||||
if (m_IsRunning)
|
if (m_IsRunning)
|
||||||
m_Queue.Wait ();
|
m_Queue.Wait ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Log::Append(std::shared_ptr<i2p::log::LogMsg> & msg)
|
void Log::Append(std::shared_ptr<i2p::log::LogMsg> & msg)
|
||||||
{
|
{
|
||||||
m_Queue.Put(msg);
|
m_Queue.Put(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Log::SendTo (const std::string& path)
|
void Log::SendTo (const std::string& path)
|
||||||
{
|
{
|
||||||
if (m_LogStream) m_LogStream = nullptr; // close previous
|
if (m_LogStream) m_LogStream = nullptr; // close previous
|
||||||
|
if (m_MinLevel == eLogNone) return;
|
||||||
auto flags = std::ofstream::out | std::ofstream::app;
|
auto flags = std::ofstream::out | std::ofstream::app;
|
||||||
auto os = std::make_shared<std::ofstream> (path, flags);
|
auto os = std::make_shared<std::ofstream> (path, flags);
|
||||||
if (os->is_open ())
|
if (os->is_open ())
|
||||||
{
|
{
|
||||||
m_HasColors = false;
|
m_HasColors = false;
|
||||||
m_Logfile = path;
|
m_Logfile = path;
|
||||||
|
@ -202,6 +207,7 @@ namespace log {
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
void Log::SendTo(const char *name, int facility) {
|
void Log::SendTo(const char *name, int facility) {
|
||||||
|
if (m_MinLevel == eLogNone) return;
|
||||||
m_HasColors = false;
|
m_HasColors = false;
|
||||||
m_Destination = eLogSyslog;
|
m_Destination = eLogSyslog;
|
||||||
m_LogStream = nullptr;
|
m_LogStream = nullptr;
|
||||||
|
|
|
@ -25,10 +25,11 @@
|
||||||
|
|
||||||
enum LogLevel
|
enum LogLevel
|
||||||
{
|
{
|
||||||
eLogError = 0,
|
eLogNone = 0,
|
||||||
|
eLogError,
|
||||||
eLogWarning,
|
eLogWarning,
|
||||||
eLogInfo,
|
eLogInfo,
|
||||||
eLogDebug,
|
eLogDebug,
|
||||||
eNumLogLevels
|
eNumLogLevels
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1247,7 +1247,7 @@ namespace transport
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
buff[4] = (uint8_t) addrsize;
|
buff[4] = (uint8_t) addrsize;
|
||||||
memcpy(buff+4, host.c_str(), addrsize);
|
memcpy(buff+5, host.c_str(), addrsize);
|
||||||
}
|
}
|
||||||
htobe16buf(buff+sz, port);
|
htobe16buf(buff+sz, port);
|
||||||
sz += 2;
|
sz += 2;
|
||||||
|
@ -1259,7 +1259,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, sz), [=](const boost::system::error_code & e, std::size_t transferred) {
|
boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 10), [=](const boost::system::error_code & e, std::size_t transferred) {
|
||||||
if(e)
|
if(e)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "NTCP: socks proxy read error ", e.message());
|
LogPrint(eLogError, "NTCP: socks proxy read error ", e.message());
|
||||||
|
|
|
@ -489,6 +489,27 @@ namespace data
|
||||||
|
|
||||||
std::string Reseeder::HttpsRequest (const std::string& address)
|
std::string Reseeder::HttpsRequest (const std::string& address)
|
||||||
{
|
{
|
||||||
|
i2p::http::URL proxyUrl;
|
||||||
|
std::string proxy; i2p::config::GetOption("reseed.proxy", proxy);
|
||||||
|
// check for proxy url
|
||||||
|
if(proxy.size()) {
|
||||||
|
// parse
|
||||||
|
if(proxyUrl.parse(proxy)) {
|
||||||
|
if (proxyUrl.schema == "http" && !proxyUrl.port) {
|
||||||
|
proxyUrl.port = 80;
|
||||||
|
} else if (proxyUrl.schema == "socks" && !proxyUrl.port) {
|
||||||
|
proxyUrl.port = 1080;
|
||||||
|
}
|
||||||
|
// check for valid proxy url schema
|
||||||
|
if (proxyUrl.schema != "http" && proxyUrl.schema != "socks") {
|
||||||
|
LogPrint(eLogError, "Reseed: bad proxy url: ", proxy);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LogPrint(eLogError, "Reseed: bad proxy url: ", proxy);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
i2p::http::URL url;
|
i2p::http::URL url;
|
||||||
if (!url.parse(address)) {
|
if (!url.parse(address)) {
|
||||||
LogPrint(eLogError, "Reseed: failed to parse url: ", address);
|
LogPrint(eLogError, "Reseed: failed to parse url: ", address);
|
||||||
|
@ -500,68 +521,185 @@ namespace data
|
||||||
|
|
||||||
boost::asio::io_service service;
|
boost::asio::io_service service;
|
||||||
boost::system::error_code ecode;
|
boost::system::error_code ecode;
|
||||||
auto it = boost::asio::ip::tcp::resolver(service).resolve (
|
|
||||||
boost::asio::ip::tcp::resolver::query (url.host, std::to_string(url.port)), ecode);
|
boost::asio::ssl::context ctx(service, boost::asio::ssl::context::sslv23);
|
||||||
if (!ecode)
|
ctx.set_verify_mode(boost::asio::ssl::context::verify_none);
|
||||||
|
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> s(service, ctx);
|
||||||
|
|
||||||
|
if(proxyUrl.schema.size())
|
||||||
{
|
{
|
||||||
boost::asio::ssl::context ctx(service, boost::asio::ssl::context::sslv23);
|
// proxy connection
|
||||||
ctx.set_verify_mode(boost::asio::ssl::context::verify_none);
|
auto it = boost::asio::ip::tcp::resolver(service).resolve (
|
||||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> s(service, ctx);
|
boost::asio::ip::tcp::resolver::query (proxyUrl.host, std::to_string(proxyUrl.port)), ecode);
|
||||||
s.lowest_layer().connect (*it, ecode);
|
if(!ecode)
|
||||||
if (!ecode)
|
|
||||||
{
|
{
|
||||||
SSL_set_tlsext_host_name(s.native_handle(), url.host.c_str ());
|
s.lowest_layer().connect(*it, ecode);
|
||||||
s.handshake (boost::asio::ssl::stream_base::client, ecode);
|
if(!ecode)
|
||||||
if (!ecode)
|
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "Reseed: Connected to ", url.host, ":", url.port);
|
auto & sock = s.next_layer();
|
||||||
i2p::http::HTTPReq req;
|
if(proxyUrl.schema == "http")
|
||||||
req.uri = url.to_string();
|
{
|
||||||
req.AddHeader("User-Agent", "Wget/1.11.4");
|
i2p::http::HTTPReq proxyReq;
|
||||||
req.AddHeader("Connection", "close");
|
i2p::http::HTTPRes proxyRes;
|
||||||
s.write_some (boost::asio::buffer (req.to_string()));
|
proxyReq.method = "CONNECT";
|
||||||
// read response
|
proxyReq.version = "HTTP/1.1";
|
||||||
std::stringstream rs;
|
proxyReq.uri = url.host + ":" + std::to_string(url.port);
|
||||||
char recv_buf[1024]; size_t l = 0;
|
|
||||||
do {
|
boost::asio::streambuf writebuf, readbuf;
|
||||||
l = s.read_some (boost::asio::buffer (recv_buf, sizeof(recv_buf)), ecode);
|
|
||||||
if (l) rs.write (recv_buf, l);
|
std::ostream out(&writebuf);
|
||||||
} while (!ecode && l);
|
out << proxyReq.to_string();
|
||||||
// process response
|
|
||||||
std::string data = rs.str();
|
boost::asio::write(sock, writebuf.data(), boost::asio::transfer_all(), ecode);
|
||||||
i2p::http::HTTPRes res;
|
if (ecode)
|
||||||
int len = res.parse(data);
|
{
|
||||||
if (len <= 0) {
|
sock.close();
|
||||||
LogPrint(eLogWarning, "Reseed: incomplete/broken response from ", url.host);
|
LogPrint(eLogError, "Reseed: HTTP CONNECT write error: ", ecode.message());
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
if (res.code != 200) {
|
boost::asio::read_until(sock, readbuf, "\r\n\r\n", ecode);
|
||||||
LogPrint(eLogError, "Reseed: failed to reseed from ", url.host, ", http code ", res.code);
|
if (ecode)
|
||||||
return "";
|
{
|
||||||
}
|
sock.close();
|
||||||
data.erase(0, len); /* drop http headers from response */
|
LogPrint(eLogError, "Reseed: HTTP CONNECT read error: ", ecode.message());
|
||||||
LogPrint(eLogDebug, "Reseed: got ", data.length(), " bytes of data from ", url.host);
|
return "";
|
||||||
if (res.is_chunked()) {
|
}
|
||||||
std::stringstream in(data), out;
|
if(proxyRes.parse(boost::asio::buffer_cast<const char *>(readbuf.data()), readbuf.size()) <= 0)
|
||||||
if (!i2p::http::MergeChunkedResponse(in, out)) {
|
{
|
||||||
LogPrint(eLogWarning, "Reseed: failed to merge chunked response from ", url.host);
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: HTTP CONNECT malformed reply");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if(proxyRes.code != 200)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: HTTP CONNECT got bad status: ", proxyRes.code);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// assume socks if not http, is checked before this for other types
|
||||||
|
// TODO: support username/password auth etc
|
||||||
|
uint8_t hs_writebuf[3] = {0x05, 0x01, 0x00};
|
||||||
|
uint8_t hs_readbuf[2];
|
||||||
|
boost::asio::write(sock, boost::asio::buffer(hs_writebuf, 3), boost::asio::transfer_all(), ecode);
|
||||||
|
if(ecode)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: SOCKS handshake write failed: ", ecode.message());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
boost::asio::read(sock, boost::asio::buffer(hs_readbuf, 2), ecode);
|
||||||
|
if(ecode)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: SOCKS handshake read failed: ", ecode.message());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
size_t sz = 0;
|
||||||
|
uint8_t buf[256];
|
||||||
|
|
||||||
|
buf[0] = 0x05;
|
||||||
|
buf[1] = 0x01;
|
||||||
|
buf[2] = 0x00;
|
||||||
|
buf[3] = 0x03;
|
||||||
|
sz += 4;
|
||||||
|
size_t hostsz = url.host.size();
|
||||||
|
if(1 + 2 + hostsz + sz > sizeof(buf))
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: SOCKS handshake failed, hostname too big: ", url.host);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
buf[4] = (uint8_t) hostsz;
|
||||||
|
memcpy(buf+5, url.host.c_str(), hostsz);
|
||||||
|
sz += hostsz + 1;
|
||||||
|
htobe16buf(buf+sz, url.port);
|
||||||
|
sz += 2;
|
||||||
|
boost::asio::write(sock, boost::asio::buffer(buf, sz), boost::asio::transfer_all(), ecode);
|
||||||
|
if(ecode)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: SOCKS handshake failed writing: ", ecode.message());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
boost::asio::read(sock, boost::asio::buffer(buf, 10), ecode);
|
||||||
|
if(ecode)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: SOCKS handshake failed reading: ", ecode.message());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if(buf[1] != 0x00)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: SOCKS handshake bad reply code: ", std::to_string(buf[1]));
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
LogPrint(eLogDebug, "Reseed: got ", data.length(), "(", out.tellg(), ") bytes of data from ", url.host);
|
|
||||||
data = out.str();
|
|
||||||
}
|
}
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
LogPrint (eLogError, "Reseed: SSL handshake failed: ", ecode.message ());
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
LogPrint (eLogError, "Reseed: Couldn't connect to ", url.host, ": ", ecode.message ());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Reseed: Couldn't resolve address ", url.host, ": ", ecode.message ());
|
{
|
||||||
|
// direct connection
|
||||||
|
auto it = boost::asio::ip::tcp::resolver(service).resolve (
|
||||||
|
boost::asio::ip::tcp::resolver::query (url.host, std::to_string(url.port)), ecode);
|
||||||
|
if(!ecode)
|
||||||
|
s.lowest_layer().connect (*it, ecode);
|
||||||
|
}
|
||||||
|
if (!ecode)
|
||||||
|
{
|
||||||
|
SSL_set_tlsext_host_name(s.native_handle(), url.host.c_str ());
|
||||||
|
s.handshake (boost::asio::ssl::stream_base::client, ecode);
|
||||||
|
if (!ecode)
|
||||||
|
{
|
||||||
|
LogPrint (eLogDebug, "Reseed: Connected to ", url.host, ":", url.port);
|
||||||
|
i2p::http::HTTPReq req;
|
||||||
|
req.uri = url.to_string();
|
||||||
|
req.AddHeader("User-Agent", "Wget/1.11.4");
|
||||||
|
req.AddHeader("Connection", "close");
|
||||||
|
s.write_some (boost::asio::buffer (req.to_string()));
|
||||||
|
// read response
|
||||||
|
std::stringstream rs;
|
||||||
|
char recv_buf[1024]; size_t l = 0;
|
||||||
|
do {
|
||||||
|
l = s.read_some (boost::asio::buffer (recv_buf, sizeof(recv_buf)), ecode);
|
||||||
|
if (l) rs.write (recv_buf, l);
|
||||||
|
} while (!ecode && l);
|
||||||
|
// process response
|
||||||
|
std::string data = rs.str();
|
||||||
|
i2p::http::HTTPRes res;
|
||||||
|
int len = res.parse(data);
|
||||||
|
if (len <= 0) {
|
||||||
|
LogPrint(eLogWarning, "Reseed: incomplete/broken response from ", url.host);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (res.code != 200) {
|
||||||
|
LogPrint(eLogError, "Reseed: failed to reseed from ", url.host, ", http code ", res.code);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
data.erase(0, len); /* drop http headers from response */
|
||||||
|
LogPrint(eLogDebug, "Reseed: got ", data.length(), " bytes of data from ", url.host);
|
||||||
|
if (res.is_chunked()) {
|
||||||
|
std::stringstream in(data), out;
|
||||||
|
if (!i2p::http::MergeChunkedResponse(in, out)) {
|
||||||
|
LogPrint(eLogWarning, "Reseed: failed to merge chunked response from ", url.host);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
LogPrint(eLogDebug, "Reseed: got ", data.length(), "(", out.tellg(), ") bytes of data from ", url.host);
|
||||||
|
data = out.str();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Reseed: SSL handshake failed: ", ecode.message ());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Reseed: Couldn't connect to ", url.host, ": ", ecode.message ());
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,13 @@ namespace data
|
||||||
}
|
}
|
||||||
if (verifySignature)
|
if (verifySignature)
|
||||||
{
|
{
|
||||||
|
// reject RSA signatures
|
||||||
|
if (m_RouterIdentity->IsRSA ())
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "RouterInfo: RSA signature type is not allowed");
|
||||||
|
m_IsUnreachable = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
// verify signature
|
// verify signature
|
||||||
int l = m_BufferLen - m_RouterIdentity->GetSignatureLen ();
|
int l = m_BufferLen - m_RouterIdentity->GetSignatureLen ();
|
||||||
if (l < 0 || !m_RouterIdentity->Verify ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l))
|
if (l < 0 || !m_RouterIdentity->Verify ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l))
|
||||||
|
|
|
@ -62,6 +62,7 @@ namespace stream
|
||||||
m_RemoteLeaseSet (remote), m_ReceiveTimer (m_Service), m_ResendTimer (m_Service),
|
m_RemoteLeaseSet (remote), m_ReceiveTimer (m_Service), m_ResendTimer (m_Service),
|
||||||
m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (port),
|
m_AckSendTimer (m_Service), m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (port),
|
||||||
m_WindowSize (MIN_WINDOW_SIZE), m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO),
|
m_WindowSize (MIN_WINDOW_SIZE), m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO),
|
||||||
|
m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()),
|
||||||
m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0)
|
m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0)
|
||||||
{
|
{
|
||||||
RAND_bytes ((uint8_t *)&m_RecvStreamID, 4);
|
RAND_bytes ((uint8_t *)&m_RecvStreamID, 4);
|
||||||
|
@ -73,7 +74,8 @@ namespace stream
|
||||||
m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local),
|
m_Status (eStreamStatusNew), m_IsAckSendScheduled (false), m_LocalDestination (local),
|
||||||
m_ReceiveTimer (m_Service), m_ResendTimer (m_Service), m_AckSendTimer (m_Service),
|
m_ReceiveTimer (m_Service), m_ResendTimer (m_Service), m_AckSendTimer (m_Service),
|
||||||
m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (0), m_WindowSize (MIN_WINDOW_SIZE),
|
m_NumSentBytes (0), m_NumReceivedBytes (0), m_Port (0), m_WindowSize (MIN_WINDOW_SIZE),
|
||||||
m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO), m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0)
|
m_RTT (INITIAL_RTT), m_RTO (INITIAL_RTO), m_AckDelay (local.GetOwner ()->GetStreamingAckDelay ()),
|
||||||
|
m_LastWindowSizeIncreaseTime (0), m_NumResendAttempts (0)
|
||||||
{
|
{
|
||||||
RAND_bytes ((uint8_t *)&m_RecvStreamID, 4);
|
RAND_bytes ((uint8_t *)&m_RecvStreamID, 4);
|
||||||
}
|
}
|
||||||
|
@ -161,7 +163,7 @@ namespace stream
|
||||||
{
|
{
|
||||||
m_IsAckSendScheduled = true;
|
m_IsAckSendScheduled = true;
|
||||||
auto ackTimeout = m_RTT/10;
|
auto ackTimeout = m_RTT/10;
|
||||||
if (ackTimeout > ACK_SEND_TIMEOUT) ackTimeout = ACK_SEND_TIMEOUT;
|
if (ackTimeout > m_AckDelay) ackTimeout = m_AckDelay;
|
||||||
m_AckSendTimer.expires_from_now (boost::posix_time::milliseconds(ackTimeout));
|
m_AckSendTimer.expires_from_now (boost::posix_time::milliseconds(ackTimeout));
|
||||||
m_AckSendTimer.async_wait (std::bind (&Stream::HandleAckSendTimer,
|
m_AckSendTimer.async_wait (std::bind (&Stream::HandleAckSendTimer,
|
||||||
shared_from_this (), std::placeholders::_1));
|
shared_from_this (), std::placeholders::_1));
|
||||||
|
@ -199,7 +201,7 @@ namespace stream
|
||||||
{
|
{
|
||||||
// wait for SYN
|
// wait for SYN
|
||||||
m_IsAckSendScheduled = true;
|
m_IsAckSendScheduled = true;
|
||||||
m_AckSendTimer.expires_from_now (boost::posix_time::milliseconds(ACK_SEND_TIMEOUT));
|
m_AckSendTimer.expires_from_now (boost::posix_time::milliseconds(SYN_TIMEOUT));
|
||||||
m_AckSendTimer.async_wait (std::bind (&Stream::HandleAckSendTimer,
|
m_AckSendTimer.async_wait (std::bind (&Stream::HandleAckSendTimer,
|
||||||
shared_from_this (), std::placeholders::_1));
|
shared_from_this (), std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
@ -228,6 +230,13 @@ namespace stream
|
||||||
if (flags & PACKET_FLAG_FROM_INCLUDED)
|
if (flags & PACKET_FLAG_FROM_INCLUDED)
|
||||||
{
|
{
|
||||||
m_RemoteIdentity = std::make_shared<i2p::data::IdentityEx>(optionData, packet->GetOptionSize ());
|
m_RemoteIdentity = std::make_shared<i2p::data::IdentityEx>(optionData, packet->GetOptionSize ());
|
||||||
|
if (m_RemoteIdentity->IsRSA ())
|
||||||
|
{
|
||||||
|
LogPrint (eLogInfo, "Streaming: Incoming stream from RSA destination ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), " Discarded");
|
||||||
|
m_LocalDestination.DeletePacket (packet);
|
||||||
|
Terminate ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
optionData += m_RemoteIdentity->GetFullLen ();
|
optionData += m_RemoteIdentity->GetFullLen ();
|
||||||
if (!m_RemoteLeaseSet)
|
if (!m_RemoteLeaseSet)
|
||||||
LogPrint (eLogDebug, "Streaming: Incoming stream from ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), ", sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID);
|
LogPrint (eLogDebug, "Streaming: Incoming stream from ", m_RemoteIdentity->GetIdentHash ().ToBase64 (), ", sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID);
|
||||||
|
@ -244,16 +253,23 @@ namespace stream
|
||||||
{
|
{
|
||||||
uint8_t signature[256];
|
uint8_t signature[256];
|
||||||
auto signatureLen = m_RemoteIdentity->GetSignatureLen ();
|
auto signatureLen = m_RemoteIdentity->GetSignatureLen ();
|
||||||
memcpy (signature, optionData, signatureLen);
|
if(signatureLen <= sizeof(signature))
|
||||||
memset (const_cast<uint8_t *>(optionData), 0, signatureLen);
|
|
||||||
if (!m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature))
|
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Streaming: Signature verification failed, sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID);
|
memcpy (signature, optionData, signatureLen);
|
||||||
Close ();
|
memset (const_cast<uint8_t *>(optionData), 0, signatureLen);
|
||||||
flags |= PACKET_FLAG_CLOSE;
|
if (!m_RemoteIdentity->Verify (packet->GetBuffer (), packet->GetLength (), signature))
|
||||||
|
{
|
||||||
|
LogPrint (eLogError, "Streaming: Signature verification failed, sSID=", m_SendStreamID, ", rSID=", m_RecvStreamID);
|
||||||
|
Close ();
|
||||||
|
flags |= PACKET_FLAG_CLOSE;
|
||||||
|
}
|
||||||
|
memcpy (const_cast<uint8_t *>(optionData), signature, signatureLen);
|
||||||
|
optionData += signatureLen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Streaming: Signature too big, ", signatureLen, " bytes");
|
||||||
}
|
}
|
||||||
memcpy (const_cast<uint8_t *>(optionData), signature, signatureLen);
|
|
||||||
optionData += signatureLen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
packet->offset = packet->GetPayload () - packet->buf;
|
packet->offset = packet->GetPayload () - packet->buf;
|
||||||
|
@ -798,7 +814,7 @@ namespace stream
|
||||||
{
|
{
|
||||||
if (m_LastReceivedSequenceNumber < 0)
|
if (m_LastReceivedSequenceNumber < 0)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "Streaming: SYN has not been received after ", ACK_SEND_TIMEOUT, " milliseconds after follow on, terminate rSID=", m_RecvStreamID, ", sSID=", m_SendStreamID);
|
LogPrint (eLogWarning, "Streaming: SYN has not been received after ", SYN_TIMEOUT, " milliseconds after follow on, terminate rSID=", m_RecvStreamID, ", sSID=", m_SendStreamID);
|
||||||
m_Status = eStreamStatusReset;
|
m_Status = eStreamStatusReset;
|
||||||
Close ();
|
Close ();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -42,13 +42,13 @@ namespace stream
|
||||||
const size_t STREAMING_MTU = 1730;
|
const size_t STREAMING_MTU = 1730;
|
||||||
const size_t MAX_PACKET_SIZE = 4096;
|
const size_t MAX_PACKET_SIZE = 4096;
|
||||||
const size_t COMPRESSION_THRESHOLD_SIZE = 66;
|
const size_t COMPRESSION_THRESHOLD_SIZE = 66;
|
||||||
const int ACK_SEND_TIMEOUT = 200; // in milliseconds
|
|
||||||
const int MAX_NUM_RESEND_ATTEMPTS = 6;
|
const int MAX_NUM_RESEND_ATTEMPTS = 6;
|
||||||
const int WINDOW_SIZE = 6; // in messages
|
const int WINDOW_SIZE = 6; // in messages
|
||||||
const int MIN_WINDOW_SIZE = 1;
|
const int MIN_WINDOW_SIZE = 1;
|
||||||
const int MAX_WINDOW_SIZE = 128;
|
const int MAX_WINDOW_SIZE = 128;
|
||||||
const int INITIAL_RTT = 8000; // in milliseconds
|
const int INITIAL_RTT = 8000; // in milliseconds
|
||||||
const int INITIAL_RTO = 9000; // in milliseconds
|
const int INITIAL_RTO = 9000; // in milliseconds
|
||||||
|
const int SYN_TIMEOUT = 200; // how long we wait for SYN after follow-on, in milliseconds
|
||||||
const size_t MAX_PENDING_INCOMING_BACKLOG = 128;
|
const size_t MAX_PENDING_INCOMING_BACKLOG = 128;
|
||||||
const int PENDING_INCOMING_TIMEOUT = 10; // in seconds
|
const int PENDING_INCOMING_TIMEOUT = 10; // in seconds
|
||||||
const int MAX_RECEIVE_TIMEOUT = 30; // in seconds
|
const int MAX_RECEIVE_TIMEOUT = 30; // in seconds
|
||||||
|
@ -242,7 +242,7 @@ namespace stream
|
||||||
|
|
||||||
std::mutex m_SendBufferMutex;
|
std::mutex m_SendBufferMutex;
|
||||||
SendBufferQueue m_SendBuffer;
|
SendBufferQueue m_SendBuffer;
|
||||||
int m_WindowSize, m_RTT, m_RTO;
|
int m_WindowSize, m_RTT, m_RTO, m_AckDelay;
|
||||||
uint64_t m_LastWindowSizeIncreaseTime;
|
uint64_t m_LastWindowSizeIncreaseTime;
|
||||||
int m_NumResendAttempts;
|
int m_NumResendAttempts;
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c)
|
#define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c)
|
||||||
|
|
||||||
#define I2PD_VERSION_MAJOR 2
|
#define I2PD_VERSION_MAJOR 2
|
||||||
#define I2PD_VERSION_MINOR 15
|
#define I2PD_VERSION_MINOR 16
|
||||||
#define I2PD_VERSION_MICRO 0
|
#define I2PD_VERSION_MICRO 0
|
||||||
#define I2PD_VERSION_PATCH 0
|
#define I2PD_VERSION_PATCH 0
|
||||||
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
|
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
|
||||||
|
|
|
@ -71,12 +71,12 @@ namespace client
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_HttpProxy = new i2p::proxy::HTTPProxy(httpProxyAddr, httpProxyPort, httpOutProxyURL, localDestination);
|
m_HttpProxy = new i2p::proxy::HTTPProxy("HTTP Proxy", httpProxyAddr, httpProxyPort, httpOutProxyURL, localDestination);
|
||||||
m_HttpProxy->Start();
|
m_HttpProxy->Start();
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what());
|
LogPrint(eLogError, "Clients: Exception in HTTP Proxy: ", e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,8 @@ namespace client
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_SocksProxy = new i2p::proxy::SOCKSProxy(socksProxyAddr, socksProxyPort, socksOutProxy, socksOutProxyAddr, socksOutProxyPort, localDestination);
|
m_SocksProxy = new i2p::proxy::SOCKSProxy("SOCKS", socksProxyAddr, socksProxyPort,
|
||||||
|
socksOutProxy, socksOutProxyAddr, socksOutProxyPort, localDestination);
|
||||||
m_SocksProxy->Start();
|
m_SocksProxy->Start();
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
|
@ -283,6 +284,13 @@ namespace client
|
||||||
bool ClientContext::LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename,
|
bool ClientContext::LoadPrivateKeys (i2p::data::PrivateKeys& keys, const std::string& filename,
|
||||||
i2p::data::SigningKeyType sigType, i2p::data::CryptoKeyType cryptoType)
|
i2p::data::SigningKeyType sigType, i2p::data::CryptoKeyType cryptoType)
|
||||||
{
|
{
|
||||||
|
if (filename == "transient")
|
||||||
|
{
|
||||||
|
keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType, cryptoType);
|
||||||
|
LogPrint (eLogInfo, "Clients: New transient keys address ", m_AddressBook.ToAddress(keys.GetPublic ()->GetIdentHash ()), " created");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
std::string fullPath = i2p::fs::DataDirPath (filename);
|
std::string fullPath = i2p::fs::DataDirPath (filename);
|
||||||
std::ifstream s(fullPath, std::ifstream::binary);
|
std::ifstream s(fullPath, std::ifstream::binary);
|
||||||
|
@ -341,10 +349,11 @@ namespace client
|
||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ClientDestination> ClientContext::CreateNewLocalDestination (bool isPublic, i2p::data::SigningKeyType sigType,
|
std::shared_ptr<ClientDestination> ClientContext::CreateNewLocalDestination (bool isPublic,
|
||||||
const std::map<std::string, std::string> * params)
|
i2p::data::SigningKeyType sigType, i2p::data::CryptoKeyType cryptoType,
|
||||||
|
const std::map<std::string, std::string> * params)
|
||||||
{
|
{
|
||||||
i2p::data::PrivateKeys keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType);
|
i2p::data::PrivateKeys keys = i2p::data::PrivateKeys::CreateRandomKeys (sigType, cryptoType);
|
||||||
auto localDestination = std::make_shared<ClientDestination> (keys, isPublic, params);
|
auto localDestination = std::make_shared<ClientDestination> (keys, isPublic, params);
|
||||||
std::unique_lock<std::mutex> l(m_DestinationsMutex);
|
std::unique_lock<std::mutex> l(m_DestinationsMutex);
|
||||||
m_Destinations[localDestination->GetIdentHash ()] = localDestination;
|
m_Destinations[localDestination->GetIdentHash ()] = localDestination;
|
||||||
|
@ -422,6 +431,7 @@ namespace client
|
||||||
options[I2CP_PARAM_TAGS_TO_SEND] = GetI2CPOption (section, I2CP_PARAM_TAGS_TO_SEND, DEFAULT_TAGS_TO_SEND);
|
options[I2CP_PARAM_TAGS_TO_SEND] = GetI2CPOption (section, I2CP_PARAM_TAGS_TO_SEND, DEFAULT_TAGS_TO_SEND);
|
||||||
options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY);
|
options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MIN_TUNNEL_LATENCY, DEFAULT_MIN_TUNNEL_LATENCY);
|
||||||
options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY);
|
options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = GetI2CPOption(section, I2CP_PARAM_MAX_TUNNEL_LATENCY, DEFAULT_MAX_TUNNEL_LATENCY);
|
||||||
|
options[I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY] = GetI2CPOption(section, I2CP_PARAM_STREAMING_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientContext::ReadI2CPOptionsFromConfig (const std::string& prefix, std::map<std::string, std::string>& options) const
|
void ClientContext::ReadI2CPOptionsFromConfig (const std::string& prefix, std::map<std::string, std::string>& options) const
|
||||||
|
@ -438,7 +448,7 @@ namespace client
|
||||||
if (i2p::config::GetOption(prefix + I2CP_PARAM_MIN_TUNNEL_LATENCY, value))
|
if (i2p::config::GetOption(prefix + I2CP_PARAM_MIN_TUNNEL_LATENCY, value))
|
||||||
options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = value;
|
options[I2CP_PARAM_MIN_TUNNEL_LATENCY] = value;
|
||||||
if (i2p::config::GetOption(prefix + I2CP_PARAM_MAX_TUNNEL_LATENCY, value))
|
if (i2p::config::GetOption(prefix + I2CP_PARAM_MAX_TUNNEL_LATENCY, value))
|
||||||
options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = value;
|
options[I2CP_PARAM_MAX_TUNNEL_LATENCY] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientContext::ReadTunnels ()
|
void ClientContext::ReadTunnels ()
|
||||||
|
@ -533,14 +543,14 @@ namespace client
|
||||||
if (type == I2P_TUNNELS_SECTION_TYPE_SOCKS)
|
if (type == I2P_TUNNELS_SECTION_TYPE_SOCKS)
|
||||||
{
|
{
|
||||||
// socks proxy
|
// socks proxy
|
||||||
clientTunnel = new i2p::proxy::SOCKSProxy(address, port, false, "", destinationPort, localDestination);
|
clientTunnel = new i2p::proxy::SOCKSProxy(name, address, port, false, "", destinationPort, localDestination);
|
||||||
clientEndpoint = ((i2p::proxy::SOCKSProxy*)clientTunnel)->GetLocalEndpoint ();
|
clientEndpoint = ((i2p::proxy::SOCKSProxy*)clientTunnel)->GetLocalEndpoint ();
|
||||||
}
|
}
|
||||||
else if (type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY)
|
else if (type == I2P_TUNNELS_SECTION_TYPE_HTTPPROXY)
|
||||||
{
|
{
|
||||||
// http proxy
|
// http proxy
|
||||||
std::string outproxy = section.second.get("outproxy", "");
|
std::string outproxy = section.second.get("outproxy", "");
|
||||||
clientTunnel = new i2p::proxy::HTTPProxy(address, port, outproxy, localDestination);
|
clientTunnel = new i2p::proxy::HTTPProxy(name, address, port, outproxy, localDestination);
|
||||||
clientEndpoint = ((i2p::proxy::HTTPProxy*)clientTunnel)->GetLocalEndpoint ();
|
clientEndpoint = ((i2p::proxy::HTTPProxy*)clientTunnel)->GetLocalEndpoint ();
|
||||||
}
|
}
|
||||||
else if (type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS)
|
else if (type == I2P_TUNNELS_SECTION_TYPE_WEBSOCKS)
|
||||||
|
|
|
@ -64,10 +64,12 @@ namespace client
|
||||||
void ReloadConfig ();
|
void ReloadConfig ();
|
||||||
|
|
||||||
std::shared_ptr<ClientDestination> GetSharedLocalDestination () const { return m_SharedLocalDestination; };
|
std::shared_ptr<ClientDestination> GetSharedLocalDestination () const { return m_SharedLocalDestination; };
|
||||||
std::shared_ptr<ClientDestination> CreateNewLocalDestination (bool isPublic = false, i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1,
|
std::shared_ptr<ClientDestination> CreateNewLocalDestination (bool isPublic = false, // transient
|
||||||
const std::map<std::string, std::string> * params = nullptr); // transient
|
i2p::data::SigningKeyType sigType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1,
|
||||||
|
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL,
|
||||||
|
const std::map<std::string, std::string> * params = nullptr); // used by SAM only
|
||||||
std::shared_ptr<ClientDestination> CreateNewLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true,
|
std::shared_ptr<ClientDestination> CreateNewLocalDestination (const i2p::data::PrivateKeys& keys, bool isPublic = true,
|
||||||
const std::map<std::string, std::string> * params = nullptr);
|
const std::map<std::string, std::string> * params = nullptr);
|
||||||
std::shared_ptr<ClientDestination> CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys, const std::string & name, const std::map<std::string, std::string> * params = nullptr);
|
std::shared_ptr<ClientDestination> CreateNewMatchedTunnelDestination(const i2p::data::PrivateKeys &keys, const std::string & name, const std::map<std::string, std::string> * params = nullptr);
|
||||||
void DeleteLocalDestination (std::shared_ptr<ClientDestination> destination);
|
void DeleteLocalDestination (std::shared_ptr<ClientDestination> destination);
|
||||||
std::shared_ptr<ClientDestination> FindLocalDestination (const i2p::data::IdentHash& destination) const;
|
std::shared_ptr<ClientDestination> FindLocalDestination (const i2p::data::IdentHash& destination) const;
|
||||||
|
@ -76,6 +78,7 @@ namespace client
|
||||||
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL);
|
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL);
|
||||||
|
|
||||||
AddressBook& GetAddressBook () { return m_AddressBook; };
|
AddressBook& GetAddressBook () { return m_AddressBook; };
|
||||||
|
const BOBCommandChannel * GetBOBCommandChannel () const { return m_BOBCommandChannel; };
|
||||||
const SAMBridge * GetSAMBridge () const { return m_SamBridge; };
|
const SAMBridge * GetSAMBridge () const { return m_SamBridge; };
|
||||||
const I2CPServer * GetI2CPServer () const { return m_I2CPServer; };
|
const I2CPServer * GetI2CPServer () const { return m_I2CPServer; };
|
||||||
|
|
||||||
|
@ -87,8 +90,8 @@ namespace client
|
||||||
template<typename Section, typename Type>
|
template<typename Section, typename Type>
|
||||||
std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const;
|
std::string GetI2CPOption (const Section& section, const std::string& name, const Type& value) const;
|
||||||
template<typename Section>
|
template<typename Section>
|
||||||
void ReadI2CPOptions (const Section& section, std::map<std::string, std::string>& options) const;
|
void ReadI2CPOptions (const Section& section, std::map<std::string, std::string>& options) const; // for tunnels
|
||||||
void ReadI2CPOptionsFromConfig (const std::string& prefix, std::map<std::string, std::string>& options) const;
|
void ReadI2CPOptionsFromConfig (const std::string& prefix, std::map<std::string, std::string>& options) const; // for HTTP and SOCKS proxy
|
||||||
|
|
||||||
void CleanupUDP(const boost::system::error_code & ecode);
|
void CleanupUDP(const boost::system::error_code & ecode);
|
||||||
void ScheduleCleanupUDP();
|
void ScheduleCleanupUDP();
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace proxy {
|
||||||
void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered);
|
void HandleSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered);
|
||||||
void Terminate();
|
void Terminate();
|
||||||
void AsyncSockRead();
|
void AsyncSockRead();
|
||||||
bool ExtractAddressHelper(i2p::http::URL & url, std::string & b64);
|
bool ExtractAddressHelper(i2p::http::URL & url, std::string & b64, bool & confirm);
|
||||||
void SanitizeHTTPRequest(i2p::http::HTTPReq & req);
|
void SanitizeHTTPRequest(i2p::http::HTTPReq & req);
|
||||||
void SentHTTPFailed(const boost::system::error_code & ecode);
|
void SentHTTPFailed(const boost::system::error_code & ecode);
|
||||||
void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
|
void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
|
||||||
|
@ -182,13 +182,15 @@ namespace proxy {
|
||||||
std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
|
std::bind(&HTTPReqHandler::SentHTTPFailed, shared_from_this(), std::placeholders::_1));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HTTPReqHandler::ExtractAddressHelper(i2p::http::URL & url, std::string & b64)
|
bool HTTPReqHandler::ExtractAddressHelper(i2p::http::URL & url, std::string & b64, bool & confirm)
|
||||||
{
|
{
|
||||||
|
confirm = false;
|
||||||
const char *param = "i2paddresshelper=";
|
const char *param = "i2paddresshelper=";
|
||||||
std::size_t pos = url.query.find(param);
|
std::size_t pos = url.query.find(param);
|
||||||
std::size_t len = std::strlen(param);
|
std::size_t len = std::strlen(param);
|
||||||
std::map<std::string, std::string> params;
|
std::map<std::string, std::string> params;
|
||||||
|
|
||||||
|
|
||||||
if (pos == std::string::npos)
|
if (pos == std::string::npos)
|
||||||
return false; /* not found */
|
return false; /* not found */
|
||||||
if (!url.parse_query(params))
|
if (!url.parse_query(params))
|
||||||
|
@ -197,6 +199,8 @@ namespace proxy {
|
||||||
std::string value = params["i2paddresshelper"];
|
std::string value = params["i2paddresshelper"];
|
||||||
len += value.length();
|
len += value.length();
|
||||||
b64 = i2p::http::UrlDecode(value);
|
b64 = i2p::http::UrlDecode(value);
|
||||||
|
// if we need update exists, request formed with update param
|
||||||
|
if (params["update"] == "true") { len += std::strlen("&update=true"); confirm = true; }
|
||||||
url.query.replace(pos, len, "");
|
url.query.replace(pos, len, "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -242,24 +246,36 @@ namespace proxy {
|
||||||
/* parsing success, now let's look inside request */
|
/* parsing success, now let's look inside request */
|
||||||
LogPrint(eLogDebug, "HTTPProxy: requested: ", m_ClientRequest.uri);
|
LogPrint(eLogDebug, "HTTPProxy: requested: ", m_ClientRequest.uri);
|
||||||
m_RequestURL.parse(m_ClientRequest.uri);
|
m_RequestURL.parse(m_ClientRequest.uri);
|
||||||
|
bool m_Confirm;
|
||||||
|
|
||||||
if (ExtractAddressHelper(m_RequestURL, b64))
|
if (ExtractAddressHelper(m_RequestURL, b64, m_Confirm))
|
||||||
{
|
{
|
||||||
bool addresshelper; i2p::config::GetOption("httpproxy.addresshelper", addresshelper);
|
bool addresshelper; i2p::config::GetOption("httpproxy.addresshelper", addresshelper);
|
||||||
if (!addresshelper)
|
if (!addresshelper)
|
||||||
{
|
{
|
||||||
LogPrint(eLogWarning, "HTTPProxy: addresshelper disabled");
|
LogPrint(eLogWarning, "HTTPProxy: addresshelper request rejected");
|
||||||
GenericProxyError("Invalid request", "adddresshelper is not supported");
|
GenericProxyError("Invalid request", "addresshelper is not supported");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
i2p::client::context.GetAddressBook ().InsertAddress (m_RequestURL.host, b64);
|
if (!i2p::client::context.GetAddressBook ().FindAddress (m_RequestURL.host) || m_Confirm)
|
||||||
LogPrint (eLogInfo, "HTTPProxy: added b64 from addresshelper for ", m_RequestURL.host);
|
{
|
||||||
std::string full_url = m_RequestURL.to_string();
|
i2p::client::context.GetAddressBook ().InsertAddress (m_RequestURL.host, b64);
|
||||||
std::stringstream ss;
|
LogPrint (eLogInfo, "HTTPProxy: added b64 from addresshelper for ", m_RequestURL.host);
|
||||||
ss << "Host " << m_RequestURL.host << " added to router's addressbook from helper. "
|
std::string full_url = m_RequestURL.to_string();
|
||||||
<< "Click <a href=\"" << full_url << "\">here</a> to proceed.";
|
std::stringstream ss;
|
||||||
GenericProxyInfo("Addresshelper found", ss.str().c_str());
|
ss << "Host " << m_RequestURL.host << " added to router's addressbook from helper. "
|
||||||
return true; /* request processed */
|
<< "Click <a href=\"" << full_url << "\">here</a> to proceed.";
|
||||||
|
GenericProxyInfo("Addresshelper found", ss.str().c_str());
|
||||||
|
return true; /* request processed */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Host " << m_RequestURL.host << " <font color=red>already in router's addressbook</font>. "
|
||||||
|
<< "Click <a href=\"" << m_RequestURL.query << "?i2paddresshelper=" << b64 << "&update=true\">here</a> to update record.";
|
||||||
|
GenericProxyInfo("Addresshelper found", ss.str().c_str());
|
||||||
|
return true; /* request processed */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
std::string dest_host;
|
std::string dest_host;
|
||||||
uint16_t dest_port;
|
uint16_t dest_port;
|
||||||
|
@ -570,7 +586,7 @@ namespace proxy {
|
||||||
{
|
{
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info");
|
LogPrint (eLogError, "HTTPProxy: error when creating the stream, check the previous warnings for more info");
|
||||||
GenericProxyError("Host is down", "Can't create connection to requested host, it may be down");
|
GenericProxyError("Host is down", "Can't create connection to requested host, it may be down. Please try again later.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Kill())
|
if (Kill())
|
||||||
|
@ -582,9 +598,9 @@ namespace proxy {
|
||||||
Done (shared_from_this());
|
Done (shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
HTTPProxy::HTTPProxy(const std::string& address, int port, const std::string & outproxy, std::shared_ptr<i2p::client::ClientDestination> localDestination):
|
HTTPProxy::HTTPProxy(const std::string& name, const std::string& address, int port, const std::string & outproxy, std::shared_ptr<i2p::client::ClientDestination> localDestination):
|
||||||
TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()),
|
TCPIPAcceptor(address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()),
|
||||||
m_OutproxyUrl(outproxy)
|
m_Name (name), m_OutproxyUrl(outproxy)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ namespace proxy {
|
||||||
class HTTPProxy: public i2p::client::TCPIPAcceptor
|
class HTTPProxy: public i2p::client::TCPIPAcceptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HTTPProxy(const std::string& address, int port, const std::string & outproxy, std::shared_ptr<i2p::client::ClientDestination> localDestination);
|
HTTPProxy(const std::string& name, const std::string& address, int port, const std::string & outproxy, std::shared_ptr<i2p::client::ClientDestination> localDestination);
|
||||||
HTTPProxy(const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr) :
|
HTTPProxy(const std::string& name, const std::string& address, int port, std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr) :
|
||||||
HTTPProxy(address, port, "", localDestination) {} ;
|
HTTPProxy(name, address, port, "", localDestination) {} ;
|
||||||
~HTTPProxy() {};
|
~HTTPProxy() {};
|
||||||
|
|
||||||
std::string GetOutproxyURL() const { return m_OutproxyUrl; }
|
std::string GetOutproxyURL() const { return m_OutproxyUrl; }
|
||||||
|
@ -16,9 +16,10 @@ namespace proxy {
|
||||||
protected:
|
protected:
|
||||||
// Implements TCPIPAcceptor
|
// Implements TCPIPAcceptor
|
||||||
std::shared_ptr<i2p::client::I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
std::shared_ptr<i2p::client::I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||||
const char* GetName() { return "HTTP Proxy"; }
|
const char* GetName() { return m_Name.c_str (); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::string m_Name;
|
||||||
std::string m_OutproxyUrl;
|
std::string m_OutproxyUrl;
|
||||||
};
|
};
|
||||||
} // http
|
} // http
|
||||||
|
|
|
@ -489,11 +489,15 @@ namespace client
|
||||||
ExtractParams (buf, params);
|
ExtractParams (buf, params);
|
||||||
// extract signature type
|
// extract signature type
|
||||||
i2p::data::SigningKeyType signatureType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1;
|
i2p::data::SigningKeyType signatureType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1;
|
||||||
|
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL;
|
||||||
auto it = params.find (SAM_PARAM_SIGNATURE_TYPE);
|
auto it = params.find (SAM_PARAM_SIGNATURE_TYPE);
|
||||||
if (it != params.end ())
|
if (it != params.end ())
|
||||||
// TODO: extract string values
|
// TODO: extract string values
|
||||||
signatureType = std::stoi(it->second);
|
signatureType = std::stoi(it->second);
|
||||||
auto keys = i2p::data::PrivateKeys::CreateRandomKeys (signatureType);
|
it = params.find (SAM_PARAM_CRYPTO_TYPE);
|
||||||
|
if (it != params.end ())
|
||||||
|
cryptoType = std::stoi(it->second);
|
||||||
|
auto keys = i2p::data::PrivateKeys::CreateRandomKeys (signatureType, cryptoType);
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
size_t l = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_DEST_REPLY,
|
size_t l = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_DEST_REPLY,
|
||||||
keys.GetPublic ()->ToBase64 ().c_str (), keys.ToBase64 ().c_str ());
|
keys.GetPublic ()->ToBase64 ().c_str (), keys.ToBase64 ().c_str ());
|
||||||
|
@ -911,14 +915,18 @@ namespace client
|
||||||
{
|
{
|
||||||
// extract signature type
|
// extract signature type
|
||||||
i2p::data::SigningKeyType signatureType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1;
|
i2p::data::SigningKeyType signatureType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1;
|
||||||
|
i2p::data::CryptoKeyType cryptoType = i2p::data::CRYPTO_KEY_TYPE_ELGAMAL;
|
||||||
if (params)
|
if (params)
|
||||||
{
|
{
|
||||||
auto it = params->find (SAM_PARAM_SIGNATURE_TYPE);
|
auto it = params->find (SAM_PARAM_SIGNATURE_TYPE);
|
||||||
if (it != params->end ())
|
if (it != params->end ())
|
||||||
// TODO: extract string values
|
// TODO: extract string values
|
||||||
signatureType = std::stoi(it->second);
|
signatureType = std::stoi(it->second);
|
||||||
|
it = params->find (SAM_PARAM_CRYPTO_TYPE);
|
||||||
|
if (it != params->end ())
|
||||||
|
cryptoType = std::stoi(it->second);
|
||||||
}
|
}
|
||||||
localDestination = i2p::client::context.CreateNewLocalDestination (true, signatureType, params);
|
localDestination = i2p::client::context.CreateNewLocalDestination (true, signatureType, cryptoType, params);
|
||||||
}
|
}
|
||||||
if (localDestination)
|
if (localDestination)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,6 +53,7 @@ namespace client
|
||||||
const char SAM_PARAM_DESTINATION[] = "DESTINATION";
|
const char SAM_PARAM_DESTINATION[] = "DESTINATION";
|
||||||
const char SAM_PARAM_NAME[] = "NAME";
|
const char SAM_PARAM_NAME[] = "NAME";
|
||||||
const char SAM_PARAM_SIGNATURE_TYPE[] = "SIGNATURE_TYPE";
|
const char SAM_PARAM_SIGNATURE_TYPE[] = "SIGNATURE_TYPE";
|
||||||
|
const char SAM_PARAM_CRYPTO_TYPE[] = "CRYPTO_TYPE";
|
||||||
const char SAM_PARAM_SIZE[] = "SIZE";
|
const char SAM_PARAM_SIZE[] = "SIZE";
|
||||||
const char SAM_VALUE_TRANSIENT[] = "TRANSIENT";
|
const char SAM_VALUE_TRANSIENT[] = "TRANSIENT";
|
||||||
const char SAM_VALUE_STREAM[] = "STREAM";
|
const char SAM_VALUE_STREAM[] = "STREAM";
|
||||||
|
|
|
@ -768,9 +768,10 @@ namespace proxy
|
||||||
shared_from_this(), std::placeholders::_1, std::placeholders::_2));
|
shared_from_this(), std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
|
||||||
SOCKSServer::SOCKSServer(const std::string& address, int port, bool outEnable, const std::string& outAddress, uint16_t outPort,
|
SOCKSServer::SOCKSServer(const std::string& name, const std::string& address, int port,
|
||||||
std::shared_ptr<i2p::client::ClientDestination> localDestination) :
|
bool outEnable, const std::string& outAddress, uint16_t outPort,
|
||||||
TCPIPAcceptor (address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ())
|
std::shared_ptr<i2p::client::ClientDestination> localDestination) :
|
||||||
|
TCPIPAcceptor (address, port, localDestination ? localDestination : i2p::client::context.GetSharedLocalDestination ()), m_Name (name)
|
||||||
{
|
{
|
||||||
m_UseUpstreamProxy = false;
|
m_UseUpstreamProxy = false;
|
||||||
if (outAddress.length() > 0 && outEnable)
|
if (outAddress.length() > 0 && outEnable)
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace proxy
|
||||||
class SOCKSServer: public i2p::client::TCPIPAcceptor
|
class SOCKSServer: public i2p::client::TCPIPAcceptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SOCKSServer(const std::string& address, int port, bool outEnable, const std::string& outAddress, uint16_t outPort,
|
SOCKSServer(const std::string& name, const std::string& address, int port, bool outEnable, const std::string& outAddress, uint16_t outPort,
|
||||||
std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr);
|
std::shared_ptr<i2p::client::ClientDestination> localDestination = nullptr);
|
||||||
~SOCKSServer() {};
|
~SOCKSServer() {};
|
||||||
|
|
||||||
|
@ -23,9 +23,11 @@ namespace proxy
|
||||||
protected:
|
protected:
|
||||||
// Implements TCPIPAcceptor
|
// Implements TCPIPAcceptor
|
||||||
std::shared_ptr<i2p::client::I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
std::shared_ptr<i2p::client::I2PServiceHandler> CreateHandler(std::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||||
const char* GetName() { return "SOCKS"; }
|
const char* GetName() { return m_Name.c_str (); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
std::string m_Name;
|
||||||
std::string m_UpstreamProxyAddress;
|
std::string m_UpstreamProxyAddress;
|
||||||
uint16_t m_UpstreamProxyPort;
|
uint16_t m_UpstreamProxyPort;
|
||||||
bool m_UseUpstreamProxy;
|
bool m_UseUpstreamProxy;
|
||||||
|
|
4
qt/i2pd_qt/.gitignore
vendored
4
qt/i2pd_qt/.gitignore
vendored
|
@ -3,5 +3,7 @@ moc_*
|
||||||
ui_*
|
ui_*
|
||||||
qrc_*
|
qrc_*
|
||||||
i2pd_qt
|
i2pd_qt
|
||||||
Makefile
|
Makefile*
|
||||||
*.stash
|
*.stash
|
||||||
|
object_script.*
|
||||||
|
i2pd_qt_plugin_import.cpp
|
|
@ -70,13 +70,6 @@ public:
|
||||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_TC26_A_512_GOSTR3411_512", 0), SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512); //10
|
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_TC26_A_512_GOSTR3411_512", 0), SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512); //10
|
||||||
if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
|
if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
|
||||||
++index;
|
++index;
|
||||||
// TODO: remove later
|
|
||||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST", 0), SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST); //65281
|
|
||||||
if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
|
|
||||||
++index;
|
|
||||||
addItem(signatureTypeCombobox, QApplication::translate("signatureTypeCombobox", "GOSTR3410_TC26_A_512_GOSTR3411_512_TEST", 0), SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512_TEST); //65282
|
|
||||||
if(selectedSigType==SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512_TEST){signatureTypeCombobox->setCurrentIndex(index);foundSelected=true;}
|
|
||||||
++index;
|
|
||||||
if(!foundSelected){
|
if(!foundSelected){
|
||||||
addItem(signatureTypeCombobox, QString::number(selectedSigType), selectedSigType); //unknown sigtype
|
addItem(signatureTypeCombobox, QString::number(selectedSigType), selectedSigType); //unknown sigtype
|
||||||
signatureTypeCombobox->setCurrentIndex(index);
|
signatureTypeCombobox->setCurrentIndex(index);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.15.0" android:versionCode="2" android:installLocation="auto">
|
<manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.16.0" android:versionCode="2" android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23"/>
|
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23"/>
|
||||||
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
|
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
|
||||||
<!-- <application android:hardwareAccelerated="true" -->
|
<!-- <application android:hardwareAccelerated="true" -->
|
||||||
|
|
|
@ -155,8 +155,9 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
|
||||||
uiSettings->logDestinationComboBox->clear();
|
uiSettings->logDestinationComboBox->clear();
|
||||||
uiSettings->logDestinationComboBox->insertItems(0, QStringList()
|
uiSettings->logDestinationComboBox->insertItems(0, QStringList()
|
||||||
<< QApplication::translate("MainWindow", "stdout", 0)
|
<< QApplication::translate("MainWindow", "syslog", 0)
|
||||||
<< QApplication::translate("MainWindow", "file", 0)
|
<< QApplication::translate("MainWindow", "stdout", 0)
|
||||||
|
<< QApplication::translate("MainWindow", "file", 0)
|
||||||
);
|
);
|
||||||
initLogDestinationCombobox( OPTION("","log",[]{return "";}), uiSettings->logDestinationComboBox);
|
initLogDestinationCombobox( OPTION("","log",[]{return "";}), uiSettings->logDestinationComboBox);
|
||||||
|
|
||||||
|
@ -302,9 +303,9 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::logDestinationComboBoxValueChanged(const QString & text) {
|
void MainWindow::logDestinationComboBoxValueChanged(const QString & text) {
|
||||||
bool stdout = text==QString("stdout");
|
bool fileEnabled = text==QString("file");
|
||||||
uiSettings->logFileLineEdit->setEnabled(!stdout);
|
uiSettings->logFileLineEdit->setEnabled(fileEnabled);
|
||||||
uiSettings->logFileBrowsePushButton->setEnabled(!stdout);
|
uiSettings->logFileBrowsePushButton->setEnabled(fileEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -224,7 +224,6 @@ public:
|
||||||
}
|
}
|
||||||
virtual void saveToStringStream(std::stringstream& out){
|
virtual void saveToStringStream(std::stringstream& out){
|
||||||
std::string logDest = comboBox->currentText().toStdString();
|
std::string logDest = comboBox->currentText().toStdString();
|
||||||
if(logDest==std::string("stdout"))logDest="";
|
|
||||||
optionValue=logDest;
|
optionValue=logDest;
|
||||||
MainWindowItem::saveToStringStream(out);
|
MainWindowItem::saveToStringStream(out);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue