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