Merge pull request #703 from PurpleI2P/openssl

recent changes
pull/63/merge
orignal 8 years ago committed by GitHub
commit 7419f992e7

@ -227,10 +227,8 @@ namespace crypto
DHKeys::DHKeys (): m_IsUpdated (true)
{
m_DH = DH_new ();
m_DH->p = BN_dup (elgp);
m_DH->g = BN_dup (elgg);
m_DH->priv_key = NULL;
m_DH->pub_key = NULL;
DH_set0_pqg (m_DH, BN_dup (elgp), NULL, BN_dup (elgg));
DH_set0_key (m_DH, NULL, NULL);
}
DHKeys::~DHKeys ()
@ -240,27 +238,31 @@ namespace crypto
void DHKeys::GenerateKeys (uint8_t * priv, uint8_t * pub)
{
if (m_DH->priv_key) { BN_free (m_DH->priv_key); m_DH->priv_key = NULL; };
if (m_DH->pub_key) { BN_free (m_DH->pub_key); m_DH->pub_key = NULL; };
BIGNUM * priv_key = NULL, * pub_key = NULL;
#if !defined(__x86_64__) // use short exponent for non x64
m_DH->priv_key = BN_new ();
BN_rand (m_DH->priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1);
priv_key = BN_new ();
BN_rand (priv_key, ELGAMAL_SHORT_EXPONENT_NUM_BITS, 0, 1);
#endif
if (g_ElggTable)
{
#if defined(__x86_64__)
m_DH->priv_key = BN_new ();
BN_rand (m_DH->priv_key, ELGAMAL_FULL_EXPONENT_NUM_BITS, 0, 1);
priv_key = BN_new ();
BN_rand (priv_key, ELGAMAL_FULL_EXPONENT_NUM_BITS, 0, 1);
#endif
auto ctx = BN_CTX_new ();
m_DH->pub_key = ElggPow (m_DH->priv_key, g_ElggTable, ctx);
pub_key = ElggPow (priv_key, g_ElggTable, ctx);
DH_set0_key (m_DH, pub_key, priv_key);
BN_CTX_free (ctx);
}
else
{
DH_set0_key (m_DH, NULL, priv_key);
DH_generate_key (m_DH);
DH_get0_key (m_DH, (const BIGNUM **)&pub_key, (const BIGNUM **)&priv_key);
}
if (priv) bn2buf (m_DH->priv_key, priv, 256);
if (pub) bn2buf (m_DH->pub_key, pub, 256);
if (priv) bn2buf (priv_key, priv, 256);
if (pub) bn2buf (pub_key, pub, 256);
m_IsUpdated = true;
}

@ -301,6 +301,17 @@ inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
inline void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
{ *n = r->n; *e = r->e; *d = r->d; }
inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
{ dh->p = p; dh->q = q; dh->g = g; return 1; }
inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
{
if (dh->pub_key) BN_free (dh->pub_key);
if (dh->priv_key) BN_free (dh->priv_key);
dh->pub_key = pub_key; dh->priv_key = priv_key; return 1;
}
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; }
#endif
}

