1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker // Based on [MS-NLMP]: NT LAN Manager (NTLM) Authentication Protocol 6*6777b538SAndroid Build Coastguard Worker // Specification version 28.0 [1], an unofficial NTLM reference [2], and a 7*6777b538SAndroid Build Coastguard Worker // blog post describing Extended Protection for Authentication [3]. 8*6777b538SAndroid Build Coastguard Worker // 9*6777b538SAndroid Build Coastguard Worker // [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx 10*6777b538SAndroid Build Coastguard Worker // [2] http://davenport.sourceforge.net/ntlm.html 11*6777b538SAndroid Build Coastguard Worker // [3] 12*6777b538SAndroid Build Coastguard Worker // https://blogs.msdn.microsoft.com/openspecification/2013/03/26/ntlm-and-channel-binding-hash-aka-extended-protection-for-authentication/ 13*6777b538SAndroid Build Coastguard Worker 14*6777b538SAndroid Build Coastguard Worker #ifndef NET_NTLM_NTLM_CLIENT_H_ 15*6777b538SAndroid Build Coastguard Worker #define NET_NTLM_NTLM_CLIENT_H_ 16*6777b538SAndroid Build Coastguard Worker 17*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 18*6777b538SAndroid Build Coastguard Worker #include <stdint.h> 19*6777b538SAndroid Build Coastguard Worker 20*6777b538SAndroid Build Coastguard Worker #include <memory> 21*6777b538SAndroid Build Coastguard Worker #include <string> 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker #include "base/check.h" 24*6777b538SAndroid Build Coastguard Worker #include "base/containers/span.h" 25*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_piece.h" 26*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h" 27*6777b538SAndroid Build Coastguard Worker #include "net/ntlm/ntlm_constants.h" 28*6777b538SAndroid Build Coastguard Worker 29*6777b538SAndroid Build Coastguard Worker namespace net::ntlm { 30*6777b538SAndroid Build Coastguard Worker 31*6777b538SAndroid Build Coastguard Worker // Provides an implementation of an NTLMv1 or NTLMv2 Client with support 32*6777b538SAndroid Build Coastguard Worker // for MIC and EPA [1]. This implementation does not support the key exchange, 33*6777b538SAndroid Build Coastguard Worker // signing or sealing feature as the NTLMSSP_NEGOTIATE_KEY_EXCH flag is never 34*6777b538SAndroid Build Coastguard Worker // negotiated. 35*6777b538SAndroid Build Coastguard Worker // 36*6777b538SAndroid Build Coastguard Worker // [1] - 37*6777b538SAndroid Build Coastguard Worker // https://support.microsoft.com/en-us/help/968389/extended-protection-for-authentication 38*6777b538SAndroid Build Coastguard Worker class NET_EXPORT_PRIVATE NtlmClient { 39*6777b538SAndroid Build Coastguard Worker public: 40*6777b538SAndroid Build Coastguard Worker // Pass feature flags to enable/disable NTLMv2 and additional NTLMv2 41*6777b538SAndroid Build Coastguard Worker // features such as Extended Protection for Authentication (EPA) and Message 42*6777b538SAndroid Build Coastguard Worker // Integrity Check (MIC). 43*6777b538SAndroid Build Coastguard Worker explicit NtlmClient(NtlmFeatures features); 44*6777b538SAndroid Build Coastguard Worker 45*6777b538SAndroid Build Coastguard Worker NtlmClient(const NtlmClient&) = delete; 46*6777b538SAndroid Build Coastguard Worker NtlmClient& operator=(const NtlmClient&) = delete; 47*6777b538SAndroid Build Coastguard Worker 48*6777b538SAndroid Build Coastguard Worker ~NtlmClient(); 49*6777b538SAndroid Build Coastguard Worker IsNtlmV2()50*6777b538SAndroid Build Coastguard Worker bool IsNtlmV2() const { return features_.enable_NTLMv2; } 51*6777b538SAndroid Build Coastguard Worker IsMicEnabled()52*6777b538SAndroid Build Coastguard Worker bool IsMicEnabled() const { return IsNtlmV2() && features_.enable_MIC; } 53*6777b538SAndroid Build Coastguard Worker IsEpaEnabled()54*6777b538SAndroid Build Coastguard Worker bool IsEpaEnabled() const { return IsNtlmV2() && features_.enable_EPA; } 55*6777b538SAndroid Build Coastguard Worker 56*6777b538SAndroid Build Coastguard Worker // Returns the Negotiate message. 57*6777b538SAndroid Build Coastguard Worker std::vector<uint8_t> GetNegotiateMessage() const; 58*6777b538SAndroid Build Coastguard Worker 59*6777b538SAndroid Build Coastguard Worker // Returns a the Authenticate message. If the method fails an empty vector 60*6777b538SAndroid Build Coastguard Worker // is returned. 61*6777b538SAndroid Build Coastguard Worker // 62*6777b538SAndroid Build Coastguard Worker // |username| is treated case insensitively by NTLM however the mechanism 63*6777b538SAndroid Build Coastguard Worker // to uppercase is not clearly defined. In this implementation the default 64*6777b538SAndroid Build Coastguard Worker // locale is used. Additionally for names longer than 20 characters, the 65*6777b538SAndroid Build Coastguard Worker // fully qualified name in the new '@' format must be used. 66*6777b538SAndroid Build Coastguard Worker // eg. [email protected]. Names shorter than 20 characters can 67*6777b538SAndroid Build Coastguard Worker // optionally omit the '@domain.com' part. 68*6777b538SAndroid Build Coastguard Worker // |hostname| can be a short NetBIOS name or an FQDN, however the server will 69*6777b538SAndroid Build Coastguard Worker // only inspect this field if the default domain policy is to restrict NTLM. 70*6777b538SAndroid Build Coastguard Worker // In this case the hostname will be compared to an allowlist stored in this 71*6777b538SAndroid Build Coastguard Worker // group policy [1]. 72*6777b538SAndroid Build Coastguard Worker // |channel_bindings| is a string supplied out of band (usually from a web 73*6777b538SAndroid Build Coastguard Worker // browser) and is a (21+sizeof(hash)) byte ASCII string, where 'hash' is 74*6777b538SAndroid Build Coastguard Worker // usually a SHA-256 of the servers certificate, but may be another hash 75*6777b538SAndroid Build Coastguard Worker // algorithm. The format as defined by RFC 5929 Section 4 is shown below; 76*6777b538SAndroid Build Coastguard Worker // 77*6777b538SAndroid Build Coastguard Worker // [0-20] - "tls-server-end-point:" (Literal string) 78*6777b538SAndroid Build Coastguard Worker // [21-(20+sizeof(hash)] - HASH(server_certificate) (Certificate hash) 79*6777b538SAndroid Build Coastguard Worker // 80*6777b538SAndroid Build Coastguard Worker // |spn| is a string supplied out of band (usually from a web browser) and 81*6777b538SAndroid Build Coastguard Worker // is a Service Principal Name [2]. For NTLM over HTTP the value of this 82*6777b538SAndroid Build Coastguard Worker // string will usually be "HTTP/<hostname>". 83*6777b538SAndroid Build Coastguard Worker // |client_time| 64 bit Windows timestamp defined as the number of 84*6777b538SAndroid Build Coastguard Worker // 100 nanosecond ticks since midnight Jan 01, 1601 (UTC). If the server does 85*6777b538SAndroid Build Coastguard Worker // not send a timestamp, the client timestamp is used in the Proof Input 86*6777b538SAndroid Build Coastguard Worker // instead. 87*6777b538SAndroid Build Coastguard Worker // |server_challenge_message| is the full content of the challenge message 88*6777b538SAndroid Build Coastguard Worker // sent by the server. 89*6777b538SAndroid Build Coastguard Worker // 90*6777b538SAndroid Build Coastguard Worker // [1] - https://technet.microsoft.com/en-us/library/jj852267(v=ws.11).aspx 91*6777b538SAndroid Build Coastguard Worker std::vector<uint8_t> GenerateAuthenticateMessage( 92*6777b538SAndroid Build Coastguard Worker const std::u16string& domain, 93*6777b538SAndroid Build Coastguard Worker const std::u16string& username, 94*6777b538SAndroid Build Coastguard Worker const std::u16string& password, 95*6777b538SAndroid Build Coastguard Worker const std::string& hostname, 96*6777b538SAndroid Build Coastguard Worker const std::string& channel_bindings, 97*6777b538SAndroid Build Coastguard Worker const std::string& spn, 98*6777b538SAndroid Build Coastguard Worker uint64_t client_time, 99*6777b538SAndroid Build Coastguard Worker base::span<const uint8_t, kChallengeLen> client_challenge, 100*6777b538SAndroid Build Coastguard Worker base::span<const uint8_t> server_challenge_message) const; 101*6777b538SAndroid Build Coastguard Worker 102*6777b538SAndroid Build Coastguard Worker // Simplified method for NTLMv1 which does not require |channel_bindings|, 103*6777b538SAndroid Build Coastguard Worker // |spn|, or |client_time|. See |GenerateAuthenticateMessage| for more 104*6777b538SAndroid Build Coastguard Worker // details. GenerateAuthenticateMessageV1(const std::u16string & domain,const std::u16string & username,const std::u16string & password,const std::string & hostname,base::span<const uint8_t,8> client_challenge,base::span<const uint8_t> server_challenge_message)105*6777b538SAndroid Build Coastguard Worker std::vector<uint8_t> GenerateAuthenticateMessageV1( 106*6777b538SAndroid Build Coastguard Worker const std::u16string& domain, 107*6777b538SAndroid Build Coastguard Worker const std::u16string& username, 108*6777b538SAndroid Build Coastguard Worker const std::u16string& password, 109*6777b538SAndroid Build Coastguard Worker const std::string& hostname, 110*6777b538SAndroid Build Coastguard Worker base::span<const uint8_t, 8> client_challenge, 111*6777b538SAndroid Build Coastguard Worker base::span<const uint8_t> server_challenge_message) const { 112*6777b538SAndroid Build Coastguard Worker DCHECK(!IsNtlmV2()); 113*6777b538SAndroid Build Coastguard Worker 114*6777b538SAndroid Build Coastguard Worker return GenerateAuthenticateMessage( 115*6777b538SAndroid Build Coastguard Worker domain, username, password, hostname, std::string(), std::string(), 0, 116*6777b538SAndroid Build Coastguard Worker client_challenge, server_challenge_message); 117*6777b538SAndroid Build Coastguard Worker } 118*6777b538SAndroid Build Coastguard Worker 119*6777b538SAndroid Build Coastguard Worker private: 120*6777b538SAndroid Build Coastguard Worker // Returns the length of the Authenticate message based on the length of the 121*6777b538SAndroid Build Coastguard Worker // variable length parts of the message and whether Unicode support was 122*6777b538SAndroid Build Coastguard Worker // negotiated. 123*6777b538SAndroid Build Coastguard Worker size_t CalculateAuthenticateMessageLength( 124*6777b538SAndroid Build Coastguard Worker bool is_unicode, 125*6777b538SAndroid Build Coastguard Worker const std::u16string& domain, 126*6777b538SAndroid Build Coastguard Worker const std::u16string& username, 127*6777b538SAndroid Build Coastguard Worker const std::string& hostname, 128*6777b538SAndroid Build Coastguard Worker size_t updated_target_info_len) const; 129*6777b538SAndroid Build Coastguard Worker 130*6777b538SAndroid Build Coastguard Worker bool CalculatePayloadLayout(bool is_unicode, 131*6777b538SAndroid Build Coastguard Worker const std::u16string& domain, 132*6777b538SAndroid Build Coastguard Worker const std::u16string& username, 133*6777b538SAndroid Build Coastguard Worker const std::string& hostname, 134*6777b538SAndroid Build Coastguard Worker size_t updated_target_info_len, 135*6777b538SAndroid Build Coastguard Worker SecurityBuffer* lm_info, 136*6777b538SAndroid Build Coastguard Worker SecurityBuffer* ntlm_info, 137*6777b538SAndroid Build Coastguard Worker SecurityBuffer* domain_info, 138*6777b538SAndroid Build Coastguard Worker SecurityBuffer* username_info, 139*6777b538SAndroid Build Coastguard Worker SecurityBuffer* hostname_info, 140*6777b538SAndroid Build Coastguard Worker SecurityBuffer* session_key_info, 141*6777b538SAndroid Build Coastguard Worker size_t* authenticate_message_len) const; 142*6777b538SAndroid Build Coastguard Worker 143*6777b538SAndroid Build Coastguard Worker // Returns the length of the header part of the Authenticate message. 144*6777b538SAndroid Build Coastguard Worker size_t GetAuthenticateHeaderLength() const; 145*6777b538SAndroid Build Coastguard Worker 146*6777b538SAndroid Build Coastguard Worker // Returns the length of the NTLM response. 147*6777b538SAndroid Build Coastguard Worker size_t GetNtlmResponseLength(size_t updated_target_info_len) const; 148*6777b538SAndroid Build Coastguard Worker 149*6777b538SAndroid Build Coastguard Worker // Generates the negotiate message (which is always the same) into 150*6777b538SAndroid Build Coastguard Worker // |negotiate_message_|. 151*6777b538SAndroid Build Coastguard Worker void GenerateNegotiateMessage(); 152*6777b538SAndroid Build Coastguard Worker 153*6777b538SAndroid Build Coastguard Worker const NtlmFeatures features_; 154*6777b538SAndroid Build Coastguard Worker NegotiateFlags negotiate_flags_; 155*6777b538SAndroid Build Coastguard Worker std::vector<uint8_t> negotiate_message_; 156*6777b538SAndroid Build Coastguard Worker }; 157*6777b538SAndroid Build Coastguard Worker 158*6777b538SAndroid Build Coastguard Worker } // namespace net::ntlm 159*6777b538SAndroid Build Coastguard Worker 160*6777b538SAndroid Build Coastguard Worker #endif // NET_NTLM_NTLM_CLIENT_H_ 161