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