ntlm_buffer_writer.cc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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 <string.h>
  6. #include <limits>
  7. #include "base/check_op.h"
  8. #include "base/strings/utf_string_conversions.h"
  9. #include "build/build_config.h"
  10. namespace net::ntlm {
  11. NtlmBufferWriter::NtlmBufferWriter(size_t buffer_len)
  12. : buffer_(buffer_len, 0) {}
  13. NtlmBufferWriter::~NtlmBufferWriter() = default;
  14. bool NtlmBufferWriter::CanWrite(size_t len) const {
  15. if (len == 0)
  16. return true;
  17. if (!GetBufferPtr())
  18. return false;
  19. DCHECK_LE(GetCursor(), GetLength());
  20. return (len <= GetLength()) && (GetCursor() <= GetLength() - len);
  21. }
  22. bool NtlmBufferWriter::WriteUInt16(uint16_t value) {
  23. return WriteUInt<uint16_t>(value);
  24. }
  25. bool NtlmBufferWriter::WriteUInt32(uint32_t value) {
  26. return WriteUInt<uint32_t>(value);
  27. }
  28. bool NtlmBufferWriter::WriteUInt64(uint64_t value) {
  29. return WriteUInt<uint64_t>(value);
  30. }
  31. bool NtlmBufferWriter::WriteFlags(NegotiateFlags flags) {
  32. return WriteUInt32(static_cast<uint32_t>(flags));
  33. }
  34. bool NtlmBufferWriter::WriteBytes(base::span<const uint8_t> bytes) {
  35. if (bytes.size() == 0)
  36. return true;
  37. if (!CanWrite(bytes.size()))
  38. return false;
  39. memcpy(GetBufferPtrAtCursor(), bytes.data(), bytes.size());
  40. AdvanceCursor(bytes.size());
  41. return true;
  42. }
  43. bool NtlmBufferWriter::WriteZeros(size_t count) {
  44. if (count == 0)
  45. return true;
  46. if (!CanWrite(count))
  47. return false;
  48. memset(GetBufferPtrAtCursor(), 0, count);
  49. AdvanceCursor(count);
  50. return true;
  51. }
  52. bool NtlmBufferWriter::WriteSecurityBuffer(SecurityBuffer sec_buf) {
  53. return WriteUInt16(sec_buf.length) && WriteUInt16(sec_buf.length) &&
  54. WriteUInt32(sec_buf.offset);
  55. }
  56. bool NtlmBufferWriter::WriteAvPairHeader(TargetInfoAvId avid, uint16_t avlen) {
  57. if (!CanWrite(kAvPairHeaderLen))
  58. return false;
  59. bool result = WriteUInt16(static_cast<uint16_t>(avid)) && WriteUInt16(avlen);
  60. DCHECK(result);
  61. return result;
  62. }
  63. bool NtlmBufferWriter::WriteAvPairTerminator() {
  64. return WriteAvPairHeader(TargetInfoAvId::kEol, 0);
  65. }
  66. bool NtlmBufferWriter::WriteAvPair(const AvPair& pair) {
  67. if (!WriteAvPairHeader(pair))
  68. return false;
  69. if (pair.avid == TargetInfoAvId::kFlags) {
  70. if (pair.avlen != sizeof(uint32_t))
  71. return false;
  72. return WriteUInt32(static_cast<uint32_t>(pair.flags));
  73. } else {
  74. return WriteBytes(pair.buffer);
  75. }
  76. }
  77. bool NtlmBufferWriter::WriteUtf8String(const std::string& str) {
  78. return WriteBytes(base::as_bytes(base::make_span(str)));
  79. }
  80. bool NtlmBufferWriter::WriteUtf16AsUtf8String(const std::u16string& str) {
  81. std::string utf8 = base::UTF16ToUTF8(str);
  82. return WriteUtf8String(utf8);
  83. }
  84. bool NtlmBufferWriter::WriteUtf8AsUtf16String(const std::string& str) {
  85. std::u16string unicode = base::UTF8ToUTF16(str);
  86. return WriteUtf16String(unicode);
  87. }
  88. bool NtlmBufferWriter::WriteUtf16String(const std::u16string& str) {
  89. if (str.size() > std::numeric_limits<size_t>::max() / 2)
  90. return false;
  91. size_t num_bytes = str.size() * 2;
  92. if (num_bytes == 0)
  93. return true;
  94. if (!CanWrite(num_bytes))
  95. return false;
  96. #if defined(ARCH_CPU_BIG_ENDIAN)
  97. uint8_t* ptr = reinterpret_cast<uint8_t*>(GetBufferPtrAtCursor());
  98. for (int i = 0; i < num_bytes; i += 2) {
  99. ptr[i] = str[i / 2] & 0xff;
  100. ptr[i + 1] = str[i / 2] >> 8;
  101. }
  102. #else
  103. memcpy(reinterpret_cast<void*>(GetBufferPtrAtCursor()), str.c_str(),
  104. num_bytes);
  105. #endif
  106. AdvanceCursor(num_bytes);
  107. return true;
  108. }
  109. bool NtlmBufferWriter::WriteSignature() {
  110. return WriteBytes(kSignature);
  111. }
  112. bool NtlmBufferWriter::WriteMessageType(MessageType message_type) {
  113. return WriteUInt32(static_cast<uint32_t>(message_type));
  114. }
  115. bool NtlmBufferWriter::WriteMessageHeader(MessageType message_type) {
  116. return WriteSignature() && WriteMessageType(message_type);
  117. }
  118. template <typename T>
  119. bool NtlmBufferWriter::WriteUInt(T value) {
  120. size_t int_size = sizeof(T);
  121. if (!CanWrite(int_size))
  122. return false;
  123. for (size_t i = 0; i < int_size; i++) {
  124. GetBufferPtrAtCursor()[i] = static_cast<uint8_t>(value & 0xff);
  125. value >>= 8;
  126. }
  127. AdvanceCursor(int_size);
  128. return true;
  129. }
  130. void NtlmBufferWriter::SetCursor(size_t cursor) {
  131. DCHECK(GetBufferPtr() && cursor <= GetLength());
  132. cursor_ = cursor;
  133. }
  134. } // namespace net::ntlm