|
|
@ -131,51 +131,63 @@ 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 ()) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
// TODO: implement all signature types
|
|
|
|
//try to verify signature
|
|
|
|
if (signatureType == SIGNING_KEY_TYPE_RSA_SHA512_4096) |
|
|
|
auto it = m_SigningKeys.find (signerID); |
|
|
|
|
|
|
|
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"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (verify) // not verified
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
LogPrint (eLogError, "Reseed: SU3 verification failed"); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
|
|
|
|
LogPrint (eLogWarning, "Reseed: Certificate for ", signerID, " not loaded"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// handle content
|
|
|
|
// handle content
|
|
|
|
int numFiles = 0; |
|
|
|
int numFiles = 0; |
|
|
|