2 * This file is part of the Nice GLib ICE library.
4 * (C) 2007 Nokia Corporation. All rights reserved.
5 * Contact: Rémi Denis-Courmont
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/
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
17 * The Original Code is the Nice GLib ICE library.
19 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20 * Corporation. All Rights Reserved.
23 * Rémi Denis-Courmont, Nokia
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.
40 #include "stun/stunagent.h"
41 #include "stun/stunhmac.h"
51 #include <sys/types.h>
52 #include <sys/socket.h>
53 #include <arpa/inet.h>
54 #include <netinet/in.h>
58 # define STUN_MAX_STR (763u)
59 # define STUN_MAX_CP (127u)
61 static void fatal (const char *msg
, ...)
65 vfprintf (stderr
, msg
, ap
);
72 static void validate (const uint8_t *msg
, unsigned len
)
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
);
82 while (i
++ < (len
+ 4));
86 /* Tests for generic message validation routines */
87 static void test_message (void)
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};
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};
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,
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,
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,
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};
214 uint16_t known_attributes
[] = {STUN_ATTRIBUTE_USERNAME
,
215 STUN_ATTRIBUTE_ERROR_CODE
,
216 STUN_ATTRIBUTE_MESSAGE_INTEGRITY
};
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};
230 StunDefaultValidaterData v
= {username_v
, 72, password_v
, 16};
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
);
238 stun_agent_validate (&agent2
, &msg
, req
, sizeof(req
), NULL
, NULL
);
239 stun_agent_finish_message (&agent2
, &msg
, NULL
, 0);
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");
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);
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");
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");
288 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
)
292 char *pwd
= (char *) user_data
;
294 if (username_len
!= 4 ||
295 memcmp (username
, "ABCD", 4) != 0)
299 *password_len
= strlen (pwd
);
304 /* Tests for message attribute parsing */
305 static void test_attribute (void)
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,
315 0xff, 0x01, 0x00, 0x00,
317 /* FF02: address of unknown family, 32-bits */
318 0xff, 0x02, 0x00, 0x04,
319 0x41, 0x42, 0x43, 0x44,
321 /* FF03: too short IPv6 address */
322 0xff, 0x03, 0x00, 0x06,
323 0x00, 0x02, 0x12, 0x34,
324 0x20, 0x01, 0x0d, 0xb8,
326 /* FF04: valid IPv4 address, 64-bits */
327 0xff, 0x04, 0x00, 0x08,
328 0x00, 0x01, 0x12, 0x34,
329 0xc0, 0x00, 0x02, 0x01,
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,
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,
345 /* dummy USERNAME header */
346 0x00, 0x06, 0x00, 0x04,
347 0x41, 0x42, 0x43, 0x44,
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};
360 struct sockaddr_in6 s6
;
365 char str
[STUN_MAX_STR
];
369 uint16_t known_attributes
[] = {STUN_ATTRIBUTE_MESSAGE_INTEGRITY
, STUN_ATTRIBUTE_USERNAME
, 0};
371 printf ("Attribute test message length: %lu\n", sizeof (acme
));
373 stun_agent_init (&agent
, known_attributes
,
374 STUN_COMPATIBILITY_RFC5389
, STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS
);
376 if (stun_agent_validate (&agent
, &msg
, acme
, sizeof(acme
),
377 NULL
, NULL
) != STUN_VALIDATION_UNAUTHORIZED
)
378 fatal ("Unauthorized validation failed");
380 if (stun_agent_validate (&agent
, &msg
, acme
, sizeof(acme
),
381 test_attribute_validater
, "bad__guy") != STUN_VALIDATION_UNAUTHORIZED
)
382 fatal ("invalid password validation failed");
384 if (stun_agent_validate (&agent
, &msg
, acme
, sizeof(acme
),
385 test_attribute_validater
, "good_guy") != STUN_VALIDATION_SUCCESS
)
386 fatal ("good password validation failed");
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");
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");
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");
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");
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");
424 addrlen
= sizeof (addr
);
425 if (stun_message_find_addr (&msg
, 0xff01, &addr
.sa
, &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
.sa
, &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
.sa
, &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
.sa
, &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
.sa
, &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
.sa
, &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");
453 static const char vector_username
[] = "evtj:h6vY";
454 static const char vector_password
[] = "VOkJxbRl1RmTxUk/WvJxBt";
456 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
)
460 intptr_t callable
= (intptr_t) user_data
;
463 fatal ("vector test : Validater should not be called!");
465 if (username_len
!= strlen (vector_username
) ||
466 memcmp (username
, vector_username
, strlen (vector_username
)) != 0)
467 fatal ("vector test : Validater received wrong username!");
469 *password
= (uint8_t *) vector_password
;
470 *password_len
= strlen (vector_password
);
476 static void test_vectors (void)
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,
486 0x00, 0x24, 0x00, 0x04, // PRIORITY
487 0x6e, 0x00, 0x01, 0xff,
489 0x80, 0x29, 0x00, 0x08, // ICE_CONTROLLED
490 0x93, 0x2f, 0xf9, 0xb1,
491 0x51, 0x26, 0x3b, 0x36,
493 0x00, 0x06, 0x00, 0x09, // USERNAME
494 0x65, 0x76, 0x74, 0x6a,
495 0x3a, 0x68, 0x36, 0x76,
496 0x59, 0x20, 0x20, 0x20,
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,
505 0x80, 0x28, 0x00, 0x04, // FINGERPRINT
506 0xad, 0x8a, 0x85, 0xff};
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,
515 0x00, 0x24, 0x00, 0x04, // PRIORITY
516 0x6e, 0x00, 0x01, 0xff,
518 0x80, 0x29, 0x00, 0x08, // ICE_CONTROLLED
519 0x93, 0x2f, 0xf9, 0xb1,
520 0x51, 0x26, 0x3b, 0x36,
522 0x00, 0x06, 0x00, 0x09, // USERNAME
523 0x65, 0x76, 0x74, 0x6a,
524 0x3a, 0x68, 0x36, 0x76,
525 0x59, 0x20, 0x20, 0x20,
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,
534 0x80, 0x28, 0x00, 0x04, // FINGERPRINT
535 0xad, 0x8a, 0x85, 0xff};
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,
545 0x80, 0x22, 0x00, 0x0b, // SERVER
546 0x74, 0x65, 0x73, 0x74,
547 0x20, 0x76, 0x65, 0x63,
548 0x74, 0x6f, 0x72, 0x20,
550 0x00, 0x20, 0x00, 0x08, // XOR_MAPPED_ADDRESS
551 0x00, 0x01, 0xa1, 0x47,
552 0xe1, 0x12, 0xa6, 0x43,
554 0x00, 0x06, 0x00, 0x09, // USERNAME
555 0x65, 0x76, 0x74, 0x6a,
556 0x3a, 0x68, 0x36, 0x76,
557 0x59, 0x20, 0x20, 0x20,
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,
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,
575 0x80, 0x22, 0x00, 0x0b, // SERVER
576 0x74, 0x65, 0x73, 0x74,
577 0x20, 0x76, 0x65, 0x63,
578 0x74, 0x6f, 0x72, 0x20,
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,
587 0x00, 0x06, 0x00, 0x09, // USERNAME
588 0x65, 0x76, 0x74, 0x6a,
589 0x3a, 0x68, 0x36, 0x76,
590 0x59, 0x20, 0x20, 0x20,
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,
599 0x80, 0x28, 0x00, 0x04, // FINGERPRINT
600 0xec, 0x27, 0xae, 0xb7};
601 struct sockaddr_in ip4
;
602 struct sockaddr_in6 ip6
;
608 uint16_t known_attributes
[] = {
609 STUN_ATTRIBUTE_MESSAGE_INTEGRITY
,
610 STUN_ATTRIBUTE_USERNAME
,
611 STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS
,
612 STUN_ATTRIBUTE_PRIORITY
, 0};
614 stun_agent_init (&agent
, known_attributes
,
615 STUN_COMPATIBILITY_RFC5389
,
616 STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS
|
617 STUN_AGENT_USAGE_USE_FINGERPRINT
);
619 memset (&ip4
, 0, sizeof (ip4
));
620 memset (&ip6
, 0, sizeof (ip6
));
622 puts ("Checking test vectors...");
624 if (stun_agent_validate (&agent
, &msg2
, req2
, sizeof(req2
),
625 test_vector_validater
, (void *) 1) != STUN_VALIDATION_SUCCESS
)
626 fatal ("Request test vector authentication failed");
628 if (stun_agent_validate (&agent
, &msg
, req
, sizeof(req
),
629 test_vector_validater
, (void *) 1) != STUN_VALIDATION_SUCCESS
)
630 fatal ("Request test vector authentication failed");
632 /* Remove the message-integrity and fingerprint attributes */
635 if (stun_message_length (&msg
) != sizeof(req
) - 32)
636 fatal ("vector test: removing attributes failed");
638 stun_agent_finish_message (&agent
, &msg
, vector_password
, strlen (vector_password
));
640 if (stun_message_length (&msg
) != stun_message_length (&msg2
) ||
641 memcmp (req
, req2
, sizeof(req
)) != 0)
642 fatal ("vector test : req and req2 are different");
644 if (stun_agent_validate (&agent
, &msg
, respv4
, sizeof(respv4
),
645 test_vector_validater
, (void *) 0) != STUN_VALIDATION_SUCCESS
)
646 fatal ("Response ipv4 test vector authentication failed");
648 if (stun_agent_validate (&agent
, &msg
, respv4
, sizeof(respv4
),
649 test_vector_validater
, (void *) 0) != STUN_VALIDATION_UNMATCHED_RESPONSE
)
650 fatal ("Response ipv4 test vector authentication failed");
652 addrlen
= sizeof (ip4
);
653 if (stun_message_find_xor_addr (&msg
, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS
,
654 (struct sockaddr
*)&ip4
, &addrlen
) != STUN_MESSAGE_RETURN_SUCCESS
)
655 fatal ("Response test vector IPv4 extraction failed");
656 if (ip4
.sin_family
!= AF_INET
)
657 fatal ("Response test vector IPv4 family failed");
658 if (ntohl (ip4
.sin_addr
.s_addr
) != 0xC0000201)
659 fatal ("Response test vector IPv4 address failed");
660 if (ntohs (ip4
.sin_port
) != 32853)
661 fatal ("Response test vector IPv6 port failed");
663 if (stun_agent_validate (&agent
, &msg
, req
, sizeof(req
),
664 test_vector_validater
, (void *) 1) != STUN_VALIDATION_SUCCESS
)
665 fatal ("Request test vector second authentication failed");
667 /* Remove the fingerprint attributes */
672 if (stun_message_length (&msg
) != sizeof(req
) - 8)
673 fatal ("vector test: removing attributes failed");
675 stun_agent_finish_message (&agent
, &msg
, NULL
, 0);
677 if (stun_message_length (&msg
) != stun_message_length (&msg2
) ||
678 memcmp (req
, req2
, sizeof(req
)) != 0)
679 fatal ("vector test : req and req2 are different");
681 if (stun_agent_validate (&agent
, &msg
, respv6
, sizeof(respv6
),
682 test_vector_validater
, (void *) 1) != STUN_VALIDATION_SUCCESS
)
683 fatal ("Response ipv6 test vector authentication failed");
685 addrlen
= sizeof (ip6
);
686 if (stun_message_find_xor_addr (&msg
, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS
,
687 (struct sockaddr
*)&ip6
, &addrlen
) != STUN_MESSAGE_RETURN_SUCCESS
)
688 fatal ("Response test vector IPv6 extraction failed");
689 if (ip6
.sin6_family
!= AF_INET6
)
690 fatal ("Response test vector IPv6 family failed");
691 if (memcmp (ip6
.sin6_addr
.s6_addr
, "\x20\x01\x0d\xb8\x12\x34\x56\x78"
692 "\x00\x11\x22\x33\x44\x55\x66\x77", 16) != 0)
693 fatal ("Response test vector IPv6 address failed");
694 if (ntohs (ip6
.sin6_port
) != 32853)
695 fatal ("Response test vector IPv6 port failed");
701 static void test_hash_creds (void)
704 uint8_t real_md5
[] = {
705 0x84, 0x93, 0xfb, 0xc5,
706 0x3b, 0xa5, 0x82, 0xfb,
707 0x4c, 0x04, 0x4c, 0x45,
708 0x6b, 0xdc, 0x40, 0xeb};
710 puts ("Testing long term credentials hash algorithm...");
713 stun_hash_creds ("realm", strlen ("realm"),
714 "user", strlen ("user"),
715 "pass", strlen ("pass"), md5
);
717 stun_debug ("key for user:realm:pass is : ");
718 stun_debug_bytes (md5
, 16);
721 stun_debug ("RFC key for user:realm:pass is : ");
722 stun_debug_bytes (real_md5
, 16);
725 if(memcmp (md5
, real_md5
, sizeof(md5
)) != 0)
726 fatal ("MD5 hashes are different!");