Merge remote-tracking branch 'purple/openssl'

pull/709/head
Jeff Becker 8 years ago
commit 8a545b98ec

@ -1,6 +1,10 @@
# 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.10.1] - 2016-11-07
### Fixed
- Fixed some performance issues for Windows and Android
## [2.10.0] - 2016-10-17 ## [2.10.0] - 2016-10-17
### Added ### Added
- Datagram i2p tunnels - Datagram i2p tunnels

@ -166,7 +166,6 @@ namespace config {
"https://netdb.i2p2.no/," "https://netdb.i2p2.no/,"
"https://us.reseed.i2p2.no:444/," "https://us.reseed.i2p2.no:444/,"
"https://uk.reseed.i2p2.no:444/," "https://uk.reseed.i2p2.no:444/,"
"https://i2p.manas.ca:8443/,"
"https://i2p-0.manas.ca:8443/," "https://i2p-0.manas.ca:8443/,"
"https://reseed.i2p.vzaws.com:8443/," "https://reseed.i2p.vzaws.com:8443/,"
"https://download.xxlspeed.com/," "https://download.xxlspeed.com/,"

@ -224,7 +224,7 @@ namespace crypto
// DH // DH
DHKeys::DHKeys (): m_IsUpdated (true) 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));
@ -236,7 +236,7 @@ namespace crypto
DH_free (m_DH); DH_free (m_DH);
} }
void DHKeys::GenerateKeys (uint8_t * priv, uint8_t * pub) 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
@ -261,20 +261,7 @@ namespace crypto
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);
} }
if (priv) bn2buf (priv_key, priv, 256); bn2buf (pub_key, m_PublicKey, 256);
if (pub) bn2buf (pub_key, pub, 256);
m_IsUpdated = true;
}
const uint8_t * DHKeys::GetPublicKey ()
{
if (m_IsUpdated)
{
bn2buf (m_DH->pub_key, m_PublicKey, 256);
BN_free (m_DH->pub_key); m_DH->pub_key = NULL;
m_IsUpdated= false;
}
return m_PublicKey;
} }
void DHKeys::Agree (const uint8_t * pub, uint8_t * shared) void DHKeys::Agree (const uint8_t * pub, uint8_t * shared)

@ -10,6 +10,7 @@
#include <openssl/ecdsa.h> #include <openssl/ecdsa.h>
#include <openssl/rsa.h> #include <openssl/rsa.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <openssl/evp.h>
#include <openssl/rand.h> #include <openssl/rand.h>
#include "Base.h" #include "Base.h"
@ -35,15 +36,14 @@ namespace crypto
DHKeys (); DHKeys ();
~DHKeys (); ~DHKeys ();
void GenerateKeys (uint8_t * priv = nullptr, uint8_t * pub = nullptr); void GenerateKeys ();
const uint8_t * GetPublicKey (); const uint8_t * GetPublicKey () const { return m_PublicKey; };
void Agree (const uint8_t * pub, uint8_t * shared); void Agree (const uint8_t * pub, uint8_t * shared);
private: private:
DH * m_DH; DH * m_DH;
uint8_t m_PublicKey[256]; uint8_t m_PublicKey[256];
bool m_IsUpdated;
}; };
// ElGamal // ElGamal
@ -281,6 +281,8 @@ namespace crypto
void InitCrypto (bool precomputation); void InitCrypto (bool precomputation);
void TerminateCrypto (); void TerminateCrypto ();
}
}
// take care about openssl version // take care about openssl version
#include <openssl/opensslv.h> #include <openssl/opensslv.h>
@ -318,9 +320,10 @@ inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
inline void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) inline void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
{ *pub_key = dh->pub_key; *priv_key = dh->priv_key; } { *pub_key = dh->pub_key; *priv_key = dh->priv_key; }
inline int EVP_PKEY_base_id(const EVP_PKEY *pkey)
{ return EVP_PKEY_type(pkey->type); }
inline RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
{ return pkey->pkey.rsa; }
#endif #endif
}
}
#endif #endif

@ -143,6 +143,7 @@ namespace client
// for HTTP only // for HTTP only
int GetNumRemoteLeaseSets () const { return m_RemoteLeaseSets.size (); }; int GetNumRemoteLeaseSets () const { return m_RemoteLeaseSets.size (); };
const decltype(m_RemoteLeaseSets)& GetLeaseSets () const { return m_RemoteLeaseSets; };
}; };
class ClientDestination: public LeaseSetDestination class ClientDestination: public LeaseSetDestination

