ntlm_buffer_reader_unittest.cc 23 KB

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