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