| Index: net/ntlm/ntlm_unittest.cc
|
| diff --git a/net/ntlm/ntlm_unittest.cc b/net/ntlm/ntlm_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..cf237fa3715d4dcdde5d355b32bc01dd6053bef3
|
| --- /dev/null
|
| +++ b/net/ntlm/ntlm_unittest.cc
|
| @@ -0,0 +1,115 @@
|
| +// Copyright 2017 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +// Tests on exact results from cryptographic operations are based on test data
|
| +// provided in [MS-NLMP] Version 28.0 [1] Section 4.2.
|
| +//
|
| +// Additional sanity checks on the low level hashing operations test for
|
| +// properties of the outputs, such as whether the hashes change, whether they
|
| +// should be zeroed out, or whether they should be the same or different.
|
| +//
|
| +// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
|
| +
|
| +#include "net/ntlm/ntlm.h"
|
| +
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "net/ntlm/ntlm_test_data.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace net {
|
| +namespace ntlm {
|
| +
|
| +TEST(NtlmClientTest, GenerateNtlmHashV1PasswordSpecTests) {
|
| + uint8_t hash[NTLM_HASH_LEN];
|
| + GenerateNtlmHashV1(NTLM_PASSWORD, hash);
|
| + ASSERT_EQ(0, memcmp(hash, EXPECTED_V1_HASH, NTLM_HASH_LEN));
|
| +}
|
| +
|
| +TEST(NtlmClientTest, GenerateNtlmHashV1PasswordChangesHash) {
|
| + base::string16 password1 = base::UTF8ToUTF16("pwd01");
|
| + base::string16 password2 = base::UTF8ToUTF16("pwd02");
|
| + uint8_t hash1[NTLM_HASH_LEN];
|
| + uint8_t hash2[NTLM_HASH_LEN];
|
| +
|
| + GenerateNtlmHashV1(password1, hash1);
|
| + GenerateNtlmHashV1(password2, hash2);
|
| +
|
| + // Verify that the hash is different with a different password.
|
| + ASSERT_NE(0, memcmp(hash1, hash2, NTLM_HASH_LEN));
|
| +}
|
| +
|
| +TEST(NtlmClientTest, GenerateResponsesV1SpecTests) {
|
| + uint8_t lm_response[RESPONSE_V1_LEN];
|
| + uint8_t ntlm_response[RESPONSE_V1_LEN];
|
| + GenerateResponsesV1(NTLM_PASSWORD, SERVER_CHALLENGE, lm_response,
|
| + ntlm_response);
|
| +
|
| + ASSERT_EQ(0,
|
| + memcmp(EXPECTED_V1_NTLM_RESPONSE, ntlm_response, RESPONSE_V1_LEN));
|
| +
|
| + // This implementation never sends an LMv1 response (spec equivalent of the
|
| + // client variable NoLMResponseNTLMv1 being false) so the LM response is
|
| + // equal to the NTLM response when
|
| + // NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY is not negotiated. See
|
| + // [MS-NLMP] Section 3.3.1.
|
| + ASSERT_EQ(0, memcmp(EXPECTED_V1_NTLM_RESPONSE, lm_response, RESPONSE_V1_LEN));
|
| +}
|
| +
|
| +TEST(NtlmClientTest, GenerateResponsesV1WithSSSpecTests) {
|
| + uint8_t lm_response[RESPONSE_V1_LEN];
|
| + uint8_t ntlm_response[RESPONSE_V1_LEN];
|
| + GenerateResponsesV1WithSS(NTLM_PASSWORD, SERVER_CHALLENGE, CLIENT_CHALLENGE,
|
| + lm_response, ntlm_response);
|
| +
|
| + ASSERT_EQ(
|
| + 0, memcmp(EXPECTED_V1_WITH_SS_LM_RESPONSE, lm_response, RESPONSE_V1_LEN));
|
| + ASSERT_EQ(0, memcmp(EXPECTED_V1_WITH_SS_NTLM_RESPONSE, ntlm_response,
|
| + RESPONSE_V1_LEN));
|
| +}
|
| +
|
| +TEST(NtlmClientTest, GenerateResponsesV1WithSSClientChallengeUsed) {
|
| + uint8_t lm_response1[RESPONSE_V1_LEN];
|
| + uint8_t lm_response2[RESPONSE_V1_LEN];
|
| + uint8_t ntlm_response1[RESPONSE_V1_LEN];
|
| + uint8_t ntlm_response2[RESPONSE_V1_LEN];
|
| + uint8_t client_challenge1[CHALLENGE_LEN];
|
| + uint8_t client_challenge2[CHALLENGE_LEN];
|
| +
|
| + memset(client_challenge1, 0x01, CHALLENGE_LEN);
|
| + memset(client_challenge2, 0x02, CHALLENGE_LEN);
|
| +
|
| + GenerateResponsesV1WithSS(NTLM_PASSWORD, SERVER_CHALLENGE, client_challenge1,
|
| + lm_response1, ntlm_response1);
|
| + GenerateResponsesV1WithSS(NTLM_PASSWORD, SERVER_CHALLENGE, client_challenge2,
|
| + lm_response2, ntlm_response2);
|
| +
|
| + // The point of session security is that the client can introduce some
|
| + // randomness, so verify different client_challenge gives a different result.
|
| + ASSERT_NE(0, memcmp(lm_response1, lm_response2, RESPONSE_V1_LEN));
|
| + ASSERT_NE(0, memcmp(ntlm_response1, ntlm_response2, RESPONSE_V1_LEN));
|
| +
|
| + // With session security the lm and ntlm hash should be different.
|
| + ASSERT_NE(0, memcmp(lm_response1, ntlm_response1, RESPONSE_V1_LEN));
|
| + ASSERT_NE(0, memcmp(lm_response2, ntlm_response2, RESPONSE_V1_LEN));
|
| +}
|
| +
|
| +TEST(NtlmClientTest, GenerateResponsesV1WithSSVerifySSUsed) {
|
| + uint8_t lm_response1[RESPONSE_V1_LEN];
|
| + uint8_t lm_response2[RESPONSE_V1_LEN];
|
| + uint8_t ntlm_response1[RESPONSE_V1_LEN];
|
| + uint8_t ntlm_response2[RESPONSE_V1_LEN];
|
| +
|
| + GenerateResponsesV1WithSS(NTLM_PASSWORD, SERVER_CHALLENGE, CLIENT_CHALLENGE,
|
| + lm_response1, ntlm_response1);
|
| + GenerateResponsesV1(NTLM_PASSWORD, SERVER_CHALLENGE, lm_response2,
|
| + ntlm_response2);
|
| +
|
| + // Verify that the responses with session security are not the
|
| + // same as without it.
|
| + ASSERT_NE(0, memcmp(lm_response1, lm_response2, RESPONSE_V1_LEN));
|
| + ASSERT_NE(0, memcmp(ntlm_response1, ntlm_response2, RESPONSE_V1_LEN));
|
| +}
|
| +
|
| +} // namespace ntlm
|
| +} // namespace net
|
|
|