Browse Source

Merge pull request #839 from PurpleI2P/openssl

recent changes
pull/63/merge
orignal 7 years ago committed by GitHub
parent
commit
b2d2c56a09
  1. 6
      BOB.cpp
  2. 18
      Config.cpp
  3. 2
      Config.h
  4. 2
      Crypto.cpp
  5. 2
      Crypto.h
  6. 4
      DaemonLinux.cpp
  7. 99
      Gost.cpp
  8. 9
      Gost.h
  9. 52
      Identity.cpp
  10. 11
      Identity.h
  11. 3
      Makefile.linux
  12. 59
      SAM.cpp
  13. 11
      SAM.h
  14. 30
      Signature.cpp
  15. 30
      Signature.h
  16. 14
      Streaming.cpp
  17. 4
      Streaming.h
  18. 2
      api.cpp
  19. 1
      appveyor.yml
  20. 3
      build/.gitignore
  21. 62
      build/build_mingw.cmd
  22. 2
      contrib/.gitignore
  23. 25
      contrib/build_mingw.cmd
  24. 88
      contrib/build_mingw.sh
  25. 9
      tests/Makefile
  26. 35
      tests/test-gost-sig.cpp
  27. 69
      tests/test-gost.cpp

6
BOB.cpp

@ -430,8 +430,10 @@ namespace client @@ -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

@ -238,18 +238,26 @@ namespace config { @@ -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

@ -41,7 +41,7 @@ namespace config { @@ -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

2
Crypto.cpp

@ -799,7 +799,7 @@ namespace crypto @@ -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

@ -279,7 +279,7 @@ namespace crypto @@ -279,7 +279,7 @@ namespace crypto
#endif
};
void InitCrypto (bool precomputation, bool withGost = false);
void InitCrypto (bool precomputation);
void TerminateCrypto ();
}
}

4
DaemonLinux.cpp

@ -42,6 +42,9 @@ void handle_signal(int sig) @@ -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 @@ -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

@ -2,6 +2,7 @@ @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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

@ -13,13 +13,10 @@ namespace crypto @@ -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 @@ -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 @@ -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

@ -102,8 +102,8 @@ namespace data @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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:
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);
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_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

@ -60,11 +60,14 @@ namespace data @@ -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;

3
Makefile.linux

@ -55,15 +55,12 @@ else @@ -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

@ -18,7 +18,7 @@ namespace client @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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

@ -87,9 +87,9 @@ namespace client @@ -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 @@ -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 @@ -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 @@ -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);
}

30
Signature.cpp

@ -168,14 +168,13 @@ namespace crypto @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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

@ -444,32 +444,22 @@ namespace crypto @@ -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 @@ -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;
}
}

14
Streaming.cpp

@ -1091,16 +1091,18 @@ namespace stream @@ -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)

4
Streaming.h

@ -280,7 +280,9 @@ namespace stream @@ -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

@ -19,7 +19,7 @@ namespace api @@ -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);

1
appveyor.yml

@ -19,6 +19,7 @@ environment: @@ -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

@ -8,3 +8,6 @@ @@ -8,3 +8,6 @@
/CPackConfig.cmake
/CPackSourceConfig.cmake
/install_manifest.txt
# windows build script
i2pd*.zip
build*.log

62
build/build_mingw.cmd

@ -0,0 +1,62 @@ @@ -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

@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
i2pd*.zip
build*.log

25
contrib/build_mingw.cmd

@ -1,25 +0,0 @@ @@ -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

88
contrib/build_mingw.sh

@ -1,88 +0,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;

9
tests/Makefile

@ -1,7 +1,6 @@ @@ -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 @@ -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

@ -0,0 +1,35 @@ @@ -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

@ -0,0 +1,69 @@ @@ -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…
Cancel
Save