1 | /***************************************************************************
|
---|
2 | * _ _ ____ _
|
---|
3 | * Project ___| | | | _ \| |
|
---|
4 | * / __| | | | |_) | |
|
---|
5 | * | (__| |_| | _ <| |___
|
---|
6 | * \___|\___/|_| \_\_____|
|
---|
7 | *
|
---|
8 | * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
---|
9 | *
|
---|
10 | * This software is licensed as described in the file COPYING, which
|
---|
11 | * you should have received as part of this distribution. The terms
|
---|
12 | * are also available at https://curl.haxx.se/docs/copyright.html.
|
---|
13 | *
|
---|
14 | * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
---|
15 | * copies of the Software, and permit persons to whom the Software is
|
---|
16 | * furnished to do so, under the terms of the COPYING file.
|
---|
17 | *
|
---|
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
---|
19 | * KIND, either express or implied.
|
---|
20 | *
|
---|
21 | ***************************************************************************/
|
---|
22 |
|
---|
23 | #include "curl_setup.h"
|
---|
24 |
|
---|
25 | #if defined(USE_NTLM)
|
---|
26 |
|
---|
27 | /*
|
---|
28 | * NTLM details:
|
---|
29 | *
|
---|
30 | * http://davenport.sourceforge.net/ntlm.html
|
---|
31 | * http://www.innovation.ch/java/ntlm.html
|
---|
32 | */
|
---|
33 |
|
---|
34 | #if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
|
---|
35 |
|
---|
36 | #ifdef USE_OPENSSL
|
---|
37 |
|
---|
38 | # ifdef USE_OPENSSL
|
---|
39 | # include <openssl/des.h>
|
---|
40 | # ifndef OPENSSL_NO_MD4
|
---|
41 | # include <openssl/md4.h>
|
---|
42 | # endif
|
---|
43 | # include <openssl/md5.h>
|
---|
44 | # include <openssl/ssl.h>
|
---|
45 | # include <openssl/rand.h>
|
---|
46 | # else
|
---|
47 | # include <des.h>
|
---|
48 | # ifndef OPENSSL_NO_MD4
|
---|
49 | # include <md4.h>
|
---|
50 | # endif
|
---|
51 | # include <md5.h>
|
---|
52 | # include <ssl.h>
|
---|
53 | # include <rand.h>
|
---|
54 | # endif
|
---|
55 | # if (OPENSSL_VERSION_NUMBER < 0x00907001L)
|
---|
56 | # define DES_key_schedule des_key_schedule
|
---|
57 | # define DES_cblock des_cblock
|
---|
58 | # define DES_set_odd_parity des_set_odd_parity
|
---|
59 | # define DES_set_key des_set_key
|
---|
60 | # define DES_ecb_encrypt des_ecb_encrypt
|
---|
61 | # define DESKEY(x) x
|
---|
62 | # define DESKEYARG(x) x
|
---|
63 | # else
|
---|
64 | # define DESKEYARG(x) *x
|
---|
65 | # define DESKEY(x) &x
|
---|
66 | # endif
|
---|
67 |
|
---|
68 | #elif defined(USE_GNUTLS_NETTLE)
|
---|
69 |
|
---|
70 | # include <nettle/des.h>
|
---|
71 | # include <nettle/md4.h>
|
---|
72 |
|
---|
73 | #elif defined(USE_GNUTLS)
|
---|
74 |
|
---|
75 | # include <gcrypt.h>
|
---|
76 | # define MD5_DIGEST_LENGTH 16
|
---|
77 | # define MD4_DIGEST_LENGTH 16
|
---|
78 |
|
---|
79 | #elif defined(USE_NSS)
|
---|
80 |
|
---|
81 | # include <nss.h>
|
---|
82 | # include <pk11pub.h>
|
---|
83 | # include <hasht.h>
|
---|
84 | # include "curl_md4.h"
|
---|
85 | # define MD5_DIGEST_LENGTH MD5_LENGTH
|
---|
86 |
|
---|
87 | #elif defined(USE_DARWINSSL)
|
---|
88 |
|
---|
89 | # include <CommonCrypto/CommonCryptor.h>
|
---|
90 | # include <CommonCrypto/CommonDigest.h>
|
---|
91 |
|
---|
92 | #elif defined(USE_OS400CRYPTO)
|
---|
93 | # include "cipher.mih" /* mih/cipher */
|
---|
94 | # include "curl_md4.h"
|
---|
95 | #elif defined(USE_WIN32_CRYPTO)
|
---|
96 | # include <wincrypt.h>
|
---|
97 | #else
|
---|
98 | # error "Can't compile NTLM support without a crypto library."
|
---|
99 | #endif
|
---|
100 |
|
---|
101 | #include "urldata.h"
|
---|
102 | #include "non-ascii.h"
|
---|
103 | #include "rawstr.h"
|
---|
104 | #include "curl_ntlm_core.h"
|
---|
105 | #include "curl_md5.h"
|
---|
106 | #include "curl_hmac.h"
|
---|
107 | #include "warnless.h"
|
---|
108 | #include "curl_endian.h"
|
---|
109 | #include "curl_des.h"
|
---|
110 | #include "curl_printf.h"
|
---|
111 |
|
---|
112 | /* The last #include files should be: */
|
---|
113 | #include "curl_memory.h"
|
---|
114 | #include "memdebug.h"
|
---|
115 |
|
---|
116 | #define NTLM_HMAC_MD5_LEN (16)
|
---|
117 | #define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00"
|
---|
118 | #define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4)
|
---|
119 |
|
---|
120 | /*
|
---|
121 | * Turns a 56-bit key into being 64-bit wide.
|
---|
122 | */
|
---|
123 | static void extend_key_56_to_64(const unsigned char *key_56, char *key)
|
---|
124 | {
|
---|
125 | key[0] = key_56[0];
|
---|
126 | key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
|
---|
127 | key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
|
---|
128 | key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
|
---|
129 | key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
|
---|
130 | key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
|
---|
131 | key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
|
---|
132 | key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
|
---|
133 | }
|
---|
134 |
|
---|
135 | #ifdef USE_OPENSSL
|
---|
136 | /*
|
---|
137 | * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
|
---|
138 | * key schedule ks is also set.
|
---|
139 | */
|
---|
140 | static void setup_des_key(const unsigned char *key_56,
|
---|
141 | DES_key_schedule DESKEYARG(ks))
|
---|
142 | {
|
---|
143 | DES_cblock key;
|
---|
144 |
|
---|
145 | /* Expand the 56-bit key to 64-bits */
|
---|
146 | extend_key_56_to_64(key_56, (char *) key);
|
---|
147 |
|
---|
148 | /* Set the key parity to odd */
|
---|
149 | #ifndef HAVE_DES_SET_ODD_PARITY /* older boringssl */
|
---|
150 | Curl_des_set_odd_parity((unsigned char *) &key, sizeof(key));
|
---|
151 | #else
|
---|
152 | DES_set_odd_parity(&key);
|
---|
153 | #endif
|
---|
154 |
|
---|
155 | /* Set the key */
|
---|
156 | DES_set_key(&key, ks);
|
---|
157 | }
|
---|
158 |
|
---|
159 | #elif defined(USE_GNUTLS_NETTLE)
|
---|
160 |
|
---|
161 | static void setup_des_key(const unsigned char *key_56,
|
---|
162 | struct des_ctx *des)
|
---|
163 | {
|
---|
164 | char key[8];
|
---|
165 |
|
---|
166 | /* Expand the 56-bit key to 64-bits */
|
---|
167 | extend_key_56_to_64(key_56, key);
|
---|
168 |
|
---|
169 | /* Set the key parity to odd */
|
---|
170 | Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
---|
171 |
|
---|
172 | /* Set the key */
|
---|
173 | des_set_key(des, (const uint8_t *) key);
|
---|
174 | }
|
---|
175 |
|
---|
176 | #elif defined(USE_GNUTLS)
|
---|
177 |
|
---|
178 | /*
|
---|
179 | * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.
|
---|
180 | */
|
---|
181 | static void setup_des_key(const unsigned char *key_56,
|
---|
182 | gcry_cipher_hd_t *des)
|
---|
183 | {
|
---|
184 | char key[8];
|
---|
185 |
|
---|
186 | /* Expand the 56-bit key to 64-bits */
|
---|
187 | extend_key_56_to_64(key_56, key);
|
---|
188 |
|
---|
189 | /* Set the key parity to odd */
|
---|
190 | Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
---|
191 |
|
---|
192 | /* Set the key */
|
---|
193 | gcry_cipher_setkey(*des, key, sizeof(key));
|
---|
194 | }
|
---|
195 |
|
---|
196 | #elif defined(USE_NSS)
|
---|
197 |
|
---|
198 | /*
|
---|
199 | * Expands a 56 bit key KEY_56 to 64 bit and encrypts 64 bit of data, using
|
---|
200 | * the expanded key. The caller is responsible for giving 64 bit of valid
|
---|
201 | * data is IN and (at least) 64 bit large buffer as OUT.
|
---|
202 | */
|
---|
203 | static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
---|
204 | const unsigned char *key_56)
|
---|
205 | {
|
---|
206 | const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */
|
---|
207 | PK11SlotInfo *slot = NULL;
|
---|
208 | char key[8]; /* expanded 64 bit key */
|
---|
209 | SECItem key_item;
|
---|
210 | PK11SymKey *symkey = NULL;
|
---|
211 | SECItem *param = NULL;
|
---|
212 | PK11Context *ctx = NULL;
|
---|
213 | int out_len; /* not used, required by NSS */
|
---|
214 | bool rv = FALSE;
|
---|
215 |
|
---|
216 | /* use internal slot for DES encryption (requires NSS to be initialized) */
|
---|
217 | slot = PK11_GetInternalKeySlot();
|
---|
218 | if(!slot)
|
---|
219 | return FALSE;
|
---|
220 |
|
---|
221 | /* Expand the 56-bit key to 64-bits */
|
---|
222 | extend_key_56_to_64(key_56, key);
|
---|
223 |
|
---|
224 | /* Set the key parity to odd */
|
---|
225 | Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
---|
226 |
|
---|
227 | /* Import the key */
|
---|
228 | key_item.data = (unsigned char *)key;
|
---|
229 | key_item.len = sizeof(key);
|
---|
230 | symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT,
|
---|
231 | &key_item, NULL);
|
---|
232 | if(!symkey)
|
---|
233 | goto fail;
|
---|
234 |
|
---|
235 | /* Create the DES encryption context */
|
---|
236 | param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL);
|
---|
237 | if(!param)
|
---|
238 | goto fail;
|
---|
239 | ctx = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symkey, param);
|
---|
240 | if(!ctx)
|
---|
241 | goto fail;
|
---|
242 |
|
---|
243 | /* Perform the encryption */
|
---|
244 | if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8,
|
---|
245 | (unsigned char *)in, /* inbuflen */ 8)
|
---|
246 | && SECSuccess == PK11_Finalize(ctx))
|
---|
247 | rv = /* all OK */ TRUE;
|
---|
248 |
|
---|
249 | fail:
|
---|
250 | /* cleanup */
|
---|
251 | if(ctx)
|
---|
252 | PK11_DestroyContext(ctx, PR_TRUE);
|
---|
253 | if(symkey)
|
---|
254 | PK11_FreeSymKey(symkey);
|
---|
255 | if(param)
|
---|
256 | SECITEM_FreeItem(param, PR_TRUE);
|
---|
257 | PK11_FreeSlot(slot);
|
---|
258 | return rv;
|
---|
259 | }
|
---|
260 |
|
---|
261 | #elif defined(USE_DARWINSSL)
|
---|
262 |
|
---|
263 | static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
---|
264 | const unsigned char *key_56)
|
---|
265 | {
|
---|
266 | char key[8];
|
---|
267 | size_t out_len;
|
---|
268 | CCCryptorStatus err;
|
---|
269 |
|
---|
270 | /* Expand the 56-bit key to 64-bits */
|
---|
271 | extend_key_56_to_64(key_56, key);
|
---|
272 |
|
---|
273 | /* Set the key parity to odd */
|
---|
274 | Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
---|
275 |
|
---|
276 | /* Perform the encryption */
|
---|
277 | err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key,
|
---|
278 | kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out,
|
---|
279 | 8 /* outbuflen */, &out_len);
|
---|
280 |
|
---|
281 | return err == kCCSuccess;
|
---|
282 | }
|
---|
283 |
|
---|
284 | #elif defined(USE_OS400CRYPTO)
|
---|
285 |
|
---|
286 | static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
---|
287 | const unsigned char *key_56)
|
---|
288 | {
|
---|
289 | char key[8];
|
---|
290 | _CIPHER_Control_T ctl;
|
---|
291 |
|
---|
292 | /* Setup the cipher control structure */
|
---|
293 | ctl.Func_ID = ENCRYPT_ONLY;
|
---|
294 | ctl.Data_Len = sizeof(key);
|
---|
295 |
|
---|
296 | /* Expand the 56-bit key to 64-bits */
|
---|
297 | extend_key_56_to_64(key_56, ctl.Crypto_Key);
|
---|
298 |
|
---|
299 | /* Set the key parity to odd */
|
---|
300 | Curl_des_set_odd_parity((unsigned char *) ctl.Crypto_Key, ctl.Data_Len);
|
---|
301 |
|
---|
302 | /* Perform the encryption */
|
---|
303 | _CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in);
|
---|
304 |
|
---|
305 | return TRUE;
|
---|
306 | }
|
---|
307 |
|
---|
308 | #elif defined(USE_WIN32_CRYPTO)
|
---|
309 |
|
---|
310 | static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
---|
311 | const unsigned char *key_56)
|
---|
312 | {
|
---|
313 | HCRYPTPROV hprov;
|
---|
314 | HCRYPTKEY hkey;
|
---|
315 | struct {
|
---|
316 | BLOBHEADER hdr;
|
---|
317 | unsigned int len;
|
---|
318 | char key[8];
|
---|
319 | } blob;
|
---|
320 | DWORD len = 8;
|
---|
321 |
|
---|
322 | /* Acquire the crypto provider */
|
---|
323 | if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
|
---|
324 | CRYPT_VERIFYCONTEXT))
|
---|
325 | return FALSE;
|
---|
326 |
|
---|
327 | /* Setup the key blob structure */
|
---|
328 | memset(&blob, 0, sizeof(blob));
|
---|
329 | blob.hdr.bType = PLAINTEXTKEYBLOB;
|
---|
330 | blob.hdr.bVersion = 2;
|
---|
331 | blob.hdr.aiKeyAlg = CALG_DES;
|
---|
332 | blob.len = sizeof(blob.key);
|
---|
333 |
|
---|
334 | /* Expand the 56-bit key to 64-bits */
|
---|
335 | extend_key_56_to_64(key_56, blob.key);
|
---|
336 |
|
---|
337 | /* Set the key parity to odd */
|
---|
338 | Curl_des_set_odd_parity((unsigned char *) blob.key, sizeof(blob.key));
|
---|
339 |
|
---|
340 | /* Import the key */
|
---|
341 | if(!CryptImportKey(hprov, (BYTE *) &blob, sizeof(blob), 0, 0, &hkey)) {
|
---|
342 | CryptReleaseContext(hprov, 0);
|
---|
343 |
|
---|
344 | return FALSE;
|
---|
345 | }
|
---|
346 |
|
---|
347 | memcpy(out, in, 8);
|
---|
348 |
|
---|
349 | /* Perform the encryption */
|
---|
350 | CryptEncrypt(hkey, 0, FALSE, 0, out, &len, len);
|
---|
351 |
|
---|
352 | CryptDestroyKey(hkey);
|
---|
353 | CryptReleaseContext(hprov, 0);
|
---|
354 |
|
---|
355 | return TRUE;
|
---|
356 | }
|
---|
357 |
|
---|
358 | #endif /* defined(USE_WIN32_CRYPTO) */
|
---|
359 |
|
---|
360 | /*
|
---|
361 | * takes a 21 byte array and treats it as 3 56-bit DES keys. The
|
---|
362 | * 8 byte plaintext is encrypted with each key and the resulting 24
|
---|
363 | * bytes are stored in the results array.
|
---|
364 | */
|
---|
365 | void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
---|
366 | const unsigned char *plaintext,
|
---|
367 | unsigned char *results)
|
---|
368 | {
|
---|
369 | #ifdef USE_OPENSSL
|
---|
370 | DES_key_schedule ks;
|
---|
371 |
|
---|
372 | setup_des_key(keys, DESKEY(ks));
|
---|
373 | DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
|
---|
374 | DESKEY(ks), DES_ENCRYPT);
|
---|
375 |
|
---|
376 | setup_des_key(keys + 7, DESKEY(ks));
|
---|
377 | DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 8),
|
---|
378 | DESKEY(ks), DES_ENCRYPT);
|
---|
379 |
|
---|
380 | setup_des_key(keys + 14, DESKEY(ks));
|
---|
381 | DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16),
|
---|
382 | DESKEY(ks), DES_ENCRYPT);
|
---|
383 | #elif defined(USE_GNUTLS_NETTLE)
|
---|
384 | struct des_ctx des;
|
---|
385 | setup_des_key(keys, &des);
|
---|
386 | des_encrypt(&des, 8, results, plaintext);
|
---|
387 | setup_des_key(keys + 7, &des);
|
---|
388 | des_encrypt(&des, 8, results + 8, plaintext);
|
---|
389 | setup_des_key(keys + 14, &des);
|
---|
390 | des_encrypt(&des, 8, results + 16, plaintext);
|
---|
391 | #elif defined(USE_GNUTLS)
|
---|
392 | gcry_cipher_hd_t des;
|
---|
393 |
|
---|
394 | gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
---|
395 | setup_des_key(keys, &des);
|
---|
396 | gcry_cipher_encrypt(des, results, 8, plaintext, 8);
|
---|
397 | gcry_cipher_close(des);
|
---|
398 |
|
---|
399 | gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
---|
400 | setup_des_key(keys + 7, &des);
|
---|
401 | gcry_cipher_encrypt(des, results + 8, 8, plaintext, 8);
|
---|
402 | gcry_cipher_close(des);
|
---|
403 |
|
---|
404 | gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
---|
405 | setup_des_key(keys + 14, &des);
|
---|
406 | gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
|
---|
407 | gcry_cipher_close(des);
|
---|
408 | #elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
|
---|
409 | || defined(USE_WIN32_CRYPTO)
|
---|
410 | encrypt_des(plaintext, results, keys);
|
---|
411 | encrypt_des(plaintext, results + 8, keys + 7);
|
---|
412 | encrypt_des(plaintext, results + 16, keys + 14);
|
---|
413 | #endif
|
---|
414 | }
|
---|
415 |
|
---|
416 | /*
|
---|
417 | * Set up lanmanager hashed password
|
---|
418 | */
|
---|
419 | CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
|
---|
420 | const char *password,
|
---|
421 | unsigned char *lmbuffer /* 21 bytes */)
|
---|
422 | {
|
---|
423 | CURLcode result;
|
---|
424 | unsigned char pw[14];
|
---|
425 | static const unsigned char magic[] = {
|
---|
426 | 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
|
---|
427 | };
|
---|
428 | size_t len = CURLMIN(strlen(password), 14);
|
---|
429 |
|
---|
430 | Curl_strntoupper((char *)pw, password, len);
|
---|
431 | memset(&pw[len], 0, 14 - len);
|
---|
432 |
|
---|
433 | /*
|
---|
434 | * The LanManager hashed password needs to be created using the
|
---|
435 | * password in the network encoding not the host encoding.
|
---|
436 | */
|
---|
437 | result = Curl_convert_to_network(data, (char *)pw, 14);
|
---|
438 | if(result)
|
---|
439 | return result;
|
---|
440 |
|
---|
441 | {
|
---|
442 | /* Create LanManager hashed password. */
|
---|
443 |
|
---|
444 | #ifdef USE_OPENSSL
|
---|
445 | DES_key_schedule ks;
|
---|
446 |
|
---|
447 | setup_des_key(pw, DESKEY(ks));
|
---|
448 | DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
|
---|
449 | DESKEY(ks), DES_ENCRYPT);
|
---|
450 |
|
---|
451 | setup_des_key(pw + 7, DESKEY(ks));
|
---|
452 | DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8),
|
---|
453 | DESKEY(ks), DES_ENCRYPT);
|
---|
454 | #elif defined(USE_GNUTLS_NETTLE)
|
---|
455 | struct des_ctx des;
|
---|
456 | setup_des_key(pw, &des);
|
---|
457 | des_encrypt(&des, 8, lmbuffer, magic);
|
---|
458 | setup_des_key(pw + 7, &des);
|
---|
459 | des_encrypt(&des, 8, lmbuffer + 8, magic);
|
---|
460 | #elif defined(USE_GNUTLS)
|
---|
461 | gcry_cipher_hd_t des;
|
---|
462 |
|
---|
463 | gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
---|
464 | setup_des_key(pw, &des);
|
---|
465 | gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8);
|
---|
466 | gcry_cipher_close(des);
|
---|
467 |
|
---|
468 | gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
|
---|
469 | setup_des_key(pw + 7, &des);
|
---|
470 | gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
|
---|
471 | gcry_cipher_close(des);
|
---|
472 | #elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
|
---|
473 | || defined(USE_WIN32_CRYPTO)
|
---|
474 | encrypt_des(magic, lmbuffer, pw);
|
---|
475 | encrypt_des(magic, lmbuffer + 8, pw + 7);
|
---|
476 | #endif
|
---|
477 |
|
---|
478 | memset(lmbuffer + 16, 0, 21 - 16);
|
---|
479 | }
|
---|
480 |
|
---|
481 | return CURLE_OK;
|
---|
482 | }
|
---|
483 |
|
---|
484 | #if USE_NTRESPONSES
|
---|
485 | static void ascii_to_unicode_le(unsigned char *dest, const char *src,
|
---|
486 | size_t srclen)
|
---|
487 | {
|
---|
488 | size_t i;
|
---|
489 | for(i = 0; i < srclen; i++) {
|
---|
490 | dest[2 * i] = (unsigned char)src[i];
|
---|
491 | dest[2 * i + 1] = '\0';
|
---|
492 | }
|
---|
493 | }
|
---|
494 |
|
---|
495 | #if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
|
---|
496 |
|
---|
497 | static void ascii_uppercase_to_unicode_le(unsigned char *dest,
|
---|
498 | const char *src, size_t srclen)
|
---|
499 | {
|
---|
500 | size_t i;
|
---|
501 | for(i = 0; i < srclen; i++) {
|
---|
502 | dest[2 * i] = (unsigned char)(toupper(src[i]));
|
---|
503 | dest[2 * i + 1] = '\0';
|
---|
504 | }
|
---|
505 | }
|
---|
506 |
|
---|
507 | #endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
|
---|
508 |
|
---|
509 | /*
|
---|
510 | * Set up nt hashed passwords
|
---|
511 | * @unittest: 1600
|
---|
512 | */
|
---|
513 | CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
|
---|
514 | const char *password,
|
---|
515 | unsigned char *ntbuffer /* 21 bytes */)
|
---|
516 | {
|
---|
517 | size_t len = strlen(password);
|
---|
518 | unsigned char *pw = malloc(len * 2);
|
---|
519 | CURLcode result;
|
---|
520 | if(!pw)
|
---|
521 | return CURLE_OUT_OF_MEMORY;
|
---|
522 |
|
---|
523 | ascii_to_unicode_le(pw, password, len);
|
---|
524 |
|
---|
525 | /*
|
---|
526 | * The NT hashed password needs to be created using the password in the
|
---|
527 | * network encoding not the host encoding.
|
---|
528 | */
|
---|
529 | result = Curl_convert_to_network(data, (char *)pw, len * 2);
|
---|
530 | if(result)
|
---|
531 | return result;
|
---|
532 |
|
---|
533 | {
|
---|
534 | /* Create NT hashed password. */
|
---|
535 | #ifdef USE_OPENSSL
|
---|
536 | MD4_CTX MD4pw;
|
---|
537 | MD4_Init(&MD4pw);
|
---|
538 | MD4_Update(&MD4pw, pw, 2 * len);
|
---|
539 | MD4_Final(ntbuffer, &MD4pw);
|
---|
540 | #elif defined(USE_GNUTLS_NETTLE)
|
---|
541 | struct md4_ctx MD4pw;
|
---|
542 | md4_init(&MD4pw);
|
---|
543 | md4_update(&MD4pw, (unsigned int)(2 * len), pw);
|
---|
544 | md4_digest(&MD4pw, MD4_DIGEST_SIZE, ntbuffer);
|
---|
545 | #elif defined(USE_GNUTLS)
|
---|
546 | gcry_md_hd_t MD4pw;
|
---|
547 | gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);
|
---|
548 | gcry_md_write(MD4pw, pw, 2 * len);
|
---|
549 | memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH);
|
---|
550 | gcry_md_close(MD4pw);
|
---|
551 | #elif defined(USE_NSS) || defined(USE_OS400CRYPTO)
|
---|
552 | Curl_md4it(ntbuffer, pw, 2 * len);
|
---|
553 | #elif defined(USE_DARWINSSL)
|
---|
554 | (void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer);
|
---|
555 | #elif defined(USE_WIN32_CRYPTO)
|
---|
556 | HCRYPTPROV hprov;
|
---|
557 | if(CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
|
---|
558 | CRYPT_VERIFYCONTEXT)) {
|
---|
559 | HCRYPTHASH hhash;
|
---|
560 | if(CryptCreateHash(hprov, CALG_MD4, 0, 0, &hhash)) {
|
---|
561 | DWORD length = 16;
|
---|
562 | CryptHashData(hhash, pw, (unsigned int)len * 2, 0);
|
---|
563 | CryptGetHashParam(hhash, HP_HASHVAL, ntbuffer, &length, 0);
|
---|
564 | CryptDestroyHash(hhash);
|
---|
565 | }
|
---|
566 | CryptReleaseContext(hprov, 0);
|
---|
567 | }
|
---|
568 | #endif
|
---|
569 |
|
---|
570 | memset(ntbuffer + 16, 0, 21 - 16);
|
---|
571 | }
|
---|
572 |
|
---|
573 | free(pw);
|
---|
574 |
|
---|
575 | return CURLE_OK;
|
---|
576 | }
|
---|
577 |
|
---|
578 | #if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
|
---|
579 |
|
---|
580 | /* This returns the HMAC MD5 digest */
|
---|
581 | CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
|
---|
582 | const unsigned char *data, unsigned int datalen,
|
---|
583 | unsigned char *output)
|
---|
584 | {
|
---|
585 | HMAC_context *ctxt = Curl_HMAC_init(Curl_HMAC_MD5, key, keylen);
|
---|
586 |
|
---|
587 | if(!ctxt)
|
---|
588 | return CURLE_OUT_OF_MEMORY;
|
---|
589 |
|
---|
590 | /* Update the digest with the given challenge */
|
---|
591 | Curl_HMAC_update(ctxt, data, datalen);
|
---|
592 |
|
---|
593 | /* Finalise the digest */
|
---|
594 | Curl_HMAC_final(ctxt, output);
|
---|
595 |
|
---|
596 | return CURLE_OK;
|
---|
597 | }
|
---|
598 |
|
---|
599 | /* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
|
---|
600 | * (uppercase UserName + Domain) as the data
|
---|
601 | */
|
---|
602 | CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
|
---|
603 | const char *domain, size_t domlen,
|
---|
604 | unsigned char *ntlmhash,
|
---|
605 | unsigned char *ntlmv2hash)
|
---|
606 | {
|
---|
607 | /* Unicode representation */
|
---|
608 | size_t identity_len = (userlen + domlen) * 2;
|
---|
609 | unsigned char *identity = malloc(identity_len);
|
---|
610 | CURLcode result = CURLE_OK;
|
---|
611 |
|
---|
612 | if(!identity)
|
---|
613 | return CURLE_OUT_OF_MEMORY;
|
---|
614 |
|
---|
615 | ascii_uppercase_to_unicode_le(identity, user, userlen);
|
---|
616 | ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
|
---|
617 |
|
---|
618 | result = Curl_hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
|
---|
619 | ntlmv2hash);
|
---|
620 |
|
---|
621 | free(identity);
|
---|
622 |
|
---|
623 | return result;
|
---|
624 | }
|
---|
625 |
|
---|
626 | /*
|
---|
627 | * Curl_ntlm_core_mk_ntlmv2_resp()
|
---|
628 | *
|
---|
629 | * This creates the NTLMv2 response as set in the ntlm type-3 message.
|
---|
630 | *
|
---|
631 | * Parameters:
|
---|
632 | *
|
---|
633 | * ntlmv2hash [in] - The ntlmv2 hash (16 bytes)
|
---|
634 | * challenge_client [in] - The client nonce (8 bytes)
|
---|
635 | * ntlm [in] - The ntlm data struct being used to read TargetInfo
|
---|
636 | and Server challenge received in the type-2 message
|
---|
637 | * ntresp [out] - The address where a pointer to newly allocated
|
---|
638 | * memory holding the NTLMv2 response.
|
---|
639 | * ntresp_len [out] - The length of the output message.
|
---|
640 | *
|
---|
641 | * Returns CURLE_OK on success.
|
---|
642 | */
|
---|
643 | CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
---|
644 | unsigned char *challenge_client,
|
---|
645 | struct ntlmdata *ntlm,
|
---|
646 | unsigned char **ntresp,
|
---|
647 | unsigned int *ntresp_len)
|
---|
648 | {
|
---|
649 | /* NTLMv2 response structure :
|
---|
650 | ------------------------------------------------------------------------------
|
---|
651 | 0 HMAC MD5 16 bytes
|
---|
652 | ------BLOB--------------------------------------------------------------------
|
---|
653 | 16 Signature 0x01010000
|
---|
654 | 20 Reserved long (0x00000000)
|
---|
655 | 24 Timestamp LE, 64-bit signed value representing the number of
|
---|
656 | tenths of a microsecond since January 1, 1601.
|
---|
657 | 32 Client Nonce 8 bytes
|
---|
658 | 40 Unknown 4 bytes
|
---|
659 | 44 Target Info N bytes (from the type-2 message)
|
---|
660 | 44+N Unknown 4 bytes
|
---|
661 | ------------------------------------------------------------------------------
|
---|
662 | */
|
---|
663 |
|
---|
664 | unsigned int len = 0;
|
---|
665 | unsigned char *ptr = NULL;
|
---|
666 | unsigned char hmac_output[NTLM_HMAC_MD5_LEN];
|
---|
667 | curl_off_t tw;
|
---|
668 |
|
---|
669 | CURLcode result = CURLE_OK;
|
---|
670 |
|
---|
671 | #if CURL_SIZEOF_CURL_OFF_T < 8
|
---|
672 | #error "this section needs 64bit support to work"
|
---|
673 | #endif
|
---|
674 |
|
---|
675 | /* Calculate the timestamp */
|
---|
676 | #ifdef DEBUGBUILD
|
---|
677 | char *force_timestamp = getenv("CURL_FORCETIME");
|
---|
678 | if(force_timestamp)
|
---|
679 | tw = CURL_OFF_T_C(11644473600) * 10000000;
|
---|
680 | else
|
---|
681 | #endif
|
---|
682 | tw = ((curl_off_t)time(NULL) + CURL_OFF_T_C(11644473600)) * 10000000;
|
---|
683 |
|
---|
684 | /* Calculate the response len */
|
---|
685 | len = NTLM_HMAC_MD5_LEN + NTLMv2_BLOB_LEN;
|
---|
686 |
|
---|
687 | /* Allocate the response */
|
---|
688 | ptr = malloc(len);
|
---|
689 | if(!ptr)
|
---|
690 | return CURLE_OUT_OF_MEMORY;
|
---|
691 |
|
---|
692 | memset(ptr, 0, len);
|
---|
693 |
|
---|
694 | /* Create the BLOB structure */
|
---|
695 | snprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
|
---|
696 | NTLMv2_BLOB_SIGNATURE
|
---|
697 | "%c%c%c%c", /* Reserved = 0 */
|
---|
698 | 0, 0, 0, 0);
|
---|
699 |
|
---|
700 | Curl_write64_le(tw, ptr + 24);
|
---|
701 | memcpy(ptr + 32, challenge_client, 8);
|
---|
702 | memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len);
|
---|
703 |
|
---|
704 | /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
|
---|
705 | memcpy(ptr + 8, &ntlm->nonce[0], 8);
|
---|
706 | result = Curl_hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
|
---|
707 | NTLMv2_BLOB_LEN + 8, hmac_output);
|
---|
708 | if(result) {
|
---|
709 | free(ptr);
|
---|
710 | return result;
|
---|
711 | }
|
---|
712 |
|
---|
713 | /* Concatenate the HMAC MD5 output with the BLOB */
|
---|
714 | memcpy(ptr, hmac_output, NTLM_HMAC_MD5_LEN);
|
---|
715 |
|
---|
716 | /* Return the response */
|
---|
717 | *ntresp = ptr;
|
---|
718 | *ntresp_len = len;
|
---|
719 |
|
---|
720 | return result;
|
---|
721 | }
|
---|
722 |
|
---|
723 | /*
|
---|
724 | * Curl_ntlm_core_mk_lmv2_resp()
|
---|
725 | *
|
---|
726 | * This creates the LMv2 response as used in the ntlm type-3 message.
|
---|
727 | *
|
---|
728 | * Parameters:
|
---|
729 | *
|
---|
730 | * ntlmv2hash [in] - The ntlmv2 hash (16 bytes)
|
---|
731 | * challenge_client [in] - The client nonce (8 bytes)
|
---|
732 | * challenge_client [in] - The server challenge (8 bytes)
|
---|
733 | * lmresp [out] - The LMv2 response (24 bytes)
|
---|
734 | *
|
---|
735 | * Returns CURLE_OK on success.
|
---|
736 | */
|
---|
737 | CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
|
---|
738 | unsigned char *challenge_client,
|
---|
739 | unsigned char *challenge_server,
|
---|
740 | unsigned char *lmresp)
|
---|
741 | {
|
---|
742 | unsigned char data[16];
|
---|
743 | unsigned char hmac_output[16];
|
---|
744 | CURLcode result = CURLE_OK;
|
---|
745 |
|
---|
746 | memcpy(&data[0], challenge_server, 8);
|
---|
747 | memcpy(&data[8], challenge_client, 8);
|
---|
748 |
|
---|
749 | result = Curl_hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
|
---|
750 | if(result)
|
---|
751 | return result;
|
---|
752 |
|
---|
753 | /* Concatenate the HMAC MD5 output with the client nonce */
|
---|
754 | memcpy(lmresp, hmac_output, 16);
|
---|
755 | memcpy(lmresp+16, challenge_client, 8);
|
---|
756 |
|
---|
757 | return result;
|
---|
758 | }
|
---|
759 |
|
---|
760 | #endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
|
---|
761 |
|
---|
762 | #endif /* USE_NTRESPONSES */
|
---|
763 |
|
---|
764 | #endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
|
---|
765 |
|
---|
766 | #endif /* USE_NTLM */
|
---|