]>
Commit | Line | Data |
---|---|---|
c624081a | 1 | /* |
4e67f195 | 2 | * Copyright (C) 2013 Tobias Brunner |
c624081a MW |
3 | * Copyright (C) 2008 Martin Willi |
4 | * Hochschule fuer Technik Rapperswil | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License as published by the | |
8 | * Free Software Foundation; either version 2 of the License, or (at your | |
9 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, but | |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 | * for more details. | |
15 | */ | |
16 | ||
4e67f195 | 17 | |
95e99150 | 18 | #include "test_suite.h" |
4e67f195 TB |
19 | |
20 | #include <utils/chunk.h> | |
c624081a | 21 | |
c2dba63b TB |
22 | /******************************************************************************* |
23 | * utilities | |
24 | */ | |
25 | ||
26 | static void assert_chunk_empty(chunk_t chunk) | |
27 | { | |
28 | ck_assert(chunk.len == 0 && chunk.ptr == NULL); | |
29 | } | |
30 | ||
31 | /******************************************************************************* | |
32 | * equals | |
33 | */ | |
34 | ||
35 | START_TEST(test_chunk_equals) | |
36 | { | |
37 | chunk_t chunk = chunk_from_str("chunk"); | |
38 | chunk_t chunk_a, chunk_b; | |
39 | ||
40 | chunk_a = chunk_empty; | |
41 | chunk_b = chunk_empty; | |
42 | ck_assert(!chunk_equals(chunk_a, chunk_b)); | |
43 | ||
44 | chunk_a = chunk; | |
45 | ck_assert(!chunk_equals(chunk_a, chunk_b)); | |
46 | chunk_b = chunk; | |
47 | ck_assert(chunk_equals(chunk_a, chunk_b)); | |
48 | ||
49 | chunk_b = chunk_from_str("asdf"); | |
50 | ck_assert(!chunk_equals(chunk_a, chunk_b)); | |
51 | ||
52 | chunk_b = chunk_from_str("chunk"); | |
53 | ck_assert(chunk_equals(chunk_a, chunk_b)); | |
54 | } | |
55 | END_TEST | |
56 | ||
57 | /******************************************************************************* | |
58 | * chunk_compare test | |
59 | */ | |
60 | ||
61 | static struct { | |
62 | int result; | |
63 | chunk_t a; | |
64 | chunk_t b; | |
65 | } compare_data[] = { | |
66 | { 0, { NULL, 0 }, { NULL, 0 }}, | |
67 | { 0, chunk_from_chars(0x00), chunk_from_chars(0x00)}, | |
68 | {-1, chunk_from_chars(0x00), chunk_from_chars(0x01)}, | |
69 | { 1, chunk_from_chars(0x01), chunk_from_chars(0x00)}, | |
70 | { 0, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x00)}, | |
71 | {-1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x01)}, | |
72 | { 1, chunk_from_chars(0x00, 0x01), chunk_from_chars(0x00, 0x00)}, | |
73 | {-1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x01, 0x00)}, | |
74 | { 1, chunk_from_chars(0x01, 0x00), chunk_from_chars(0x00, 0x00)}, | |
75 | {-1, chunk_from_chars(0xff), chunk_from_chars(0x00, 0x00)}, | |
76 | { 1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0xff)}, | |
77 | }; | |
78 | ||
79 | START_TEST(test_compare) | |
80 | { | |
81 | int result, expected; | |
82 | ||
83 | result = chunk_compare(compare_data[_i].a, compare_data[_i].b); | |
84 | expected = compare_data[_i].result; | |
85 | ck_assert((result == 0 && expected == 0) || | |
86 | (result < 0 && expected < 0) || | |
87 | (result > 0 && expected > 0)); | |
88 | } | |
89 | END_TEST | |
90 | ||
91 | /******************************************************************************* | |
92 | * clear | |
93 | */ | |
94 | ||
95 | START_TEST(test_chunk_clear) | |
96 | { | |
97 | chunk_t chunk; | |
98 | u_char *ptr; | |
99 | int i; | |
44886a06 | 100 | bool cleared = TRUE; |
c2dba63b TB |
101 | |
102 | chunk = chunk_empty; | |
103 | chunk_clear(&chunk); | |
104 | chunk_free(&chunk); | |
105 | ||
106 | chunk = chunk_alloc(64); | |
107 | ptr = chunk.ptr; | |
108 | for (i = 0; i < 64; i++) | |
109 | { | |
110 | chunk.ptr[i] = i; | |
111 | } | |
112 | chunk_clear(&chunk); | |
44886a06 MW |
113 | /* check memory area of freed chunk. We can't use ck_assert() for this |
114 | * test directly, as it might allocate data at the freed area. */ | |
c2dba63b TB |
115 | for (i = 0; i < 64; i++) |
116 | { | |
44886a06 MW |
117 | if (ptr[i] != 0 && ptr[i] == i) |
118 | { | |
119 | cleared = FALSE; | |
120 | break; | |
121 | } | |
c2dba63b | 122 | } |
44886a06 MW |
123 | assert_chunk_empty(chunk); |
124 | ck_assert(cleared); | |
c2dba63b TB |
125 | } |
126 | END_TEST | |
127 | ||
128 | /******************************************************************************* | |
129 | * chunk_length | |
130 | */ | |
131 | ||
132 | START_TEST(test_chunk_length) | |
133 | { | |
134 | chunk_t a, b, c; | |
135 | size_t len; | |
136 | ||
137 | a = chunk_empty; | |
138 | b = chunk_empty; | |
139 | c = chunk_empty; | |
140 | len = chunk_length("ccc", a, b, c); | |
141 | ck_assert_int_eq(len, 0); | |
142 | ||
143 | a = chunk_from_str("foo"); | |
144 | b = chunk_from_str("bar"); | |
145 | len = chunk_length("ccc", a, b, c); | |
146 | ck_assert_int_eq(len, 6); | |
147 | ||
148 | len = chunk_length("zcc", a, b, c); | |
149 | ck_assert_int_eq(len, 0); | |
150 | ||
151 | len = chunk_length("czc", a, b, c); | |
152 | ck_assert_int_eq(len, 3); | |
153 | ||
154 | a = chunk_from_str("foo"); | |
155 | b = chunk_from_str("bar"); | |
156 | c = chunk_from_str("baz"); | |
157 | len = chunk_length("ccc", a, b, c); | |
158 | ck_assert_int_eq(len, 9); | |
159 | } | |
160 | END_TEST | |
161 | ||
162 | /******************************************************************************* | |
163 | * chunk_create_cat | |
164 | */ | |
165 | ||
166 | START_TEST(test_chunk_create_cat) | |
167 | { | |
168 | chunk_t foo, bar; | |
169 | chunk_t a, b, c; | |
170 | u_char *ptra, *ptrb; | |
171 | ||
172 | foo = chunk_from_str("foo"); | |
173 | bar = chunk_from_str("bar"); | |
174 | ||
175 | /* to simplify things we use the chunk_cata macro */ | |
176 | ||
177 | a = chunk_empty; | |
178 | b = chunk_empty; | |
179 | c = chunk_cata("cc", a, b); | |
180 | ck_assert_int_eq(c.len, 0); | |
181 | ck_assert(c.ptr != NULL); | |
182 | ||
183 | a = foo; | |
184 | b = bar; | |
185 | c = chunk_cata("cc", a, b); | |
186 | ck_assert_int_eq(c.len, 6); | |
187 | ck_assert(chunk_equals(c, chunk_from_str("foobar"))); | |
188 | ||
189 | a = chunk_clone(foo); | |
190 | b = chunk_clone(bar); | |
191 | c = chunk_cata("mm", a, b); | |
192 | ck_assert_int_eq(c.len, 6); | |
193 | ck_assert(chunk_equals(c, chunk_from_str("foobar"))); | |
194 | ||
195 | a = chunk_clone(foo); | |
196 | b = chunk_clone(bar); | |
197 | ptra = a.ptr; | |
198 | ptrb = b.ptr; | |
199 | c = chunk_cata("ss", a, b); | |
200 | ck_assert_int_eq(c.len, 6); | |
201 | ck_assert(chunk_equals(c, chunk_from_str("foobar"))); | |
202 | /* check memory area of cleared chunk */ | |
203 | ck_assert(!chunk_equals(foo, chunk_create(ptra, 3))); | |
204 | ck_assert(!chunk_equals(bar, chunk_create(ptrb, 3))); | |
205 | } | |
206 | END_TEST | |
207 | ||
208 | /******************************************************************************* | |
209 | * chunk_split | |
210 | */ | |
211 | ||
212 | static bool mem_in_chunk(u_char *ptr, chunk_t chunk) | |
213 | { | |
214 | return ptr >= chunk.ptr && ptr < (chunk.ptr + chunk.len); | |
215 | } | |
216 | ||
217 | START_TEST(test_chunk_split) | |
218 | { | |
219 | chunk_t foo, bar, foobar; | |
220 | chunk_t a, b, c; | |
221 | u_char *ptra, *ptrb; | |
222 | ||
223 | foo = chunk_from_str("foo"); | |
224 | bar = chunk_from_str("bar"); | |
225 | foobar = chunk_from_str("foobar"); | |
226 | ||
227 | chunk_split(foobar, "aa", 3, &a, 3, &b); | |
228 | ck_assert(chunk_equals(a, foo)); | |
229 | ck_assert(chunk_equals(b, bar)); | |
230 | ck_assert(!mem_in_chunk(a.ptr, foobar)); | |
231 | ck_assert(!mem_in_chunk(b.ptr, foobar)); | |
232 | chunk_free(&a); | |
233 | chunk_free(&b); | |
234 | ||
235 | chunk_split(foobar, "mm", 3, &a, 3, &b); | |
236 | ck_assert(chunk_equals(a, foo)); | |
237 | ck_assert(chunk_equals(b, bar)); | |
238 | ck_assert(mem_in_chunk(a.ptr, foobar)); | |
239 | ck_assert(mem_in_chunk(b.ptr, foobar)); | |
240 | ||
241 | chunk_split(foobar, "am", 3, &a, 3, &b); | |
242 | ck_assert(chunk_equals(a, foo)); | |
243 | ck_assert(chunk_equals(b, bar)); | |
244 | ck_assert(!mem_in_chunk(a.ptr, foobar)); | |
245 | ck_assert(mem_in_chunk(b.ptr, foobar)); | |
246 | chunk_free(&a); | |
247 | ||
248 | a = chunk_alloca(3); | |
249 | ptra = a.ptr; | |
250 | b = chunk_alloca(3); | |
251 | ptrb = b.ptr; | |
252 | chunk_split(foobar, "cc", 3, &a, 3, &b); | |
253 | ck_assert(chunk_equals(a, foo)); | |
254 | ck_assert(chunk_equals(b, bar)); | |
255 | ck_assert(a.ptr == ptra); | |
256 | ck_assert(b.ptr == ptrb); | |
257 | ||
258 | chunk_split(foobar, "mm", 1, NULL, 2, &a, 2, NULL, 1, &b); | |
259 | ck_assert(chunk_equals(a, chunk_from_str("oo"))); | |
260 | ck_assert(chunk_equals(b, chunk_from_str("r"))); | |
261 | ||
262 | chunk_split(foobar, "mm", 6, &a, 6, &b); | |
263 | ck_assert(chunk_equals(a, foobar)); | |
264 | assert_chunk_empty(b); | |
265 | ||
266 | chunk_split(foobar, "mac", 12, &a, 12, &b, 12, &c); | |
267 | ck_assert(chunk_equals(a, foobar)); | |
268 | assert_chunk_empty(b); | |
269 | assert_chunk_empty(c); | |
270 | } | |
271 | END_TEST | |
272 | ||
273 | /******************************************************************************* | |
274 | * chunk_skip[_zero] | |
275 | */ | |
276 | ||
277 | START_TEST(test_chunk_skip) | |
278 | { | |
279 | chunk_t foobar, a; | |
280 | ||
281 | foobar = chunk_from_str("foobar"); | |
282 | a = foobar; | |
283 | a = chunk_skip(a, 0); | |
284 | ck_assert(chunk_equals(a, foobar)); | |
285 | a = chunk_skip(a, 1); | |
286 | ck_assert(chunk_equals(a, chunk_from_str("oobar"))); | |
287 | a = chunk_skip(a, 2); | |
288 | ck_assert(chunk_equals(a, chunk_from_str("bar"))); | |
289 | a = chunk_skip(a, 3); | |
290 | assert_chunk_empty(a); | |
291 | ||
292 | a = foobar; | |
293 | a = chunk_skip(a, 6); | |
294 | assert_chunk_empty(a); | |
295 | ||
296 | a = foobar; | |
297 | a = chunk_skip(a, 10); | |
298 | assert_chunk_empty(a); | |
299 | } | |
300 | END_TEST | |
301 | ||
302 | START_TEST(test_chunk_skip_zero) | |
303 | { | |
304 | chunk_t foobar, a; | |
305 | ||
306 | a = chunk_empty; | |
307 | a = chunk_skip_zero(a); | |
308 | assert_chunk_empty(a); | |
309 | ||
310 | foobar = chunk_from_str("foobar"); | |
311 | a = foobar; | |
312 | a = chunk_skip_zero(a); | |
313 | ck_assert(chunk_equals(a, foobar)); | |
314 | ||
315 | a = chunk_from_chars(0x00, 0xaa, 0xbb, 0xcc); | |
316 | a = chunk_skip_zero(a); | |
317 | ck_assert(chunk_equals(a, chunk_from_chars(0xaa, 0xbb, 0xcc))); | |
318 | a = chunk_skip_zero(a); | |
319 | ck_assert(chunk_equals(a, chunk_from_chars(0xaa, 0xbb, 0xcc))); | |
320 | } | |
321 | END_TEST | |
322 | ||
323 | /******************************************************************************* | |
324 | * BASE16 encoding test | |
325 | */ | |
326 | ||
327 | START_TEST(test_base16) | |
328 | { | |
329 | /* test vectors from RFC 4648: | |
330 | * | |
331 | * BASE16("") = "" | |
332 | * BASE16("f") = "66" | |
333 | * BASE16("fo") = "666F" | |
334 | * BASE16("foo") = "666F6F" | |
335 | * BASE16("foob") = "666F6F62" | |
336 | * BASE16("fooba") = "666F6F6261" | |
337 | * BASE16("foobar") = "666F6F626172" | |
338 | */ | |
339 | typedef struct { | |
340 | bool upper; | |
341 | char *in; | |
342 | char *out; | |
343 | } testdata_t; | |
344 | ||
345 | testdata_t test[] = { | |
346 | {TRUE, "", ""}, | |
347 | {TRUE, "f", "66"}, | |
348 | {TRUE, "fo", "666F"}, | |
349 | {TRUE, "foo", "666F6F"}, | |
350 | {TRUE, "foob", "666F6F62"}, | |
351 | {TRUE, "fooba", "666F6F6261"}, | |
352 | {TRUE, "foobar", "666F6F626172"}, | |
353 | {FALSE, "", ""}, | |
354 | {FALSE, "f", "66"}, | |
355 | {FALSE, "fo", "666f"}, | |
356 | {FALSE, "foo", "666f6f"}, | |
357 | {FALSE, "foob", "666f6f62"}, | |
358 | {FALSE, "fooba", "666f6f6261"}, | |
359 | {FALSE, "foobar", "666f6f626172"}, | |
360 | }; | |
361 | testdata_t test_colon[] = { | |
362 | {TRUE, "", ""}, | |
363 | {TRUE, "f", "66"}, | |
364 | {TRUE, "fo", "66:6F"}, | |
365 | {TRUE, "foo", "66:6F:6F"}, | |
366 | {FALSE, "foob", "66:6f:6f:62"}, | |
367 | {FALSE, "fooba", "66:6f:6f:62:61"}, | |
368 | {FALSE, "foobar", "66:6f:6f:62:61:72"}, | |
369 | {FALSE, "foobar", "66:6f6f:6261:72"}, | |
370 | }; | |
371 | int i; | |
372 | ||
373 | for (i = 0; i < countof(test); i++) | |
374 | { | |
375 | chunk_t out; | |
376 | ||
377 | out = chunk_to_hex(chunk_create(test[i].in, strlen(test[i].in)), NULL, | |
378 | test[i].upper); | |
379 | ck_assert_str_eq(out.ptr, test[i].out); | |
380 | free(out.ptr); | |
381 | } | |
382 | ||
383 | for (i = 0; i < countof(test); i++) | |
384 | { | |
385 | chunk_t out; | |
386 | ||
387 | out = chunk_from_hex(chunk_create(test[i].out, strlen(test[i].out)), NULL); | |
388 | fail_unless(strneq(out.ptr, test[i].in, out.len), | |
389 | "base16 conversion error - should '%s', is %#B", | |
390 | test[i].in, &out); | |
391 | free(out.ptr); | |
392 | } | |
393 | ||
394 | for (i = 0; i < countof(test_colon); i++) | |
395 | { | |
396 | chunk_t out; | |
397 | ||
398 | out = chunk_from_hex(chunk_create(test_colon[i].out, strlen(test_colon[i].out)), NULL); | |
399 | fail_unless(strneq(out.ptr, test_colon[i].in, out.len), | |
400 | "base16 conversion error - should '%s', is %#B", | |
401 | test_colon[i].in, &out); | |
402 | free(out.ptr); | |
403 | } | |
404 | } | |
405 | END_TEST | |
406 | ||
c624081a | 407 | /******************************************************************************* |
4e67f195 TB |
408 | * BASE64 encoding test |
409 | */ | |
410 | ||
411 | START_TEST(test_base64) | |
c624081a | 412 | { |
c2dba63b | 413 | /* test vectors from RFC 4648: |
c624081a MW |
414 | * |
415 | * BASE64("") = "" | |
416 | * BASE64("f") = "Zg==" | |
417 | * BASE64("fo") = "Zm8=" | |
418 | * BASE64("foo") = "Zm9v" | |
419 | * BASE64("foob") = "Zm9vYg==" | |
420 | * BASE64("fooba") = "Zm9vYmE=" | |
421 | * BASE64("foobar") = "Zm9vYmFy" | |
422 | */ | |
c624081a MW |
423 | typedef struct { |
424 | char *in; | |
425 | char *out; | |
426 | } testdata_t; | |
7daf5226 | 427 | |
c624081a MW |
428 | testdata_t test[] = { |
429 | {"", ""}, | |
430 | {"f", "Zg=="}, | |
431 | {"fo", "Zm8="}, | |
432 | {"foo", "Zm9v"}, | |
433 | {"foob", "Zm9vYg=="}, | |
434 | {"fooba", "Zm9vYmE="}, | |
435 | {"foobar", "Zm9vYmFy"}, | |
436 | }; | |
437 | int i; | |
7daf5226 | 438 | |
c624081a MW |
439 | for (i = 0; i < countof(test); i++) |
440 | { | |
441 | chunk_t out; | |
7daf5226 | 442 | |
c624081a | 443 | out = chunk_to_base64(chunk_create(test[i].in, strlen(test[i].in)), NULL); |
4e67f195 | 444 | ck_assert_str_eq(out.ptr, test[i].out); |
c624081a MW |
445 | free(out.ptr); |
446 | } | |
7daf5226 | 447 | |
c624081a MW |
448 | for (i = 0; i < countof(test); i++) |
449 | { | |
450 | chunk_t out; | |
7daf5226 | 451 | |
c624081a | 452 | out = chunk_from_base64(chunk_create(test[i].out, strlen(test[i].out)), NULL); |
4e67f195 TB |
453 | fail_unless(strneq(out.ptr, test[i].in, out.len), |
454 | "base64 conversion error - should '%s', is %#B", | |
455 | test[i].in, &out); | |
c624081a MW |
456 | free(out.ptr); |
457 | } | |
c624081a | 458 | } |
4e67f195 TB |
459 | END_TEST |
460 | ||
c2dba63b TB |
461 | /******************************************************************************* |
462 | * BASE32 encoding test | |
463 | */ | |
464 | ||
465 | START_TEST(test_base32) | |
466 | { | |
467 | /* test vectors from RFC 4648: | |
468 | * | |
469 | * BASE32("") = "" | |
470 | * BASE32("f") = "MY======" | |
471 | * BASE32("fo") = "MZXQ====" | |
472 | * BASE32("foo") = "MZXW6===" | |
473 | * BASE32("foob") = "MZXW6YQ=" | |
474 | * BASE32("fooba") = "MZXW6YTB" | |
475 | * BASE32("foobar") = "MZXW6YTBOI======" | |
476 | */ | |
477 | typedef struct { | |
478 | char *in; | |
479 | char *out; | |
480 | } testdata_t; | |
481 | ||
482 | testdata_t test[] = { | |
483 | {"", ""}, | |
484 | {"f", "MY======"}, | |
485 | {"fo", "MZXQ===="}, | |
486 | {"foo", "MZXW6==="}, | |
487 | {"foob", "MZXW6YQ="}, | |
488 | {"fooba", "MZXW6YTB"}, | |
489 | {"foobar", "MZXW6YTBOI======"}, | |
490 | }; | |
491 | int i; | |
492 | ||
493 | for (i = 0; i < countof(test); i++) | |
494 | { | |
495 | chunk_t out; | |
496 | ||
497 | out = chunk_to_base32(chunk_create(test[i].in, strlen(test[i].in)), NULL); | |
498 | ck_assert_str_eq(out.ptr, test[i].out); | |
499 | free(out.ptr); | |
500 | } | |
501 | } | |
502 | END_TEST | |
503 | ||
504 | /******************************************************************************* | |
505 | * chunk_increment test | |
506 | */ | |
507 | ||
508 | static struct { | |
509 | bool overflow; | |
510 | chunk_t in; | |
511 | chunk_t out; | |
512 | } increment_data[] = { | |
513 | {TRUE, { NULL, 0 }, { NULL, 0 }}, | |
514 | {FALSE, chunk_from_chars(0x00), chunk_from_chars(0x01)}, | |
515 | {FALSE, chunk_from_chars(0xfe), chunk_from_chars(0xff)}, | |
516 | {TRUE, chunk_from_chars(0xff), chunk_from_chars(0x00)}, | |
517 | {FALSE, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x01)}, | |
518 | {FALSE, chunk_from_chars(0x00, 0xff), chunk_from_chars(0x01, 0x00)}, | |
519 | {FALSE, chunk_from_chars(0xfe, 0xff), chunk_from_chars(0xff, 0x00)}, | |
520 | {TRUE, chunk_from_chars(0xff, 0xff), chunk_from_chars(0x00, 0x00)}, | |
521 | }; | |
522 | ||
523 | START_TEST(test_increment) | |
524 | { | |
525 | chunk_t chunk; | |
526 | bool overflow; | |
527 | ||
528 | chunk = chunk_clonea(increment_data[_i].in); | |
529 | overflow = chunk_increment(chunk); | |
530 | ck_assert(overflow == increment_data[_i].overflow); | |
531 | ck_assert(!increment_data[_i].out.ptr || | |
532 | chunk_equals(chunk, increment_data[_i].out)); | |
533 | } | |
534 | END_TEST | |
535 | ||
536 | /******************************************************************************* | |
537 | * chunk_printable tests | |
538 | */ | |
539 | ||
540 | static struct { | |
541 | bool printable; | |
542 | chunk_t in; | |
543 | char *out; | |
544 | } printable_data[] = { | |
545 | {TRUE, chunk_from_chars(0x31), "1"}, | |
546 | {FALSE, chunk_from_chars(0x00), "?"}, | |
547 | {FALSE, chunk_from_chars(0x31, 0x00), "1?"}, | |
548 | {FALSE, chunk_from_chars(0x00, 0x31), "?1"}, | |
549 | {TRUE, chunk_from_chars(0x3f, 0x31), "?1"}, | |
550 | {FALSE, chunk_from_chars(0x00, 0x31, 0x00), "?1?"}, | |
551 | {FALSE, chunk_from_chars(0x00, 0x31, 0x00, 0x32), "?1?2"}, | |
552 | }; | |
553 | ||
554 | START_TEST(test_printable) | |
555 | { | |
556 | bool printable; | |
557 | ||
558 | printable = chunk_printable(printable_data[_i].in, NULL, ' '); | |
559 | ck_assert(printable == printable_data[_i].printable); | |
560 | } | |
561 | END_TEST | |
562 | ||
563 | START_TEST(test_printable_sanitize) | |
564 | { | |
565 | chunk_t sane, expected; | |
566 | bool printable; | |
567 | ||
568 | printable = chunk_printable(printable_data[_i].in, &sane, '?'); | |
569 | ck_assert(printable == printable_data[_i].printable); | |
570 | expected = chunk_from_str(printable_data[_i].out); | |
571 | ck_assert(chunk_equals(sane, expected)); | |
572 | chunk_free(&sane); | |
573 | } | |
574 | END_TEST | |
575 | ||
576 | START_TEST(test_printable_empty) | |
577 | { | |
578 | chunk_t sane; | |
579 | bool printable; | |
580 | ||
581 | printable = chunk_printable(chunk_empty, NULL, ' '); | |
582 | ck_assert(printable); | |
583 | ||
584 | sane.ptr = (void*)1; | |
585 | sane.len = 1; | |
586 | printable = chunk_printable(chunk_empty, &sane, ' '); | |
587 | ck_assert(printable); | |
588 | assert_chunk_empty(sane); | |
589 | } | |
590 | END_TEST | |
591 | ||
1255de5a TB |
592 | /******************************************************************************* |
593 | * test for chunk_mac(), i.e. SipHash-2-4 | |
594 | */ | |
595 | ||
596 | /** | |
597 | * SipHash-2-4 output with | |
598 | * k = 00 01 02 ... | |
599 | * and | |
600 | * in = (empty string) | |
601 | * in = 00 (1 byte) | |
602 | * in = 00 01 (2 bytes) | |
603 | * in = 00 01 02 (3 bytes) | |
604 | * ... | |
605 | * in = 00 01 02 ... 3e (63 bytes) | |
606 | */ | |
607 | static const u_char sip_vectors[64][8] = | |
608 | { | |
609 | { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, }, | |
610 | { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, }, | |
611 | { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, }, | |
612 | { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, }, | |
613 | { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, }, | |
614 | { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, }, | |
615 | { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, }, | |
616 | { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, }, | |
617 | { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, }, | |
618 | { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, }, | |
619 | { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, }, | |
620 | { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, }, | |
621 | { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, }, | |
622 | { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, }, | |
623 | { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, }, | |
624 | { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, }, | |
625 | { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, }, | |
626 | { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, }, | |
627 | { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, }, | |
628 | { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, }, | |
629 | { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, }, | |
630 | { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, }, | |
631 | { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, }, | |
632 | { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, }, | |
633 | { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, }, | |
634 | { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, }, | |
635 | { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, }, | |
636 | { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, }, | |
637 | { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, }, | |
638 | { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, }, | |
639 | { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, }, | |
640 | { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, }, | |
641 | { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, }, | |
642 | { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, }, | |
643 | { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, }, | |
644 | { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, }, | |
645 | { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, }, | |
646 | { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, }, | |
647 | { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, }, | |
648 | { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, }, | |
649 | { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, }, | |
650 | { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, }, | |
651 | { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, }, | |
652 | { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, }, | |
653 | { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, }, | |
654 | { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, }, | |
655 | { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, }, | |
656 | { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, }, | |
657 | { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, }, | |
658 | { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, }, | |
659 | { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, }, | |
660 | { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, }, | |
661 | { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, }, | |
662 | { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, }, | |
663 | { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, }, | |
664 | { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, }, | |
665 | { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, }, | |
666 | { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, }, | |
667 | { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, }, | |
668 | { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, }, | |
669 | { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, }, | |
670 | { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, }, | |
671 | { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, }, | |
672 | { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, } | |
673 | }; | |
674 | ||
675 | START_TEST(test_chunk_mac) | |
676 | { | |
677 | chunk_t in; | |
678 | u_char key[16]; | |
679 | u_int64_t out; | |
680 | int i, count; | |
681 | ||
682 | count = countof(sip_vectors); | |
683 | in = chunk_alloca(count); | |
684 | ||
685 | for (i = 0; i < 16; ++i) | |
686 | { | |
687 | key[i] = i; | |
688 | } | |
689 | ||
690 | for (i = 0; i < count; ++i) | |
691 | { | |
692 | in.ptr[i] = i; | |
693 | in.len = i; | |
694 | out = chunk_mac(in, key); | |
695 | fail_unless(memeq(&out, sip_vectors[i], 8), | |
696 | "test vector failed for %d bytes", i); | |
697 | } | |
698 | } | |
699 | END_TEST | |
700 | ||
c2dba63b TB |
701 | /******************************************************************************* |
702 | * test for chunk_hash[_inc]() | |
703 | */ | |
704 | ||
705 | START_TEST(test_chunk_hash) | |
706 | { | |
707 | chunk_t chunk; | |
708 | u_int32_t hash_a, hash_b, hash_c; | |
709 | ||
710 | chunk = chunk_from_str("asdf"); | |
711 | ||
712 | /* output is randomized, so there are no test-vectors we could use */ | |
713 | hash_a = chunk_hash(chunk); | |
714 | hash_b = chunk_hash(chunk); | |
715 | ck_assert(hash_a == hash_b); | |
716 | hash_b = chunk_hash_inc(chunk, hash_a); | |
717 | ck_assert(hash_a != hash_b); | |
718 | hash_c = chunk_hash_inc(chunk, hash_a); | |
719 | ck_assert(hash_b == hash_c); | |
720 | } | |
721 | END_TEST | |
722 | ||
ed235dbb TB |
723 | /******************************************************************************* |
724 | * test for chunk_hash_static[_inc]() | |
725 | */ | |
726 | ||
727 | START_TEST(test_chunk_hash_static) | |
728 | { | |
729 | chunk_t in; | |
730 | u_int32_t out, hash_a, hash_b, hash_inc = 0x7b891a95; | |
731 | int i, count; | |
732 | ||
733 | count = countof(sip_vectors); | |
734 | in = chunk_alloca(count); | |
735 | ||
736 | for (i = 0; i < count; ++i) | |
737 | { | |
738 | in.ptr[i] = i; | |
739 | in.len = i; | |
740 | /* compared to chunk_mac() we only get half the value back */ | |
741 | out = chunk_hash_static(in); | |
742 | fail_unless(memeq(&out, sip_vectors[i], 4), | |
743 | "test vector failed for %d bytes", i); | |
744 | } | |
745 | hash_a = chunk_hash_static_inc(in, out); | |
746 | ck_assert_int_eq(hash_a, hash_inc); | |
747 | hash_b = chunk_hash_static_inc(in, out); | |
748 | ck_assert_int_eq(hash_a, hash_b); | |
749 | } | |
750 | END_TEST | |
751 | ||
c2dba63b TB |
752 | /******************************************************************************* |
753 | * printf_hook tests | |
754 | */ | |
755 | ||
756 | static struct { | |
757 | chunk_t in; | |
758 | char *out; | |
f0c54e8c | 759 | char *out_plus; |
c2dba63b | 760 | } printf_hook_data[] = { |
f0c54e8c TB |
761 | {chunk_from_chars(), "", ""}, |
762 | {chunk_from_chars(0x00), "00", "00"}, | |
763 | {chunk_from_chars(0x00, 0x01), "00:01", "0001"}, | |
764 | {chunk_from_chars(0x00, 0x01, 0x02), "00:01:02", "000102"}, | |
c2dba63b TB |
765 | }; |
766 | ||
767 | START_TEST(test_printf_hook_hash) | |
768 | { | |
769 | char buf[16]; | |
770 | int len; | |
771 | ||
772 | len = snprintf(buf, sizeof(buf), "%#B", &printf_hook_data[_i].in); | |
773 | ck_assert(len >= 0 && len < sizeof(buf)); | |
774 | ck_assert_str_eq(buf, printf_hook_data[_i].out); | |
775 | } | |
776 | END_TEST | |
777 | ||
f0c54e8c TB |
778 | START_TEST(test_printf_hook_plus) |
779 | { | |
780 | char buf[16]; | |
781 | int len; | |
782 | ||
783 | len = snprintf(buf, sizeof(buf), "%+B", &printf_hook_data[_i].in); | |
784 | ck_assert(len >= 0 && len < sizeof(buf)); | |
785 | ck_assert_str_eq(buf, printf_hook_data[_i].out_plus); | |
786 | } | |
787 | END_TEST | |
788 | ||
c2dba63b TB |
789 | START_TEST(test_printf_hook) |
790 | { | |
791 | char buf[128], mem[128]; | |
792 | int len; | |
793 | ||
794 | /* %B should be the same as %b, which is what we check, comparing the | |
795 | * acutal result could be tricky as %b prints the chunk's memory address */ | |
796 | len = snprintf(buf, sizeof(buf), "%B", &printf_hook_data[_i].in); | |
797 | ck_assert(len >= 0 && len < sizeof(buf)); | |
798 | len = snprintf(mem, sizeof(mem), "%b", printf_hook_data[_i].in.ptr, | |
799 | (u_int)printf_hook_data[_i].in.len); | |
800 | ck_assert(len >= 0 && len < sizeof(mem)); | |
801 | ck_assert_str_eq(buf, mem); | |
802 | } | |
803 | END_TEST | |
804 | ||
4e67f195 TB |
805 | Suite *chunk_suite_create() |
806 | { | |
807 | Suite *s; | |
808 | TCase *tc; | |
c624081a | 809 | |
4e67f195 TB |
810 | s = suite_create("chunk"); |
811 | ||
c2dba63b TB |
812 | tc = tcase_create("equals"); |
813 | tcase_add_test(tc, test_chunk_equals); | |
814 | suite_add_tcase(s, tc); | |
815 | ||
816 | tc = tcase_create("chunk_compare"); | |
817 | tcase_add_loop_test(tc, test_compare, 0, countof(compare_data)); | |
818 | suite_add_tcase(s, tc); | |
819 | ||
820 | tc = tcase_create("clear"); | |
821 | tcase_add_test(tc, test_chunk_clear); | |
822 | suite_add_tcase(s, tc); | |
823 | ||
824 | tc = tcase_create("chunk_length"); | |
825 | tcase_add_test(tc, test_chunk_length); | |
826 | suite_add_tcase(s, tc); | |
827 | ||
828 | tc = tcase_create("chunk_create_cat"); | |
829 | tcase_add_test(tc, test_chunk_create_cat); | |
830 | suite_add_tcase(s, tc); | |
831 | ||
832 | tc = tcase_create("chunk_split"); | |
833 | tcase_add_test(tc, test_chunk_split); | |
834 | suite_add_tcase(s, tc); | |
835 | ||
836 | tc = tcase_create("chunk_skip"); | |
837 | tcase_add_test(tc, test_chunk_skip); | |
838 | tcase_add_test(tc, test_chunk_skip_zero); | |
839 | suite_add_tcase(s, tc); | |
840 | ||
841 | tc = tcase_create("chunk_increment"); | |
842 | tcase_add_loop_test(tc, test_increment, 0, countof(increment_data)); | |
843 | suite_add_tcase(s, tc); | |
844 | ||
845 | tc = tcase_create("chunk_printable"); | |
846 | tcase_add_loop_test(tc, test_printable, 0, countof(printable_data)); | |
847 | tcase_add_loop_test(tc, test_printable_sanitize, 0, countof(printable_data)); | |
848 | tcase_add_test(tc, test_printable_empty); | |
849 | suite_add_tcase(s, tc); | |
850 | ||
851 | tc = tcase_create("baseXX"); | |
4e67f195 | 852 | tcase_add_test(tc, test_base64); |
c2dba63b TB |
853 | tcase_add_test(tc, test_base32); |
854 | tcase_add_test(tc, test_base16); | |
4e67f195 TB |
855 | suite_add_tcase(s, tc); |
856 | ||
1255de5a TB |
857 | tc = tcase_create("chunk_mac"); |
858 | tcase_add_test(tc, test_chunk_mac); | |
859 | suite_add_tcase(s, tc); | |
860 | ||
c2dba63b TB |
861 | tc = tcase_create("chunk_hash"); |
862 | tcase_add_test(tc, test_chunk_hash); | |
863 | suite_add_tcase(s, tc); | |
864 | ||
ed235dbb TB |
865 | tc = tcase_create("chunk_hash_static"); |
866 | tcase_add_test(tc, test_chunk_hash_static); | |
867 | suite_add_tcase(s, tc); | |
868 | ||
c2dba63b TB |
869 | tc = tcase_create("printf_hook"); |
870 | tcase_add_loop_test(tc, test_printf_hook_hash, 0, countof(printf_hook_data)); | |
f0c54e8c | 871 | tcase_add_loop_test(tc, test_printf_hook_plus, 0, countof(printf_hook_data)); |
c2dba63b TB |
872 | tcase_add_loop_test(tc, test_printf_hook, 0, countof(printf_hook_data)); |
873 | suite_add_tcase(s, tc); | |
874 | ||
4e67f195 TB |
875 | return s; |
876 | } |