Imported Upstream version 0.1.17
[platform/upstream/libnice.git] / stun / tests / test-parse.c
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
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
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 */
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
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 */
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
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
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
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
731 int main (void)
732 {
733   test_message ();
734   test_attribute ();
735   test_vectors ();
736   test_hash_creds ();
737   return 0;
738 }