@ -277,19 +277,20 @@ namespace client
LogPrint (eLogInfo, "Destination: Reply token is ignored for DatabaseStore");
offset += 36;
}
i2p::data::IdentHash key (buf + DATABASE_STORE_KEY_OFFSET);
std::shared_ptr<i2p::data::LeaseSet> leaseSet;
if (buf[DATABASE_STORE_TYPE_OFFSET] == 1) // LeaseSet
{
LogPrint (eLogDebug, "Destination: Remote LeaseSet");
std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
auto it = m_RemoteLeaseSets.find (buf + DATABASE_STORE_KEY_OFFSET);
auto it = m_RemoteLeaseSets.find (key);
if (it != m_RemoteLeaseSets.end ())
{
leaseSet = it->second;
if (leaseSet->IsNewer (buf + offset, len - offset))
{
leaseSet->Update (buf + offset, len - offset);
if (leaseSet->IsValid ())
if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key)
LogPrint (eLogDebug, "Destination: Remote LeaseSet updated");
else
{
@ -304,12 +305,12 @@ namespace client
else
{
leaseSet = std::make_shared<i2p::data::LeaseSet> (buf + offset, len - offset);
if (leaseSet->IsValid ())
if (leaseSet->IsValid () && leaseSet->GetIdentHash () == key)
{
if (leaseSet->GetIdentHash () != GetIdentHash ())
{
LogPrint (eLogDebug, "Destination: New remote LeaseSet added");
m_RemoteLeaseSets[buf + DATABASE_STORE_KEY_OFFSET] = leaseSet;
m_RemoteLeaseSets[key] = leaseSet;
}
else
LogPrint (eLogDebug, "Destination: Own remote LeaseSet dropped");
@ -324,7 +325,7 @@ namespace client
else
LogPrint (eLogError, "Destination: Unexpected client's DatabaseStore type ", buf[DATABASE_STORE_TYPE_OFFSET], ", dropped");
auto it1 = m_LeaseSetRequests.find (buf + DATABASE_STORE_KEY_OFFSET);
auto it1 = m_LeaseSetRequests.find (key);
if (it1 != m_LeaseSetRequests.end ())
{
it1->second->requestTimeoutTimer.cancel ();

@ -94,7 +94,7 @@ strip: $(I2PD) $(SHLIB_CLIENT) $(SHLIB)
strip $^
LATEST_TAG=$(shell git describe --tags --abbrev=0 openssl)
BRANCH=$(shell git branch --no-color | cut -c 3-)
BRANCH=$(shell git rev-parse --abbrev-ref HEAD)
dist:
git archive --format=tar.gz -9 --worktree-attributes \
--prefix=i2pd_$(LATEST_TAG)/ $(LATEST_TAG) -o i2pd_$(LATEST_TAG).tar.gz

@ -1111,7 +1111,7 @@ namespace transport
RAND_bytes ((uint8_t *)&nonce, 4);
if (!nonce) nonce = 1;
m_IsPeerTest = false;
m_Server.NewPeerTest (nonce, ePeerTestParticipantAlice1);
m_Server.NewPeerTest (nonce, ePeerTestParticipantAlice1, shared_from_this ());
SendPeerTest (nonce, boost::asio::ip::address(), 0, address->key, false, false); // address and port always zero for Alice
}

@ -48,11 +48,22 @@ namespace transport
{
while (m_IsRunning)
{
int num;
while ((num = m_QueueSize - m_Queue.size ()) > 0)
int num, total = 0;
while ((num = m_QueueSize - (int)m_Queue.size ()) > 0 && total < 20)
{
CreateDHKeysPairs (num);
std::unique_lock<std::mutex> l(m_AcquiredMutex);
m_Acquired.wait (l); // wait for element gets aquired
total += num;
}
if (total >= 20)
{
LogPrint (eLogWarning, "Transports: ", total, " DH keys generated at the time");
std::this_thread::sleep_for (std::chrono::seconds(1)); // take a break
}
else
{
std::unique_lock<std::mutex> l(m_AcquiredMutex);
m_Acquired.wait (l); // wait for element gets aquired
}
}
}
@ -60,7 +71,6 @@ namespace transport
{
if (num > 0)
{
i2p::crypto::DHKeys dh;
for (int i = 0; i < num; i++)
{
auto pair = std::make_shared<i2p::crypto::DHKeys> ();

@ -117,7 +117,7 @@ namespace tunnel
m.nextFragmentNum = 1;
auto ret = m_IncompleteMessages.insert (std::pair<uint32_t, TunnelMessageBlockEx>(msgID, m));
if (ret.second)
HandleOutOfSequenceFragment (msgID, ret.first->second);
HandleOutOfSequenceFragments (msgID, ret.first->second);
else
LogPrint (eLogError, "TunnelMessage: Incomplete message ", msgID, " already exists");
}
@ -168,7 +168,7 @@ namespace tunnel
else
{
msg.nextFragmentNum++;
HandleOutOfSequenceFragment (msgID, msg);
HandleOutOfSequenceFragments (msgID, msg);
}
}
else
@ -192,19 +192,31 @@ namespace tunnel
void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr<I2NPMessage> data)
{
auto it = m_OutOfSequenceFragments.find (msgID);
if (it == m_OutOfSequenceFragments.end ())
m_OutOfSequenceFragments.insert (std::pair<uint32_t, Fragment> (msgID, {fragmentNum, isLastFragment, data}));
if (!m_OutOfSequenceFragments.insert ({{msgID, fragmentNum}, {fragmentNum, isLastFragment, data}}).second)
LogPrint (eLogInfo, "TunnelMessage: duplicate out-of-sequence fragment ", fragmentNum, " of message ", msgID);
}
void TunnelEndpoint::HandleOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg)
void TunnelEndpoint::HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg)
{
auto it = m_OutOfSequenceFragments.find (msgID);
if (it != m_OutOfSequenceFragments.end ())
while (ConcatNextOutOfSequenceFragment (msgID, msg))
{
if (!msg.nextFragmentNum) // message complete
{
HandleNextMessage (msg);
m_IncompleteMessages.erase (msgID);
break;
}
}
}
bool TunnelEndpoint::ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg)
{
auto it = m_OutOfSequenceFragments.find ({msgID, msg.nextFragmentNum});
if (it != m_OutOfSequenceFragments.end ())
{
if (it->second.fragmentNum == msg.nextFragmentNum)
{
LogPrint (eLogWarning, "TunnelMessage: Out-of-sequence fragment ", (int)it->second.fragmentNum, " of message ", msgID, " found");
LogPrint (eLogDebug, "TunnelMessage: Out-of-sequence fragment ", (int)it->second.fragmentNum, " of message ", msgID, " found");
size_t size = it->second.data->GetLength ();
if (msg.data->len + size > msg.data->maxLen)
{
@ -214,18 +226,19 @@ namespace tunnel
msg.data = newMsg;
}
if (msg.data->Concat (it->second.data->GetBuffer (), size) < size) // concatenate out-of-sync fragment
LogPrint (eLogError, "Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen);
LogPrint (eLogError, "TunnelMessage: Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen);
if (it->second.isLastFragment)
{
// message complete
HandleNextMessage (msg);
m_IncompleteMessages.erase (msgID);
}
msg.nextFragmentNum = 0;
else
msg.nextFragmentNum++;
m_OutOfSequenceFragments.erase (it);
}
return true;
}
else
LogPrint (eLogError, "Tunnel message: next fragment ", (int)it->second.fragmentNum, " of message ", msgID, " mismatch. ", (int)msg.nextFragmentNum, " expected");
}
return false;
}
void TunnelEndpoint::HandleNextMessage (const TunnelMessageBlock& msg)

@ -39,12 +39,13 @@ namespace tunnel
void HandleNextMessage (const TunnelMessageBlock& msg);
void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr<I2NPMessage> data);
void HandleOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg);
bool ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg); // true if something added
void HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg);
private:
std::map<uint32_t, TunnelMessageBlockEx> m_IncompleteMessages;
std::map<uint32_t, Fragment> m_OutOfSequenceFragments;
std::map<std::pair<uint32_t, uint8_t>, Fragment> m_OutOfSequenceFragments; // (msgID, fragment#)->fragment
bool m_IsInbound;
size_t m_NumReceivedBytes;
};

