#622. Force SU3 verification by reseed.verify

This commit is contained in:
orignal 2016-10-11 15:02:23 -04:00
parent f0d098d0ef
commit fe8a0c1a6b
3 changed files with 56 additions and 42 deletions

View File

@ -150,6 +150,7 @@ namespace config {
options_description reseed("Reseed options"); options_description reseed("Reseed options");
reseed.add_options() reseed.add_options()
("reseed.verify", value<bool>()->default_value(false), "Verify .su3 signature")
("reseed.file", value<std::string>()->default_value(""), "Path to .su3 file") ("reseed.file", value<std::string>()->default_value(""), "Path to .su3 file")
#ifdef MESHNET #ifdef MESHNET
("reseed.urls", value<std::string>()->default_value("https://reseed.i2p.rocks:8443/"), "Reseed URLs, separated by comma") ("reseed.urls", value<std::string>()->default_value("https://reseed.i2p.rocks:8443/"), "Reseed URLs, separated by comma")

View File

@ -131,52 +131,64 @@ namespace data
s.read (signerID, signerIDLength); // signerID s.read (signerID, signerIDLength); // signerID
signerID[signerIDLength] = 0; signerID[signerIDLength] = 0;
//try to verify signature bool verify; i2p::config::GetOption("reseed.verify", verify);
auto it = m_SigningKeys.find (signerID); if (verify)
if (it != m_SigningKeys.end ()) {
{ //try to verify signature
// TODO: implement all signature types auto it = m_SigningKeys.find (signerID);
if (signatureType == SIGNING_KEY_TYPE_RSA_SHA512_4096) if (it != m_SigningKeys.end ())
{ {
size_t pos = s.tellg (); // TODO: implement all signature types
size_t tbsLen = pos + contentLength; if (signatureType == SIGNING_KEY_TYPE_RSA_SHA512_4096)
uint8_t * tbs = new uint8_t[tbsLen];
s.seekg (0, std::ios::beg);
s.read ((char *)tbs, tbsLen);
uint8_t * signature = new uint8_t[signatureLength];
s.read ((char *)signature, signatureLength);
// RSA-raw
{ {
// calculate digest size_t pos = s.tellg ();
uint8_t digest[64]; size_t tbsLen = pos + contentLength;
SHA512 (tbs, tbsLen, digest); uint8_t * tbs = new uint8_t[tbsLen];
// encrypt signature s.seekg (0, std::ios::beg);
BN_CTX * bnctx = BN_CTX_new (); s.read ((char *)tbs, tbsLen);
BIGNUM * s = BN_new (), * n = BN_new (); uint8_t * signature = new uint8_t[signatureLength];
BN_bin2bn (signature, signatureLength, s); s.read ((char *)signature, signatureLength);
BN_bin2bn (it->second, i2p::crypto::RSASHA5124096_KEY_LENGTH, n); // RSA-raw
BN_mod_exp (s, s, i2p::crypto::GetRSAE (), n, bnctx); // s = s^e mod n {
uint8_t * enSigBuf = new uint8_t[signatureLength]; // calculate digest
i2p::crypto::bn2buf (s, enSigBuf, signatureLength); uint8_t digest[64];
// digest is right aligned SHA512 (tbs, tbsLen, digest);
// we can't use RSA_verify due wrong padding in SU3 // encrypt signature
if (memcmp (enSigBuf + (signatureLength - 64), digest, 64)) BN_CTX * bnctx = BN_CTX_new ();
LogPrint (eLogWarning, "Reseed: SU3 signature verification failed"); BIGNUM * s = BN_new (), * n = BN_new ();
delete[] enSigBuf; BN_bin2bn (signature, signatureLength, s);
BN_free (s); BN_free (n); BN_bin2bn (it->second, i2p::crypto::RSASHA5124096_KEY_LENGTH, n);
BN_CTX_free (bnctx); BN_mod_exp (s, s, i2p::crypto::GetRSAE (), n, bnctx); // s = s^e mod n
} uint8_t * enSigBuf = new uint8_t[signatureLength];
i2p::crypto::bn2buf (s, enSigBuf, signatureLength);
// digest is right aligned
// we can't use RSA_verify due wrong padding in SU3
if (memcmp (enSigBuf + (signatureLength - 64), digest, 64))
LogPrint (eLogWarning, "Reseed: SU3 signature verification failed");
else
verify = false; // verified
delete[] enSigBuf;
BN_free (s); BN_free (n);
BN_CTX_free (bnctx);
}
delete[] signature; delete[] signature;
delete[] tbs; delete[] tbs;
s.seekg (pos, std::ios::beg); s.seekg (pos, std::ios::beg);
}
else
LogPrint (eLogWarning, "Reseed: Signature type ", signatureType, " is not supported");
} }
else else
LogPrint (eLogWarning, "Reseed: Signature type ", signatureType, " is not supported"); LogPrint (eLogWarning, "Reseed: Certificate for ", signerID, " not loaded");
} }
else
LogPrint (eLogWarning, "Reseed: Certificate for ", signerID, " not loaded"); if (verify) // not verified
{
LogPrint (eLogError, "Reseed: SU3 verification failed");
return 0;
}
// handle content // handle content
int numFiles = 0; int numFiles = 0;
size_t contentPos = s.tellg (); size_t contentPos = s.tellg ();

View File

@ -72,8 +72,9 @@ All options below still possible in cmdline, but better write it in config file:
* --upnp.name= - Name i2pd appears in UPnP forwardings list. I2Pd by default * --upnp.name= - Name i2pd appears in UPnP forwardings list. I2Pd by default
* --precomputation.elgamal= - Use ElGamal precomputated tables. false for x64 and true for other platforms by default * --precomputation.elgamal= - Use ElGamal precomputated tables. false for x64 and true for other platforms by default
* --reseed.file - Full path to SU3 file to reseed from * --reseed.verify= - Request SU3 signature verification
* --reseed.urls - Reseed URLs, separated by comma * --reseed.file= - Full path to SU3 file to reseed from
* --reseed.urls= - Reseed URLs, separated by comma
* --limits.transittunnels= - Override maximum number of transit tunnels. 2500 by default * --limits.transittunnels= - Override maximum number of transit tunnels. 2500 by default