79aeb08b3fdc468639d98528e1f3542b294e951c
[platform/upstream/curl.git] / lib / curl_ntlm_core.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2012, 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 http://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) && !defined(USE_WINDOWS_SSPI)
26
27 /*
28  * NTLM details:
29  *
30  * http://davenport.sourceforge.net/ntlm.html
31  * http://www.innovation.ch/java/ntlm.html
32  */
33
34 #ifdef USE_SSLEAY
35
36 #  ifdef USE_OPENSSL
37 #    include <openssl/des.h>
38 #    ifndef OPENSSL_NO_MD4
39 #      include <openssl/md4.h>
40 #    endif
41 #    include <openssl/md5.h>
42 #    include <openssl/ssl.h>
43 #    include <openssl/rand.h>
44 #  else
45 #    include <des.h>
46 #    ifndef OPENSSL_NO_MD4
47 #      include <md4.h>
48 #    endif
49 #    include <md5.h>
50 #    include <ssl.h>
51 #    include <rand.h>
52 #  endif
53 #  if (OPENSSL_VERSION_NUMBER < 0x00907001L)
54 #    define DES_key_schedule des_key_schedule
55 #    define DES_cblock des_cblock
56 #    define DES_set_odd_parity des_set_odd_parity
57 #    define DES_set_key des_set_key
58 #    define DES_ecb_encrypt des_ecb_encrypt
59 #    define DESKEY(x) x
60 #    define DESKEYARG(x) x
61 #  else
62 #    define DESKEYARG(x) *x
63 #    define DESKEY(x) &x
64 #  endif
65
66 #elif defined(USE_GNUTLS_NETTLE)
67
68 #  include <nettle/des.h>
69 #  include <nettle/md4.h>
70
71 #elif defined(USE_GNUTLS)
72
73 #  include <gcrypt.h>
74 #  define MD5_DIGEST_LENGTH 16
75 #  define MD4_DIGEST_LENGTH 16
76
77 #elif defined(USE_NSS)
78
79 #  include <nss.h>
80 #  include <pk11pub.h>
81 #  include <hasht.h>
82 #  include "curl_md4.h"
83 #  define MD5_DIGEST_LENGTH MD5_LENGTH
84
85 #elif defined(USE_DARWINSSL)
86
87 #  include <CommonCrypto/CommonCryptor.h>
88 #  include <CommonCrypto/CommonDigest.h>
89
90 #else
91 #  error "Can't compile NTLM support without a crypto library."
92 #endif
93
94 #include "urldata.h"
95 #include "non-ascii.h"
96 #include "rawstr.h"
97 #include "curl_memory.h"
98 #include "curl_ntlm_core.h"
99
100 #define _MPRINTF_REPLACE /* use our functions only */
101 #include <curl/mprintf.h>
102
103 /* The last #include file should be: */
104 #include "memdebug.h"
105
106 #ifdef USE_SSLEAY
107 /*
108  * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.  The
109  * key schedule ks is also set.
110  */
111 static void setup_des_key(const unsigned char *key_56,
112                           DES_key_schedule DESKEYARG(ks))
113 {
114   DES_cblock key;
115
116   key[0] = key_56[0];
117   key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
118   key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
119   key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
120   key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
121   key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
122   key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
123   key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
124
125   DES_set_odd_parity(&key);
126   DES_set_key(&key, ks);
127 }
128
129 #else /* defined(USE_SSLEAY) */
130
131 /*
132  * Turns a 56 bit key into the 64 bit, odd parity key.  Used by GnuTLS and NSS.
133  */
134 static void extend_key_56_to_64(const unsigned char *key_56, char *key)
135 {
136   key[0] = key_56[0];
137   key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
138   key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
139   key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
140   key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
141   key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
142   key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
143   key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
144 }
145
146 #if defined(USE_GNUTLS_NETTLE)
147
148 static void setup_des_key(const unsigned char *key_56,
149                           struct des_ctx *des)
150 {
151   char key[8];
152   extend_key_56_to_64(key_56, key);
153   des_set_key(des, (const uint8_t*)key);
154 }
155
156 #elif defined(USE_GNUTLS)
157
158 /*
159  * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.
160  */
161 static void setup_des_key(const unsigned char *key_56,
162                           gcry_cipher_hd_t *des)
163 {
164   char key[8];
165   extend_key_56_to_64(key_56, key);
166   gcry_cipher_setkey(*des, key, 8);
167 }
168
169 #elif defined(USE_NSS)
170
171 /*
172  * Expands a 56 bit key KEY_56 to 64 bit and encrypts 64 bit of data, using
173  * the expanded key.  The caller is responsible for giving 64 bit of valid
174  * data is IN and (at least) 64 bit large buffer as OUT.
175  */
176 static bool encrypt_des(const unsigned char *in, unsigned char *out,
177                         const unsigned char *key_56)
178 {
179   const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */
180   PK11SlotInfo *slot = NULL;
181   char key[8];                                /* expanded 64 bit key */
182   SECItem key_item;
183   PK11SymKey *symkey = NULL;
184   SECItem *param = NULL;
185   PK11Context *ctx = NULL;
186   int out_len;                                /* not used, required by NSS */
187   bool rv = FALSE;
188
189   /* use internal slot for DES encryption (requires NSS to be initialized) */
190   slot = PK11_GetInternalKeySlot();
191   if(!slot)
192     return FALSE;
193
194   /* expand the 56 bit key to 64 bit and wrap by NSS */
195   extend_key_56_to_64(key_56, key);
196   key_item.data = (unsigned char *)key;
197   key_item.len = /* hard-wired */ 8;
198   symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT,
199                              &key_item, NULL);
200   if(!symkey)
201     goto fail;
202
203   /* create DES encryption context */
204   param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL);
205   if(!param)
206     goto fail;
207   ctx = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symkey, param);
208   if(!ctx)
209     goto fail;
210
211   /* perform the encryption */
212   if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8,
213                                  (unsigned char *)in, /* inbuflen */ 8)
214       && SECSuccess == PK11_Finalize(ctx))
215     rv = /* all OK */ TRUE;
216
217 fail:
218   /* cleanup */
219   if(ctx)
220     PK11_DestroyContext(ctx, PR_TRUE);
221   if(symkey)
222     PK11_FreeSymKey(symkey);
223   if(param)
224     SECITEM_FreeItem(param, PR_TRUE);
225   PK11_FreeSlot(slot);
226   return rv;
227 }
228
229 #elif defined(USE_DARWINSSL)
230
231 static bool encrypt_des(const unsigned char *in, unsigned char *out,
232                         const unsigned char *key_56)
233 {
234   char key[8];
235   size_t out_len;
236   CCCryptorStatus err;
237
238   extend_key_56_to_64(key_56, key);
239   err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key,
240                 kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out,
241                 8 /* outbuflen */, &out_len);
242   return err == kCCSuccess;
243 }
244
245 #endif /* defined(USE_DARWINSSL) */
246
247 #endif /* defined(USE_SSLEAY) */
248
249  /*
250   * takes a 21 byte array and treats it as 3 56-bit DES keys. The
251   * 8 byte plaintext is encrypted with each key and the resulting 24
252   * bytes are stored in the results array.
253   */
254 void Curl_ntlm_core_lm_resp(const unsigned char *keys,
255                             const unsigned char *plaintext,
256                             unsigned char *results)
257 {
258 #ifdef USE_SSLEAY
259   DES_key_schedule ks;
260
261   setup_des_key(keys, DESKEY(ks));
262   DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
263                   DESKEY(ks), DES_ENCRYPT);
264
265   setup_des_key(keys + 7, DESKEY(ks));
266   DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 8),
267                   DESKEY(ks), DES_ENCRYPT);
268
269   setup_des_key(keys + 14, DESKEY(ks));
270   DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16),
271                   DESKEY(ks), DES_ENCRYPT);
272 #elif defined(USE_GNUTLS_NETTLE)
273   struct des_ctx des;
274   setup_des_key(keys, &des);
275   des_encrypt(&des, 8, results, plaintext);
276   setup_des_key(keys + 7, &des);
277   des_encrypt(&des, 8, results + 8, plaintext);
278   setup_des_key(keys + 14, &des);
279   des_encrypt(&des, 8, results + 16, plaintext);
280 #elif defined(USE_GNUTLS)
281   gcry_cipher_hd_t des;
282
283   gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
284   setup_des_key(keys, &des);
285   gcry_cipher_encrypt(des, results, 8, plaintext, 8);
286   gcry_cipher_close(des);
287
288   gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
289   setup_des_key(keys + 7, &des);
290   gcry_cipher_encrypt(des, results + 8, 8, plaintext, 8);
291   gcry_cipher_close(des);
292
293   gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
294   setup_des_key(keys + 14, &des);
295   gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
296   gcry_cipher_close(des);
297 #elif defined(USE_NSS) || defined(USE_DARWINSSL)
298   encrypt_des(plaintext, results, keys);
299   encrypt_des(plaintext, results + 8, keys + 7);
300   encrypt_des(plaintext, results + 16, keys + 14);
301 #endif
302 }
303
304 /*
305  * Set up lanmanager hashed password
306  */
307 void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
308                                const char *password,
309                                unsigned char *lmbuffer /* 21 bytes */)
310 {
311   CURLcode res;
312   unsigned char pw[14];
313   static const unsigned char magic[] = {
314     0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
315   };
316   size_t len = CURLMIN(strlen(password), 14);
317
318   Curl_strntoupper((char *)pw, password, len);
319   memset(&pw[len], 0, 14 - len);
320
321   /*
322    * The LanManager hashed password needs to be created using the
323    * password in the network encoding not the host encoding.
324    */
325   res = Curl_convert_to_network(data, (char *)pw, 14);
326   if(res)
327     return;
328
329   {
330     /* Create LanManager hashed password. */
331
332 #ifdef USE_SSLEAY
333     DES_key_schedule ks;
334
335     setup_des_key(pw, DESKEY(ks));
336     DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
337                     DESKEY(ks), DES_ENCRYPT);
338
339     setup_des_key(pw + 7, DESKEY(ks));
340     DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8),
341                     DESKEY(ks), DES_ENCRYPT);
342 #elif defined(USE_GNUTLS_NETTLE)
343     struct des_ctx des;
344     setup_des_key(pw, &des);
345     des_encrypt(&des, 8, lmbuffer, magic);
346     setup_des_key(pw + 7, &des);
347     des_encrypt(&des, 8, lmbuffer + 8, magic);
348 #elif defined(USE_GNUTLS)
349     gcry_cipher_hd_t des;
350
351     gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
352     setup_des_key(pw, &des);
353     gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8);
354     gcry_cipher_close(des);
355
356     gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
357     setup_des_key(pw + 7, &des);
358     gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
359     gcry_cipher_close(des);
360 #elif defined(USE_NSS) || defined(USE_DARWINSSL)
361     encrypt_des(magic, lmbuffer, pw);
362     encrypt_des(magic, lmbuffer + 8, pw + 7);
363 #endif
364
365     memset(lmbuffer + 16, 0, 21 - 16);
366   }
367 }
368
369 #if USE_NTRESPONSES
370 static void ascii_to_unicode_le(unsigned char *dest, const char *src,
371                                 size_t srclen)
372 {
373   size_t i;
374   for(i = 0; i < srclen; i++) {
375     dest[2 * i] = (unsigned char)src[i];
376     dest[2 * i + 1] = '\0';
377   }
378 }
379
380 /*
381  * Set up nt hashed passwords
382  */
383 CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
384                                    const char *password,
385                                    unsigned char *ntbuffer /* 21 bytes */)
386 {
387   size_t len = strlen(password);
388   unsigned char *pw = malloc(len * 2);
389   CURLcode result;
390   if(!pw)
391     return CURLE_OUT_OF_MEMORY;
392
393   ascii_to_unicode_le(pw, password, len);
394
395   /*
396    * The NT hashed password needs to be created using the password in the
397    * network encoding not the host encoding.
398    */
399   result = Curl_convert_to_network(data, (char *)pw, len * 2);
400   if(result)
401     return result;
402
403   {
404     /* Create NT hashed password. */
405 #ifdef USE_SSLEAY
406     MD4_CTX MD4pw;
407     MD4_Init(&MD4pw);
408     MD4_Update(&MD4pw, pw, 2 * len);
409     MD4_Final(ntbuffer, &MD4pw);
410 #elif defined(USE_GNUTLS_NETTLE)
411     struct md4_ctx MD4pw;
412     md4_init(&MD4pw);
413     md4_update(&MD4pw, (unsigned int)(2 * len), pw);
414     md4_digest(&MD4pw, MD4_DIGEST_SIZE, ntbuffer);
415 #elif defined(USE_GNUTLS)
416     gcry_md_hd_t MD4pw;
417     gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);
418     gcry_md_write(MD4pw, pw, 2 * len);
419     memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH);
420     gcry_md_close(MD4pw);
421 #elif defined(USE_NSS)
422     Curl_md4it(ntbuffer, pw, 2 * len);
423 #elif defined(USE_DARWINSSL)
424     (void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer);
425 #endif
426
427     memset(ntbuffer + 16, 0, 21 - 16);
428   }
429
430   free(pw);
431
432   return CURLE_OK;
433 }
434 #endif /* USE_NTRESPONSES */
435
436 #endif /* USE_NTLM && !USE_WINDOWS_SSPI */