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