• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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