FreeRDP
Loading...
Searching...
No Matches
utils/ntlm.c
1
20#include <winpr/config.h>
21
22#include <winpr/ntlm.h>
23#include <winpr/assert.h>
24
25#include <winpr/crt.h>
26#include <winpr/crypto.h>
27
34BOOL NTOWFv1W(LPWSTR Password, UINT32 PasswordLength, BYTE* NtHash)
35{
36 if (!Password || !NtHash)
37 return FALSE;
38
39 if (!winpr_Digest(WINPR_MD_MD4, (BYTE*)Password, (size_t)PasswordLength, NtHash,
40 WINPR_MD4_DIGEST_LENGTH))
41 return FALSE;
42
43 return TRUE;
44}
45
46BOOL NTOWFv1A(LPSTR Password, UINT32 PasswordLength, BYTE* NtHash)
47{
48 LPWSTR PasswordW = NULL;
49 BOOL result = FALSE;
50 size_t pwdCharLength = 0;
51
52 if (!NtHash)
53 return FALSE;
54
55 PasswordW = ConvertUtf8NToWCharAlloc(Password, PasswordLength, &pwdCharLength);
56 if (!PasswordW)
57 return FALSE;
58
59 if (!NTOWFv1W(PasswordW, (UINT32)pwdCharLength * sizeof(WCHAR), NtHash))
60 goto out_fail;
61
62 result = TRUE;
63out_fail:
64 free(PasswordW);
65 return result;
66}
67
75BOOL NTOWFv2W(LPWSTR Password, UINT32 PasswordLength, LPWSTR User, UINT32 UserLength, LPWSTR Domain,
76 UINT32 DomainLength, BYTE* NtHash)
77{
78 BYTE NtHashV1[WINPR_MD5_DIGEST_LENGTH];
79
80 if ((!User) || (!Password) || (!NtHash))
81 return FALSE;
82
83 if (!NTOWFv1W(Password, PasswordLength, NtHashV1))
84 return FALSE;
85
86 return NTOWFv2FromHashW(NtHashV1, User, UserLength, Domain, DomainLength, NtHash);
87}
88
89BOOL NTOWFv2A(LPSTR Password, UINT32 PasswordLength, LPSTR User, UINT32 UserLength, LPSTR Domain,
90 UINT32 DomainLength, BYTE* NtHash)
91{
92 LPWSTR UserW = NULL;
93 LPWSTR DomainW = NULL;
94 LPWSTR PasswordW = NULL;
95 BOOL result = FALSE;
96 size_t userCharLength = 0;
97 size_t domainCharLength = 0;
98 size_t pwdCharLength = 0;
99
100 if (!NtHash)
101 return FALSE;
102
103 UserW = ConvertUtf8NToWCharAlloc(User, UserLength, &userCharLength);
104 DomainW = ConvertUtf8NToWCharAlloc(Domain, DomainLength, &domainCharLength);
105 PasswordW = ConvertUtf8NToWCharAlloc(Password, PasswordLength, &pwdCharLength);
106
107 if (!UserW || !DomainW || !PasswordW)
108 goto out_fail;
109
110 if (!NTOWFv2W(PasswordW, (UINT32)pwdCharLength * sizeof(WCHAR), UserW,
111 (UINT32)userCharLength * sizeof(WCHAR), DomainW,
112 (UINT32)domainCharLength * sizeof(WCHAR), NtHash))
113 goto out_fail;
114
115 result = TRUE;
116out_fail:
117 free(UserW);
118 free(DomainW);
119 free(PasswordW);
120 return result;
121}
122
123BOOL NTOWFv2FromHashW(BYTE* NtHashV1, LPWSTR User, UINT32 UserLength, LPWSTR Domain,
124 UINT32 DomainLength, BYTE* NtHash)
125{
126 BYTE* buffer = NULL;
127 BYTE result = FALSE;
128
129 if (!User || !NtHash)
130 return FALSE;
131
132 if (!(buffer = (BYTE*)malloc(UserLength + DomainLength)))
133 return FALSE;
134
135 /* Concatenate(UpperCase(User), Domain) */
136 CopyMemory(buffer, User, UserLength);
137 CharUpperBuffW((LPWSTR)buffer, UserLength / 2);
138
139 if (DomainLength > 0)
140 {
141 CopyMemory(&buffer[UserLength], Domain, DomainLength);
142 }
143
144 /* Compute the HMAC-MD5 hash of the above value using the NTLMv1 hash as the key, the result is
145 * the NTLMv2 hash */
146 if (!winpr_HMAC(WINPR_MD_MD5, NtHashV1, 16, buffer, UserLength + DomainLength, NtHash,
147 WINPR_MD5_DIGEST_LENGTH))
148 goto out_fail;
149
150 result = TRUE;
151out_fail:
152 free(buffer);
153 return result;
154}
155
156BOOL NTOWFv2FromHashA(BYTE* NtHashV1, LPSTR User, UINT32 UserLength, LPSTR Domain,
157 UINT32 DomainLength, BYTE* NtHash)
158{
159 LPWSTR UserW = NULL;
160 LPWSTR DomainW = NULL;
161 BOOL result = FALSE;
162 size_t userCharLength = 0;
163 size_t domainCharLength = 0;
164 if (!NtHash)
165 return FALSE;
166
167 UserW = ConvertUtf8NToWCharAlloc(User, UserLength, &userCharLength);
168 DomainW = ConvertUtf8NToWCharAlloc(Domain, DomainLength, &domainCharLength);
169
170 if (!UserW || !DomainW)
171 goto out_fail;
172
173 if (!NTOWFv2FromHashW(NtHashV1, UserW, (UINT32)userCharLength * sizeof(WCHAR), DomainW,
174 (UINT32)domainCharLength * sizeof(WCHAR), NtHash))
175 goto out_fail;
176
177 result = TRUE;
178out_fail:
179 free(UserW);
180 free(DomainW);
181 return result;
182}