-
Notifications
You must be signed in to change notification settings - Fork 35
/
verifyhost.cpp
107 lines (87 loc) · 2.74 KB
/
verifyhost.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <iostream>
#include <fstream>
#include <sstream>
#include "Identity.h"
#include "Base.h"
int main (int argc, char * argv[])
{
if (argc < 2)
{
std::cout << "Usage: verifyhost '<host record>'" << std::endl;
return -1;
}
i2p::crypto::InitCrypto (false, 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;
}