@ -1,9 +1,11 @@
#define I2Pd_AppName "i2pd"
#define I2Pd_ver "2.10.0"
#define I2Pd_ver "2.10.1"
#define I2Pd_Publisher "PurpleI2P"
[Setup]
AppName={#I2Pd_AppName}
AppVersion={#I2Pd_ver}
AppPublisher={#I2Pd_Publisher}
DefaultDirName={pf}\I2Pd
DefaultGroupName=I2Pd
UninstallDisplayIcon={app}\I2Pd.exe
@ -14,19 +16,25 @@ InternalCompressLevel=ultra64
Compression=lzma/ultra64
SolidCompression=true
ArchitecturesInstallIn64BitMode=x64
AppVerName={#I2Pd_AppName}
ExtraDiskSpaceRequired=15
AppID={{621A23E0-3CF4-4BD6-97BC-4835EA5206A2}
AppPublisherURL=http://i2pd.website/
AppSupportURL=https://github.com/PurpleI2P/i2pd/issues
AppUpdatesURL=https://github.com/PurpleI2P/i2pd/releases
[Files]
Source: "..\i2pd_x86.exe"; DestDir: "{app}"; DestName: "i2pd.exe"; Flags: ignoreversion; Check: not IsWin64
Source: "..\i2pd_x64.exe"; DestDir: "{app}"; DestName: "i2pd.exe"; Flags: ignoreversion; Check: IsWin64
Source: "..\README.md"; DestDir: "{app}"; DestName: "Readme.txt"; Flags: onlyifdoesntexist
Source: "..\docs\i2pd.conf"; DestDir: "{userappdata}\i2pd"; Flags: onlyifdoesntexist
Source: "..\docs\subscriptions.txt"; DestDir: "{userappdata}\i2pd"; Flags: onlyifdoesntexist
Source: "..\docs\tunnels.conf"; DestDir: "{userappdata}\i2pd"; Flags: onlyifdoesntexist
Source: "..\contrib\*"; DestDir: "{userappdata}\i2pd"; Flags: onlyifdoesntexist recursesubdirs createallsubdirs
Source: ..\i2pd_x86.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: not IsWin64
Source: ..\i2pd_x64.exe; DestDir: {app}; DestName: i2pd.exe; Flags: ignoreversion; Check: IsWin64
Source: ..\README.md; DestDir: {app}; DestName: Readme.txt; Flags: onlyifdoesntexist
Source: ..\docs\i2pd.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
Source: ..\docs\subscriptions.txt; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
Source: ..\docs\tunnels.conf; DestDir: {userappdata}\i2pd; Flags: onlyifdoesntexist
Source: ..\contrib\certificates\*; DestDir: {userappdata}\i2pd\certificates; Flags: onlyifdoesntexist recursesubdirs createallsubdirs
[Icons]
Name: "{group}\I2Pd"; Filename: "{app}\i2pd.exe"
Name: "{group}\Readme"; Filename: "{app}\Readme.txt"
Name: {group}\I2Pd; Filename: {app}\i2pd.exe
Name: {group}\Readme; Filename: {app}\Readme.txt
[UninstallDelete]
Type: filesandordirs; Name: {app}\*
Type: filesandordirs; Name: {app}

@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.purplei2p.i2pd"
android:versionCode="1"
android:versionName="2.10.0">
android:versionName="2.10.1">
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="24"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>

@ -10,6 +10,47 @@ i2pd can be used for:
and many more.
## Starting, stopping and reloading configuration
After you have built i2pd from source, just run a binary:
./i2pd
To display all available options:
./i2pd --help
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:
kill -TERM $( cat /var/run/i2pd/i2pd.pid )
i2pd supports the following signals:
TERM - Graceful shutdown. i2pd will wait for 10 minutes and stop. Send second TERM signal to shutdown i2pd immediately.
HUP - Reload configuration files.
### systemd unit
Some binary Linux packages have a systemd control unit, so it is possible to managage i2pd with it.
Start/stop i2pd:
sudo systemctl start i2pd.service
sudo systemctl stop i2pd.service
Enable/disable i2pd to be started on bootup:
sudo systemctl enable i2pd.service
sudo systemctl disable i2pd.service
## Configuring i2pd
See [configuration page](i2pd.readthedocs.io/page/configuration.html).
## Browsing and hosting websites
### Browse anonymous websites

@ -8,7 +8,7 @@
#define I2PD_VERSION_MAJOR 2
#define I2PD_VERSION_MINOR 10
#define I2PD_VERSION_MICRO 0
#define I2PD_VERSION_MICRO 1
#define I2PD_VERSION_PATCH 0
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
#define VERSION I2PD_VERSION

Loading…
Cancel
Save