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