• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7 #pragma allow_unsafe_buffers
8 #endif
9 
10 #include "net/ntlm/ntlm_buffer_reader.h"
11 
12 #include "base/strings/utf_string_conversions.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 namespace net::ntlm {
16 
TEST(NtlmBufferReaderTest,Initialization)17 TEST(NtlmBufferReaderTest, Initialization) {
18   const uint8_t buf[1] = {0};
19   NtlmBufferReader reader(buf);
20 
21   ASSERT_EQ(std::size(buf), reader.GetLength());
22   ASSERT_EQ(0u, reader.GetCursor());
23   ASSERT_FALSE(reader.IsEndOfBuffer());
24   ASSERT_TRUE(reader.CanRead(1));
25   ASSERT_FALSE(reader.CanRead(2));
26   ASSERT_TRUE(reader.CanReadFrom(0, 1));
27   ASSERT_TRUE(reader.CanReadFrom(SecurityBuffer(0, 1)));
28   ASSERT_FALSE(reader.CanReadFrom(1, 1));
29   ASSERT_FALSE(reader.CanReadFrom(SecurityBuffer(1, 1)));
30   ASSERT_FALSE(reader.CanReadFrom(0, 2));
31   ASSERT_FALSE(reader.CanReadFrom(SecurityBuffer(0, 2)));
32 
33   // With length=0 the offset can be out of bounds.
34   ASSERT_TRUE(reader.CanReadFrom(99, 0));
35   ASSERT_TRUE(reader.CanReadFrom(SecurityBuffer(99, 0)));
36 }
37 
TEST(NtlmBufferReaderTest,EmptyBuffer)38 TEST(NtlmBufferReaderTest, EmptyBuffer) {
39   std::vector<uint8_t> b;
40   NtlmBufferReader reader(b);
41 
42   ASSERT_EQ(0u, reader.GetCursor());
43   ASSERT_EQ(0u, reader.GetLength());
44   ASSERT_TRUE(reader.CanRead(0));
45   ASSERT_FALSE(reader.CanRead(1));
46   ASSERT_TRUE(reader.IsEndOfBuffer());
47 
48   // A read from an empty (zero-byte) source into an empty (zero-byte)
49   // destination buffer should succeed as a no-op.
50   std::vector<uint8_t> dest;
51   ASSERT_TRUE(reader.ReadBytes(dest));
52 
53   // A read from a non-empty source into an empty (zero-byte) destination
54   // buffer should succeed as a no-op.
55   std::vector<uint8_t> b2{0x01};
56   NtlmBufferReader reader2(b2);
57   ASSERT_EQ(0u, reader2.GetCursor());
58   ASSERT_EQ(1u, reader2.GetLength());
59 
60   ASSERT_TRUE(reader2.CanRead(0));
61   ASSERT_TRUE(reader2.ReadBytes(dest));
62 
63   ASSERT_EQ(0u, reader2.GetCursor());
64   ASSERT_EQ(1u, reader2.GetLength());
65 }
66 
TEST(NtlmBufferReaderTest,NullBuffer)67 TEST(NtlmBufferReaderTest, NullBuffer) {
68   NtlmBufferReader reader;
69 
70   ASSERT_EQ(0u, reader.GetCursor());
71   ASSERT_EQ(0u, reader.GetLength());
72   ASSERT_TRUE(reader.CanRead(0));
73   ASSERT_FALSE(reader.CanRead(1));
74   ASSERT_TRUE(reader.IsEndOfBuffer());
75 
76   // A read from a null source into an empty (zero-byte) destination buffer
77   // should succeed as a no-op.
78   std::vector<uint8_t> dest;
79   ASSERT_TRUE(reader.ReadBytes(dest));
80 }
81 
TEST(NtlmBufferReaderTest,Read16)82 TEST(NtlmBufferReaderTest, Read16) {
83   const uint8_t buf[2] = {0x22, 0x11};
84   const uint16_t expected = 0x1122;
85 
86   NtlmBufferReader reader(buf);
87 
88   uint16_t actual;
89   ASSERT_TRUE(reader.ReadUInt16(&actual));
90   ASSERT_EQ(expected, actual);
91   ASSERT_TRUE(reader.IsEndOfBuffer());
92   ASSERT_FALSE(reader.ReadUInt16(&actual));
93 }
94 
TEST(NtlmBufferReaderTest,Read32)95 TEST(NtlmBufferReaderTest, Read32) {
96   const uint8_t buf[4] = {0x44, 0x33, 0x22, 0x11};
97   const uint32_t expected = 0x11223344;
98 
99   NtlmBufferReader reader(buf);
100 
101   uint32_t actual;
102   ASSERT_TRUE(reader.ReadUInt32(&actual));
103   ASSERT_EQ(expected, actual);
104   ASSERT_TRUE(reader.IsEndOfBuffer());
105   ASSERT_FALSE(reader.ReadUInt32(&actual));
106 }
107 
TEST(NtlmBufferReaderTest,Read64)108 TEST(NtlmBufferReaderTest, Read64) {
109   const uint8_t buf[8] = {0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
110   const uint64_t expected = 0x1122334455667788;
111 
112   NtlmBufferReader reader(buf);
113 
114   uint64_t actual;
115   ASSERT_TRUE(reader.ReadUInt64(&actual));
116   ASSERT_EQ(expected, actual);
117   ASSERT_TRUE(reader.IsEndOfBuffer());
118   ASSERT_FALSE(reader.ReadUInt64(&actual));
119 }
120 
TEST(NtlmBufferReaderTest,ReadBytes)121 TEST(NtlmBufferReaderTest, ReadBytes) {
122   const uint8_t expected[8] = {0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
123   uint8_t actual[8];
124 
125   NtlmBufferReader reader(expected);
126 
127   ASSERT_TRUE(reader.ReadBytes(actual));
128   ASSERT_EQ(0, memcmp(actual, expected, std::size(actual)));
129   ASSERT_TRUE(reader.IsEndOfBuffer());
130   ASSERT_FALSE(reader.ReadBytes(base::span(actual, 1u)));
131 }
132 
TEST(NtlmBufferReaderTest,ReadSecurityBuffer)133 TEST(NtlmBufferReaderTest, ReadSecurityBuffer) {
134   const uint8_t buf[8] = {0x22, 0x11, 0xFF, 0xEE, 0x88, 0x77, 0x66, 0x55};
135   const uint16_t length = 0x1122;
136   const uint32_t offset = 0x55667788;
137 
138   NtlmBufferReader reader(buf);
139 
140   SecurityBuffer sec_buf;
141   ASSERT_TRUE(reader.ReadSecurityBuffer(&sec_buf));
142   ASSERT_EQ(length, sec_buf.length);
143   ASSERT_EQ(offset, sec_buf.offset);
144   ASSERT_TRUE(reader.IsEndOfBuffer());
145   ASSERT_FALSE(reader.ReadSecurityBuffer(&sec_buf));
146 }
147 
TEST(NtlmBufferReaderTest,ReadSecurityBufferPastEob)148 TEST(NtlmBufferReaderTest, ReadSecurityBufferPastEob) {
149   const uint8_t buf[7] = {0};
150   NtlmBufferReader reader(buf);
151 
152   SecurityBuffer sec_buf;
153   ASSERT_FALSE(reader.ReadSecurityBuffer(&sec_buf));
154 }
155 
TEST(NtlmBufferReaderTest,ReadPayloadAsBufferReader)156 TEST(NtlmBufferReaderTest, ReadPayloadAsBufferReader) {
157   const uint8_t buf[8] = {0xff, 0xff, 0x11, 0x22, 0x33, 0x44, 0xff, 0xff};
158   const uint32_t expected = 0x44332211;
159   NtlmBufferReader reader(buf);
160   ASSERT_EQ(0u, reader.GetCursor());
161 
162   // Create a security buffer with offset 2 and length 4.
163   SecurityBuffer sec_buf(2, 4);
164   NtlmBufferReader sub_reader;
165   ASSERT_EQ(0u, sub_reader.GetLength());
166   ASSERT_EQ(0u, sub_reader.GetCursor());
167 
168   // Read the 4 non-0xff bytes from the middle of |buf|.
169   ASSERT_TRUE(reader.ReadPayloadAsBufferReader(sec_buf, &sub_reader));
170 
171   // |reader| cursor should not move.
172   ASSERT_EQ(0u, reader.GetCursor());
173   ASSERT_EQ(sec_buf.length, sub_reader.GetLength());
174   ASSERT_EQ(0u, sub_reader.GetCursor());
175 
176   // Read from the payload in |sub_reader|.
177   uint32_t actual;
178   ASSERT_TRUE(sub_reader.ReadUInt32(&actual));
179   ASSERT_EQ(expected, actual);
180   ASSERT_TRUE(sub_reader.IsEndOfBuffer());
181 }
182 
TEST(NtlmBufferReaderTest,ReadPayloadBadOffset)183 TEST(NtlmBufferReaderTest, ReadPayloadBadOffset) {
184   const uint8_t buf[4] = {0};
185   NtlmBufferReader reader(buf);
186 
187   NtlmBufferReader sub_reader;
188   ASSERT_FALSE(
189       reader.ReadPayloadAsBufferReader(SecurityBuffer(4, 1), &sub_reader));
190 }
191 
TEST(NtlmBufferReaderTest,ReadPayloadBadLength)192 TEST(NtlmBufferReaderTest, ReadPayloadBadLength) {
193   const uint8_t buf[4] = {0};
194   NtlmBufferReader reader(buf);
195 
196   NtlmBufferReader sub_reader;
197   ASSERT_FALSE(
198       reader.ReadPayloadAsBufferReader(SecurityBuffer(3, 2), &sub_reader));
199 }
200 
TEST(NtlmBufferReaderTest,SkipSecurityBuffer)201 TEST(NtlmBufferReaderTest, SkipSecurityBuffer) {
202   const uint8_t buf[kSecurityBufferLen] = {0};
203 
204   NtlmBufferReader reader(buf);
205   ASSERT_TRUE(reader.SkipSecurityBuffer());
206   ASSERT_TRUE(reader.IsEndOfBuffer());
207   ASSERT_FALSE(reader.SkipSecurityBuffer());
208 }
209 
TEST(NtlmBufferReaderTest,SkipSecurityBufferPastEob)210 TEST(NtlmBufferReaderTest, SkipSecurityBufferPastEob) {
211   // The buffer is one byte shorter than security buffer.
212   const uint8_t buf[kSecurityBufferLen - 1] = {0};
213 
214   NtlmBufferReader reader(buf);
215   ASSERT_FALSE(reader.SkipSecurityBuffer());
216 }
217 
TEST(NtlmBufferReaderTest,SkipSecurityBufferWithValidationEmpty)218 TEST(NtlmBufferReaderTest, SkipSecurityBufferWithValidationEmpty) {
219   const uint8_t buf[kSecurityBufferLen] = {0, 0, 0, 0, 0, 0, 0, 0};
220 
221   NtlmBufferReader reader(buf);
222   ASSERT_TRUE(reader.SkipSecurityBufferWithValidation());
223   ASSERT_TRUE(reader.IsEndOfBuffer());
224   ASSERT_FALSE(reader.SkipSecurityBufferWithValidation());
225 }
226 
TEST(NtlmBufferReaderTest,SkipSecurityBufferWithValidationValid)227 TEST(NtlmBufferReaderTest, SkipSecurityBufferWithValidationValid) {
228   // A valid security buffer that points to the 1 payload byte.
229   const uint8_t buf[kSecurityBufferLen + 1] = {
230       0x01, 0, 0x01, 0, kSecurityBufferLen, 0, 0, 0, 0xFF};
231 
232   NtlmBufferReader reader(buf);
233   ASSERT_TRUE(reader.SkipSecurityBufferWithValidation());
234   ASSERT_EQ(kSecurityBufferLen, reader.GetCursor());
235   ASSERT_FALSE(reader.SkipSecurityBufferWithValidation());
236 }
237 
TEST(NtlmBufferReaderTest,SkipSecurityBufferWithValidationPayloadLengthPastEob)238 TEST(NtlmBufferReaderTest,
239      SkipSecurityBufferWithValidationPayloadLengthPastEob) {
240   // Security buffer with length that points past the end of buffer.
241   const uint8_t buf[kSecurityBufferLen + 1] = {
242       0x02, 0, 0x02, 0, kSecurityBufferLen, 0, 0, 0, 0xFF};
243 
244   NtlmBufferReader reader(buf);
245   ASSERT_FALSE(reader.SkipSecurityBufferWithValidation());
246 }
247 
TEST(NtlmBufferReaderTest,SkipSecurityBufferWithValidationPayloadOffsetPastEob)248 TEST(NtlmBufferReaderTest,
249      SkipSecurityBufferWithValidationPayloadOffsetPastEob) {
250   // Security buffer with offset that points past the end of buffer.
251   const uint8_t buf[kSecurityBufferLen + 1] = {
252       0x02, 0, 0x02, 0, kSecurityBufferLen + 1, 0, 0, 0, 0xFF};
253 
254   NtlmBufferReader reader(buf);
255   ASSERT_FALSE(reader.SkipSecurityBufferWithValidation());
256 }
257 
TEST(NtlmBufferReaderTest,SkipSecurityBufferWithValidationZeroLengthPayloadOffsetPastEob)258 TEST(NtlmBufferReaderTest,
259      SkipSecurityBufferWithValidationZeroLengthPayloadOffsetPastEob) {
260   // Security buffer with offset that points past the end of buffer but
261   // length is 0.
262   const uint8_t buf[kSecurityBufferLen] = {0, 0, 0, 0, kSecurityBufferLen + 1,
263                                            0, 0, 0};
264 
265   NtlmBufferReader reader(buf);
266   ASSERT_TRUE(reader.SkipSecurityBufferWithValidation());
267   ASSERT_EQ(kSecurityBufferLen, reader.GetCursor());
268 }
269 
TEST(NtlmBufferReaderTest,SkipBytes)270 TEST(NtlmBufferReaderTest, SkipBytes) {
271   const uint8_t buf[8] = {0};
272 
273   NtlmBufferReader reader(buf);
274 
275   ASSERT_TRUE(reader.SkipBytes(std::size(buf)));
276   ASSERT_TRUE(reader.IsEndOfBuffer());
277   ASSERT_FALSE(reader.SkipBytes(std::size(buf)));
278 }
279 
TEST(NtlmBufferReaderTest,SkipBytesPastEob)280 TEST(NtlmBufferReaderTest, SkipBytesPastEob) {
281   const uint8_t buf[8] = {0};
282 
283   NtlmBufferReader reader(buf);
284 
285   ASSERT_FALSE(reader.SkipBytes(std::size(buf) + 1));
286 }
287 
TEST(NtlmBufferReaderTest,MatchSignatureTooShort)288 TEST(NtlmBufferReaderTest, MatchSignatureTooShort) {
289   const uint8_t buf[7] = {0};
290 
291   NtlmBufferReader reader(buf);
292 
293   ASSERT_TRUE(reader.CanRead(7));
294   ASSERT_FALSE(reader.MatchSignature());
295 }
296 
TEST(NtlmBufferReaderTest,MatchSignatureNoMatch)297 TEST(NtlmBufferReaderTest, MatchSignatureNoMatch) {
298   // The last byte should be a 0.
299   const uint8_t buf[8] = {'N', 'T', 'L', 'M', 'S', 'S', 'P', 0xff};
300   NtlmBufferReader reader(buf);
301 
302   ASSERT_TRUE(reader.CanRead(8));
303   ASSERT_FALSE(reader.MatchSignature());
304 }
305 
TEST(NtlmBufferReaderTest,MatchSignatureOk)306 TEST(NtlmBufferReaderTest, MatchSignatureOk) {
307   const uint8_t buf[8] = {'N', 'T', 'L', 'M', 'S', 'S', 'P', 0};
308   NtlmBufferReader reader(buf);
309 
310   ASSERT_TRUE(reader.MatchSignature());
311   ASSERT_TRUE(reader.IsEndOfBuffer());
312 }
313 
TEST(NtlmBufferReaderTest,ReadInvalidMessageType)314 TEST(NtlmBufferReaderTest, ReadInvalidMessageType) {
315   // Only 0x01, 0x02, and 0x03 are valid message types.
316   const uint8_t buf[4] = {0x04, 0, 0, 0};
317   NtlmBufferReader reader(buf);
318 
319   MessageType message_type;
320   ASSERT_FALSE(reader.ReadMessageType(&message_type));
321 }
322 
TEST(NtlmBufferReaderTest,ReadMessageTypeNegotiate)323 TEST(NtlmBufferReaderTest, ReadMessageTypeNegotiate) {
324   const uint8_t buf[4] = {static_cast<uint8_t>(MessageType::kNegotiate), 0, 0,
325                           0};
326   NtlmBufferReader reader(buf);
327 
328   MessageType message_type;
329   ASSERT_TRUE(reader.ReadMessageType(&message_type));
330   ASSERT_EQ(MessageType::kNegotiate, message_type);
331   ASSERT_TRUE(reader.IsEndOfBuffer());
332 }
333 
TEST(NtlmBufferReaderTest,ReadMessageTypeChallenge)334 TEST(NtlmBufferReaderTest, ReadMessageTypeChallenge) {
335   const uint8_t buf[4] = {static_cast<uint8_t>(MessageType::kChallenge), 0, 0,
336                           0};
337   NtlmBufferReader reader(buf);
338 
339   MessageType message_type;
340   ASSERT_TRUE(reader.ReadMessageType(&message_type));
341   ASSERT_EQ(MessageType::kChallenge, message_type);
342   ASSERT_TRUE(reader.IsEndOfBuffer());
343 }
344 
TEST(NtlmBufferReaderTest,ReadTargetInfoEolOnly)345 TEST(NtlmBufferReaderTest, ReadTargetInfoEolOnly) {
346   // Buffer contains only an EOL terminator.
347   const uint8_t buf[4] = {0, 0, 0, 0};
348 
349   NtlmBufferReader reader(buf);
350 
351   std::vector<AvPair> av_pairs;
352   ASSERT_TRUE(reader.ReadTargetInfo(std::size(buf), &av_pairs));
353   ASSERT_TRUE(reader.IsEndOfBuffer());
354   ASSERT_TRUE(av_pairs.empty());
355 }
356 
TEST(NtlmBufferReaderTest,ReadTargetInfoEmpty)357 TEST(NtlmBufferReaderTest, ReadTargetInfoEmpty) {
358   NtlmBufferReader reader;
359 
360   std::vector<AvPair> av_pairs;
361   ASSERT_TRUE(reader.ReadTargetInfo(0, &av_pairs));
362   ASSERT_TRUE(reader.IsEndOfBuffer());
363   ASSERT_TRUE(av_pairs.empty());
364 }
365 
TEST(NtlmBufferReaderTest,ReadTargetInfoTimestampAndEolOnly)366 TEST(NtlmBufferReaderTest, ReadTargetInfoTimestampAndEolOnly) {
367   // Buffer contains a timestamp av pair and an EOL terminator.
368   const uint8_t buf[16] = {0x07, 0,    0x08, 0,    0x11, 0x22, 0x33, 0x44,
369                            0x55, 0x66, 0x77, 0x88, 0,    0,    0,    0};
370   const uint64_t expected_timestamp = 0x8877665544332211;
371 
372   NtlmBufferReader reader(buf);
373 
374   std::vector<AvPair> av_pairs;
375   ASSERT_TRUE(reader.ReadTargetInfo(std::size(buf), &av_pairs));
376   ASSERT_TRUE(reader.IsEndOfBuffer());
377   ASSERT_EQ(1u, av_pairs.size());
378 
379   // Verify the timestamp av pair.
380   ASSERT_EQ(TargetInfoAvId::kTimestamp, av_pairs[0].avid);
381   ASSERT_EQ(sizeof(uint64_t), av_pairs[0].avlen);
382   ASSERT_EQ(sizeof(uint64_t), av_pairs[0].buffer.size());
383   ASSERT_EQ(expected_timestamp, av_pairs[0].timestamp);
384 }
385 
TEST(NtlmBufferReaderTest,ReadTargetInfoFlagsAndEolOnly)386 TEST(NtlmBufferReaderTest, ReadTargetInfoFlagsAndEolOnly) {
387   // Buffer contains a flags av pair with the MIC bit and an EOL terminator.
388   const uint8_t buf[12] = {0x06, 0, 0x04, 0, 0x02, 0, 0, 0, 0, 0, 0, 0};
389 
390   NtlmBufferReader reader(buf);
391 
392   std::vector<AvPair> av_pairs;
393   ASSERT_TRUE(reader.ReadTargetInfo(std::size(buf), &av_pairs));
394   ASSERT_TRUE(reader.IsEndOfBuffer());
395   ASSERT_EQ(1u, av_pairs.size());
396 
397   // Verify the flags av pair.
398   ASSERT_EQ(TargetInfoAvId::kFlags, av_pairs[0].avid);
399   ASSERT_EQ(sizeof(TargetInfoAvFlags), av_pairs[0].avlen);
400   ASSERT_EQ(TargetInfoAvFlags::kMicPresent, av_pairs[0].flags);
401 }
402 
TEST(NtlmBufferReaderTest,ReadTargetInfoTooSmall)403 TEST(NtlmBufferReaderTest, ReadTargetInfoTooSmall) {
404   // Target info must least contain enough space for a terminator pair.
405   const uint8_t buf[3] = {0};
406 
407   NtlmBufferReader reader(buf);
408 
409   std::vector<AvPair> av_pairs;
410   ASSERT_FALSE(reader.ReadTargetInfo(std::size(buf), &av_pairs));
411 }
412 
TEST(NtlmBufferReaderTest,ReadTargetInfoInvalidTimestampSize)413 TEST(NtlmBufferReaderTest, ReadTargetInfoInvalidTimestampSize) {
414   // Timestamps must be 64 bits/8 bytes. A timestamp av pair with a
415   // different length is invalid.
416   const uint8_t buf[15] = {0x07, 0,    0x07, 0, 0x11, 0x22, 0x33, 0x44,
417                            0x55, 0x66, 0x77, 0, 0,    0,    0};
418 
419   NtlmBufferReader reader(buf);
420 
421   std::vector<AvPair> av_pairs;
422   ASSERT_FALSE(reader.ReadTargetInfo(std::size(buf), &av_pairs));
423 }
424 
TEST(NtlmBufferReaderTest,ReadTargetInfoInvalidTimestampPastEob)425 TEST(NtlmBufferReaderTest, ReadTargetInfoInvalidTimestampPastEob) {
426   // The timestamp avlen is correct but would read past the end of the buffer.
427   const uint8_t buf[11] = {0x07, 0,    0x08, 0,    0x11, 0x22,
428                            0x33, 0x44, 0x55, 0x66, 0x77};
429 
430   NtlmBufferReader reader(buf);
431 
432   std::vector<AvPair> av_pairs;
433   ASSERT_FALSE(reader.ReadTargetInfo(std::size(buf), &av_pairs));
434 }
435 
TEST(NtlmBufferReaderTest,ReadTargetInfoOtherField)436 TEST(NtlmBufferReaderTest, ReadTargetInfoOtherField) {
437   // A domain name AvPair containing the string L'ABCD' followed by
438   // a terminating AvPair.
439   const uint8_t buf[16] = {0x02, 0, 0x08, 0, 'A', 0, 'B', 0,
440                            'C',  0, 'D',  0, 0,   0, 0,   0};
441 
442   NtlmBufferReader reader(buf);
443 
444   std::vector<AvPair> av_pairs;
445   ASSERT_TRUE(reader.ReadTargetInfo(std::size(buf), &av_pairs));
446   ASSERT_TRUE(reader.IsEndOfBuffer());
447   ASSERT_EQ(1u, av_pairs.size());
448 
449   // Verify the domain name AvPair.
450   ASSERT_EQ(TargetInfoAvId::kDomainName, av_pairs[0].avid);
451   ASSERT_EQ(8, av_pairs[0].avlen);
452   ASSERT_EQ(0, memcmp(buf + 4, av_pairs[0].buffer.data(), 8));
453 }
454 
TEST(NtlmBufferReaderTest,ReadTargetInfoNoTerminator)455 TEST(NtlmBufferReaderTest, ReadTargetInfoNoTerminator) {
456   // A domain name AvPair containing the string L'ABCD' but there is no
457   // terminating AvPair.
458   const uint8_t buf[12] = {0x02, 0, 0x08, 0, 'A', 0, 'B', 0, 'C', 0, 'D', 0};
459 
460   NtlmBufferReader reader(buf);
461 
462   std::vector<AvPair> av_pairs;
463   ASSERT_FALSE(reader.ReadTargetInfo(std::size(buf), &av_pairs));
464 }
465 
TEST(NtlmBufferReaderTest,ReadTargetInfoTerminatorAtLocationOtherThanEnd)466 TEST(NtlmBufferReaderTest, ReadTargetInfoTerminatorAtLocationOtherThanEnd) {
467   // Target info contains [flags, terminator, domain, terminator]. This
468   // should fail because the terminator should only appear at the end.
469   const uint8_t buf[] = {0x06, 0, 0x04, 0, 0x02, 0, 0,   0, 0,   0,
470                          0,    0, 0x02, 0, 0x08, 0, 'A', 0, 'B', 0,
471                          'C',  0, 'D',  0, 0,    0, 0,   0};
472 
473   NtlmBufferReader reader(buf);
474 
475   std::vector<AvPair> av_pairs;
476   ASSERT_FALSE(reader.ReadTargetInfo(std::size(buf), &av_pairs));
477 }
478 
TEST(NtlmBufferReaderTest,ReadTargetInfoTerminatorNonZeroLength)479 TEST(NtlmBufferReaderTest, ReadTargetInfoTerminatorNonZeroLength) {
480   // A flags Av Pair followed by a terminator pair with a non-zero length.
481   const uint8_t buf[] = {0x06, 0, 0x04, 0, 0x02, 0, 0, 0, 0, 0, 0x01, 0};
482 
483   NtlmBufferReader reader(buf);
484 
485   std::vector<AvPair> av_pairs;
486   ASSERT_FALSE(reader.ReadTargetInfo(std::size(buf), &av_pairs));
487 }
488 
TEST(NtlmBufferReaderTest,ReadTargetInfoTerminatorNonZeroLength2)489 TEST(NtlmBufferReaderTest, ReadTargetInfoTerminatorNonZeroLength2) {
490   // A flags Av Pair followed by a terminator pair with a non-zero length,
491   // but otherwise in bounds payload. Terminator pairs must have zero
492   // length, so this is not valid.
493   const uint8_t buf[] = {0x06, 0,    0x04, 0,    0x02, 0, 0, 0, 0,
494                          0,    0x01, 0,    0xff, 0,    0, 0, 0};
495 
496   NtlmBufferReader reader(buf);
497 
498   std::vector<AvPair> av_pairs;
499   ASSERT_FALSE(reader.ReadTargetInfo(std::size(buf), &av_pairs));
500 }
501 
TEST(NtlmBufferReaderTest,ReadTargetInfoEmptyPayload)502 TEST(NtlmBufferReaderTest, ReadTargetInfoEmptyPayload) {
503   // Security buffer with no payload.
504   const uint8_t buf[] = {0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00};
505 
506   NtlmBufferReader reader(buf);
507 
508   std::vector<AvPair> av_pairs;
509   ASSERT_TRUE(reader.ReadTargetInfoPayload(&av_pairs));
510   ASSERT_TRUE(reader.IsEndOfBuffer());
511   ASSERT_TRUE(av_pairs.empty());
512 }
513 
TEST(NtlmBufferReaderTest,ReadTargetInfoEolOnlyPayload)514 TEST(NtlmBufferReaderTest, ReadTargetInfoEolOnlyPayload) {
515   // Security buffer with an EOL payload
516   const uint8_t buf[] = {0x04, 0x00, 0x04, 0x00, 0x08, 0x00,
517                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
518 
519   NtlmBufferReader reader(buf);
520 
521   std::vector<AvPair> av_pairs;
522   ASSERT_TRUE(reader.ReadTargetInfoPayload(&av_pairs));
523   ASSERT_FALSE(reader.IsEndOfBuffer());
524 
525   // Should only have advanced over the security buffer.
526   ASSERT_EQ(kSecurityBufferLen, reader.GetCursor());
527   ASSERT_TRUE(av_pairs.empty());
528 }
529 
TEST(NtlmBufferReaderTest,ReadTargetInfoTooShortPayload)530 TEST(NtlmBufferReaderTest, ReadTargetInfoTooShortPayload) {
531   // Security buffer with a payload too small to contain any pairs.
532   const uint8_t buf[] = {0x03, 0x00, 0x03, 0x00, 0x08, 0x00,
533                          0x00, 0x00, 0x00, 0x00, 0x00};
534 
535   NtlmBufferReader reader(buf);
536 
537   std::vector<AvPair> av_pairs;
538   ASSERT_FALSE(reader.ReadTargetInfoPayload(&av_pairs));
539 }
540 
TEST(NtlmBufferReaderTest,ReadTargetInfoFlagsPayload)541 TEST(NtlmBufferReaderTest, ReadTargetInfoFlagsPayload) {
542   // Security buffer followed by a 12 byte payload containing a flags AvPair
543   // with the MIC bit, followed by a terminator pair.
544   const uint8_t buf[] = {0x0c, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x00,
545                          0x00, 0x06, 0,    0x04, 0,    0x02, 0,
546                          0,    0,    0,    0,    0,    0};
547 
548   NtlmBufferReader reader(buf);
549 
550   std::vector<AvPair> av_pairs;
551   ASSERT_TRUE(reader.ReadTargetInfoPayload(&av_pairs));
552   ASSERT_FALSE(reader.IsEndOfBuffer());
553 
554   // Should only have advanced over the security buffer.
555   ASSERT_EQ(kSecurityBufferLen, reader.GetCursor());
556 
557   // Contains a single flags AVPair containing the MIC bit.
558   ASSERT_EQ(1u, av_pairs.size());
559   ASSERT_EQ(TargetInfoAvFlags::kMicPresent, av_pairs[0].flags);
560 }
561 
TEST(NtlmBufferReaderTest,ReadTargetInfoFlagsPayloadWithPaddingBetween)562 TEST(NtlmBufferReaderTest, ReadTargetInfoFlagsPayloadWithPaddingBetween) {
563   // Security buffer followed by a 12 byte payload containing a flags AvPair
564   // with the MIC bit, followed by a terminator pair. 5 bytes of 0xff padding
565   // are between the SecurityBuffer and the payload to test when the payload
566   // is not contiguous.
567   const uint8_t buf[] = {0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00, 0x00,
568                          0xff, 0xff, 0xff, 0xff, 0x06, 0,    0x04, 0,
569                          0x02, 0,    0,    0,    0,    0,    0,    0};
570   NtlmBufferReader reader(buf);
571 
572   std::vector<AvPair> av_pairs;
573   ASSERT_TRUE(reader.ReadTargetInfoPayload(&av_pairs));
574   ASSERT_FALSE(reader.IsEndOfBuffer());
575 
576   // Should only have advanced over the security buffer.
577   ASSERT_EQ(kSecurityBufferLen, reader.GetCursor());
578 
579   // Contains a single flags AVPair containing the MIC bit.
580   ASSERT_EQ(1u, av_pairs.size());
581   ASSERT_EQ(TargetInfoAvFlags::kMicPresent, av_pairs[0].flags);
582 }
583 
TEST(NtlmBufferReaderTest,ReadMessageTypeAuthenticate)584 TEST(NtlmBufferReaderTest, ReadMessageTypeAuthenticate) {
585   const uint8_t buf[4] = {static_cast<uint8_t>(MessageType::kAuthenticate), 0,
586                           0, 0};
587   NtlmBufferReader reader(buf);
588 
589   MessageType message_type;
590   ASSERT_TRUE(reader.ReadMessageType(&message_type));
591   ASSERT_EQ(MessageType::kAuthenticate, message_type);
592   ASSERT_TRUE(reader.IsEndOfBuffer());
593 }
594 
TEST(NtlmBufferReaderTest,MatchMessageTypeAuthenticate)595 TEST(NtlmBufferReaderTest, MatchMessageTypeAuthenticate) {
596   const uint8_t buf[4] = {static_cast<uint8_t>(MessageType::kAuthenticate), 0,
597                           0, 0};
598   NtlmBufferReader reader(buf);
599 
600   ASSERT_TRUE(reader.MatchMessageType(MessageType::kAuthenticate));
601   ASSERT_TRUE(reader.IsEndOfBuffer());
602 }
603 
TEST(NtlmBufferReaderTest,MatchMessageTypeInvalid)604 TEST(NtlmBufferReaderTest, MatchMessageTypeInvalid) {
605   // Only 0x01, 0x02, and 0x03 are valid message types.
606   const uint8_t buf[4] = {0x04, 0, 0, 0};
607   NtlmBufferReader reader(buf);
608 
609   ASSERT_FALSE(reader.MatchMessageType(MessageType::kAuthenticate));
610 }
611 
TEST(NtlmBufferReaderTest,MatchMessageTypeMismatch)612 TEST(NtlmBufferReaderTest, MatchMessageTypeMismatch) {
613   const uint8_t buf[4] = {static_cast<uint8_t>(MessageType::kChallenge), 0, 0,
614                           0};
615   NtlmBufferReader reader(buf);
616 
617   ASSERT_FALSE(reader.MatchMessageType(MessageType::kAuthenticate));
618 }
619 
TEST(NtlmBufferReaderTest,MatchAuthenticateHeader)620 TEST(NtlmBufferReaderTest, MatchAuthenticateHeader) {
621   const uint8_t buf[12] = {
622       'N', 'T', 'L',
623       'M', 'S', 'S',
624       'P', 0,   static_cast<uint8_t>(MessageType::kAuthenticate),
625       0,   0,   0};
626   NtlmBufferReader reader(buf);
627 
628   ASSERT_TRUE(reader.MatchMessageHeader(MessageType::kAuthenticate));
629   ASSERT_TRUE(reader.IsEndOfBuffer());
630 }
631 
TEST(NtlmBufferReaderTest,MatchAuthenticateHeaderMisMatch)632 TEST(NtlmBufferReaderTest, MatchAuthenticateHeaderMisMatch) {
633   const uint8_t buf[12] = {
634       'N', 'T', 'L',
635       'M', 'S', 'S',
636       'P', 0,   static_cast<uint8_t>(MessageType::kChallenge),
637       0,   0,   0};
638   NtlmBufferReader reader(buf);
639 
640   ASSERT_FALSE(reader.MatchMessageType(MessageType::kAuthenticate));
641 }
642 
TEST(NtlmBufferReaderTest,MatchZeros)643 TEST(NtlmBufferReaderTest, MatchZeros) {
644   const uint8_t buf[6] = {0, 0, 0, 0, 0, 0};
645 
646   NtlmBufferReader reader(buf);
647 
648   ASSERT_TRUE(reader.MatchZeros(std::size(buf)));
649   ASSERT_TRUE(reader.IsEndOfBuffer());
650   ASSERT_FALSE(reader.MatchZeros(1));
651 }
652 
TEST(NtlmBufferReaderTest,MatchZerosFail)653 TEST(NtlmBufferReaderTest, MatchZerosFail) {
654   const uint8_t buf[6] = {0, 0, 0, 0, 0, 0xFF};
655 
656   NtlmBufferReader reader(buf);
657 
658   ASSERT_FALSE(reader.MatchZeros(std::size(buf)));
659 }
660 
TEST(NtlmBufferReaderTest,MatchEmptySecurityBuffer)661 TEST(NtlmBufferReaderTest, MatchEmptySecurityBuffer) {
662   const uint8_t buf[kSecurityBufferLen] = {0, 0, 0, 0, 0, 0, 0, 0};
663 
664   NtlmBufferReader reader(buf);
665 
666   ASSERT_TRUE(reader.MatchEmptySecurityBuffer());
667   ASSERT_TRUE(reader.IsEndOfBuffer());
668   ASSERT_FALSE(reader.MatchEmptySecurityBuffer());
669 }
670 
TEST(NtlmBufferReaderTest,MatchEmptySecurityBufferLengthZeroOffsetEnd)671 TEST(NtlmBufferReaderTest, MatchEmptySecurityBufferLengthZeroOffsetEnd) {
672   const uint8_t buf[kSecurityBufferLen] = {0, 0, 0, 0, 0x08, 0, 0, 0};
673 
674   NtlmBufferReader reader(buf);
675 
676   ASSERT_TRUE(reader.MatchEmptySecurityBuffer());
677   ASSERT_TRUE(reader.IsEndOfBuffer());
678 }
679 
TEST(NtlmBufferReaderTest,MatchEmptySecurityBufferLengthZeroPastEob)680 TEST(NtlmBufferReaderTest, MatchEmptySecurityBufferLengthZeroPastEob) {
681   const uint8_t buf[kSecurityBufferLen] = {0, 0, 0, 0, 0x09, 0, 0, 0};
682 
683   NtlmBufferReader reader(buf);
684 
685   ASSERT_FALSE(reader.MatchEmptySecurityBuffer());
686 }
687 
TEST(NtlmBufferReaderTest,MatchEmptySecurityBufferLengthNonZeroLength)688 TEST(NtlmBufferReaderTest, MatchEmptySecurityBufferLengthNonZeroLength) {
689   const uint8_t buf[kSecurityBufferLen + 1] = {0x01, 0, 0, 0,   0x08,
690                                                0,    0, 0, 0xff};
691 
692   NtlmBufferReader reader(buf);
693 
694   ASSERT_FALSE(reader.MatchEmptySecurityBuffer());
695 }
696 
TEST(NtlmBufferReaderTest,ReadAvPairHeader)697 TEST(NtlmBufferReaderTest, ReadAvPairHeader) {
698   const uint8_t buf[4] = {0x06, 0x00, 0x11, 0x22};
699 
700   NtlmBufferReader reader(buf);
701 
702   TargetInfoAvId actual_avid;
703   uint16_t actual_avlen;
704   ASSERT_TRUE(reader.ReadAvPairHeader(&actual_avid, &actual_avlen));
705   ASSERT_EQ(TargetInfoAvId::kFlags, actual_avid);
706   ASSERT_EQ(0x2211, actual_avlen);
707   ASSERT_TRUE(reader.IsEndOfBuffer());
708   ASSERT_FALSE(reader.ReadAvPairHeader(&actual_avid, &actual_avlen));
709 }
710 
TEST(NtlmBufferReaderTest,ReadAvPairHeaderPastEob)711 TEST(NtlmBufferReaderTest, ReadAvPairHeaderPastEob) {
712   const uint8_t buf[3] = {0x06, 0x00, 0x11};
713 
714   NtlmBufferReader reader(buf);
715 
716   TargetInfoAvId avid;
717   uint16_t avlen;
718   ASSERT_FALSE(reader.ReadAvPairHeader(&avid, &avlen));
719 }
720 
721 }  // namespace net::ntlm
722