@ -40,7 +40,7 @@ namespace data
if (family) family[0] = 0; if (family) family[0] = 0;
} }
auto pkey = X509_get_pubkey (cert); auto pkey = X509_get_pubkey (cert);
int keyType = EVP_PKEY_type(pkey->type); int keyType = EVP_PKEY_base_id (pkey);
switch (keyType) switch (keyType)
{ {
case EVP_PKEY_DSA: case EVP_PKEY_DSA:

@ -225,7 +225,7 @@ namespace http {
else else
s << numKBytesSent / 1024 / 1024 << " GiB"; s << numKBytesSent / 1024 / 1024 << " GiB";
s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " KiB/s)<br>\r\n"; s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " KiB/s)<br>\r\n";
s << "<b>Data path:</b> " << i2p::fs::GetDataDir() << "<br>\r\n<br>\r\n"; s << "<b>Data path:</b> " << i2p::fs::GetDataDir() << "<br>\r\n";
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'>Hidden content. Press on text to see.</label>\r\n<input type='checkbox' id='slide1'/>\r\n<p class='content'>\r\n";
s << "<b>Router Ident:</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n"; s << "<b>Router Ident:</b> " << i2p::context.GetRouterInfo().GetIdentHashBase64() << "<br>\r\n";
s << "<b>Router Family:</b> " << i2p::context.GetRouterInfo().GetProperty("family") << "<br>\r\n"; s << "<b>Router Family:</b> " << i2p::context.GetRouterInfo().GetProperty("family") << "<br>\r\n";
@ -253,7 +253,7 @@ namespace http {
s << address->host.to_string() << ":" << address->port << "<br>\r\n"; s << address->host.to_string() << ":" << address->port << "<br>\r\n";
} }
s << "</p>\r\n</div>\r\n"; s << "</p>\r\n</div>\r\n";
s << "<br>\r\n<b>Routers:</b> " << i2p::data::netdb.GetNumRouters () << " "; s << "<b>Routers:</b> " << i2p::data::netdb.GetNumRouters () << " ";
s << "<b>Floodfills:</b> " << i2p::data::netdb.GetNumFloodfills () << " "; s << "<b>Floodfills:</b> " << i2p::data::netdb.GetNumFloodfills () << " ";
s << "<b>LeaseSets:</b> " << i2p::data::netdb.GetNumLeaseSets () << "<br>\r\n"; s << "<b>LeaseSets:</b> " << i2p::data::netdb.GetNumLeaseSets () << "<br>\r\n";
@ -287,6 +287,13 @@ 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"; s << "<b>LeaseSets:</b> <i>" << dest->GetNumRemoteLeaseSets () << "</i><br>\r\n";
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";
for(auto& it: dest->GetLeaseSets ())
s << it.second->GetIdentHash ().ToBase32 () << "<br>\r\n";
s << "</p>\r\n</div>\r\n";
}
auto pool = dest->GetTunnelPool (); auto pool = dest->GetTunnelPool ();
if (pool) if (pool)
{ {

@ -488,7 +488,7 @@ namespace data
switch (m_Public->GetSigningKeyType ()) switch (m_Public->GetSigningKeyType ())
{ {
case SIGNING_KEY_TYPE_DSA_SHA1: case SIGNING_KEY_TYPE_DSA_SHA1:
m_Signer.reset (new i2p::crypto::DSASigner (m_SigningPrivateKey)); m_Signer.reset (new i2p::crypto::DSASigner (m_SigningPrivateKey, m_Public->GetStandardIdentity ().signingKey));
break; break;
case SIGNING_KEY_TYPE_ECDSA_SHA256_P256: case SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
m_Signer.reset (new i2p::crypto::ECDSAP256Signer (m_SigningPrivateKey)); m_Signer.reset (new i2p::crypto::ECDSAP256Signer (m_SigningPrivateKey));

@ -100,8 +100,8 @@ namespace data
/** visit N random router that match using filter, then visit them with a visitor, return number of RouterInfos that were visited */ /** visit N random router that match using filter, then visit them with a visitor, return number of RouterInfos that were visited */
size_t VisitRandomRouterInfos(RouterInfoFilter f, RouterInfoVisitor v, size_t n); size_t VisitRandomRouterInfos(RouterInfoFilter f, RouterInfoVisitor v, size_t n);
void ClearRouterInfos () { m_RouterInfos.clear (); };
private: private:
void Load (); void Load ();

@ -305,6 +305,34 @@ namespace data
if (end - contentPos >= contentLength) if (end - contentPos >= contentLength)
break; // we are beyond contentLength break; // we are beyond contentLength
} }
if (numFiles) // check if routers are not outdated
{
auto ts = i2p::util::GetMillisecondsSinceEpoch ();
int numOutdated = 0;
i2p::data::netdb.VisitRouterInfos (
[&numOutdated, ts](std::shared_ptr<const RouterInfo> r)
{
if (r && ts > r->GetTimestamp () + 10*i2p::data::NETDB_MAX_EXPIRATION_TIMEOUT*1000LL) // 270 hours
{
LogPrint (eLogError, "Reseed: router ", r->GetIdentHash().ToBase64 (), " is outdated by ", (ts - r->GetTimestamp ())/1000LL/3600LL, " hours");
numOutdated++;
}
});
if (numOutdated > numFiles/2) // more than half
{
LogPrint (eLogError, "Reseed: mammoth's shit\n"
" *_____*\n"
" *_*****_*\n"
" *_(O)_(O)_*\n"
" **____V____**\n"
" **_________**\n"
" **_________**\n"
" *_________*\n"
" ***___***");
i2p::data::netdb.ClearRouterInfos ();
numFiles = 0;
}
}
return numFiles; return numFiles;
} }
@ -350,9 +378,11 @@ namespace data
if (terminator) terminator[0] = 0; if (terminator) terminator[0] = 0;
} }
// extract RSA key (we need n only, e = 65537) // extract RSA key (we need n only, e = 65537)
RSA * key = X509_get_pubkey (cert)->pkey.rsa; RSA * key = EVP_PKEY_get0_RSA (X509_get_pubkey (cert));
const BIGNUM * n, * e, * d;
RSA_get0_key(key, &n, &e, &d);
PublicKey value; PublicKey value;
i2p::crypto::bn2buf (key->n, value, 512); i2p::crypto::bn2buf (n, value, 512);
if (cn) if (cn)
m_SigningKeys[cn] = value; m_SigningKeys[cn] = value;
else else

