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