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