ntlm_buffer_writer_unittest.cc 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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_writer.h"
  5. #include "base/strings/utf_string_conversions.h"
  6. #include "testing/gtest/include/gtest/gtest.h"
  7. namespace net::ntlm {
  8. namespace {
  9. // Helper method to get a raw pointer to the buffer.
  10. const uint8_t* GetBufferPtr(const NtlmBufferWriter& writer) {
  11. return writer.GetBuffer().data();
  12. }
  13. // Helper method to get a byte at a specific index in the buffer.
  14. uint8_t GetByteFromBuffer(const NtlmBufferWriter& writer, size_t index) {
  15. EXPECT_TRUE(index < writer.GetLength());
  16. return writer.GetBuffer()[index];
  17. }
  18. } // namespace
  19. TEST(NtlmBufferWriterTest, Initialization) {
  20. NtlmBufferWriter writer(1);
  21. ASSERT_EQ(1u, writer.GetLength());
  22. ASSERT_EQ(1u, writer.GetBuffer().size());
  23. ASSERT_EQ(0u, writer.GetCursor());
  24. ASSERT_FALSE(writer.IsEndOfBuffer());
  25. ASSERT_TRUE(writer.CanWrite(1));
  26. ASSERT_FALSE(writer.CanWrite(2));
  27. }
  28. TEST(NtlmBufferWriterTest, EmptyWrite) {
  29. NtlmBufferWriter writer(0);
  30. ASSERT_EQ(0u, writer.GetLength());
  31. ASSERT_EQ(0u, writer.GetBuffer().size());
  32. ASSERT_EQ(0u, writer.GetCursor());
  33. ASSERT_EQ(nullptr, GetBufferPtr(writer));
  34. // An empty (zero-byte) write into a zero-byte writer should succeed as a
  35. // no-op.
  36. std::vector<uint8_t> b;
  37. ASSERT_TRUE(writer.CanWrite(0));
  38. ASSERT_TRUE(writer.WriteBytes(b));
  39. ASSERT_EQ(0u, writer.GetLength());
  40. ASSERT_EQ(0u, writer.GetBuffer().size());
  41. ASSERT_EQ(0u, writer.GetCursor());
  42. ASSERT_EQ(nullptr, GetBufferPtr(writer));
  43. // An empty (zero-byte) write into a non-zero-byte writer should succeed as
  44. // a no-op.
  45. NtlmBufferWriter writer2(1);
  46. ASSERT_EQ(1u, writer2.GetLength());
  47. ASSERT_EQ(1u, writer2.GetBuffer().size());
  48. ASSERT_EQ(0u, writer2.GetCursor());
  49. ASSERT_NE(nullptr, GetBufferPtr(writer2));
  50. ASSERT_TRUE(writer2.CanWrite(0));
  51. ASSERT_TRUE(writer2.WriteBytes(b));
  52. ASSERT_EQ(1u, writer2.GetLength());
  53. ASSERT_EQ(1u, writer2.GetBuffer().size());
  54. ASSERT_EQ(0u, writer2.GetCursor());
  55. ASSERT_NE(nullptr, GetBufferPtr(writer2));
  56. }
  57. TEST(NtlmBufferWriterTest, Write16) {
  58. uint8_t expected[2] = {0x22, 0x11};
  59. const uint16_t value = 0x1122;
  60. NtlmBufferWriter writer(sizeof(uint16_t));
  61. ASSERT_TRUE(writer.WriteUInt16(value));
  62. ASSERT_TRUE(writer.IsEndOfBuffer());
  63. ASSERT_EQ(std::size(expected), writer.GetLength());
  64. ASSERT_FALSE(writer.WriteUInt16(value));
  65. ASSERT_EQ(0,
  66. memcmp(expected, writer.GetBuffer().data(), std::size(expected)));
  67. }
  68. TEST(NtlmBufferWriterTest, Write16PastEob) {
  69. NtlmBufferWriter writer(sizeof(uint16_t) - 1);
  70. ASSERT_FALSE(writer.WriteUInt16(0));
  71. ASSERT_EQ(0u, writer.GetCursor());
  72. }
  73. TEST(NtlmBufferWriterTest, Write32) {
  74. uint8_t expected[4] = {0x44, 0x33, 0x22, 0x11};
  75. const uint32_t value = 0x11223344;
  76. NtlmBufferWriter writer(sizeof(uint32_t));
  77. ASSERT_TRUE(writer.WriteUInt32(value));
  78. ASSERT_TRUE(writer.IsEndOfBuffer());
  79. ASSERT_FALSE(writer.WriteUInt32(value));
  80. ASSERT_EQ(0, memcmp(expected, GetBufferPtr(writer), std::size(expected)));
  81. }
  82. TEST(NtlmBufferWriterTest, Write32PastEob) {
  83. NtlmBufferWriter writer(sizeof(uint32_t) - 1);
  84. ASSERT_FALSE(writer.WriteUInt32(0));
  85. ASSERT_EQ(0u, writer.GetCursor());
  86. }
  87. TEST(NtlmBufferWriterTest, Write64) {
  88. uint8_t expected[8] = {0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
  89. const uint64_t value = 0x1122334455667788;
  90. NtlmBufferWriter writer(sizeof(uint64_t));
  91. ASSERT_TRUE(writer.WriteUInt64(value));
  92. ASSERT_TRUE(writer.IsEndOfBuffer());
  93. ASSERT_FALSE(writer.WriteUInt64(value));
  94. ASSERT_EQ(0, memcmp(expected, GetBufferPtr(writer), std::size(expected)));
  95. }
  96. TEST(NtlmBufferWriterTest, Write64PastEob) {
  97. NtlmBufferWriter writer(sizeof(uint64_t) - 1);
  98. ASSERT_FALSE(writer.WriteUInt64(0));
  99. ASSERT_EQ(0u, writer.GetCursor());
  100. }
  101. TEST(NtlmBufferWriterTest, WriteBytes) {
  102. uint8_t expected[8] = {0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
  103. NtlmBufferWriter writer(std::size(expected));
  104. ASSERT_TRUE(writer.WriteBytes(expected));
  105. ASSERT_EQ(0, memcmp(GetBufferPtr(writer), expected, std::size(expected)));
  106. ASSERT_TRUE(writer.IsEndOfBuffer());
  107. ASSERT_FALSE(writer.WriteBytes(base::make_span(expected, 1)));
  108. ASSERT_EQ(0, memcmp(expected, GetBufferPtr(writer), std::size(expected)));
  109. }
  110. TEST(NtlmBufferWriterTest, WriteBytesPastEob) {
  111. uint8_t buffer[8];
  112. NtlmBufferWriter writer(std::size(buffer) - 1);
  113. ASSERT_FALSE(writer.WriteBytes(buffer));
  114. }
  115. TEST(NtlmBufferWriterTest, WriteSecurityBuffer) {
  116. uint8_t expected[8] = {0x22, 0x11, 0x22, 0x11, 0x88, 0x77, 0x66, 0x55};
  117. uint16_t length = 0x1122;
  118. uint32_t offset = 0x55667788;
  119. NtlmBufferWriter writer(kSecurityBufferLen);
  120. ASSERT_TRUE(writer.WriteSecurityBuffer(SecurityBuffer(offset, length)));
  121. ASSERT_TRUE(writer.IsEndOfBuffer());
  122. ASSERT_FALSE(writer.WriteSecurityBuffer(SecurityBuffer(offset, length)));
  123. ASSERT_EQ(0, memcmp(expected, GetBufferPtr(writer), std::size(expected)));
  124. }
  125. TEST(NtlmBufferWriterTest, WriteSecurityBufferPastEob) {
  126. SecurityBuffer sec_buf;
  127. NtlmBufferWriter writer(kSecurityBufferLen - 1);
  128. ASSERT_FALSE(writer.WriteSecurityBuffer(sec_buf));
  129. }
  130. TEST(NtlmBufferWriterTest, WriteNarrowString) {
  131. uint8_t expected[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
  132. std::string value("12345678");
  133. NtlmBufferWriter writer(value.size());
  134. ASSERT_TRUE(writer.WriteUtf8String(value));
  135. ASSERT_TRUE(writer.IsEndOfBuffer());
  136. ASSERT_FALSE(writer.WriteUtf8String(value));
  137. ASSERT_EQ(0, memcmp(expected, GetBufferPtr(writer), std::size(expected)));
  138. }
  139. TEST(NtlmBufferWriterTest, WriteAsciiStringPastEob) {
  140. std::string str("12345678");
  141. NtlmBufferWriter writer(str.length() - 1);
  142. ASSERT_FALSE(writer.WriteUtf8String(str));
  143. }
  144. TEST(NtlmBufferWriterTest, WriteUtf16String) {
  145. uint8_t expected[16] = {'1', 0, '2', 0, '3', 0, '4', 0,
  146. '5', 0, '6', 0, '7', 0, '8', 0};
  147. std::u16string value = u"12345678";
  148. NtlmBufferWriter writer(value.size() * 2);
  149. ASSERT_TRUE(writer.WriteUtf16String(value));
  150. ASSERT_TRUE(writer.IsEndOfBuffer());
  151. ASSERT_FALSE(writer.WriteUtf16String(value));
  152. ASSERT_EQ(0, memcmp(expected, GetBufferPtr(writer), std::size(expected)));
  153. }
  154. TEST(NtlmBufferWriterTest, WriteUtf16StringPastEob) {
  155. std::u16string str = u"12345678";
  156. NtlmBufferWriter writer((str.length() * 2) - 1);
  157. ASSERT_FALSE(writer.WriteUtf16String(str));
  158. }
  159. TEST(NtlmBufferWriterTest, WriteUtf8AsUtf16String) {
  160. uint8_t expected[16] = {'1', 0, '2', 0, '3', 0, '4', 0,
  161. '5', 0, '6', 0, '7', 0, '8', 0};
  162. std::string input = "12345678";
  163. NtlmBufferWriter writer(input.size() * 2);
  164. ASSERT_TRUE(writer.WriteUtf8AsUtf16String(input));
  165. ASSERT_TRUE(writer.IsEndOfBuffer());
  166. ASSERT_FALSE(writer.WriteUtf8AsUtf16String(input));
  167. ASSERT_EQ(0, memcmp(expected, GetBufferPtr(writer), std::size(expected)));
  168. }
  169. TEST(NtlmBufferWriterTest, WriteSignature) {
  170. uint8_t expected[8] = {'N', 'T', 'L', 'M', 'S', 'S', 'P', 0};
  171. NtlmBufferWriter writer(kSignatureLen);
  172. ASSERT_TRUE(writer.WriteSignature());
  173. ASSERT_TRUE(writer.IsEndOfBuffer());
  174. ASSERT_EQ(0, memcmp(expected, GetBufferPtr(writer), std::size(expected)));
  175. }
  176. TEST(NtlmBufferWriterTest, WriteSignaturePastEob) {
  177. NtlmBufferWriter writer(1);
  178. ASSERT_FALSE(writer.WriteSignature());
  179. }
  180. TEST(NtlmBufferWriterTest, WriteMessageType) {
  181. NtlmBufferWriter writer(4);
  182. ASSERT_TRUE(writer.WriteMessageType(MessageType::kNegotiate));
  183. ASSERT_TRUE(writer.IsEndOfBuffer());
  184. ASSERT_EQ(static_cast<uint32_t>(MessageType::kNegotiate),
  185. GetByteFromBuffer(writer, 0));
  186. ASSERT_EQ(0, GetByteFromBuffer(writer, 1));
  187. ASSERT_EQ(0, GetByteFromBuffer(writer, 2));
  188. ASSERT_EQ(0, GetByteFromBuffer(writer, 3));
  189. }
  190. TEST(NtlmBufferWriterTest, WriteMessageTypePastEob) {
  191. NtlmBufferWriter writer(sizeof(uint32_t) - 1);
  192. ASSERT_FALSE(writer.WriteMessageType(MessageType::kNegotiate));
  193. }
  194. TEST(NtlmBufferWriterTest, WriteAvPairHeader) {
  195. const uint8_t expected[4] = {0x06, 0x00, 0x11, 0x22};
  196. NtlmBufferWriter writer(std::size(expected));
  197. ASSERT_TRUE(writer.WriteAvPairHeader(TargetInfoAvId::kFlags, 0x2211));
  198. ASSERT_TRUE(writer.IsEndOfBuffer());
  199. ASSERT_EQ(0, memcmp(expected, GetBufferPtr(writer), std::size(expected)));
  200. }
  201. TEST(NtlmBufferWriterTest, WriteAvPairHeaderPastEob) {
  202. NtlmBufferWriter writer(kAvPairHeaderLen - 1);
  203. ASSERT_FALSE(writer.WriteAvPairHeader(TargetInfoAvId::kFlags, 0x2211));
  204. ASSERT_EQ(0u, writer.GetCursor());
  205. }
  206. } // namespace net::ntlm