#include #include #include #include "Identity.h" #include "Base.h" int main (int argc, char * argv[]) { if (argc < 2) { std::cout << "Usage: verifyhost ''" << std::endl; return -1; } i2p::crypto::InitCrypto (false, true, true, false); i2p::data::IdentityEx Identity, OldIdentity; std::string str (argv[1]); std::size_t pos; // get record without command block after "#!" pos = str.find ("#!"); std::string hostStr = str.substr (0, pos); // get host base64 pos = hostStr.find ("="); std::string hostBase64 = hostStr.substr (pos + 1); // load identity if (Identity.FromBase64 (hostBase64)) { // get record without sig key and signature pos = str.find ("#sig="); if (pos == std::string::npos) { pos = str.find ("!sig="); if (pos == std::string::npos) { std::cout << "Destination signature not found." << std::endl; return 1; } } int offset = (str[pos - 1] == '#' /* only sig in record */) ? 1 : 0; std::string hostNoSig = str.substr (0, pos - offset); std::string sig = str.substr (pos + 5); // after "#sig=" till end auto signatureLen = Identity.GetSignatureLen (); uint8_t * signature = new uint8_t[signatureLen]; // validate signature i2p::data::Base64ToByteStream(sig.c_str (), sig.length(), signature, signatureLen); if (!Identity.Verify ((uint8_t *)hostNoSig.c_str (), hostNoSig.length (), signature)) { std::cout << "Invalid destination signature." << std::endl; return 1; } if (str.find ("olddest=") != std::string::npos) // if olddest present { // get olddest pos = str.find ("#olddest="); std::string oldDestCut = str.substr (pos + 9); pos = oldDestCut.find ("#"); std::string oldDestBase64 = oldDestCut.substr (0, pos); // load identity if(!OldIdentity.FromBase64 (oldDestBase64)) { std::cout << "Invalid old destination base64." << std::endl; return 1; } signatureLen = OldIdentity.GetSignatureLen (); signature = new uint8_t[signatureLen]; // get record till oldsig key and oldsig pos = str.find ("#oldsig="); std::string hostNoOldSig = str.substr (0, pos); std::string oldSigCut = str.substr (pos + 8); pos = oldSigCut.find ("#"); std::string oldSig = oldSigCut.substr (0, pos); // validate signature i2p::data::Base64ToByteStream(oldSig.c_str (), oldSig.length(), signature, signatureLen); bool oldSignValid = OldIdentity.Verify ((uint8_t *)hostNoOldSig.c_str (), hostNoOldSig.length (), signature); if(!oldSignValid) { std::cout << "Invalid old destination signature." << std::endl; return 1; } } } else { std::cout << "Invalid destination base64." << std::endl; return 1; } i2p::crypto::TerminateCrypto (); return 0; }