113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci 2513498266Sopenharmony_ci#include "curl_setup.h" 2613498266Sopenharmony_ci 2713498266Sopenharmony_ci#if defined(USE_CURL_NTLM_CORE) 2813498266Sopenharmony_ci 2913498266Sopenharmony_ci/* 3013498266Sopenharmony_ci * NTLM details: 3113498266Sopenharmony_ci * 3213498266Sopenharmony_ci * https://davenport.sourceforge.net/ntlm.html 3313498266Sopenharmony_ci * https://www.innovation.ch/java/ntlm.html 3413498266Sopenharmony_ci */ 3513498266Sopenharmony_ci 3613498266Sopenharmony_ci/* Please keep the SSL backend-specific #if branches in this order: 3713498266Sopenharmony_ci 3813498266Sopenharmony_ci 1. USE_OPENSSL 3913498266Sopenharmony_ci 2. USE_WOLFSSL 4013498266Sopenharmony_ci 3. USE_GNUTLS 4113498266Sopenharmony_ci 4. - 4213498266Sopenharmony_ci 5. USE_MBEDTLS 4313498266Sopenharmony_ci 6. USE_SECTRANSP 4413498266Sopenharmony_ci 7. USE_OS400CRYPTO 4513498266Sopenharmony_ci 8. USE_WIN32_CRYPTO 4613498266Sopenharmony_ci 4713498266Sopenharmony_ci This ensures that: 4813498266Sopenharmony_ci - the same SSL branch gets activated throughout this source 4913498266Sopenharmony_ci file even if multiple backends are enabled at the same time. 5013498266Sopenharmony_ci - OpenSSL has higher priority than Windows Crypt, due 5113498266Sopenharmony_ci to issues with the latter supporting NTLM2Session responses 5213498266Sopenharmony_ci in NTLM type-3 messages. 5313498266Sopenharmony_ci */ 5413498266Sopenharmony_ci 5513498266Sopenharmony_ci#if defined(USE_OPENSSL) 5613498266Sopenharmony_ci #include <openssl/opensslconf.h> 5713498266Sopenharmony_ci #if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_DEPRECATED_3_0) 5813498266Sopenharmony_ci #define USE_OPENSSL_DES 5913498266Sopenharmony_ci #endif 6013498266Sopenharmony_ci#endif 6113498266Sopenharmony_ci 6213498266Sopenharmony_ci#if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL) 6313498266Sopenharmony_ci 6413498266Sopenharmony_ci#if defined(USE_OPENSSL) 6513498266Sopenharmony_ci# include <openssl/des.h> 6613498266Sopenharmony_ci# include <openssl/md5.h> 6713498266Sopenharmony_ci# include <openssl/ssl.h> 6813498266Sopenharmony_ci# include <openssl/rand.h> 6913498266Sopenharmony_ci#else 7013498266Sopenharmony_ci# include <wolfssl/options.h> 7113498266Sopenharmony_ci# include <wolfssl/openssl/des.h> 7213498266Sopenharmony_ci# include <wolfssl/openssl/md5.h> 7313498266Sopenharmony_ci# include <wolfssl/openssl/ssl.h> 7413498266Sopenharmony_ci# include <wolfssl/openssl/rand.h> 7513498266Sopenharmony_ci#endif 7613498266Sopenharmony_ci 7713498266Sopenharmony_ci# if (defined(OPENSSL_VERSION_NUMBER) && \ 7813498266Sopenharmony_ci (OPENSSL_VERSION_NUMBER < 0x00907001L)) && !defined(USE_WOLFSSL) 7913498266Sopenharmony_ci# define DES_key_schedule des_key_schedule 8013498266Sopenharmony_ci# define DES_cblock des_cblock 8113498266Sopenharmony_ci# define DES_set_odd_parity des_set_odd_parity 8213498266Sopenharmony_ci# define DES_set_key des_set_key 8313498266Sopenharmony_ci# define DES_ecb_encrypt des_ecb_encrypt 8413498266Sopenharmony_ci# define DESKEY(x) x 8513498266Sopenharmony_ci# define DESKEYARG(x) x 8613498266Sopenharmony_ci# elif defined(OPENSSL_IS_AWSLC) 8713498266Sopenharmony_ci# define DES_set_key_unchecked (void)DES_set_key 8813498266Sopenharmony_ci# define DESKEYARG(x) *x 8913498266Sopenharmony_ci# define DESKEY(x) &x 9013498266Sopenharmony_ci# else 9113498266Sopenharmony_ci# define DESKEYARG(x) *x 9213498266Sopenharmony_ci# define DESKEY(x) &x 9313498266Sopenharmony_ci# endif 9413498266Sopenharmony_ci 9513498266Sopenharmony_ci#elif defined(USE_GNUTLS) 9613498266Sopenharmony_ci 9713498266Sopenharmony_ci# include <nettle/des.h> 9813498266Sopenharmony_ci 9913498266Sopenharmony_ci#elif defined(USE_MBEDTLS) 10013498266Sopenharmony_ci 10113498266Sopenharmony_ci# include <mbedtls/des.h> 10213498266Sopenharmony_ci 10313498266Sopenharmony_ci#elif defined(USE_SECTRANSP) 10413498266Sopenharmony_ci 10513498266Sopenharmony_ci# include <CommonCrypto/CommonCryptor.h> 10613498266Sopenharmony_ci# include <CommonCrypto/CommonDigest.h> 10713498266Sopenharmony_ci 10813498266Sopenharmony_ci#elif defined(USE_OS400CRYPTO) 10913498266Sopenharmony_ci# include "cipher.mih" /* mih/cipher */ 11013498266Sopenharmony_ci#elif defined(USE_WIN32_CRYPTO) 11113498266Sopenharmony_ci# include <wincrypt.h> 11213498266Sopenharmony_ci#else 11313498266Sopenharmony_ci# error "Can't compile NTLM support without a crypto library with DES." 11413498266Sopenharmony_ci# define CURL_NTLM_NOT_SUPPORTED 11513498266Sopenharmony_ci#endif 11613498266Sopenharmony_ci 11713498266Sopenharmony_ci#include "urldata.h" 11813498266Sopenharmony_ci#include "strcase.h" 11913498266Sopenharmony_ci#include "curl_ntlm_core.h" 12013498266Sopenharmony_ci#include "curl_md5.h" 12113498266Sopenharmony_ci#include "curl_hmac.h" 12213498266Sopenharmony_ci#include "warnless.h" 12313498266Sopenharmony_ci#include "curl_endian.h" 12413498266Sopenharmony_ci#include "curl_des.h" 12513498266Sopenharmony_ci#include "curl_md4.h" 12613498266Sopenharmony_ci/* The last 3 #include files should be in this order */ 12713498266Sopenharmony_ci#include "curl_printf.h" 12813498266Sopenharmony_ci#include "curl_memory.h" 12913498266Sopenharmony_ci#include "memdebug.h" 13013498266Sopenharmony_ci 13113498266Sopenharmony_ci#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00" 13213498266Sopenharmony_ci#define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4) 13313498266Sopenharmony_ci 13413498266Sopenharmony_ci#if !defined(CURL_NTLM_NOT_SUPPORTED) 13513498266Sopenharmony_ci/* 13613498266Sopenharmony_ci* Turns a 56-bit key into being 64-bit wide. 13713498266Sopenharmony_ci*/ 13813498266Sopenharmony_cistatic void extend_key_56_to_64(const unsigned char *key_56, char *key) 13913498266Sopenharmony_ci{ 14013498266Sopenharmony_ci key[0] = key_56[0]; 14113498266Sopenharmony_ci key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1)); 14213498266Sopenharmony_ci key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2)); 14313498266Sopenharmony_ci key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3)); 14413498266Sopenharmony_ci key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4)); 14513498266Sopenharmony_ci key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5)); 14613498266Sopenharmony_ci key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6)); 14713498266Sopenharmony_ci key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF); 14813498266Sopenharmony_ci} 14913498266Sopenharmony_ci#endif 15013498266Sopenharmony_ci 15113498266Sopenharmony_ci#if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL) 15213498266Sopenharmony_ci/* 15313498266Sopenharmony_ci * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The 15413498266Sopenharmony_ci * key schedule ks is also set. 15513498266Sopenharmony_ci */ 15613498266Sopenharmony_cistatic void setup_des_key(const unsigned char *key_56, 15713498266Sopenharmony_ci DES_key_schedule DESKEYARG(ks)) 15813498266Sopenharmony_ci{ 15913498266Sopenharmony_ci DES_cblock key; 16013498266Sopenharmony_ci 16113498266Sopenharmony_ci /* Expand the 56-bit key to 64-bits */ 16213498266Sopenharmony_ci extend_key_56_to_64(key_56, (char *) &key); 16313498266Sopenharmony_ci 16413498266Sopenharmony_ci /* Set the key parity to odd */ 16513498266Sopenharmony_ci DES_set_odd_parity(&key); 16613498266Sopenharmony_ci 16713498266Sopenharmony_ci /* Set the key */ 16813498266Sopenharmony_ci DES_set_key_unchecked(&key, ks); 16913498266Sopenharmony_ci} 17013498266Sopenharmony_ci 17113498266Sopenharmony_ci#elif defined(USE_GNUTLS) 17213498266Sopenharmony_ci 17313498266Sopenharmony_cistatic void setup_des_key(const unsigned char *key_56, 17413498266Sopenharmony_ci struct des_ctx *des) 17513498266Sopenharmony_ci{ 17613498266Sopenharmony_ci char key[8]; 17713498266Sopenharmony_ci 17813498266Sopenharmony_ci /* Expand the 56-bit key to 64-bits */ 17913498266Sopenharmony_ci extend_key_56_to_64(key_56, key); 18013498266Sopenharmony_ci 18113498266Sopenharmony_ci /* Set the key parity to odd */ 18213498266Sopenharmony_ci Curl_des_set_odd_parity((unsigned char *) key, sizeof(key)); 18313498266Sopenharmony_ci 18413498266Sopenharmony_ci /* Set the key */ 18513498266Sopenharmony_ci des_set_key(des, (const uint8_t *) key); 18613498266Sopenharmony_ci} 18713498266Sopenharmony_ci 18813498266Sopenharmony_ci#elif defined(USE_MBEDTLS) 18913498266Sopenharmony_ci 19013498266Sopenharmony_cistatic bool encrypt_des(const unsigned char *in, unsigned char *out, 19113498266Sopenharmony_ci const unsigned char *key_56) 19213498266Sopenharmony_ci{ 19313498266Sopenharmony_ci mbedtls_des_context ctx; 19413498266Sopenharmony_ci char key[8]; 19513498266Sopenharmony_ci 19613498266Sopenharmony_ci /* Expand the 56-bit key to 64-bits */ 19713498266Sopenharmony_ci extend_key_56_to_64(key_56, key); 19813498266Sopenharmony_ci 19913498266Sopenharmony_ci /* Set the key parity to odd */ 20013498266Sopenharmony_ci mbedtls_des_key_set_parity((unsigned char *) key); 20113498266Sopenharmony_ci 20213498266Sopenharmony_ci /* Perform the encryption */ 20313498266Sopenharmony_ci mbedtls_des_init(&ctx); 20413498266Sopenharmony_ci mbedtls_des_setkey_enc(&ctx, (unsigned char *) key); 20513498266Sopenharmony_ci return mbedtls_des_crypt_ecb(&ctx, in, out) == 0; 20613498266Sopenharmony_ci} 20713498266Sopenharmony_ci 20813498266Sopenharmony_ci#elif defined(USE_SECTRANSP) 20913498266Sopenharmony_ci 21013498266Sopenharmony_cistatic bool encrypt_des(const unsigned char *in, unsigned char *out, 21113498266Sopenharmony_ci const unsigned char *key_56) 21213498266Sopenharmony_ci{ 21313498266Sopenharmony_ci char key[8]; 21413498266Sopenharmony_ci size_t out_len; 21513498266Sopenharmony_ci CCCryptorStatus err; 21613498266Sopenharmony_ci 21713498266Sopenharmony_ci /* Expand the 56-bit key to 64-bits */ 21813498266Sopenharmony_ci extend_key_56_to_64(key_56, key); 21913498266Sopenharmony_ci 22013498266Sopenharmony_ci /* Set the key parity to odd */ 22113498266Sopenharmony_ci Curl_des_set_odd_parity((unsigned char *) key, sizeof(key)); 22213498266Sopenharmony_ci 22313498266Sopenharmony_ci /* Perform the encryption */ 22413498266Sopenharmony_ci err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key, 22513498266Sopenharmony_ci kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out, 22613498266Sopenharmony_ci 8 /* outbuflen */, &out_len); 22713498266Sopenharmony_ci 22813498266Sopenharmony_ci return err == kCCSuccess; 22913498266Sopenharmony_ci} 23013498266Sopenharmony_ci 23113498266Sopenharmony_ci#elif defined(USE_OS400CRYPTO) 23213498266Sopenharmony_ci 23313498266Sopenharmony_cistatic bool encrypt_des(const unsigned char *in, unsigned char *out, 23413498266Sopenharmony_ci const unsigned char *key_56) 23513498266Sopenharmony_ci{ 23613498266Sopenharmony_ci char key[8]; 23713498266Sopenharmony_ci _CIPHER_Control_T ctl; 23813498266Sopenharmony_ci 23913498266Sopenharmony_ci /* Setup the cipher control structure */ 24013498266Sopenharmony_ci ctl.Func_ID = ENCRYPT_ONLY; 24113498266Sopenharmony_ci ctl.Data_Len = sizeof(key); 24213498266Sopenharmony_ci 24313498266Sopenharmony_ci /* Expand the 56-bit key to 64-bits */ 24413498266Sopenharmony_ci extend_key_56_to_64(key_56, ctl.Crypto_Key); 24513498266Sopenharmony_ci 24613498266Sopenharmony_ci /* Set the key parity to odd */ 24713498266Sopenharmony_ci Curl_des_set_odd_parity((unsigned char *) ctl.Crypto_Key, ctl.Data_Len); 24813498266Sopenharmony_ci 24913498266Sopenharmony_ci /* Perform the encryption */ 25013498266Sopenharmony_ci _CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in); 25113498266Sopenharmony_ci 25213498266Sopenharmony_ci return TRUE; 25313498266Sopenharmony_ci} 25413498266Sopenharmony_ci 25513498266Sopenharmony_ci#elif defined(USE_WIN32_CRYPTO) 25613498266Sopenharmony_ci 25713498266Sopenharmony_cistatic bool encrypt_des(const unsigned char *in, unsigned char *out, 25813498266Sopenharmony_ci const unsigned char *key_56) 25913498266Sopenharmony_ci{ 26013498266Sopenharmony_ci HCRYPTPROV hprov; 26113498266Sopenharmony_ci HCRYPTKEY hkey; 26213498266Sopenharmony_ci struct { 26313498266Sopenharmony_ci BLOBHEADER hdr; 26413498266Sopenharmony_ci unsigned int len; 26513498266Sopenharmony_ci char key[8]; 26613498266Sopenharmony_ci } blob; 26713498266Sopenharmony_ci DWORD len = 8; 26813498266Sopenharmony_ci 26913498266Sopenharmony_ci /* Acquire the crypto provider */ 27013498266Sopenharmony_ci if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL, 27113498266Sopenharmony_ci CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) 27213498266Sopenharmony_ci return FALSE; 27313498266Sopenharmony_ci 27413498266Sopenharmony_ci /* Setup the key blob structure */ 27513498266Sopenharmony_ci memset(&blob, 0, sizeof(blob)); 27613498266Sopenharmony_ci blob.hdr.bType = PLAINTEXTKEYBLOB; 27713498266Sopenharmony_ci blob.hdr.bVersion = 2; 27813498266Sopenharmony_ci blob.hdr.aiKeyAlg = CALG_DES; 27913498266Sopenharmony_ci blob.len = sizeof(blob.key); 28013498266Sopenharmony_ci 28113498266Sopenharmony_ci /* Expand the 56-bit key to 64-bits */ 28213498266Sopenharmony_ci extend_key_56_to_64(key_56, blob.key); 28313498266Sopenharmony_ci 28413498266Sopenharmony_ci /* Set the key parity to odd */ 28513498266Sopenharmony_ci Curl_des_set_odd_parity((unsigned char *) blob.key, sizeof(blob.key)); 28613498266Sopenharmony_ci 28713498266Sopenharmony_ci /* Import the key */ 28813498266Sopenharmony_ci if(!CryptImportKey(hprov, (BYTE *) &blob, sizeof(blob), 0, 0, &hkey)) { 28913498266Sopenharmony_ci CryptReleaseContext(hprov, 0); 29013498266Sopenharmony_ci 29113498266Sopenharmony_ci return FALSE; 29213498266Sopenharmony_ci } 29313498266Sopenharmony_ci 29413498266Sopenharmony_ci memcpy(out, in, 8); 29513498266Sopenharmony_ci 29613498266Sopenharmony_ci /* Perform the encryption */ 29713498266Sopenharmony_ci CryptEncrypt(hkey, 0, FALSE, 0, out, &len, len); 29813498266Sopenharmony_ci 29913498266Sopenharmony_ci CryptDestroyKey(hkey); 30013498266Sopenharmony_ci CryptReleaseContext(hprov, 0); 30113498266Sopenharmony_ci 30213498266Sopenharmony_ci return TRUE; 30313498266Sopenharmony_ci} 30413498266Sopenharmony_ci 30513498266Sopenharmony_ci#endif /* defined(USE_WIN32_CRYPTO) */ 30613498266Sopenharmony_ci 30713498266Sopenharmony_ci /* 30813498266Sopenharmony_ci * takes a 21 byte array and treats it as 3 56-bit DES keys. The 30913498266Sopenharmony_ci * 8 byte plaintext is encrypted with each key and the resulting 24 31013498266Sopenharmony_ci * bytes are stored in the results array. 31113498266Sopenharmony_ci */ 31213498266Sopenharmony_civoid Curl_ntlm_core_lm_resp(const unsigned char *keys, 31313498266Sopenharmony_ci const unsigned char *plaintext, 31413498266Sopenharmony_ci unsigned char *results) 31513498266Sopenharmony_ci{ 31613498266Sopenharmony_ci#if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL) 31713498266Sopenharmony_ci DES_key_schedule ks; 31813498266Sopenharmony_ci 31913498266Sopenharmony_ci setup_des_key(keys, DESKEY(ks)); 32013498266Sopenharmony_ci DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results, 32113498266Sopenharmony_ci DESKEY(ks), DES_ENCRYPT); 32213498266Sopenharmony_ci 32313498266Sopenharmony_ci setup_des_key(keys + 7, DESKEY(ks)); 32413498266Sopenharmony_ci DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 8), 32513498266Sopenharmony_ci DESKEY(ks), DES_ENCRYPT); 32613498266Sopenharmony_ci 32713498266Sopenharmony_ci setup_des_key(keys + 14, DESKEY(ks)); 32813498266Sopenharmony_ci DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16), 32913498266Sopenharmony_ci DESKEY(ks), DES_ENCRYPT); 33013498266Sopenharmony_ci#elif defined(USE_GNUTLS) 33113498266Sopenharmony_ci struct des_ctx des; 33213498266Sopenharmony_ci setup_des_key(keys, &des); 33313498266Sopenharmony_ci des_encrypt(&des, 8, results, plaintext); 33413498266Sopenharmony_ci setup_des_key(keys + 7, &des); 33513498266Sopenharmony_ci des_encrypt(&des, 8, results + 8, plaintext); 33613498266Sopenharmony_ci setup_des_key(keys + 14, &des); 33713498266Sopenharmony_ci des_encrypt(&des, 8, results + 16, plaintext); 33813498266Sopenharmony_ci#elif defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ 33913498266Sopenharmony_ci || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) 34013498266Sopenharmony_ci encrypt_des(plaintext, results, keys); 34113498266Sopenharmony_ci encrypt_des(plaintext, results + 8, keys + 7); 34213498266Sopenharmony_ci encrypt_des(plaintext, results + 16, keys + 14); 34313498266Sopenharmony_ci#else 34413498266Sopenharmony_ci (void)keys; 34513498266Sopenharmony_ci (void)plaintext; 34613498266Sopenharmony_ci (void)results; 34713498266Sopenharmony_ci#endif 34813498266Sopenharmony_ci} 34913498266Sopenharmony_ci 35013498266Sopenharmony_ci/* 35113498266Sopenharmony_ci * Set up lanmanager hashed password 35213498266Sopenharmony_ci */ 35313498266Sopenharmony_ciCURLcode Curl_ntlm_core_mk_lm_hash(const char *password, 35413498266Sopenharmony_ci unsigned char *lmbuffer /* 21 bytes */) 35513498266Sopenharmony_ci{ 35613498266Sopenharmony_ci unsigned char pw[14]; 35713498266Sopenharmony_ci#if !defined(CURL_NTLM_NOT_SUPPORTED) 35813498266Sopenharmony_ci static const unsigned char magic[] = { 35913498266Sopenharmony_ci 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */ 36013498266Sopenharmony_ci }; 36113498266Sopenharmony_ci#endif 36213498266Sopenharmony_ci size_t len = CURLMIN(strlen(password), 14); 36313498266Sopenharmony_ci 36413498266Sopenharmony_ci Curl_strntoupper((char *)pw, password, len); 36513498266Sopenharmony_ci memset(&pw[len], 0, 14 - len); 36613498266Sopenharmony_ci 36713498266Sopenharmony_ci { 36813498266Sopenharmony_ci /* Create LanManager hashed password. */ 36913498266Sopenharmony_ci 37013498266Sopenharmony_ci#if defined(USE_OPENSSL_DES) || defined(USE_WOLFSSL) 37113498266Sopenharmony_ci DES_key_schedule ks; 37213498266Sopenharmony_ci 37313498266Sopenharmony_ci setup_des_key(pw, DESKEY(ks)); 37413498266Sopenharmony_ci DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer, 37513498266Sopenharmony_ci DESKEY(ks), DES_ENCRYPT); 37613498266Sopenharmony_ci 37713498266Sopenharmony_ci setup_des_key(pw + 7, DESKEY(ks)); 37813498266Sopenharmony_ci DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8), 37913498266Sopenharmony_ci DESKEY(ks), DES_ENCRYPT); 38013498266Sopenharmony_ci#elif defined(USE_GNUTLS) 38113498266Sopenharmony_ci struct des_ctx des; 38213498266Sopenharmony_ci setup_des_key(pw, &des); 38313498266Sopenharmony_ci des_encrypt(&des, 8, lmbuffer, magic); 38413498266Sopenharmony_ci setup_des_key(pw + 7, &des); 38513498266Sopenharmony_ci des_encrypt(&des, 8, lmbuffer + 8, magic); 38613498266Sopenharmony_ci#elif defined(USE_MBEDTLS) || defined(USE_SECTRANSP) \ 38713498266Sopenharmony_ci || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) 38813498266Sopenharmony_ci encrypt_des(magic, lmbuffer, pw); 38913498266Sopenharmony_ci encrypt_des(magic, lmbuffer + 8, pw + 7); 39013498266Sopenharmony_ci#endif 39113498266Sopenharmony_ci 39213498266Sopenharmony_ci memset(lmbuffer + 16, 0, 21 - 16); 39313498266Sopenharmony_ci } 39413498266Sopenharmony_ci 39513498266Sopenharmony_ci return CURLE_OK; 39613498266Sopenharmony_ci} 39713498266Sopenharmony_ci 39813498266Sopenharmony_cistatic void ascii_to_unicode_le(unsigned char *dest, const char *src, 39913498266Sopenharmony_ci size_t srclen) 40013498266Sopenharmony_ci{ 40113498266Sopenharmony_ci size_t i; 40213498266Sopenharmony_ci for(i = 0; i < srclen; i++) { 40313498266Sopenharmony_ci dest[2 * i] = (unsigned char)src[i]; 40413498266Sopenharmony_ci dest[2 * i + 1] = '\0'; 40513498266Sopenharmony_ci } 40613498266Sopenharmony_ci} 40713498266Sopenharmony_ci 40813498266Sopenharmony_ci#if !defined(USE_WINDOWS_SSPI) 40913498266Sopenharmony_ci 41013498266Sopenharmony_cistatic void ascii_uppercase_to_unicode_le(unsigned char *dest, 41113498266Sopenharmony_ci const char *src, size_t srclen) 41213498266Sopenharmony_ci{ 41313498266Sopenharmony_ci size_t i; 41413498266Sopenharmony_ci for(i = 0; i < srclen; i++) { 41513498266Sopenharmony_ci dest[2 * i] = (unsigned char)(Curl_raw_toupper(src[i])); 41613498266Sopenharmony_ci dest[2 * i + 1] = '\0'; 41713498266Sopenharmony_ci } 41813498266Sopenharmony_ci} 41913498266Sopenharmony_ci 42013498266Sopenharmony_ci#endif /* !USE_WINDOWS_SSPI */ 42113498266Sopenharmony_ci 42213498266Sopenharmony_ci/* 42313498266Sopenharmony_ci * Set up nt hashed passwords 42413498266Sopenharmony_ci * @unittest: 1600 42513498266Sopenharmony_ci */ 42613498266Sopenharmony_ciCURLcode Curl_ntlm_core_mk_nt_hash(const char *password, 42713498266Sopenharmony_ci unsigned char *ntbuffer /* 21 bytes */) 42813498266Sopenharmony_ci{ 42913498266Sopenharmony_ci size_t len = strlen(password); 43013498266Sopenharmony_ci unsigned char *pw; 43113498266Sopenharmony_ci CURLcode result; 43213498266Sopenharmony_ci if(len > SIZE_T_MAX/2) /* avoid integer overflow */ 43313498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 43413498266Sopenharmony_ci pw = len ? malloc(len * 2) : (unsigned char *)strdup(""); 43513498266Sopenharmony_ci if(!pw) 43613498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 43713498266Sopenharmony_ci 43813498266Sopenharmony_ci ascii_to_unicode_le(pw, password, len); 43913498266Sopenharmony_ci 44013498266Sopenharmony_ci /* Create NT hashed password. */ 44113498266Sopenharmony_ci result = Curl_md4it(ntbuffer, pw, 2 * len); 44213498266Sopenharmony_ci if(!result) 44313498266Sopenharmony_ci memset(ntbuffer + 16, 0, 21 - 16); 44413498266Sopenharmony_ci 44513498266Sopenharmony_ci free(pw); 44613498266Sopenharmony_ci 44713498266Sopenharmony_ci return result; 44813498266Sopenharmony_ci} 44913498266Sopenharmony_ci 45013498266Sopenharmony_ci#if !defined(USE_WINDOWS_SSPI) 45113498266Sopenharmony_ci 45213498266Sopenharmony_ci/* Timestamp in tenths of a microsecond since January 1, 1601 00:00:00 UTC. */ 45313498266Sopenharmony_cistruct ms_filetime { 45413498266Sopenharmony_ci unsigned int dwLowDateTime; 45513498266Sopenharmony_ci unsigned int dwHighDateTime; 45613498266Sopenharmony_ci}; 45713498266Sopenharmony_ci 45813498266Sopenharmony_ci/* Convert a time_t to an MS FILETIME (MS-DTYP section 2.3.3). */ 45913498266Sopenharmony_cistatic void time2filetime(struct ms_filetime *ft, time_t t) 46013498266Sopenharmony_ci{ 46113498266Sopenharmony_ci#if SIZEOF_TIME_T > 4 46213498266Sopenharmony_ci t = (t + CURL_OFF_T_C(11644473600)) * 10000000; 46313498266Sopenharmony_ci ft->dwLowDateTime = (unsigned int) (t & 0xFFFFFFFF); 46413498266Sopenharmony_ci ft->dwHighDateTime = (unsigned int) (t >> 32); 46513498266Sopenharmony_ci#else 46613498266Sopenharmony_ci unsigned int r, s; 46713498266Sopenharmony_ci unsigned int i; 46813498266Sopenharmony_ci 46913498266Sopenharmony_ci ft->dwLowDateTime = t & 0xFFFFFFFF; 47013498266Sopenharmony_ci ft->dwHighDateTime = 0; 47113498266Sopenharmony_ci 47213498266Sopenharmony_ci# ifndef HAVE_TIME_T_UNSIGNED 47313498266Sopenharmony_ci /* Extend sign if needed. */ 47413498266Sopenharmony_ci if(ft->dwLowDateTime & 0x80000000) 47513498266Sopenharmony_ci ft->dwHighDateTime = ~0; 47613498266Sopenharmony_ci# endif 47713498266Sopenharmony_ci 47813498266Sopenharmony_ci /* Bias seconds to Jan 1, 1601. 47913498266Sopenharmony_ci 134774 days = 11644473600 seconds = 0x2B6109100 */ 48013498266Sopenharmony_ci r = ft->dwLowDateTime; 48113498266Sopenharmony_ci ft->dwLowDateTime = (ft->dwLowDateTime + 0xB6109100U) & 0xFFFFFFFF; 48213498266Sopenharmony_ci ft->dwHighDateTime += ft->dwLowDateTime < r? 0x03: 0x02; 48313498266Sopenharmony_ci 48413498266Sopenharmony_ci /* Convert to tenths of microseconds. */ 48513498266Sopenharmony_ci ft->dwHighDateTime *= 10000000; 48613498266Sopenharmony_ci i = 32; 48713498266Sopenharmony_ci do { 48813498266Sopenharmony_ci i -= 8; 48913498266Sopenharmony_ci s = ((ft->dwLowDateTime >> i) & 0xFF) * (10000000 - 1); 49013498266Sopenharmony_ci r = (s << i) & 0xFFFFFFFF; 49113498266Sopenharmony_ci s >>= 1; /* Split shift to avoid width overflow. */ 49213498266Sopenharmony_ci s >>= 31 - i; 49313498266Sopenharmony_ci ft->dwLowDateTime = (ft->dwLowDateTime + r) & 0xFFFFFFFF; 49413498266Sopenharmony_ci if(ft->dwLowDateTime < r) 49513498266Sopenharmony_ci s++; 49613498266Sopenharmony_ci ft->dwHighDateTime += s; 49713498266Sopenharmony_ci } while(i); 49813498266Sopenharmony_ci ft->dwHighDateTime &= 0xFFFFFFFF; 49913498266Sopenharmony_ci#endif 50013498266Sopenharmony_ci} 50113498266Sopenharmony_ci 50213498266Sopenharmony_ci/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode 50313498266Sopenharmony_ci * (uppercase UserName + Domain) as the data 50413498266Sopenharmony_ci */ 50513498266Sopenharmony_ciCURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen, 50613498266Sopenharmony_ci const char *domain, size_t domlen, 50713498266Sopenharmony_ci unsigned char *ntlmhash, 50813498266Sopenharmony_ci unsigned char *ntlmv2hash) 50913498266Sopenharmony_ci{ 51013498266Sopenharmony_ci /* Unicode representation */ 51113498266Sopenharmony_ci size_t identity_len; 51213498266Sopenharmony_ci unsigned char *identity; 51313498266Sopenharmony_ci CURLcode result = CURLE_OK; 51413498266Sopenharmony_ci 51513498266Sopenharmony_ci if((userlen > CURL_MAX_INPUT_LENGTH) || (domlen > CURL_MAX_INPUT_LENGTH)) 51613498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 51713498266Sopenharmony_ci 51813498266Sopenharmony_ci identity_len = (userlen + domlen) * 2; 51913498266Sopenharmony_ci identity = malloc(identity_len + 1); 52013498266Sopenharmony_ci 52113498266Sopenharmony_ci if(!identity) 52213498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 52313498266Sopenharmony_ci 52413498266Sopenharmony_ci ascii_uppercase_to_unicode_le(identity, user, userlen); 52513498266Sopenharmony_ci ascii_to_unicode_le(identity + (userlen << 1), domain, domlen); 52613498266Sopenharmony_ci 52713498266Sopenharmony_ci result = Curl_hmacit(Curl_HMAC_MD5, ntlmhash, 16, identity, identity_len, 52813498266Sopenharmony_ci ntlmv2hash); 52913498266Sopenharmony_ci free(identity); 53013498266Sopenharmony_ci 53113498266Sopenharmony_ci return result; 53213498266Sopenharmony_ci} 53313498266Sopenharmony_ci 53413498266Sopenharmony_ci/* 53513498266Sopenharmony_ci * Curl_ntlm_core_mk_ntlmv2_resp() 53613498266Sopenharmony_ci * 53713498266Sopenharmony_ci * This creates the NTLMv2 response as set in the ntlm type-3 message. 53813498266Sopenharmony_ci * 53913498266Sopenharmony_ci * Parameters: 54013498266Sopenharmony_ci * 54113498266Sopenharmony_ci * ntlmv2hash [in] - The ntlmv2 hash (16 bytes) 54213498266Sopenharmony_ci * challenge_client [in] - The client nonce (8 bytes) 54313498266Sopenharmony_ci * ntlm [in] - The ntlm data struct being used to read TargetInfo 54413498266Sopenharmony_ci and Server challenge received in the type-2 message 54513498266Sopenharmony_ci * ntresp [out] - The address where a pointer to newly allocated 54613498266Sopenharmony_ci * memory holding the NTLMv2 response. 54713498266Sopenharmony_ci * ntresp_len [out] - The length of the output message. 54813498266Sopenharmony_ci * 54913498266Sopenharmony_ci * Returns CURLE_OK on success. 55013498266Sopenharmony_ci */ 55113498266Sopenharmony_ciCURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash, 55213498266Sopenharmony_ci unsigned char *challenge_client, 55313498266Sopenharmony_ci struct ntlmdata *ntlm, 55413498266Sopenharmony_ci unsigned char **ntresp, 55513498266Sopenharmony_ci unsigned int *ntresp_len) 55613498266Sopenharmony_ci{ 55713498266Sopenharmony_ci/* NTLMv2 response structure : 55813498266Sopenharmony_ci------------------------------------------------------------------------------ 55913498266Sopenharmony_ci0 HMAC MD5 16 bytes 56013498266Sopenharmony_ci------BLOB-------------------------------------------------------------------- 56113498266Sopenharmony_ci16 Signature 0x01010000 56213498266Sopenharmony_ci20 Reserved long (0x00000000) 56313498266Sopenharmony_ci24 Timestamp LE, 64-bit signed value representing the number of 56413498266Sopenharmony_ci tenths of a microsecond since January 1, 1601. 56513498266Sopenharmony_ci32 Client Nonce 8 bytes 56613498266Sopenharmony_ci40 Unknown 4 bytes 56713498266Sopenharmony_ci44 Target Info N bytes (from the type-2 message) 56813498266Sopenharmony_ci44+N Unknown 4 bytes 56913498266Sopenharmony_ci------------------------------------------------------------------------------ 57013498266Sopenharmony_ci*/ 57113498266Sopenharmony_ci 57213498266Sopenharmony_ci unsigned int len = 0; 57313498266Sopenharmony_ci unsigned char *ptr = NULL; 57413498266Sopenharmony_ci unsigned char hmac_output[HMAC_MD5_LENGTH]; 57513498266Sopenharmony_ci struct ms_filetime tw; 57613498266Sopenharmony_ci 57713498266Sopenharmony_ci CURLcode result = CURLE_OK; 57813498266Sopenharmony_ci 57913498266Sopenharmony_ci /* Calculate the timestamp */ 58013498266Sopenharmony_ci#ifdef DEBUGBUILD 58113498266Sopenharmony_ci char *force_timestamp = getenv("CURL_FORCETIME"); 58213498266Sopenharmony_ci if(force_timestamp) 58313498266Sopenharmony_ci time2filetime(&tw, (time_t) 0); 58413498266Sopenharmony_ci else 58513498266Sopenharmony_ci#endif 58613498266Sopenharmony_ci time2filetime(&tw, time(NULL)); 58713498266Sopenharmony_ci 58813498266Sopenharmony_ci /* Calculate the response len */ 58913498266Sopenharmony_ci len = HMAC_MD5_LENGTH + NTLMv2_BLOB_LEN; 59013498266Sopenharmony_ci 59113498266Sopenharmony_ci /* Allocate the response */ 59213498266Sopenharmony_ci ptr = calloc(1, len); 59313498266Sopenharmony_ci if(!ptr) 59413498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 59513498266Sopenharmony_ci 59613498266Sopenharmony_ci /* Create the BLOB structure */ 59713498266Sopenharmony_ci msnprintf((char *)ptr + HMAC_MD5_LENGTH, NTLMv2_BLOB_LEN, 59813498266Sopenharmony_ci "%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */ 59913498266Sopenharmony_ci "%c%c%c%c" /* Reserved = 0 */ 60013498266Sopenharmony_ci "%c%c%c%c%c%c%c%c", /* Timestamp */ 60113498266Sopenharmony_ci NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1], 60213498266Sopenharmony_ci NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3], 60313498266Sopenharmony_ci 0, 0, 0, 0, 60413498266Sopenharmony_ci LONGQUARTET(tw.dwLowDateTime), LONGQUARTET(tw.dwHighDateTime)); 60513498266Sopenharmony_ci 60613498266Sopenharmony_ci memcpy(ptr + 32, challenge_client, 8); 60713498266Sopenharmony_ci if(ntlm->target_info_len) 60813498266Sopenharmony_ci memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len); 60913498266Sopenharmony_ci 61013498266Sopenharmony_ci /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */ 61113498266Sopenharmony_ci memcpy(ptr + 8, &ntlm->nonce[0], 8); 61213498266Sopenharmony_ci result = Curl_hmacit(Curl_HMAC_MD5, ntlmv2hash, HMAC_MD5_LENGTH, ptr + 8, 61313498266Sopenharmony_ci NTLMv2_BLOB_LEN + 8, hmac_output); 61413498266Sopenharmony_ci if(result) { 61513498266Sopenharmony_ci free(ptr); 61613498266Sopenharmony_ci return result; 61713498266Sopenharmony_ci } 61813498266Sopenharmony_ci 61913498266Sopenharmony_ci /* Concatenate the HMAC MD5 output with the BLOB */ 62013498266Sopenharmony_ci memcpy(ptr, hmac_output, HMAC_MD5_LENGTH); 62113498266Sopenharmony_ci 62213498266Sopenharmony_ci /* Return the response */ 62313498266Sopenharmony_ci *ntresp = ptr; 62413498266Sopenharmony_ci *ntresp_len = len; 62513498266Sopenharmony_ci 62613498266Sopenharmony_ci return result; 62713498266Sopenharmony_ci} 62813498266Sopenharmony_ci 62913498266Sopenharmony_ci/* 63013498266Sopenharmony_ci * Curl_ntlm_core_mk_lmv2_resp() 63113498266Sopenharmony_ci * 63213498266Sopenharmony_ci * This creates the LMv2 response as used in the ntlm type-3 message. 63313498266Sopenharmony_ci * 63413498266Sopenharmony_ci * Parameters: 63513498266Sopenharmony_ci * 63613498266Sopenharmony_ci * ntlmv2hash [in] - The ntlmv2 hash (16 bytes) 63713498266Sopenharmony_ci * challenge_client [in] - The client nonce (8 bytes) 63813498266Sopenharmony_ci * challenge_client [in] - The server challenge (8 bytes) 63913498266Sopenharmony_ci * lmresp [out] - The LMv2 response (24 bytes) 64013498266Sopenharmony_ci * 64113498266Sopenharmony_ci * Returns CURLE_OK on success. 64213498266Sopenharmony_ci */ 64313498266Sopenharmony_ciCURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash, 64413498266Sopenharmony_ci unsigned char *challenge_client, 64513498266Sopenharmony_ci unsigned char *challenge_server, 64613498266Sopenharmony_ci unsigned char *lmresp) 64713498266Sopenharmony_ci{ 64813498266Sopenharmony_ci unsigned char data[16]; 64913498266Sopenharmony_ci unsigned char hmac_output[16]; 65013498266Sopenharmony_ci CURLcode result = CURLE_OK; 65113498266Sopenharmony_ci 65213498266Sopenharmony_ci memcpy(&data[0], challenge_server, 8); 65313498266Sopenharmony_ci memcpy(&data[8], challenge_client, 8); 65413498266Sopenharmony_ci 65513498266Sopenharmony_ci result = Curl_hmacit(Curl_HMAC_MD5, ntlmv2hash, 16, &data[0], 16, 65613498266Sopenharmony_ci hmac_output); 65713498266Sopenharmony_ci if(result) 65813498266Sopenharmony_ci return result; 65913498266Sopenharmony_ci 66013498266Sopenharmony_ci /* Concatenate the HMAC MD5 output with the client nonce */ 66113498266Sopenharmony_ci memcpy(lmresp, hmac_output, 16); 66213498266Sopenharmony_ci memcpy(lmresp + 16, challenge_client, 8); 66313498266Sopenharmony_ci 66413498266Sopenharmony_ci return result; 66513498266Sopenharmony_ci} 66613498266Sopenharmony_ci 66713498266Sopenharmony_ci#endif /* !USE_WINDOWS_SSPI */ 66813498266Sopenharmony_ci 66913498266Sopenharmony_ci#endif /* USE_CURL_NTLM_CORE */ 670