@ -77,10 +77,11 @@ namespace crypto
{ {
public: public:
DSASigner (const uint8_t * signingPrivateKey) DSASigner (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey)
// openssl 1.1 always requires DSA public key even for signing
{ {
m_PrivateKey = CreateDSA (); m_PrivateKey = CreateDSA ();
DSA_set0_key (m_PrivateKey, NULL, BN_bin2bn (signingPrivateKey, DSA_PRIVATE_KEY_LENGTH, NULL)); DSA_set0_key (m_PrivateKey, BN_bin2bn (signingPublicKey, DSA_PUBLIC_KEY_LENGTH, NULL), BN_bin2bn (signingPrivateKey, DSA_PRIVATE_KEY_LENGTH, NULL));
} }
~DSASigner () ~DSASigner ()

@ -108,7 +108,8 @@ namespace transport
Transports transports; Transports transports;
Transports::Transports (): Transports::Transports ():
m_IsOnline (true), m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service), m_PeerCleanupTimer (m_Service), m_IsOnline (true), m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service),
m_PeerCleanupTimer (m_Service), m_PeerTestTimer (m_Service),
m_NTCPServer (nullptr), m_SSUServer (nullptr), m_DHKeysPairSupplier (5), // 5 pre-generated keys m_NTCPServer (nullptr), m_SSUServer (nullptr), m_DHKeysPairSupplier (5), // 5 pre-generated keys
m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_InBandwidth (0), m_OutBandwidth (0), m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_InBandwidth (0), m_OutBandwidth (0),
m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), m_LastBandwidthUpdateTime (0) m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), m_LastBandwidthUpdateTime (0)
@ -168,11 +169,14 @@ namespace transport
} }
m_PeerCleanupTimer.expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT)); m_PeerCleanupTimer.expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT));
m_PeerCleanupTimer.async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1)); m_PeerCleanupTimer.async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1));
m_PeerTestTimer.expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL));
m_PeerTestTimer.async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1));
} }
void Transports::Stop () void Transports::Stop ()
{ {
m_PeerCleanupTimer.cancel (); m_PeerCleanupTimer.cancel ();
m_PeerTestTimer.cancel ();
m_Peers.clear (); m_Peers.clear ();
if (m_SSUServer) if (m_SSUServer)
{ {
@ -546,8 +550,7 @@ namespace transport
{ {
if (RoutesRestricted()) return; if (RoutesRestricted()) return;
if (m_SSUServer) if (m_SSUServer)
{ {
bool statusChanged = false; bool statusChanged = false;
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
@ -688,6 +691,16 @@ namespace transport
} }
} }
void Transports::HandlePeerTestTimer (const boost::system::error_code& ecode)
{
if (ecode != boost::asio::error::operation_aborted)
{
PeerTest ();
m_PeerTestTimer.expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL));
m_PeerTestTimer.async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1));
}
}
std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRandomPeer () const std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRandomPeer () const
{ {
if (m_Peers.empty ()) return nullptr; if (m_Peers.empty ()) return nullptr;

@ -66,6 +66,7 @@ namespace transport
}; };
const size_t SESSION_CREATION_TIMEOUT = 10; // in seconds const size_t SESSION_CREATION_TIMEOUT = 10; // in seconds
const int PEER_TEST_INTERVAL = 71; // in minutes
const int MAX_NUM_DELAYED_MESSAGES = 50; const int MAX_NUM_DELAYED_MESSAGES = 50;
class Transports class Transports
{ {
@ -127,7 +128,8 @@ namespace transport
void PostCloseSession (std::shared_ptr<const i2p::data::RouterInfo> router); void PostCloseSession (std::shared_ptr<const i2p::data::RouterInfo> router);
bool ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer); bool ConnectToPeer (const i2p::data::IdentHash& ident, Peer& peer);
void HandlePeerCleanupTimer (const boost::system::error_code& ecode); void HandlePeerCleanupTimer (const boost::system::error_code& ecode);
void HandlePeerTestTimer (const boost::system::error_code& ecode);
void NTCPResolve (const std::string& addr, const i2p::data::IdentHash& ident); void NTCPResolve (const std::string& addr, const i2p::data::IdentHash& ident);
void HandleNTCPResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it, void HandleNTCPResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::iterator it,
i2p::data::IdentHash ident, std::shared_ptr<boost::asio::ip::tcp::resolver> resolver); i2p::data::IdentHash ident, std::shared_ptr<boost::asio::ip::tcp::resolver> resolver);
@ -144,7 +146,7 @@ namespace transport
std::thread * m_Thread; std::thread * m_Thread;
boost::asio::io_service m_Service; boost::asio::io_service m_Service;
boost::asio::io_service::work m_Work; boost::asio::io_service::work m_Work;
boost::asio::deadline_timer m_PeerCleanupTimer; boost::asio::deadline_timer m_PeerCleanupTimer, m_PeerTestTimer;
NTCPServer * m_NTCPServer; NTCPServer * m_NTCPServer;
SSUServer * m_SSUServer; SSUServer * m_SSUServer;

