mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-02 11:04:00 +01:00
commit
b2d2c56a09
6
BOB.cpp
6
BOB.cpp
|
@ -430,8 +430,10 @@ namespace client
|
|||
void BOBCommandSession::SetkeysCommandHandler (const char * operand, size_t len)
|
||||
{
|
||||
LogPrint (eLogDebug, "BOB: setkeys ", operand);
|
||||
m_Keys.FromBase64 (operand);
|
||||
SendReplyOK (m_Keys.GetPublic ()->ToBase64 ().c_str ());
|
||||
if (m_Keys.FromBase64 (operand))
|
||||
SendReplyOK (m_Keys.GetPublic ()->ToBase64 ().c_str ());
|
||||
else
|
||||
SendReplyError ("invalid keys");
|
||||
}
|
||||
|
||||
void BOBCommandSession::GetkeysCommandHandler (const char * operand, size_t len)
|
||||
|
|
18
Config.cpp
18
Config.cpp
|
@ -238,18 +238,26 @@ namespace config {
|
|||
;
|
||||
}
|
||||
|
||||
void ParseCmdline(int argc, char* argv[]) {
|
||||
try {
|
||||
void ParseCmdline(int argc, char* argv[], bool ignoreUnknown)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto style = boost::program_options::command_line_style::unix_style
|
||||
| boost::program_options::command_line_style::allow_long_disguise;
|
||||
style &= ~ boost::program_options::command_line_style::allow_guessing;
|
||||
store(parse_command_line(argc, argv, m_OptionsDesc, style), m_Options);
|
||||
} catch (boost::program_options::error& e) {
|
||||
if (ignoreUnknown)
|
||||
store(command_line_parser(argc, argv).options(m_OptionsDesc).style (style).allow_unregistered().run(), m_Options);
|
||||
else
|
||||
store(parse_command_line(argc, argv, m_OptionsDesc, style), m_Options);
|
||||
}
|
||||
catch (boost::program_options::error& e)
|
||||
{
|
||||
std::cerr << "args: " << e.what() << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (m_Options.count("help") || m_Options.count("h")) {
|
||||
if (!ignoreUnknown && (m_Options.count("help") || m_Options.count("h")))
|
||||
{
|
||||
std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl;
|
||||
std::cout << m_OptionsDesc;
|
||||
exit(EXIT_SUCCESS);
|
||||
|
|
2
Config.h
2
Config.h
|
@ -41,7 +41,7 @@ namespace config {
|
|||
*
|
||||
* Other exceptions will be passed to higher level.
|
||||
*/
|
||||
void ParseCmdline(int argc, char* argv[]);
|
||||
void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false);
|
||||
|
||||
/**
|
||||
* @brief Load and parse given config file
|
||||
|
|
|
@ -799,7 +799,7 @@ namespace crypto
|
|||
}*/
|
||||
|
||||
|
||||
void InitCrypto (bool precomputation, bool withGost)
|
||||
void InitCrypto (bool precomputation)
|
||||
{
|
||||
SSL_library_init ();
|
||||
/* auto numLocks = CRYPTO_num_locks();
|
||||
|
|
2
Crypto.h
2
Crypto.h
|
@ -279,7 +279,7 @@ namespace crypto
|
|||
#endif
|
||||
};
|
||||
|
||||
void InitCrypto (bool precomputation, bool withGost = false);
|
||||
void InitCrypto (bool precomputation);
|
||||
void TerminateCrypto ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,9 @@ void handle_signal(int sig)
|
|||
case SIGTERM:
|
||||
Daemon.running = 0; // Exit loop
|
||||
break;
|
||||
case SIGPIPE:
|
||||
LogPrint(eLogInfo, "SIGPIPE received");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,6 +163,7 @@ namespace i2p
|
|||
sigaction(SIGABRT, &sa, 0);
|
||||
sigaction(SIGTERM, &sa, 0);
|
||||
sigaction(SIGINT, &sa, 0);
|
||||
sigaction(SIGPIPE, &sa, 0);
|
||||
|
||||
return Daemon_Singleton::start();
|
||||
}
|
||||
|
|
99
Gost.cpp
99
Gost.cpp
|
@ -2,6 +2,7 @@
|
|||
#include <array>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "I2PEndian.h"
|
||||
#include "Gost.h"
|
||||
|
||||
namespace i2p
|
||||
|
@ -95,6 +96,38 @@ namespace crypto
|
|||
return ret;
|
||||
}
|
||||
|
||||
EC_POINT * GOSTR3410Curve::RecoverPublicKey (const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s, bool isNegativeY) const
|
||||
{
|
||||
// s*P = r*Q + h*C
|
||||
BN_CTX * ctx = BN_CTX_new ();
|
||||
BN_CTX_start (ctx);
|
||||
EC_POINT * C = EC_POINT_new (m_Group); // C = k*P = (rx, ry)
|
||||
EC_POINT * Q = nullptr;
|
||||
if (EC_POINT_set_compressed_coordinates_GFp (m_Group, C, r, isNegativeY ? 1 : 0, ctx))
|
||||
{
|
||||
EC_POINT * S = EC_POINT_new (m_Group); // S = s*P
|
||||
EC_POINT_mul (m_Group, S, s, nullptr, nullptr, ctx);
|
||||
BIGNUM * q = BN_CTX_get (ctx);
|
||||
EC_GROUP_get_order(m_Group, q, ctx);
|
||||
BIGNUM * h = BN_CTX_get (ctx);
|
||||
BN_mod (h, digest, q, ctx); // h = digest % q
|
||||
BN_sub (h, q, h); // h = -h
|
||||
EC_POINT * H = EC_POINT_new (m_Group);
|
||||
EC_POINT_mul (m_Group, H, nullptr, C, h, ctx); // -h*C
|
||||
EC_POINT_add (m_Group, C, S, H, ctx); // s*P - h*C
|
||||
EC_POINT_free (H);
|
||||
EC_POINT_free (S);
|
||||
BIGNUM * r1 = BN_CTX_get (ctx);
|
||||
BN_mod_inverse (r1, r, q, ctx);
|
||||
Q = EC_POINT_new (m_Group);
|
||||
EC_POINT_mul (m_Group, Q, nullptr, C, r1, ctx); // (s*P - h*C)/r
|
||||
}
|
||||
EC_POINT_free (C);
|
||||
BN_CTX_end (ctx);
|
||||
BN_CTX_free (ctx);
|
||||
return Q;
|
||||
}
|
||||
|
||||
static GOSTR3410Curve * CreateGOSTR3410Curve (GOSTR3410ParamSet paramSet)
|
||||
{
|
||||
// a, b, p, q, x, y
|
||||
|
@ -107,15 +140,7 @@ namespace crypto
|
|||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
|
||||
"1",
|
||||
"8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"
|
||||
}, // A
|
||||
{
|
||||
"C2173F1513981673AF4892C23035A27CE25E2013BF95AA33B22C656F277E7335",
|
||||
"295F9BAE7428ED9CCC20E7C359A9D41A22FCCD9108E17BF7BA9337A6F8AE9513",
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
|
||||
"400000000000000000000000000000000FD8CDDFC87B6635C115AF556C360C67",
|
||||
"0D",
|
||||
"32879423AB1A0375895786C4BB46E9565FDE0B5344766740AF268ADB32322E5C"
|
||||
}, // tc26-2012-paramSetA-256
|
||||
}, // CryptoPro A
|
||||
{
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC4",
|
||||
"E8C2505DEDFC86DDC1BD0B2B6667F1DA34B82574761CB0E879BD081CFD0B6265EE3CB090F30D27614CB4574010DA90DD862EF9D4EBEE4761503190785A71C760",
|
||||
|
@ -192,20 +217,7 @@ namespace crypto
|
|||
0x492c024284fbaec0, 0xaa16012142f35760, 0x550b8e9e21f7a530, 0xa48b474f9ef5dc18,
|
||||
0x70a6a56e2440598e, 0x3853dc371220a247, 0x1ca76e95091051ad, 0x0edd37c48a08a6d8,
|
||||
0x07e095624504536c, 0x8d70c431ac02a736, 0xc83862965601dd1b, 0x641c314b2b8ee083
|
||||
};
|
||||
|
||||
static const uint8_t T_[64]=
|
||||
{
|
||||
0, 8, 16, 24, 32, 40, 48, 56,
|
||||
1, 9, 17, 25, 33, 41, 49, 57,
|
||||
2, 10, 18, 26, 34, 42, 50, 58,
|
||||
3, 11, 19, 27, 35, 43, 51, 59,
|
||||
4, 12, 20, 28, 36, 44, 52, 60,
|
||||
5, 13, 21, 29, 37, 45, 53, 61,
|
||||
6, 14, 22, 30, 38, 46, 54, 62,
|
||||
7, 15, 23, 31, 39, 47, 55, 63
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
static const uint8_t C_[12][64] =
|
||||
{
|
||||
|
@ -327,51 +339,36 @@ namespace crypto
|
|||
}
|
||||
}
|
||||
|
||||
void S ()
|
||||
{
|
||||
for (int i = 0; i < 64; i++)
|
||||
buf[i] = sbox_[buf[i]];
|
||||
}
|
||||
|
||||
void L ()
|
||||
void SPL ()
|
||||
{
|
||||
uint8_t p[64];
|
||||
memcpy (p, buf, 64); // we need to copy it for P's transposition
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
uint64_t c = 0;
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
uint8_t bit = 0x80;
|
||||
uint8_t byte = sbox_[p[j*8+i]]; // S - sbox_, P - transpose (i,j)
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
if (buf[i*8+j] & bit) c ^= A_[j*8+k];
|
||||
if (byte & bit) c ^= A_[j*8+k];
|
||||
bit >>= 1;
|
||||
}
|
||||
}
|
||||
ll[i] = c;
|
||||
ll[i] = htobe64 (c);
|
||||
}
|
||||
}
|
||||
|
||||
void P ()
|
||||
{
|
||||
uint8_t t[64];
|
||||
for (int i = 0; i < 64; i++)
|
||||
t[i] = buf[T_[i]];
|
||||
memcpy (buf, t, 64);
|
||||
}
|
||||
|
||||
GOST3411Block E (const GOST3411Block& m)
|
||||
{
|
||||
GOST3411Block k = *this;
|
||||
GOST3411Block res = k^m;
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
res.S ();
|
||||
res.P ();
|
||||
res.L ();
|
||||
res.SPL ();
|
||||
k = k^C_[i];
|
||||
k.S ();
|
||||
k.P ();
|
||||
k.L ();
|
||||
k.SPL ();
|
||||
res = k^res;
|
||||
}
|
||||
return res;
|
||||
|
@ -381,12 +378,10 @@ namespace crypto
|
|||
static GOST3411Block gN (const GOST3411Block& N, const GOST3411Block& h, const GOST3411Block& m)
|
||||
{
|
||||
GOST3411Block res = N ^ h;
|
||||
res.S ();
|
||||
res.P ();
|
||||
res.L ();
|
||||
res.SPL ();
|
||||
res = res.E (m);
|
||||
res = res ^ h;
|
||||
res = res ^ m;
|
||||
res = res^h;
|
||||
res = res^m;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -405,7 +400,7 @@ namespace crypto
|
|||
h= gN (N, h, m);
|
||||
N.Add (512);
|
||||
s = m + s;
|
||||
len -= 64;
|
||||
l -= 64;
|
||||
}
|
||||
// stage 3
|
||||
size_t padding = 64 - l;
|
||||
|
|
9
Gost.h
9
Gost.h
|
@ -13,13 +13,10 @@ namespace crypto
|
|||
|
||||
enum GOSTR3410ParamSet
|
||||
{
|
||||
// GOST R 34.10-2001
|
||||
eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1
|
||||
// XchA = A, XchB = C
|
||||
//eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0
|
||||
//eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1
|
||||
// GOST R 34.10-2012
|
||||
eGOSTR3410TC26A256, // 1.2.643.7.1.2.1.1.1
|
||||
//eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1
|
||||
eGOSTR3410TC26A512, // 1.2.643.7.1.2.1.2.1
|
||||
eGOSTR3410NumParamSets
|
||||
};
|
||||
|
@ -32,11 +29,13 @@ namespace crypto
|
|||
~GOSTR3410Curve ();
|
||||
|
||||
size_t GetKeyLen () const { return m_KeyLen; };
|
||||
const EC_GROUP * GetGroup () const { return m_Group; };
|
||||
EC_POINT * MulP (const BIGNUM * n) const;
|
||||
bool GetXY (const EC_POINT * p, BIGNUM * x, BIGNUM * y) const;
|
||||
EC_POINT * CreatePoint (const BIGNUM * x, const BIGNUM * y) const;
|
||||
void Sign (const BIGNUM * priv, const BIGNUM * digest, BIGNUM * r, BIGNUM * s);
|
||||
bool Verify (const EC_POINT * pub, const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s);
|
||||
EC_POINT * RecoverPublicKey (const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s, bool isNegativeY = false) const;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -47,7 +46,7 @@ namespace crypto
|
|||
std::unique_ptr<GOSTR3410Curve>& GetGOSTR3410Curve (GOSTR3410ParamSet paramSet);
|
||||
|
||||
void GOSTR3411_2012_256 (const uint8_t * buf, size_t len, uint8_t * digest);
|
||||
void GOSTR3411_2012_512 (const uint8_t * buf, size_t len, uint8_t * digest);
|
||||
void GOSTR3411_2012_512 (const uint8_t * buf, size_t len, uint8_t * digest);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
52
Identity.cpp
52
Identity.cpp
|
@ -102,8 +102,8 @@ namespace data
|
|||
memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH);
|
||||
break;
|
||||
}
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_2001_CRYPTO_PRO_A_GOSTR3411:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_2012_TC26_A_256_GOSTR3411:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST:
|
||||
{
|
||||
// 256
|
||||
size_t padding = 128 - i2p::crypto::GOSTR3410_256_PUBLIC_KEY_LENGTH; // 64 = 128 - 64
|
||||
|
@ -111,7 +111,8 @@ namespace data
|
|||
memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::GOSTR3410_256_PUBLIC_KEY_LENGTH);
|
||||
break;
|
||||
}
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_2012_TC26_A_512_GOSTR3411:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512_TEST:
|
||||
{
|
||||
// 512
|
||||
// no padding, key length is 128
|
||||
|
@ -386,22 +387,18 @@ namespace data
|
|||
UpdateVerifier (new i2p::crypto::EDDSA25519Verifier (m_StandardIdentity.signingKey + padding));
|
||||
break;
|
||||
}
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_2001_CRYPTO_PRO_A_GOSTR3411:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST:
|
||||
{
|
||||
size_t padding = 128 - i2p::crypto::GOSTR3410_256_PUBLIC_KEY_LENGTH; // 64 = 128 - 64
|
||||
UpdateVerifier (new i2p::crypto::GOSTR3410_2001_Verifier (i2p::crypto::eGOSTR3410CryptoProA, m_StandardIdentity.signingKey + padding));
|
||||
break;
|
||||
}
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_2012_TC26_A_256_GOSTR3411:
|
||||
{
|
||||
size_t padding = 128 - i2p::crypto::GOSTR3410_256_PUBLIC_KEY_LENGTH; // 64 = 128 - 64
|
||||
UpdateVerifier (new i2p::crypto::GOSTR3410_2012_256_Verifier (i2p::crypto::eGOSTR3410TC26A256, m_StandardIdentity.signingKey + padding));
|
||||
UpdateVerifier (new i2p::crypto::GOSTR3410_256_Verifier (i2p::crypto::eGOSTR3410CryptoProA, m_StandardIdentity.signingKey + padding));
|
||||
break;
|
||||
}
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_2012_TC26_A_512_GOSTR3411:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512_TEST:
|
||||
{
|
||||
// zero padding
|
||||
UpdateVerifier (new i2p::crypto::GOSTR3410_2012_512_Verifier (i2p::crypto::eGOSTR3410TC26A512, m_StandardIdentity.signingKey));
|
||||
UpdateVerifier (new i2p::crypto::GOSTR3410_512_Verifier (i2p::crypto::eGOSTR3410TC26A512, m_StandardIdentity.signingKey));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -462,8 +459,9 @@ namespace data
|
|||
|
||||
size_t PrivateKeys::FromBuffer (const uint8_t * buf, size_t len)
|
||||
{
|
||||
m_Public = std::make_shared<IdentityEx>(buf, len);
|
||||
size_t ret = m_Public->GetFullLen ();
|
||||
m_Public = std::make_shared<IdentityEx>();
|
||||
size_t ret = m_Public->FromBuffer (buf, len);
|
||||
if (!ret || ret + 256 > len) return 0; // overflow
|
||||
memcpy (m_PrivateKey, buf + ret, 256); // private key always 256
|
||||
ret += 256;
|
||||
size_t signingPrivateKeySize = m_Public->GetSigningPrivateKeyLen ();
|
||||
|
@ -545,14 +543,13 @@ namespace data
|
|||
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
||||
m_Signer.reset (new i2p::crypto::EDDSA25519Signer (m_SigningPrivateKey, m_Public->GetStandardIdentity ().certificate - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH));
|
||||
break;
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_2001_CRYPTO_PRO_A_GOSTR3411:
|
||||
m_Signer.reset (new i2p::crypto::GOSTR3410_2001_Signer (i2p::crypto::eGOSTR3410CryptoProA, m_SigningPrivateKey));
|
||||
break;
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_2012_TC26_A_256_GOSTR3411:
|
||||
m_Signer.reset (new i2p::crypto::GOSTR3410_2012_256_Signer (i2p::crypto::eGOSTR3410TC26A256, m_SigningPrivateKey));
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST:
|
||||
m_Signer.reset (new i2p::crypto::GOSTR3410_256_Signer (i2p::crypto::eGOSTR3410CryptoProA, m_SigningPrivateKey));
|
||||
break;
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_2012_TC26_A_512_GOSTR3411:
|
||||
m_Signer.reset (new i2p::crypto::GOSTR3410_2012_512_Signer (i2p::crypto::eGOSTR3410TC26A512, m_SigningPrivateKey));
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512_TEST:
|
||||
m_Signer.reset (new i2p::crypto::GOSTR3410_512_Signer (i2p::crypto::eGOSTR3410TC26A512, m_SigningPrivateKey));
|
||||
break;
|
||||
default:
|
||||
LogPrint (eLogError, "Identity: Signing key type ", (int)m_Public->GetSigningKeyType (), " is not supported");
|
||||
|
@ -588,14 +585,13 @@ namespace data
|
|||
break;
|
||||
case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519:
|
||||
i2p::crypto::CreateEDDSA25519RandomKeys (keys.m_SigningPrivateKey, signingPublicKey);
|
||||
break;
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_2001_CRYPTO_PRO_A_GOSTR3411:
|
||||
break;
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST:
|
||||
i2p::crypto::CreateGOSTR3410RandomKeys (i2p::crypto::eGOSTR3410CryptoProA, keys.m_SigningPrivateKey, signingPublicKey);
|
||||
break;
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_2012_TC26_A_256_GOSTR3411:
|
||||
i2p::crypto::CreateGOSTR3410RandomKeys (i2p::crypto::eGOSTR3410TC26A256, keys.m_SigningPrivateKey, signingPublicKey);
|
||||
break;
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_2012_TC26_A_512_GOSTR3411:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512:
|
||||
case SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512_TEST:
|
||||
i2p::crypto::CreateGOSTR3410RandomKeys (i2p::crypto::eGOSTR3410TC26A512, keys.m_SigningPrivateKey, signingPublicKey);
|
||||
break;
|
||||
default:
|
||||
|
|
11
Identity.h
11
Identity.h
|
@ -60,11 +60,14 @@ namespace data
|
|||
const uint16_t SIGNING_KEY_TYPE_RSA_SHA384_3072 = 5;
|
||||
const uint16_t SIGNING_KEY_TYPE_RSA_SHA512_4096 = 6;
|
||||
const uint16_t SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519 = 7;
|
||||
const uint16_t SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph = 8; // not implemented
|
||||
// following signature type should never appear in netid=2
|
||||
const uint16_t SIGNING_KEY_TYPE_GOSTR3410_2001_CRYPTO_PRO_A_GOSTR3411 = 65280; // approved by FSB
|
||||
const uint16_t SIGNING_KEY_TYPE_GOSTR3410_2012_TC26_A_256_GOSTR3411 = 65281;
|
||||
const uint16_t SIGNING_KEY_TYPE_GOSTR3410_2012_TC26_A_512_GOSTR3411 = 65282;
|
||||
|
||||
const uint16_t SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256 = 9;
|
||||
const uint16_t SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512 = 10; // approved by FSB
|
||||
// TODO: remove later
|
||||
const uint16_t SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256_TEST = 65281;
|
||||
const uint16_t SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512_TEST = 65282;
|
||||
|
||||
typedef uint16_t SigningKeyType;
|
||||
typedef uint16_t CryptoKeyType;
|
||||
|
||||
|
|
|
@ -55,15 +55,12 @@ else
|
|||
endif
|
||||
endif
|
||||
|
||||
IS_64 := $(shell $(CXX) -dumpmachine 2>&1 | $(GREP) -c "64")
|
||||
ifeq ($(USE_AESNI),yes)
|
||||
ifeq ($(IS_64),1)
|
||||
#check if AES-NI is supported by CPU
|
||||
ifneq ($(shell $(GREP) -c aes /proc/cpuinfo),0)
|
||||
CPU_FLAGS += -maes -DAESNI
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(USE_AVX),yes)
|
||||
#check if AVX supported by CPU
|
||||
|
|
59
SAM.cpp
59
SAM.cpp
|
@ -18,7 +18,7 @@ namespace client
|
|||
SAMSocket::SAMSocket (SAMBridge& owner):
|
||||
m_Owner (owner), m_Socket (m_Owner.GetService ()), m_Timer (m_Owner.GetService ()),
|
||||
m_BufferOffset (0), m_SocketType (eSAMSocketTypeUnknown), m_IsSilent (false),
|
||||
m_Stream (nullptr), m_Session (nullptr)
|
||||
m_IsAccepting (false), m_Stream (nullptr), m_Session (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ namespace client
|
|||
if (m_Session)
|
||||
{
|
||||
m_Session->DelSocket (shared_from_this ());
|
||||
if (m_Session->localDestination)
|
||||
if (m_IsAccepting && m_Session->localDestination)
|
||||
m_Session->localDestination->StopAcceptingStreams ();
|
||||
}
|
||||
break;
|
||||
|
@ -214,11 +214,11 @@ namespace client
|
|||
if (!strcmp (m_Buffer, SAM_SESSION_CREATE))
|
||||
ProcessSessionCreate (separator + 1, bytes_transferred - (separator - m_Buffer) - 1);
|
||||
else if (!strcmp (m_Buffer, SAM_STREAM_CONNECT))
|
||||
ProcessStreamConnect (separator + 1, bytes_transferred - (separator - m_Buffer) - 1);
|
||||
ProcessStreamConnect (separator + 1, bytes_transferred - (separator - m_Buffer) - 1, bytes_transferred - (eol - m_Buffer) - 1);
|
||||
else if (!strcmp (m_Buffer, SAM_STREAM_ACCEPT))
|
||||
ProcessStreamAccept (separator + 1, bytes_transferred - (separator - m_Buffer) - 1);
|
||||
else if (!strcmp (m_Buffer, SAM_DEST_GENERATE))
|
||||
ProcessDestGenerate ();
|
||||
ProcessDestGenerate (separator + 1, bytes_transferred - (separator - m_Buffer) - 1);
|
||||
else if (!strcmp (m_Buffer, SAM_NAMING_LOOKUP))
|
||||
ProcessNamingLookup (separator + 1, bytes_transferred - (separator - m_Buffer) - 1);
|
||||
else if (!strcmp (m_Buffer, SAM_DATAGRAM_SEND))
|
||||
|
@ -358,7 +358,7 @@ namespace client
|
|||
SendMessageReply (m_Buffer, l2, false);
|
||||
}
|
||||
|
||||
void SAMSocket::ProcessStreamConnect (char * buf, size_t len)
|
||||
void SAMSocket::ProcessStreamConnect (char * buf, size_t len, size_t rem)
|
||||
{
|
||||
LogPrint (eLogDebug, "SAM: stream connect: ", buf);
|
||||
std::map<std::string, std::string> params;
|
||||
|
@ -371,9 +371,17 @@ namespace client
|
|||
m_Session = m_Owner.FindSession (id);
|
||||
if (m_Session)
|
||||
{
|
||||
if (rem > 0) // handle follow on data
|
||||
{
|
||||
memmove (m_Buffer, buf + len + 1, rem); // buf is a pointer to m_Buffer's content
|
||||
m_BufferOffset = rem;
|
||||
}
|
||||
else
|
||||
m_BufferOffset = 0;
|
||||
|
||||
auto dest = std::make_shared<i2p::data::IdentityEx> ();
|
||||
size_t len = dest->FromBase64(destination);
|
||||
if (len > 0)
|
||||
size_t l = dest->FromBase64(destination);
|
||||
if (l > 0)
|
||||
{
|
||||
context.GetAddressBook().InsertAddress(dest);
|
||||
auto leaseSet = m_Session->localDestination->FindLeaseSet(dest->GetIdentHash());
|
||||
|
@ -398,7 +406,8 @@ namespace client
|
|||
m_SocketType = eSAMSocketTypeStream;
|
||||
m_Session->AddSocket (shared_from_this ());
|
||||
m_Stream = m_Session->localDestination->CreateStream (remote);
|
||||
m_Stream->Send ((uint8_t *)m_Buffer, 0); // connect
|
||||
m_Stream->Send ((uint8_t *)m_Buffer, m_BufferOffset); // connect and send
|
||||
m_BufferOffset = 0;
|
||||
I2PReceive ();
|
||||
SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false);
|
||||
}
|
||||
|
@ -429,7 +438,10 @@ namespace client
|
|||
m_SocketType = eSAMSocketTypeAcceptor;
|
||||
m_Session->AddSocket (shared_from_this ());
|
||||
if (!m_Session->localDestination->IsAcceptingStreams ())
|
||||
{
|
||||
m_IsAccepting = true;
|
||||
m_Session->localDestination->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, shared_from_this (), std::placeholders::_1));
|
||||
}
|
||||
SendMessageReply (SAM_STREAM_STATUS_OK, strlen(SAM_STREAM_STATUS_OK), false);
|
||||
}
|
||||
else
|
||||
|
@ -467,18 +479,26 @@ namespace client
|
|||
return offset + size;
|
||||
}
|
||||
|
||||
void SAMSocket::ProcessDestGenerate ()
|
||||
void SAMSocket::ProcessDestGenerate (char * buf, size_t len)
|
||||
{
|
||||
LogPrint (eLogDebug, "SAM: dest generate");
|
||||
auto keys = i2p::data::PrivateKeys::CreateRandomKeys ();
|
||||
std::map<std::string, std::string> params;
|
||||
ExtractParams (buf, params);
|
||||
// extract signature type
|
||||
i2p::data::SigningKeyType signatureType = i2p::data::SIGNING_KEY_TYPE_DSA_SHA1;
|
||||
auto it = params.find (SAM_PARAM_SIGNATURE_TYPE);
|
||||
if (it != params.end ())
|
||||
// TODO: extract string values
|
||||
signatureType = std::stoi(it->second);
|
||||
auto keys = i2p::data::PrivateKeys::CreateRandomKeys (signatureType);
|
||||
#ifdef _MSC_VER
|
||||
size_t len = 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 ());
|
||||
#else
|
||||
size_t len = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_DEST_REPLY,
|
||||
size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_DEST_REPLY,
|
||||
keys.GetPublic ()->ToBase64 ().c_str (), keys.ToBase64 ().c_str ());
|
||||
#endif
|
||||
SendMessageReply (m_Buffer, len, false);
|
||||
SendMessageReply (m_Buffer, l, false);
|
||||
}
|
||||
|
||||
void SAMSocket::ProcessNamingLookup (char * buf, size_t len)
|
||||
|
@ -603,6 +623,8 @@ namespace client
|
|||
{
|
||||
if (m_Stream)
|
||||
{
|
||||
bytes_transferred += m_BufferOffset;
|
||||
m_BufferOffset = 0;
|
||||
auto s = shared_from_this ();
|
||||
m_Stream->AsyncSend ((uint8_t *)m_Buffer, bytes_transferred,
|
||||
[s](const boost::system::error_code& ecode)
|
||||
|
@ -690,6 +712,7 @@ namespace client
|
|||
{
|
||||
LogPrint (eLogDebug, "SAM: incoming I2P connection for session ", m_ID);
|
||||
m_SocketType = eSAMSocketTypeStream;
|
||||
m_IsAccepting = false;
|
||||
m_Stream = stream;
|
||||
context.GetAddressBook ().InsertAddress (stream->GetRemoteIdentity ());
|
||||
auto session = m_Owner.FindSession (m_ID);
|
||||
|
@ -699,6 +722,7 @@ namespace client
|
|||
for (auto it: session->ListSockets ())
|
||||
if (it->m_SocketType == eSAMSocketTypeAcceptor)
|
||||
{
|
||||
it->m_IsAccepting = true;
|
||||
session->localDestination->AcceptOnce (std::bind (&SAMSocket::HandleI2PAccept, it, std::placeholders::_1));
|
||||
break;
|
||||
}
|
||||
|
@ -778,13 +802,14 @@ namespace client
|
|||
|
||||
void SAMSession::CloseStreams ()
|
||||
{
|
||||
std::vector<std::shared_ptr<SAMSocket> > socks;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_SocketsMutex);
|
||||
for (auto& sock : m_Sockets) {
|
||||
sock->CloseStream();
|
||||
for (const auto& sock : m_Sockets) {
|
||||
socks.push_back(sock);
|
||||
}
|
||||
}
|
||||
// XXX: should this be done inside locked parts?
|
||||
for (auto & sock : socks ) sock->Terminate();
|
||||
m_Sockets.clear();
|
||||
}
|
||||
|
||||
|
@ -875,7 +900,7 @@ namespace client
|
|||
if (destination != "")
|
||||
{
|
||||
i2p::data::PrivateKeys keys;
|
||||
keys.FromBase64 (destination);
|
||||
if (!keys.FromBase64 (destination)) return nullptr;
|
||||
localDestination = i2p::client::context.CreateNewLocalDestination (keys, true, params);
|
||||
}
|
||||
else // transient
|
||||
|
|
11
SAM.h
11
SAM.h
|
@ -87,9 +87,9 @@ namespace client
|
|||
void SetSocketType (SAMSocketType socketType) { m_SocketType = socketType; };
|
||||
SAMSocketType GetSocketType () const { return m_SocketType; };
|
||||
|
||||
void Terminate ();
|
||||
private:
|
||||
|
||||
void Terminate ();
|
||||
void HandleHandshakeReceived (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
void HandleHandshakeReplySent (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
void HandleMessage (const boost::system::error_code& ecode, std::size_t bytes_transferred);
|
||||
|
@ -105,9 +105,9 @@ namespace client
|
|||
void HandleI2PDatagramReceive (const i2p::data::IdentityEx& from, uint16_t fromPort, uint16_t toPort, const uint8_t * buf, size_t len);
|
||||
|
||||
void ProcessSessionCreate (char * buf, size_t len);
|
||||
void ProcessStreamConnect (char * buf, size_t len);
|
||||
void ProcessStreamConnect (char * buf, size_t len, size_t rem);
|
||||
void ProcessStreamAccept (char * buf, size_t len);
|
||||
void ProcessDestGenerate ();
|
||||
void ProcessDestGenerate (char * buf, size_t len);
|
||||
void ProcessNamingLookup (char * buf, size_t len);
|
||||
void SendI2PError(const std::string & msg);
|
||||
size_t ProcessDatagramSend (char * buf, size_t len, const char * data); // from SAM 1.0
|
||||
|
@ -131,6 +131,7 @@ namespace client
|
|||
SAMSocketType m_SocketType;
|
||||
std::string m_ID; // nickname
|
||||
bool m_IsSilent;
|
||||
bool m_IsAccepting; // for eSAMSocketTypeAcceptor only
|
||||
std::shared_ptr<i2p::stream::Stream> m_Stream;
|
||||
std::shared_ptr<SAMSession> m_Session;
|
||||
};
|
||||
|
@ -143,13 +144,13 @@ namespace client
|
|||
std::mutex m_SocketsMutex;
|
||||
|
||||
/** safely add a socket to this session */
|
||||
void AddSocket(std::shared_ptr<SAMSocket> sock) {
|
||||
void AddSocket(const std::shared_ptr<SAMSocket> & sock) {
|
||||
std::lock_guard<std::mutex> lock(m_SocketsMutex);
|
||||
m_Sockets.push_back(sock);
|
||||
}
|
||||
|
||||
/** safely remove a socket from this session */
|
||||
void DelSocket(std::shared_ptr<SAMSocket> sock) {
|
||||
void DelSocket(const std::shared_ptr<SAMSocket> & sock) {
|
||||
std::lock_guard<std::mutex> lock(m_SocketsMutex);
|
||||
m_Sockets.remove(sock);
|
||||
}
|
||||
|
|
|
@ -168,14 +168,13 @@ namespace crypto
|
|||
|
||||
BN_mul (x3, p1.x, p2.x, ctx); // A = x1*x2
|
||||
BN_mul (y3, p1.y, p2.y, ctx); // B = y1*y2
|
||||
|
||||
|
||||
BN_CTX_start (ctx);
|
||||
BIGNUM * t1 = p1.t, * t2 = p2.t;
|
||||
if (!t1) { t1 = BN_new (); BN_mul (t1, p1.x, p1.y, ctx); }
|
||||
if (!t2) { t2 = BN_new (); BN_mul (t2, p2.x, p2.y, ctx); }
|
||||
if (!t1) { t1 = BN_CTX_get (ctx); BN_mul (t1, p1.x, p1.y, ctx); }
|
||||
if (!t2) { t2 = BN_CTX_get (ctx); BN_mul (t2, p2.x, p2.y, ctx); }
|
||||
BN_mul (t3, t1, t2, ctx);
|
||||
BN_mul (t3, t3, d, ctx); // C = d*t1*t2
|
||||
if (!p1.t) BN_free (t1);
|
||||
if (!p2.t) BN_free (t2);
|
||||
|
||||
if (p1.z)
|
||||
{
|
||||
|
@ -192,7 +191,6 @@ namespace crypto
|
|||
BN_one (z3); // D = 1
|
||||
}
|
||||
|
||||
BN_CTX_start (ctx);
|
||||
BIGNUM * E = BN_CTX_get (ctx), * F = BN_CTX_get (ctx), * G = BN_CTX_get (ctx), * H = BN_CTX_get (ctx);
|
||||
BN_add (E, p1.x, p1.y);
|
||||
BN_add (F, p2.x, p2.y);
|
||||
|
@ -213,9 +211,10 @@ namespace crypto
|
|||
return EDDSAPoint {x3, y3, z3, t3};
|
||||
}
|
||||
|
||||
EDDSAPoint Double (const EDDSAPoint& p, BN_CTX * ctx) const
|
||||
void Double (EDDSAPoint& p, BN_CTX * ctx) const
|
||||
{
|
||||
BIGNUM * x2 = BN_new (), * y2 = BN_new (), * z2 = BN_new (), * t2 = BN_new ();
|
||||
BN_CTX_start (ctx);
|
||||
BIGNUM * x2 = BN_CTX_get (ctx), * y2 = BN_CTX_get (ctx), * z2 = BN_CTX_get (ctx), * t2 = BN_CTX_get (ctx);
|
||||
|
||||
BN_sqr (x2, p.x, ctx); // x2 = A = x^2
|
||||
BN_sqr (y2, p.y, ctx); // y2 = B = y^2
|
||||
|
@ -232,7 +231,6 @@ namespace crypto
|
|||
else
|
||||
BN_one (z2); // z2 = 1
|
||||
|
||||
BN_CTX_start (ctx);
|
||||
BIGNUM * E = BN_CTX_get (ctx), * F = BN_CTX_get (ctx), * G = BN_CTX_get (ctx), * H = BN_CTX_get (ctx);
|
||||
// E = (x+y)*(x+y)-A-B = x^2+y^2+2xy-A-B = 2xy
|
||||
BN_mul (E, p.x, p.y, ctx);
|
||||
|
@ -241,14 +239,14 @@ namespace crypto
|
|||
BN_add (G, z2, t2); // G = D + C
|
||||
BN_add (H, y2, x2); // H = B + A
|
||||
|
||||
BN_mod_mul (x2, E, F, q, ctx); // x2 = E*F
|
||||
BN_mod_mul (y2, G, H, q, ctx); // y2 = G*H
|
||||
BN_mod_mul (z2, F, G, q, ctx); // z2 = F*G
|
||||
BN_mod_mul (t2, E, H, q, ctx); // t2 = E*H
|
||||
BN_mod_mul (p.x, E, F, q, ctx); // x2 = E*F
|
||||
BN_mod_mul (p.y, G, H, q, ctx); // y2 = G*H
|
||||
if (!p.z) p.z = BN_new ();
|
||||
BN_mod_mul (p.z, F, G, q, ctx); // z2 = F*G
|
||||
if (!p.t) p.t = BN_new ();
|
||||
BN_mod_mul (p.t, E, H, q, ctx); // t2 = E*H
|
||||
|
||||
BN_CTX_end (ctx);
|
||||
|
||||
return EDDSAPoint {x2, y2, z2, t2};
|
||||
}
|
||||
|
||||
EDDSAPoint Mul (const EDDSAPoint& p, const BIGNUM * e, BN_CTX * ctx) const
|
||||
|
@ -261,7 +259,7 @@ namespace crypto
|
|||
int bitCount = BN_num_bits (e);
|
||||
for (int i = bitCount - 1; i >= 0; i--)
|
||||
{
|
||||
res = Double (res, ctx);
|
||||
Double (res, ctx);
|
||||
if (BN_is_bit_set (e, i)) res = Sum (res, p, ctx);
|
||||
}
|
||||
}
|
||||
|
|
30
Signature.h
30
Signature.h
|
@ -444,32 +444,22 @@ namespace crypto
|
|||
}
|
||||
|
||||
|
||||
// ГОСТ Р 34.11
|
||||
struct GOSTR3411_2001_Hash
|
||||
// ГОСТ Р 34.11
|
||||
struct GOSTR3411_256_Hash
|
||||
{
|
||||
static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest)
|
||||
{
|
||||
SHA256 (buf, len, digest); // TODO: implement GOST R 34.11 - 2001
|
||||
}
|
||||
|
||||
enum { hashLen = 32 };
|
||||
};
|
||||
|
||||
struct GOSTR3411_2012_256_Hash
|
||||
{
|
||||
static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest)
|
||||
{
|
||||
SHA256 (buf, len, digest); // TODO: implement GOST R 34.11 - 2012
|
||||
GOSTR3411_2012_256 (buf, len, digest);
|
||||
}
|
||||
|
||||
enum { hashLen = 32 };
|
||||
};
|
||||
|
||||
struct GOSTR3411_2012_512_Hash
|
||||
struct GOSTR3411_512_Hash
|
||||
{
|
||||
static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest)
|
||||
{
|
||||
SHA512 (buf, len, digest); // TODO: implement GOST R 34.11 - 2012
|
||||
GOSTR3411_2012_512 (buf, len, digest);
|
||||
}
|
||||
|
||||
enum { hashLen = 64 };
|
||||
|
@ -566,12 +556,10 @@ namespace crypto
|
|||
BN_free (x); BN_free (y);
|
||||
}
|
||||
|
||||
typedef GOSTR3410Verifier<GOSTR3411_2001_Hash> GOSTR3410_2001_Verifier;
|
||||
typedef GOSTR3410Signer<GOSTR3411_2001_Hash> GOSTR3410_2001_Signer;
|
||||
typedef GOSTR3410Verifier<GOSTR3411_2012_256_Hash> GOSTR3410_2012_256_Verifier;
|
||||
typedef GOSTR3410Signer<GOSTR3411_2012_256_Hash> GOSTR3410_2012_256_Signer;
|
||||
typedef GOSTR3410Verifier<GOSTR3411_2012_512_Hash> GOSTR3410_2012_512_Verifier;
|
||||
typedef GOSTR3410Signer<GOSTR3411_2012_512_Hash> GOSTR3410_2012_512_Signer;
|
||||
typedef GOSTR3410Verifier<GOSTR3411_256_Hash> GOSTR3410_256_Verifier;
|
||||
typedef GOSTR3410Signer<GOSTR3411_256_Hash> GOSTR3410_256_Signer;
|
||||
typedef GOSTR3410Verifier<GOSTR3411_512_Hash> GOSTR3410_512_Verifier;
|
||||
typedef GOSTR3410Signer<GOSTR3411_512_Hash> GOSTR3410_512_Signer;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1091,16 +1091,18 @@ namespace stream
|
|||
}
|
||||
else // we must save old acceptor and set it back
|
||||
{
|
||||
auto oldAcceptor = m_Acceptor;
|
||||
m_Acceptor = [acceptor, oldAcceptor, this](std::shared_ptr<Stream> stream)
|
||||
{
|
||||
acceptor (stream);
|
||||
m_Acceptor = oldAcceptor;
|
||||
};
|
||||
m_Acceptor = std::bind (&StreamingDestination::AcceptOnceAcceptor, this,
|
||||
std::placeholders::_1, acceptor, m_Acceptor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void StreamingDestination::AcceptOnceAcceptor (std::shared_ptr<Stream> stream, Acceptor acceptor, Acceptor prev)
|
||||
{
|
||||
m_Acceptor = prev;
|
||||
acceptor (stream);
|
||||
}
|
||||
|
||||
void StreamingDestination::HandlePendingIncomingTimer (const boost::system::error_code& ecode)
|
||||
{
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
|
|
|
@ -280,7 +280,9 @@ namespace stream
|
|||
void DeletePacket (Packet * p) { if (p) m_PacketsPool.Release (p); };
|
||||
|
||||
private:
|
||||
|
||||
|
||||
void AcceptOnceAcceptor (std::shared_ptr<Stream> stream, Acceptor acceptor, Acceptor prev);
|
||||
|
||||
void HandleNextPacket (Packet * packet);
|
||||
std::shared_ptr<Stream> CreateNewIncomingStream ();
|
||||
void HandlePendingIncomingTimer (const boost::system::error_code& ecode);
|
||||
|
|
2
api.cpp
2
api.cpp
|
@ -19,7 +19,7 @@ namespace api
|
|||
void InitI2P (int argc, char* argv[], const char * appName)
|
||||
{
|
||||
i2p::config::Init ();
|
||||
i2p::config::ParseCmdline (argc, argv);
|
||||
i2p::config::ParseCmdline (argc, argv, true); // ignore unknown options and help
|
||||
i2p::config::Finalize ();
|
||||
|
||||
std::string datadir; i2p::config::GetOption("datadir", datadir);
|
||||
|
|
|
@ -19,6 +19,7 @@ environment:
|
|||
install:
|
||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Rns gcc-fortran gcc"
|
||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu"
|
||||
|
||||
- c:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syuu"
|
||||
|
||||
- if "%MSYSTEM%" == "MINGW64" (
|
||||
|
|
3
build/.gitignore
vendored
3
build/.gitignore
vendored
|
@ -8,3 +8,6 @@
|
|||
/CPackConfig.cmake
|
||||
/CPackSourceConfig.cmake
|
||||
/install_manifest.txt
|
||||
# windows build script
|
||||
i2pd*.zip
|
||||
build*.log
|
||||
|
|
62
build/build_mingw.cmd
Normal file
62
build/build_mingw.cmd
Normal file
|
@ -0,0 +1,62 @@
|
|||
@echo off
|
||||
setlocal enableextensions enabledelayedexpansion
|
||||
title Building i2pd
|
||||
|
||||
REM Copyright (c) 2013-2017, The PurpleI2P Project
|
||||
REM This file is part of Purple i2pd project and licensed under BSD3
|
||||
REM See full license text in LICENSE file at top of project tree
|
||||
|
||||
REM To use that script, you must have installed in your MSYS installation theese packages:
|
||||
REM Base: git make zip
|
||||
REM x86_64: mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-gcc
|
||||
REM i686: mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-gcc
|
||||
|
||||
REM setting up variables for MSYS
|
||||
REM Note: if you installed MSYS64 to different path, edit WD variable (only C:\msys64 needed to edit)!
|
||||
set "WD=C:\msys64\usr\bin\"
|
||||
set MSYS2_PATH_TYPE=inherit
|
||||
set CHERE_INVOKING=enabled_from_arguments
|
||||
set MSYSTEM=MSYS
|
||||
|
||||
REM detecting number of processors and subtract 1.
|
||||
set /a threads=%NUMBER_OF_PROCESSORS%-1
|
||||
|
||||
REM we must work in root of repo
|
||||
cd ..
|
||||
|
||||
echo Receiving latest commit and cleaning up...
|
||||
"%WD%bash" -lc "git pull && make clean" > build/build_git.log 2>&1
|
||||
echo.
|
||||
|
||||
REM set to variable current commit hash
|
||||
FOR /F "usebackq" %%a IN (`%WD%bash -lc 'git describe --tags'`) DO (
|
||||
set tag=%%a
|
||||
)
|
||||
|
||||
REM starting building
|
||||
set MSYSTEM=MINGW32
|
||||
set bitness=32
|
||||
call :BUILDING
|
||||
echo.
|
||||
|
||||
set MSYSTEM=MINGW64
|
||||
set bitness=64
|
||||
call :BUILDING
|
||||
echo.
|
||||
|
||||
echo Build complete...
|
||||
pause
|
||||
exit /b 0
|
||||
|
||||
:BUILDING
|
||||
echo Building i2pd %tag% for win%bitness%:
|
||||
echo Build AVX+AESNI...
|
||||
"%WD%bash" -lc "make USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j%threads% && zip -9 build/i2pd_%tag%_win%bitness%_mingw_avx_aesni.zip i2pd.exe && make clean" > build/build_win%bitness%_avx_aesni.log 2>&1
|
||||
echo Build AVX...
|
||||
"%WD%bash" -lc "make USE_UPNP=yes USE_AVX=1 -j%threads% && zip -9 build/i2pd_%tag%_win%bitness%_mingw_avx.zip i2pd.exe && make clean" > build/build_win%bitness%_avx.log 2>&1
|
||||
echo Build AESNI...
|
||||
"%WD%bash" -lc "make USE_UPNP=yes USE_AESNI=1 -j%threads% && zip -9 build/i2pd_%tag%_win%bitness%_mingw_aesni.zip i2pd.exe && make clean" > build/build_win%bitness%_aesni.log 2>&1
|
||||
echo Build without extensions...
|
||||
"%WD%bash" -lc "make USE_UPNP=yes -j%threads% && zip -9 build/i2pd_%tag%_win%bitness%_mingw.zip i2pd.exe && make clean" > build/build_win%bitness%.log 2>&1
|
||||
|
||||
:EOF
|
2
contrib/.gitignore
vendored
2
contrib/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
i2pd*.zip
|
||||
build*.log
|
|
@ -1,25 +0,0 @@
|
|||
@echo off
|
||||
setlocal
|
||||
|
||||
title Building i2pd
|
||||
|
||||
set "WD=C:\msys64\usr\bin\"
|
||||
set MSYS2_PATH_TYPE=inherit
|
||||
set CHERE_INVOKING=enabled_from_arguments
|
||||
set MSYSCON=
|
||||
|
||||
echo Building i2pd for win32. Press Enter after the end of compilation...
|
||||
set MSYSTEM=MINGW32
|
||||
set CONTITLE=MinGW x32
|
||||
start "%CONTITLE%" /WAIT "%WD%bash" --login build_mingw.sh
|
||||
pause > nul
|
||||
|
||||
echo Building i2pd for win64. Press Enter after the end of compilation...
|
||||
set MSYSTEM=MINGW64
|
||||
set CONTITLE=MinGW x64
|
||||
start "%CONTITLE%" /WAIT "%WD%bash" --login build_mingw.sh
|
||||
pause > nul
|
||||
|
||||
echo Build complete...
|
||||
pause
|
||||
exit /b 0
|
|
@ -1,88 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Определяем архитектуру.
|
||||
if [ $MSYSTEM == MINGW64 ]; then
|
||||
export arch="win64"
|
||||
elif [ $MSYSTEM == MINGW32 ]; then
|
||||
export arch="win32"
|
||||
else
|
||||
echo "Не могу понять, какая у вас архитектура, используемая для сборки.";
|
||||
echo "Вы точно запустили скрипт в оболочке MSYS2 MinGW [64/32]-bit ?";
|
||||
echo "Обычно её можно запустить выполнив c:\msys64\mingw64.exe или c:\msys64\mingw32.exe";
|
||||
exit 1;
|
||||
fi;
|
||||
|
||||
# Задаём переменной contrib текущий путь и переходим на уровень выше.
|
||||
export contrib=$PWD
|
||||
cd ..
|
||||
|
||||
# Очистка от предыдущей сборки (на всякий случай =) ).
|
||||
make clean >> /dev/null
|
||||
|
||||
# Обновляем репозиторий, и получаем хеш последнего коммита.
|
||||
echo "Получаем обновления из репозитория.";
|
||||
git pull
|
||||
if [ "$?" != 0 ]; then
|
||||
echo "Не удалось обновить локальный репозиторий.";
|
||||
echo "Вы точно запустили скрипт в папке репозитория?";
|
||||
exit 1;
|
||||
fi;
|
||||
|
||||
export commit=$(git rev-parse --verify HEAD | cut -c -7)
|
||||
if [ -z commit ]; then
|
||||
echo "Не удалось получить хеш последнего коммита.";
|
||||
echo "Вы точно запустили скрипт в папке репозитория?";
|
||||
exit 1;
|
||||
fi;
|
||||
|
||||
# Получаем версию приложения
|
||||
export version=$(grep -E "I2PD_VERSION_(MAJOR|MINOR|MICRO)\ " version.h | grep -oE '[^ ]+$' | tr '\n' '.'|head -c -1)
|
||||
|
||||
# Получаем количество ядер, и уменьшаем количество потоков на 1 от количества ядер (если их больше чем 1).
|
||||
if [ $NUMBER_OF_PROCESSORS -ge 2 ]; then
|
||||
export threads=$(( $NUMBER_OF_PROCESSORS - 1 ))
|
||||
else
|
||||
export threads=$NUMBER_OF_PROCESSORS
|
||||
fi;
|
||||
|
||||
echo "Собираем i2pd ${version} (коммит ${commit}) для ${arch}.";
|
||||
|
||||
# Собираем приложение с разными параметрами, и архивируем в zip архивы.
|
||||
echo "Сборка AVX+AESNI";
|
||||
make USE_UPNP=yes USE_AVX=1 USE_AESNI=1 -j ${threads} > ${contrib}/build_${arch}_avx_aesni.log 2>&1
|
||||
if [ "$?" != 0 ]; then
|
||||
echo "Сборка не удалась. Смотрите в build_avx_aesni.log";
|
||||
exit 1;
|
||||
fi;
|
||||
zip -9 ${contrib}/i2pd_${version}_${commit}_${arch}_mingw_avx_aesni.zip i2pd.exe >> /dev/null
|
||||
make clean >> /dev/null
|
||||
|
||||
echo "Сборка AVX";
|
||||
make USE_UPNP=yes USE_AVX=1 -j ${threads} > ${contrib}/build_${arch}_avx.log 2>&1
|
||||
if [ "$?" != 0 ]; then
|
||||
echo "Сборка не удалась. Смотрите в build_avx.log.";
|
||||
exit 1;
|
||||
fi;
|
||||
zip -9 ${contrib}/i2pd_${version}_${commit}_${arch}_mingw_avx.zip i2pd.exe >> /dev/null
|
||||
make clean >> /dev/null
|
||||
|
||||
echo "Сборка AESNI";
|
||||
make USE_UPNP=yes USE_AESNI=1 -j ${threads} > ${contrib}/build_${arch}_aesni.log 2>&1
|
||||
if [ "$?" != 0 ]; then
|
||||
echo "Сборка не удалась. Смотрите в build_aesni.log";
|
||||
exit 1;
|
||||
fi;
|
||||
zip -9 ${contrib}/i2pd_${version}_${commit}_${arch}_mingw_aesni.zip i2pd.exe >> /dev/null
|
||||
make clean >> /dev/null
|
||||
|
||||
echo "Сборка без дополнительных инструкций";
|
||||
make USE_UPNP=yes -j ${threads} > ${contrib}/build_${arch}.log 2>&1
|
||||
if [ "$?" != 0 ]; then
|
||||
echo "Сборка не удалась. Смотрите в build.log";
|
||||
exit 1;
|
||||
fi;
|
||||
zip -9 ${contrib}/i2pd_${version}_${commit}_${arch}_mingw.zip i2pd.exe >> /dev/null
|
||||
make clean >> /dev/null
|
||||
|
||||
echo "Сборка i2pd ${version} для ${arch} завершена.";
|
||||
exit 0;
|
|
@ -1,7 +1,6 @@
|
|||
CXXFLAGS += -Wall -Wextra -pedantic -O0 -g -std=c++11 -D_GLIBCXX_USE_NANOSLEEP=1
|
||||
|
||||
TESTS = test-http-url test-http-req test-http-res test-http-url_decode \
|
||||
test-http-merge_chunked test-base-64
|
||||
TESTS = test-gost test-gost-sig test-base-64
|
||||
|
||||
all: $(TESTS) run
|
||||
|
||||
|
@ -11,6 +10,12 @@ test-http-%: ../HTTP.cpp test-http-%.cpp
|
|||
test-base-%: ../Base.cpp test-base-%.cpp
|
||||
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^
|
||||
|
||||
test-gost: ../Gost.cpp ../I2PEndian.cpp test-gost.cpp
|
||||
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto
|
||||
|
||||
test-gost-sig: ../Gost.cpp ../I2PEndian.cpp ../Signature.cpp ../Crypto.cpp ../Log.cpp test-gost-sig.cpp
|
||||
$(CXX) $(CXXFLAGS) $(NEEDED_CXXFLAGS) $(INCFLAGS) -o $@ $^ -lcrypto -lssl -lboost_system
|
||||
|
||||
run: $(TESTS)
|
||||
@for TEST in $(TESTS); do ./$$TEST ; done
|
||||
|
||||
|
|
35
tests/test-gost-sig.cpp
Normal file
35
tests/test-gost-sig.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#include <cassert>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../Gost.h"
|
||||
#include "../Signature.h"
|
||||
|
||||
const uint8_t example2[72] =
|
||||
{
|
||||
0xfb,0xe2,0xe5,0xf0,0xee,0xe3,0xc8,0x20,0xfb,0xea,0xfa,0xeb,0xef,0x20,0xff,0xfb,
|
||||
0xf0,0xe1,0xe0,0xf0,0xf5,0x20,0xe0,0xed,0x20,0xe8,0xec,0xe0,0xeb,0xe5,0xf0,0xf2,
|
||||
0xf1,0x20,0xff,0xf0,0xee,0xec,0x20,0xf1,0x20,0xfa,0xf2,0xfe,0xe5,0xe2,0x20,0x2c,
|
||||
0xe8,0xf6,0xf3,0xed,0xe2,0x20,0xe8,0xe6,0xee,0xe1,0xe8,0xf0,0xf2,0xd1,0x20,0x2c,
|
||||
0xe8,0xf0,0xf2,0xe5,0xe2,0x20,0xe5,0xd1
|
||||
};
|
||||
|
||||
|
||||
int main ()
|
||||
{
|
||||
uint8_t priv[64], pub[128], signature[128];
|
||||
i2p::crypto::CreateGOSTR3410RandomKeys (i2p::crypto::eGOSTR3410TC26A512, priv, pub);
|
||||
i2p::crypto::GOSTR3410_512_Signer signer (i2p::crypto::eGOSTR3410TC26A512, priv);
|
||||
signer.Sign (example2, 72, signature);
|
||||
i2p::crypto::GOSTR3410_512_Verifier verifier (i2p::crypto::eGOSTR3410TC26A512, pub);
|
||||
assert (verifier.Verify (example2, 72, signature));
|
||||
|
||||
i2p::crypto::CreateGOSTR3410RandomKeys (i2p::crypto::eGOSTR3410CryptoProA, priv, pub);
|
||||
i2p::crypto::GOSTR3410_256_Signer signer1 (i2p::crypto::eGOSTR3410CryptoProA, priv);
|
||||
signer1.Sign (example2, 72, signature);
|
||||
i2p::crypto::GOSTR3410_256_Verifier verifier1 (i2p::crypto::eGOSTR3410CryptoProA, pub);
|
||||
assert (verifier1.Verify (example2, 72, signature));
|
||||
}
|
||||
|
||||
|
||||
|
69
tests/test-gost.cpp
Normal file
69
tests/test-gost.cpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
#include <cassert>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../Gost.h"
|
||||
|
||||
const uint8_t example1[63] =
|
||||
{
|
||||
0x32,0x31,0x30,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x39,0x38,0x37,
|
||||
0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,
|
||||
0x30,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,0x39,0x38,0x37,0x36,0x35,
|
||||
0x34,0x33,0x32,0x31,0x30,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30
|
||||
};
|
||||
|
||||
const uint8_t example2[72] =
|
||||
{
|
||||
0xfb,0xe2,0xe5,0xf0,0xee,0xe3,0xc8,0x20,0xfb,0xea,0xfa,0xeb,0xef,0x20,0xff,0xfb,
|
||||
0xf0,0xe1,0xe0,0xf0,0xf5,0x20,0xe0,0xed,0x20,0xe8,0xec,0xe0,0xeb,0xe5,0xf0,0xf2,
|
||||
0xf1,0x20,0xff,0xf0,0xee,0xec,0x20,0xf1,0x20,0xfa,0xf2,0xfe,0xe5,0xe2,0x20,0x2c,
|
||||
0xe8,0xf6,0xf3,0xed,0xe2,0x20,0xe8,0xe6,0xee,0xe1,0xe8,0xf0,0xf2,0xd1,0x20,0x2c,
|
||||
0xe8,0xf0,0xf2,0xe5,0xe2,0x20,0xe5,0xd1
|
||||
};
|
||||
|
||||
const uint8_t example1_hash_512[64] =
|
||||
{
|
||||
0x48,0x6f,0x64,0xc1,0x91,0x78,0x79,0x41,0x7f,0xef,0x08,0x2b,0x33,0x81,0xa4,0xe2,
|
||||
0x11,0xc3,0x24,0xf0,0x74,0x65,0x4c,0x38,0x82,0x3a,0x7b,0x76,0xf8,0x30,0xad,0x00,
|
||||
0xfa,0x1f,0xba,0xe4,0x2b,0x12,0x85,0xc0,0x35,0x2f,0x22,0x75,0x24,0xbc,0x9a,0xb1,
|
||||
0x62,0x54,0x28,0x8d,0xd6,0x86,0x3d,0xcc,0xd5,0xb9,0xf5,0x4a,0x1a,0xd0,0x54,0x1b
|
||||
};
|
||||
|
||||
const uint8_t example1_hash_256[32] =
|
||||
{
|
||||
0x00,0x55,0x7b,0xe5,0xe5,0x84,0xfd,0x52,0xa4,0x49,0xb1,0x6b,0x02,0x51,0xd0,0x5d,
|
||||
0x27,0xf9,0x4a,0xb7,0x6c,0xba,0xa6,0xda,0x89,0x0b,0x59,0xd8,0xef,0x1e,0x15,0x9d
|
||||
};
|
||||
|
||||
const uint8_t example2_hash_512[64] =
|
||||
{
|
||||
0x28,0xfb,0xc9,0xba,0xda,0x03,0x3b,0x14,0x60,0x64,0x2b,0xdc,0xdd,0xb9,0x0c,0x3f,
|
||||
0xb3,0xe5,0x6c,0x49,0x7c,0xcd,0x0f,0x62,0xb8,0xa2,0xad,0x49,0x35,0xe8,0x5f,0x03,
|
||||
0x76,0x13,0x96,0x6d,0xe4,0xee,0x00,0x53,0x1a,0xe6,0x0f,0x3b,0x5a,0x47,0xf8,0xda,
|
||||
0xe0,0x69,0x15,0xd5,0xf2,0xf1,0x94,0x99,0x6f,0xca,0xbf,0x26,0x22,0xe6,0x88,0x1e
|
||||
};
|
||||
|
||||
const uint8_t example2_hash_256[32] =
|
||||
{
|
||||
0x50,0x8f,0x7e,0x55,0x3c,0x06,0x50,0x1d,0x74,0x9a,0x66,0xfc,0x28,0xc6,0xca,0xc0,
|
||||
0xb0,0x05,0x74,0x6d,0x97,0x53,0x7f,0xa8,0x5d,0x9e,0x40,0x90,0x4e,0xfe,0xd2,0x9d
|
||||
};
|
||||
|
||||
int main ()
|
||||
{
|
||||
uint8_t digest[64];
|
||||
i2p::crypto::GOSTR3411_2012_512 (example1, 63, digest);
|
||||
assert(memcmp (digest, example1_hash_512, 64) == 0);
|
||||
|
||||
i2p::crypto::GOSTR3411_2012_256 (example1, 63, digest);
|
||||
assert(memcmp (digest, example1_hash_256, 32) == 0);
|
||||
|
||||
i2p::crypto::GOSTR3411_2012_512 (example2, 72, digest);
|
||||
assert(memcmp (digest, example2_hash_512, 64) == 0);
|
||||
|
||||
i2p::crypto::GOSTR3411_2012_256 (example2, 72, digest);
|
||||
assert(memcmp (digest, example2_hash_256, 32) == 0);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue