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 #ifndef NET_NTLM_NTLM_CONSTANTS_H_ 6*6777b538SAndroid Build Coastguard Worker #define NET_NTLM_NTLM_CONSTANTS_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 9*6777b538SAndroid Build Coastguard Worker #include <stdint.h> 10*6777b538SAndroid Build Coastguard Worker #include <type_traits> 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include <vector> 13*6777b538SAndroid Build Coastguard Worker 14*6777b538SAndroid Build Coastguard Worker #include "net/base/net_export.h" 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker namespace net::ntlm { 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker // A security buffer is a structure within an NTLM message that indicates 19*6777b538SAndroid Build Coastguard Worker // the offset from the beginning of the message and the length of a payload 20*6777b538SAndroid Build Coastguard Worker // that occurs later in the message. Within the raw message there is also 21*6777b538SAndroid Build Coastguard Worker // an additional field, however the field is always written with the same 22*6777b538SAndroid Build Coastguard Worker // value as length, and readers must always ignore it. 23*6777b538SAndroid Build Coastguard Worker struct SecurityBuffer { SecurityBufferSecurityBuffer24*6777b538SAndroid Build Coastguard Worker SecurityBuffer(uint32_t offset, uint16_t length) 25*6777b538SAndroid Build Coastguard Worker : offset(offset), length(length) {} SecurityBufferSecurityBuffer26*6777b538SAndroid Build Coastguard Worker SecurityBuffer() : SecurityBuffer(0, 0) {} 27*6777b538SAndroid Build Coastguard Worker 28*6777b538SAndroid Build Coastguard Worker uint32_t offset; 29*6777b538SAndroid Build Coastguard Worker uint16_t length; 30*6777b538SAndroid Build Coastguard Worker }; 31*6777b538SAndroid Build Coastguard Worker 32*6777b538SAndroid Build Coastguard Worker struct NtlmFeatures { NtlmFeaturesNtlmFeatures33*6777b538SAndroid Build Coastguard Worker explicit NtlmFeatures(bool enable_NTLMv2) : enable_NTLMv2(enable_NTLMv2) {} 34*6777b538SAndroid Build Coastguard Worker 35*6777b538SAndroid Build Coastguard Worker // Whether the use NTLMv2. 36*6777b538SAndroid Build Coastguard Worker bool enable_NTLMv2 = true; 37*6777b538SAndroid Build Coastguard Worker 38*6777b538SAndroid Build Coastguard Worker // Enables Message Integrity Check (MIC). This flag is ignored if 39*6777b538SAndroid Build Coastguard Worker // enable_NTLMv2 is false. 40*6777b538SAndroid Build Coastguard Worker bool enable_MIC = true; 41*6777b538SAndroid Build Coastguard Worker 42*6777b538SAndroid Build Coastguard Worker // Enables Extended Protection for Authentication (EPA). This flag is 43*6777b538SAndroid Build Coastguard Worker // ignored if enable_NTLMv2 is false. 44*6777b538SAndroid Build Coastguard Worker bool enable_EPA = true; 45*6777b538SAndroid Build Coastguard Worker }; 46*6777b538SAndroid Build Coastguard Worker 47*6777b538SAndroid Build Coastguard Worker // There are 3 types of messages in NTLM. The message type is a field in 48*6777b538SAndroid Build Coastguard Worker // every NTLM message header. See [MS-NLMP] Section 2.2. 49*6777b538SAndroid Build Coastguard Worker enum class MessageType : uint32_t { 50*6777b538SAndroid Build Coastguard Worker kNegotiate = 0x01, 51*6777b538SAndroid Build Coastguard Worker kChallenge = 0x02, 52*6777b538SAndroid Build Coastguard Worker kAuthenticate = 0x03, 53*6777b538SAndroid Build Coastguard Worker }; 54*6777b538SAndroid Build Coastguard Worker 55*6777b538SAndroid Build Coastguard Worker // Defined in [MS-NLMP] Section 2.2.2.5 56*6777b538SAndroid Build Coastguard Worker // Only the used subset is defined. 57*6777b538SAndroid Build Coastguard Worker enum class NegotiateFlags : uint32_t { 58*6777b538SAndroid Build Coastguard Worker kNone = 0, 59*6777b538SAndroid Build Coastguard Worker kUnicode = 0x01, 60*6777b538SAndroid Build Coastguard Worker kOem = 0x02, 61*6777b538SAndroid Build Coastguard Worker kRequestTarget = 0x04, 62*6777b538SAndroid Build Coastguard Worker kNtlm = 0x200, 63*6777b538SAndroid Build Coastguard Worker kAlwaysSign = 0x8000, 64*6777b538SAndroid Build Coastguard Worker kExtendedSessionSecurity = 0x80000, 65*6777b538SAndroid Build Coastguard Worker kTargetInfo = 0x800000, 66*6777b538SAndroid Build Coastguard Worker }; 67*6777b538SAndroid Build Coastguard Worker 68*6777b538SAndroid Build Coastguard Worker constexpr NegotiateFlags operator|(NegotiateFlags lhs, NegotiateFlags rhs) { 69*6777b538SAndroid Build Coastguard Worker using TFlagsInt = std::underlying_type<NegotiateFlags>::type; 70*6777b538SAndroid Build Coastguard Worker 71*6777b538SAndroid Build Coastguard Worker return static_cast<NegotiateFlags>(static_cast<TFlagsInt>(lhs) | 72*6777b538SAndroid Build Coastguard Worker static_cast<TFlagsInt>(rhs)); 73*6777b538SAndroid Build Coastguard Worker } 74*6777b538SAndroid Build Coastguard Worker 75*6777b538SAndroid Build Coastguard Worker constexpr NegotiateFlags operator&(NegotiateFlags lhs, NegotiateFlags rhs) { 76*6777b538SAndroid Build Coastguard Worker using TFlagsInt = std::underlying_type<NegotiateFlags>::type; 77*6777b538SAndroid Build Coastguard Worker 78*6777b538SAndroid Build Coastguard Worker return static_cast<NegotiateFlags>(static_cast<TFlagsInt>(lhs) & 79*6777b538SAndroid Build Coastguard Worker static_cast<TFlagsInt>(rhs)); 80*6777b538SAndroid Build Coastguard Worker } 81*6777b538SAndroid Build Coastguard Worker 82*6777b538SAndroid Build Coastguard Worker // Identifies the payload type in an AV Pair. See [MS-NLMP] 2.2.2.1 83*6777b538SAndroid Build Coastguard Worker enum class TargetInfoAvId : uint16_t { 84*6777b538SAndroid Build Coastguard Worker kEol = 0x0000, 85*6777b538SAndroid Build Coastguard Worker kServerName = 0x00001, 86*6777b538SAndroid Build Coastguard Worker kDomainName = 0x00002, 87*6777b538SAndroid Build Coastguard Worker kFlags = 0x0006, 88*6777b538SAndroid Build Coastguard Worker kTimestamp = 0x0007, 89*6777b538SAndroid Build Coastguard Worker kTargetName = 0x0009, 90*6777b538SAndroid Build Coastguard Worker kChannelBindings = 0x000A, 91*6777b538SAndroid Build Coastguard Worker }; 92*6777b538SAndroid Build Coastguard Worker 93*6777b538SAndroid Build Coastguard Worker // Flags used in an TargetInfoAvId::kFlags AV Pair. See [MS-NLMP] 2.2.2.1 94*6777b538SAndroid Build Coastguard Worker enum class TargetInfoAvFlags : uint32_t { 95*6777b538SAndroid Build Coastguard Worker kNone = 0, 96*6777b538SAndroid Build Coastguard Worker kMicPresent = 0x00000002, 97*6777b538SAndroid Build Coastguard Worker }; 98*6777b538SAndroid Build Coastguard Worker 99*6777b538SAndroid Build Coastguard Worker using TAvFlagsInt = std::underlying_type<TargetInfoAvFlags>::type; 100*6777b538SAndroid Build Coastguard Worker 101*6777b538SAndroid Build Coastguard Worker constexpr TargetInfoAvFlags operator|(TargetInfoAvFlags lhs, 102*6777b538SAndroid Build Coastguard Worker TargetInfoAvFlags rhs) { 103*6777b538SAndroid Build Coastguard Worker return static_cast<TargetInfoAvFlags>(static_cast<TAvFlagsInt>(lhs) | 104*6777b538SAndroid Build Coastguard Worker static_cast<TAvFlagsInt>(rhs)); 105*6777b538SAndroid Build Coastguard Worker } 106*6777b538SAndroid Build Coastguard Worker 107*6777b538SAndroid Build Coastguard Worker constexpr TargetInfoAvFlags operator&(TargetInfoAvFlags lhs, 108*6777b538SAndroid Build Coastguard Worker TargetInfoAvFlags rhs) { 109*6777b538SAndroid Build Coastguard Worker return static_cast<TargetInfoAvFlags>(static_cast<TAvFlagsInt>(lhs) & 110*6777b538SAndroid Build Coastguard Worker static_cast<TAvFlagsInt>(rhs)); 111*6777b538SAndroid Build Coastguard Worker } 112*6777b538SAndroid Build Coastguard Worker 113*6777b538SAndroid Build Coastguard Worker // An AV Pair is a structure that appears inside the target info field. It 114*6777b538SAndroid Build Coastguard Worker // consists of an |avid| to identify the data type and an |avlen| specifying 115*6777b538SAndroid Build Coastguard Worker // the size of the payload. Following that is |avlen| bytes of inline payload. 116*6777b538SAndroid Build Coastguard Worker // AV Pairs are concatenated together and a special terminator with |avid| 117*6777b538SAndroid Build Coastguard Worker // equal to |kEol| and |avlen| equal to zero signals that no further pairs 118*6777b538SAndroid Build Coastguard Worker // follow. See [MS-NLMP] 2.2.2.1 119*6777b538SAndroid Build Coastguard Worker // 120*6777b538SAndroid Build Coastguard Worker // AV Pairs from the Challenge message are read from the challenge message 121*6777b538SAndroid Build Coastguard Worker // and a potentially modified version is written into the authenticate 122*6777b538SAndroid Build Coastguard Worker // message. In some cases the existing AV Pair is modified, eg. flags. In 123*6777b538SAndroid Build Coastguard Worker // some cases new AV Pairs are add, eg. channel bindings and spn. 124*6777b538SAndroid Build Coastguard Worker // 125*6777b538SAndroid Build Coastguard Worker // For simplicity of processing two special fields |flags|, and |timestamp| 126*6777b538SAndroid Build Coastguard Worker // are populated during the initial parsing phase for AVIDs |kFlags| and 127*6777b538SAndroid Build Coastguard Worker // |kTimestamp| respectively. This avoids subsequent code having to 128*6777b538SAndroid Build Coastguard Worker // manipulate the payload value through the buffer directly. For all 129*6777b538SAndroid Build Coastguard Worker // other AvPairs the value of these 2 fields is undefined and the payload 130*6777b538SAndroid Build Coastguard Worker // is in the |buffer| field. For these fields the payload is copied verbatim 131*6777b538SAndroid Build Coastguard Worker // and it's content is not read or validated in any way. 132*6777b538SAndroid Build Coastguard Worker struct NET_EXPORT_PRIVATE AvPair { 133*6777b538SAndroid Build Coastguard Worker AvPair(); 134*6777b538SAndroid Build Coastguard Worker AvPair(TargetInfoAvId avid, uint16_t avlen); 135*6777b538SAndroid Build Coastguard Worker AvPair(TargetInfoAvId avid, std::vector<uint8_t> buffer); 136*6777b538SAndroid Build Coastguard Worker AvPair(const AvPair& other); 137*6777b538SAndroid Build Coastguard Worker AvPair(AvPair&& other); 138*6777b538SAndroid Build Coastguard Worker ~AvPair(); 139*6777b538SAndroid Build Coastguard Worker 140*6777b538SAndroid Build Coastguard Worker AvPair& operator=(const AvPair& other); 141*6777b538SAndroid Build Coastguard Worker AvPair& operator=(AvPair&& other); 142*6777b538SAndroid Build Coastguard Worker 143*6777b538SAndroid Build Coastguard Worker std::vector<uint8_t> buffer; 144*6777b538SAndroid Build Coastguard Worker uint64_t timestamp; 145*6777b538SAndroid Build Coastguard Worker TargetInfoAvFlags flags; 146*6777b538SAndroid Build Coastguard Worker TargetInfoAvId avid; 147*6777b538SAndroid Build Coastguard Worker uint16_t avlen; 148*6777b538SAndroid Build Coastguard Worker }; 149*6777b538SAndroid Build Coastguard Worker 150*6777b538SAndroid Build Coastguard Worker static constexpr uint8_t kSignature[] = "NTLMSSP"; 151*6777b538SAndroid Build Coastguard Worker static constexpr size_t kSignatureLen = std::size(kSignature); 152*6777b538SAndroid Build Coastguard Worker static constexpr uint16_t kProofInputVersionV2 = 0x0101; 153*6777b538SAndroid Build Coastguard Worker static constexpr size_t kSecurityBufferLen = 154*6777b538SAndroid Build Coastguard Worker (2 * sizeof(uint16_t)) + sizeof(uint32_t); 155*6777b538SAndroid Build Coastguard Worker static constexpr size_t kNegotiateMessageLen = 32; 156*6777b538SAndroid Build Coastguard Worker static constexpr size_t kMinChallengeHeaderLen = 32; 157*6777b538SAndroid Build Coastguard Worker static constexpr size_t kChallengeHeaderLen = 48; 158*6777b538SAndroid Build Coastguard Worker static constexpr size_t kResponseLenV1 = 24; 159*6777b538SAndroid Build Coastguard Worker static constexpr size_t kChallengeLen = 8; 160*6777b538SAndroid Build Coastguard Worker static constexpr size_t kVersionFieldLen = 8; 161*6777b538SAndroid Build Coastguard Worker static constexpr size_t kNtlmHashLen = 16; 162*6777b538SAndroid Build Coastguard Worker static constexpr size_t kNtlmProofLenV2 = kNtlmHashLen; 163*6777b538SAndroid Build Coastguard Worker static constexpr size_t kSessionKeyLenV2 = kNtlmHashLen; 164*6777b538SAndroid Build Coastguard Worker static constexpr size_t kMicLenV2 = kNtlmHashLen; 165*6777b538SAndroid Build Coastguard Worker static constexpr size_t kChannelBindingsHashLen = kNtlmHashLen; 166*6777b538SAndroid Build Coastguard Worker static constexpr size_t kEpaUnhashedStructHeaderLen = 20; 167*6777b538SAndroid Build Coastguard Worker static constexpr size_t kProofInputLenV2 = 28; 168*6777b538SAndroid Build Coastguard Worker static constexpr size_t kAvPairHeaderLen = 2 * sizeof(uint16_t); 169*6777b538SAndroid Build Coastguard Worker static constexpr size_t kNtlmResponseHeaderLenV2 = 170*6777b538SAndroid Build Coastguard Worker kNtlmProofLenV2 + kProofInputLenV2; 171*6777b538SAndroid Build Coastguard Worker static constexpr size_t kAuthenticateHeaderLenV1 = 64; 172*6777b538SAndroid Build Coastguard Worker static constexpr size_t kMicOffsetV2 = 72; 173*6777b538SAndroid Build Coastguard Worker static constexpr size_t kAuthenticateHeaderLenV2 = 88; 174*6777b538SAndroid Build Coastguard Worker 175*6777b538SAndroid Build Coastguard Worker static constexpr size_t kMaxFqdnLen = 255; 176*6777b538SAndroid Build Coastguard Worker static constexpr size_t kMaxUsernameLen = 104; 177*6777b538SAndroid Build Coastguard Worker static constexpr size_t kMaxPasswordLen = 256; 178*6777b538SAndroid Build Coastguard Worker 179*6777b538SAndroid Build Coastguard Worker static constexpr NegotiateFlags kNegotiateMessageFlags = 180*6777b538SAndroid Build Coastguard Worker NegotiateFlags::kUnicode | NegotiateFlags::kOem | 181*6777b538SAndroid Build Coastguard Worker NegotiateFlags::kRequestTarget | NegotiateFlags::kNtlm | 182*6777b538SAndroid Build Coastguard Worker NegotiateFlags::kAlwaysSign | NegotiateFlags::kExtendedSessionSecurity; 183*6777b538SAndroid Build Coastguard Worker 184*6777b538SAndroid Build Coastguard Worker } // namespace net::ntlm 185*6777b538SAndroid Build Coastguard Worker 186*6777b538SAndroid Build Coastguard Worker #endif // NET_NTLM_NTLM_CONSTANTS_H_ 187