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