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