6
debian/changelog vendored

@ -1,3 +1,9 @@
i2pd (2.10.1-1) unstable; urgency=low
* updated to version 2.10.1
-- orignal <orignal@i2pmail.org> Mon, 7 Nov 2016 14:18:30 +0000
i2pd (2.10.0-1) unstable; urgency=low i2pd (2.10.0-1) unstable; urgency=low
* updated to version 2.10.0/0.9.27 * updated to version 2.10.0/0.9.27

@ -30,16 +30,16 @@ Where $ARCH is `i686` or `x86_64` (matching your system).
- Open MSYS2 Shell (from Start menu). - Open MSYS2 Shell (from Start menu).
- Install all prerequisites and download i2pd source: - Install all prerequisites and download i2pd source:
export ARCH='i686' # or 'x86_64' export ARCH='i686' # or 'x86_64'
export MINGW='mingw32' # or 'mingw64' export MINGW='mingw32' # or 'mingw64'
pacman -S mingw-w64-$ARCH-boost mingw-w64-$ARCH-openssl mingw-w64-$ARCH-gcc git make pacman -S mingw-w64-$ARCH-boost mingw-w64-$ARCH-openssl mingw-w64-$ARCH-gcc git make
mkdir -p /c/dev/i2pd mkdir -p /c/dev/i2pd
cd /c/dev/i2pd cd /c/dev/i2pd
git clone https://github.com/PurpleI2P/i2pd.git git clone https://github.com/PurpleI2P/i2pd.git
cd i2pd cd i2pd
# we need compiler on PATH which is usually heavily cluttered on Windows # we need compiler on PATH which is usually heavily cluttered on Windows
export PATH=/$MINGW/bin:/usr/bin export PATH=/$MINGW/bin:/usr/bin
make make
### Caveats ### Caveats

@ -23,12 +23,12 @@ To display all available options:
i2pd can be controlled with signals. Process ID by default is written to file `~/.i2pd/i2pd.pid` or `/var/run/i2pd/i2pd.pid`. i2pd can be controlled with signals. Process ID by default is written to file `~/.i2pd/i2pd.pid` or `/var/run/i2pd/i2pd.pid`.
You can use `kill` utility to send signals like this: You can use `kill` utility to send signals like this:
kill -TERM $( cat /var/run/i2pd/i2pd.pid ) kill -INT $( cat /var/run/i2pd/i2pd.pid )
i2pd supports the following signals: i2pd supports the following signals:
TERM - Graceful shutdown. i2pd will wait for 10 minutes and stop. Send second TERM signal to shutdown i2pd immediately. * INT - Graceful shutdown. i2pd will wait for 10 minutes and stop. Send second INT signal to shutdown i2pd immediately.
HUP - Reload configuration files. * HUP - Reload configuration files.
### systemd unit ### systemd unit
@ -48,7 +48,7 @@ Enable/disable i2pd to be started on bootup:
## Configuring i2pd ## Configuring i2pd
See [configuration page](i2pd.readthedocs.io/page/configuration.html). See [configuration documentation](/page/configuration.html).
## Browsing and hosting websites ## Browsing and hosting websites

Loading…
Cancel
Save