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