verifyhost.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include <iostream>
  2. #include <fstream>
  3. #include <sstream>
  4. #include "Identity.h"
  5. #include "Base.h"
  6. int main (int argc, char * argv[])
  7. {
  8. if (argc < 2)
  9. {
  10. std::cout << "Usage: verifyhost '<host record>'" << std::endl;
  11. return -1;
  12. }
  13. i2p::crypto::InitCrypto (false, true, true, false);
  14. i2p::data::IdentityEx Identity, OldIdentity;
  15. std::string str (argv[1]);
  16. std::size_t pos;
  17. // get record without command block after "#!"
  18. pos = str.find ("#!");
  19. std::string hostStr = str.substr (0, pos);
  20. // get host base64
  21. pos = hostStr.find ("=");
  22. std::string hostBase64 = hostStr.substr (pos + 1);
  23. // load identity
  24. if (Identity.FromBase64 (hostBase64))
  25. {
  26. // get record without sig key and signature
  27. pos = str.find ("#sig=");
  28. if (pos == std::string::npos)
  29. {
  30. pos = str.find ("!sig=");
  31. if (pos == std::string::npos)
  32. {
  33. std::cout << "Destination signature not found." << std::endl;
  34. return 1;
  35. }
  36. }
  37. int offset = (str[pos - 1] == '#' /* only sig in record */) ? 1 : 0;
  38. std::string hostNoSig = str.substr (0, pos - offset);
  39. std::string sig = str.substr (pos + 5); // after "#sig=" till end
  40. auto signatureLen = Identity.GetSignatureLen ();
  41. uint8_t * signature = new uint8_t[signatureLen];
  42. // validate signature
  43. i2p::data::Base64ToByteStream(sig.c_str (), sig.length(), signature, signatureLen);
  44. if (!Identity.Verify ((uint8_t *)hostNoSig.c_str (), hostNoSig.length (), signature))
  45. {
  46. std::cout << "Invalid destination signature." << std::endl;
  47. return 1;
  48. }
  49. if (str.find ("olddest=") != std::string::npos) // if olddest present
  50. {
  51. // get olddest
  52. pos = str.find ("#olddest=");
  53. std::string oldDestCut = str.substr (pos + 9);
  54. pos = oldDestCut.find ("#");
  55. std::string oldDestBase64 = oldDestCut.substr (0, pos);
  56. // load identity
  57. if(!OldIdentity.FromBase64 (oldDestBase64))
  58. {
  59. std::cout << "Invalid old destination base64." << std::endl;
  60. return 1;
  61. }
  62. signatureLen = OldIdentity.GetSignatureLen ();
  63. signature = new uint8_t[signatureLen];
  64. // get record till oldsig key and oldsig
  65. pos = str.find ("#oldsig=");
  66. std::string hostNoOldSig = str.substr (0, pos);
  67. std::string oldSigCut = str.substr (pos + 8);
  68. pos = oldSigCut.find ("#");
  69. std::string oldSig = oldSigCut.substr (0, pos);
  70. // validate signature
  71. i2p::data::Base64ToByteStream(oldSig.c_str (), oldSig.length(), signature, signatureLen);
  72. bool oldSignValid = OldIdentity.Verify ((uint8_t *)hostNoOldSig.c_str (), hostNoOldSig.length (), signature);
  73. if(!oldSignValid)
  74. {
  75. std::cout << "Invalid old destination signature." << std::endl;
  76. return 1;
  77. }
  78. }
  79. }
  80. else
  81. {
  82. std::cout << "Invalid destination base64." << std::endl;
  83. return 1;
  84. }
  85. i2p::crypto::TerminateCrypto ();
  86. return 0;
  87. }