1#include <winpr/wtypes.h>
3#include <winpr/string.h>
4#include <winpr/print.h>
10 const BYTE expected[16];
12 const BOOL shouldMatch;
20 const BYTE expected[16];
22 const BOOL shouldMatch;
29 const BYTE passwordhash[16];
30 const BYTE expected[16];
32 const BOOL shouldMatch;
33} test_case_from_hash_t;
35static const test_case_ntowf1_t ntofw1tests[] = {
36 {
"foo1", { 0 }, TRUE, FALSE },
38 { 0x05, 0x80, 0x83, 0x4a, 0x04, 0x89, 0xed, 0x37, 0x49, 0x6b, 0x7b, 0xfa, 0xe9, 0x90, 0x9b,
43 { 0xee, 0xd4, 0xd3, 0xb5, 0x87, 0x11, 0x0d, 0x5c, 0x08, 0x51, 0x8c, 0xea, 0xa5, 0x69, 0x1e,
47 {
nullptr, { 0 }, FALSE, FALSE }
50static const test_case_ntowf2_t ntofw2tests[] = {
51 {
nullptr,
nullptr,
nullptr, { 0 }, FALSE, FALSE },
52 {
nullptr,
nullptr,
"domain1", { 0 }, FALSE, FALSE },
53 {
nullptr,
"user1",
"domain1", { 0 }, FALSE, FALSE },
54 {
"pwd1",
"user1",
"domain1", { 0 }, TRUE, FALSE },
58 { 0x9b, 0xee, 0x1e, 0x41, 0xa6, 0xd3, 0xf1, 0xf2, 0xc4, 0x00, 0xb8, 0xf9, 0x44, 0xc5, 0x44,
65 { 0xa5, 0x82, 0xcd, 0x70, 0xce, 0xb0, 0xed, 0x99, 0xe6, 0xf5, 0x45, 0x3e, 0x96, 0x93, 0x5d,
72 { 0xf9, 0x4d, 0x1e, 0x10, 0x31, 0xa1, 0x96, 0x0d, 0xa9, 0xaa, 0x64, 0xb3, 0x83, 0x1a, 0x79,
80 0x47, 0x62, 0x01, 0xda, 0x81, 0xd4, 0x48, 0xac, \
81 0x69, 0x02, 0x72, 0x46, 0x3b, 0x75, 0xb3, 0xac \
85 0x76, 0xc2, 0x51, 0x01, 0x35, 0x27, 0x08, 0x8b, \
86 0xc6, 0x4c, 0x1b, 0xd4, 0x2c, 0x78, 0x8b, 0xac \
88#define hashV1_test1_foobar1 \
90 0x2f, 0xb7, 0x06, 0xe3, 0xf4, 0xf2, 0x74, 0xe7, \
91 0x62, 0xfc, 0x53, 0xcb, 0x57, 0x9a, 0x28, 0x3a \
93#define hashV1_test1_foobar1_domain1 \
95 0xa2, 0xbc, 0x65, 0x8e, 0xda, 0xfc, 0xc2, 0xef, \
96 0xaa, 0x26, 0x41, 0x07, 0xb6, 0x9f, 0x94, 0x5c \
98#define hashV1_test1_foobar1_domain2 \
100 0xcf, 0x76, 0xd4, 0xe0, 0xe7, 0x8d, 0xc7, 0xec, \
101 0x59, 0x48, 0x9f, 0x47, 0xde, 0x52, 0xbd, 0x5c \
103#define hashV1_test2_foobar1 \
105 0x4e, 0xe8, 0xd8, 0xe1, 0xfd, 0x7a, 0x77, 0x2b, \
106 0xe7, 0x7c, 0x06, 0xe3, 0xca, 0x6e, 0x47, 0xb6 \
108#define hashV1_test2_foobar1_domain1 \
110 0x40, 0x74, 0xd1, 0x98, 0x32, 0x38, 0xdb, 0x3f, \
111 0x2d, 0x18, 0x1c, 0xd5, 0x0f, 0xb0, 0x70, 0xd2 \
113#define hashV1_test2_foobar1_domain2 \
115 0x2e, 0x63, 0x11, 0x29, 0x4f, 0x47, 0x3e, 0x87, \
116 0x72, 0x07, 0x36, 0x52, 0x20, 0xb3, 0xbe, 0x46 \
119static const test_case_from_hash_t ntofw2fromhashtests[] = {
120 {
nullptr,
nullptr, { 0 }, { 0 }, FALSE, FALSE },
121 {
"foobar1",
nullptr, hashV1_test1, { 0 }, TRUE, FALSE },
122 {
"foobar1",
nullptr, hashV1_test2, hashV1_test1_foobar1, TRUE, FALSE },
123 {
"foobar1",
nullptr, hashV1_test1, hashV1_test1_foobar1, TRUE, TRUE },
124 {
"foobar2",
nullptr, hashV1_test1, hashV1_test1_foobar1, TRUE, FALSE },
125 {
"foobar1",
"domain1", hashV1_test1, hashV1_test1_foobar1_domain1, TRUE, TRUE },
126 {
"foobar1",
"domain2", hashV1_test1, hashV1_test1_foobar1_domain1, TRUE, FALSE },
127 {
"foobar1",
"domain2", hashV1_test1, hashV1_test1_foobar1_domain2, TRUE, TRUE },
128 {
"foobar1",
nullptr, hashV1_test2, { 0 }, TRUE, FALSE },
129 {
"foobar1",
nullptr, hashV1_test1, hashV1_test2_foobar1, TRUE, FALSE },
130 {
"foobar1",
nullptr, hashV1_test2, hashV1_test2_foobar1, TRUE, TRUE },
131 {
"foobar2",
nullptr, hashV1_test2, hashV1_test2_foobar1, TRUE, FALSE },
132 {
"foobar1",
"domain1", hashV1_test2, hashV1_test2_foobar1_domain1, TRUE, TRUE },
133 {
"foobar1",
"domain2", hashV1_test2, hashV1_test2_foobar1_domain1, TRUE, FALSE },
134 {
"foobar1",
"domain2", hashV1_test2, hashV1_test2_foobar1_domain2, TRUE, TRUE }
137static BOOL testNTOWF1(
size_t x,
const test_case_ntowf1_t* test)
141 BYTE hashA[
sizeof(test->expected)] = WINPR_C_ARRAY_INIT;
142 BYTE hashW[
sizeof(test->expected)] = WINPR_C_ARRAY_INIT;
145 pwdlen = strlen(test->password);
147 const BOOL rcA = NTOWFv1A(test->password, pwdlen, hashA);
149 WCHAR* passwordW =
nullptr;
152 passwordW = ConvertUtf8NToWCharAlloc(test->password, pwdlen, &pwdwlen);
153 const BOOL rcW = NTOWFv1W(passwordW, pwdwlen *
sizeof(WCHAR), hashW);
156 winpr_HexDump(
"NTOWFv1A", WLOG_INFO, hashA,
sizeof(hashA));
157 winpr_HexDump(
"expect", WLOG_INFO, test->expected,
sizeof(test->expected));
158 WLog_INFO(
"result",
"[%" PRIuz
"] got %d, expected %d", x, rcA, test->result);
160 winpr_HexDump(
"NTOWFv1W", WLOG_INFO, hashW,
sizeof(hashW));
161 winpr_HexDump(
"expect", WLOG_INFO, test->expected,
sizeof(test->expected));
162 WLog_INFO(
"result",
"[%" PRIuz
"] got %d, expected %d", x, rcW, test->result);
164 if (rcA != test->result)
167 if (memcmp(test->expected, hashA,
sizeof(test->expected)) != 0)
169 if (test->shouldMatch)
173 if (rcW != test->result)
176 if (memcmp(test->expected, hashW,
sizeof(test->expected)) != 0)
178 if (test->shouldMatch)
184static BOOL testNTOWF2(
size_t x,
const test_case_ntowf2_t* test)
188 BYTE hashA[
sizeof(test->expected)] = WINPR_C_ARRAY_INIT;
189 BYTE hashW[
sizeof(test->expected)] = WINPR_C_ARRAY_INIT;
193 pwdlen = strlen(test->password);
197 userlen = strlen(test->user);
199 size_t domainlen = 0;
201 domainlen = strlen(test->domain);
204 NTOWFv2A(test->password, pwdlen, test->user, userlen, test->domain, domainlen, hashA);
206 WCHAR* passwordW =
nullptr;
209 passwordW = ConvertUtf8NToWCharAlloc(test->password, pwdlen, &pwdwlen);
211 WCHAR* userW =
nullptr;
214 userW = ConvertUtf8NToWCharAlloc(test->user, userlen, &userwlen);
216 WCHAR* domainW =
nullptr;
217 size_t domainwlen = 0;
219 domainW = ConvertUtf8NToWCharAlloc(test->domain, domainlen, &domainwlen);
221 const BOOL rcW = NTOWFv2W(passwordW, pwdwlen *
sizeof(WCHAR), userW, userwlen *
sizeof(WCHAR),
222 domainW, domainlen *
sizeof(WCHAR), hashW);
227 winpr_HexDump(
"NTOWFv2A", WLOG_INFO, hashA,
sizeof(hashA));
228 winpr_HexDump(
"expect", WLOG_INFO, test->expected,
sizeof(test->expected));
229 WLog_INFO(
"result",
"[%" PRIuz
"] got %d, expected %d", x, rcA, test->result);
231 winpr_HexDump(
"NTOWFv2W", WLOG_INFO, hashW,
sizeof(hashW));
232 winpr_HexDump(
"expect", WLOG_INFO, test->expected,
sizeof(test->expected));
233 WLog_INFO(
"result",
"[%" PRIuz
"] got %d, expected %d", x, rcW, test->result);
235 if (rcA != test->result)
237 if (memcmp(test->expected, hashA,
sizeof(test->expected)) != 0)
239 if (test->shouldMatch)
243 if (rcW != test->result)
245 if (memcmp(test->expected, hashW,
sizeof(test->expected)) != 0)
247 if (test->shouldMatch)
253static BOOL testNTOWFv2FromHash(
size_t x,
const test_case_from_hash_t* test)
257 BYTE hashA[
sizeof(test->expected)] = WINPR_C_ARRAY_INIT;
258 BYTE hashW[
sizeof(test->expected)] = WINPR_C_ARRAY_INIT;
262 userlen = strlen(test->user);
264 size_t domainlen = 0;
266 domainlen = strlen(test->domain);
269 NTOWFv2FromHashA(test->passwordhash, test->user, userlen, test->domain, domainlen, hashA);
271 WCHAR* userW =
nullptr;
274 userW = ConvertUtf8NToWCharAlloc(test->user, userlen, &userwlen);
276 WCHAR* domainW =
nullptr;
277 size_t domainwlen = 0;
279 domainW = ConvertUtf8NToWCharAlloc(test->domain, domainlen, &domainwlen);
281 const BOOL rcW = NTOWFv2FromHashW(test->passwordhash, userW, userwlen *
sizeof(WCHAR), domainW,
282 domainwlen *
sizeof(WCHAR), hashW);
287 winpr_HexDump(
"NTOWFv2A", WLOG_INFO, hashA,
sizeof(hashA));
288 winpr_HexDump(
"expect", WLOG_INFO, test->expected,
sizeof(test->expected));
289 WLog_INFO(
"result",
"[%" PRIuz
"] got %d, expected %d", x, rcA, test->result);
291 winpr_HexDump(
"NTOWFv2W", WLOG_INFO, hashW,
sizeof(hashW));
292 winpr_HexDump(
"expect", WLOG_INFO, test->expected,
sizeof(test->expected));
293 WLog_INFO(
"result",
"[%" PRIuz
"] got %d, expected %d", x, rcW, test->result);
295 if (rcA != test->result)
297 if (memcmp(test->expected, hashA,
sizeof(test->expected)) != 0)
299 if (test->shouldMatch)
303 if (rcW != test->result)
305 if (memcmp(test->expected, hashW,
sizeof(test->expected)) != 0)
307 if (test->shouldMatch)
313int TestNTLM(WINPR_ATTR_UNUSED
int argc, WINPR_ATTR_UNUSED
char* argv[])
316 winpr_InitializeSSL(WINPR_SSL_INIT_DEFAULT);
318 for (
size_t x = 0; x < ARRAYSIZE(ntofw1tests); x++)
320 const test_case_ntowf1_t* cur = &ntofw1tests[x];
321 if (!testNTOWF1(x, cur))
323 WLog_WARN(
"testNTOWF1",
"[%" PRIuz
"] test failed", x);
327 for (
size_t x = 0; x < ARRAYSIZE(ntofw2tests); x++)
329 const test_case_ntowf2_t* cur = &ntofw2tests[x];
330 if (!testNTOWF2(x, cur))
332 WLog_WARN(
"testNTOWF2",
"[%" PRIuz
"] test failed", x);
336 for (
size_t x = 0; x < ARRAYSIZE(ntofw2fromhashtests); x++)
338 const test_case_from_hash_t* cur = &ntofw2fromhashtests[x];
339 if (!testNTOWFv2FromHash(x, cur))
341 WLog_WARN(
"testNTOWFv2FromHash",
"[%" PRIuz
"] test failed", x);