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