1 /*
2 * This file is part of the Nice GLib ICE library.
3 *
4 * (C) 2007 Nokia Corporation. All rights reserved.
5 * Contact: Rémi Denis-Courmont
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is the Nice GLib ICE library.
18 *
19 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20 * Corporation. All Rights Reserved.
21 *
22 * Contributors:
23 * Rémi Denis-Courmont, Nokia
24 *
25 * Alternatively, the contents of this file may be used under the terms of the
26 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
27 * case the provisions of LGPL are applicable instead of those above. If you
28 * wish to allow use of your version of this file only under the terms of the
29 * LGPL and not to allow others to use your version of this file under the
30 * MPL, indicate your decision by deleting the provisions above and replace
31 * them with the notice and other provisions required by the LGPL. If you do
32 * not delete the provisions above, a recipient may use your version of this
33 * file under either the MPL or the LGPL.
34 */
35
36 #ifdef HAVE_CONFIG_H
37 # include <config.h>
38 #endif
39
40 #include "stun/stunagent.h"
41 #include "stun/stunhmac.h"
42 #include <stdio.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <stdarg.h>
46
47 #ifdef _WIN32
48 #include <winsock2.h>
49 #include <io.h>
50 #else
51 #include <sys/types.h>
52 #include <sys/socket.h>
53 #include <arpa/inet.h>
54 #include <netinet/in.h>
55 #endif
56
57
58 # define STUN_MAX_STR (763u)
59 # define STUN_MAX_CP (127u)
60
fatal(const char * msg,...)61 static void fatal (const char *msg, ...)
62 {
63 va_list ap;
64 va_start (ap, msg);
65 vfprintf (stderr, msg, ap);
66 va_end (ap);
67 fputc ('\n', stderr);
68 exit (1);
69 }
70
71
validate(const uint8_t * msg,unsigned len)72 static void validate (const uint8_t *msg, unsigned len)
73 {
74 unsigned i = 1;
75
76 do
77 {
78 size_t vlen = stun_message_validate_buffer_length (msg, i, TRUE);
79 if ((vlen & 3) || (vlen != ((i >= len) * len)))
80 fatal ("%u/%u short message test failed", i, len);
81 }
82 while (i++ < (len + 4));
83 }
84
85
86 /* Tests for generic message validation routines */
test_message(void)87 static void test_message (void)
88 {
89 static const uint8_t extra_garbage[] =
90 {0x15, 0x55, 0x00, 0x00,
91 0x21, 0x12, 0xA4, 0x42, // cookie
92 0x76, 0x54, 0x32, 0x10,
93 0xfe, 0xdc, 0xba, 0x98,
94 0x76, 0x54, 0x32, 0x10,
95 0xaa, 0xbb, 0xcc, 0xdd}; //extra garbage
96 static const uint8_t simple_resp[] =
97 {0x15, 0x55, 0x00, 0x00,
98 0x21, 0x12, 0xA4, 0x42, // cookie
99 0x76, 0x54, 0x32, 0x10,
100 0xfe, 0xdc, 0xba, 0x98,
101 0x76, 0x54, 0x32, 0x10};
102 static const uint8_t old_ind[] =
103 {0x14, 0x55, 0x00, 0x00,
104 0xfe, 0xdc, 0xba, 0x98, // NO cookie
105 0x76, 0x54, 0x32, 0x10,
106 0xfe, 0xdc, 0xba, 0x98,
107 0x76, 0x54, 0x32, 0x10};
108 static const uint8_t fpr_resp[] =
109 {0x15, 0x55, 0x00, 0x10,
110 0x21, 0x12, 0xA4, 0x42, // cookie
111 0x76, 0x54, 0x32, 0x10,
112 0xfe, 0xdc, 0xba, 0x98,
113 0x76, 0x54, 0x32, 0x10,
114 0x00, 0x06, 0x00, 0x04, // dummy USERNAME header
115 0x41, 0x42, 0x43, 0x44,
116 0x80, 0x28, 0x00, 0x04, // FINGERPRINT header
117 0xdc, 0x8d, 0xa7, 0x74}; // CRC32;
118 static const uint8_t bad1[32] =
119 {0x15, 0x55, 0x00, 0x08,
120 0x21, 0x12, 0xA4, 0x42, // cookie
121 0x76, 0x54, 0x32, 0x10,
122 0xfe, 0xdc, 0xba, 0x98,
123 0x76, 0x54, 0x32, 0x10,
124 0x00, 0x06, 0x00, 0x05, // too big attribute for message
125 0x11, 0x22, 0x33, 0x44,
126 0x55, 0x66, 0x77, 0x88};
127 static const uint8_t bad2[24] =
128 {0x15, 0x55, 0x00, 0x05, // invalid message length
129 0x21, 0x12, 0xA4, 0x42,
130 0x76, 0x54, 0x32, 0x10,
131 0xfe, 0xdc, 0xba, 0x98,
132 0x76, 0x54, 0x32, 0x10,
133 0x00, 0x06, 0x00, 0x01};
134 static const uint8_t bad3[27] =
135 {0x15, 0x55, 0x00, 0x08,
136 0x21, 0x12, 0xA4, 0x42,
137 0x76, 0x54, 0x32, 0x10,
138 0xfe, 0xdc, 0xba, 0x98,
139 0x76, 0x54, 0x32, 0x10,
140 0x00, 0x06, 0x00, 0x03,
141 0x11, 0x22, 0x33}; // missing padding
142 static const uint8_t bad_crc[] =
143 {0x15, 0x55, 0x00, 0x08,
144 0x21, 0x12, 0xA4, 0x42,
145 0x76, 0x54, 0x32, 0x10,
146 0xfe, 0xdc, 0xba, 0x98,
147 0x76, 0x54, 0x32, 0x10,
148 0x80, 0x28, 0x00, 0x04, // FINGERPRINT header
149 0x04, 0x91, 0xcd, 0x78}; // CRC32
150 static uint8_t bad_crc_offset[] =
151 {0x15, 0x55, 0x00, 0x10,
152 0x21, 0x12, 0xA4, 0x42,
153 0x76, 0x54, 0x32, 0x10,
154 0xfe, 0xdc, 0xba, 0x98,
155 0x20, 0x67, 0xc4, 0x09,
156 0x80, 0x28, 0x00, 0x04, // FINGERPRINT header
157 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x06, 0x00, 0x04,
159 0x41, 0x42, 0x43, 0x44};
160
161 static unsigned char req[] =
162 {0x00, 0x01, 0x00, 0x00,
163 0x8b, 0x45, 0x9b, 0xc3,
164 0xe7, 0x7a, 0x05, 0xb3,
165 0xe4, 0xfe, 0x01, 0xf0,
166 0xaf, 0x83, 0xe1, 0x9e};
167
168 static uint8_t binding_error_resp[] =
169 {0x01, 0x11, 0x00, 0x84,
170 0x8b, 0x45, 0x9b, 0xc3,
171 0xe7, 0x7a, 0x05, 0xb3,
172 0xe4, 0xfe, 0x01, 0xf0,
173 0xaf, 0x83, 0xe1, 0x9e,
174
175 0x00, 0x06, 0x00, 0x48, // USERNAME
176 0x92, 0x6b, 0x2b, 0x3e,
177 0x6a, 0xa5, 0x43, 0x58,
178 0xa8, 0x51, 0x25, 0xa6,
179 0xf7, 0x9c, 0x0a, 0xe7,
180 0xd8, 0x86, 0xf7, 0x76,
181 0xf9, 0xcd, 0x8a, 0x2e,
182 0x45, 0xd7, 0xcb, 0xbb,
183 0xae, 0xe5, 0x03, 0xc3,
184 0x3a, 0x32, 0x3a, 0xa9,
185 0x9e, 0xb7, 0x7b, 0x32,
186 0xe3, 0xf3, 0xa6, 0xc0,
187 0xe8, 0x54, 0x4b, 0xef,
188 0x52, 0xd2, 0xe2, 0xc0,
189 0x43, 0xc2, 0x4c, 0xbc,
190 0xaf, 0xd9, 0xf2, 0xfa,
191 0x48, 0x8b, 0x8c, 0xe6,
192 0x62, 0x14, 0x64, 0x3a,
193 0x32, 0x00, 0x00, 0x00,
194
195 0x00, 0x09, 0x00, 0x1c, // ERROR-CODE
196 0x00, 0x00, 0x04, 0x1f,
197 0x49, 0x6e, 0x74, 0x65,
198 0x67, 0x72, 0x69, 0x74,
199 0x79, 0x20, 0x43, 0x68,
200 0x65, 0x63, 0x6b, 0x20,
201 0x46, 0x61, 0x69, 0x6c,
202 0x75, 0x72, 0x65, 0x2e,
203
204 0x00, 0x08, 0x00, 0x14, // MESSAGE-INTEGRITY
205 0xf7, 0x46, 0x81, 0xc4,
206 0x6f, 0x4c, 0x21, 0x5c,
207 0xf6, 0x8e, 0xc0, 0x81,
208 0x0e, 0x20, 0x3f, 0xb1,
209 0xb1, 0xad, 0xa4, 0x8a};
210
211 StunAgent agent;
212 StunAgent agent2;
213 StunMessage msg;
214 uint16_t known_attributes[] = {STUN_ATTRIBUTE_USERNAME,
215 STUN_ATTRIBUTE_ERROR_CODE,
216 STUN_ATTRIBUTE_MESSAGE_INTEGRITY};
217
218 uint8_t username_v[] = {0x92, 0x6b, 0x2b, 0x3e, 0x6a, 0xa5, 0x43, 0x58,
219 0xa8, 0x51, 0x25, 0xa6, 0xf7, 0x9c, 0x0a, 0xe7,
220 0xd8, 0x86, 0xf7, 0x76, 0xf9, 0xcd, 0x8a, 0x2e,
221 0x45, 0xd7, 0xcb, 0xbb, 0xae, 0xe5, 0x03, 0xc3,
222 0x3a, 0x32, 0x3a, 0xa9, 0x9e, 0xb7, 0x7b, 0x32,
223 0xe3, 0xf3, 0xa6, 0xc0, 0xe8, 0x54, 0x4b, 0xef,
224 0x52, 0xd2, 0xe2, 0xc0, 0x43, 0xc2, 0x4c, 0xbc,
225 0xaf, 0xd9, 0xf2, 0xfa, 0x48, 0x8b, 0x8c, 0xe6,
226 0x62, 0x14, 0x64, 0x3a, 0x32, 0x00, 0x00, 0x00};
227 uint8_t password_v[] = {0x77, 0xd9, 0x7a, 0xe9, 0xcf, 0xe0, 0x3e, 0xa2,
228 0x28, 0xa0, 0x5d, 0xec, 0xcf, 0x36, 0xe8, 0x49};
229
230 StunDefaultValidaterData v = {username_v, 72, password_v, 16};
231
232 stun_agent_init (&agent, known_attributes,
233 STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT);
234 stun_agent_init (&agent2, known_attributes,
235 STUN_COMPATIBILITY_RFC3489, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS);
236
237
238 stun_agent_validate (&agent2, &msg, req, sizeof(req), NULL, NULL);
239 stun_agent_finish_message (&agent2, &msg, NULL, 0);
240
241 if (stun_agent_validate (&agent2, &msg, binding_error_resp,
242 sizeof(binding_error_resp),
243 stun_agent_default_validater, &v) != STUN_VALIDATION_SUCCESS)
244 fatal ("Binding Error Response failed");
245
246
247 if (stun_message_validate_buffer_length (NULL, 0, TRUE) !=
248 STUN_MESSAGE_BUFFER_INVALID)
249 fatal ("0 bytes test failed");
250 if (stun_message_validate_buffer_length ((uint8_t *)"\xf0", 1, TRUE) >= 0)
251 fatal ("1 byte test failed");
252 if (stun_message_validate_buffer_length (bad1, sizeof (bad1), TRUE) >= 0)
253 fatal ("Badness 1 test failed");
254 if (stun_message_validate_buffer_length (bad2, sizeof (bad2), TRUE) >= 0)
255 fatal ("Badness 2 test failed");
256 if (stun_message_validate_buffer_length (bad3, sizeof (bad3), TRUE) != 0)
257 fatal ("Badness 3 test failed");
258 validate (simple_resp, 20);
259 validate (old_ind, 20);
260 validate (fpr_resp, 36);
261
262 if (stun_agent_validate (&agent, &msg, extra_garbage, sizeof(extra_garbage),
263 NULL, NULL) != STUN_VALIDATION_NOT_STUN)
264 fatal ("Extra garbage test failed");
265 if (stun_agent_validate (&agent, &msg, simple_resp, sizeof(simple_resp),
266 NULL, NULL) != STUN_VALIDATION_BAD_REQUEST)
267 fatal ("Missing CRC test failed");
268 if (stun_agent_validate (&agent, &msg, old_ind, sizeof(old_ind),
269 NULL, NULL) != STUN_VALIDATION_BAD_REQUEST)
270 fatal ("Missing cookie test failed");
271 if (stun_agent_validate (&agent, &msg, bad_crc, sizeof(bad_crc),
272 NULL, NULL) != STUN_VALIDATION_BAD_REQUEST)
273 fatal ("Bad CRC test failed");
274 if (stun_agent_validate (&agent, &msg, bad_crc_offset, sizeof(bad_crc_offset),
275 NULL, NULL) != STUN_VALIDATION_BAD_REQUEST)
276 fatal ("Bad CRC offset test failed");
277 if (stun_agent_validate (&agent, &msg, fpr_resp, sizeof(fpr_resp),
278 NULL, NULL) != STUN_VALIDATION_UNMATCHED_RESPONSE)
279 fatal ("Good CRC test failed");
280
281 if (stun_message_get_class (&msg) != 3)
282 fatal ("Class test failed");
283 if (stun_message_get_method (&msg) != 0x525)
284 fatal ("Method test failed");
285 }
286
287
test_attribute_validater(StunAgent * agent,StunMessage * message,uint8_t * username,uint16_t username_len,uint8_t ** password,size_t * password_len,void * user_data)288 static bool test_attribute_validater (StunAgent *agent,
289 StunMessage *message, uint8_t *username, uint16_t username_len,
290 uint8_t **password, size_t *password_len, void *user_data)
291 {
292 uint8_t *pwd = user_data;
293
294 if (username_len != 4 ||
295 memcmp (username, "ABCD", 4) != 0)
296 return false;
297
298 *password = pwd;
299 *password_len = strlen ((char *) pwd);
300
301 return true;
302 }
303
304 /* Tests for message attribute parsing */
test_attribute(void)305 static void test_attribute (void)
306 {
307 static const uint8_t acme[] =
308 {0x04, 0x55, 0x00, 0x6C, // <-- update message length if needed!!
309 0x21, 0x12, 0xA4, 0x42, // cookie
310 0x76, 0x54, 0x32, 0x10,
311 0xfe, 0xdc, 0xba, 0x98,
312 0x76, 0x54, 0x32, 0x10,
313
314 /* FF01: empty */
315 0xff, 0x01, 0x00, 0x00,
316
317 /* FF02: address of unknown family, 32-bits */
318 0xff, 0x02, 0x00, 0x04,
319 0x41, 0x42, 0x43, 0x44,
320
321 /* FF03: too short IPv6 address */
322 0xff, 0x03, 0x00, 0x06,
323 0x00, 0x02, 0x12, 0x34,
324 0x20, 0x01, 0x0d, 0xb8,
325
326 /* FF04: valid IPv4 address, 64-bits */
327 0xff, 0x04, 0x00, 0x08,
328 0x00, 0x01, 0x12, 0x34,
329 0xc0, 0x00, 0x02, 0x01,
330
331 /* FF05: too long IPv4 address */
332 0xff, 0x05, 0x00, 0x0A,
333 0x00, 0x01, 0x12, 0x34,
334 0xc0, 0x00, 0x02, 0x01,
335 0x66, 0x60, 0x00, 0x00,
336
337 /* FF06: valid xor'd IPv6 address, 160-bits */
338 0xff, 0x06, 0x00, 0x14,
339 0x00, 0x02, 0x12, 0x34,
340 0x01, 0x13, 0xa9, 0xfa,
341 0xa8, 0xf9, 0x8c, 0xff,
342 0x20, 0x26, 0x74, 0x48,
343 0x8c, 0x9a, 0xec, 0xfd,
344
345 /* dummy USERNAME header */
346 0x00, 0x06, 0x00, 0x04,
347 0x41, 0x42, 0x43, 0x44,
348
349 /* MESSAGE-INTEGRITY attribute */
350 0x00, 0x08, 0x00, 0x14,
351 0x0b, 0xc4, 0xb2, 0x0c,
352 0x94, 0x58, 0xbb, 0x25,
353 0xa3, 0x22, 0x1a, 0xc8,
354 0xe1, 0x87, 0x32, 0x36,
355 0x3a, 0xfc, 0xe2, 0xc3};
356
357 union
358 {
359 struct sockaddr_storage st;
360 struct sockaddr_in6 s6;
361 } addr;
362 socklen_t addrlen;
363 uint32_t dword;
364 uint64_t qword;
365 char str[STUN_MAX_STR];
366
367 StunAgent agent;
368 StunMessage msg;
369 uint16_t known_attributes[] = {STUN_ATTRIBUTE_MESSAGE_INTEGRITY, STUN_ATTRIBUTE_USERNAME, 0};
370
371 printf ("Attribute test message length: %zd\n", sizeof (acme));
372
373 stun_agent_init (&agent, known_attributes,
374 STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS);
375
376 if (stun_agent_validate (&agent, &msg, acme, sizeof(acme),
377 NULL, NULL) != STUN_VALIDATION_UNAUTHORIZED)
378 fatal ("Unauthorized validation failed");
379
380 if (stun_agent_validate (&agent, &msg, acme, sizeof(acme),
381 test_attribute_validater, (void *) "bad__guy") != STUN_VALIDATION_UNAUTHORIZED)
382 fatal ("invalid password validation failed");
383
384 if (stun_agent_validate (&agent, &msg, acme, sizeof(acme),
385 test_attribute_validater, (void *) "good_guy") != STUN_VALIDATION_SUCCESS)
386 fatal ("good password validation failed");
387
388 if (stun_message_has_attribute (&msg, 0xff00))
389 fatal ("Absent attribute test failed");
390 if (!stun_message_has_attribute (&msg, 0xff01))
391 fatal ("Present attribute test failed");
392
393 if (stun_message_find_flag (&msg, 0xff00) != STUN_MESSAGE_RETURN_NOT_FOUND)
394 fatal ("Absent flag test failed");
395 if (stun_message_find_flag (&msg, 0xff01) != STUN_MESSAGE_RETURN_SUCCESS)
396 fatal ("Flag test failed");
397 if (stun_message_find_flag (&msg, 0xff02) != STUN_MESSAGE_RETURN_INVALID)
398 fatal ("Too big flag test failed");
399
400 if (stun_message_find32 (&msg, 0xff00, &dword) !=
401 STUN_MESSAGE_RETURN_NOT_FOUND)
402 fatal ("Absent dword test failed");
403 if (stun_message_find32 (&msg, 0xff01, &dword) != STUN_MESSAGE_RETURN_INVALID)
404 fatal ("Bad dword test failed");
405 if (stun_message_find32 (&msg, 0xff02, &dword) != STUN_MESSAGE_RETURN_SUCCESS)
406 fatal ("Double-word test failed");
407
408 if (stun_message_find64 (&msg, 0xff00, &qword) !=
409 STUN_MESSAGE_RETURN_NOT_FOUND)
410 fatal ("Absent qword test failed");
411 if (stun_message_find64 (&msg, 0xff01, &qword) != STUN_MESSAGE_RETURN_INVALID)
412 fatal ("Bad qword test failed");
413 if (stun_message_find64 (&msg, 0xff04, &qword) != STUN_MESSAGE_RETURN_SUCCESS)
414 fatal ("Quad-word test failed");
415
416 if (stun_message_find_string (&msg, 0xff00, str, STUN_MAX_CP) !=
417 STUN_MESSAGE_RETURN_NOT_FOUND)
418 fatal ("Absent string test failed");
419 if ((stun_message_find_string (&msg, 0xff02, str, STUN_MAX_CP) !=
420 STUN_MESSAGE_RETURN_SUCCESS)
421 || strcmp (str, "ABCD"))
422 fatal ("String test failed");
423
424 addrlen = sizeof (addr);
425 if (stun_message_find_addr (&msg, 0xff01, &addr.st, &addrlen) !=
426 STUN_MESSAGE_RETURN_INVALID)
427 fatal ("Too short addres test failed");
428 addrlen = sizeof (addr);
429 if (stun_message_find_addr (&msg, 0xff02, &addr.st, &addrlen) !=
430 STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS)
431 fatal ("Unknown address family test failed");
432 addrlen = sizeof (addr);
433 if (stun_message_find_addr (&msg, 0xff03, &addr.st, &addrlen) !=
434 STUN_MESSAGE_RETURN_INVALID)
435 fatal ("Too short IPv6 address test failed");
436 addrlen = sizeof (addr);
437 if (stun_message_find_addr (&msg, 0xff04, &addr.st, &addrlen) !=
438 STUN_MESSAGE_RETURN_SUCCESS)
439 fatal ("IPv4 address test failed");
440 addrlen = sizeof (addr);
441 if (stun_message_find_addr (&msg, 0xff05, &addr.st, &addrlen) !=
442 STUN_MESSAGE_RETURN_INVALID)
443 fatal ("Too big IPv4 address test failed");
444 addrlen = sizeof (addr);
445 if (stun_message_find_xor_addr (&msg, 0xff06, &addr.st, &addrlen) !=
446 STUN_MESSAGE_RETURN_SUCCESS ||
447 memcmp (&addr.s6.sin6_addr, "\x20\x01\x0d\xb8""\xde\xad\xbe\xef"
448 "\xde\xfa\xce\xd0""\xfa\xce\xde\xed", 16))
449 fatal ("IPv6 address test failed");
450
451 }
452
453 static const char vector_username[] = "evtj:h6vY";
454 static uint8_t vector_password[] = "VOkJxbRl1RmTxUk/WvJxBt";
455
test_vector_validater(StunAgent * agent,StunMessage * message,uint8_t * username,uint16_t username_len,uint8_t ** password,size_t * password_len,void * user_data)456 static bool test_vector_validater (StunAgent *agent,
457 StunMessage *message, uint8_t *username, uint16_t username_len,
458 uint8_t **password, size_t *password_len, void *user_data)
459 {
460 intptr_t callable = (intptr_t) user_data;
461
462 if (!callable)
463 fatal ("vector test : Validater should not be called!");
464
465 if (username_len != strlen (vector_username) ||
466 memcmp (username, vector_username, strlen (vector_username)) != 0)
467 fatal ("vector test : Validater received wrong username!");
468
469 *password = vector_password;
470 *password_len = strlen ((char *) vector_password);
471
472
473 return true;
474 }
475
test_vectors(void)476 static void test_vectors (void)
477 {
478 /* Request message */
479 static unsigned char req[] =
480 {0x00, 0x01, 0x00, 0x44,
481 0x21, 0x12, 0xa4, 0x42,
482 0xb7, 0xe7, 0xa7, 0x01,
483 0xbc, 0x34, 0xd6, 0x86,
484 0xfa, 0x87, 0xdf, 0xae,
485
486 0x00, 0x24, 0x00, 0x04, // PRIORITY
487 0x6e, 0x00, 0x01, 0xff,
488
489 0x80, 0x29, 0x00, 0x08, // ICE_CONTROLLED
490 0x93, 0x2f, 0xf9, 0xb1,
491 0x51, 0x26, 0x3b, 0x36,
492
493 0x00, 0x06, 0x00, 0x09, // USERNAME
494 0x65, 0x76, 0x74, 0x6a,
495 0x3a, 0x68, 0x36, 0x76,
496 0x59, 0x20, 0x20, 0x20,
497
498 0x00, 0x08, 0x00, 0x14, // MESSAGE_INTEGRITY
499 0x62, 0x4e, 0xeb, 0xdc,
500 0x3c, 0xc9, 0x2d, 0xd8,
501 0x4b, 0x74, 0xbf, 0x85,
502 0xd1, 0xc0, 0xf5, 0xde,
503 0x36, 0x87, 0xbd, 0x33,
504
505 0x80, 0x28, 0x00, 0x04, // FINGERPRINT
506 0xad, 0x8a, 0x85, 0xff};
507
508 static const unsigned char req2[] =
509 {0x00, 0x01, 0x00, 0x44,
510 0x21, 0x12, 0xa4, 0x42,
511 0xb7, 0xe7, 0xa7, 0x01,
512 0xbc, 0x34, 0xd6, 0x86,
513 0xfa, 0x87, 0xdf, 0xae,
514
515 0x00, 0x24, 0x00, 0x04, // PRIORITY
516 0x6e, 0x00, 0x01, 0xff,
517
518 0x80, 0x29, 0x00, 0x08, // ICE_CONTROLLED
519 0x93, 0x2f, 0xf9, 0xb1,
520 0x51, 0x26, 0x3b, 0x36,
521
522 0x00, 0x06, 0x00, 0x09, // USERNAME
523 0x65, 0x76, 0x74, 0x6a,
524 0x3a, 0x68, 0x36, 0x76,
525 0x59, 0x20, 0x20, 0x20,
526
527 0x00, 0x08, 0x00, 0x14, // MESSAGE_INTEGRITY
528 0x62, 0x4e, 0xeb, 0xdc,
529 0x3c, 0xc9, 0x2d, 0xd8,
530 0x4b, 0x74, 0xbf, 0x85,
531 0xd1, 0xc0, 0xf5, 0xde,
532 0x36, 0x87, 0xbd, 0x33,
533
534 0x80, 0x28, 0x00, 0x04, // FINGERPRINT
535 0xad, 0x8a, 0x85, 0xff};
536
537 /* Response message */
538 static const unsigned char respv4[] =
539 {0x01, 0x01, 0x00, 0x4c,
540 0x21, 0x12, 0xa4, 0x42,
541 0xb7, 0xe7, 0xa7, 0x01,
542 0xbc, 0x34, 0xd6, 0x86,
543 0xfa, 0x87, 0xdf, 0xae,
544
545 0x80, 0x22, 0x00, 0x0b, // SERVER
546 0x74, 0x65, 0x73, 0x74,
547 0x20, 0x76, 0x65, 0x63,
548 0x74, 0x6f, 0x72, 0x20,
549
550 0x00, 0x20, 0x00, 0x08, // XOR_MAPPED_ADDRESS
551 0x00, 0x01, 0xa1, 0x47,
552 0xe1, 0x12, 0xa6, 0x43,
553
554 0x00, 0x06, 0x00, 0x09, // USERNAME
555 0x65, 0x76, 0x74, 0x6a,
556 0x3a, 0x68, 0x36, 0x76,
557 0x59, 0x20, 0x20, 0x20,
558
559 0x00, 0x08, 0x00, 0x14, // MESSAGE_INTEGRITY
560 0x7d, 0xb7, 0xfc, 0x52,
561 0x70, 0xc6, 0xdb, 0x1f,
562 0xc3, 0x26, 0x34, 0xbb,
563 0x4c, 0x64, 0x6e, 0xe7,
564 0x1d, 0xb3, 0x78, 0x4a,
565
566 0x80, 0x28, 0x00, 0x04, // FINGERPRINT
567 0xf0, 0x60, 0x66, 0xa9};
568 static const unsigned char respv6[] =
569 {0x01, 0x01, 0x00, 0x58,
570 0x21, 0x12, 0xa4, 0x42,
571 0xb7, 0xe7, 0xa7, 0x01,
572 0xbc, 0x34, 0xd6, 0x86,
573 0xfa, 0x87, 0xdf, 0xae,
574
575 0x80, 0x22, 0x00, 0x0b, // SERVER
576 0x74, 0x65, 0x73, 0x74,
577 0x20, 0x76, 0x65, 0x63,
578 0x74, 0x6f, 0x72, 0x20,
579
580 0x00, 0x20, 0x00, 0x14, // XOR_MAPPED_ADDRESS
581 0x00, 0x02, 0xa1, 0x47,
582 0x01, 0x13, 0xa9, 0xfa,
583 0xa5, 0xd3, 0xf1, 0x79,
584 0xbc, 0x25, 0xf4, 0xb5,
585 0xbe, 0xd2, 0xb9, 0xd9,
586
587 0x00, 0x06, 0x00, 0x09, // USERNAME
588 0x65, 0x76, 0x74, 0x6a,
589 0x3a, 0x68, 0x36, 0x76,
590 0x59, 0x20, 0x20, 0x20,
591
592 0x00, 0x08, 0x00, 0x14, // MESSAGE_INTEGRITY
593 0x21, 0xcb, 0xbd, 0x25,
594 0x1a, 0x8c, 0x4c, 0x38,
595 0x8c, 0xc5, 0xcd, 0xb3,
596 0x27, 0x6a, 0xf5, 0x61,
597 0xb2, 0x21, 0xc8, 0x2b,
598
599 0x80, 0x28, 0x00, 0x04, // FINGERPRINT
600 0xec, 0x27, 0xae, 0xb7};
601 union {
602 struct sockaddr_storage st;
603 struct sockaddr_in ip4;
604 struct sockaddr_in6 ip6;
605 } addr;
606 socklen_t addrlen;
607
608 StunAgent agent;
609 StunMessage msg;
610 StunMessage msg2;
611 uint16_t known_attributes[] = {
612 STUN_ATTRIBUTE_MESSAGE_INTEGRITY,
613 STUN_ATTRIBUTE_USERNAME,
614 STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
615 STUN_ATTRIBUTE_PRIORITY, 0};
616
617 stun_agent_init (&agent, known_attributes,
618 STUN_COMPATIBILITY_RFC5389,
619 STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS |
620 STUN_AGENT_USAGE_USE_FINGERPRINT);
621
622 memset (&addr, 0, sizeof (addr));
623
624 puts ("Checking test vectors...");
625
626 if (stun_agent_validate (&agent, &msg2, req2, sizeof(req2),
627 test_vector_validater, (void *) 1) != STUN_VALIDATION_SUCCESS)
628 fatal ("Request test vector authentication failed");
629
630 if (stun_agent_validate (&agent, &msg, req, sizeof(req),
631 test_vector_validater, (void *) 1) != STUN_VALIDATION_SUCCESS)
632 fatal ("Request test vector authentication failed");
633
634 /* Remove the message-integrity and fingerprint attributes */
635 req[3] = 0x24;
636
637 if (stun_message_length (&msg) != sizeof(req) - 32)
638 fatal ("vector test: removing attributes failed");
639
640 stun_agent_finish_message (&agent, &msg, vector_password,
641 strlen ((char *) vector_password));
642
643 if (stun_message_length (&msg) != stun_message_length (&msg2) ||
644 memcmp (req, req2, sizeof(req)) != 0)
645 fatal ("vector test : req and req2 are different");
646
647 if (stun_agent_validate (&agent, &msg, respv4, sizeof(respv4),
648 test_vector_validater, (void *) 0) != STUN_VALIDATION_SUCCESS)
649 fatal ("Response ipv4 test vector authentication failed");
650
651 if (stun_agent_validate (&agent, &msg, respv4, sizeof(respv4),
652 test_vector_validater, (void *) 0) != STUN_VALIDATION_UNMATCHED_RESPONSE)
653 fatal ("Response ipv4 test vector authentication failed");
654
655 addrlen = sizeof (addr.ip4);
656 if (stun_message_find_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
657 &addr.st, &addrlen) != STUN_MESSAGE_RETURN_SUCCESS)
658 fatal ("Response test vector IPv4 extraction failed");
659 if (addr.ip4.sin_family != AF_INET)
660 fatal ("Response test vector IPv4 family failed");
661 if (ntohl (addr.ip4.sin_addr.s_addr) != 0xC0000201)
662 fatal ("Response test vector IPv4 address failed");
663 if (ntohs (addr.ip4.sin_port) != 32853)
664 fatal ("Response test vector IPv6 port failed");
665
666 if (stun_agent_validate (&agent, &msg, req, sizeof(req),
667 test_vector_validater, (void *) 1) != STUN_VALIDATION_SUCCESS)
668 fatal ("Request test vector second authentication failed");
669
670 /* Remove the fingerprint attributes */
671 msg.key = NULL;
672 msg.key_len = 0;
673 req[3] = 0x3C;
674
675 if (stun_message_length (&msg) != sizeof(req) - 8)
676 fatal ("vector test: removing attributes failed");
677
678 stun_agent_finish_message (&agent, &msg, NULL, 0);
679
680 if (stun_message_length (&msg) != stun_message_length (&msg2) ||
681 memcmp (req, req2, sizeof(req)) != 0)
682 fatal ("vector test : req and req2 are different");
683
684 if (stun_agent_validate (&agent, &msg, respv6, sizeof(respv6),
685 test_vector_validater, (void *) 1) != STUN_VALIDATION_SUCCESS)
686 fatal ("Response ipv6 test vector authentication failed");
687
688 addrlen = sizeof (addr.ip6);
689 if (stun_message_find_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
690 &addr.st, &addrlen) != STUN_MESSAGE_RETURN_SUCCESS)
691 fatal ("Response test vector IPv6 extraction failed");
692 if (addr.ip6.sin6_family != AF_INET6)
693 fatal ("Response test vector IPv6 family failed");
694 if (memcmp (addr.ip6.sin6_addr.s6_addr, "\x20\x01\x0d\xb8\x12\x34\x56\x78"
695 "\x00\x11\x22\x33\x44\x55\x66\x77", 16) != 0)
696 fatal ("Response test vector IPv6 address failed");
697 if (ntohs (addr.ip6.sin6_port) != 32853)
698 fatal ("Response test vector IPv6 port failed");
699
700
701 puts ("Done.");
702 }
703
test_hash_creds(void)704 static void test_hash_creds (void)
705 {
706 uint8_t md5[16];
707 uint8_t real_md5[] = {
708 0x84, 0x93, 0xfb, 0xc5,
709 0x3b, 0xa5, 0x82, 0xfb,
710 0x4c, 0x04, 0x4c, 0x45,
711 0x6b, 0xdc, 0x40, 0xeb};
712
713 puts ("Testing long term credentials hash algorithm...");
714
715
716 stun_hash_creds ((uint8_t *) "realm", strlen ("realm"),
717 (uint8_t *) "user", strlen ("user"),
718 (uint8_t *) "pass", strlen ("pass"), md5);
719
720 stun_debug_bytes ("key for user:realm:pass is : ", md5, 16);
721
722 stun_debug_bytes ("RFC key for user:realm:pass is : ", real_md5, 16);
723
724 if(memcmp (md5, real_md5, sizeof(md5)) != 0)
725 fatal ("MD5 hashes are different!");
726
727 puts ("Done!");
728
729 }
730
main(void)731 int main (void)
732 {
733 test_message ();
734 test_attribute ();
735 test_vectors ();
736 test_hash_creds ();
737 return 0;
738 }
739