-
Notifications
You must be signed in to change notification settings - Fork 11
/
dump_hash.h
146 lines (132 loc) · 4.15 KB
/
dump_hash.h
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// hash functions for microsoft platforms.
#include <cassert>
#include <exception>
#include <cpputils/formatter.h>
#include <string>
#include <wincrypt.h>
class winerror : std::exception {
DWORD _code;
std::string _msg;
public:
winerror(const std::string& msg) : _code(GetLastError()), _msg(msg) { }
virtual const char* what() const noexcept
{
return stringformat("[%08x] %s", _code, _msg).c_str();
}
};
class CryptProvider {
private:
HCRYPTPROV m_hProv;
public:
CryptProvider() : m_hProv(0) { }
~CryptProvider() { Close(); }
void Open()
{
if (!CryptAcquireContext(&m_hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
m_hProv= NULL;
throw winerror("CryptAcquireContext");
}
}
void Close()
{
if (m_hProv) {
CryptReleaseContext(m_hProv, 0);
m_hProv= NULL;
}
}
HCRYPTPROV GetHandle()
{
if (m_hProv==NULL)
Open();
return m_hProv;
}
};
class CryptHash {
private:
CryptProvider &m_prov;
HCRYPTHASH m_hHash;
int m_type;
public:
enum { MD2, MD4, MD5, SHA1, SHA256, SHA384, SHA512, HASHTYPECOUNT };
CryptHash(CryptProvider &provider) : m_prov(provider), m_hHash(0), m_type(0) { }
~CryptHash() { Close(); }
void Close()
{
if (m_hHash!=NULL)
CloseHash();
}
void InitHash(int type)
{
HCRYPTPROV hProv = m_prov.GetHandle();
if (m_hHash!=NULL)
CloseHash();
m_type= type==MD2 ? CALG_MD2
:type==MD4 ? CALG_MD4
:type==MD5 ? CALG_MD5
:type==SHA1 ? CALG_SHA1
:type==SHA256? CALG_SHA_256
:type==SHA384? CALG_SHA_384
:type==SHA512? CALG_SHA_512
: type;
bool silent= (m_type==type);
if (!CryptCreateHash(hProv, (ALG_ID)m_type, 0, 0, &m_hHash))
{
if (!silent)
throw winerror(stringformat("CryptCreateHash(%08lx)", m_type));
}
}
void CloseHash()
{
if (m_hHash) {
CryptDestroyHash(m_hHash);
m_hHash= NULL;
}
}
void AddData(const std::vector<uint8_t>& data)
{
assert(m_hHash!=NULL);
if (!CryptHashData(m_hHash, &data[0], data.size(), 0))
throw winerror(stringformat("CryptHashData(%08lx)", m_type));
}
std::vector<uint8_t> GetHash()
{
assert(m_hHash!=NULL);
DWORD dwSize;
if (!CryptGetHashParam(m_hHash, HP_HASHVAL, NULL, &dwSize, 0))
throw winerror(stringformat("CryptGetHashParam(%08lx, HASHVAL-size)", m_type));
std::vector<uint8_t> hash(dwSize);
if (!CryptGetHashParam(m_hHash, HP_HASHVAL, &hash[0], &dwSize, 0))
throw winerror(stringformat("CryptGetHashParam(%08lx, HASHVAL-data)", m_type));
CloseHash();
return hash;
}
std::vector<uint8_t> CalcHash(const std::vector<uint8_t>& data, int type)
{
InitHash(type);
AddData(data);
return GetHash();
}
int hashtype() const { return m_type; }
std::string hashname() const
{
switch(GET_ALG_SID(m_type))
{
case ALG_SID_MD2 : return "MD2";
case ALG_SID_MD4 : return "MD4";
case ALG_SID_MD5 : return "MD5";
case ALG_SID_SHA1 : return "SHA1";
case ALG_SID_MAC : return "MAC";
case ALG_SID_RIPEMD : return "RIPEMD";
case ALG_SID_RIPEMD160 : return "RIPEMD160";
case ALG_SID_SSL3SHAMD5 : return "SSL3SHAMD5";
case ALG_SID_HMAC : return "HMAC";
case ALG_SID_TLS1PRF : return "TLS1PRF";
case ALG_SID_HASH_REPLACE_OWF : return "OWF";
case ALG_SID_SHA_256 : return "SHA_256";
case ALG_SID_SHA_384 : return "SHA_384";
case ALG_SID_SHA_512 : return "SHA_512";
default: return stringformat("a_%08x", m_type);
}
}
};