tor-browser

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

stun_unittest.cc (69509B)


      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 <cstdint>
     14 #include <cstring>
     15 #include <memory>
     16 #include <optional>
     17 #include <string>
     18 #include <utility>
     19 #include <vector>
     20 
     21 #include "api/array_view.h"
     22 #include "rtc_base/byte_buffer.h"
     23 #include "rtc_base/byte_order.h"
     24 #include "rtc_base/ip_address.h"
     25 #include "rtc_base/socket_address.h"
     26 #include "system_wrappers/include/metrics.h"
     27 #include "test/gmock.h"
     28 #include "test/gtest.h"
     29 
     30 namespace webrtc {
     31 
     32 namespace {
     33 // Sample STUN packets with various attributes
     34 // Gathered by wiresharking pjproject's pjnath test programs
     35 // pjproject available at www.pjsip.org
     36 
     37 // clang-format off
     38 // clang formatting doesn't respect inline comments.
     39 
     40 constexpr uint8_t kStunMessageWithIPv6MappedAddress[] = {
     41  0x00, 0x01, 0x00, 0x18,  // message header
     42  0x21, 0x12, 0xa4, 0x42,  // transaction id
     43  0x29, 0x1f, 0xcd, 0x7c,
     44  0xba, 0x58, 0xab, 0xd7,
     45  0xf2, 0x41, 0x01, 0x00,
     46  0x00, 0x01, 0x00, 0x14,  // Address type (mapped), length
     47  0x00, 0x02, 0xb8, 0x81,  // family (IPv6), port
     48  0x24, 0x01, 0xfa, 0x00,  // an IPv6 address
     49  0x00, 0x04, 0x10, 0x00,
     50  0xbe, 0x30, 0x5b, 0xff,
     51  0xfe, 0xe5, 0x00, 0xc3
     52 };
     53 
     54 constexpr uint8_t kStunMessageWithIPv4MappedAddress[] = {
     55  0x01, 0x01, 0x00, 0x0c,   // binding response, length 12
     56  0x21, 0x12, 0xa4, 0x42,   // magic cookie
     57  0x29, 0x1f, 0xcd, 0x7c,   // transaction ID
     58  0xba, 0x58, 0xab, 0xd7,
     59  0xf2, 0x41, 0x01, 0x00,
     60  0x00, 0x01, 0x00, 0x08,  // Mapped, 8 byte length
     61  0x00, 0x01, 0x9d, 0xfc,  // AF_INET, unxor-ed port
     62  0xac, 0x17, 0x44, 0xe6   // IPv4 address
     63 };
     64 
     65 // Test XOR-mapped IP addresses:
     66 constexpr uint8_t kStunMessageWithIPv6XorMappedAddress[] = {
     67  0x01, 0x01, 0x00, 0x18,  // message header (binding response)
     68  0x21, 0x12, 0xa4, 0x42,  // magic cookie (rfc5389)
     69  0xe3, 0xa9, 0x46, 0xe1,  // transaction ID
     70  0x7c, 0x00, 0xc2, 0x62,
     71  0x54, 0x08, 0x01, 0x00,
     72  0x00, 0x20, 0x00, 0x14,  // Address Type (XOR), length
     73  0x00, 0x02, 0xcb, 0x5b,  // family, XOR-ed port
     74  0x05, 0x13, 0x5e, 0x42,  // XOR-ed IPv6 address
     75  0xe3, 0xad, 0x56, 0xe1,
     76  0xc2, 0x30, 0x99, 0x9d,
     77  0xaa, 0xed, 0x01, 0xc3
     78 };
     79 
     80 constexpr uint8_t kStunMessageWithIPv4XorMappedAddress[] = {
     81  0x01, 0x01, 0x00, 0x0c,  // message header (binding response)
     82  0x21, 0x12, 0xa4, 0x42,  // magic cookie
     83  0x29, 0x1f, 0xcd, 0x7c,  // transaction ID
     84  0xba, 0x58, 0xab, 0xd7,
     85  0xf2, 0x41, 0x01, 0x00,
     86  0x00, 0x20, 0x00, 0x08,  // address type (xor), length
     87  0x00, 0x01, 0xfc, 0xb5,  // family (AF_INET), XOR-ed port
     88  0x8d, 0x05, 0xe0, 0xa4   // IPv4 address
     89 };
     90 
     91 // ByteString Attribute (username)
     92 constexpr uint8_t kStunMessageWithByteStringAttribute[] = {
     93  0x00, 0x01, 0x00, 0x0c,
     94  0x21, 0x12, 0xa4, 0x42,
     95  0xe3, 0xa9, 0x46, 0xe1,
     96  0x7c, 0x00, 0xc2, 0x62,
     97  0x54, 0x08, 0x01, 0x00,
     98  0x00, 0x06, 0x00, 0x08,  // username attribute (length 8)
     99  0x61, 0x62, 0x63, 0x64,  // abcdefgh
    100  0x65, 0x66, 0x67, 0x68
    101 };
    102 
    103 // Message with an unknown but comprehensible optional attribute.
    104 // Parsing should succeed despite this unknown attribute.
    105 constexpr uint8_t kStunMessageWithUnknownAttribute[] = {
    106  0x00, 0x01, 0x00, 0x14,
    107  0x21, 0x12, 0xa4, 0x42,
    108  0xe3, 0xa9, 0x46, 0xe1,
    109  0x7c, 0x00, 0xc2, 0x62,
    110  0x54, 0x08, 0x01, 0x00,
    111  0x00, 0xaa, 0x00, 0x07,  // Unknown attribute, length 7 (needs padding!)
    112  0x61, 0x62, 0x63, 0x64,  // abcdefg + padding
    113  0x65, 0x66, 0x67, 0x00,
    114  0x00, 0x06, 0x00, 0x03,  // Followed by a known attribute we can
    115  0x61, 0x62, 0x63, 0x00   // check for (username of length 3)
    116 };
    117 
    118 // ByteString Attribute (username) with padding byte
    119 constexpr uint8_t kStunMessageWithPaddedByteStringAttribute[] = {
    120  0x00, 0x01, 0x00, 0x08,
    121  0x21, 0x12, 0xa4, 0x42,
    122  0xe3, 0xa9, 0x46, 0xe1,
    123  0x7c, 0x00, 0xc2, 0x62,
    124  0x54, 0x08, 0x01, 0x00,
    125  0x00, 0x06, 0x00, 0x03,  // username attribute (length 3)
    126  0x61, 0x62, 0x63, 0xcc   // abc
    127 };
    128 
    129 // Message with an Unknown Attributes (uint16_t list) attribute.
    130 constexpr uint8_t kStunMessageWithUInt16ListAttribute[] = {
    131  0x00, 0x01, 0x00, 0x0c,
    132  0x21, 0x12, 0xa4, 0x42,
    133  0xe3, 0xa9, 0x46, 0xe1,
    134  0x7c, 0x00, 0xc2, 0x62,
    135  0x54, 0x08, 0x01, 0x00,
    136  0x00, 0x0a, 0x00, 0x06,  // username attribute (length 6)
    137  0x00, 0x01, 0x10, 0x00,  // three attributes plus padding
    138  0xAB, 0xCU, 0xBE, 0xEF
    139 };
    140 
    141 // Error response message (unauthorized)
    142 constexpr uint8_t kStunMessageWithErrorAttribute[] = {
    143  0x01, 0x11, 0x00, 0x14,
    144  0x21, 0x12, 0xa4, 0x42,
    145  0x29, 0x1f, 0xcd, 0x7c,
    146  0xba, 0x58, 0xab, 0xd7,
    147  0xf2, 0x41, 0x01, 0x00,
    148  0x00, 0x09, 0x00, 0x10,
    149  0x00, 0x00, 0x04, 0x01,
    150  0x55, 0x6e, 0x61, 0x75,
    151  0x74, 0x68, 0x6f, 0x72,
    152  0x69, 0x7a, 0x65, 0x64
    153 };
    154 
    155 // Sample messages with an invalid length Field
    156 
    157 // The actual length in bytes of the invalid messages (including STUN header)
    158 constexpr int kRealLengthOfInvalidLengthTestCases = 32;
    159 
    160 constexpr uint8_t kStunMessageWithZeroLength[] = {
    161  0x00, 0x01, 0x00, 0x00,  // length of 0 (last 2 bytes)
    162  0x21, 0x12, 0xA4, 0x42,  // magic cookie
    163  '0', '1', '2', '3',      // transaction id
    164  '4', '5', '6', '7',
    165  '8', '9', 'a', 'b',
    166  0x00, 0x20, 0x00, 0x08,  // xor mapped address
    167  0x00, 0x01, 0x21, 0x1F,
    168  0x21, 0x12, 0xA4, 0x53,
    169 };
    170 
    171 constexpr uint8_t kStunMessageWithExcessLength[] = {
    172  0x00, 0x01, 0x00, 0x55,  // length of 85
    173  0x21, 0x12, 0xA4, 0x42,  // magic cookie
    174  '0', '1', '2', '3',      // transaction id
    175  '4', '5', '6', '7',
    176  '8', '9', 'a', 'b',
    177  0x00, 0x20, 0x00, 0x08,  // xor mapped address
    178  0x00, 0x01, 0x21, 0x1F,
    179  0x21, 0x12, 0xA4, 0x53,
    180 };
    181 
    182 constexpr uint8_t kStunMessageWithSmallLength[] = {
    183  0x00, 0x01, 0x00, 0x03,  // length of 3
    184  0x21, 0x12, 0xA4, 0x42,  // magic cookie
    185  '0', '1', '2', '3',      // transaction id
    186  '4', '5', '6', '7',
    187  '8', '9', 'a', 'b',
    188  0x00, 0x20, 0x00, 0x08,  // xor mapped address
    189  0x00, 0x01, 0x21, 0x1F,
    190  0x21, 0x12, 0xA4, 0x53,
    191 };
    192 
    193 constexpr uint8_t kStunMessageWithBadHmacAtEnd[] = {
    194  0x00, 0x01, 0x00, 0x14,  // message length exactly 20
    195  0x21, 0x12, 0xA4, 0x42,  // magic cookie
    196  '0', '1', '2', '3',      // transaction ID
    197  '4', '5', '6', '7',
    198  '8', '9', 'a', 'b',
    199  0x00, 0x08, 0x00, 0x14,  // type=STUN_ATTR_MESSAGE_INTEGRITY, length=20
    200  '0', '0', '0', '0',      // We lied, there are only 16 bytes of HMAC.
    201  '0', '0', '0', '0',
    202  '0', '0', '0', '0',
    203  '0', '0', '0', '0',
    204 };
    205 
    206 // RTCP packet, for testing we correctly ignore non stun packet types.
    207 // V=2, P=false, RC=0, Type=200, Len=6, Sender-SSRC=85, etc
    208 constexpr uint8_t kRtcpPacket[] = {
    209  0x80, 0xc8, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55,
    210  0xce, 0xa5, 0x18, 0x3a, 0x39, 0xcc, 0x7d, 0x09,
    211  0x23, 0xed, 0x19, 0x07, 0x00, 0x00, 0x01, 0x56,
    212  0x00, 0x03, 0x73, 0x50,
    213 };
    214 
    215 
    216 // RFC5769 Test Vectors
    217 // Software name (request):  "STUN test client" (without quotes)
    218 // Software name (response): "test vector" (without quotes)
    219 // Username:  "evtj:h6vY" (without quotes)
    220 // Password:  "VOkJxbRl1RmTxUk/WvJxBt" (without quotes)
    221 constexpr uint8_t kRfc5769SampleMsgTransactionId[] = {
    222  0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34, 0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae
    223 };
    224 constexpr char kRfc5769SampleMsgClientSoftware[] = "STUN test client";
    225 constexpr char kRfc5769SampleMsgServerSoftware[] = "test vector";
    226 constexpr char kRfc5769SampleMsgUsername[] = "evtj:h6vY";
    227 constexpr char kRfc5769SampleMsgPassword[] = "VOkJxbRl1RmTxUk/WvJxBt";
    228 const SocketAddress kRfc5769SampleMsgMappedAddress(
    229    "192.0.2.1", 32853);
    230 const SocketAddress kRfc5769SampleMsgIPv6MappedAddress(
    231    "2001:db8:1234:5678:11:2233:4455:6677", 32853);
    232 
    233 constexpr uint8_t kRfc5769SampleMsgWithAuthTransactionId[] = {
    234  0x78, 0xad, 0x34, 0x33, 0xc6, 0xad, 0x72, 0xc0, 0x29, 0xda, 0x41, 0x2e
    235 };
    236 constexpr char kRfc5769SampleMsgWithAuthUsername[] =
    237    "\xe3\x83\x9e\xe3\x83\x88\xe3\x83\xaa\xe3\x83\x83\xe3\x82\xaf\xe3\x82\xb9";
    238 constexpr char kRfc5769SampleMsgWithAuthPassword[] = "TheMatrIX";
    239 constexpr char kRfc5769SampleMsgWithAuthNonce[] =
    240    "f//499k954d6OL34oL9FSTvy64sA";
    241 constexpr char kRfc5769SampleMsgWithAuthRealm[] = "example.org";
    242 
    243 // 2.1.  Sample Request
    244 constexpr uint8_t kRfc5769SampleRequest[] = {
    245  0x00, 0x01, 0x00, 0x58,   //    Request type and message length
    246  0x21, 0x12, 0xa4, 0x42,   //    Magic cookie
    247  0xb7, 0xe7, 0xa7, 0x01,   // }
    248  0xbc, 0x34, 0xd6, 0x86,   // }  Transaction ID
    249  0xfa, 0x87, 0xdf, 0xae,   // }
    250  0x80, 0x22, 0x00, 0x10,   //    SOFTWARE attribute header
    251  0x53, 0x54, 0x55, 0x4e,   // }
    252  0x20, 0x74, 0x65, 0x73,   // }  User-agent...
    253  0x74, 0x20, 0x63, 0x6c,   // }  ...name
    254  0x69, 0x65, 0x6e, 0x74,   // }
    255  0x00, 0x24, 0x00, 0x04,   //    PRIORITY attribute header
    256  0x6e, 0x00, 0x01, 0xff,   //    ICE priority value
    257  0x80, 0x29, 0x00, 0x08,   //    ICE-CONTROLLED attribute header
    258  0x93, 0x2f, 0xf9, 0xb1,   // }  Pseudo-random tie breaker...
    259  0x51, 0x26, 0x3b, 0x36,   // }   ...for ICE control
    260  0x00, 0x06, 0x00, 0x09,   //    USERNAME attribute header
    261  0x65, 0x76, 0x74, 0x6a,   // }
    262  0x3a, 0x68, 0x36, 0x76,   // }  Username (9 bytes) and padding (3 bytes)
    263  0x59, 0x20, 0x20, 0x20,   // }
    264  0x00, 0x08, 0x00, 0x14,   //    MESSAGE-INTEGRITY attribute header
    265  0x9a, 0xea, 0xa7, 0x0c,   // }
    266  0xbf, 0xd8, 0xcb, 0x56,   // }
    267  0x78, 0x1e, 0xf2, 0xb5,   // }  HMAC-SHA1 fingerprint
    268  0xb2, 0xd3, 0xf2, 0x49,   // }
    269  0xc1, 0xb5, 0x71, 0xa2,   // }
    270  0x80, 0x28, 0x00, 0x04,   //    FINGERPRINT attribute header
    271  0xe5, 0x7a, 0x3b, 0xcf    //    CRC32 fingerprint
    272 };
    273 
    274 // 2.1.  Sample Request
    275 constexpr uint8_t kSampleRequestMI32[] = {
    276  0x00, 0x01, 0x00, 0x48,   //    Request type and message length
    277  0x21, 0x12, 0xa4, 0x42,   //    Magic cookie
    278  0xb7, 0xe7, 0xa7, 0x01,   // }
    279  0xbc, 0x34, 0xd6, 0x86,   // }  Transaction ID
    280  0xfa, 0x87, 0xdf, 0xae,   // }
    281  0x80, 0x22, 0x00, 0x10,   //    SOFTWARE attribute header
    282  0x53, 0x54, 0x55, 0x4e,   // }
    283  0x20, 0x74, 0x65, 0x73,   // }  User-agent...
    284  0x74, 0x20, 0x63, 0x6c,   // }  ...name
    285  0x69, 0x65, 0x6e, 0x74,   // }
    286  0x00, 0x24, 0x00, 0x04,   //    PRIORITY attribute header
    287  0x6e, 0x00, 0x01, 0xff,   //    ICE priority value
    288  0x80, 0x29, 0x00, 0x08,   //    ICE-CONTROLLED attribute header
    289  0x93, 0x2f, 0xf9, 0xb1,   // }  Pseudo-random tie breaker...
    290  0x51, 0x26, 0x3b, 0x36,   // }   ...for ICE control
    291  0x00, 0x06, 0x00, 0x09,   //    USERNAME attribute header
    292  0x65, 0x76, 0x74, 0x6a,   // }
    293  0x3a, 0x68, 0x36, 0x76,   // }  Username (9 bytes) and padding (3 bytes)
    294  0x59, 0x20, 0x20, 0x20,   // }
    295  0xC0, 0x60, 0x00, 0x04,   //    MESSAGE-INTEGRITY-32 attribute header
    296  0x45, 0x45, 0xce, 0x7c,   // }  HMAC-SHA1 fingerprint (first 32 bit)
    297  0x80, 0x28, 0x00, 0x04,   //    FINGERPRINT attribute header
    298  0xe5, 0x7a, 0x3b, 0xcf    //    CRC32 fingerprint
    299 };
    300 
    301 // 2.2.  Sample IPv4 Response
    302 constexpr uint8_t kRfc5769SampleResponse[] = {
    303  0x01, 0x01, 0x00, 0x3c,  //     Response type and message length
    304  0x21, 0x12, 0xa4, 0x42,  //     Magic cookie
    305  0xb7, 0xe7, 0xa7, 0x01,  // }
    306  0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
    307  0xfa, 0x87, 0xdf, 0xae,  // }
    308  0x80, 0x22, 0x00, 0x0b,  //    SOFTWARE attribute header
    309  0x74, 0x65, 0x73, 0x74,  // }
    310  0x20, 0x76, 0x65, 0x63,  // }  UTF-8 server name
    311  0x74, 0x6f, 0x72, 0x20,  // }
    312  0x00, 0x20, 0x00, 0x08,  //    XOR-MAPPED-ADDRESS attribute header
    313  0x00, 0x01, 0xa1, 0x47,  //    Address family (IPv4) and xor'd mapped port
    314  0xe1, 0x12, 0xa6, 0x43,  //    Xor'd mapped IPv4 address
    315  0x00, 0x08, 0x00, 0x14,  //    MESSAGE-INTEGRITY attribute header
    316  0x2b, 0x91, 0xf5, 0x99,  // }
    317  0xfd, 0x9e, 0x90, 0xc3,  // }
    318  0x8c, 0x74, 0x89, 0xf9,  // }  HMAC-SHA1 fingerprint
    319  0x2a, 0xf9, 0xba, 0x53,  // }
    320  0xf0, 0x6b, 0xe7, 0xd7,  // }
    321  0x80, 0x28, 0x00, 0x04,  //    FINGERPRINT attribute header
    322  0xc0, 0x7d, 0x4c, 0x96   //    CRC32 fingerprint
    323 };
    324 
    325 // 2.3.  Sample IPv6 Response
    326 constexpr uint8_t kRfc5769SampleResponseIPv6[] = {
    327  0x01, 0x01, 0x00, 0x48,  //    Response type and message length
    328  0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
    329  0xb7, 0xe7, 0xa7, 0x01,  // }
    330  0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
    331  0xfa, 0x87, 0xdf, 0xae,  // }
    332  0x80, 0x22, 0x00, 0x0b,  //    SOFTWARE attribute header
    333  0x74, 0x65, 0x73, 0x74,  // }
    334  0x20, 0x76, 0x65, 0x63,  // }  UTF-8 server name
    335  0x74, 0x6f, 0x72, 0x20,  // }
    336  0x00, 0x20, 0x00, 0x14,  //    XOR-MAPPED-ADDRESS attribute header
    337  0x00, 0x02, 0xa1, 0x47,  //    Address family (IPv6) and xor'd mapped port.
    338  0x01, 0x13, 0xa9, 0xfa,  // }
    339  0xa5, 0xd3, 0xf1, 0x79,  // }  Xor'd mapped IPv6 address
    340  0xbc, 0x25, 0xf4, 0xb5,  // }
    341  0xbe, 0xd2, 0xb9, 0xd9,  // }
    342  0x00, 0x08, 0x00, 0x14,  //    MESSAGE-INTEGRITY attribute header
    343  0xa3, 0x82, 0x95, 0x4e,  // }
    344  0x4b, 0xe6, 0x7b, 0xf1,  // }
    345  0x17, 0x84, 0xc9, 0x7c,  // }  HMAC-SHA1 fingerprint
    346  0x82, 0x92, 0xc2, 0x75,  // }
    347  0xbf, 0xe3, 0xed, 0x41,  // }
    348  0x80, 0x28, 0x00, 0x04,  //    FINGERPRINT attribute header
    349  0xc8, 0xfb, 0x0b, 0x4c   //    CRC32 fingerprint
    350 };
    351 
    352 // 2.4.  Sample Request with Long-Term Authentication
    353 constexpr uint8_t kRfc5769SampleRequestLongTermAuth[] = {
    354  0x00, 0x01, 0x00, 0x60,  //    Request type and message length
    355  0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
    356  0x78, 0xad, 0x34, 0x33,  // }
    357  0xc6, 0xad, 0x72, 0xc0,  // }  Transaction ID
    358  0x29, 0xda, 0x41, 0x2e,  // }
    359  0x00, 0x06, 0x00, 0x12,  //    USERNAME attribute header
    360  0xe3, 0x83, 0x9e, 0xe3,  // }
    361  0x83, 0x88, 0xe3, 0x83,  // }
    362  0xaa, 0xe3, 0x83, 0x83,  // }  Username value (18 bytes) and padding (2 bytes)
    363  0xe3, 0x82, 0xaf, 0xe3,  // }
    364  0x82, 0xb9, 0x00, 0x00,  // }
    365  0x00, 0x15, 0x00, 0x1c,  //    NONCE attribute header
    366  0x66, 0x2f, 0x2f, 0x34,  // }
    367  0x39, 0x39, 0x6b, 0x39,  // }
    368  0x35, 0x34, 0x64, 0x36,  // }
    369  0x4f, 0x4c, 0x33, 0x34,  // }  Nonce value
    370  0x6f, 0x4c, 0x39, 0x46,  // }
    371  0x53, 0x54, 0x76, 0x79,  // }
    372  0x36, 0x34, 0x73, 0x41,  // }
    373  0x00, 0x14, 0x00, 0x0b,  //    REALM attribute header
    374  0x65, 0x78, 0x61, 0x6d,  // }
    375  0x70, 0x6c, 0x65, 0x2e,  // }  Realm value (11 bytes) and padding (1 byte)
    376  0x6f, 0x72, 0x67, 0x00,  // }
    377  0x00, 0x08, 0x00, 0x14,  //    MESSAGE-INTEGRITY attribute header
    378  0xf6, 0x70, 0x24, 0x65,  // }
    379  0x6d, 0xd6, 0x4a, 0x3e,  // }
    380  0x02, 0xb8, 0xe0, 0x71,  // }  HMAC-SHA1 fingerprint
    381  0x2e, 0x85, 0xc9, 0xa2,  // }
    382  0x8c, 0xa8, 0x96, 0x66   // }
    383 };
    384 
    385 // Length parameter is changed to 0x38 from 0x58.
    386 // AddMessageIntegrity will add MI information and update the length param
    387 // accordingly.
    388 constexpr uint8_t kRfc5769SampleRequestWithoutMI[] = {
    389  0x00, 0x01, 0x00, 0x38,  //    Request type and message length
    390  0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
    391  0xb7, 0xe7, 0xa7, 0x01,  // }
    392  0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
    393  0xfa, 0x87, 0xdf, 0xae,  // }
    394  0x80, 0x22, 0x00, 0x10,  //    SOFTWARE attribute header
    395  0x53, 0x54, 0x55, 0x4e,  // }
    396  0x20, 0x74, 0x65, 0x73,  // }  User-agent...
    397  0x74, 0x20, 0x63, 0x6c,  // }  ...name
    398  0x69, 0x65, 0x6e, 0x74,  // }
    399  0x00, 0x24, 0x00, 0x04,  //    PRIORITY attribute header
    400  0x6e, 0x00, 0x01, 0xff,  //    ICE priority value
    401  0x80, 0x29, 0x00, 0x08,  //    ICE-CONTROLLED attribute header
    402  0x93, 0x2f, 0xf9, 0xb1,  // }  Pseudo-random tie breaker...
    403  0x51, 0x26, 0x3b, 0x36,  // }   ...for ICE control
    404  0x00, 0x06, 0x00, 0x09,  //    USERNAME attribute header
    405  0x65, 0x76, 0x74, 0x6a,  // }
    406  0x3a, 0x68, 0x36, 0x76,  // }  Username (9 bytes) and padding (3 bytes)
    407  0x59, 0x20, 0x20, 0x20   // }
    408 };
    409 
    410 // This HMAC differs from the RFC 5769 SampleRequest message. This differs
    411 // because spec uses 0x20 for the padding where as our implementation uses 0.
    412 constexpr uint8_t kCalculatedHmac1[] = {
    413  0x79, 0x07, 0xc2, 0xd2,  // }
    414  0xed, 0xbf, 0xea, 0x48,  // }
    415  0x0e, 0x4c, 0x76, 0xd8,  // }  HMAC-SHA1 fingerprint
    416  0x29, 0x62, 0xd5, 0xc3,  // }
    417  0x74, 0x2a, 0xf9, 0xe3   // }
    418 };
    419 
    420 // This truncated HMAC differs from kCalculatedHmac1
    421 // above since the sum is computed including header
    422 // and the header is different since the message is shorter
    423 // than when MESSAGE-INTEGRITY is used.
    424 constexpr uint8_t kCalculatedHmac1_32[] = {
    425  0xda, 0x39, 0xde, 0x5d,  // }
    426 };
    427 
    428 // Length parameter is changed to 0x1c from 0x3c.
    429 // AddMessageIntegrity will add MI information and update the length param
    430 // accordingly.
    431 constexpr uint8_t kRfc5769SampleResponseWithoutMI[] = {
    432  0x01, 0x01, 0x00, 0x1c,  //    Response type and message length
    433  0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
    434  0xb7, 0xe7, 0xa7, 0x01,  // }
    435  0xbc, 0x34, 0xd6, 0x86,  // }  Transaction ID
    436  0xfa, 0x87, 0xdf, 0xae,  // }
    437  0x80, 0x22, 0x00, 0x0b,  //    SOFTWARE attribute header
    438  0x74, 0x65, 0x73, 0x74,  // }
    439  0x20, 0x76, 0x65, 0x63,  // }  UTF-8 server name
    440  0x74, 0x6f, 0x72, 0x20,  // }
    441  0x00, 0x20, 0x00, 0x08,  //    XOR-MAPPED-ADDRESS attribute header
    442  0x00, 0x01, 0xa1, 0x47,  //    Address family (IPv4) and xor'd mapped port
    443  0xe1, 0x12, 0xa6, 0x43   //    Xor'd mapped IPv4 address
    444 };
    445 
    446 // This HMAC differs from the RFC 5769 SampleResponse message. This differs
    447 // because spec uses 0x20 for the padding where as our implementation uses 0.
    448 constexpr uint8_t kCalculatedHmac2[] = {
    449  0x5d, 0x6b, 0x58, 0xbe,  // }
    450  0xad, 0x94, 0xe0, 0x7e,  // }
    451  0xef, 0x0d, 0xfc, 0x12,  // }  HMAC-SHA1 fingerprint
    452  0x82, 0xa2, 0xbd, 0x08,  // }
    453  0x43, 0x14, 0x10, 0x28   // }
    454 };
    455 
    456 // This truncated HMAC differs from kCalculatedHmac2
    457 // above since the sum is computed including header
    458 // and the header is different since the message is shorter
    459 // than when MESSAGE-INTEGRITY is used.
    460 constexpr uint8_t kCalculatedHmac2_32[] = {
    461  0xe7, 0x5c, 0xd3, 0x16,  // }
    462 };
    463 
    464 // clang-format on
    465 
    466 // A transaction ID without the 'magic cookie' portion
    467 // pjnat's test programs use this transaction ID a lot.
    468 constexpr uint8_t kTestTransactionId1[] = {0x029, 0x01f, 0x0cd, 0x07c,
    469                                           0x0ba, 0x058, 0x0ab, 0x0d7,
    470                                           0x0f2, 0x041, 0x001, 0x000};
    471 
    472 // They use this one sometimes too.
    473 constexpr uint8_t kTestTransactionId2[] = {0x0e3, 0x0a9, 0x046, 0x0e1,
    474                                           0x07c, 0x000, 0x0c2, 0x062,
    475                                           0x054, 0x008, 0x001, 0x000};
    476 
    477 const in6_addr kIPv6TestAddress1 = {
    478    {{0x24, 0x01, 0xfa, 0x00, 0x00, 0x04, 0x10, 0x00, 0xbe, 0x30, 0x5b, 0xff,
    479      0xfe, 0xe5, 0x00, 0xc3}}};
    480 const in6_addr kIPv6TestAddress2 = {
    481    {{0x24, 0x01, 0xfa, 0x00, 0x00, 0x04, 0x10, 0x12, 0x06, 0x0c, 0xce, 0xff,
    482      0xfe, 0x1f, 0x61, 0xa4}}};
    483 
    484 #ifdef WEBRTC_POSIX
    485 const in_addr kIPv4TestAddress1 = {0xe64417ac};
    486 #elif defined WEBRTC_WIN
    487 // Windows in_addr has a union with a uchar[] array first.
    488 const in_addr kIPv4TestAddress1 = {{{0x0ac, 0x017, 0x044, 0x0e6}}};
    489 #endif
    490 constexpr char kTestUserName1[] = "abcdefgh";
    491 constexpr char kTestUserName2[] = "abc";
    492 constexpr char kTestErrorReason[] = "Unauthorized";
    493 constexpr int kTestErrorClass = 4;
    494 constexpr int kTestErrorNumber = 1;
    495 constexpr int kTestErrorCode = 401;
    496 
    497 constexpr int kTestMessagePort1 = 59977;
    498 constexpr int kTestMessagePort2 = 47233;
    499 constexpr int kTestMessagePort3 = 56743;
    500 constexpr int kTestMessagePort4 = 40444;
    501 }  // namespace
    502 
    503 class StunTest : public ::testing::Test {
    504 protected:
    505  void CheckStunHeader(const StunMessage& msg,
    506                       StunMessageType expected_type,
    507                       size_t expected_length) {
    508    ASSERT_EQ(expected_type, msg.type());
    509    ASSERT_EQ(expected_length, msg.length());
    510  }
    511 
    512  void CheckStunTransactionID(const StunMessage& msg,
    513                              const uint8_t* expectedID,
    514                              size_t length) {
    515    ASSERT_EQ(length, msg.transaction_id().size());
    516    ASSERT_EQ(length == kStunTransactionIdLength + 4, msg.IsLegacy());
    517    ASSERT_EQ(length == kStunTransactionIdLength, !msg.IsLegacy());
    518    ASSERT_EQ(0, memcmp(msg.transaction_id().c_str(), expectedID, length));
    519  }
    520 
    521  void CheckStunAddressAttribute(const StunAddressAttribute* addr,
    522                                 StunAddressFamily expected_family,
    523                                 int expected_port,
    524                                 const IPAddress& expected_address) {
    525    ASSERT_EQ(expected_family, addr->family());
    526    ASSERT_EQ(expected_port, addr->port());
    527 
    528    if (addr->family() == STUN_ADDRESS_IPV4) {
    529      in_addr v4_address = expected_address.ipv4_address();
    530      in_addr stun_address = addr->ipaddr().ipv4_address();
    531      ASSERT_EQ(0, memcmp(&v4_address, &stun_address, sizeof(stun_address)));
    532    } else if (addr->family() == STUN_ADDRESS_IPV6) {
    533      in6_addr v6_address = expected_address.ipv6_address();
    534      in6_addr stun_address = addr->ipaddr().ipv6_address();
    535      ASSERT_EQ(0, memcmp(&v6_address, &stun_address, sizeof(stun_address)));
    536    } else {
    537      ASSERT_TRUE(addr->family() == STUN_ADDRESS_IPV6 ||
    538                  addr->family() == STUN_ADDRESS_IPV4);
    539    }
    540  }
    541 
    542  size_t ReadStunMessageTestCase(StunMessage* msg,
    543                                 const uint8_t* testcase,
    544                                 size_t size) {
    545    ByteBufferReader buf(MakeArrayView(testcase, size));
    546    if (msg->Read(&buf)) {
    547      // Returns the size the stun message should report itself as being
    548      return (size - 20);
    549    } else {
    550      return 0;
    551    }
    552  }
    553 };
    554 
    555 #define ReadStunMessage(X, Y) ReadStunMessageTestCase(X, Y, sizeof(Y));
    556 
    557 // Test that the GetStun*Type and IsStun*Type methods work as expected.
    558 TEST_F(StunTest, MessageTypes) {
    559  EXPECT_EQ(STUN_BINDING_RESPONSE,
    560            GetStunSuccessResponseType(STUN_BINDING_REQUEST));
    561  EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE,
    562            GetStunErrorResponseType(STUN_BINDING_REQUEST));
    563  EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_INDICATION));
    564  EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_RESPONSE));
    565  EXPECT_EQ(-1, GetStunSuccessResponseType(STUN_BINDING_ERROR_RESPONSE));
    566  EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_INDICATION));
    567  EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_RESPONSE));
    568  EXPECT_EQ(-1, GetStunErrorResponseType(STUN_BINDING_ERROR_RESPONSE));
    569 
    570  int types[] = {STUN_BINDING_REQUEST, STUN_BINDING_INDICATION,
    571                 STUN_BINDING_RESPONSE, STUN_BINDING_ERROR_RESPONSE};
    572  for (size_t i = 0; i < std::size(types); ++i) {
    573    EXPECT_EQ(i == 0U, IsStunRequestType(types[i]));
    574    EXPECT_EQ(i == 1U, IsStunIndicationType(types[i]));
    575    EXPECT_EQ(i == 2U, IsStunSuccessResponseType(types[i]));
    576    EXPECT_EQ(i == 3U, IsStunErrorResponseType(types[i]));
    577    EXPECT_EQ(1, types[i] & 0xFEEF);
    578  }
    579 }
    580 
    581 TEST_F(StunTest, ReadMessageWithIPv4AddressAttribute) {
    582  StunMessage msg;
    583  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4MappedAddress);
    584  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
    585  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
    586 
    587  const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
    588  IPAddress test_address(kIPv4TestAddress1);
    589  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4, kTestMessagePort4,
    590                            test_address);
    591 }
    592 
    593 TEST_F(StunTest, ReadMessageWithIPv4XorAddressAttribute) {
    594  StunMessage msg;
    595  StunMessage msg2;
    596  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4XorMappedAddress);
    597  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
    598  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
    599 
    600  const StunAddressAttribute* addr =
    601      msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
    602  IPAddress test_address(kIPv4TestAddress1);
    603  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4, kTestMessagePort3,
    604                            test_address);
    605 }
    606 
    607 TEST_F(StunTest, ReadMessageWithIPv6AddressAttribute) {
    608  StunMessage msg;
    609  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress);
    610  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
    611  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
    612 
    613  IPAddress test_address(kIPv6TestAddress1);
    614 
    615  const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
    616  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6, kTestMessagePort2,
    617                            test_address);
    618 }
    619 
    620 TEST_F(StunTest, ReadMessageWithInvalidAddressAttribute) {
    621  StunMessage msg;
    622  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress);
    623  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
    624  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
    625 
    626  IPAddress test_address(kIPv6TestAddress1);
    627 
    628  const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
    629  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6, kTestMessagePort2,
    630                            test_address);
    631 }
    632 
    633 TEST_F(StunTest, ReadMessageWithIPv6XorAddressAttribute) {
    634  StunMessage msg;
    635  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6XorMappedAddress);
    636 
    637  IPAddress test_address(kIPv6TestAddress1);
    638 
    639  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
    640  CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
    641 
    642  const StunAddressAttribute* addr =
    643      msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
    644  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6, kTestMessagePort1,
    645                            test_address);
    646 }
    647 
    648 // Read the RFC5389 fields from the RFC5769 sample STUN request.
    649 TEST_F(StunTest, ReadRfc5769RequestMessage) {
    650  StunMessage msg;
    651  size_t size = ReadStunMessage(&msg, kRfc5769SampleRequest);
    652  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
    653  CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId,
    654                         kStunTransactionIdLength);
    655 
    656  const StunByteStringAttribute* software =
    657      msg.GetByteString(STUN_ATTR_SOFTWARE);
    658  ASSERT_TRUE(software != nullptr);
    659  EXPECT_EQ(kRfc5769SampleMsgClientSoftware, software->string_view());
    660 
    661  const StunByteStringAttribute* username =
    662      msg.GetByteString(STUN_ATTR_USERNAME);
    663  ASSERT_TRUE(username != nullptr);
    664  EXPECT_EQ(kRfc5769SampleMsgUsername, username->string_view());
    665 
    666  // Actual M-I value checked in a later test.
    667  ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != nullptr);
    668 
    669  // Fingerprint checked in a later test, but double-check the value here.
    670  const StunUInt32Attribute* fingerprint = msg.GetUInt32(STUN_ATTR_FINGERPRINT);
    671  ASSERT_TRUE(fingerprint != nullptr);
    672  EXPECT_EQ(0xe57a3bcf, fingerprint->value());
    673 }
    674 
    675 // Read the RFC5389 fields from the RFC5769 sample STUN response.
    676 TEST_F(StunTest, ReadRfc5769ResponseMessage) {
    677  StunMessage msg;
    678  size_t size = ReadStunMessage(&msg, kRfc5769SampleResponse);
    679  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
    680  CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId,
    681                         kStunTransactionIdLength);
    682 
    683  const StunByteStringAttribute* software =
    684      msg.GetByteString(STUN_ATTR_SOFTWARE);
    685  ASSERT_TRUE(software != nullptr);
    686  EXPECT_EQ(kRfc5769SampleMsgServerSoftware, software->string_view());
    687 
    688  const StunAddressAttribute* mapped_address =
    689      msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
    690  ASSERT_TRUE(mapped_address != nullptr);
    691  EXPECT_EQ(kRfc5769SampleMsgMappedAddress, mapped_address->GetAddress());
    692 
    693  // Actual M-I and fingerprint checked in later tests.
    694  ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != nullptr);
    695  ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) != nullptr);
    696 }
    697 
    698 // Read the RFC5389 fields from the RFC5769 sample STUN response for IPv6.
    699 TEST_F(StunTest, ReadRfc5769ResponseMessageIPv6) {
    700  StunMessage msg;
    701  size_t size = ReadStunMessage(&msg, kRfc5769SampleResponseIPv6);
    702  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
    703  CheckStunTransactionID(msg, kRfc5769SampleMsgTransactionId,
    704                         kStunTransactionIdLength);
    705 
    706  const StunByteStringAttribute* software =
    707      msg.GetByteString(STUN_ATTR_SOFTWARE);
    708  ASSERT_TRUE(software != nullptr);
    709  EXPECT_EQ(kRfc5769SampleMsgServerSoftware, software->string_view());
    710 
    711  const StunAddressAttribute* mapped_address =
    712      msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
    713  ASSERT_TRUE(mapped_address != nullptr);
    714  EXPECT_EQ(kRfc5769SampleMsgIPv6MappedAddress, mapped_address->GetAddress());
    715 
    716  // Actual M-I and fingerprint checked in later tests.
    717  ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != nullptr);
    718  ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) != nullptr);
    719 }
    720 
    721 // Read the RFC5389 fields from the RFC5769 sample STUN response with auth.
    722 TEST_F(StunTest, ReadRfc5769RequestMessageLongTermAuth) {
    723  StunMessage msg;
    724  size_t size = ReadStunMessage(&msg, kRfc5769SampleRequestLongTermAuth);
    725  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
    726  CheckStunTransactionID(msg, kRfc5769SampleMsgWithAuthTransactionId,
    727                         kStunTransactionIdLength);
    728 
    729  const StunByteStringAttribute* username =
    730      msg.GetByteString(STUN_ATTR_USERNAME);
    731  ASSERT_TRUE(username != nullptr);
    732  EXPECT_EQ(kRfc5769SampleMsgWithAuthUsername, username->string_view());
    733 
    734  const StunByteStringAttribute* nonce = msg.GetByteString(STUN_ATTR_NONCE);
    735  ASSERT_TRUE(nonce != nullptr);
    736  EXPECT_EQ(kRfc5769SampleMsgWithAuthNonce, nonce->string_view());
    737 
    738  const StunByteStringAttribute* realm = msg.GetByteString(STUN_ATTR_REALM);
    739  ASSERT_TRUE(realm != nullptr);
    740  EXPECT_EQ(kRfc5769SampleMsgWithAuthRealm, realm->string_view());
    741 
    742  // No fingerprint, actual M-I checked in later tests.
    743  ASSERT_TRUE(msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != nullptr);
    744  ASSERT_TRUE(msg.GetUInt32(STUN_ATTR_FINGERPRINT) == nullptr);
    745 }
    746 
    747 // The RFC3489 packet in this test is the same as
    748 // kStunMessageWithIPv4MappedAddress, but with a different value where the
    749 // magic cookie was.
    750 TEST_F(StunTest, ReadLegacyMessage) {
    751  uint8_t rfc3489_packet[sizeof(kStunMessageWithIPv4MappedAddress)];
    752  memcpy(rfc3489_packet, kStunMessageWithIPv4MappedAddress,
    753         sizeof(kStunMessageWithIPv4MappedAddress));
    754  // Overwrite the magic cookie here.
    755  memcpy(&rfc3489_packet[4], "ABCD", 4);
    756 
    757  StunMessage msg;
    758  size_t size = ReadStunMessage(&msg, rfc3489_packet);
    759  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
    760  CheckStunTransactionID(msg, &rfc3489_packet[4], kStunTransactionIdLength + 4);
    761 
    762  const StunAddressAttribute* addr = msg.GetAddress(STUN_ATTR_MAPPED_ADDRESS);
    763  IPAddress test_address(kIPv4TestAddress1);
    764  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4, kTestMessagePort4,
    765                            test_address);
    766 }
    767 
    768 TEST_F(StunTest, SetIPv6XorAddressAttributeOwner) {
    769  StunMessage msg;
    770  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv6XorMappedAddress);
    771 
    772  IPAddress test_address(kIPv6TestAddress1);
    773 
    774  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
    775  CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
    776 
    777  const StunAddressAttribute* addr =
    778      msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
    779  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV6, kTestMessagePort1,
    780                            test_address);
    781 
    782  // Owner with a different transaction ID.
    783  StunMessage msg2(STUN_INVALID_MESSAGE_TYPE, "ABCDABCDABCD");
    784  StunXorAddressAttribute addr2(STUN_ATTR_XOR_MAPPED_ADDRESS, 20, nullptr);
    785  addr2.SetIP(addr->ipaddr());
    786  addr2.SetPort(addr->port());
    787  addr2.SetOwner(&msg2);
    788  // The internal IP address shouldn't change.
    789  ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
    790 
    791  ByteBufferWriter correct_buf;
    792  ByteBufferWriter wrong_buf;
    793  EXPECT_TRUE(addr->Write(&correct_buf));
    794  EXPECT_TRUE(addr2.Write(&wrong_buf));
    795  // But when written out, the buffers should look different.
    796  ASSERT_NE(0,
    797            memcmp(correct_buf.Data(), wrong_buf.Data(), wrong_buf.Length()));
    798  // And when reading a known good value, the address should be wrong.
    799  ByteBufferReader read_buf(correct_buf);
    800  addr2.Read(&read_buf);
    801  ASSERT_NE(addr->ipaddr(), addr2.ipaddr());
    802  addr2.SetIP(addr->ipaddr());
    803  addr2.SetPort(addr->port());
    804  // Try writing with no owner at all, should fail and write nothing.
    805  addr2.SetOwner(nullptr);
    806  ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
    807  wrong_buf.Clear();
    808  EXPECT_FALSE(addr2.Write(&wrong_buf));
    809  ASSERT_EQ(0U, wrong_buf.Length());
    810 }
    811 
    812 TEST_F(StunTest, SetIPv4XorAddressAttributeOwner) {
    813  // Unlike the IPv6XorAddressAttributeOwner test, IPv4 XOR address attributes
    814  // should _not_ be affected by a change in owner. IPv4 XOR address uses the
    815  // magic cookie value which is fixed.
    816  StunMessage msg;
    817  size_t size = ReadStunMessage(&msg, kStunMessageWithIPv4XorMappedAddress);
    818 
    819  IPAddress test_address(kIPv4TestAddress1);
    820 
    821  CheckStunHeader(msg, STUN_BINDING_RESPONSE, size);
    822  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
    823 
    824  const StunAddressAttribute* addr =
    825      msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
    826  CheckStunAddressAttribute(addr, STUN_ADDRESS_IPV4, kTestMessagePort3,
    827                            test_address);
    828 
    829  // Owner with a different transaction ID.
    830  StunMessage msg2(STUN_INVALID_MESSAGE_TYPE, "ABCDABCDABCD");
    831  StunXorAddressAttribute addr2(STUN_ATTR_XOR_MAPPED_ADDRESS, 20, nullptr);
    832  addr2.SetIP(addr->ipaddr());
    833  addr2.SetPort(addr->port());
    834  addr2.SetOwner(&msg2);
    835  // The internal IP address shouldn't change.
    836  ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
    837 
    838  ByteBufferWriter correct_buf;
    839  ByteBufferWriter wrong_buf;
    840  EXPECT_TRUE(addr->Write(&correct_buf));
    841  EXPECT_TRUE(addr2.Write(&wrong_buf));
    842  // The same address data should be written.
    843  ASSERT_EQ(0,
    844            memcmp(correct_buf.Data(), wrong_buf.Data(), wrong_buf.Length()));
    845  // And an attribute should be able to un-XOR an address belonging to a message
    846  // with a different transaction ID.
    847  ByteBufferReader read_buf(correct_buf);
    848  EXPECT_TRUE(addr2.Read(&read_buf));
    849  ASSERT_EQ(addr->ipaddr(), addr2.ipaddr());
    850 
    851  // However, no owner is still an error, should fail and write nothing.
    852  addr2.SetOwner(nullptr);
    853  ASSERT_EQ(addr2.ipaddr(), addr->ipaddr());
    854  wrong_buf.Clear();
    855  EXPECT_FALSE(addr2.Write(&wrong_buf));
    856 }
    857 
    858 TEST_F(StunTest, CreateIPv6AddressAttribute) {
    859  IPAddress test_ip(kIPv6TestAddress2);
    860 
    861  auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
    862  SocketAddress test_addr(test_ip, kTestMessagePort2);
    863  addr->SetAddress(test_addr);
    864 
    865  CheckStunAddressAttribute(addr.get(), STUN_ADDRESS_IPV6, kTestMessagePort2,
    866                            test_ip);
    867 }
    868 
    869 TEST_F(StunTest, CreateIPv4AddressAttribute) {
    870  struct in_addr test_in_addr;
    871  test_in_addr.s_addr = 0xBEB0B0BE;
    872  IPAddress test_ip(test_in_addr);
    873 
    874  auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
    875  SocketAddress test_addr(test_ip, kTestMessagePort2);
    876  addr->SetAddress(test_addr);
    877 
    878  CheckStunAddressAttribute(addr.get(), STUN_ADDRESS_IPV4, kTestMessagePort2,
    879                            test_ip);
    880 }
    881 
    882 // Test that we don't care what order we set the parts of an address
    883 TEST_F(StunTest, CreateAddressInArbitraryOrder) {
    884  auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
    885  // Port first
    886  addr->SetPort(kTestMessagePort1);
    887  addr->SetIP(IPAddress(kIPv4TestAddress1));
    888  ASSERT_EQ(kTestMessagePort1, addr->port());
    889  ASSERT_EQ(IPAddress(kIPv4TestAddress1), addr->ipaddr());
    890 
    891  auto addr2 = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
    892  // IP first
    893  addr2->SetIP(IPAddress(kIPv4TestAddress1));
    894  addr2->SetPort(kTestMessagePort2);
    895  ASSERT_EQ(kTestMessagePort2, addr2->port());
    896  ASSERT_EQ(IPAddress(kIPv4TestAddress1), addr2->ipaddr());
    897 }
    898 
    899 TEST_F(StunTest, WriteMessageWithIPv6AddressAttribute) {
    900  size_t size = sizeof(kStunMessageWithIPv6MappedAddress);
    901 
    902  IPAddress test_ip(kIPv6TestAddress1);
    903 
    904  StunMessage msg(
    905      STUN_BINDING_REQUEST,
    906      std::string(reinterpret_cast<const char*>(kTestTransactionId1),
    907                  kStunTransactionIdLength));
    908  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
    909 
    910  auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
    911  SocketAddress test_addr(test_ip, kTestMessagePort2);
    912  addr->SetAddress(test_addr);
    913  msg.AddAttribute(std::move(addr));
    914 
    915  CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));
    916 
    917  ByteBufferWriter out;
    918  EXPECT_TRUE(msg.Write(&out));
    919  ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6MappedAddress));
    920  int len1 = static_cast<int>(out.Length());
    921  ByteBufferReader read_buf(out);
    922  std::string bytes;
    923  read_buf.ReadString(&bytes, len1);
    924  ASSERT_EQ(0, memcmp(bytes.c_str(), kStunMessageWithIPv6MappedAddress, len1));
    925 }
    926 
    927 TEST_F(StunTest, WriteMessageWithIPv4AddressAttribute) {
    928  size_t size = sizeof(kStunMessageWithIPv4MappedAddress);
    929 
    930  IPAddress test_ip(kIPv4TestAddress1);
    931 
    932  StunMessage msg(
    933      STUN_BINDING_RESPONSE,
    934      std::string(reinterpret_cast<const char*>(kTestTransactionId1),
    935                  kStunTransactionIdLength));
    936  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
    937 
    938  auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
    939  SocketAddress test_addr(test_ip, kTestMessagePort4);
    940  addr->SetAddress(test_addr);
    941  msg.AddAttribute(std::move(addr));
    942 
    943  CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
    944 
    945  ByteBufferWriter out;
    946  EXPECT_TRUE(msg.Write(&out));
    947  ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4MappedAddress));
    948  int len1 = static_cast<int>(out.Length());
    949  ByteBufferReader read_buf(out);
    950  std::string bytes;
    951  read_buf.ReadString(&bytes, len1);
    952  ASSERT_EQ(0, memcmp(bytes.c_str(), kStunMessageWithIPv4MappedAddress, len1));
    953 }
    954 
    955 TEST_F(StunTest, WriteMessageWithIPv6XorAddressAttribute) {
    956  size_t size = sizeof(kStunMessageWithIPv6XorMappedAddress);
    957 
    958  IPAddress test_ip(kIPv6TestAddress1);
    959 
    960  StunMessage msg(
    961      STUN_BINDING_RESPONSE,
    962      std::string(reinterpret_cast<const char*>(kTestTransactionId2),
    963                  kStunTransactionIdLength));
    964  CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
    965 
    966  auto addr = StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
    967  SocketAddress test_addr(test_ip, kTestMessagePort1);
    968  addr->SetAddress(test_addr);
    969  msg.AddAttribute(std::move(addr));
    970 
    971  CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
    972 
    973  ByteBufferWriter out;
    974  EXPECT_TRUE(msg.Write(&out));
    975  ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv6XorMappedAddress));
    976  int len1 = static_cast<int>(out.Length());
    977  ByteBufferReader read_buf(out);
    978  std::string bytes;
    979  read_buf.ReadString(&bytes, len1);
    980  ASSERT_EQ(0,
    981            memcmp(bytes.c_str(), kStunMessageWithIPv6XorMappedAddress, len1));
    982 }
    983 
    984 TEST_F(StunTest, WriteMessageWithIPv4XoreAddressAttribute) {
    985  size_t size = sizeof(kStunMessageWithIPv4XorMappedAddress);
    986 
    987  IPAddress test_ip(kIPv4TestAddress1);
    988 
    989  StunMessage msg(
    990      STUN_BINDING_RESPONSE,
    991      std::string(reinterpret_cast<const char*>(kTestTransactionId1),
    992                  kStunTransactionIdLength));
    993  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
    994 
    995  auto addr = StunAttribute::CreateXorAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
    996  SocketAddress test_addr(test_ip, kTestMessagePort3);
    997  addr->SetAddress(test_addr);
    998  msg.AddAttribute(std::move(addr));
    999 
   1000  CheckStunHeader(msg, STUN_BINDING_RESPONSE, (size - 20));
   1001 
   1002  ByteBufferWriter out;
   1003  EXPECT_TRUE(msg.Write(&out));
   1004  ASSERT_EQ(out.Length(), sizeof(kStunMessageWithIPv4XorMappedAddress));
   1005  int len1 = static_cast<int>(out.Length());
   1006  ByteBufferReader read_buf(out);
   1007  std::string bytes;
   1008  read_buf.ReadString(&bytes, len1);
   1009  ASSERT_EQ(0,
   1010            memcmp(bytes.c_str(), kStunMessageWithIPv4XorMappedAddress, len1));
   1011 }
   1012 
   1013 TEST_F(StunTest, ReadByteStringAttribute) {
   1014  StunMessage msg;
   1015  size_t size = ReadStunMessage(&msg, kStunMessageWithByteStringAttribute);
   1016 
   1017  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
   1018  CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
   1019  const StunByteStringAttribute* username =
   1020      msg.GetByteString(STUN_ATTR_USERNAME);
   1021  ASSERT_TRUE(username != nullptr);
   1022  EXPECT_EQ(kTestUserName1, username->string_view());
   1023 }
   1024 
   1025 TEST_F(StunTest, ReadPaddedByteStringAttribute) {
   1026  StunMessage msg;
   1027  size_t size =
   1028      ReadStunMessage(&msg, kStunMessageWithPaddedByteStringAttribute);
   1029  ASSERT_NE(0U, size);
   1030  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
   1031  CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
   1032  const StunByteStringAttribute* username =
   1033      msg.GetByteString(STUN_ATTR_USERNAME);
   1034  ASSERT_TRUE(username != nullptr);
   1035  EXPECT_EQ(kTestUserName2, username->string_view());
   1036 }
   1037 
   1038 TEST_F(StunTest, ReadErrorCodeAttribute) {
   1039  StunMessage msg;
   1040  size_t size = ReadStunMessage(&msg, kStunMessageWithErrorAttribute);
   1041 
   1042  CheckStunHeader(msg, STUN_BINDING_ERROR_RESPONSE, size);
   1043  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
   1044  const StunErrorCodeAttribute* errorcode = msg.GetErrorCode();
   1045  ASSERT_TRUE(errorcode != nullptr);
   1046  EXPECT_EQ(kTestErrorClass, errorcode->eclass());
   1047  EXPECT_EQ(kTestErrorNumber, errorcode->number());
   1048  EXPECT_EQ(kTestErrorReason, errorcode->reason());
   1049  EXPECT_EQ(kTestErrorCode, errorcode->code());
   1050  EXPECT_EQ(kTestErrorCode, msg.GetErrorCodeValue());
   1051 }
   1052 
   1053 // Test that GetErrorCodeValue returns STUN_ERROR_GLOBAL_FAILURE if the message
   1054 // in question doesn't have an error code attribute, rather than crashing.
   1055 TEST_F(StunTest, GetErrorCodeValueWithNoErrorAttribute) {
   1056  StunMessage msg;
   1057  ReadStunMessage(&msg, kStunMessageWithIPv6MappedAddress);
   1058  EXPECT_EQ(STUN_ERROR_GLOBAL_FAILURE, msg.GetErrorCodeValue());
   1059 }
   1060 
   1061 TEST_F(StunTest, ReadMessageWithAUInt16ListAttribute) {
   1062  StunMessage msg;
   1063  size_t size = ReadStunMessage(&msg, kStunMessageWithUInt16ListAttribute);
   1064  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
   1065  const StunUInt16ListAttribute* types = msg.GetUnknownAttributes();
   1066  ASSERT_TRUE(types != nullptr);
   1067  EXPECT_EQ(3U, types->Size());
   1068  EXPECT_EQ(0x1U, types->GetType(0));
   1069  EXPECT_EQ(0x1000U, types->GetType(1));
   1070  EXPECT_EQ(0xAB0CU, types->GetType(2));
   1071 }
   1072 
   1073 TEST_F(StunTest, ReadMessageWithAnUnknownAttribute) {
   1074  StunMessage msg;
   1075  size_t size = ReadStunMessage(&msg, kStunMessageWithUnknownAttribute);
   1076  CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
   1077 
   1078  // Parsing should have succeeded and there should be a USERNAME attribute
   1079  const StunByteStringAttribute* username =
   1080      msg.GetByteString(STUN_ATTR_USERNAME);
   1081  ASSERT_TRUE(username != nullptr);
   1082  EXPECT_EQ(kTestUserName2, username->string_view());
   1083 }
   1084 
   1085 TEST_F(StunTest, WriteMessageWithAnErrorCodeAttribute) {
   1086  size_t size = sizeof(kStunMessageWithErrorAttribute);
   1087 
   1088  StunMessage msg(
   1089      STUN_BINDING_ERROR_RESPONSE,
   1090      std::string(reinterpret_cast<const char*>(kTestTransactionId1),
   1091                  kStunTransactionIdLength));
   1092  CheckStunTransactionID(msg, kTestTransactionId1, kStunTransactionIdLength);
   1093  auto errorcode = StunAttribute::CreateErrorCode();
   1094  errorcode->SetCode(kTestErrorCode);
   1095  errorcode->SetReason(kTestErrorReason);
   1096  msg.AddAttribute(std::move(errorcode));
   1097  CheckStunHeader(msg, STUN_BINDING_ERROR_RESPONSE, (size - 20));
   1098 
   1099  ByteBufferWriter out;
   1100  EXPECT_TRUE(msg.Write(&out));
   1101  ASSERT_EQ(size, out.Length());
   1102  // No padding.
   1103  ASSERT_EQ(0, memcmp(out.Data(), kStunMessageWithErrorAttribute, size));
   1104 }
   1105 
   1106 TEST_F(StunTest, WriteMessageWithAUInt16ListAttribute) {
   1107  size_t size = sizeof(kStunMessageWithUInt16ListAttribute);
   1108 
   1109  StunMessage msg(
   1110      STUN_BINDING_REQUEST,
   1111      std::string(reinterpret_cast<const char*>(kTestTransactionId2),
   1112                  kStunTransactionIdLength));
   1113  CheckStunTransactionID(msg, kTestTransactionId2, kStunTransactionIdLength);
   1114  auto list = StunAttribute::CreateUnknownAttributes();
   1115  list->AddType(0x1U);
   1116  list->AddType(0x1000U);
   1117  list->AddType(0xAB0CU);
   1118  msg.AddAttribute(std::move(list));
   1119  CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));
   1120 
   1121  ByteBufferWriter out;
   1122  EXPECT_TRUE(msg.Write(&out));
   1123  ASSERT_EQ(size, out.Length());
   1124  // Check everything up to the padding.
   1125  ASSERT_EQ(0,
   1126            memcmp(out.Data(), kStunMessageWithUInt16ListAttribute, size - 2));
   1127 }
   1128 
   1129 // Test that we fail to read messages with invalid lengths.
   1130 void CheckFailureToRead(const uint8_t* testcase, size_t length) {
   1131  StunMessage msg;
   1132  ByteBufferReader buf(MakeArrayView(testcase, length));
   1133  ASSERT_FALSE(msg.Read(&buf));
   1134 }
   1135 
   1136 TEST_F(StunTest, FailToReadInvalidMessages) {
   1137  CheckFailureToRead(kStunMessageWithZeroLength,
   1138                     kRealLengthOfInvalidLengthTestCases);
   1139  CheckFailureToRead(kStunMessageWithSmallLength,
   1140                     kRealLengthOfInvalidLengthTestCases);
   1141  CheckFailureToRead(kStunMessageWithExcessLength,
   1142                     kRealLengthOfInvalidLengthTestCases);
   1143 }
   1144 
   1145 // Test that we properly fail to read a non-STUN message.
   1146 TEST_F(StunTest, FailToReadRtcpPacket) {
   1147  CheckFailureToRead(kRtcpPacket, sizeof(kRtcpPacket));
   1148 }
   1149 
   1150 // Check our STUN message validation code against the RFC5769 test messages.
   1151 TEST_F(StunTest, ValidateMessageIntegrity) {
   1152  // Try the messages from RFC 5769.
   1153  EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
   1154      reinterpret_cast<const char*>(kRfc5769SampleRequest),
   1155      sizeof(kRfc5769SampleRequest), kRfc5769SampleMsgPassword));
   1156  EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
   1157      reinterpret_cast<const char*>(kRfc5769SampleRequest),
   1158      sizeof(kRfc5769SampleRequest), "InvalidPassword"));
   1159 
   1160  EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
   1161      reinterpret_cast<const char*>(kRfc5769SampleResponse),
   1162      sizeof(kRfc5769SampleResponse), kRfc5769SampleMsgPassword));
   1163  EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
   1164      reinterpret_cast<const char*>(kRfc5769SampleResponse),
   1165      sizeof(kRfc5769SampleResponse), "InvalidPassword"));
   1166 
   1167  EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
   1168      reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6),
   1169      sizeof(kRfc5769SampleResponseIPv6), kRfc5769SampleMsgPassword));
   1170  EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
   1171      reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6),
   1172      sizeof(kRfc5769SampleResponseIPv6), "InvalidPassword"));
   1173 
   1174  // We first need to compute the key for the long-term authentication HMAC.
   1175  std::string key;
   1176  ComputeStunCredentialHash(kRfc5769SampleMsgWithAuthUsername,
   1177                            kRfc5769SampleMsgWithAuthRealm,
   1178                            kRfc5769SampleMsgWithAuthPassword, &key);
   1179  EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
   1180      reinterpret_cast<const char*>(kRfc5769SampleRequestLongTermAuth),
   1181      sizeof(kRfc5769SampleRequestLongTermAuth), key));
   1182  EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
   1183      reinterpret_cast<const char*>(kRfc5769SampleRequestLongTermAuth),
   1184      sizeof(kRfc5769SampleRequestLongTermAuth), "InvalidPassword"));
   1185 
   1186  // Try some edge cases.
   1187  EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
   1188      reinterpret_cast<const char*>(kStunMessageWithZeroLength),
   1189      sizeof(kStunMessageWithZeroLength), kRfc5769SampleMsgPassword));
   1190  EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
   1191      reinterpret_cast<const char*>(kStunMessageWithExcessLength),
   1192      sizeof(kStunMessageWithExcessLength), kRfc5769SampleMsgPassword));
   1193  EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
   1194      reinterpret_cast<const char*>(kStunMessageWithSmallLength),
   1195      sizeof(kStunMessageWithSmallLength), kRfc5769SampleMsgPassword));
   1196 
   1197  // Again, but with the lengths matching what is claimed in the headers.
   1198  EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
   1199      reinterpret_cast<const char*>(kStunMessageWithZeroLength),
   1200      kStunHeaderSize + GetBE16(&kStunMessageWithZeroLength[2]),
   1201      kRfc5769SampleMsgPassword));
   1202  EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
   1203      reinterpret_cast<const char*>(kStunMessageWithExcessLength),
   1204      kStunHeaderSize + GetBE16(&kStunMessageWithExcessLength[2]),
   1205      kRfc5769SampleMsgPassword));
   1206  EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
   1207      reinterpret_cast<const char*>(kStunMessageWithSmallLength),
   1208      kStunHeaderSize + GetBE16(&kStunMessageWithSmallLength[2]),
   1209      kRfc5769SampleMsgPassword));
   1210 
   1211  // Check that a too-short HMAC doesn't cause buffer overflow.
   1212  EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
   1213      reinterpret_cast<const char*>(kStunMessageWithBadHmacAtEnd),
   1214      sizeof(kStunMessageWithBadHmacAtEnd), kRfc5769SampleMsgPassword));
   1215 
   1216  // Test that munging a single bit anywhere in the message causes the
   1217  // message-integrity check to fail, unless it is after the M-I attribute.
   1218  char buf[sizeof(kRfc5769SampleRequest)];
   1219  memcpy(buf, kRfc5769SampleRequest, sizeof(kRfc5769SampleRequest));
   1220  for (size_t i = 0; i < sizeof(buf); ++i) {
   1221    buf[i] ^= 0x01;
   1222    if (i > 0)
   1223      buf[i - 1] ^= 0x01;
   1224    EXPECT_EQ(i >= sizeof(buf) - 8,
   1225              StunMessage::ValidateMessageIntegrityForTesting(
   1226                  buf, sizeof(buf), kRfc5769SampleMsgPassword));
   1227  }
   1228 }
   1229 
   1230 // Validate that we generate correct MESSAGE-INTEGRITY attributes.
   1231 // Note the use of IceMessage instead of StunMessage; this is necessary because
   1232 // the RFC5769 test messages used include attributes not found in basic STUN.
   1233 TEST_F(StunTest, AddMessageIntegrity) {
   1234  IceMessage msg;
   1235  ByteBufferReader buf(kRfc5769SampleRequestWithoutMI);
   1236  EXPECT_TRUE(msg.Read(&buf));
   1237  EXPECT_TRUE(msg.AddMessageIntegrity(kRfc5769SampleMsgPassword));
   1238  const StunByteStringAttribute* mi_attr =
   1239      msg.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
   1240  EXPECT_EQ(20U, mi_attr->length());
   1241  EXPECT_EQ(0, memcmp(mi_attr->array_view().data(), kCalculatedHmac1,
   1242                      sizeof(kCalculatedHmac1)));
   1243 
   1244  ByteBufferWriter buf1;
   1245  EXPECT_TRUE(msg.Write(&buf1));
   1246  EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
   1247      reinterpret_cast<const char*>(buf1.Data()), buf1.Length(),
   1248      kRfc5769SampleMsgPassword));
   1249 
   1250  IceMessage msg2;
   1251  ByteBufferReader buf2(kRfc5769SampleResponseWithoutMI);
   1252  EXPECT_TRUE(msg2.Read(&buf2));
   1253  EXPECT_TRUE(msg2.AddMessageIntegrity(kRfc5769SampleMsgPassword));
   1254  const StunByteStringAttribute* mi_attr2 =
   1255      msg2.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
   1256  EXPECT_EQ(20U, mi_attr2->length());
   1257  EXPECT_EQ(0, memcmp(mi_attr2->array_view().data(), kCalculatedHmac2,
   1258                      sizeof(kCalculatedHmac2)));
   1259 
   1260  ByteBufferWriter buf3;
   1261  EXPECT_TRUE(msg2.Write(&buf3));
   1262  EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
   1263      reinterpret_cast<const char*>(buf3.Data()), buf3.Length(),
   1264      kRfc5769SampleMsgPassword));
   1265 }
   1266 
   1267 // Check our STUN message validation code against the RFC5769 test messages.
   1268 TEST_F(StunTest, ValidateMessageIntegrity32) {
   1269  // Try the messages from RFC 5769.
   1270  EXPECT_TRUE(StunMessage::ValidateMessageIntegrity32ForTesting(
   1271      reinterpret_cast<const char*>(kSampleRequestMI32),
   1272      sizeof(kSampleRequestMI32), kRfc5769SampleMsgPassword));
   1273  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
   1274      reinterpret_cast<const char*>(kSampleRequestMI32),
   1275      sizeof(kSampleRequestMI32), "InvalidPassword"));
   1276 
   1277  // Try some edge cases.
   1278  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
   1279      reinterpret_cast<const char*>(kStunMessageWithZeroLength),
   1280      sizeof(kStunMessageWithZeroLength), kRfc5769SampleMsgPassword));
   1281  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
   1282      reinterpret_cast<const char*>(kStunMessageWithExcessLength),
   1283      sizeof(kStunMessageWithExcessLength), kRfc5769SampleMsgPassword));
   1284  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
   1285      reinterpret_cast<const char*>(kStunMessageWithSmallLength),
   1286      sizeof(kStunMessageWithSmallLength), kRfc5769SampleMsgPassword));
   1287 
   1288  // Again, but with the lengths matching what is claimed in the headers.
   1289  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
   1290      reinterpret_cast<const char*>(kStunMessageWithZeroLength),
   1291      kStunHeaderSize + GetBE16(&kStunMessageWithZeroLength[2]),
   1292      kRfc5769SampleMsgPassword));
   1293  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
   1294      reinterpret_cast<const char*>(kStunMessageWithExcessLength),
   1295      kStunHeaderSize + GetBE16(&kStunMessageWithExcessLength[2]),
   1296      kRfc5769SampleMsgPassword));
   1297  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
   1298      reinterpret_cast<const char*>(kStunMessageWithSmallLength),
   1299      kStunHeaderSize + GetBE16(&kStunMessageWithSmallLength[2]),
   1300      kRfc5769SampleMsgPassword));
   1301 
   1302  // Check that a too-short HMAC doesn't cause buffer overflow.
   1303  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
   1304      reinterpret_cast<const char*>(kStunMessageWithBadHmacAtEnd),
   1305      sizeof(kStunMessageWithBadHmacAtEnd), kRfc5769SampleMsgPassword));
   1306 
   1307  // Test that munging a single bit anywhere in the message causes the
   1308  // message-integrity check to fail, unless it is after the M-I attribute.
   1309  char buf[sizeof(kSampleRequestMI32)];
   1310  memcpy(buf, kSampleRequestMI32, sizeof(kSampleRequestMI32));
   1311  for (size_t i = 0; i < sizeof(buf); ++i) {
   1312    buf[i] ^= 0x01;
   1313    if (i > 0)
   1314      buf[i - 1] ^= 0x01;
   1315    EXPECT_EQ(i >= sizeof(buf) - 8,
   1316              StunMessage::ValidateMessageIntegrity32ForTesting(
   1317                  buf, sizeof(buf), kRfc5769SampleMsgPassword));
   1318  }
   1319 }
   1320 
   1321 // Validate that we generate correct MESSAGE-INTEGRITY-32 attributes.
   1322 TEST_F(StunTest, AddMessageIntegrity32) {
   1323  IceMessage msg;
   1324  ByteBufferReader buf(kRfc5769SampleRequestWithoutMI);
   1325  EXPECT_TRUE(msg.Read(&buf));
   1326  EXPECT_TRUE(msg.AddMessageIntegrity32(kRfc5769SampleMsgPassword));
   1327  const StunByteStringAttribute* mi_attr =
   1328      msg.GetByteString(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32);
   1329  EXPECT_EQ(4U, mi_attr->length());
   1330  EXPECT_EQ(0, memcmp(mi_attr->array_view().data(), kCalculatedHmac1_32,
   1331                      sizeof(kCalculatedHmac1_32)));
   1332 
   1333  ByteBufferWriter buf1;
   1334  EXPECT_TRUE(msg.Write(&buf1));
   1335  EXPECT_TRUE(StunMessage::ValidateMessageIntegrity32ForTesting(
   1336      reinterpret_cast<const char*>(buf1.Data()), buf1.Length(),
   1337      kRfc5769SampleMsgPassword));
   1338 
   1339  IceMessage msg2;
   1340  ByteBufferReader buf2(kRfc5769SampleResponseWithoutMI);
   1341  EXPECT_TRUE(msg2.Read(&buf2));
   1342  EXPECT_TRUE(msg2.AddMessageIntegrity32(kRfc5769SampleMsgPassword));
   1343  const StunByteStringAttribute* mi_attr2 =
   1344      msg2.GetByteString(STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32);
   1345  EXPECT_EQ(4U, mi_attr2->length());
   1346  EXPECT_EQ(0, memcmp(mi_attr2->array_view().data(), kCalculatedHmac2_32,
   1347                      sizeof(kCalculatedHmac2_32)));
   1348 
   1349  ByteBufferWriter buf3;
   1350  EXPECT_TRUE(msg2.Write(&buf3));
   1351  EXPECT_TRUE(StunMessage::ValidateMessageIntegrity32ForTesting(
   1352      reinterpret_cast<const char*>(buf3.Data()), buf3.Length(),
   1353      kRfc5769SampleMsgPassword));
   1354 }
   1355 
   1356 // Validate that the message validates if both MESSAGE-INTEGRITY-32 and
   1357 // MESSAGE-INTEGRITY are present in the message.
   1358 // This is not expected to be used, but is not forbidden.
   1359 TEST_F(StunTest, AddMessageIntegrity32AndMessageIntegrity) {
   1360  IceMessage msg;
   1361  auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
   1362  attr->CopyBytes("keso", sizeof("keso"));
   1363  msg.AddAttribute(std::move(attr));
   1364  msg.AddMessageIntegrity32("password1");
   1365  msg.AddMessageIntegrity("password2");
   1366 
   1367  ByteBufferWriter buf1;
   1368  EXPECT_TRUE(msg.Write(&buf1));
   1369  EXPECT_TRUE(StunMessage::ValidateMessageIntegrity32ForTesting(
   1370      reinterpret_cast<const char*>(buf1.Data()), buf1.Length(), "password1"));
   1371  EXPECT_TRUE(StunMessage::ValidateMessageIntegrityForTesting(
   1372      reinterpret_cast<const char*>(buf1.Data()), buf1.Length(), "password2"));
   1373 
   1374  EXPECT_FALSE(StunMessage::ValidateMessageIntegrity32ForTesting(
   1375      reinterpret_cast<const char*>(buf1.Data()), buf1.Length(), "password2"));
   1376  EXPECT_FALSE(StunMessage::ValidateMessageIntegrityForTesting(
   1377      reinterpret_cast<const char*>(buf1.Data()), buf1.Length(), "password1"));
   1378 }
   1379 
   1380 // Check our STUN message validation code against the RFC5769 test messages.
   1381 TEST_F(StunTest, ValidateFingerprint) {
   1382  EXPECT_TRUE(StunMessage::ValidateFingerprint(
   1383      reinterpret_cast<const char*>(kRfc5769SampleRequest),
   1384      sizeof(kRfc5769SampleRequest)));
   1385  EXPECT_TRUE(StunMessage::ValidateFingerprint(
   1386      reinterpret_cast<const char*>(kRfc5769SampleResponse),
   1387      sizeof(kRfc5769SampleResponse)));
   1388  EXPECT_TRUE(StunMessage::ValidateFingerprint(
   1389      reinterpret_cast<const char*>(kRfc5769SampleResponseIPv6),
   1390      sizeof(kRfc5769SampleResponseIPv6)));
   1391 
   1392  EXPECT_FALSE(StunMessage::ValidateFingerprint(
   1393      reinterpret_cast<const char*>(kStunMessageWithZeroLength),
   1394      sizeof(kStunMessageWithZeroLength)));
   1395  EXPECT_FALSE(StunMessage::ValidateFingerprint(
   1396      reinterpret_cast<const char*>(kStunMessageWithExcessLength),
   1397      sizeof(kStunMessageWithExcessLength)));
   1398  EXPECT_FALSE(StunMessage::ValidateFingerprint(
   1399      reinterpret_cast<const char*>(kStunMessageWithSmallLength),
   1400      sizeof(kStunMessageWithSmallLength)));
   1401 
   1402  // Test that munging a single bit anywhere in the message causes the
   1403  // fingerprint check to fail.
   1404  char buf[sizeof(kRfc5769SampleRequest)];
   1405  memcpy(buf, kRfc5769SampleRequest, sizeof(kRfc5769SampleRequest));
   1406  for (size_t i = 0; i < sizeof(buf); ++i) {
   1407    buf[i] ^= 0x01;
   1408    if (i > 0)
   1409      buf[i - 1] ^= 0x01;
   1410    EXPECT_FALSE(StunMessage::ValidateFingerprint(buf, sizeof(buf)));
   1411  }
   1412  // Put them all back to normal and the check should pass again.
   1413  buf[sizeof(buf) - 1] ^= 0x01;
   1414  EXPECT_TRUE(StunMessage::ValidateFingerprint(buf, sizeof(buf)));
   1415 }
   1416 
   1417 TEST_F(StunTest, AddFingerprint) {
   1418  IceMessage msg;
   1419  ByteBufferReader buf(kRfc5769SampleRequestWithoutMI);
   1420  EXPECT_TRUE(msg.Read(&buf));
   1421  EXPECT_TRUE(msg.AddFingerprint());
   1422 
   1423  ByteBufferWriter buf1;
   1424  EXPECT_TRUE(msg.Write(&buf1));
   1425  EXPECT_TRUE(StunMessage::ValidateFingerprint(
   1426      reinterpret_cast<const char*>(buf1.Data()), buf1.Length()));
   1427 }
   1428 
   1429 // Test that we can remove attribute from a message.
   1430 TEST_F(StunTest, RemoveAttribute) {
   1431  StunMessage msg;
   1432 
   1433  // Removing something that does exist should return nullptr.
   1434  EXPECT_EQ(msg.RemoveAttribute(STUN_ATTR_USERNAME), nullptr);
   1435 
   1436  {
   1437    auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
   1438    attr->CopyBytes("kes", sizeof("kes"));
   1439    msg.AddAttribute(std::move(attr));
   1440  }
   1441 
   1442  size_t len = msg.length();
   1443  {
   1444    auto attr = msg.RemoveAttribute(STUN_ATTR_USERNAME);
   1445    ASSERT_NE(attr, nullptr);
   1446    EXPECT_EQ(attr->type(), STUN_ATTR_USERNAME);
   1447    EXPECT_STREQ("kes", static_cast<StunByteStringAttribute*>(attr.get())
   1448                            ->string_view()
   1449                            .data());
   1450    EXPECT_LT(msg.length(), len);
   1451  }
   1452 
   1453  // Now add same attribute type twice.
   1454  {
   1455    auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
   1456    attr->CopyBytes("kes", sizeof("kes"));
   1457    msg.AddAttribute(std::move(attr));
   1458  }
   1459 
   1460  {
   1461    auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
   1462    attr->CopyBytes("kenta", sizeof("kenta"));
   1463    msg.AddAttribute(std::move(attr));
   1464  }
   1465 
   1466  // Remove should remove the last added occurrence.
   1467  {
   1468    auto attr = msg.RemoveAttribute(STUN_ATTR_USERNAME);
   1469    ASSERT_NE(attr, nullptr);
   1470    EXPECT_EQ(attr->type(), STUN_ATTR_USERNAME);
   1471    EXPECT_STREQ("kenta", static_cast<StunByteStringAttribute*>(attr.get())
   1472                              ->string_view()
   1473                              .data());
   1474  }
   1475 
   1476  // Remove should remove the last added occurrence.
   1477  {
   1478    auto attr = msg.RemoveAttribute(STUN_ATTR_USERNAME);
   1479    ASSERT_NE(attr, nullptr);
   1480    EXPECT_EQ(attr->type(), STUN_ATTR_USERNAME);
   1481    EXPECT_STREQ("kes", static_cast<StunByteStringAttribute*>(attr.get())
   1482                            ->string_view()
   1483                            .data());
   1484  }
   1485 
   1486  // Removing something that does exist should return nullptr.
   1487  EXPECT_EQ(msg.RemoveAttribute(STUN_ATTR_USERNAME), nullptr);
   1488 }
   1489 
   1490 // Test that we can remove attribute from a message.
   1491 TEST_F(StunTest, ClearAttributes) {
   1492  StunMessage msg;
   1493 
   1494  auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
   1495  attr->CopyBytes("kes", sizeof("kes"));
   1496  msg.AddAttribute(std::move(attr));
   1497  size_t len = msg.length();
   1498 
   1499  msg.ClearAttributes();
   1500  EXPECT_EQ(msg.length(), len - /* 3 + 1 byte padding + header */ 8);
   1501  EXPECT_EQ(nullptr, msg.GetByteString(STUN_ATTR_USERNAME));
   1502 }
   1503 
   1504 // Test CopyStunAttribute
   1505 TEST_F(StunTest, CopyAttribute) {
   1506  ByteBufferWriter buf;
   1507  ByteBufferWriter* buffer_ptrs[] = {&buf, nullptr};
   1508  // Test both with and without supplied ByteBufferWriter.
   1509  for (auto buffer_ptr : buffer_ptrs) {
   1510    {  // Test StunByteStringAttribute.
   1511      auto attr = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
   1512      attr->CopyBytes("kes", sizeof("kes"));
   1513 
   1514      auto copy = CopyStunAttribute(*attr, buffer_ptr);
   1515      ASSERT_EQ(copy->value_type(), STUN_VALUE_BYTE_STRING);
   1516      EXPECT_STREQ("kes", static_cast<StunByteStringAttribute*>(copy.get())
   1517                              ->string_view()
   1518                              .data());
   1519    }
   1520 
   1521    {  // Test StunAddressAttribute.
   1522      IPAddress test_ip(kIPv6TestAddress2);
   1523      auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
   1524      SocketAddress test_addr(test_ip, kTestMessagePort2);
   1525      addr->SetAddress(test_addr);
   1526      CheckStunAddressAttribute(addr.get(), STUN_ADDRESS_IPV6,
   1527                                kTestMessagePort2, test_ip);
   1528 
   1529      auto copy = CopyStunAttribute(*addr, buffer_ptr);
   1530      ASSERT_EQ(copy->value_type(), STUN_VALUE_ADDRESS);
   1531      CheckStunAddressAttribute(static_cast<StunAddressAttribute*>(copy.get()),
   1532                                STUN_ADDRESS_IPV6, kTestMessagePort2, test_ip);
   1533    }
   1534 
   1535    {  // Test StunAddressAttribute.
   1536      IPAddress test_ip(kIPv6TestAddress2);
   1537      auto addr = StunAttribute::CreateAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
   1538      SocketAddress test_addr(test_ip, kTestMessagePort2);
   1539      addr->SetAddress(test_addr);
   1540      CheckStunAddressAttribute(addr.get(), STUN_ADDRESS_IPV6,
   1541                                kTestMessagePort2, test_ip);
   1542 
   1543      auto copy = CopyStunAttribute(*addr, buffer_ptr);
   1544      ASSERT_EQ(copy->value_type(), STUN_VALUE_ADDRESS);
   1545      CheckStunAddressAttribute(static_cast<StunAddressAttribute*>(copy.get()),
   1546                                STUN_ADDRESS_IPV6, kTestMessagePort2, test_ip);
   1547    }
   1548  }
   1549 }
   1550 
   1551 // Test Clone
   1552 TEST_F(StunTest, Clone) {
   1553  IceMessage msg(0, "0123456789ab");
   1554  {
   1555    auto errorcode = StunAttribute::CreateErrorCode();
   1556    errorcode->SetCode(kTestErrorCode);
   1557    errorcode->SetReason(kTestErrorReason);
   1558    msg.AddAttribute(std::move(errorcode));
   1559  }
   1560  {
   1561    auto bytes2 = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
   1562    bytes2->CopyBytes("abcdefghijkl");
   1563    msg.AddAttribute(std::move(bytes2));
   1564  }
   1565  {
   1566    auto uval2 = StunAttribute::CreateUInt32(STUN_ATTR_RETRANSMIT_COUNT);
   1567    uval2->SetValue(11);
   1568    msg.AddAttribute(std::move(uval2));
   1569  }
   1570  {
   1571    auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
   1572    addr->SetIP(IPAddress(kIPv6TestAddress1));
   1573    addr->SetPort(kTestMessagePort1);
   1574    msg.AddAttribute(std::move(addr));
   1575  }
   1576  auto copy = msg.Clone();
   1577  ASSERT_NE(nullptr, copy.get());
   1578 
   1579  ByteBufferWriter out1;
   1580  EXPECT_TRUE(msg.Write(&out1));
   1581  ByteBufferWriter out2;
   1582  EXPECT_TRUE(copy->Write(&out2));
   1583 
   1584  ASSERT_EQ(out1.Length(), out2.Length());
   1585  EXPECT_EQ(0, memcmp(out1.Data(), out2.Data(), out1.Length()));
   1586 }
   1587 
   1588 // Test EqualAttributes
   1589 TEST_F(StunTest, EqualAttributes) {
   1590  IceMessage msg;
   1591  {
   1592    auto errorcode = StunAttribute::CreateErrorCode();
   1593    errorcode->SetCode(kTestErrorCode);
   1594    errorcode->SetReason(kTestErrorReason);
   1595    msg.AddAttribute(std::move(errorcode));
   1596  }
   1597  {
   1598    auto bytes2 = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
   1599    bytes2->CopyBytes("abcdefghijkl");
   1600    msg.AddAttribute(std::move(bytes2));
   1601  }
   1602  {
   1603    auto uval2 = StunAttribute::CreateUInt32(STUN_ATTR_RETRANSMIT_COUNT);
   1604    uval2->SetValue(11);
   1605    msg.AddAttribute(std::move(uval2));
   1606  }
   1607  {
   1608    auto addr = StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
   1609    addr->SetIP(IPAddress(kIPv6TestAddress1));
   1610    addr->SetPort(kTestMessagePort1);
   1611    msg.AddAttribute(std::move(addr));
   1612  }
   1613  auto copy = msg.Clone();
   1614  ASSERT_NE(nullptr, copy.get());
   1615 
   1616  EXPECT_TRUE(copy->EqualAttributes(&msg, [](int /* type */) { return true; }));
   1617 
   1618  {
   1619    auto attr = StunAttribute::CreateByteString(STUN_ATTR_NONCE);
   1620    attr->CopyBytes("keso");
   1621    msg.AddAttribute(std::move(attr));
   1622    EXPECT_FALSE(
   1623        copy->EqualAttributes(&msg, [](int /* type */) { return true; }));
   1624    EXPECT_TRUE(copy->EqualAttributes(
   1625        &msg, [](int type) { return type != STUN_ATTR_NONCE; }));
   1626  }
   1627 
   1628  {
   1629    auto attr = StunAttribute::CreateByteString(STUN_ATTR_NONCE);
   1630    attr->CopyBytes("keso");
   1631    copy->AddAttribute(std::move(attr));
   1632    EXPECT_TRUE(
   1633        copy->EqualAttributes(&msg, [](int /* type */) { return true; }));
   1634  }
   1635  {
   1636    copy->RemoveAttribute(STUN_ATTR_NONCE);
   1637    auto attr = StunAttribute::CreateByteString(STUN_ATTR_NONCE);
   1638    attr->CopyBytes("kent");
   1639    copy->AddAttribute(std::move(attr));
   1640    EXPECT_FALSE(
   1641        copy->EqualAttributes(&msg, [](int /* type */) { return true; }));
   1642    EXPECT_TRUE(copy->EqualAttributes(
   1643        &msg, [](int type) { return type != STUN_ATTR_NONCE; }));
   1644  }
   1645 
   1646  {
   1647    msg.RemoveAttribute(STUN_ATTR_NONCE);
   1648    EXPECT_FALSE(
   1649        copy->EqualAttributes(&msg, [](int /* type */) { return true; }));
   1650    EXPECT_TRUE(copy->EqualAttributes(
   1651        &msg, [](int type) { return type != STUN_ATTR_NONCE; }));
   1652  }
   1653 }
   1654 
   1655 TEST_F(StunTest, ReduceTransactionIdIsHostOrderIndependent) {
   1656  const std::string transaction_id = "abcdefghijkl";
   1657  StunMessage message(0, transaction_id);
   1658  uint32_t reduced_transaction_id = message.reduced_transaction_id();
   1659  EXPECT_EQ(reduced_transaction_id, 1835954016u);
   1660 }
   1661 
   1662 TEST_F(StunTest, GoogMiscInfo) {
   1663  StunMessage msg(STUN_BINDING_REQUEST, "ABCDEFGHIJKL");
   1664  const size_t size =
   1665      /* msg header */ 20 +
   1666      /* attr header */ 4 +
   1667      /* 3 * 2 rounded to multiple of 4 */ 8;
   1668  auto list =
   1669      StunAttribute::CreateUInt16ListAttribute(STUN_ATTR_GOOG_MISC_INFO);
   1670  list->AddTypeAtIndex(0, 0x1U);
   1671  list->AddTypeAtIndex(3, 0x1000U);
   1672  list->AddTypeAtIndex(2, 0xAB0CU);
   1673  msg.AddAttribute(std::move(list));
   1674  CheckStunHeader(msg, STUN_BINDING_REQUEST, (size - 20));
   1675 
   1676  ByteBufferWriter out;
   1677  EXPECT_TRUE(msg.Write(&out));
   1678  ASSERT_EQ(size, out.Length());
   1679 
   1680  size_t read_size = ReadStunMessageTestCase(
   1681      &msg, reinterpret_cast<const uint8_t*>(out.Data()), out.Length());
   1682  ASSERT_EQ(read_size + 20, size);
   1683  CheckStunHeader(msg, STUN_BINDING_REQUEST, read_size);
   1684  const StunUInt16ListAttribute* types =
   1685      msg.GetUInt16List(STUN_ATTR_GOOG_MISC_INFO);
   1686  ASSERT_TRUE(types != nullptr);
   1687  EXPECT_EQ(4U, types->Size());
   1688  EXPECT_EQ(0x1U, types->GetType(0));
   1689  EXPECT_EQ(0x0U, types->GetType(1));
   1690  EXPECT_EQ(0x1000U, types->GetType(3));
   1691  EXPECT_EQ(0xAB0CU, types->GetType(2));
   1692 }
   1693 
   1694 TEST_F(StunTest, IsStunMethod) {
   1695  int methods[] = {STUN_BINDING_REQUEST};
   1696  EXPECT_TRUE(StunMessage::IsStunMethod(
   1697      methods, reinterpret_cast<const char*>(kRfc5769SampleRequest),
   1698      sizeof(kRfc5769SampleRequest)));
   1699 }
   1700 
   1701 TEST_F(StunTest, SizeRestrictionOnAttributes) {
   1702  StunMessage msg(STUN_BINDING_REQUEST, "ABCDEFGHIJKL");
   1703  auto long_username = StunAttribute::CreateByteString(STUN_ATTR_USERNAME);
   1704  std::string long_string(509, 'x');
   1705  long_username->CopyBytes(long_string.c_str(), long_string.size());
   1706  msg.AddAttribute(std::move(long_username));
   1707  ByteBufferWriter out;
   1708  ASSERT_FALSE(msg.Write(&out));
   1709 }
   1710 
   1711 TEST_F(StunTest, ValidateMessageIntegrityWithParser) {
   1712  metrics::Reset();  // Ensure counters start from zero.
   1713  // Try the messages from RFC 5769.
   1714  StunMessage message;
   1715  ByteBufferReader reader(kRfc5769SampleRequest);
   1716  EXPECT_TRUE(message.Read(&reader));
   1717  EXPECT_EQ(message.ValidateMessageIntegrity(kRfc5769SampleMsgPassword),
   1718            StunMessage::IntegrityStatus::kIntegrityOk);
   1719  EXPECT_EQ(metrics::NumEvents(
   1720                "WebRTC.Stun.Integrity.Request",
   1721                static_cast<int>(StunMessage::IntegrityStatus::kIntegrityOk)),
   1722            1);
   1723  EXPECT_EQ(message.RevalidateMessageIntegrity("Invalid password"),
   1724            StunMessage::IntegrityStatus::kIntegrityBad);
   1725  EXPECT_EQ(metrics::NumEvents(
   1726                "WebRTC.Stun.Integrity.Request",
   1727                static_cast<int>(StunMessage::IntegrityStatus::kIntegrityBad)),
   1728            1);
   1729  EXPECT_EQ(metrics::NumSamples("WebRTC.Stun.Integrity.Request"), 2);
   1730 }
   1731 
   1732 TEST_F(StunTest, ByteStringAsVectorOfUint32) {
   1733  StunMessage message;
   1734  ByteBufferReader reader(kRfc5769SampleRequest);
   1735  EXPECT_TRUE(message.Read(&reader));
   1736 
   1737  // The username attribute has a length which is not a multiple of 4
   1738  // so getting a uint32_t vector from it should fail.
   1739  const StunByteStringAttribute* username =
   1740      message.GetByteString(STUN_ATTR_USERNAME);
   1741  ASSERT_TRUE(username);
   1742  EXPECT_FALSE(username->GetUInt32Vector());
   1743 
   1744  // message-integrity is 20 bytes which makes it usable as a test case.
   1745  const StunByteStringAttribute* integrity =
   1746      message.GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
   1747  ASSERT_TRUE(integrity);
   1748  std::optional<std::vector<uint32_t>> integrity_vector =
   1749      integrity->GetUInt32Vector();
   1750  ASSERT_TRUE(integrity_vector);
   1751  EXPECT_EQ(5U, integrity_vector->size());
   1752  // Taken from the RFC 5769 sample request.
   1753  std::vector<uint32_t> expected_integrity_vector = {
   1754      0x9aeaa70c, 0xbfd8cb56, 0x781ef2b5, 0xb2d3f249, 0xc1b571a2};
   1755  EXPECT_THAT(*integrity_vector,
   1756              ::testing::ElementsAreArray(expected_integrity_vector));
   1757 }
   1758 
   1759 }  // namespace webrtc