tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

stun.cc (49082B)


      1 /*
      2 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "api/transport/stun.h"
     12 
     13 #include <algorithm>  // IWYU pragma: keep
     14 #include <cstdint>
     15 #include <cstring>
     16 #include <functional>
     17 #include <iterator>
     18 #include <memory>
     19 #include <optional>
     20 #include <string>
     21 #include <utility>
     22 #include <vector>
     23 
     24 #include "absl/strings/string_view.h"
     25 #include "api/array_view.h"
     26 #include "rtc_base/byte_buffer.h"
     27 #include "rtc_base/byte_order.h"
     28 #include "rtc_base/checks.h"
     29 #include "rtc_base/crc32.h"
     30 #include "rtc_base/crypto_random.h"
     31 #include "rtc_base/ip_address.h"
     32 #include "rtc_base/logging.h"
     33 #include "rtc_base/message_digest.h"
     34 #include "rtc_base/net_helpers.h"
     35 #include "rtc_base/socket_address.h"
     36 #include "system_wrappers/include/metrics.h"
     37 
     38 using ::webrtc::ByteBufferReader;
     39 using ::webrtc::ByteBufferWriter;
     40 
     41 namespace webrtc {
     42 
     43 namespace {
     44 
     45 const int k127Utf8CharactersLengthInBytes = 508;
     46 const int kMessageIntegrityAttributeLength = 20;
     47 const int kTheoreticalMaximumAttributeLength = 65535;
     48 
     49 uint32_t ReduceTransactionId(absl::string_view transaction_id) {
     50  RTC_DCHECK(transaction_id.length() == kStunTransactionIdLength ||
     51             transaction_id.length() == kStunLegacyTransactionIdLength)
     52      << transaction_id.length();
     53  ByteBufferReader reader(
     54      MakeArrayView(reinterpret_cast<const uint8_t*>(transaction_id.data()),
     55                    transaction_id.size()));
     56  uint32_t result = 0;
     57  uint32_t next;
     58  while (reader.ReadUInt32(&next)) {
     59    result ^= next;
     60  }
     61  return result;
     62 }
     63 
     64 // Check the maximum length of a BYTE_STRING attribute against specifications.
     65 bool LengthValid(int type, int length) {
     66  // "Less than 509 bytes" is intended to indicate a maximum of 127
     67  // UTF-8 characters, which may take up to 4 bytes per character.
     68  switch (type) {
     69    case STUN_ATTR_USERNAME:
     70      return length <=
     71             k127Utf8CharactersLengthInBytes;  // RFC 8489 section 14.3
     72    case STUN_ATTR_MESSAGE_INTEGRITY:
     73      return length ==
     74             kMessageIntegrityAttributeLength;  // RFC 8489 section 14.5
     75    case STUN_ATTR_REALM:
     76      return length <=
     77             k127Utf8CharactersLengthInBytes;  // RFC 8489 section 14.9
     78    case STUN_ATTR_NONCE:
     79      return length <=
     80             k127Utf8CharactersLengthInBytes;  // RFC 8489 section 14.10
     81    case STUN_ATTR_SOFTWARE:
     82      return length <=
     83             k127Utf8CharactersLengthInBytes;  // RFC 8489 section 14.14
     84    case STUN_ATTR_DATA:
     85      // No length restriction in RFC; it's the content of an UDP datagram,
     86      // which in theory can be up to 65.535 bytes.
     87      // TODO(bugs.webrtc.org/12179): Write a test to find the real limit.
     88      return length <= kTheoreticalMaximumAttributeLength;
     89    default:
     90      // Return an arbitrary restriction for all other types.
     91      return length <= kTheoreticalMaximumAttributeLength;
     92  }
     93  RTC_DCHECK_NOTREACHED();
     94  return true;
     95 }
     96 
     97 }  // namespace
     98 
     99 const char STUN_ERROR_REASON_TRY_ALTERNATE_SERVER[] = "Try Alternate Server";
    100 const char STUN_ERROR_REASON_BAD_REQUEST[] = "Bad Request";
    101 const char STUN_ERROR_REASON_UNAUTHORIZED[] = "Unauthorized";
    102 const char STUN_ERROR_REASON_UNKNOWN_ATTRIBUTE[] = "Unknown Attribute";
    103 const char STUN_ERROR_REASON_FORBIDDEN[] = "Forbidden";
    104 const char STUN_ERROR_REASON_ALLOCATION_MISMATCH[] = "Allocation Mismatch";
    105 const char STUN_ERROR_REASON_STALE_NONCE[] = "Stale Nonce";
    106 const char STUN_ERROR_REASON_WRONG_CREDENTIALS[] = "Wrong Credentials";
    107 const char STUN_ERROR_REASON_UNSUPPORTED_PROTOCOL[] = "Unsupported Protocol";
    108 const char STUN_ERROR_REASON_ROLE_CONFLICT[] = "Role Conflict";
    109 const char STUN_ERROR_REASON_SERVER_ERROR[] = "Server Error";
    110 
    111 const char EMPTY_TRANSACTION_ID[] = "0000000000000000";
    112 const uint32_t STUN_FINGERPRINT_XOR_VALUE = 0x5354554E;
    113 const int SERVER_NOT_REACHABLE_ERROR = 701;
    114 
    115 // StunMessage
    116 
    117 StunMessage::StunMessage()
    118    : StunMessage(STUN_INVALID_MESSAGE_TYPE, EMPTY_TRANSACTION_ID) {}
    119 
    120 StunMessage::StunMessage(uint16_t type)
    121    : StunMessage(type, GenerateTransactionId()) {}
    122 
    123 StunMessage::StunMessage(uint16_t type, absl::string_view transaction_id)
    124    : type_(type),
    125      transaction_id_(transaction_id),
    126      reduced_transaction_id_(ReduceTransactionId(transaction_id_)) {
    127  RTC_DCHECK(IsValidTransactionId(transaction_id_));
    128 }
    129 
    130 StunMessage::~StunMessage() = default;
    131 
    132 bool StunMessage::IsLegacy() const {
    133  if (transaction_id_.size() == kStunLegacyTransactionIdLength)
    134    return true;
    135  RTC_DCHECK(transaction_id_.size() == kStunTransactionIdLength);
    136  return false;
    137 }
    138 
    139 static bool DesignatedExpertRange(int attr_type) {
    140  return (attr_type >= 0x4000 && attr_type <= 0x7FFF) ||
    141         (attr_type >= 0xC000 && attr_type <= 0xFFFF);
    142 }
    143 
    144 void StunMessage::AddAttribute(std::unique_ptr<StunAttribute> attr) {
    145  // Fail any attributes that aren't valid for this type of message,
    146  // but allow any type for the range that in the RFC is reserved for
    147  // the "designated experts".
    148  if (!DesignatedExpertRange(attr->type())) {
    149    RTC_DCHECK_EQ(attr->value_type(), GetAttributeValueType(attr->type()));
    150  }
    151 
    152  attr->SetOwner(this);
    153  size_t attr_length = attr->length();
    154  if (attr_length % 4 != 0) {
    155    attr_length += (4 - (attr_length % 4));
    156  }
    157  length_ += static_cast<uint16_t>(attr_length + 4);
    158 
    159  attrs_.push_back(std::move(attr));
    160 }
    161 
    162 std::unique_ptr<StunAttribute> StunMessage::RemoveAttribute(int type) {
    163  std::unique_ptr<StunAttribute> attribute;
    164  for (auto it = attrs_.rbegin(); it != attrs_.rend(); ++it) {
    165    if ((*it)->type() == type) {
    166      attribute = std::move(*it);
    167      attrs_.erase(std::next(it).base());
    168      break;
    169    }
    170  }
    171  if (attribute) {
    172    attribute->SetOwner(nullptr);
    173    size_t attr_length = attribute->length();
    174    if (attr_length % 4 != 0) {
    175      attr_length += (4 - (attr_length % 4));
    176    }
    177    length_ -= static_cast<uint16_t>(attr_length + 4);
    178  }
    179  return attribute;
    180 }
    181 
    182 void StunMessage::ClearAttributes() {
    183  for (auto it = attrs_.rbegin(); it != attrs_.rend(); ++it) {
    184    (*it)->SetOwner(nullptr);
    185  }
    186  attrs_.clear();
    187  length_ = 0;
    188 }
    189 
    190 std::vector<uint16_t> StunMessage::GetNonComprehendedAttributes() const {
    191  std::vector<uint16_t> unknown_attributes;
    192  for (auto& attr : attrs_) {
    193    // "comprehension-required" range is 0x0000-0x7FFF.
    194    if (attr->type() >= 0x0000 && attr->type() <= 0x7FFF &&
    195        GetAttributeValueType(attr->type()) == STUN_VALUE_UNKNOWN) {
    196      unknown_attributes.push_back(attr->type());
    197    }
    198  }
    199  return unknown_attributes;
    200 }
    201 
    202 const StunAddressAttribute* StunMessage::GetAddress(int type) const {
    203  switch (type) {
    204    case STUN_ATTR_MAPPED_ADDRESS: {
    205      // Return XOR-MAPPED-ADDRESS when MAPPED-ADDRESS attribute is
    206      // missing.
    207      const StunAttribute* mapped_address =
    208          GetAttribute(STUN_ATTR_MAPPED_ADDRESS);
    209      if (!mapped_address)
    210        mapped_address = GetAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS);
    211      return reinterpret_cast<const StunAddressAttribute*>(mapped_address);
    212    }
    213 
    214    default:
    215      return static_cast<const StunAddressAttribute*>(GetAttribute(type));
    216  }
    217 }
    218 
    219 const StunUInt32Attribute* StunMessage::GetUInt32(int type) const {
    220  return static_cast<const StunUInt32Attribute*>(GetAttribute(type));
    221 }
    222 
    223 const StunUInt64Attribute* StunMessage::GetUInt64(int type) const {
    224  return static_cast<const StunUInt64Attribute*>(GetAttribute(type));
    225 }
    226 
    227 const StunByteStringAttribute* StunMessage::GetByteString(int type) const {
    228  return static_cast<const StunByteStringAttribute*>(GetAttribute(type));
    229 }
    230 
    231 const StunUInt16ListAttribute* StunMessage::GetUInt16List(int type) const {
    232  return static_cast<const StunUInt16ListAttribute*>(GetAttribute(type));
    233 }
    234 
    235 const StunErrorCodeAttribute* StunMessage::GetErrorCode() const {
    236  return static_cast<const StunErrorCodeAttribute*>(
    237      GetAttribute(STUN_ATTR_ERROR_CODE));
    238 }
    239 
    240 int StunMessage::GetErrorCodeValue() const {
    241  const StunErrorCodeAttribute* error_attribute = GetErrorCode();
    242  return error_attribute ? error_attribute->code() : STUN_ERROR_GLOBAL_FAILURE;
    243 }
    244 
    245 const StunUInt16ListAttribute* StunMessage::GetUnknownAttributes() const {
    246  return static_cast<const StunUInt16ListAttribute*>(
    247      GetAttribute(STUN_ATTR_UNKNOWN_ATTRIBUTES));
    248 }
    249 
    250 StunMessage::IntegrityStatus StunMessage::ValidateMessageIntegrity(
    251    const std::string& password) {
    252  RTC_DCHECK(integrity_ == IntegrityStatus::kNotSet)
    253      << "Usage error: Verification should only be done once";
    254  password_ = password;
    255  if (GetByteString(STUN_ATTR_MESSAGE_INTEGRITY)) {
    256    if (ValidateMessageIntegrityOfType(
    257            STUN_ATTR_MESSAGE_INTEGRITY, kStunMessageIntegritySize,
    258            buffer_.c_str(), buffer_.size(), password)) {
    259      integrity_ = IntegrityStatus::kIntegrityOk;
    260    } else {
    261      integrity_ = IntegrityStatus::kIntegrityBad;
    262    }
    263  } else if (GetByteString(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32)) {
    264    if (ValidateMessageIntegrityOfType(
    265            STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32, kStunMessageIntegrity32Size,
    266            buffer_.c_str(), buffer_.size(), password)) {
    267      integrity_ = IntegrityStatus::kIntegrityOk;
    268    } else {
    269      integrity_ = IntegrityStatus::kIntegrityBad;
    270    }
    271  } else {
    272    integrity_ = IntegrityStatus::kNoIntegrity;
    273  }
    274  // Log the result of integrity checking. See crbug.com/1177125 for background.
    275  // Convert args to integer for the benefit of the macros.
    276  int bucket_count = static_cast<int>(IntegrityStatus::kMaxValue) + 1;
    277  int integrity = static_cast<int>(integrity_);
    278  if (IsStunRequestType(type_)) {
    279    RTC_HISTOGRAM_ENUMERATION("WebRTC.Stun.Integrity.Request", integrity,
    280                              bucket_count);
    281  } else if (IsStunSuccessResponseType(type_)) {
    282    RTC_HISTOGRAM_ENUMERATION("WebRTC.Stun.Integrity.Response", integrity,
    283                              bucket_count);
    284  } else if (IsStunIndicationType(type_)) {
    285    RTC_HISTOGRAM_ENUMERATION("WebRTC.Stun.Integrity.Indication", integrity,
    286                              bucket_count);
    287  } else {
    288    RTC_DCHECK(IsStunErrorResponseType(type_));
    289    auto* error_attribute = GetErrorCode();
    290    if (!error_attribute) {
    291      RTC_HISTOGRAM_ENUMERATION(
    292          "WebRTC.Stun.Integrity.ErrorResponse.NoErrorAttribute", integrity,
    293          bucket_count);
    294    } else {
    295      switch (error_attribute->code()) {
    296        case STUN_ERROR_TRY_ALTERNATE:
    297          RTC_HISTOGRAM_ENUMERATION(
    298              "WebRTC.Stun.Integrity.ErrorResponse.TryAlternate", integrity,
    299              bucket_count);
    300          break;
    301        case STUN_ERROR_BAD_REQUEST:
    302          RTC_HISTOGRAM_ENUMERATION(
    303              "WebRTC.Stun.Integrity.ErrorResponse.BadRequest", integrity,
    304              bucket_count);
    305          break;
    306        case STUN_ERROR_UNAUTHORIZED:
    307          RTC_HISTOGRAM_ENUMERATION(
    308              "WebRTC.Stun.Integrity.ErrorResponse.Unauthorized", integrity,
    309              bucket_count);
    310          break;
    311        case STUN_ERROR_UNKNOWN_ATTRIBUTE:
    312          RTC_HISTOGRAM_ENUMERATION(
    313              "WebRTC.Stun.Integrity.ErrorResponse.UnknownAttribute", integrity,
    314              bucket_count);
    315          break;
    316        case STUN_ERROR_STALE_NONCE:
    317          RTC_HISTOGRAM_ENUMERATION(
    318              "WebRTC.Stun.Integrity.ErrorResponse.StaleNonce", integrity,
    319              bucket_count);
    320          break;
    321        case STUN_ERROR_SERVER_ERROR:
    322          RTC_HISTOGRAM_ENUMERATION(
    323              "WebRTC.Stun.Integrity.ErrorResponse.ServerError", integrity,
    324              bucket_count);
    325          break;
    326        case STUN_ERROR_GLOBAL_FAILURE:
    327          RTC_HISTOGRAM_ENUMERATION(
    328              "WebRTC.Stun.Integrity.ErrorResponse.GlobalFailure", integrity,
    329              bucket_count);
    330          break;
    331        default:
    332          RTC_HISTOGRAM_ENUMERATION(
    333              "WebRTC.Stun.Integrity.ErrorResponse.ErrorOther", integrity,
    334              bucket_count);
    335          break;
    336      }
    337    }
    338  }
    339  return integrity_;
    340 }
    341 
    342 StunMessage::IntegrityStatus StunMessage::RevalidateMessageIntegrity(
    343    const std::string& password) {
    344  RTC_LOG(LS_INFO) << "Message revalidation, old status was "
    345                   << static_cast<int>(integrity_);
    346  integrity_ = IntegrityStatus::kNotSet;
    347  return ValidateMessageIntegrity(password);
    348 }
    349 
    350 bool StunMessage::ValidateMessageIntegrityForTesting(
    351    const char* data,
    352    size_t size,
    353    const std::string& password) {
    354  return ValidateMessageIntegrityOfType(STUN_ATTR_MESSAGE_INTEGRITY,
    355                                        kStunMessageIntegritySize, data, size,
    356                                        password);
    357 }
    358 
    359 bool StunMessage::ValidateMessageIntegrity32ForTesting(
    360    const char* data,
    361    size_t size,
    362    const std::string& password) {
    363  return ValidateMessageIntegrityOfType(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32,
    364                                        kStunMessageIntegrity32Size, data, size,
    365                                        password);
    366 }
    367 
    368 // Verifies a STUN message has a valid MESSAGE-INTEGRITY attribute, using the
    369 // procedure outlined in RFC 5389, section 15.4.
    370 bool StunMessage::ValidateMessageIntegrityOfType(int mi_attr_type,
    371                                                 size_t mi_attr_size,
    372                                                 const char* data,
    373                                                 size_t size,
    374                                                 const std::string& password) {
    375  RTC_DCHECK(mi_attr_size <= kStunMessageIntegritySize);
    376 
    377  // Verifying the size of the message.
    378  if ((size % 4) != 0 || size < kStunHeaderSize) {
    379    return false;
    380  }
    381 
    382  // Getting the message length from the STUN header.
    383  uint16_t msg_length = GetBE16(&data[2]);
    384  if (size != (msg_length + kStunHeaderSize)) {
    385    return false;
    386  }
    387 
    388  // Finding Message Integrity attribute in stun message.
    389  size_t current_pos = kStunHeaderSize;
    390  bool has_message_integrity_attr = false;
    391  while (current_pos + 4 <= size) {
    392    uint16_t attr_type, attr_length;
    393    // Getting attribute type and length.
    394    attr_type = GetBE16(&data[current_pos]);
    395    attr_length = GetBE16(&data[current_pos + sizeof(attr_type)]);
    396 
    397    // If M-I, sanity check it, and break out.
    398    if (attr_type == mi_attr_type) {
    399      if (attr_length != mi_attr_size ||
    400          current_pos + sizeof(attr_type) + sizeof(attr_length) + attr_length >
    401              size) {
    402        return false;
    403      }
    404      has_message_integrity_attr = true;
    405      break;
    406    }
    407 
    408    // Otherwise, skip to the next attribute.
    409    current_pos += sizeof(attr_type) + sizeof(attr_length) + attr_length;
    410    if ((attr_length % 4) != 0) {
    411      current_pos += (4 - (attr_length % 4));
    412    }
    413  }
    414 
    415  if (!has_message_integrity_attr) {
    416    return false;
    417  }
    418 
    419  // Getting length of the message to calculate Message Integrity.
    420  size_t mi_pos = current_pos;
    421  std::unique_ptr<char[]> temp_data(new char[current_pos]);
    422  memcpy(temp_data.get(), data, current_pos);
    423  if (size > mi_pos + kStunAttributeHeaderSize + mi_attr_size) {
    424    // Stun message has other attributes after message integrity.
    425    // Adjust the length parameter in stun message to calculate HMAC.
    426    size_t extra_offset =
    427        size - (mi_pos + kStunAttributeHeaderSize + mi_attr_size);
    428    size_t new_adjusted_len = size - extra_offset - kStunHeaderSize;
    429 
    430    // Writing new length of the STUN message @ Message Length in temp buffer.
    431    //      0                   1                   2                   3
    432    //      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    433    //     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    434    //     |0 0|     STUN Message Type     |         Message Length        |
    435    //     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    436    SetBE16(temp_data.get() + 2, static_cast<uint16_t>(new_adjusted_len));
    437  }
    438 
    439  char hmac[kStunMessageIntegritySize];
    440  size_t ret = ComputeHmac(DIGEST_SHA_1, password.c_str(), password.size(),
    441                           temp_data.get(), mi_pos, hmac, sizeof(hmac));
    442  RTC_DCHECK(ret == sizeof(hmac));
    443  if (ret != sizeof(hmac)) {
    444    return false;
    445  }
    446 
    447  // Comparing the calculated HMAC with the one present in the message.
    448  return memcmp(data + current_pos + kStunAttributeHeaderSize, hmac,
    449                mi_attr_size) == 0;
    450 }
    451 
    452 bool StunMessage::AddMessageIntegrity(absl::string_view password) {
    453  return AddMessageIntegrityOfType(STUN_ATTR_MESSAGE_INTEGRITY,
    454                                   kStunMessageIntegritySize, password);
    455 }
    456 
    457 bool StunMessage::AddMessageIntegrity32(absl::string_view password) {
    458  return AddMessageIntegrityOfType(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32,
    459                                   kStunMessageIntegrity32Size, password);
    460 }
    461 
    462 bool StunMessage::AddMessageIntegrityOfType(int attr_type,
    463                                            size_t attr_size,
    464                                            absl::string_view key) {
    465  // Add the attribute with a dummy value. Since this is a known attribute, it
    466  // can't fail.
    467  RTC_DCHECK(attr_size <= kStunMessageIntegritySize);
    468  auto msg_integrity_attr_ptr = std::make_unique<StunByteStringAttribute>(
    469      attr_type, std::string(attr_size, '0'));
    470  auto* msg_integrity_attr = msg_integrity_attr_ptr.get();
    471  AddAttribute(std::move(msg_integrity_attr_ptr));
    472 
    473  // Calculate the HMAC for the message.
    474  ByteBufferWriter buf;
    475  if (!Write(&buf))
    476    return false;
    477 
    478  int msg_len_for_hmac = static_cast<int>(
    479      buf.Length() - kStunAttributeHeaderSize - msg_integrity_attr->length());
    480  char hmac[kStunMessageIntegritySize];
    481  size_t ret = ComputeHmac(DIGEST_SHA_1, key.data(), key.size(), buf.Data(),
    482                           msg_len_for_hmac, hmac, sizeof(hmac));
    483  RTC_DCHECK(ret == sizeof(hmac));
    484  if (ret != sizeof(hmac)) {
    485    RTC_LOG(LS_ERROR) << "HMAC computation failed. Message-Integrity "
    486                         "has dummy value.";
    487    return false;
    488  }
    489 
    490  // Insert correct HMAC into the attribute.
    491  msg_integrity_attr->CopyBytes(hmac, attr_size);
    492  password_ = std::string(key);
    493  integrity_ = IntegrityStatus::kIntegrityOk;
    494  return true;
    495 }
    496 
    497 // Verifies a message is in fact a STUN message, by performing the checks
    498 // outlined in RFC 5389, section 7.3, including the FINGERPRINT check detailed
    499 // in section 15.5.
    500 bool StunMessage::ValidateFingerprint(const char* data, size_t size) {
    501  // Check the message length.
    502  size_t fingerprint_attr_size =
    503      kStunAttributeHeaderSize + StunUInt32Attribute::SIZE;
    504  if (size % 4 != 0 || size < kStunHeaderSize + fingerprint_attr_size)
    505    return false;
    506 
    507  // Skip the rest if the magic cookie isn't present.
    508  const char* magic_cookie =
    509      data + kStunTransactionIdOffset - kStunMagicCookieLength;
    510  if (GetBE32(magic_cookie) != kStunMagicCookie)
    511    return false;
    512 
    513  // Check the fingerprint type and length.
    514  const char* fingerprint_attr_data = data + size - fingerprint_attr_size;
    515  if (GetBE16(fingerprint_attr_data) != STUN_ATTR_FINGERPRINT ||
    516      GetBE16(fingerprint_attr_data + sizeof(uint16_t)) !=
    517          StunUInt32Attribute::SIZE)
    518    return false;
    519 
    520  // Check the fingerprint value.
    521  uint32_t fingerprint =
    522      GetBE32(fingerprint_attr_data + kStunAttributeHeaderSize);
    523  return ((fingerprint ^ STUN_FINGERPRINT_XOR_VALUE) ==
    524          ComputeCrc32(data, size - fingerprint_attr_size));
    525 }
    526 
    527 // static
    528 std::string StunMessage::GenerateTransactionId() {
    529  return CreateRandomString(kStunTransactionIdLength);
    530 }
    531 
    532 bool StunMessage::IsStunMethod(ArrayView<int> methods,
    533                               const char* data,
    534                               size_t size) {
    535  // Check the message length.
    536  if (size % 4 != 0 || size < kStunHeaderSize)
    537    return false;
    538 
    539  // Skip the rest if the magic cookie isn't present.
    540  const char* magic_cookie =
    541      data + kStunTransactionIdOffset - kStunMagicCookieLength;
    542  if (GetBE32(magic_cookie) != kStunMagicCookie)
    543    return false;
    544 
    545  int method = GetBE16(data);
    546  for (int m : methods) {
    547    if (m == method) {
    548      return true;
    549    }
    550  }
    551  return false;
    552 }
    553 
    554 bool StunMessage::AddFingerprint() {
    555  // Add the attribute with a dummy value. Since this is a known attribute,
    556  // it can't fail.
    557  auto fingerprint_attr_ptr =
    558      std::make_unique<StunUInt32Attribute>(STUN_ATTR_FINGERPRINT, 0);
    559  auto* fingerprint_attr = fingerprint_attr_ptr.get();
    560  AddAttribute(std::move(fingerprint_attr_ptr));
    561 
    562  // Calculate the CRC-32 for the message and insert it.
    563  ByteBufferWriter buf;
    564  if (!Write(&buf))
    565    return false;
    566 
    567  int msg_len_for_crc32 = static_cast<int>(
    568      buf.Length() - kStunAttributeHeaderSize - fingerprint_attr->length());
    569  uint32_t c = ComputeCrc32(buf.Data(), msg_len_for_crc32);
    570 
    571  // Insert the correct CRC-32, XORed with a constant, into the attribute.
    572  fingerprint_attr->SetValue(c ^ STUN_FINGERPRINT_XOR_VALUE);
    573  return true;
    574 }
    575 
    576 bool StunMessage::Read(ByteBufferReader* buf) {
    577  // Keep a copy of the buffer data around for later verification.
    578  buffer_.assign(reinterpret_cast<const char*>(buf->Data()), buf->Length());
    579 
    580  if (!buf->ReadUInt16(&type_)) {
    581    return false;
    582  }
    583 
    584  if (type_ & 0x8000) {
    585    // RTP and RTCP set the MSB of first byte, since first two bits are version,
    586    // and version is always 2 (10). If set, this is not a STUN packet.
    587    return false;
    588  }
    589 
    590  if (!buf->ReadUInt16(&length_)) {
    591    return false;
    592  }
    593 
    594  absl::string_view magic_cookie;
    595  if (!buf->ReadStringView(&magic_cookie, kStunMagicCookieLength)) {
    596    return false;
    597  }
    598 
    599  std::string transaction_id;
    600  if (!buf->ReadString(&transaction_id, kStunTransactionIdLength)) {
    601    return false;
    602  }
    603 
    604  uint32_t magic_cookie_int;
    605  static_assert(sizeof(magic_cookie_int) == kStunMagicCookieLength,
    606                "Integer size mismatch: magic_cookie_int and kStunMagicCookie");
    607  std::memcpy(&magic_cookie_int, magic_cookie.data(), sizeof(magic_cookie_int));
    608  if (NetworkToHost32(magic_cookie_int) != kStunMagicCookie) {
    609    // If magic cookie is invalid it means that the peer implements
    610    // RFC3489 instead of RFC5389.
    611    transaction_id.insert(0, magic_cookie);
    612  }
    613  RTC_DCHECK(IsValidTransactionId(transaction_id));
    614  transaction_id_ = transaction_id;
    615  reduced_transaction_id_ = ReduceTransactionId(transaction_id_);
    616 
    617  if (length_ != buf->Length()) {
    618    return false;
    619  }
    620 
    621  attrs_.resize(0);
    622 
    623  size_t rest = buf->Length() - length_;
    624  while (buf->Length() > rest) {
    625    uint16_t attr_type, attr_length;
    626    if (!buf->ReadUInt16(&attr_type))
    627      return false;
    628    if (!buf->ReadUInt16(&attr_length))
    629      return false;
    630 
    631    std::unique_ptr<StunAttribute> attr(
    632        CreateAttribute(attr_type, attr_length));
    633    if (!attr) {
    634      // Skip any unknown or malformed attributes.
    635      if ((attr_length % 4) != 0) {
    636        attr_length += (4 - (attr_length % 4));
    637      }
    638      if (!buf->Consume(attr_length)) {
    639        return false;
    640      }
    641    } else {
    642      if (!attr->Read(buf)) {
    643        return false;
    644      }
    645      attrs_.push_back(std::move(attr));
    646    }
    647  }
    648 
    649  RTC_DCHECK(buf->Length() == rest);
    650  return true;
    651 }
    652 
    653 bool StunMessage::Write(ByteBufferWriter* buf) const {
    654  buf->WriteUInt16(type_);
    655  buf->WriteUInt16(length_);
    656  if (!IsLegacy())
    657    buf->WriteUInt32(stun_magic_cookie_);
    658  buf->WriteString(transaction_id_);
    659 
    660  for (const auto& attr : attrs_) {
    661    buf->WriteUInt16(attr->type());
    662    buf->WriteUInt16(static_cast<uint16_t>(attr->length()));
    663    if (!attr->Write(buf)) {
    664      return false;
    665    }
    666  }
    667 
    668  return true;
    669 }
    670 
    671 StunMessage* StunMessage::CreateNew() const {
    672  return new StunMessage();
    673 }
    674 
    675 void StunMessage::SetStunMagicCookie(uint32_t val) {
    676  stun_magic_cookie_ = val;
    677 }
    678 
    679 void StunMessage::SetTransactionIdForTesting(absl::string_view transaction_id) {
    680  RTC_DCHECK(IsValidTransactionId(transaction_id));
    681  transaction_id_ = std::string(transaction_id);
    682  reduced_transaction_id_ = ReduceTransactionId(transaction_id_);
    683 }
    684 
    685 StunAttributeValueType StunMessage::GetAttributeValueType(int type) const {
    686  switch (type) {
    687    case STUN_ATTR_MAPPED_ADDRESS:
    688      return STUN_VALUE_ADDRESS;
    689    case STUN_ATTR_USERNAME:
    690      return STUN_VALUE_BYTE_STRING;
    691    case STUN_ATTR_MESSAGE_INTEGRITY:
    692      return STUN_VALUE_BYTE_STRING;
    693    case STUN_ATTR_ERROR_CODE:
    694      return STUN_VALUE_ERROR_CODE;
    695    case STUN_ATTR_UNKNOWN_ATTRIBUTES:
    696      return STUN_VALUE_UINT16_LIST;
    697    case STUN_ATTR_REALM:
    698      return STUN_VALUE_BYTE_STRING;
    699    case STUN_ATTR_NONCE:
    700      return STUN_VALUE_BYTE_STRING;
    701    case STUN_ATTR_XOR_MAPPED_ADDRESS:
    702      return STUN_VALUE_XOR_ADDRESS;
    703    case STUN_ATTR_SOFTWARE:
    704      return STUN_VALUE_BYTE_STRING;
    705    case STUN_ATTR_ALTERNATE_SERVER:
    706      return STUN_VALUE_ADDRESS;
    707    case STUN_ATTR_FINGERPRINT:
    708      return STUN_VALUE_UINT32;
    709    case STUN_ATTR_RETRANSMIT_COUNT:
    710      return STUN_VALUE_UINT32;
    711    case STUN_ATTR_GOOG_LAST_ICE_CHECK_RECEIVED:
    712      return STUN_VALUE_BYTE_STRING;
    713    case STUN_ATTR_GOOG_MISC_INFO:
    714      return STUN_VALUE_UINT16_LIST;
    715    case STUN_ATTR_GOOG_DELTA:
    716      return STUN_VALUE_BYTE_STRING;
    717    case STUN_ATTR_GOOG_DELTA_ACK:
    718      return STUN_VALUE_UINT64;
    719    default:
    720      return STUN_VALUE_UNKNOWN;
    721  }
    722 }
    723 
    724 StunAttribute* StunMessage::CreateAttribute(int type, size_t length) /*const*/ {
    725  StunAttributeValueType value_type = GetAttributeValueType(type);
    726  if (value_type != STUN_VALUE_UNKNOWN) {
    727    return StunAttribute::Create(value_type, type,
    728                                 static_cast<uint16_t>(length), this);
    729  } else if (DesignatedExpertRange(type)) {
    730    // Read unknown attributes as STUN_VALUE_BYTE_STRING
    731    return StunAttribute::Create(STUN_VALUE_BYTE_STRING, type,
    732                                 static_cast<uint16_t>(length), this);
    733  } else {
    734    return nullptr;
    735  }
    736 }
    737 
    738 const StunAttribute* StunMessage::GetAttribute(int type) const {
    739  for (const auto& attr : attrs_) {
    740    if (attr->type() == type) {
    741      return attr.get();
    742    }
    743  }
    744  return nullptr;
    745 }
    746 
    747 bool StunMessage::IsValidTransactionId(absl::string_view transaction_id) {
    748  return transaction_id.size() == kStunTransactionIdLength ||
    749         transaction_id.size() == kStunLegacyTransactionIdLength;
    750 }
    751 
    752 bool StunMessage::EqualAttributes(
    753    const StunMessage* other,
    754    std::function<bool(int type)> attribute_type_mask) const {
    755  RTC_DCHECK(other != nullptr);
    756  ByteBufferWriter tmp_buffer_ptr1;
    757  ByteBufferWriter tmp_buffer_ptr2;
    758  for (const auto& attr : attrs_) {
    759    if (attribute_type_mask(attr->type())) {
    760      const StunAttribute* other_attr = other->GetAttribute(attr->type());
    761      if (other_attr == nullptr) {
    762        return false;
    763      }
    764      tmp_buffer_ptr1.Clear();
    765      tmp_buffer_ptr2.Clear();
    766      attr->Write(&tmp_buffer_ptr1);
    767      other_attr->Write(&tmp_buffer_ptr2);
    768      if (tmp_buffer_ptr1.Length() != tmp_buffer_ptr2.Length()) {
    769        return false;
    770      }
    771      if (memcmp(tmp_buffer_ptr1.Data(), tmp_buffer_ptr2.Data(),
    772                 tmp_buffer_ptr1.Length()) != 0) {
    773        return false;
    774      }
    775    }
    776  }
    777 
    778  for (const auto& attr : other->attrs_) {
    779    if (attribute_type_mask(attr->type())) {
    780      const StunAttribute* own_attr = GetAttribute(attr->type());
    781      if (own_attr == nullptr) {
    782        return false;
    783      }
    784      // we have already compared all values...
    785    }
    786  }
    787  return true;
    788 }
    789 
    790 // StunAttribute
    791 
    792 StunAttribute::StunAttribute(uint16_t type, uint16_t length)
    793    : type_(type), length_(length) {}
    794 
    795 void StunAttribute::ConsumePadding(ByteBufferReader* buf) const {
    796  int remainder = length_ % 4;
    797  if (remainder > 0) {
    798    buf->Consume(4 - remainder);
    799  }
    800 }
    801 
    802 void StunAttribute::WritePadding(ByteBufferWriter* buf) const {
    803  int remainder = length_ % 4;
    804  if (remainder > 0) {
    805    uint8_t zeroes[4] = {0};
    806    buf->Write(ArrayView<const uint8_t>(zeroes, 4 - remainder));
    807  }
    808 }
    809 
    810 StunAttribute* StunAttribute::Create(StunAttributeValueType value_type,
    811                                     uint16_t type,
    812                                     uint16_t length,
    813                                     StunMessage* owner) {
    814  switch (value_type) {
    815    case STUN_VALUE_ADDRESS:
    816      return new StunAddressAttribute(type, length);
    817    case STUN_VALUE_XOR_ADDRESS:
    818      return new StunXorAddressAttribute(type, length, owner);
    819    case STUN_VALUE_UINT32:
    820      return new StunUInt32Attribute(type);
    821    case STUN_VALUE_UINT64:
    822      return new StunUInt64Attribute(type);
    823    case STUN_VALUE_BYTE_STRING:
    824      return new StunByteStringAttribute(type, length);
    825    case STUN_VALUE_ERROR_CODE:
    826      return new StunErrorCodeAttribute(type, length);
    827    case STUN_VALUE_UINT16_LIST:
    828      return new StunUInt16ListAttribute(type, length);
    829    default:
    830      return nullptr;
    831  }
    832 }
    833 
    834 std::unique_ptr<StunAddressAttribute> StunAttribute::CreateAddress(
    835    uint16_t type) {
    836  return std::make_unique<StunAddressAttribute>(type, 0);
    837 }
    838 
    839 std::unique_ptr<StunXorAddressAttribute> StunAttribute::CreateXorAddress(
    840    uint16_t type) {
    841  return std::make_unique<StunXorAddressAttribute>(type, 0, nullptr);
    842 }
    843 
    844 std::unique_ptr<StunUInt64Attribute> StunAttribute::CreateUInt64(
    845    uint16_t type) {
    846  return std::make_unique<StunUInt64Attribute>(type);
    847 }
    848 
    849 std::unique_ptr<StunUInt32Attribute> StunAttribute::CreateUInt32(
    850    uint16_t type) {
    851  return std::make_unique<StunUInt32Attribute>(type);
    852 }
    853 
    854 std::unique_ptr<StunByteStringAttribute> StunAttribute::CreateByteString(
    855    uint16_t type) {
    856  return std::make_unique<StunByteStringAttribute>(type, 0);
    857 }
    858 
    859 std::unique_ptr<StunErrorCodeAttribute> StunAttribute::CreateErrorCode() {
    860  return std::make_unique<StunErrorCodeAttribute>(
    861      STUN_ATTR_ERROR_CODE, StunErrorCodeAttribute::MIN_SIZE);
    862 }
    863 
    864 std::unique_ptr<StunUInt16ListAttribute>
    865 StunAttribute::CreateUInt16ListAttribute(uint16_t type) {
    866  return std::make_unique<StunUInt16ListAttribute>(type, 0);
    867 }
    868 
    869 std::unique_ptr<StunUInt16ListAttribute>
    870 StunAttribute::CreateUnknownAttributes() {
    871  return std::make_unique<StunUInt16ListAttribute>(STUN_ATTR_UNKNOWN_ATTRIBUTES,
    872                                                   0);
    873 }
    874 
    875 StunAddressAttribute::StunAddressAttribute(uint16_t type,
    876                                           const SocketAddress& addr)
    877    : StunAttribute(type, 0) {
    878  SetAddress(addr);
    879 }
    880 
    881 StunAddressAttribute::StunAddressAttribute(uint16_t type, uint16_t length)
    882    : StunAttribute(type, length) {}
    883 
    884 StunAttributeValueType StunAddressAttribute::value_type() const {
    885  return STUN_VALUE_ADDRESS;
    886 }
    887 
    888 bool StunAddressAttribute::Read(ByteBufferReader* buf) {
    889  uint8_t dummy;
    890  if (!buf->ReadUInt8(&dummy))
    891    return false;
    892 
    893  uint8_t stun_family;
    894  if (!buf->ReadUInt8(&stun_family)) {
    895    return false;
    896  }
    897  uint16_t port;
    898  if (!buf->ReadUInt16(&port))
    899    return false;
    900  if (stun_family == STUN_ADDRESS_IPV4) {
    901    in_addr v4addr;
    902    if (length() != SIZE_IP4) {
    903      return false;
    904    }
    905    if (!buf->ReadBytes(MakeArrayView(reinterpret_cast<uint8_t*>(&v4addr),
    906                                      sizeof(v4addr)))) {
    907      return false;
    908    }
    909    IPAddress ipaddr(v4addr);
    910    SetAddress(SocketAddress(ipaddr, port));
    911  } else if (stun_family == STUN_ADDRESS_IPV6) {
    912    in6_addr v6addr;
    913    if (length() != SIZE_IP6) {
    914      return false;
    915    }
    916    if (!buf->ReadBytes(MakeArrayView(reinterpret_cast<uint8_t*>(&v6addr),
    917                                      sizeof(v6addr)))) {
    918      return false;
    919    }
    920    IPAddress ipaddr(v6addr);
    921    SetAddress(SocketAddress(ipaddr, port));
    922  } else {
    923    return false;
    924  }
    925  return true;
    926 }
    927 
    928 bool StunAddressAttribute::Write(ByteBufferWriter* buf) const {
    929  StunAddressFamily address_family = family();
    930  if (address_family == STUN_ADDRESS_UNDEF) {
    931    RTC_LOG(LS_ERROR) << "Error writing address attribute: unknown family.";
    932    return false;
    933  }
    934  buf->WriteUInt8(0);
    935  buf->WriteUInt8(address_family);
    936  buf->WriteUInt16(address_.port());
    937  switch (address_.family()) {
    938    case AF_INET: {
    939      in_addr v4addr = address_.ipaddr().ipv4_address();
    940      buf->Write(ArrayView<const uint8_t>(reinterpret_cast<uint8_t*>(&v4addr),
    941                                          sizeof(v4addr)));
    942      break;
    943    }
    944    case AF_INET6: {
    945      in6_addr v6addr = address_.ipaddr().ipv6_address();
    946      buf->Write(ArrayView<const uint8_t>(reinterpret_cast<uint8_t*>(&v6addr),
    947                                          sizeof(v6addr)));
    948      break;
    949    }
    950  }
    951  return true;
    952 }
    953 
    954 StunXorAddressAttribute::StunXorAddressAttribute(uint16_t type,
    955                                                 const SocketAddress& addr)
    956    : StunAddressAttribute(type, addr), owner_(nullptr) {}
    957 
    958 StunXorAddressAttribute::StunXorAddressAttribute(uint16_t type,
    959                                                 uint16_t length,
    960                                                 StunMessage* owner)
    961    : StunAddressAttribute(type, length), owner_(owner) {}
    962 
    963 StunAttributeValueType StunXorAddressAttribute::value_type() const {
    964  return STUN_VALUE_XOR_ADDRESS;
    965 }
    966 
    967 void StunXorAddressAttribute::SetOwner(StunMessage* owner) {
    968  owner_ = owner;
    969 }
    970 
    971 IPAddress StunXorAddressAttribute::GetXoredIP() const {
    972  if (owner_) {
    973    IPAddress ip = ipaddr();
    974    switch (ip.family()) {
    975      case AF_INET: {
    976        in_addr v4addr = ip.ipv4_address();
    977        v4addr.s_addr = (v4addr.s_addr ^ HostToNetwork32(kStunMagicCookie));
    978        return IPAddress(v4addr);
    979      }
    980      case AF_INET6: {
    981        in6_addr v6addr = ip.ipv6_address();
    982        const std::string& transaction_id = owner_->transaction_id();
    983        if (transaction_id.length() == kStunTransactionIdLength) {
    984          uint32_t transactionid_as_ints[3];
    985          memcpy(&transactionid_as_ints[0], transaction_id.c_str(),
    986                 transaction_id.length());
    987          uint32_t* ip_as_ints = reinterpret_cast<uint32_t*>(&v6addr.s6_addr);
    988          // Transaction ID is in network byte order, but magic cookie
    989          // is stored in host byte order.
    990          ip_as_ints[0] = (ip_as_ints[0] ^ HostToNetwork32(kStunMagicCookie));
    991          ip_as_ints[1] = (ip_as_ints[1] ^ transactionid_as_ints[0]);
    992          ip_as_ints[2] = (ip_as_ints[2] ^ transactionid_as_ints[1]);
    993          ip_as_ints[3] = (ip_as_ints[3] ^ transactionid_as_ints[2]);
    994          return IPAddress(v6addr);
    995        }
    996        break;
    997      }
    998    }
    999  }
   1000  // Invalid ip family or transaction ID, or missing owner.
   1001  // Return an AF_UNSPEC address.
   1002  return IPAddress();
   1003 }
   1004 
   1005 bool StunXorAddressAttribute::Read(ByteBufferReader* buf) {
   1006  if (!StunAddressAttribute::Read(buf))
   1007    return false;
   1008  uint16_t xoredport = port() ^ (kStunMagicCookie >> 16);
   1009  IPAddress xored_ip = GetXoredIP();
   1010  SetAddress(SocketAddress(xored_ip, xoredport));
   1011  return true;
   1012 }
   1013 
   1014 bool StunXorAddressAttribute::Write(ByteBufferWriter* buf) const {
   1015  StunAddressFamily address_family = family();
   1016  if (address_family == STUN_ADDRESS_UNDEF) {
   1017    RTC_LOG(LS_ERROR) << "Error writing xor-address attribute: unknown family.";
   1018    return false;
   1019  }
   1020  IPAddress xored_ip = GetXoredIP();
   1021  if (xored_ip.family() == AF_UNSPEC) {
   1022    return false;
   1023  }
   1024  buf->WriteUInt8(0);
   1025  buf->WriteUInt8(family());
   1026  buf->WriteUInt16(port() ^ (kStunMagicCookie >> 16));
   1027  switch (xored_ip.family()) {
   1028    case AF_INET: {
   1029      in_addr v4addr = xored_ip.ipv4_address();
   1030      buf->Write(ArrayView<const uint8_t>(
   1031          reinterpret_cast<const uint8_t*>(&v4addr), sizeof(v4addr)));
   1032      break;
   1033    }
   1034    case AF_INET6: {
   1035      in6_addr v6addr = xored_ip.ipv6_address();
   1036      buf->Write(ArrayView<const uint8_t>(
   1037          reinterpret_cast<const uint8_t*>(&v6addr), sizeof(v6addr)));
   1038      break;
   1039    }
   1040  }
   1041  return true;
   1042 }
   1043 
   1044 StunUInt32Attribute::StunUInt32Attribute(uint16_t type, uint32_t value)
   1045    : StunAttribute(type, SIZE), bits_(value) {}
   1046 
   1047 StunUInt32Attribute::StunUInt32Attribute(uint16_t type)
   1048    : StunAttribute(type, SIZE), bits_(0) {}
   1049 
   1050 StunAttributeValueType StunUInt32Attribute::value_type() const {
   1051  return STUN_VALUE_UINT32;
   1052 }
   1053 
   1054 bool StunUInt32Attribute::GetBit(size_t index) const {
   1055  RTC_DCHECK(index < 32);
   1056  return static_cast<bool>((bits_ >> index) & 0x1);
   1057 }
   1058 
   1059 void StunUInt32Attribute::SetBit(size_t index, bool value) {
   1060  RTC_DCHECK(index < 32);
   1061  bits_ &= ~(1 << index);
   1062  bits_ |= value ? (1 << index) : 0;
   1063 }
   1064 
   1065 bool StunUInt32Attribute::Read(ByteBufferReader* buf) {
   1066  if (length() != SIZE || !buf->ReadUInt32(&bits_))
   1067    return false;
   1068  return true;
   1069 }
   1070 
   1071 bool StunUInt32Attribute::Write(ByteBufferWriter* buf) const {
   1072  buf->WriteUInt32(bits_);
   1073  return true;
   1074 }
   1075 
   1076 StunUInt64Attribute::StunUInt64Attribute(uint16_t type, uint64_t value)
   1077    : StunAttribute(type, SIZE), bits_(value) {}
   1078 
   1079 StunUInt64Attribute::StunUInt64Attribute(uint16_t type)
   1080    : StunAttribute(type, SIZE), bits_(0) {}
   1081 
   1082 StunAttributeValueType StunUInt64Attribute::value_type() const {
   1083  return STUN_VALUE_UINT64;
   1084 }
   1085 
   1086 bool StunUInt64Attribute::Read(ByteBufferReader* buf) {
   1087  if (length() != SIZE || !buf->ReadUInt64(&bits_))
   1088    return false;
   1089  return true;
   1090 }
   1091 
   1092 bool StunUInt64Attribute::Write(ByteBufferWriter* buf) const {
   1093  buf->WriteUInt64(bits_);
   1094  return true;
   1095 }
   1096 
   1097 StunByteStringAttribute::StunByteStringAttribute(uint16_t type)
   1098    : StunAttribute(type, 0), bytes_(nullptr) {}
   1099 
   1100 StunByteStringAttribute::StunByteStringAttribute(uint16_t type,
   1101                                                 absl::string_view str)
   1102    : StunAttribute(type, 0), bytes_(nullptr) {
   1103  CopyBytes(str);
   1104 }
   1105 
   1106 StunByteStringAttribute::StunByteStringAttribute(uint16_t type,
   1107                                                 const void* bytes,
   1108                                                 size_t length)
   1109    : StunAttribute(type, 0), bytes_(nullptr) {
   1110  CopyBytes(bytes, length);
   1111 }
   1112 
   1113 StunByteStringAttribute::StunByteStringAttribute(
   1114    uint16_t type,
   1115    const std::vector<uint32_t>& values)
   1116    : StunAttribute(type, 0), bytes_(nullptr) {
   1117  ByteBufferWriter writer;
   1118  for (const auto& value : values) {
   1119    writer.WriteUInt32(value);
   1120  }
   1121  CopyBytes(writer.Data(), writer.Length());
   1122 }
   1123 
   1124 StunByteStringAttribute::StunByteStringAttribute(uint16_t type, uint16_t length)
   1125    : StunAttribute(type, length), bytes_(nullptr) {}
   1126 
   1127 StunByteStringAttribute::~StunByteStringAttribute() {
   1128  delete[] bytes_;
   1129 }
   1130 
   1131 StunAttributeValueType StunByteStringAttribute::value_type() const {
   1132  return STUN_VALUE_BYTE_STRING;
   1133 }
   1134 
   1135 std::optional<std::vector<uint32_t>> StunByteStringAttribute::GetUInt32Vector()
   1136    const {
   1137  if (length() % 4 != 0) {
   1138    return std::nullopt;
   1139  }
   1140  std::vector<uint32_t> values;
   1141  ByteBufferReader reader(array_view());
   1142  uint32_t value;
   1143  while (reader.ReadUInt32(&value)) {
   1144    values.push_back(value);
   1145  }
   1146  return values;
   1147 }
   1148 
   1149 void StunByteStringAttribute::CopyBytes(absl::string_view bytes) {
   1150  uint8_t* new_bytes = new uint8_t[bytes.size()];
   1151  memcpy(new_bytes, bytes.data(), bytes.size());
   1152  SetBytes(new_bytes, bytes.size());
   1153 }
   1154 
   1155 void StunByteStringAttribute::CopyBytes(const void* bytes, size_t length) {
   1156  uint8_t* new_bytes = new uint8_t[length];
   1157  memcpy(new_bytes, bytes, length);
   1158  SetBytes(new_bytes, length);
   1159 }
   1160 
   1161 uint8_t StunByteStringAttribute::GetByte(size_t index) const {
   1162  RTC_DCHECK(bytes_ != nullptr);
   1163  RTC_DCHECK(index < length());
   1164  return bytes_[index];
   1165 }
   1166 
   1167 void StunByteStringAttribute::SetByte(size_t index, uint8_t value) {
   1168  RTC_DCHECK(bytes_ != nullptr);
   1169  RTC_DCHECK(index < length());
   1170  bytes_[index] = value;
   1171 }
   1172 
   1173 bool StunByteStringAttribute::Read(ByteBufferReader* buf) {
   1174  bytes_ = new uint8_t[length()];
   1175  if (!buf->ReadBytes(ArrayView<uint8_t>(bytes_, length()))) {
   1176    return false;
   1177  }
   1178 
   1179  ConsumePadding(buf);
   1180  return true;
   1181 }
   1182 
   1183 bool StunByteStringAttribute::Write(ByteBufferWriter* buf) const {
   1184  // Check that length is legal according to specs
   1185  if (!LengthValid(type(), length())) {
   1186    return false;
   1187  }
   1188  buf->Write(ArrayView<const uint8_t>(bytes_, length()));
   1189  WritePadding(buf);
   1190  return true;
   1191 }
   1192 
   1193 void StunByteStringAttribute::SetBytes(uint8_t* bytes, size_t length) {
   1194  delete[] bytes_;
   1195  bytes_ = bytes;
   1196  SetLength(static_cast<uint16_t>(length));
   1197 }
   1198 
   1199 const uint16_t StunErrorCodeAttribute::MIN_SIZE = 4;
   1200 
   1201 StunErrorCodeAttribute::StunErrorCodeAttribute(uint16_t type,
   1202                                               int code,
   1203                                               const std::string& reason)
   1204    : StunAttribute(type, 0) {
   1205  SetCode(code);
   1206  SetReason(reason);
   1207 }
   1208 
   1209 StunErrorCodeAttribute::StunErrorCodeAttribute(uint16_t type, uint16_t length)
   1210    : StunAttribute(type, length), class_(0), number_(0) {}
   1211 
   1212 StunErrorCodeAttribute::~StunErrorCodeAttribute() {}
   1213 
   1214 StunAttributeValueType StunErrorCodeAttribute::value_type() const {
   1215  return STUN_VALUE_ERROR_CODE;
   1216 }
   1217 
   1218 int StunErrorCodeAttribute::code() const {
   1219  return class_ * 100 + number_;
   1220 }
   1221 
   1222 void StunErrorCodeAttribute::SetCode(int code) {
   1223  class_ = static_cast<uint8_t>(code / 100);
   1224  number_ = static_cast<uint8_t>(code % 100);
   1225 }
   1226 
   1227 void StunErrorCodeAttribute::SetReason(const std::string& reason) {
   1228  SetLength(MIN_SIZE + static_cast<uint16_t>(reason.size()));
   1229  reason_ = reason;
   1230 }
   1231 
   1232 bool StunErrorCodeAttribute::Read(ByteBufferReader* buf) {
   1233  uint32_t val;
   1234  if (length() < MIN_SIZE || !buf->ReadUInt32(&val))
   1235    return false;
   1236 
   1237  if ((val >> 11) != 0)
   1238    RTC_LOG(LS_ERROR) << "error-code bits not zero";
   1239 
   1240  class_ = ((val >> 8) & 0x7);
   1241  number_ = (val & 0xff);
   1242 
   1243  if (!buf->ReadString(&reason_, length() - 4))
   1244    return false;
   1245 
   1246  ConsumePadding(buf);
   1247  return true;
   1248 }
   1249 
   1250 bool StunErrorCodeAttribute::Write(ByteBufferWriter* buf) const {
   1251  buf->WriteUInt32(class_ << 8 | number_);
   1252  buf->WriteString(reason_);
   1253  WritePadding(buf);
   1254  return true;
   1255 }
   1256 
   1257 StunUInt16ListAttribute::StunUInt16ListAttribute(uint16_t type, uint16_t length)
   1258    : StunAttribute(type, length) {
   1259  attr_types_ = new std::vector<uint16_t>();
   1260 }
   1261 
   1262 StunUInt16ListAttribute::~StunUInt16ListAttribute() {
   1263  delete attr_types_;
   1264 }
   1265 
   1266 StunAttributeValueType StunUInt16ListAttribute::value_type() const {
   1267  return STUN_VALUE_UINT16_LIST;
   1268 }
   1269 
   1270 size_t StunUInt16ListAttribute::Size() const {
   1271  return attr_types_->size();
   1272 }
   1273 
   1274 uint16_t StunUInt16ListAttribute::GetType(int index) const {
   1275  return (*attr_types_)[index];
   1276 }
   1277 
   1278 void StunUInt16ListAttribute::SetType(int index, uint16_t value) {
   1279  (*attr_types_)[index] = value;
   1280 }
   1281 
   1282 void StunUInt16ListAttribute::AddType(uint16_t value) {
   1283  attr_types_->push_back(value);
   1284  SetLength(static_cast<uint16_t>(attr_types_->size() * 2));
   1285 }
   1286 
   1287 void StunUInt16ListAttribute::AddTypeAtIndex(uint16_t index, uint16_t value) {
   1288  if (attr_types_->size() < static_cast<size_t>(index + 1)) {
   1289    attr_types_->resize(index + 1);
   1290  }
   1291  (*attr_types_)[index] = value;
   1292  SetLength(static_cast<uint16_t>(attr_types_->size() * 2));
   1293 }
   1294 
   1295 bool StunUInt16ListAttribute::Read(ByteBufferReader* buf) {
   1296  if (length() % 2) {
   1297    return false;
   1298  }
   1299 
   1300  for (size_t i = 0; i < length() / 2; i++) {
   1301    uint16_t attr;
   1302    if (!buf->ReadUInt16(&attr))
   1303      return false;
   1304    attr_types_->push_back(attr);
   1305  }
   1306  // Padding of these attributes is done in RFC 5389 style. This is
   1307  // slightly different from RFC3489, but it shouldn't be important.
   1308  // RFC3489 pads out to a 32 bit boundary by duplicating one of the
   1309  // entries in the list (not necessarily the last one - it's unspecified).
   1310  // RFC5389 pads on the end, and the bytes are always ignored.
   1311  ConsumePadding(buf);
   1312  return true;
   1313 }
   1314 
   1315 bool StunUInt16ListAttribute::Write(ByteBufferWriter* buf) const {
   1316  for (size_t i = 0; i < attr_types_->size(); ++i) {
   1317    buf->WriteUInt16((*attr_types_)[i]);
   1318  }
   1319  WritePadding(buf);
   1320  return true;
   1321 }
   1322 
   1323 std::string StunMethodToString(int msg_type) {
   1324  switch (msg_type) {
   1325    case STUN_BINDING_REQUEST:
   1326      return "STUN BINDING request";
   1327    case STUN_BINDING_INDICATION:
   1328      return "STUN BINDING indication";
   1329    case STUN_BINDING_RESPONSE:
   1330      return "STUN BINDING response";
   1331    case STUN_BINDING_ERROR_RESPONSE:
   1332      return "STUN BINDING error response";
   1333    case GOOG_PING_REQUEST:
   1334      return "GOOG PING request";
   1335    case GOOG_PING_RESPONSE:
   1336      return "GOOG PING response";
   1337    case GOOG_PING_ERROR_RESPONSE:
   1338      return "GOOG PING error response";
   1339    case STUN_ALLOCATE_REQUEST:
   1340      return "TURN ALLOCATE request";
   1341    case STUN_ALLOCATE_RESPONSE:
   1342      return "TURN ALLOCATE response";
   1343    case STUN_ALLOCATE_ERROR_RESPONSE:
   1344      return "TURN ALLOCATE error response";
   1345    case TURN_REFRESH_REQUEST:
   1346      return "TURN REFRESH request";
   1347    case TURN_REFRESH_RESPONSE:
   1348      return "TURN REFRESH response";
   1349    case TURN_REFRESH_ERROR_RESPONSE:
   1350      return "TURN REFRESH error response";
   1351    case TURN_SEND_INDICATION:
   1352      return "TURN SEND INDICATION";
   1353    case TURN_DATA_INDICATION:
   1354      return "TURN DATA INDICATION";
   1355    case TURN_CREATE_PERMISSION_REQUEST:
   1356      return "TURN CREATE PERMISSION request";
   1357    case TURN_CREATE_PERMISSION_RESPONSE:
   1358      return "TURN CREATE PERMISSION response";
   1359    case TURN_CREATE_PERMISSION_ERROR_RESPONSE:
   1360      return "TURN CREATE PERMISSION error response";
   1361    case TURN_CHANNEL_BIND_REQUEST:
   1362      return "TURN CHANNEL BIND request";
   1363    case TURN_CHANNEL_BIND_RESPONSE:
   1364      return "TURN CHANNEL BIND response";
   1365    case TURN_CHANNEL_BIND_ERROR_RESPONSE:
   1366      return "TURN CHANNEL BIND error response";
   1367    default:
   1368      return "UNKNOWN<" + std::to_string(msg_type) + ">";
   1369  }
   1370 }
   1371 
   1372 int GetStunSuccessResponseType(int req_type) {
   1373  return IsStunRequestType(req_type) ? (req_type | 0x100) : -1;
   1374 }
   1375 
   1376 int GetStunErrorResponseType(int req_type) {
   1377  return IsStunRequestType(req_type) ? (req_type | 0x110) : -1;
   1378 }
   1379 
   1380 bool IsStunRequestType(int msg_type) {
   1381  return ((msg_type & kStunTypeMask) == 0x000);
   1382 }
   1383 
   1384 bool IsStunIndicationType(int msg_type) {
   1385  return ((msg_type & kStunTypeMask) == 0x010);
   1386 }
   1387 
   1388 bool IsStunSuccessResponseType(int msg_type) {
   1389  return ((msg_type & kStunTypeMask) == 0x100);
   1390 }
   1391 
   1392 bool IsStunErrorResponseType(int msg_type) {
   1393  return ((msg_type & kStunTypeMask) == 0x110);
   1394 }
   1395 
   1396 bool ComputeStunCredentialHash(const std::string& username,
   1397                               const std::string& realm,
   1398                               const std::string& password,
   1399                               std::string* hash) {
   1400  // http://tools.ietf.org/html/rfc5389#section-15.4
   1401  // long-term credentials will be calculated using the key and key is
   1402  // key = MD5(username ":" realm ":" SASLprep(password))
   1403  std::string input = username;
   1404  input += ':';
   1405  input += realm;
   1406  input += ':';
   1407  input += password;
   1408 
   1409  char digest[MessageDigest::kMaxSize];
   1410  size_t size = ComputeDigest(DIGEST_MD5, input.c_str(), input.size(), digest,
   1411                              sizeof(digest));
   1412  if (size == 0) {
   1413    return false;
   1414  }
   1415 
   1416  *hash = std::string(digest, size);
   1417  return true;
   1418 }
   1419 
   1420 std::unique_ptr<StunAttribute> CopyStunAttribute(
   1421    const StunAttribute& attribute,
   1422    ByteBufferWriter* tmp_buffer_ptr) {
   1423  ByteBufferWriter tmpBuffer;
   1424  if (tmp_buffer_ptr == nullptr) {
   1425    tmp_buffer_ptr = &tmpBuffer;
   1426  }
   1427 
   1428  std::unique_ptr<StunAttribute> copy(StunAttribute::Create(
   1429      attribute.value_type(), attribute.type(),
   1430      static_cast<uint16_t>(attribute.length()), nullptr));
   1431 
   1432  if (!copy) {
   1433    return nullptr;
   1434  }
   1435  tmp_buffer_ptr->Clear();
   1436  if (!attribute.Write(tmp_buffer_ptr)) {
   1437    return nullptr;
   1438  }
   1439  ByteBufferReader reader(*tmp_buffer_ptr);
   1440  if (!copy->Read(&reader)) {
   1441    return nullptr;
   1442  }
   1443 
   1444  return copy;
   1445 }
   1446 
   1447 StunAttributeValueType TurnMessage::GetAttributeValueType(int type) const {
   1448  switch (type) {
   1449    case STUN_ATTR_CHANNEL_NUMBER:
   1450      return STUN_VALUE_UINT32;
   1451    case STUN_ATTR_LIFETIME:
   1452      return STUN_VALUE_UINT32;
   1453    case STUN_ATTR_XOR_PEER_ADDRESS:
   1454      return STUN_VALUE_XOR_ADDRESS;
   1455    case STUN_ATTR_DATA:
   1456      return STUN_VALUE_BYTE_STRING;
   1457    case STUN_ATTR_XOR_RELAYED_ADDRESS:
   1458      return STUN_VALUE_XOR_ADDRESS;
   1459    case STUN_ATTR_EVEN_PORT:
   1460      return STUN_VALUE_BYTE_STRING;
   1461    case STUN_ATTR_REQUESTED_TRANSPORT:
   1462      return STUN_VALUE_UINT32;
   1463    case STUN_ATTR_DONT_FRAGMENT:
   1464      return STUN_VALUE_BYTE_STRING;
   1465    case STUN_ATTR_RESERVATION_TOKEN:
   1466      return STUN_VALUE_BYTE_STRING;
   1467    default:
   1468      return StunMessage::GetAttributeValueType(type);
   1469  }
   1470 }
   1471 
   1472 StunMessage* TurnMessage::CreateNew() const {
   1473  return new TurnMessage();
   1474 }
   1475 
   1476 StunAttributeValueType IceMessage::GetAttributeValueType(int type) const {
   1477  switch (type) {
   1478    case STUN_ATTR_PRIORITY:
   1479    case STUN_ATTR_GOOG_NETWORK_INFO:
   1480    case STUN_ATTR_NOMINATION:
   1481      return STUN_VALUE_UINT32;
   1482    case STUN_ATTR_USE_CANDIDATE:
   1483      return STUN_VALUE_BYTE_STRING;
   1484    case STUN_ATTR_ICE_CONTROLLED:
   1485      return STUN_VALUE_UINT64;
   1486    case STUN_ATTR_ICE_CONTROLLING:
   1487      return STUN_VALUE_UINT64;
   1488    default:
   1489      return StunMessage::GetAttributeValueType(type);
   1490  }
   1491 }
   1492 
   1493 StunMessage* IceMessage::CreateNew() const {
   1494  return new IceMessage();
   1495 }
   1496 
   1497 std::unique_ptr<StunMessage> StunMessage::Clone() const {
   1498  std::unique_ptr<StunMessage> copy(CreateNew());
   1499  if (!copy) {
   1500    return nullptr;
   1501  }
   1502  ByteBufferWriter buf;
   1503  if (!Write(&buf)) {
   1504    return nullptr;
   1505  }
   1506  ByteBufferReader reader(buf);
   1507  if (!copy->Read(&reader)) {
   1508    return nullptr;
   1509  }
   1510  return copy;
   1511 }
   1512 
   1513 }  // namespace webrtc