// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This file contains common input and result values use to verify the NTLM // implementation. They are defined in [MS-NLMP] Section 4.2 [1]. // // [MS-NLMP] has no test data for Extended Protection for Authentication (EPA). // Test vectors related to EPA (aka Channel Binding) have been taken from // a Microsoft blog post [2]. // // [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx // [2] https://blogs.msdn.microsoft.com/openspecification/2013/03/26/ntlm-and- // channel-binding-hash-aka-extended-protection-for-authentication/ #ifndef NET_NTLM_NTLM_TEST_DATA_H_ #define NET_NTLM_NTLM_TEST_DATA_H_ #include "net/ntlm/ntlm_constants.h" namespace net::ntlm::test { // Common input values defined in [MS-NLMP] Section 4.2.1. constexpr char16_t kPassword[] = …; constexpr char16_t kNtlmDomain[] = …; constexpr uint8_t kNtlmDomainRaw[] = …; constexpr char16_t kUser[] = …; constexpr char16_t kDomainUserCombined[] = …; constexpr char16_t kHostname[] = …; constexpr char16_t kServer[] = …; constexpr uint8_t kServerRaw[] = …; // ASCII Versions of the above strings. constexpr char kNtlmDomainAscii[] = …; constexpr char kUserAscii[] = …; constexpr char kHostnameAscii[] = …; // Test data obtained from [2]. constexpr uint8_t kChannelBindings[] = …; constexpr char kNtlmSpn[] = …; constexpr uint8_t kNtlmSpnRaw[] = …; // Input value defined in [MS-NLMP] Section 4.2.1. constexpr uint64_t kServerTimestamp = …; // Arbitrary value for client timestamp. The spec does not provide test data // or scenarios involving the client timestamp. The relevant thing is that it // is not equal to |kServerTimestamp| so it can be determined which timestamp // is within the message. // Tue, 23 May 2017 20:13:07 +0000 constexpr uint64_t kClientTimestamp = …; // Challenge vectors defined in [MS-NLMP] Section 4.2.1. constexpr uint8_t kServerChallenge[kChallengeLen] = …; constexpr uint8_t kClientChallenge[kChallengeLen] = …; // Test input defined in [MS-NLMP] Section 4.2.3.3. constexpr uint8_t kChallengeMsgV1[] = …; // Test input defined in [MS-NLMP] Section 4.2.4.3. constexpr uint8_t kChallengeMsgFromSpecV2[] = …; // A minimal challenge message for tests. For NTLMv1 this implementation only // reads the smallest required version of the message (32 bytes). Some // servers may still send messages this small. The only relevant flags // that affect behavior are that both NTLMSSP_NEGOTIATE_UNICODE and // NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY are set. // // [0-7] - "NTLMSSP\0" (Signature) // [9-11] - |MessageType::kChallenge| (Message Type = 0x00000002) // [12-19] - |SecBuf(kNegotiateMessageLen, 0)| (Target Name - Not Used) // [20-23] - |kNegotiateMessageFlags| (Flags = 0x00088207) // [24-31] - |kServerChallenge| (Server Challenge) // // See [MS-NLMP] Section 2.2.2.2 for more information about the Challenge // message. constexpr uint8_t kMinChallengeMessage[kChallengeHeaderLen] = …; // The same message as |kMinChallengeMessage| but with the // NTLMSSP_NEGOTIATE_UNICODE flag cleared. constexpr uint8_t kMinChallengeMessageNoUnicode[kChallengeHeaderLen] = …; // The same message as |kMinChallengeMessage| but with the // NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY flag cleared. constexpr uint8_t kMinChallengeMessageNoSS[kChallengeHeaderLen] = …; // Test result value for NTOWFv1() defined in [MS-NLMP] Section 4.2.2.1.2. constexpr uint8_t kExpectedNtlmHashV1[kNtlmHashLen] = …; // Test result value for NTOWFv2() defined in [MS-NLMP] Section 4.2.4.1.1. constexpr uint8_t kExpectedNtlmHashV2[kNtlmHashLen] = …; // Test result value defined in [MS-NLMP] Section 4.2.2.1. constexpr uint8_t kExpectedNtlmResponseV1[kResponseLenV1] = …; // Test result value defined in [MS-NLMP] Section 4.2.3.2.2. constexpr uint8_t kExpectedNtlmResponseWithV1SS[kResponseLenV1] = …; // Test result value defined in [MS-NLMP] Section 4.2.3.2.1. constexpr uint8_t kExpectedLmResponseWithV1SS[kResponseLenV1] = …; // Test result value defined in [MS-NLMP] Section 4.2.4.1.3. // // "temp" is defined in Section 3.3.2 and is part of the data to be hashed // to generate the NTLMv2 Proof. It is composed of 3 parts; // // 1) [0-27] A fixed length part in the first 28 (|kProofInputLenV2|) bytes // which in this implementation is generated by |GenerateProofInputV2|. // // 2) [28-63] A variable length part which the spec calls "ServerName" but // defines as the AV Pairs (aka Target Information) from the Authenticate // message. See |kExpectedTargetInfoFromSpecV2| for more information. // // 3) [64-68] 4 zero bytes. // // NOTE: The timestamp (bytes [8-15]) should not actually be 0 here. In order // to use the test data from the spec some lower level tests do generate this // value. The target info sent by the server does not contain a timestamp // AvPair, and section 3.1.5.1.2 states that the client should populate the // timestamp with the servers timestamp if it exists, otherwise with the // client's local time. For end to end tests the alternate value // |kExpectedTempWithClientTimestampV2| below is used for end to end tests. // Having different test data for the server and client time allows testing // the logic more correctly. constexpr uint8_t kExpectedTempFromSpecV2[] = …; // This value is the same as |kExpectedTempFromSpecV2| but with the timestamp // field at bytes [8-15] populated with |kClientTimestamp|. constexpr uint8_t kExpectedTempWithClientTimestampV2[] = …; // Test result value defined (indirectly) in [MS-NLMP] Section 4.2.4. // // This is part 2 (bytes [28-63]) of |kExpectedTempFromSpecV2|. Additional // notes; // // a) The spec defines the AV Pairs to be in the opposite order to which they // actually appear in the output in Section 4.2.4.1.3. // // b) The implicit presence of a terminating AV Pair is not mentioned. // // c) Section 4.2.4 does not show the byte sequences of the AV Pair Headers. // // NOTE: The real implementation in default settings would not have such a // simple set of AV Pairs since a flags field to indicate the presence of a // MIC, and a channel bindings field would also have been added. constexpr uint8_t kExpectedTargetInfoFromSpecV2[] = …; // This target info is to test the behavior when a server timestamp is // present. It is the same as |kExpectedTargetInfoFromSpecV2| but with // an additional timestamp AvPair. constexpr uint8_t kExpectedTargetInfoFromSpecPlusServerTimestampV2[] = …; // The target info after being updated by the client when the server sends // |kExpectedTargetInfoFromSpecV2| in the challenge message with both EPA and // MIC enabled. // // When MIC and EPA are enabled, 3 additional AvPairs are added. // 1) A flags AVPair with the MIC_PRESENT bit set. // 2) A channel bindings AVPair containing the channel bindings hash. // 3) A target name AVPair containing the SPN of the server. // // AvPair 1 [0-1] |TargetInfoAvId::kDomainName| Av ID = 0x0002 // AvPair 1 [2-3] |len(kNtlmDomainRaw)| Av Length = 0x000c // AvPair 1 [4-15] |kNtlmDomainRaw| Av Payload = L"Domain" // // AvPair 2 [16-17] |TargetInfoAvId::kServerName| Av ID = 0x0001 // AvPair 2 [18-19] |len(kServerRaw)| Av Length = 0x000c // AvPair 2 [20-31] |kServerRaw| Av Payload = L"Server" // // AvPair 3 [32-33] |TargetInfoAvId::kFlags| Av ID = 0x0006 // AvPair 3 [34-35] |sizeof(uint32_t)| Av Length = 0x0004 // AvPair 3 [36-39] |TargetInfoAvFlags::kMicPresent| Av Payload = 0x00000002 // // AvPair 4 [40-41] |TargetInfoAvId::kChannelBindings| Av ID = 0x000a // AvPair 4 [42-43] |kChannelBindingsHashLen| Av Length = 0x0010 // AvPair 4 [44-59] |kExpectedChannelBindingHashV2| Av Payload // // AvPair 5 [60-61] |TargetInfoAvId::kTargetName| Av ID = 0x0009 // AvPair 5 [62-63] |len(kNtlmSpnRaw)| Av Length = 0x0016 // AvPair 5 [64-85] |kNtlmSpnRaw| Av Payload = // L"HTTP/Server" // // AvPair 6 [86-87] |TargetInfoAvId::kEol| Av ID = 0x0000 // AvPair 6 [88-89] Av Length = 0x0000 constexpr uint8_t kExpectedTargetInfoSpecResponseV2[] = …; // Test result value defined in [MS-NLMP] Section 4.2.4.2.2. constexpr uint8_t kExpectedProofFromSpecV2[kNtlmProofLenV2] = …; // The value of the NTLMv2 proof when |kExpectedTargetInfoSpecResponseV2| is // the updated target info in the Authenticate message. constexpr uint8_t kExpectedProofSpecResponseV2[kNtlmProofLenV2] = …; // The value of the NTLMv2 proof when |kExpectedTargetInfoSpecResponseV2| is // the updated target info, and |kClientTimestamp| is correctly set in the // Authenticate message. constexpr uint8_t kExpectedProofSpecResponseWithClientTimestampV2[kNtlmProofLenV2] = …; // Test result data obtained from [2]. constexpr uint8_t kExpectedChannelBindingHashV2[kChannelBindingsHashLen] = …; // Test result value defined in [MS-NLMP] Section 4.2.4.1.2. constexpr uint8_t kExpectedSessionBaseKeyFromSpecV2[kSessionKeyLenV2] = …; // The session base key when the proof is // |kExpectedProofSpecResponseWithClientTimestampV2|. constexpr uint8_t kExpectedSessionBaseKeyWithClientTimestampV2[kSessionKeyLenV2] = …; // The Message Integrity Check (MIC) using // |kExpectedSessionBaseKeyWithClientTimestampV2| over the following 3 // messages; |kExpectedNegotiateMsg|, |kChallengeMsgFromSpecV2|, and // |kExpectedAuthenticateMsgSpecResponseV2|. // The MIC field in |kExpectedAuthenticateMsgSpecResponseV2| is set to all // zeros while calculating the hash. constexpr uint8_t kExpectedMicV2[kMicLenV2] = …; // Expected negotiate message from this implementation. // [0-7] - "NTLMSSP\0" (Signature) // [9-11] - |MessageType::kNegotiate| (Message Type = 0x00000001) // [12-15] - |kNegotiateMessageFlags| (Flags = 0x00088207) // [16-23] - |SecBuf(kNegotiateMessageLen, 0)| (Domain) // [24-32] - |SecBuf(kNegotiateMessageLen, 0)| (Workstation) // // NOTE: Message does not include Version field. Since // NTLMSSP_NEGOTIATE_VERSION is never sent, it is not required, and the server // won't try to read it. The field is currently omitted for test compatibility // with the existing implementation. When NTLMv2 is implemented this field // will be present for both NTLMv1 and NTLMv2, however it will always be set to // all zeros. The version field is only used for debugging and only defines // a mapping to Windows operating systems. // // Similarly both Domain and Workstation fields are are not strictly required // either (though are included here) since neither // NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED nor // NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED are ever sent. A compliant server // should never read past the 16th byte in this message. // // See [MS-NLMP] Section 2.2.2.5 for more detail on flags and 2.2.2.1 for the // Negotiate message in general. constexpr uint8_t kExpectedNegotiateMsg[kNegotiateMessageLen] = …; // Expected V1 Authenticate message from this implementation when sent // |kChallengeMsgV1| as the challenge. // // [0-7] - "NTLMSSP\0" (Signature) // [9-11] - |MessageType::kAuthenticate| (Message Type = 0x00000003) // [12-19] - |SecBuf(64, kResponseLenV1)| (LM Response) // [20-27] - |SecBuf(88, kResponseLenV1)| (NTLM Response) // [28-35] - |SecBuf(112, 12)| (Target Name = L"Domain") // [36-43] - |SecBuf(124, 8)| (User = L"User") // [44-51] - |SecBuf(132, 16)| (Workstation = L"COMPUTER") // [52-59] - |SecBuf(64, 0)| (Session Key (empty)) // [60-63] - 0x00088203 (Flags) // [64-87] - |EXPECTED_V1_WITH_SS_LM_RESPONSE| (LM Response Payload) // [88-111] - |EXPECTED_V1_WITH_SS_NTLM_RESPONSE| (NTLM Response Payload) // [112-123]- L"Domain" (Target Name Payload) // [124-132]- L"User" (User Payload) // [132-147]- L"COMPUTER" (Workstation Payload) // // NOTE: This is not identical to the message in [MS-NLMP] Section 4.2.2.3 for // several reasons. // // 1) The flags are different because this implementation does not support // the flags related to version, key exchange, signing and sealing. These // flags are not relevant to implementing the NTLM scheme in HTTP. // 2) Since key exchange is not required nor supported, the session base key // payload is not required nor present. // 3) The specification allows payloads to be in any order. This (and the // prior) implementation uses a different payload order than the example. // 4) The version field is Windows specific and there is no provision for // non-Windows OS information. This message does not include a version field. constexpr uint8_t kExpectedAuthenticateMsgSpecResponseV1[] = …; // Expected V2 Authenticate message from this implementation when sent // |kChallengeMsgFromSpecV2| as the challenge using default features. // // [0-7] - "NTLMSSP\0" (Signature) // [9-11] - |MessageType::kAuthenticate| (Message Type = 0x00000003) // [12-19] - |SecBuf(88, kResponseLenV1)| (LM Response) // [20-27] - |SecBuf(112, 138)| (NTLM Response) // [28-35] - |SecBuf(250, 12)| (Target Name = L"Domain") // [36-43] - |SecBuf(262, 8)| (User = L"User") // [44-51] - |SecBuf(270, 16)| (Workstation = L"COMPUTER") // [52-59] - |SecBuf(88, 0)| (Session Key (empty)) // [60-63] - 0x00088203 (Flags) // [64-71] - All zero (Version) // [72-87] - |kExpectedMicV2| (MIC) // [88-111] - All zero (LM Response Payload) // [112-249]-------------------------------------- (NTLM Response Payload) // [112-127]-|kExpectedProofSpecResponseWithClientTimestampV2| // (NTLMv2 Proof) // [128-155]-|kExpectedTempWithClientTimestampV2[0-27]| // (Proof Input) // [156-245]-|kExpectedTargetInfoSpecResponseV2| (Updated target info) // [246-249]-0x00000000 (Reserved - zeros) // ----------------------------------------------------------------------- // [250-261]- L"Domain" (Target Name Payload) // [262-269]- L"User" (User Payload) // [270-285]- L"COMPUTER" (Workstation Payload) // // NOTE: This is not identical to the message in [MS-NLMP] Section TODO(X) for // several reasons. // // 1) The flags are different because this implementation does not support // the flags related to version, key exchange, signing and sealing. These // flags are not relevant to implementing the NTLM scheme in HTTP. // 2) Since key exchange is not required nor supported, the session base key // payload is not required nor present. // 3) The specification allows payloads to be in any order. This (and the // prior) implementation uses a different payload order than the example. // 4) The version field is Windows specific and there is no provision for a // non-Windows OS information. This message does not include a version field. // 5) The example in the spec does not use Extended Protection for // Authentication (EPA). This message includes an extra AV Pair containing // the hashed channel bindings. // 6) The example in the spec does not use Message Integrity Check (MIC). // The optional field is not present, nor is the flags AV Pair that indicates // it's presence. // 7) Since the server does not provide a timestamp, the client should // provide one. constexpr uint8_t kExpectedAuthenticateMsgSpecResponseV2[] = …; // Expected V2 Authenticate message from this implementation when sent // |kChallengeMsgV1| as the challenge using default features. This scenario // can occur because some older implementations (Windows 2003 and earlier), // do not send NTLMSSP_NEGOTIATE_TARGET_INFO, nor a Target Info payload in // the challenge message. // // [0-7] - "NTLMSSP\0" (Signature) // [9-11] - |MessageType::kAuthenticate| (Message Type = 0x00000003) // [12-19] - |SecBuf(88, kResponseLenV1)| (LM Response) // [20-27] - |SecBuf(112, 106)| (NTLM Response) // [28-35] - |SecBuf(218, 12)| (Target Name = L"Domain") // [36-43] - |SecBuf(230, 8)| (User = L"User") // [44-51] - |SecBuf(238, 16)| (Workstation = L"COMPUTER") // [52-59] - |SecBuf(88, 0)| (Session Key (empty)) // [60-63] - 0x00088203 (Flags) // [64-71] - All zero (Version) // [72-87] - (MIC) // [88-111] - All zero (LM Response Payload) // [112-217]-------------------------------------- (NTLM Response Payload) // [112-127]- (NTLMv2 Proof) // [128-155]-|kExpectedTempWithClientTimestampV2[0-27]| // (Proof Input) // [156-213]-|kExpectedTargetInfoSpecResponseV2[32-89]| // (Updated target info) // [214-217]-0x00000000 (Reserved - zeros) // ----------------------------------------------------------------------- // [218-229]- L"Domain" (Target Name Payload) // [230-237]- L"User" (User Payload) // [238-253]- L"COMPUTER" (Workstation Payload) // // NOTE: This is message is almost the same as // |kExpectedAuthenticateMsgSpecResponseV2| with the following changes. // 1) The target info within the NTLM response is missing the first 32 // bytes, which represent the 2 AvPairs that the server does not send in // this case. // 2) The NTLM Response security buffer length is reduced by 32 and therefore // all subsequent security buffer offsets are reduced by 32. // 3) The NTLMv2 Proof is different since the different target info changes // the hash. // 4) As with the NTLMv2 Proof, the MIC is different because the message is // different. constexpr uint8_t kExpectedAuthenticateMsgToOldV1ChallegeV2[] = …; // Expected V2 Authenticate message from this implementation when sent // |kChallengeMsgFromSpecV2|, no channel bindings exist, and the remote // server is named 'server' (with lowercase 's'). All the test data from the // spec uses 'Server' with an uppercase 'S'. Chrome lower cases the hostname // so this result vector is needed for an end to end test in // |HttpNetworkTransactionUnitTest|. // // The response is the same as |kExpectedAuthenticateMsgSpecResponseV2| with // the following differences. // // [72-87] - The MIC (hash of all messages) is different because the // message is different. // [112-127] - The cryptographic proof is different due to the changed // AvPairs below, which are inputs to the hash. // [225]- The 's' in the SPN AvPair is lowercase. // [200-215] - The channel binding AvPair in the target info is all zero. See // |kExpectedTargetInfoSpecResponseV2| for more information. constexpr uint8_t kExpectedAuthenticateMsgEmptyChannelBindingsV2[] = …; } // namespace net::ntlm::test #endif // NET_NTLM_NTLM_TEST_DATA_H_