Commit b89acda4 authored by zentaro's avatar zentaro Committed by Commit Bot

Add unit tests for existing NTLM portable code.

- Adds tests for existing implementation.
- Minor code change to reject certain invalid messages.

NOTE: The existing code just ignored the target name field if it
had length and/or offset outside the bounds of the message. This
change explicitly rejects that case in order to test that the
behavior is correct.

BUG=chromium:22532
TEST=builds and tests pass

Review-Url: https://codereview.chromium.org/2873673002
Cr-Commit-Position: refs/heads/master@{#486604}
parent 8f05f8dd
......@@ -795,8 +795,6 @@ component("net") {
"http/bidirectional_stream_request_info.h",
"http/broken_alternative_services.cc",
"http/broken_alternative_services.h",
"http/des.cc",
"http/des.h",
"http/failing_http_transaction_factory.cc",
"http/failing_http_transaction_factory.h",
"http/http_auth.cc",
......@@ -885,8 +883,6 @@ component("net") {
"http/http_transaction.h",
"http/http_transaction_factory.h",
"http/http_version.h",
"http/md4.cc",
"http/md4.h",
"http/partial_data.cc",
"http/partial_data.h",
"http/proxy_client_socket.cc",
......@@ -1028,6 +1024,12 @@ component("net") {
"nqe/throughput_analyzer.cc",
"nqe/throughput_analyzer.h",
"nqe/weighted_observation.h",
"ntlm/des.cc",
"ntlm/des.h",
"ntlm/md4.cc",
"ntlm/md4.h",
"ntlm/ntlm.cc",
"ntlm/ntlm.h",
"ntlm/ntlm_buffer_reader.cc",
"ntlm/ntlm_buffer_reader.h",
"ntlm/ntlm_buffer_writer.cc",
......@@ -1776,6 +1778,12 @@ component("net") {
if (is_win) {
sources -= [
"ntlm/des.cc",
"ntlm/des.h",
"ntlm/md4.cc",
"ntlm/md4.h",
"ntlm/ntlm.cc",
"ntlm/ntlm.h",
"ntlm/ntlm_buffer_reader.cc",
"ntlm/ntlm_buffer_reader.h",
"ntlm/ntlm_buffer_writer.cc",
......@@ -4705,7 +4713,6 @@ test("net_unittests") {
"ftp/ftp_util_unittest.cc",
"http/bidirectional_stream_unittest.cc",
"http/broken_alternative_services_unittest.cc",
"http/des_unittest.cc",
"http/http_auth_cache_unittest.cc",
"http/http_auth_challenge_tokenizer_unittest.cc",
"http/http_auth_controller_unittest.cc",
......@@ -4717,6 +4724,7 @@ test("net_unittests") {
"http/http_auth_handler_mock.cc",
"http/http_auth_handler_mock.h",
"http/http_auth_handler_negotiate_unittest.cc",
"http/http_auth_handler_ntlm_portable_unittest.cc",
"http/http_auth_handler_unittest.cc",
"http/http_auth_multi_round_parse_unittest.cc",
"http/http_auth_preferences_unittest.cc",
......@@ -4844,8 +4852,11 @@ test("net_unittests") {
"nqe/observation_buffer_unittest.cc",
"nqe/socket_watcher_unittest.cc",
"nqe/throughput_analyzer_unittest.cc",
"ntlm/des_unittest.cc",
"ntlm/ntlm_buffer_reader_unittest.cc",
"ntlm/ntlm_buffer_writer_unittest.cc",
"ntlm/ntlm_test_data.h",
"ntlm/ntlm_unittest.cc",
"proxy/dhcp_proxy_script_adapter_fetcher_win_unittest.cc",
"proxy/dhcp_proxy_script_fetcher_factory_unittest.cc",
"proxy/dhcp_proxy_script_fetcher_win_unittest.cc",
......@@ -5261,8 +5272,12 @@ test("net_unittests") {
if (is_win) {
sources -= [
"http/http_auth_handler_ntlm_portable_unittest.cc",
"ntlm/des_unittest.cc",
"ntlm/ntlm_buffer_reader_unittest.cc",
"ntlm/ntlm_buffer_writer_unittest.cc",
"ntlm/ntlm_test_data.h",
"ntlm/ntlm_unittest.cc",
]
}
......
......@@ -19,8 +19,8 @@
#include "base/strings/utf_string_conversions.h"
#include "net/base/net_errors.h"
#include "net/base/network_interfaces.h"
#include "net/http/des.h"
#include "net/http/md4.h"
#include "net/ntlm/des.h"
#include "net/ntlm/md4.h"
namespace net {
......@@ -363,11 +363,19 @@ static int ParseType2Msg(const void* in_buf, uint32_t in_len, Type2Msg* msg) {
uint32_t offset = ReadUint32(cursor); // get offset from in_buf
msg->target_len = 0;
msg->target = NULL;
// Check the offset / length combo is in range of the input buffer, including
// integer overflow checking.
if (offset + target_len > offset && offset + target_len <= in_len) {
msg->target_len = target_len;
msg->target = ((const uint8_t*)in_buf) + offset;
// Target length 0 is valid and indicates no target information.
if (target_len != 0) {
// Check the offset / length combo is in range of the input buffer,
// including integer overflow checking.
if (target_len <= in_len && in_len - offset >= target_len) {
msg->target_len = target_len;
msg->target = ((const uint8_t*)in_buf) + offset;
} else {
// Reject a message with a non-zero target length that
// would cause an overflow.
return ERR_UNEXPECTED;
}
}
// read flags
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/http/des.h"
#include "net/ntlm/des.h"
#include "base/logging.h"
#include "crypto/openssl_util.h"
......@@ -11,6 +11,7 @@
// The iOS version of DESEncrypt is our own code.
// DESSetKeyParity and DESMakeKey are based on
// mozilla/security/manager/ssl/src/nsNTLMAuthModule.cpp, CVS rev. 1.14.
/* clang-format off */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
......
......@@ -4,7 +4,7 @@
#include <string.h>
#include "net/http/des.h"
#include "net/ntlm/des.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
......
......@@ -4,6 +4,7 @@
// WARNING: MD4 is cryptographically weak. Do not use MD4 except in NTLM
// authentication.
/* clang-format off */
/* vim:set ts=2 sw=2 et cindent: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
......@@ -45,7 +46,7 @@
* "clean room" MD4 implementation (see RFC 1320)
*/
#include "net/http/md4.h"
#include "net/ntlm/md4.h"
#include <string.h>
......
// 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.
#include "net/ntlm/ntlm.h"
#include <string.h>
#include "base/logging.h"
#include "base/md5.h"
#include "net/ntlm/des.h"
#include "net/ntlm/md4.h"
#include "net/ntlm/ntlm_buffer_writer.h"
namespace net {
namespace ntlm {
void GenerateNtlmHashV1(const base::string16& password, uint8_t* hash) {
size_t length = password.length() * 2;
NtlmBufferWriter writer(length);
// The writer will handle the big endian case if necessary.
bool result = writer.WriteUtf16String(password);
DCHECK(result);
weak_crypto::MD4Sum(
reinterpret_cast<const uint8_t*>(writer.GetBuffer().data()), length,
hash);
}
void GenerateResponseDesl(const uint8_t* hash,
const uint8_t* challenge,
uint8_t* response) {
// See DESL(K, D) function in [MS-NLMP] Section 6
uint8_t key1[8];
uint8_t key2[8];
uint8_t key3[8];
// The last 2 bytes of the hash are zero padded (5 zeros) as the
// input to generate key3.
uint8_t padded_hash[7];
padded_hash[0] = hash[14];
padded_hash[1] = hash[15];
memset(padded_hash + 2, 0, 5);
DESMakeKey(hash, key1);
DESMakeKey(hash + 7, key2);
DESMakeKey(padded_hash, key3);
DESEncrypt(key1, challenge, response);
DESEncrypt(key2, challenge, response + 8);
DESEncrypt(key3, challenge, response + 16);
}
void GenerateNtlmResponseV1(const base::string16& password,
const uint8_t* challenge,
uint8_t* ntlm_response) {
uint8_t ntlm_hash[kNtlmHashLen];
GenerateNtlmHashV1(password, ntlm_hash);
GenerateResponseDesl(ntlm_hash, challenge, ntlm_response);
}
void GenerateResponsesV1(const base::string16& password,
const uint8_t* server_challenge,
uint8_t* lm_response,
uint8_t* ntlm_response) {
GenerateNtlmResponseV1(password, server_challenge, ntlm_response);
// In NTLM v1 (with LMv1 disabled), the lm_response and ntlm_response are the
// same. So just copy the ntlm_response into the lm_response.
memcpy(lm_response, ntlm_response, kResponseLenV1);
}
void GenerateLMResponseV1WithSessionSecurity(const uint8_t* client_challenge,
uint8_t* lm_response) {
// In NTLM v1 with Session Security (aka NTLM2) the lm_response is 8 bytes of
// client challenge and 16 bytes of zeros. (See 3.3.1)
memcpy(lm_response, client_challenge, kChallengeLen);
memset(lm_response + kChallengeLen, 0, kResponseLenV1 - kChallengeLen);
}
void GenerateSessionHashV1WithSessionSecurity(const uint8_t* server_challenge,
const uint8_t* client_challenge,
base::MD5Digest* session_hash) {
base::MD5Context ctx;
base::MD5Init(&ctx);
base::MD5Update(
&ctx, base::StringPiece(reinterpret_cast<const char*>(server_challenge),
kChallengeLen));
base::MD5Update(
&ctx, base::StringPiece(reinterpret_cast<const char*>(client_challenge),
kChallengeLen));
base::MD5Final(session_hash, &ctx);
}
void GenerateNtlmResponseV1WithSessionSecurity(const base::string16& password,
const uint8_t* server_challenge,
const uint8_t* client_challenge,
uint8_t* ntlm_response) {
// Generate the NTLMv1 Hash.
uint8_t ntlm_hash[kNtlmHashLen];
GenerateNtlmHashV1(password, ntlm_hash);
// Generate the NTLMv1 Session Hash.
base::MD5Digest session_hash;
GenerateSessionHashV1WithSessionSecurity(server_challenge, client_challenge,
&session_hash);
// Only the first 8 bytes of |session_hash.a| are actually used.
GenerateResponseDesl(ntlm_hash, session_hash.a, ntlm_response);
}
void GenerateResponsesV1WithSessionSecurity(const base::string16& password,
const uint8_t* server_challenge,
const uint8_t* client_challenge,
uint8_t* lm_response,
uint8_t* ntlm_response) {
GenerateLMResponseV1WithSessionSecurity(client_challenge, lm_response);
GenerateNtlmResponseV1WithSessionSecurity(password, server_challenge,
client_challenge, ntlm_response);
}
} // namespace ntlm
} // namespace net
// 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.
// Based on [MS-NLMP]: NT LAN Manager (NTLM) Authentication Protocol
// Specification version 28.0 [1]. Additional NTLM reference [2].
//
// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
// [2] http://davenport.sourceforge.net/ntlm.html
#ifndef NET_BASE_NTLM_H_
#define NET_BASE_NTLM_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include "base/strings/string16.h"
#include "base/strings/string_piece.h"
#include "net/base/net_export.h"
#include "net/ntlm/ntlm_constants.h"
namespace base {
struct MD5Digest;
}
namespace net {
namespace ntlm {
// Generates the NTLMv1 Hash and writes the |kNtlmHashLen| byte result to
// |hash|. Defined by NTOWFv1() in [MS-NLMP] Section 3.3.1.
NET_EXPORT_PRIVATE void GenerateNtlmHashV1(const base::string16& password,
uint8_t* hash);
// Generates the |kResponseLenV1| byte NTLMv1 response field according to the
// DESL(K, V) function in [MS-NLMP] Section 6.
//
// |hash| must contain |kNtlmHashLen| bytes.
// |challenge| must contain |kChallengeLen| bytes.
// |response| must contain |kResponseLenV1| bytes.
NET_EXPORT_PRIVATE void GenerateResponseDesl(const uint8_t* hash,
const uint8_t* challenge,
uint8_t* response);
// Generates the NTLM Response field for NTLMv1 without extended session
// security. Defined by ComputeResponse() in [MS-NLMP] Section 3.3.1 for the
// case where NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY is not set.
//
// |server_challenge| must contain |kChallengeLen| bytes.
// |ntlm_response| must contain |kResponseLenV1| bytes.
NET_EXPORT_PRIVATE void GenerateNtlmResponseV1(const base::string16& password,
const uint8_t* server_challenge,
uint8_t* ntlm_response);
// Generates both the LM Response and NTLM Response fields for NTLMv1 based
// on the users password and the servers challenge. Both the LM and NTLM
// Response are the result of |GenerateNtlmResponseV1|.
//
// NOTE: This should not be used. The default flags always include session
// security. Session security can however be disabled in NTLMv1 by omitting
// NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY from the flag set used to
// initialize |NtlmClient|.
//
// The default flags include this flag and the client will not be
// downgraded by the server.
//
// |server_challenge| must contain |kChallengeLen| bytes.
// |lm_response| must contain |kResponseLenV1| bytes.
// |ntlm_response| must contain |kResponseLenV1| bytes.
NET_EXPORT_PRIVATE void GenerateResponsesV1(const base::string16& password,
const uint8_t* server_challenge,
uint8_t* lm_response,
uint8_t* ntlm_response);
// The LM Response in V1 with extended session security is 8 bytes of the
// |client_challenge| then 16 bytes of zero. This is the value
// LmChallengeResponse in ComputeResponse() when
// NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY is set. See [MS-NLMP] Section
// 3.3.1.
//
// |lm_response| must contain |kResponseLenV1| bytes.
NET_EXPORT_PRIVATE void GenerateLMResponseV1WithSessionSecurity(
const uint8_t* client_challenge,
uint8_t* lm_response);
// The |session_hash| is MD5(CONCAT(server_challenge, client_challenge)).
// It is used instead of just |server_challenge| in NTLMv1 when
// NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY is set. See [MS-NLMP] Section
// 3.3.1.
//
// |server_challenge| must contain |kChallengeLen| bytes.
// |client_challenge| must contain |kChallengeLen| bytes.
NET_EXPORT_PRIVATE void GenerateSessionHashV1WithSessionSecurity(
const uint8_t* server_challenge,
const uint8_t* client_challenge,
base::MD5Digest* session_hash);
// Generates the NTLM Response for NTLMv1 with session security.
// Defined by ComputeResponse() in [MS-NLMP] Section 3.3.1 for the
// case where NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY is set.
//
// |server_challenge| must contain |kChallengeLen| bytes.
// |client_challenge| must contain |kChallengeLen| bytes.
// |ntlm_response| must contain |kResponseLenV1| bytes.
NET_EXPORT_PRIVATE void GenerateNtlmResponseV1WithSessionSecurity(
const base::string16& password,
const uint8_t* server_challenge,
const uint8_t* client_challenge,
uint8_t* ntlm_response);
// Generates the responses for V1 with extended session security.
// This is also known as NTLM2 (which is not the same as NTLMv2).
// |lm_response| is the result of |GenerateLMResponseV1WithSessionSecurity| and
// |ntlm_response| is the result of |GenerateNtlmResponseV1WithSessionSecurity|.
// See [MS-NLMP] Section 3.3.1.
//
// |server_challenge| must contain |kChallengeLen| bytes.
// |client_challenge| must contain |kChallengeLen| bytes.
// |ntlm_response| must contain |kResponseLenV1| bytes.
NET_EXPORT_PRIVATE void GenerateResponsesV1WithSessionSecurity(
const base::string16& password,
const uint8_t* server_challenge,
const uint8_t* client_challenge,
uint8_t* lm_response,
uint8_t* ntlm_response);
} // namespace ntlm
} // namespace net
#endif // NET_BASE_NTLM_H_
......@@ -75,6 +75,7 @@ static constexpr size_t kSignatureLen = arraysize(kSignature);
static constexpr size_t kSecurityBufferLen =
(2 * sizeof(uint16_t)) + sizeof(uint32_t);
static constexpr size_t kNegotiateMessageLen = 32;
static constexpr size_t kChallengeHeaderLen = 32;
static constexpr size_t kResponseLenV1 = 24;
static constexpr size_t kChallengeLen = 8;
static constexpr size_t kNtlmHashLen = 16;
......
// 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.
// This file contains common input and result values use to verify the NTLM
// implementation. They are defined in [MS-NLMP] Section 4.2 [1].
//
// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
#ifndef NET_BASE_NTLM_TEST_DATA_H_
#define NET_BASE_NTLM_TEST_DATA_H_
#include "net/ntlm/ntlm_constants.h"
namespace net {
namespace ntlm {
namespace test {
// Common input values defined in [MS-NLMP] Section 4.2.1.
constexpr base::char16 kPassword[] = {'P', 'a', 's', 's', 'w',
'o', 'r', 'd', '\0'};
constexpr base::char16 kNtlmDomain[] = {'D', 'o', 'm', 'a', 'i', 'n', '\0'};
constexpr base::char16 kUser[] = {'U', 's', 'e', 'r', '\0'};
constexpr base::char16 kHostname[] = {'C', 'O', 'M', 'P', 'U',
'T', 'E', 'R', '\0'};
// ASCII Versions of the above strings.
constexpr char kNtlmDomainAscii[] = "Domain";
constexpr char kUserAscii[] = "User";
constexpr char kHostnameAscii[] = "COMPUTER";
// Challenge vectors defined in [MS-NLMP] Section 4.2.1.
constexpr uint8_t kServerChallenge[kChallengeLen] = {0x01, 0x23, 0x45, 0x67,
0x89, 0xab, 0xcd, 0xef};
constexpr uint8_t kClientChallenge[kChallengeLen] = {0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa};
// 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] - |NEGOTIATE_MESSAGE_FLAGS| (Flags = 0x00088207)
// [24-31] - |SERVER_CHALLENGE| (Server Challenge)
//
// See [MS-NLMP] Section 2.2.2.2 for more information about the Challenge
// message.
constexpr uint8_t kMinChallengeMessage[kChallengeHeaderLen] = {
'N', 'T', 'L', 'M', 'S', 'S', 'P', '\0', 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0x82,
0x08, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
// Test result value for NTOWFv1() defined in [MS-NLMP] Section 4.2.2.1.2.
constexpr uint8_t kExpectedNtlmHashV1[kNtlmHashLen] = {
0xa4, 0xf4, 0x9c, 0x40, 0x65, 0x10, 0xbd, 0xca,
0xb6, 0x82, 0x4e, 0xe7, 0xc3, 0x0f, 0xd8, 0x52};
// Test result value defined in [MS-NLMP] Section 4.2.2.1.
constexpr uint8_t kExpectedNtlmResponseV1[kResponseLenV1] = {
0x67, 0xc4, 0x30, 0x11, 0xf3, 0x02, 0x98, 0xa2, 0xad, 0x35, 0xec, 0xe6,
0x4f, 0x16, 0x33, 0x1c, 0x44, 0xbd, 0xbe, 0xd9, 0x27, 0x84, 0x1f, 0x94};
// Test result value defined in [MS-NLMP] Section 4.2.3.2.2.
constexpr uint8_t kExpectedNtlmResponseWithV1SS[kResponseLenV1] = {
0x75, 0x37, 0xf8, 0x03, 0xae, 0x36, 0x71, 0x28, 0xca, 0x45, 0x82, 0x04,
0xbd, 0xe7, 0xca, 0xf8, 0x1e, 0x97, 0xed, 0x26, 0x83, 0x26, 0x72, 0x32};
// Test result value defined in [MS-NLMP] Section 4.2.3.2.1.
constexpr uint8_t kExpectedLmResponseWithV1SS[kResponseLenV1] = {
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
} // namespace test
} // namespace ntlm
} // namespace net
#endif // NET_BASE_NTLM_TEST_DATA_H_
\ No newline at end of file
// 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(NtlmTest, GenerateNtlmHashV1PasswordSpecTests) {
uint8_t hash[kNtlmHashLen];
GenerateNtlmHashV1(test::kPassword, hash);
ASSERT_EQ(0, memcmp(hash, test::kExpectedNtlmHashV1, kNtlmHashLen));
}
TEST(NtlmTest, GenerateNtlmHashV1PasswordChangesHash) {
base::string16 password1 = base::UTF8ToUTF16("pwd01");
base::string16 password2 = base::UTF8ToUTF16("pwd02");
uint8_t hash1[kNtlmHashLen];
uint8_t hash2[kNtlmHashLen];
GenerateNtlmHashV1(password1, hash1);
GenerateNtlmHashV1(password2, hash2);
// Verify that the hash is different with a different password.
ASSERT_NE(0, memcmp(hash1, hash2, kNtlmHashLen));
}
TEST(NtlmTest, GenerateResponsesV1SpecTests) {
uint8_t lm_response[kResponseLenV1];
uint8_t ntlm_response[kResponseLenV1];
GenerateResponsesV1(test::kPassword, test::kServerChallenge, lm_response,
ntlm_response);
ASSERT_EQ(
0, memcmp(test::kExpectedNtlmResponseV1, ntlm_response, kResponseLenV1));
// 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(test::kExpectedNtlmResponseV1, lm_response, kResponseLenV1));
}
TEST(NtlmTest, GenerateResponsesV1WithSessionSecuritySpecTests) {
uint8_t lm_response[kResponseLenV1];
uint8_t ntlm_response[kResponseLenV1];
GenerateResponsesV1WithSessionSecurity(
test::kPassword, test::kServerChallenge, test::kClientChallenge,
lm_response, ntlm_response);
ASSERT_EQ(0, memcmp(test::kExpectedLmResponseWithV1SS, lm_response,
kResponseLenV1));
ASSERT_EQ(0, memcmp(test::kExpectedNtlmResponseWithV1SS, ntlm_response,
kResponseLenV1));
}
TEST(NtlmTest, GenerateResponsesV1WithSessionSecurityClientChallengeUsed) {
uint8_t lm_response1[kResponseLenV1];
uint8_t lm_response2[kResponseLenV1];
uint8_t ntlm_response1[kResponseLenV1];
uint8_t ntlm_response2[kResponseLenV1];
uint8_t client_challenge1[kChallengeLen];
uint8_t client_challenge2[kChallengeLen];
memset(client_challenge1, 0x01, kChallengeLen);
memset(client_challenge2, 0x02, kChallengeLen);
GenerateResponsesV1WithSessionSecurity(
test::kPassword, test::kServerChallenge, client_challenge1, lm_response1,
ntlm_response1);
GenerateResponsesV1WithSessionSecurity(
test::kPassword, test::kServerChallenge, 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, kResponseLenV1));
ASSERT_NE(0, memcmp(ntlm_response1, ntlm_response2, kResponseLenV1));
// With session security the lm and ntlm hash should be different.
ASSERT_NE(0, memcmp(lm_response1, ntlm_response1, kResponseLenV1));
ASSERT_NE(0, memcmp(lm_response2, ntlm_response2, kResponseLenV1));
}
TEST(NtlmTest, GenerateResponsesV1WithSessionSecurityVerifySSUsed) {
uint8_t lm_response1[kResponseLenV1];
uint8_t lm_response2[kResponseLenV1];
uint8_t ntlm_response1[kResponseLenV1];
uint8_t ntlm_response2[kResponseLenV1];
GenerateResponsesV1WithSessionSecurity(
test::kPassword, test::kServerChallenge, test::kClientChallenge,
lm_response1, ntlm_response1);
GenerateResponsesV1(test::kPassword, test::kServerChallenge, 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, kResponseLenV1));
ASSERT_NE(0, memcmp(ntlm_response1, ntlm_response2, kResponseLenV1));
}
} // namespace ntlm
} // namespace net
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment