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