summaryrefslogtreecommitdiffstats
path: root/lib/curl_ntlm_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/curl_ntlm_core.c')
-rw-r--r--lib/curl_ntlm_core.c145
1 files changed, 69 insertions, 76 deletions
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index 9a075ac..89d4ec8 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -34,13 +34,12 @@
/* Please keep the SSL backend-specific #if branches in this order:
1. USE_OPENSSL
- 2. USE_GNUTLS_NETTLE
- 3. USE_GNUTLS
- 4. USE_NSS
- 5. USE_MBEDTLS
- 6. USE_SECTRANSP
- 7. USE_OS400CRYPTO
- 8. USE_WIN32_CRYPTO
+ 2. USE_GNUTLS
+ 3. USE_NSS
+ 4. USE_MBEDTLS
+ 5. USE_SECTRANSP
+ 6. USE_OS400CRYPTO
+ 7. USE_WIN32_CRYPTO
This ensures that:
- the same SSL branch gets activated throughout this source
@@ -74,13 +73,9 @@
# define DESKEY(x) &x
# endif
-#elif defined(USE_GNUTLS_NETTLE)
-
-# include <nettle/des.h>
-
#elif defined(USE_GNUTLS)
-# include <gcrypt.h>
+# include <nettle/des.h>
#elif defined(USE_NSS)
@@ -159,7 +154,7 @@ static void setup_des_key(const unsigned char *key_56,
DES_set_key(&key, ks);
}
-#elif defined(USE_GNUTLS_NETTLE)
+#elif defined(USE_GNUTLS)
static void setup_des_key(const unsigned char *key_56,
struct des_ctx *des)
@@ -176,26 +171,6 @@ static void setup_des_key(const unsigned char *key_56,
des_set_key(des, (const uint8_t *) key);
}
-#elif defined(USE_GNUTLS)
-
-/*
- * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.
- */
-static void setup_des_key(const unsigned char *key_56,
- gcry_cipher_hd_t *des)
-{
- char key[8];
-
- /* Expand the 56-bit key to 64-bits */
- extend_key_56_to_64(key_56, key);
-
- /* Set the key parity to odd */
- Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
-
- /* Set the key */
- gcry_cipher_setkey(*des, key, sizeof(key));
-}
-
#elif defined(USE_NSS)
/*
@@ -402,7 +377,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
setup_des_key(keys + 14, DESKEY(ks));
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16),
DESKEY(ks), DES_ENCRYPT);
-#elif defined(USE_GNUTLS_NETTLE)
+#elif defined(USE_GNUTLS)
struct des_ctx des;
setup_des_key(keys, &des);
des_encrypt(&des, 8, results, plaintext);
@@ -410,23 +385,6 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
des_encrypt(&des, 8, results + 8, plaintext);
setup_des_key(keys + 14, &des);
des_encrypt(&des, 8, results + 16, plaintext);
-#elif defined(USE_GNUTLS)
- gcry_cipher_hd_t des;
-
- gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
- setup_des_key(keys, &des);
- gcry_cipher_encrypt(des, results, 8, plaintext, 8);
- gcry_cipher_close(des);
-
- gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
- setup_des_key(keys + 7, &des);
- gcry_cipher_encrypt(des, results + 8, 8, plaintext, 8);
- gcry_cipher_close(des);
-
- gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
- setup_des_key(keys + 14, &des);
- gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
- gcry_cipher_close(des);
#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
encrypt_des(plaintext, results, keys);
@@ -473,24 +431,12 @@ CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
setup_des_key(pw + 7, DESKEY(ks));
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8),
DESKEY(ks), DES_ENCRYPT);
-#elif defined(USE_GNUTLS_NETTLE)
+#elif defined(USE_GNUTLS)
struct des_ctx des;
setup_des_key(pw, &des);
des_encrypt(&des, 8, lmbuffer, magic);
setup_des_key(pw + 7, &des);
des_encrypt(&des, 8, lmbuffer + 8, magic);
-#elif defined(USE_GNUTLS)
- gcry_cipher_hd_t des;
-
- gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
- setup_des_key(pw, &des);
- gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8);
- gcry_cipher_close(des);
-
- gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
- setup_des_key(pw + 7, &des);
- gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
- gcry_cipher_close(des);
#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \
|| defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
encrypt_des(magic, lmbuffer, pw);
@@ -567,6 +513,56 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
+/* Timestamp in tenths of a microsecond since January 1, 1601 00:00:00 UTC. */
+struct ms_filetime {
+ unsigned int dwLowDateTime;
+ unsigned int dwHighDateTime;
+};
+
+/* Convert a time_t to an MS FILETIME (MS-DTYP section 2.3.3). */
+static void time2filetime(struct ms_filetime *ft, time_t t)
+{
+#if SIZEOF_TIME_T > 4
+ t = (t + CURL_OFF_T_C(11644473600)) * 10000000;
+ ft->dwLowDateTime = (unsigned int) (t & 0xFFFFFFFF);
+ ft->dwHighDateTime = (unsigned int) (t >> 32);
+#else
+ unsigned int r, s;
+ unsigned int i;
+
+ ft->dwLowDateTime = t & 0xFFFFFFFF;
+ ft->dwHighDateTime = 0;
+
+# ifndef HAVE_TIME_T_UNSIGNED
+ /* Extend sign if needed. */
+ if(ft->dwLowDateTime & 0x80000000)
+ ft->dwHighDateTime = ~0;
+# endif
+
+ /* Bias seconds to Jan 1, 1601.
+ 134774 days = 11644473600 seconds = 0x2B6109100 */
+ r = ft->dwLowDateTime;
+ ft->dwLowDateTime = (ft->dwLowDateTime + 0xB6109100U) & 0xFFFFFFFF;
+ ft->dwHighDateTime += ft->dwLowDateTime < r? 0x03: 0x02;
+
+ /* Convert to tenths of microseconds. */
+ ft->dwHighDateTime *= 10000000;
+ i = 32;
+ do {
+ i -= 8;
+ s = ((ft->dwLowDateTime >> i) & 0xFF) * (10000000 - 1);
+ r = (s << i) & 0xFFFFFFFF;
+ s >>= 1; /* Split shift to avoid width overflow. */
+ s >>= 31 - i;
+ ft->dwLowDateTime = (ft->dwLowDateTime + r) & 0xFFFFFFFF;
+ if(ft->dwLowDateTime < r)
+ s++;
+ ft->dwHighDateTime += s;
+ } while(i);
+ ft->dwHighDateTime &= 0xFFFFFFFF;
+#endif
+}
+
/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
* (uppercase UserName + Domain) as the data
*/
@@ -640,22 +636,18 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
unsigned int len = 0;
unsigned char *ptr = NULL;
unsigned char hmac_output[HMAC_MD5_LENGTH];
- curl_off_t tw;
+ struct ms_filetime tw;
CURLcode result = CURLE_OK;
-#if CURL_SIZEOF_CURL_OFF_T < 8
-#error "this section needs 64bit support to work"
-#endif
-
/* Calculate the timestamp */
#ifdef DEBUGBUILD
char *force_timestamp = getenv("CURL_FORCETIME");
if(force_timestamp)
- tw = CURL_OFF_T_C(11644473600) * 10000000;
+ time2filetime(&tw, (time_t) 0);
else
#endif
- tw = ((curl_off_t)time(NULL) + CURL_OFF_T_C(11644473600)) * 10000000;
+ time2filetime(&tw, time(NULL));
/* Calculate the response len */
len = HMAC_MD5_LENGTH + NTLMv2_BLOB_LEN;
@@ -667,13 +659,14 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
/* Create the BLOB structure */
msnprintf((char *)ptr + HMAC_MD5_LENGTH, NTLMv2_BLOB_LEN,
- "%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
- "%c%c%c%c", /* Reserved = 0 */
+ "%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
+ "%c%c%c%c" /* Reserved = 0 */
+ "%c%c%c%c%c%c%c%c", /* Timestamp */
NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
- 0, 0, 0, 0);
+ 0, 0, 0, 0,
+ LONGQUARTET(tw.dwLowDateTime), LONGQUARTET(tw.dwHighDateTime));
- Curl_write64_le(tw, ptr + 24);
memcpy(ptr + 32, challenge_client, 8);
memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len);