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