chromium/net/ntlm/ntlm_test_data.h

// 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_