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