unit-tests: Move test suites to its own subfolder

This commit is contained in:
Martin Willi
2013-11-06 10:30:58 +01:00
parent c49c3f3208
commit 9ae1140118
20 changed files with 22 additions and 8 deletions
+360
View File
@@ -0,0 +1,360 @@
/*
* Copyright (C) 2013 Martin Willi
* Copyright (C) 2013 revosec AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <collections/array.h>
START_TEST(test_append_ptr)
{
array_t *array;
uintptr_t x;
int i;
array = array_create(0, 0);
for (i = 0; i < 4; i++)
{
ck_assert_int_eq(array_count(array), 0);
array_insert(array, ARRAY_HEAD, (void*)(uintptr_t)3);
array_insert(array, ARRAY_TAIL, (void*)(uintptr_t)4);
ck_assert_int_eq(array_count(array), 2);
/* 3, 4 */
array_insert(array, ARRAY_HEAD, (void*)(uintptr_t)1);
array_insert(array, 1, (void*)(uintptr_t)2);
ck_assert_int_eq(array_count(array), 4);
/* 1, 2, 3, 4 */
array_insert(array, ARRAY_TAIL, (void*)(uintptr_t)5);
array_insert(array, ARRAY_HEAD, (void*)(uintptr_t)0);
ck_assert_int_eq(array_count(array), 6);
/* 0, 1, 2, 3, 4, 5 */
ck_assert(array_remove(array, ARRAY_TAIL, &x));
ck_assert_int_eq(x, 5);
ck_assert(array_remove(array, 4, &x));
ck_assert_int_eq(x, 4);
if (i < 3)
{
array_compress(array);
}
/* 0, 1, 2, 3 */
ck_assert(array_remove(array, 1, &x));
ck_assert_int_eq(x, 1);
ck_assert(array_remove(array, ARRAY_HEAD, &x));
ck_assert_int_eq(x, 0);
if (i < 2)
{
array_compress(array);
}
/* 2, 3 */
ck_assert(array_remove(array, ARRAY_TAIL, &x));
ck_assert_int_eq(x, 3);
ck_assert(array_remove(array, ARRAY_TAIL, &x));
ck_assert_int_eq(x, 2);
if (i < 1)
{
array_compress(array);
}
ck_assert_int_eq(array_count(array), 0);
ck_assert(array_remove(array, ARRAY_HEAD, NULL) == FALSE);
ck_assert(array_remove(array, ARRAY_TAIL, NULL) == FALSE);
}
array_destroy(array);
}
END_TEST
START_TEST(test_append_obj)
{
array_t *array;
int i, x, y[6] = {0, 1, 2, 3, 4, 5};
array = array_create(sizeof(y[0]), 0);
for (i = 0; i < 4; i++)
{
ck_assert_int_eq(array_count(array), 0);
array_insert(array, ARRAY_HEAD, &y[3]);
array_insert(array, ARRAY_TAIL, &y[4]);
ck_assert_int_eq(array_count(array), 2);;
/* 3, 4 */
array_insert(array, ARRAY_HEAD, &y[1]);
array_insert(array, 1, &y[2]);
ck_assert_int_eq(array_count(array), 4);
/* 1, 2, 3, 4 */
array_insert(array, ARRAY_TAIL, &y[5]);
array_insert(array, ARRAY_HEAD, &y[0]);
ck_assert_int_eq(array_count(array), 6);
/* 0, 1, 2, 3, 4, 5 */
ck_assert(array_remove(array, ARRAY_TAIL, &x));
ck_assert_int_eq(x, 5);
ck_assert(array_remove(array, 4, &x));
ck_assert_int_eq(x, 4);
if (i < 3)
{
array_compress(array);
}
/* 0, 1, 2, 3 */
ck_assert(array_remove(array, ARRAY_HEAD, &x));
ck_assert_int_eq(x, 0);
ck_assert(array_remove(array, ARRAY_HEAD, &x));
ck_assert_int_eq(x, 1);
if (i < 2)
{
array_compress(array);
}
/* 2, 3 */
ck_assert(array_remove(array, ARRAY_TAIL, &x));
ck_assert_int_eq(x, 3);
ck_assert(array_remove(array, ARRAY_HEAD, &x));
ck_assert_int_eq(x, 2);
if (i < 1)
{
array_compress(array);
}
ck_assert_int_eq(array_count(array), 0);
ck_assert(array_remove(array, ARRAY_HEAD, NULL) == FALSE);
ck_assert(array_remove(array, ARRAY_TAIL, NULL) == FALSE);
}
array_destroy(array);
}
END_TEST
START_TEST(test_enumerate)
{
array_t *array;
int i, *x, y[6] = {0, 1, 2, 3, 4, 5};
enumerator_t *enumerator;
array = array_create(sizeof(y[0]), 0);
array_insert(array, ARRAY_TAIL, &y[0]);
array_insert(array, ARRAY_TAIL, &y[1]);
array_insert(array, ARRAY_TAIL, &y[2]);
array_insert(array, ARRAY_TAIL, &y[3]);
array_insert(array, ARRAY_TAIL, &y[4]);
array_insert(array, ARRAY_TAIL, &y[5]);
ck_assert_int_eq(array_count(array), 6);
/* 0, 1, 2, 3, 4, 5 */
i = 0;
enumerator = array_create_enumerator(array);
while (enumerator->enumerate(enumerator, &x))
{
ck_assert_int_eq(*x, y[i]);
i++;
}
enumerator->destroy(enumerator);
ck_assert_int_eq(i, 6);
i = 0;
enumerator = array_create_enumerator(array);
while (enumerator->enumerate(enumerator, &x))
{
ck_assert_int_eq(*x, y[i]);
if (i == 0 || i == 3 || i == 5)
{
array_remove_at(array, enumerator);
}
i++;
}
enumerator->destroy(enumerator);
ck_assert_int_eq(i, 6);
ck_assert_int_eq(array_count(array), 3);
/* 1, 2, 4 */
i = 0;
enumerator = array_create_enumerator(array);
while (enumerator->enumerate(enumerator, &x))
{
switch (i++)
{
case 0:
ck_assert_int_eq(*x, y[1]);
break;
case 1:
ck_assert_int_eq(*x, y[2]);
break;
case 2:
ck_assert_int_eq(*x, y[4]);
break;
default:
ck_assert(0);
}
}
enumerator->destroy(enumerator);
array_compress(array);
i = 0;
enumerator = array_create_enumerator(array);
while (enumerator->enumerate(enumerator, &x))
{
switch (i++)
{
case 0:
ck_assert_int_eq(*x, y[1]);
break;
case 1:
ck_assert_int_eq(*x, y[2]);
break;
case 2:
ck_assert_int_eq(*x, y[4]);
break;
default:
ck_assert(0);
}
}
enumerator->destroy(enumerator);
array_destroy(array);
}
END_TEST
static void invoke(void *data, int idx, void *user)
{
int *y = user, *x = data;
ck_assert(idx < 3);
ck_assert_int_eq(y[idx], *x);
y[idx] = 0;
}
START_TEST(test_invoke)
{
array_t *array;
int y[] = {1, 2, 3};
array = array_create(sizeof(y[0]), 0);
array_insert(array, ARRAY_TAIL, &y[0]);
array_insert(array, ARRAY_TAIL, &y[1]);
array_insert(array, ARRAY_TAIL, &y[2]);
array_invoke(array, invoke, y);
ck_assert_int_eq(y[0], 0);
ck_assert_int_eq(y[0], 0);
ck_assert_int_eq(y[0], 0);
array_destroy(array);
}
END_TEST
typedef struct obj_t obj_t;
struct obj_t {
void (*fun)(obj_t *obj);
int x;
int *counter;
};
static void fun(obj_t *obj)
{
ck_assert(obj->x == (*obj->counter)++);
}
START_TEST(test_invoke_offset)
{
array_t *array;
obj_t objs[5];
int i, counter = 0;
array = array_create(0, 0);
for (i = 0; i < countof(objs); i++)
{
objs[i].x = i;
objs[i].counter = &counter;
objs[i].fun = fun;
array_insert(array, ARRAY_TAIL, &objs[i]);
}
ck_assert_int_eq(countof(objs), array_count(array));
array_invoke_offset(array, offsetof(obj_t, fun));
ck_assert_int_eq(counter, countof(objs));
array_destroy(array);
}
END_TEST
Suite *array_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("array");
tc = tcase_create("add/remove ptr");
tcase_add_test(tc, test_append_ptr);
suite_add_tcase(s, tc);
tc = tcase_create("add/remove obj");
tcase_add_test(tc, test_append_obj);
suite_add_tcase(s, tc);
tc = tcase_create("enumerate");
tcase_add_test(tc, test_enumerate);
suite_add_tcase(s, tc);
tc = tcase_create("invoke");
tcase_add_test(tc, test_invoke);
suite_add_tcase(s, tc);
tc = tcase_create("invoke offset");
tcase_add_test(tc, test_invoke_offset);
suite_add_tcase(s, tc);
return s;
}
+840
View File
@@ -0,0 +1,840 @@
/*
* Copyright (C) 2013 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <asn1/asn1.h>
#include <asn1/oid.h>
#include <utils/chunk.h>
/*******************************************************************************
* algorithm_identifier
*/
START_TEST(test_asn1_algorithmIdentifier)
{
typedef struct {
int n;
chunk_t algid;
} testdata_t;
testdata_t test[] = {
{ OID_ECDSA_WITH_SHA1, chunk_from_chars(0x30, 0x09, 0x06, 0x07,
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01) },
{ OID_SHA1_WITH_RSA, chunk_from_chars(0x30, 0x0d, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00) },
};
chunk_t algid;
int i;
for (i = 0; i < countof(test); i++)
{
algid = asn1_algorithmIdentifier(test[i].n);
ck_assert(chunk_equals(algid, test[i].algid));
}
}
END_TEST
/*******************************************************************************
* parse_algorithm_identifier
*/
START_TEST(test_asn1_parse_algorithmIdentifier)
{
typedef struct {
int alg;
bool empty;
chunk_t parameters;
} testdata_t;
testdata_t test[] = {
{ OID_ECDSA_WITH_SHA1, TRUE, chunk_empty },
{ OID_SHA1_WITH_RSA, TRUE, chunk_from_chars(0x05, 0x00) },
{ OID_3DES_EDE_CBC, FALSE, chunk_from_chars(0x04, 0x01, 0xaa) },
{ OID_PBKDF2, FALSE, chunk_from_chars(0x30, 0x01, 0xaa) }
};
chunk_t algid, parameters;
int i, alg;
for (i = 0; i < countof(test); i++)
{
algid = asn1_wrap(ASN1_SEQUENCE, "mc",
asn1_build_known_oid(test[i].alg), test[i].parameters);
parameters = chunk_empty;
if (i == 2)
{
alg = asn1_parse_algorithmIdentifier(algid, 0, NULL);
}
else
{
alg = asn1_parse_algorithmIdentifier(algid, 0, &parameters);
if (test[i].empty)
{
ck_assert(parameters.len == 0 && parameters.ptr == NULL);
}
else
{
ck_assert(chunk_equals(parameters, test[i].parameters));
}
}
ck_assert(alg == test[i].alg);
chunk_free(&algid);
}
}
END_TEST
/*******************************************************************************
* known_oid
*/
START_TEST(test_asn1_known_oid)
{
typedef struct {
int n;
chunk_t oid;
} testdata_t;
testdata_t test[] = {
{ OID_UNKNOWN, chunk_empty },
{ OID_UNKNOWN, chunk_from_chars(0x55, 0x04, 0x02) },
{ OID_COUNTRY, chunk_from_chars(0x55, 0x04, 0x06) },
{ OID_STRONGSWAN, chunk_from_chars(0x2b, 0x06, 0x01, 0x04, 0x01,
0x82, 0xa0, 0x2a, 0x01) }
};
int i;
for (i = 0; i < countof(test); i++)
{
ck_assert(asn1_known_oid(test[i].oid) == test[i].n);
}
}
END_TEST
/*******************************************************************************
* build_known_oid
*/
START_TEST(test_asn1_build_known_oid)
{
typedef struct {
int n;
chunk_t oid;
} testdata_t;
testdata_t test[] = {
{ OID_UNKNOWN, chunk_empty },
{ OID_MAX, chunk_empty },
{ OID_COUNTRY, chunk_from_chars(0x06, 0x03, 0x55, 0x04, 0x06) },
{ OID_STRONGSWAN, chunk_from_chars(0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
0x01, 0x82, 0xa0, 0x2a, 0x01) }
};
int i;
chunk_t oid = chunk_empty;
for (i = 0; i < countof(test); i++)
{
oid = asn1_build_known_oid(test[i].n);
if (test[i].oid.len == 0)
{
ck_assert(oid.len == 0 && oid.ptr == NULL);
}
else
{
ck_assert(chunk_equals(oid, test[i].oid));
chunk_free(&oid);
}
}
}
END_TEST
/*******************************************************************************
* oid_from_string
*/
START_TEST(test_asn1_oid_from_string)
{
typedef struct {
char *string;
chunk_t oid;
} testdata_t;
testdata_t test[] = {
{ "", chunk_empty },
{ " ", chunk_empty },
{ "0.2.262.1", chunk_from_chars(
0x02, 0x82, 0x06, 0x01) },
{ "1.2.840.10045.4.1", chunk_from_chars(
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01) },
{ "1.3.6.1.4.1.36906.1", chunk_from_chars(
0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa0, 0x2a, 0x01) },
{ "2.16.840.1.101.3.4.2.1", chunk_from_chars(
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01) },
{ "0.10.100.1000.10000.100000.1000000.10000000.100000000.268435455",
chunk_from_chars(0x0a,0x64, 0x87, 0x68, 0xce, 0x10, 0x86, 0x8d,
0x20, 0xbd, 0x84, 0x40, 0x84, 0xe2, 0xad, 0x00,
0xaf, 0xd7, 0xc2, 0x00, 0xff, 0xff, 0xff, 0x7f) },
{ "0.1.2.3.4.5.6.7.8.9.10.128.129.130.131.132.133.134.135.136.137."
"256.257.258.259.260.261.262.263.264.265.384.385.386.387.388."
"2097153", chunk_from_chars(
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x81, 0x00, 0x81, 0x01, 0x81, 0x02, 0x81, 0x03, 0x81, 0x04,
0x81, 0x05, 0x81, 0x06, 0x81, 0x07, 0x81, 0x08, 0x81, 0x09,
0x82, 0x00, 0x82, 0x01, 0x82, 0x02, 0x82, 0x03, 0x82, 0x04,
0x82, 0x05, 0x82, 0x06, 0x82, 0x07, 0x82, 0x08, 0x82, 0x09,
0x83, 0x00, 0x83, 0x01, 0x83, 0x02, 0x83, 0x03, 0x83, 0x04,
0x81, 0x80, 0x80, 0x01) },
{ "0.1.2.3.4.5.6.7.8.9.10.128.129.130.131.132.133.134.135.136.137."
"256.257.258.259.260.261.262.263.264.265.384.385.386.387.388."
"1.2097153", chunk_empty },
{ "1.a.2.b.3", chunk_empty }
};
int i;
chunk_t oid = chunk_empty;
for (i = 0; i < countof(test); i++)
{
oid = asn1_oid_from_string(test[i].string);
if (test[i].oid.len == 0)
{
ck_assert(oid.len == 0 && oid.ptr == NULL);
}
else
{
ck_assert(chunk_equals(oid, test[i].oid));
chunk_free(&oid);
}
}
}
END_TEST
/*******************************************************************************
* oid_to_string
*/
START_TEST(test_asn1_oid_to_string)
{
typedef struct {
char *string;
chunk_t oid;
} testdata_t;
testdata_t test[] = {
{ NULL, chunk_empty },
{ "0.2.262.1", chunk_from_chars(
0x02, 0x82, 0x06, 0x01) },
{ "1.2.840.10045.4.1", chunk_from_chars(
0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01) },
{ "1.3.6.1.4.1.36906.1", chunk_from_chars(
0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa0, 0x2a, 0x01) },
{ "2.16.840.1.101.3.4.2.1", chunk_from_chars(
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01) },
{ "0.10.100.1000.10000.100000.1000000.10000000.100000000.268435455",
chunk_from_chars( 0x0a, 0x64, 0x87, 0x68, 0xce, 0x10, 0x86, 0x8d,
0x20, 0xbd, 0x84, 0x40, 0x84, 0xe2, 0xad, 0x00,
0xaf, 0xd7, 0xc2, 0x00, 0xff, 0xff, 0xff, 0x7f) },
{ NULL, chunk_from_chars(
0x0a, 0x02, 0x64, 0x87, 0x68, 0xce, 0x10, 0x86, 0x8d, 0x20,
0xbd, 0x84, 0x40, 0x84, 0xe2, 0xad, 0x00, 0xaf, 0xd7, 0xc2, 0x00,
0xff, 0xff, 0xff, 0x7f) },
{ NULL, chunk_from_chars(0x0a, 0x87) }
};
int i;
char *string = NULL;
for (i = 0; i < countof(test); i++)
{
string = asn1_oid_to_string(test[i].oid);
if (test[i].string == NULL)
{
ck_assert(string == NULL);
}
else
{
ck_assert(streq(string, test[i].string));
free(string);
}
}
}
END_TEST
/*******************************************************************************
* length
*/
START_TEST(test_asn1_length)
{
chunk_t a;
a = chunk_empty;
ck_assert(asn1_length(&a) == ASN1_INVALID_LENGTH);
a = chunk_from_chars(0x04);
ck_assert(asn1_length(&a) == ASN1_INVALID_LENGTH);
a = chunk_from_chars(0x04, 0x00);
ck_assert(asn1_length(&a) == 0);
a = chunk_from_chars(0x04, 0x01);
ck_assert(asn1_length(&a) == ASN1_INVALID_LENGTH);
a = chunk_from_chars(0x04, 0x01, 0xaa);
ck_assert(asn1_length(&a) == 1);
a = chunk_from_chars(0x04, 0x7f, 0xaa);
a.len = 2 + 127;
ck_assert(asn1_length(&a) == 127);
a = chunk_from_chars(0x04, 0x80, 0xaa);
a.len = 2 + 128;
ck_assert(asn1_length(&a) == ASN1_INVALID_LENGTH);
a = chunk_from_chars(0x04, 0x81);
ck_assert(asn1_length(&a) == ASN1_INVALID_LENGTH);
a = chunk_from_chars(0x04, 0x81, 0x80, 0xaa);
ck_assert(asn1_length(&a) == ASN1_INVALID_LENGTH);
a = chunk_from_chars(0x04, 0x81, 0x80, 0xaa);
a.len = 3 + 128;
ck_assert(asn1_length(&a) == 128);
a = chunk_from_chars(0x04, 0x82, 0x01, 0x02, 0xaa);
a.len = 4 + 258;
ck_assert(asn1_length(&a) == 258);
a = chunk_from_chars(0x04, 0x83, 0x01, 0x02, 0x03, 0xaa);
a.len = 5 + 66051;
ck_assert(asn1_length(&a) == 66051);
}
END_TEST
/*******************************************************************************
* unwrap
*/
START_TEST(test_asn1_unwrap)
{
chunk_t c0 = chunk_from_chars(0x30);
chunk_t c1 = chunk_from_chars(0x30, 0x01, 0xaa);
chunk_t c2 = chunk_from_chars(0x30, 0x80);
chunk_t c3 = chunk_from_chars(0x30, 0x81);
chunk_t c4 = chunk_from_chars(0x30, 0x81, 0x01, 0xaa);
chunk_t c5 = chunk_from_chars(0x30, 0x81, 0x02, 0xaa);
chunk_t inner;
chunk_t inner_ref = chunk_from_chars(0xaa);
ck_assert(asn1_unwrap(&c0, &inner) == ASN1_INVALID);
ck_assert(asn1_unwrap(&c1, &inner) == ASN1_SEQUENCE);
ck_assert(chunk_equals(inner, inner_ref));
ck_assert(asn1_unwrap(&c2, &inner) == ASN1_INVALID);
ck_assert(asn1_unwrap(&c3, &inner) == ASN1_INVALID);
ck_assert(asn1_unwrap(&c4, &inner) == ASN1_SEQUENCE);
ck_assert(chunk_equals(inner, inner_ref));
ck_assert(asn1_unwrap(&c5, &inner) == ASN1_INVALID);
}
END_TEST
/*******************************************************************************
* is_asn1
*/
START_TEST(test_is_asn1)
{
typedef struct {
bool asn1;
chunk_t chunk;
} testdata_t;
u_char buf[8];
chunk_t chunk_zero = { buf, 0 };
chunk_t chunk_mean = { 0, 1 };
testdata_t test[] = {
{ FALSE, chunk_zero },
{ FALSE, chunk_empty },
{ FALSE, chunk_mean },
{ TRUE, chunk_from_chars(0x30, 0x00) },
{ TRUE, chunk_from_chars(0x31, 0x00) },
{ TRUE, chunk_from_chars(0x04, 0x00) },
{ FALSE, chunk_from_chars(0x02, 0x00) },
{ FALSE, chunk_from_chars(0x30, 0x01) },
{ FALSE, chunk_from_chars(0x30, 0x80) },
{ TRUE, chunk_from_chars(0x30, 0x01, 0xa1) },
{ FALSE, chunk_from_chars(0x30, 0x01, 0xa1, 0xa2) },
{ TRUE, chunk_from_chars(0x30, 0x01, 0xa1, 0x0a) },
{ FALSE, chunk_from_chars(0x30, 0x01, 0xa1, 0xa2, 0x0a) },
};
int i;
for (i = 0; i < countof(test); i++)
{
ck_assert(is_asn1(test[i].chunk) == test[i].asn1);
}
}
END_TEST
/*******************************************************************************
* is_printablestring
*/
START_TEST(test_asn1_is_printablestring)
{
typedef struct {
bool printable;
char *string;
} testdata_t;
testdata_t test[] = {
{ TRUE, "" },
{ TRUE, "Z" },
{ FALSE, "Z#" },
{ FALSE, "&Z" },
{ FALSE, "Z@z" },
{ FALSE, "!" }, { FALSE, "*" }, { FALSE, "$" }, { FALSE, "%" },
{ FALSE, "[" }, { FALSE, "]" }, { FALSE, "{" }, { FALSE, "}" },
{ FALSE, "|" }, { FALSE, "~" }, { FALSE, "^" }, { FALSE, "_" },
{ FALSE, "\"" }, { FALSE, "\\" }, { FALSE, "ä" }, { FALSE, "à" },
{ TRUE, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
"0123456789 '()+,-./:=?" },
};
chunk_t chunk;
int i;
ck_assert(asn1_is_printablestring(chunk_empty));
for (i = 0; i < countof(test); i++)
{
chunk = chunk_from_str(test[i].string);
ck_assert(asn1_is_printablestring(chunk) == test[i].printable);
}
}
END_TEST
/*******************************************************************************
* to_time
*/
START_TEST(test_asn1_to_time)
{
typedef struct {
time_t time;
u_int8_t type;
char *string;
} testdata_t;
testdata_t test[] = {
{ 352980, 0x18, "197001050203Z" },
{ 352984, 0x18, "19700105020304Z" },
{ 352980, 0x17, "7001050203Z" },
{ 347580, 0x17, "7001050203+0130" },
{ 358380, 0x17, "7001050203-0130" },
{ 352984, 0x17, "700105020304Z" },
{ 347584, 0x17, "700105020304+0130" },
{ 358384, 0x17, "700105020304-0130" },
{ 0, 0x17, "700105020304+01" },
{ 0, 0x17, "700105020304-01" },
{ 0, 0x17, "700105020304" },
{ 0, 0x17, "70010502Z" },
{ 0, 0x17, "7001050203xxZ" },
{ 0, 0x17, "7000050203Z" },
{ 0, 0x17, "7013050203Z" },
{ 5097600, 0x17, "7003010000Z" },
{ 68256000, 0x17, "7203010000Z" },
{ 951868800, 0x17, "0003010000Z" },
{ 4107542400, 0x18, "210003010000Z" }
};
int i;
chunk_t chunk;
for (i = 0; i < countof(test); i++)
{
if (test[i].time > TIME_32_BIT_SIGNED_MAX && sizeof(time_t) == 4)
{
continue;
}
chunk = chunk_from_str(test[i].string);
ck_assert(asn1_to_time(&chunk, test[i].type) == test[i].time);
}
}
END_TEST
/*******************************************************************************
* from_time
*/
START_TEST(test_asn1_from_time)
{
typedef struct {
time_t time;
u_int8_t type;
chunk_t chunk;
} testdata_t;
testdata_t test[] = {
{ 352984, 0x18, chunk_from_chars(
0x18, 0x0f, 0x31, 0x39, 0x37, 0x30, 0x30, 0x31, 0x30, 0x35,
0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x5a) },
{ 352984, 0x17, chunk_from_chars(
0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30, 0x35,
0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x5a) },
{ 1078099200, 0x17, chunk_from_chars(
0x17, 0x0d, 0x30, 0x34, 0x30, 0x33, 0x30, 0x31,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a) },
{ 4107542400, 0x18, chunk_from_chars(
0x18, 0x0f, 0x32, 0x31, 0x30, 0x30, 0x30, 0x33, 0x30, 0x31,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a) }
};
int i;
chunk_t chunk;
for (i = 0; i < countof(test); i++)
{
if (test[i].time > TIME_32_BIT_SIGNED_MAX && sizeof(time_t) == 4)
{
continue;
}
chunk = asn1_from_time(&test[i].time, test[i].type);
ck_assert(chunk_equals(chunk, test[i].chunk));
}
}
END_TEST
/*******************************************************************************
* parse_time
*/
START_TEST(test_asn1_parse_time)
{
typedef struct {
time_t time;
chunk_t chunk;
} testdata_t;
testdata_t test[] = {
{ 352984, chunk_from_chars(
0x18, 0x0f, 0x31, 0x39, 0x37, 0x30, 0x30, 0x31, 0x30, 0x35,
0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x5a) },
{ 352984, chunk_from_chars(
0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30, 0x35,
0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x5a) },
{ 0, chunk_from_chars(0x05, 0x00) }
};
int i;
for (i = 0; i < countof(test); i++)
{
ck_assert(asn1_parse_time(test[i].chunk, 0) == test[i].time);
}
}
END_TEST
/*******************************************************************************
* build_object
*/
START_TEST(test_asn1_build_object)
{
typedef struct {
size_t len;
size_t size;
u_char *b;
} testdata_t;
u_char b0[] = { 0x05, 0x00 };
u_char b1[] = { 0x04, 0x7f };
u_char b2[] = { 0x04, 0x81, 0x80 };
u_char b3[] = { 0x04, 0x81, 0xff };
u_char b4[] = { 0x04, 0x82, 0x01, 0x00 };
u_char b5[] = { 0x04, 0x82, 0xff, 0xff };
u_char b6[] = { 0x04, 0x83, 0x01, 0x00, 0x00 };
testdata_t test[] = {
{ 0, sizeof(b0), b0 },
{ 127, sizeof(b1), b1 },
{ 128, sizeof(b2), b2 },
{ 255, sizeof(b3), b3 },
{ 256, sizeof(b4), b4 },
{ 65535, sizeof(b5), b5 },
{ 65536, sizeof(b6), b6 }
};
chunk_t a = chunk_empty;
u_char *pos;
int i;
for (i = 0; i < countof(test); i++)
{
pos = asn1_build_object(&a, test[i].b[0], test[i].len);
ck_assert(pos == (a.ptr + test[i].size));
ck_assert(a.len == test[i].size + test[i].len);
ck_assert(memeq(a.ptr, test[i].b, test[i].size));
chunk_free(&a);
}
}
END_TEST
/*******************************************************************************
* simple_object
*/
START_TEST(test_asn1_simple_object)
{
chunk_t a = chunk_empty;
chunk_t b = chunk_from_chars(0x04, 0x05, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5);
chunk_t c = chunk_from_chars(0xa1, 0xa2, 0xa3, 0xa4, 0xa5);
a = asn1_simple_object(0x04, c);
ck_assert(chunk_equals(a, b));
chunk_free(&a);
}
END_TEST
/*******************************************************************************
* parse_simple_object
*/
START_TEST(test_asn1_parse_simple_object)
{
typedef struct {
bool res;
int type;
chunk_t chunk;
} testdata_t;
testdata_t test[] = {
{ FALSE, 0x04, chunk_from_chars(0x04) },
{ FALSE, 0x04, chunk_from_chars(0x02, 0x01, 0x55) },
{ FALSE, 0x04, chunk_from_chars(0x04, 0x01) },
{ TRUE, 0x04, chunk_from_chars(0x04, 0x01, 0x55) },
{ TRUE, 0x06, chunk_from_chars(0x06, 0x02, 0x55, 0x03) },
{ TRUE, 0x06, chunk_from_chars(0x06, 0x00) },
{ TRUE, 0x13, chunk_from_chars(0x13, 0x01, 0x55), }
};
int i;
bool res;
for (i = 0; i < countof(test); i++)
{
res = asn1_parse_simple_object(&test[i].chunk, test[i].type, 0, "test");
ck_assert(res == test[i].res);
if (res && test[i].chunk.len)
{
ck_assert(*test[i].chunk.ptr == 0x55);
}
}
}
END_TEST
/*******************************************************************************
* bitstring
*/
START_TEST(test_asn1_bitstring)
{
chunk_t a = chunk_empty;
chunk_t b = chunk_from_chars(0x03, 0x05, 0x00, 0xa1, 0xa2, 0xa3, 0xa4);
chunk_t c = chunk_from_chars(0xa1, 0xa2, 0xa3, 0xa4);
chunk_t d = chunk_clone(c);
a = asn1_bitstring("c", c);
ck_assert(chunk_equals(a, b));
chunk_free(&a);
a = asn1_bitstring("m", d);
ck_assert(chunk_equals(a, b));
chunk_free(&a);
}
END_TEST
/*******************************************************************************
* integer
*/
START_TEST(test_asn1_integer)
{
typedef struct {
chunk_t b;
chunk_t c;
} testdata_t;
chunk_t b0 = chunk_from_chars(0x02, 0x01, 0x00);
chunk_t b1 = chunk_from_chars(0x02, 0x01, 0x7f);
chunk_t b2 = chunk_from_chars(0x02, 0x02, 0x00, 0x80);
chunk_t c0 = chunk_empty;
chunk_t c1 = chunk_from_chars(0x7f);
chunk_t c2 = chunk_from_chars(0x80);
chunk_t c3 = chunk_from_chars(0x00, 0x80);
testdata_t test[] = {
{ b0, c0 },
{ b1, c1 },
{ b2, c2 },
{ b2, c3 }
};
chunk_t a = chunk_empty;
int i;
for (i = 0; i < countof(test); i++)
{
a = asn1_integer("c", test[i].c);
ck_assert(chunk_equals(a, test[i].b));
chunk_free(&a);
a = asn1_integer("m", chunk_clone(test[i].c));
ck_assert(chunk_equals(a, test[i].b));
chunk_free(&a);
}
}
END_TEST
/*******************************************************************************
* parse_integer_uint64
*/
START_TEST(test_asn1_parse_integer_uint64)
{
typedef struct {
u_int64_t n;
chunk_t chunk;
} testdata_t;
testdata_t test[] = {
{ 67305985ULL, chunk_from_chars(
0x04, 0x03, 0x02, 0x01) },
{ 578437695752307201ULL, chunk_from_chars(
0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01) },
{ 18446744073709551615ULL, chunk_from_chars(
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff) }
};
int i;
for (i = 0; i < countof(test); i++)
{
ck_assert(asn1_parse_integer_uint64(test[i].chunk) == test[i].n);
}
}
END_TEST
Suite *asn1_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("asn1");
tc = tcase_create("algorithmIdentifier");
tcase_add_test(tc, test_asn1_algorithmIdentifier);
suite_add_tcase(s, tc);
tc = tcase_create("parse_algorithmIdentifier");
tcase_add_test(tc, test_asn1_parse_algorithmIdentifier);
suite_add_tcase(s, tc);
tc = tcase_create("known_oid");
tcase_add_test(tc, test_asn1_known_oid);
suite_add_tcase(s, tc);
tc = tcase_create("build_known_oid");
tcase_add_test(tc, test_asn1_build_known_oid);
suite_add_tcase(s, tc);
tc = tcase_create("oid_from_string");
tcase_add_test(tc, test_asn1_oid_from_string);
suite_add_tcase(s, tc);
tc = tcase_create("oid_to_string");
tcase_add_test(tc, test_asn1_oid_to_string);
suite_add_tcase(s, tc);
tc = tcase_create("length");
tcase_add_test(tc, test_asn1_length);
suite_add_tcase(s, tc);
tc = tcase_create("unwrap");
tcase_add_test(tc, test_asn1_unwrap);
suite_add_tcase(s, tc);
tc = tcase_create("is_asn1");
tcase_add_test(tc, test_is_asn1);
suite_add_tcase(s, tc);
tc = tcase_create("is_printablestring");
tcase_add_test(tc, test_asn1_is_printablestring);
suite_add_tcase(s, tc);
tc = tcase_create("to_time");
tcase_add_test(tc, test_asn1_to_time);
suite_add_tcase(s, tc);
tc = tcase_create("from_time");
tcase_add_test(tc, test_asn1_from_time);
suite_add_tcase(s, tc);
tc = tcase_create("parse_time");
tcase_add_test(tc, test_asn1_parse_time);
suite_add_tcase(s, tc);
tc = tcase_create("build_object");
tcase_add_test(tc, test_asn1_build_object);
suite_add_tcase(s, tc);
tc = tcase_create("simple_object");
tcase_add_test(tc, test_asn1_simple_object);
suite_add_tcase(s, tc);
tc = tcase_create("parse_simple_object");
tcase_add_test(tc, test_asn1_parse_simple_object);
suite_add_tcase(s, tc);
tc = tcase_create("bitstring");
tcase_add_test(tc, test_asn1_bitstring);
suite_add_tcase(s, tc);
tc = tcase_create("integer");
tcase_add_test(tc, test_asn1_integer);
suite_add_tcase(s, tc);
tc = tcase_create("parse_integer_uint64");
tcase_add_test(tc, test_asn1_parse_integer_uint64);
suite_add_tcase(s, tc);
return s;
}
@@ -0,0 +1,450 @@
/*
* Copyright (C) 2013 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <bio/bio_reader.h>
/*******************************************************************************
* different integer reads
*/
#define assert_integer_read(data, bits, val) ({ \
bio_reader_t *reader = bio_reader_create(data); \
typeof(val) i; \
for (i = 0; reader->remaining(reader) >= (bits / 8); i++) \
{ \
ck_assert(reader->read_uint##bits(reader, &val)); \
ck_assert_int_eq(i, val); \
} \
ck_assert_int_eq(i, data.len / (bits / 8)); \
ck_assert_int_eq(reader->remaining(reader), data.len % (bits / 8)); \
ck_assert(!reader->read_uint##bits(reader, &val)); \
reader->destroy(reader); \
})
#define assert_integer_read_uneven(data, bits, val) ({ \
int i; \
for (i = 0; i <= bits / 8; i++, data.len++) \
{ \
assert_integer_read(data, bits, val); \
} \
})
#define assert_basic_read(bits, val) ({ \
chunk_t data; \
data = chunk_empty; \
assert_integer_read(data, bits, val); \
data = chunk_alloca(bits / 8); \
memset(data.ptr, 0, data.len); \
data.len = 0; \
assert_integer_read_uneven(data, bits, val); \
})
#define assert_extended_read(data, bits, val) ({ \
chunk_t extended = chunk_alloca(data.len + bits / 8); \
memset(extended.ptr, 0, extended.len); \
extended.ptr[extended.len - 1] = data.len / (bits / 8); \
memcpy(extended.ptr, data.ptr, data.len); \
extended.len = data.len; \
assert_integer_read_uneven(extended, bits, val); \
})
START_TEST(test_read_uint8)
{
chunk_t data = chunk_from_chars(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07);
u_int8_t val;
assert_integer_read(data, 8, val);
assert_basic_read(8, val);
assert_extended_read(data, 8, val);
}
END_TEST
START_TEST(test_read_uint16)
{
chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03);
u_int16_t val;
assert_integer_read(data, 16, val);
assert_basic_read(16, val);
assert_extended_read(data, 16, val);
}
END_TEST
START_TEST(test_read_uint24)
{
chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03);
u_int32_t val;
assert_integer_read(data, 24, val);
assert_basic_read(24, val);
assert_extended_read(data, 24, val);
}
END_TEST
START_TEST(test_read_uint32)
{
chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03);
u_int32_t val;
assert_integer_read(data, 32, val);
assert_basic_read(32, val);
assert_extended_read(data, 32, val);
}
END_TEST
START_TEST(test_read_uint64)
{
chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03);
u_int64_t val;
assert_integer_read(data, 64, val);
assert_basic_read(64, val);
assert_extended_read(data, 64, val);
}
END_TEST
/*******************************************************************************
* different integer reads from the end of a buffer
*/
#define assert_integer_read_end(data, bits, val) ({ \
bio_reader_t *reader = bio_reader_create(data); \
typeof(val) i; \
for (i = 0; reader->remaining(reader) >= (bits / 8); i++) \
{ \
ck_assert(reader->read_uint##bits##_end(reader, &val)); \
ck_assert_int_eq(i, val); \
} \
ck_assert_int_eq(i, data.len / (bits / 8)); \
ck_assert_int_eq(reader->remaining(reader), data.len % (bits / 8)); \
ck_assert(!reader->read_uint##bits##_end(reader, &val)); \
reader->destroy(reader); \
})
#define assert_integer_read_end_uneven(data, bits, val) ({ \
int i; \
data.ptr += bits / 8; \
for (i = 0; i <= bits / 8; i++, data.ptr--, data.len++) \
{ \
assert_integer_read_end(data, bits, val); \
} \
})
#define assert_basic_read_end(bits, val) ({ \
chunk_t data; \
data = chunk_empty; \
assert_integer_read_end(data, bits, val); \
data = chunk_alloca(bits / 8); \
memset(data.ptr, 0, data.len); \
data.len = 0; \
assert_integer_read_end_uneven(data, bits, val); \
})
#define assert_extended_read_end(data, bits, val) ({ \
chunk_t extended = chunk_alloca(data.len + bits / 8); \
memset(extended.ptr, 0, extended.len); \
extended.ptr[bits / 8 - 1] = data.len / (bits / 8); \
memcpy(extended.ptr + bits / 8, data.ptr, data.len); \
extended.len = data.len; \
assert_integer_read_end_uneven(extended, bits, val); \
})
START_TEST(test_read_uint8_end)
{
chunk_t data = chunk_from_chars(0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00);
u_int8_t val;
assert_integer_read_end(data, 8, val);
assert_basic_read_end(8, val);
assert_extended_read_end(data, 8, val);
}
END_TEST
START_TEST(test_read_uint16_end)
{
chunk_t data = chunk_from_chars(0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00);
u_int16_t val;
assert_integer_read_end(data, 16, val);
assert_basic_read_end(16, val);
assert_extended_read_end(data, 16, val);
}
END_TEST
START_TEST(test_read_uint24_end)
{
chunk_t data = chunk_from_chars(0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00);
u_int32_t val;
assert_integer_read_end(data, 24, val);
assert_basic_read_end(24, val);
assert_extended_read_end(data, 24, val);
}
END_TEST
START_TEST(test_read_uint32_end)
{
chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00);
u_int32_t val;
assert_integer_read_end(data, 32, val);
assert_basic_read_end(32, val);
assert_extended_read_end(data, 32, val);
}
END_TEST
START_TEST(test_read_uint64_end)
{
chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
u_int64_t val;
assert_integer_read_end(data, 64, val);
assert_basic_read_end(64, val);
assert_extended_read_end(data, 64, val);
}
END_TEST
/*******************************************************************************
* read data
*/
static inline void assert_reader_after_read(bio_reader_t *reader, chunk_t data)
{
chunk_t peek;
ck_assert_int_eq(reader->remaining(reader), data.len);
peek = reader->peek(reader);
ck_assert_int_eq(reader->remaining(reader), data.len);
ck_assert(peek.ptr == data.ptr);
data.ptr != NULL ? ck_assert(chunk_equals(peek, data))
: ck_assert(peek.ptr == NULL);
}
START_TEST(test_read_data)
{
chunk_t read, data = chunk_from_chars(0x00, 0x00, 0x00, 0x00);
bio_reader_t *reader;
reader = bio_reader_create(chunk_empty);
ck_assert_int_eq(reader->remaining(reader), 0);
ck_assert(reader->read_data(reader, 0, &read));
ck_assert(!reader->read_data(reader, 1, &read));
reader->destroy(reader);
reader = bio_reader_create(data);
ck_assert(reader->read_data(reader, 0, &read));
ck_assert_int_eq(read.len, 0);
ck_assert(read.ptr == data.ptr);
assert_reader_after_read(reader, data);
ck_assert(reader->read_data(reader, 1, &read));
ck_assert_int_eq(read.len, 1);
ck_assert(read.ptr == data.ptr);
assert_reader_after_read(reader, chunk_skip(data, 1));
ck_assert(reader->read_data(reader, 2, &read));
ck_assert_int_eq(read.len, 2);
ck_assert(read.ptr == data.ptr + 1);
assert_reader_after_read(reader, chunk_skip(data, 3));
ck_assert(!reader->read_data(reader, 2, &read));
ck_assert(reader->read_data(reader, 1, &read));
ck_assert_int_eq(read.len, 1);
ck_assert(read.ptr == data.ptr + 3);
assert_reader_after_read(reader, chunk_skip(data, 4));
ck_assert_int_eq(reader->remaining(reader), 0);
ck_assert(reader->read_data(reader, 0, &read));
ck_assert(!reader->read_data(reader, 1, &read));
reader->destroy(reader);
}
END_TEST
START_TEST(test_read_data_end)
{
chunk_t read, data = chunk_from_chars(0x00, 0x00, 0x00, 0x00);
bio_reader_t *reader;
reader = bio_reader_create(chunk_empty);
ck_assert_int_eq(reader->remaining(reader), 0);
ck_assert(reader->read_data_end(reader, 0, &read));
ck_assert(!reader->read_data_end(reader, 1, &read));
reader->destroy(reader);
reader = bio_reader_create(data);
ck_assert(reader->read_data_end(reader, 0, &read));
ck_assert_int_eq(read.len, 0);
ck_assert(read.ptr == data.ptr + data.len);
assert_reader_after_read(reader, data);
ck_assert(reader->read_data_end(reader, 1, &read));
ck_assert_int_eq(read.len, 1);
data.len--;
ck_assert(read.ptr == data.ptr + data.len);
assert_reader_after_read(reader, data);
ck_assert(reader->read_data_end(reader, 2, &read));
ck_assert_int_eq(read.len, 2);
data.len -= 2;
ck_assert(read.ptr == data.ptr + data.len);
assert_reader_after_read(reader, data);
ck_assert(!reader->read_data(reader, 2, &read));
ck_assert(reader->read_data(reader, 1, &read));
ck_assert_int_eq(read.len, 1);
ck_assert(read.ptr == data.ptr);
assert_reader_after_read(reader, chunk_empty);
ck_assert_int_eq(reader->remaining(reader), 0);
ck_assert(reader->read_data(reader, 0, &read));
ck_assert(!reader->read_data(reader, 1, &read));
reader->destroy(reader);
}
END_TEST
/*******************************************************************************
* read length followed by data
*/
#define assert_read_data_len(bits) ({ \
bio_reader_t *reader; \
chunk_t read, data; \
int i, len = bits / 8; \
data = chunk_empty; \
reader = bio_reader_create(data); \
ck_assert(!reader->read_data##bits(reader, &read)); \
reader->destroy(reader); \
data = chunk_alloca(len + 8); \
memset(data.ptr, 0, data.len); \
for (i = 0; i <= 8; i++) \
{ \
data.ptr[len - 1] = i; \
data.len = len + i; \
reader = bio_reader_create(data); \
ck_assert(reader->read_data##bits(reader, &read)); \
ck_assert_int_eq(reader->remaining(reader), 0); \
ck_assert_int_eq(read.len, i); \
ck_assert((!read.ptr && !read.len) || (read.ptr == data.ptr + len)); \
reader->destroy(reader); \
} \
data.ptr[len - 1] = i; \
reader = bio_reader_create(data); \
ck_assert(!reader->read_data##bits(reader, &read)); \
reader->destroy(reader); \
})
START_TEST(test_read_data8)
{
assert_read_data_len(8);
}
END_TEST
START_TEST(test_read_data16)
{
assert_read_data_len(16);
}
END_TEST
START_TEST(test_read_data24)
{
assert_read_data_len(24);
}
END_TEST
START_TEST(test_read_data32)
{
assert_read_data_len(32);
}
END_TEST
/*******************************************************************************
* test constructors
*/
START_TEST(test_create)
{
chunk_t data = chunk_from_str("foobar");
bio_reader_t *reader;
data = chunk_clone(data);
reader = bio_reader_create(data);
reader->destroy(reader);
chunk_free(&data);
}
END_TEST
START_TEST(test_create_own)
{
chunk_t data = chunk_from_str("foobar");
bio_reader_t *reader;
data = chunk_clone(data);
reader = bio_reader_create_own(data);
reader->destroy(reader);
}
END_TEST
Suite *bio_reader_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("bio_reader");
tc = tcase_create("integer reads");
tcase_add_test(tc, test_read_uint8);
tcase_add_test(tc, test_read_uint16);
tcase_add_test(tc, test_read_uint24);
tcase_add_test(tc, test_read_uint32);
tcase_add_test(tc, test_read_uint64);
suite_add_tcase(s, tc);
tc = tcase_create("integer reads from end");
tcase_add_test(tc, test_read_uint8_end);
tcase_add_test(tc, test_read_uint16_end);
tcase_add_test(tc, test_read_uint24_end);
tcase_add_test(tc, test_read_uint32_end);
tcase_add_test(tc, test_read_uint64_end);
suite_add_tcase(s, tc);
tc = tcase_create("data reads and peek");
tcase_add_test(tc, test_read_data);
tcase_add_test(tc, test_read_data_end);
suite_add_tcase(s, tc);
tc = tcase_create("data length reads");
tcase_add_test(tc, test_read_data8);
tcase_add_test(tc, test_read_data16);
tcase_add_test(tc, test_read_data24);
tcase_add_test(tc, test_read_data32);
suite_add_tcase(s, tc);
tc = tcase_create("constructors");
tcase_add_test(tc, test_create);
tcase_add_test(tc, test_create_own);
suite_add_tcase(s, tc);
return s;
}
@@ -0,0 +1,392 @@
/*
* Copyright (C) 2013 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <bio/bio_writer.h>
/*******************************************************************************
* different integer writes
*/
static inline void verify_int_buffer(chunk_t data, int bits, int val)
{
size_t i;
int len = bits / 8;
ck_assert_int_eq(data.len, (val + 1) * len);
for (i = 0; i < data.len; i++)
{
if ((i + 1) % len)
{
ck_assert_int_eq(data.ptr[i], 0);
}
else
{
ck_assert_int_eq(data.ptr[i], i / len);
}
}
}
#define assert_integer_write(init, bits) ({ \
int i; \
bio_writer_t *writer = bio_writer_create(init); \
for (i = 0; i < 16; i++) \
{ \
writer->write_uint##bits(writer, i); \
verify_int_buffer(writer->get_buf(writer), bits, i); \
} \
writer->destroy(writer); \
})
START_TEST(test_write_uint8)
{
/* use default buffer (and increase) size */
assert_integer_write(0, 8);
/* force a resize by the given size */
assert_integer_write(1, 8);
}
END_TEST
START_TEST(test_write_uint16)
{
assert_integer_write(0, 16);
assert_integer_write(1, 16);
}
END_TEST
START_TEST(test_write_uint24)
{
assert_integer_write(0, 24);
assert_integer_write(1, 24);
}
END_TEST
START_TEST(test_write_uint32)
{
assert_integer_write(0, 32);
assert_integer_write(1, 32);
}
END_TEST
START_TEST(test_write_uint64)
{
assert_integer_write(0, 64);
assert_integer_write(1, 64);
}
END_TEST
/*******************************************************************************
* write data / skip
*/
static inline void assert_writer_after_write(bio_writer_t *writer, int count)
{
chunk_t buf;
size_t i;
buf = writer->get_buf(writer);
ck_assert_int_eq(buf.len, count * 3);
for (i = 0; i < buf.len; i++)
{
ck_assert(buf.ptr[i] == i % 3);
}
}
START_TEST(test_write_data)
{
chunk_t buf, data = chunk_from_chars(0x00, 0x01, 0x02);
bio_writer_t *writer;
/* no allocation, but default buffer size */
writer = bio_writer_create(0);
buf = writer->get_buf(writer);
ck_assert_int_eq(buf.len, 0);
ck_assert(buf.ptr == NULL);
writer->write_data(writer, chunk_empty);
buf = writer->get_buf(writer);
ck_assert_int_eq(buf.len, 0);
ck_assert(buf.ptr == NULL);
writer->destroy(writer);
/* custom buffer size, initial buffer allocated */
writer = bio_writer_create(1);
buf = writer->get_buf(writer);
ck_assert_int_eq(buf.len, 0);
ck_assert(buf.ptr != NULL);
writer->write_data(writer, chunk_empty);
buf = writer->get_buf(writer);
ck_assert_int_eq(buf.len, 0);
ck_assert(buf.ptr != NULL);
writer->destroy(writer);
writer = bio_writer_create(0);
writer->write_data(writer, data);
assert_writer_after_write(writer, 1);
writer->write_data(writer, data);
assert_writer_after_write(writer, 2);
writer->write_data(writer, data);
assert_writer_after_write(writer, 3);
writer->destroy(writer);
}
END_TEST
START_TEST(test_skip)
{
chunk_t skipped, buf, data = chunk_from_chars(0x00, 0x01, 0x02);
bio_writer_t *writer;
writer = bio_writer_create(4);
skipped = writer->skip(writer, 3);
ck_assert_int_eq(skipped.len, 3);
buf = writer->get_buf(writer);
ck_assert(skipped.ptr == buf.ptr);
memset(skipped.ptr, 0, skipped.len);
writer->write_data(writer, data);
buf = writer->get_buf(writer);
ck_assert(chunk_equals(buf, chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x01, 0x02)));
writer->destroy(writer);
writer = bio_writer_create(1);
skipped = writer->skip(writer, 3);
memcpy(skipped.ptr, data.ptr, data.len);
writer->write_data(writer, data);
assert_writer_after_write(writer, 2);
writer->destroy(writer);
}
END_TEST
/*******************************************************************************
* write length followed by data
*/
#define assert_write_data_len(init, bits) ({ \
bio_writer_t *writer; \
chunk_t buf, data; \
int i, len = bits / 8; \
writer = bio_writer_create(init); \
writer->write_data##bits(writer, chunk_empty); \
buf = writer->get_buf(writer); \
ck_assert_int_eq(buf.len, len); \
ck_assert_int_eq(buf.ptr[len - 1], 0); \
writer->destroy(writer); \
data = chunk_alloca(32); \
memset(data.ptr, 0, data.len); \
for (i = 0; i < 32; i++) \
{ \
data.ptr[i] = i; \
data.len = i; \
writer = bio_writer_create(init); \
writer->write_data##bits(writer, data); \
buf = writer->get_buf(writer); \
ck_assert_int_eq(buf.len, len + i); \
ck_assert_int_eq(buf.ptr[len - 1], i); \
ck_assert(chunk_equals(chunk_create(buf.ptr + len, buf.len - len), data)); \
writer->destroy(writer); \
} \
})
START_TEST(test_write_data8)
{
assert_write_data_len(0, 8);
assert_write_data_len(1, 8);
}
END_TEST
START_TEST(test_write_data16)
{
assert_write_data_len(0, 16);
assert_write_data_len(1, 16);
}
END_TEST
START_TEST(test_write_data24)
{
assert_write_data_len(0, 24);
assert_write_data_len(1, 24);
}
END_TEST
START_TEST(test_write_data32)
{
assert_write_data_len(0, 32);
assert_write_data_len(1, 32);
}
END_TEST
/*******************************************************************************
* add length header before current data
*/
#define assert_wrap_data(init, bits) ({ \
bio_writer_t *writer; \
chunk_t buf, data; \
int i, len = bits / 8; \
writer = bio_writer_create(init); \
writer->wrap##bits(writer); \
buf = writer->get_buf(writer); \
ck_assert_int_eq(buf.len, len); \
ck_assert_int_eq(buf.ptr[len - 1], 0); \
writer->destroy(writer); \
data = chunk_alloca(32); \
memset(data.ptr, 0, data.len); \
for (i = 0; i < 32; i++) \
{ \
data.ptr[i] = i; \
data.len = i; \
writer = bio_writer_create(init); \
writer->write_data(writer, data); \
writer->wrap##bits(writer); \
buf = writer->get_buf(writer); \
ck_assert_int_eq(buf.len, len + i); \
ck_assert_int_eq(buf.ptr[len - 1], i); \
ck_assert(chunk_equals(chunk_create(buf.ptr + len, buf.len - len), data)); \
writer->wrap##bits(writer); \
buf = writer->get_buf(writer); \
ck_assert_int_eq(buf.len, 2 * len + i); \
ck_assert_int_eq(buf.ptr[len - 1], len + i); \
ck_assert(chunk_equals(chunk_create(buf.ptr + 2 * len, buf.len - 2 * len), data)); \
writer->destroy(writer); \
} \
})
START_TEST(test_wrap8)
{
assert_wrap_data(0, 8);
assert_wrap_data(1, 8);
}
END_TEST
START_TEST(test_wrap16)
{
assert_wrap_data(0, 16);
assert_wrap_data(1, 16);
}
END_TEST
START_TEST(test_wrap24)
{
assert_wrap_data(0, 24);
assert_wrap_data(1, 24);
}
END_TEST
START_TEST(test_wrap32)
{
assert_wrap_data(0, 32);
assert_wrap_data(1, 32);
}
END_TEST
/*******************************************************************************
* test data extraction
*/
START_TEST(test_get_buf)
{
bio_writer_t *writer;
chunk_t data1, data2;
writer = bio_writer_create(0);
writer->write_uint8(writer, 1);
data1 = writer->get_buf(writer);
ck_assert_int_eq(data1.len, 1);
ck_assert(data1.ptr[0] == 1);
data2 = writer->get_buf(writer);
ck_assert(chunk_equals(data1, data2));
ck_assert(data1.ptr == data2.ptr);
writer->destroy(writer);
}
END_TEST
START_TEST(test_extract_buf)
{
bio_writer_t *writer;
chunk_t data1, data2;
writer = bio_writer_create(0);
writer->write_uint8(writer, 1);
data1 = writer->extract_buf(writer);
ck_assert_int_eq(data1.len, 1);
ck_assert(data1.ptr[0] == 1);
data2 = writer->get_buf(writer);
ck_assert_int_eq(data2.len, 0);
ck_assert(data2.ptr == NULL);
data2 = writer->extract_buf(writer);
ck_assert_int_eq(data2.len, 0);
ck_assert(data2.ptr == NULL);
writer->write_uint8(writer, 1);
data2 = writer->get_buf(writer);
ck_assert(chunk_equals(data1, data2));
ck_assert(data1.ptr != data2.ptr);
writer->destroy(writer);
chunk_free(&data1);
}
END_TEST
Suite *bio_writer_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("bio_writer");
tc = tcase_create("integer writes");
tcase_add_test(tc, test_write_uint8);
tcase_add_test(tc, test_write_uint16);
tcase_add_test(tc, test_write_uint24);
tcase_add_test(tc, test_write_uint32);
tcase_add_test(tc, test_write_uint64);
suite_add_tcase(s, tc);
tc = tcase_create("data writes/skip");
tcase_add_test(tc, test_write_data);
tcase_add_test(tc, test_skip);
suite_add_tcase(s, tc);
tc = tcase_create("data length writes");
tcase_add_test(tc, test_write_data8);
tcase_add_test(tc, test_write_data16);
tcase_add_test(tc, test_write_data24);
tcase_add_test(tc, test_write_data32);
suite_add_tcase(s, tc);
tc = tcase_create("wrap writes");
tcase_add_test(tc, test_wrap8);
tcase_add_test(tc, test_wrap16);
tcase_add_test(tc, test_wrap24);
tcase_add_test(tc, test_wrap32);
suite_add_tcase(s, tc);
tc = tcase_create("get/extract");
tcase_add_test(tc, test_get_buf);
tcase_add_test(tc, test_extract_buf);
suite_add_tcase(s, tc);
return s;
}
+876
View File
@@ -0,0 +1,876 @@
/*
* Copyright (C) 2013 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <utils/chunk.h>
/*******************************************************************************
* utilities
*/
static void assert_chunk_empty(chunk_t chunk)
{
ck_assert(chunk.len == 0 && chunk.ptr == NULL);
}
/*******************************************************************************
* equals
*/
START_TEST(test_chunk_equals)
{
chunk_t chunk = chunk_from_str("chunk");
chunk_t chunk_a, chunk_b;
chunk_a = chunk_empty;
chunk_b = chunk_empty;
ck_assert(!chunk_equals(chunk_a, chunk_b));
chunk_a = chunk;
ck_assert(!chunk_equals(chunk_a, chunk_b));
chunk_b = chunk;
ck_assert(chunk_equals(chunk_a, chunk_b));
chunk_b = chunk_from_str("asdf");
ck_assert(!chunk_equals(chunk_a, chunk_b));
chunk_b = chunk_from_str("chunk");
ck_assert(chunk_equals(chunk_a, chunk_b));
}
END_TEST
/*******************************************************************************
* chunk_compare test
*/
static struct {
int result;
chunk_t a;
chunk_t b;
} compare_data[] = {
{ 0, { NULL, 0 }, { NULL, 0 }},
{ 0, chunk_from_chars(0x00), chunk_from_chars(0x00)},
{-1, chunk_from_chars(0x00), chunk_from_chars(0x01)},
{ 1, chunk_from_chars(0x01), chunk_from_chars(0x00)},
{ 0, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x00)},
{-1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x01)},
{ 1, chunk_from_chars(0x00, 0x01), chunk_from_chars(0x00, 0x00)},
{-1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x01, 0x00)},
{ 1, chunk_from_chars(0x01, 0x00), chunk_from_chars(0x00, 0x00)},
{-1, chunk_from_chars(0xff), chunk_from_chars(0x00, 0x00)},
{ 1, chunk_from_chars(0x00, 0x00), chunk_from_chars(0xff)},
};
START_TEST(test_compare)
{
int result, expected;
result = chunk_compare(compare_data[_i].a, compare_data[_i].b);
expected = compare_data[_i].result;
ck_assert((result == 0 && expected == 0) ||
(result < 0 && expected < 0) ||
(result > 0 && expected > 0));
}
END_TEST
/*******************************************************************************
* clear
*/
START_TEST(test_chunk_clear)
{
chunk_t chunk;
u_char *ptr;
int i;
bool cleared = TRUE;
chunk = chunk_empty;
chunk_clear(&chunk);
chunk_free(&chunk);
chunk = chunk_alloc(64);
ptr = chunk.ptr;
for (i = 0; i < 64; i++)
{
chunk.ptr[i] = i;
}
chunk_clear(&chunk);
/* check memory area of freed chunk. We can't use ck_assert() for this
* test directly, as it might allocate data at the freed area. */
for (i = 0; i < 64; i++)
{
if (ptr[i] != 0 && ptr[i] == i)
{
cleared = FALSE;
break;
}
}
assert_chunk_empty(chunk);
ck_assert(cleared);
}
END_TEST
/*******************************************************************************
* chunk_length
*/
START_TEST(test_chunk_length)
{
chunk_t a, b, c;
size_t len;
a = chunk_empty;
b = chunk_empty;
c = chunk_empty;
len = chunk_length("ccc", a, b, c);
ck_assert_int_eq(len, 0);
a = chunk_from_str("foo");
b = chunk_from_str("bar");
len = chunk_length("ccc", a, b, c);
ck_assert_int_eq(len, 6);
len = chunk_length("zcc", a, b, c);
ck_assert_int_eq(len, 0);
len = chunk_length("czc", a, b, c);
ck_assert_int_eq(len, 3);
a = chunk_from_str("foo");
b = chunk_from_str("bar");
c = chunk_from_str("baz");
len = chunk_length("ccc", a, b, c);
ck_assert_int_eq(len, 9);
}
END_TEST
/*******************************************************************************
* chunk_create_cat
*/
START_TEST(test_chunk_create_cat)
{
chunk_t foo, bar;
chunk_t a, b, c;
u_char *ptra, *ptrb;
foo = chunk_from_str("foo");
bar = chunk_from_str("bar");
/* to simplify things we use the chunk_cata macro */
a = chunk_empty;
b = chunk_empty;
c = chunk_cata("cc", a, b);
ck_assert_int_eq(c.len, 0);
ck_assert(c.ptr != NULL);
a = foo;
b = bar;
c = chunk_cata("cc", a, b);
ck_assert_int_eq(c.len, 6);
ck_assert(chunk_equals(c, chunk_from_str("foobar")));
a = chunk_clone(foo);
b = chunk_clone(bar);
c = chunk_cata("mm", a, b);
ck_assert_int_eq(c.len, 6);
ck_assert(chunk_equals(c, chunk_from_str("foobar")));
a = chunk_clone(foo);
b = chunk_clone(bar);
ptra = a.ptr;
ptrb = b.ptr;
c = chunk_cata("ss", a, b);
ck_assert_int_eq(c.len, 6);
ck_assert(chunk_equals(c, chunk_from_str("foobar")));
/* check memory area of cleared chunk */
ck_assert(!chunk_equals(foo, chunk_create(ptra, 3)));
ck_assert(!chunk_equals(bar, chunk_create(ptrb, 3)));
}
END_TEST
/*******************************************************************************
* chunk_split
*/
static bool mem_in_chunk(u_char *ptr, chunk_t chunk)
{
return ptr >= chunk.ptr && ptr < (chunk.ptr + chunk.len);
}
START_TEST(test_chunk_split)
{
chunk_t foo, bar, foobar;
chunk_t a, b, c;
u_char *ptra, *ptrb;
foo = chunk_from_str("foo");
bar = chunk_from_str("bar");
foobar = chunk_from_str("foobar");
chunk_split(foobar, "aa", 3, &a, 3, &b);
ck_assert(chunk_equals(a, foo));
ck_assert(chunk_equals(b, bar));
ck_assert(!mem_in_chunk(a.ptr, foobar));
ck_assert(!mem_in_chunk(b.ptr, foobar));
chunk_free(&a);
chunk_free(&b);
chunk_split(foobar, "mm", 3, &a, 3, &b);
ck_assert(chunk_equals(a, foo));
ck_assert(chunk_equals(b, bar));
ck_assert(mem_in_chunk(a.ptr, foobar));
ck_assert(mem_in_chunk(b.ptr, foobar));
chunk_split(foobar, "am", 3, &a, 3, &b);
ck_assert(chunk_equals(a, foo));
ck_assert(chunk_equals(b, bar));
ck_assert(!mem_in_chunk(a.ptr, foobar));
ck_assert(mem_in_chunk(b.ptr, foobar));
chunk_free(&a);
a = chunk_alloca(3);
ptra = a.ptr;
b = chunk_alloca(3);
ptrb = b.ptr;
chunk_split(foobar, "cc", 3, &a, 3, &b);
ck_assert(chunk_equals(a, foo));
ck_assert(chunk_equals(b, bar));
ck_assert(a.ptr == ptra);
ck_assert(b.ptr == ptrb);
chunk_split(foobar, "mm", 1, NULL, 2, &a, 2, NULL, 1, &b);
ck_assert(chunk_equals(a, chunk_from_str("oo")));
ck_assert(chunk_equals(b, chunk_from_str("r")));
chunk_split(foobar, "mm", 6, &a, 6, &b);
ck_assert(chunk_equals(a, foobar));
assert_chunk_empty(b);
chunk_split(foobar, "mac", 12, &a, 12, &b, 12, &c);
ck_assert(chunk_equals(a, foobar));
assert_chunk_empty(b);
assert_chunk_empty(c);
}
END_TEST
/*******************************************************************************
* chunk_skip[_zero]
*/
START_TEST(test_chunk_skip)
{
chunk_t foobar, a;
foobar = chunk_from_str("foobar");
a = foobar;
a = chunk_skip(a, 0);
ck_assert(chunk_equals(a, foobar));
a = chunk_skip(a, 1);
ck_assert(chunk_equals(a, chunk_from_str("oobar")));
a = chunk_skip(a, 2);
ck_assert(chunk_equals(a, chunk_from_str("bar")));
a = chunk_skip(a, 3);
assert_chunk_empty(a);
a = foobar;
a = chunk_skip(a, 6);
assert_chunk_empty(a);
a = foobar;
a = chunk_skip(a, 10);
assert_chunk_empty(a);
}
END_TEST
START_TEST(test_chunk_skip_zero)
{
chunk_t foobar, a;
a = chunk_empty;
a = chunk_skip_zero(a);
assert_chunk_empty(a);
foobar = chunk_from_str("foobar");
a = foobar;
a = chunk_skip_zero(a);
ck_assert(chunk_equals(a, foobar));
a = chunk_from_chars(0x00, 0xaa, 0xbb, 0xcc);
a = chunk_skip_zero(a);
ck_assert(chunk_equals(a, chunk_from_chars(0xaa, 0xbb, 0xcc)));
a = chunk_skip_zero(a);
ck_assert(chunk_equals(a, chunk_from_chars(0xaa, 0xbb, 0xcc)));
}
END_TEST
/*******************************************************************************
* BASE16 encoding test
*/
START_TEST(test_base16)
{
/* test vectors from RFC 4648:
*
* BASE16("") = ""
* BASE16("f") = "66"
* BASE16("fo") = "666F"
* BASE16("foo") = "666F6F"
* BASE16("foob") = "666F6F62"
* BASE16("fooba") = "666F6F6261"
* BASE16("foobar") = "666F6F626172"
*/
typedef struct {
bool upper;
char *in;
char *out;
} testdata_t;
testdata_t test[] = {
{TRUE, "", ""},
{TRUE, "f", "66"},
{TRUE, "fo", "666F"},
{TRUE, "foo", "666F6F"},
{TRUE, "foob", "666F6F62"},
{TRUE, "fooba", "666F6F6261"},
{TRUE, "foobar", "666F6F626172"},
{FALSE, "", ""},
{FALSE, "f", "66"},
{FALSE, "fo", "666f"},
{FALSE, "foo", "666f6f"},
{FALSE, "foob", "666f6f62"},
{FALSE, "fooba", "666f6f6261"},
{FALSE, "foobar", "666f6f626172"},
};
testdata_t test_colon[] = {
{TRUE, "", ""},
{TRUE, "f", "66"},
{TRUE, "fo", "66:6F"},
{TRUE, "foo", "66:6F:6F"},
{FALSE, "foob", "66:6f:6f:62"},
{FALSE, "fooba", "66:6f:6f:62:61"},
{FALSE, "foobar", "66:6f:6f:62:61:72"},
{FALSE, "foobar", "66:6f6f:6261:72"},
};
int i;
for (i = 0; i < countof(test); i++)
{
chunk_t out;
out = chunk_to_hex(chunk_create(test[i].in, strlen(test[i].in)), NULL,
test[i].upper);
ck_assert_str_eq(out.ptr, test[i].out);
free(out.ptr);
}
for (i = 0; i < countof(test); i++)
{
chunk_t out;
out = chunk_from_hex(chunk_create(test[i].out, strlen(test[i].out)), NULL);
fail_unless(strneq(out.ptr, test[i].in, out.len),
"base16 conversion error - should '%s', is %#B",
test[i].in, &out);
free(out.ptr);
}
for (i = 0; i < countof(test_colon); i++)
{
chunk_t out;
out = chunk_from_hex(chunk_create(test_colon[i].out, strlen(test_colon[i].out)), NULL);
fail_unless(strneq(out.ptr, test_colon[i].in, out.len),
"base16 conversion error - should '%s', is %#B",
test_colon[i].in, &out);
free(out.ptr);
}
}
END_TEST
/*******************************************************************************
* BASE64 encoding test
*/
START_TEST(test_base64)
{
/* test vectors from RFC 4648:
*
* BASE64("") = ""
* BASE64("f") = "Zg=="
* BASE64("fo") = "Zm8="
* BASE64("foo") = "Zm9v"
* BASE64("foob") = "Zm9vYg=="
* BASE64("fooba") = "Zm9vYmE="
* BASE64("foobar") = "Zm9vYmFy"
*/
typedef struct {
char *in;
char *out;
} testdata_t;
testdata_t test[] = {
{"", ""},
{"f", "Zg=="},
{"fo", "Zm8="},
{"foo", "Zm9v"},
{"foob", "Zm9vYg=="},
{"fooba", "Zm9vYmE="},
{"foobar", "Zm9vYmFy"},
};
int i;
for (i = 0; i < countof(test); i++)
{
chunk_t out;
out = chunk_to_base64(chunk_create(test[i].in, strlen(test[i].in)), NULL);
ck_assert_str_eq(out.ptr, test[i].out);
free(out.ptr);
}
for (i = 0; i < countof(test); i++)
{
chunk_t out;
out = chunk_from_base64(chunk_create(test[i].out, strlen(test[i].out)), NULL);
fail_unless(strneq(out.ptr, test[i].in, out.len),
"base64 conversion error - should '%s', is %#B",
test[i].in, &out);
free(out.ptr);
}
}
END_TEST
/*******************************************************************************
* BASE32 encoding test
*/
START_TEST(test_base32)
{
/* test vectors from RFC 4648:
*
* BASE32("") = ""
* BASE32("f") = "MY======"
* BASE32("fo") = "MZXQ===="
* BASE32("foo") = "MZXW6==="
* BASE32("foob") = "MZXW6YQ="
* BASE32("fooba") = "MZXW6YTB"
* BASE32("foobar") = "MZXW6YTBOI======"
*/
typedef struct {
char *in;
char *out;
} testdata_t;
testdata_t test[] = {
{"", ""},
{"f", "MY======"},
{"fo", "MZXQ===="},
{"foo", "MZXW6==="},
{"foob", "MZXW6YQ="},
{"fooba", "MZXW6YTB"},
{"foobar", "MZXW6YTBOI======"},
};
int i;
for (i = 0; i < countof(test); i++)
{
chunk_t out;
out = chunk_to_base32(chunk_create(test[i].in, strlen(test[i].in)), NULL);
ck_assert_str_eq(out.ptr, test[i].out);
free(out.ptr);
}
}
END_TEST
/*******************************************************************************
* chunk_increment test
*/
static struct {
bool overflow;
chunk_t in;
chunk_t out;
} increment_data[] = {
{TRUE, { NULL, 0 }, { NULL, 0 }},
{FALSE, chunk_from_chars(0x00), chunk_from_chars(0x01)},
{FALSE, chunk_from_chars(0xfe), chunk_from_chars(0xff)},
{TRUE, chunk_from_chars(0xff), chunk_from_chars(0x00)},
{FALSE, chunk_from_chars(0x00, 0x00), chunk_from_chars(0x00, 0x01)},
{FALSE, chunk_from_chars(0x00, 0xff), chunk_from_chars(0x01, 0x00)},
{FALSE, chunk_from_chars(0xfe, 0xff), chunk_from_chars(0xff, 0x00)},
{TRUE, chunk_from_chars(0xff, 0xff), chunk_from_chars(0x00, 0x00)},
};
START_TEST(test_increment)
{
chunk_t chunk;
bool overflow;
chunk = chunk_clonea(increment_data[_i].in);
overflow = chunk_increment(chunk);
ck_assert(overflow == increment_data[_i].overflow);
ck_assert(!increment_data[_i].out.ptr ||
chunk_equals(chunk, increment_data[_i].out));
}
END_TEST
/*******************************************************************************
* chunk_printable tests
*/
static struct {
bool printable;
chunk_t in;
char *out;
} printable_data[] = {
{TRUE, chunk_from_chars(0x31), "1"},
{FALSE, chunk_from_chars(0x00), "?"},
{FALSE, chunk_from_chars(0x31, 0x00), "1?"},
{FALSE, chunk_from_chars(0x00, 0x31), "?1"},
{TRUE, chunk_from_chars(0x3f, 0x31), "?1"},
{FALSE, chunk_from_chars(0x00, 0x31, 0x00), "?1?"},
{FALSE, chunk_from_chars(0x00, 0x31, 0x00, 0x32), "?1?2"},
};
START_TEST(test_printable)
{
bool printable;
printable = chunk_printable(printable_data[_i].in, NULL, ' ');
ck_assert(printable == printable_data[_i].printable);
}
END_TEST
START_TEST(test_printable_sanitize)
{
chunk_t sane, expected;
bool printable;
printable = chunk_printable(printable_data[_i].in, &sane, '?');
ck_assert(printable == printable_data[_i].printable);
expected = chunk_from_str(printable_data[_i].out);
ck_assert(chunk_equals(sane, expected));
chunk_free(&sane);
}
END_TEST
START_TEST(test_printable_empty)
{
chunk_t sane;
bool printable;
printable = chunk_printable(chunk_empty, NULL, ' ');
ck_assert(printable);
sane.ptr = (void*)1;
sane.len = 1;
printable = chunk_printable(chunk_empty, &sane, ' ');
ck_assert(printable);
assert_chunk_empty(sane);
}
END_TEST
/*******************************************************************************
* test for chunk_mac(), i.e. SipHash-2-4
*/
/**
* SipHash-2-4 output with
* k = 00 01 02 ...
* and
* in = (empty string)
* in = 00 (1 byte)
* in = 00 01 (2 bytes)
* in = 00 01 02 (3 bytes)
* ...
* in = 00 01 02 ... 3e (63 bytes)
*/
static const u_char sip_vectors[64][8] =
{
{ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
{ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
{ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
{ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
{ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
{ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
{ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
{ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
{ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
{ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
{ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
{ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
{ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
{ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
{ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
{ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
{ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
{ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
{ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
{ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
{ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
{ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
{ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
{ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
{ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
{ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
{ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
{ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
{ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
{ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
{ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
{ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
{ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
{ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
{ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
{ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
{ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
{ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
{ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
{ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
{ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
{ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
{ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
{ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
{ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
{ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
{ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
{ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
{ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
{ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
{ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
{ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
{ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
{ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
{ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
{ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
{ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
{ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
{ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
{ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
{ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
{ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
{ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
{ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
};
START_TEST(test_chunk_mac)
{
chunk_t in;
u_char key[16];
u_int64_t out;
int i, count;
count = countof(sip_vectors);
in = chunk_alloca(count);
for (i = 0; i < 16; ++i)
{
key[i] = i;
}
for (i = 0; i < count; ++i)
{
in.ptr[i] = i;
in.len = i;
out = chunk_mac(in, key);
fail_unless(memeq(&out, sip_vectors[i], 8),
"test vector failed for %d bytes", i);
}
}
END_TEST
/*******************************************************************************
* test for chunk_hash[_inc]()
*/
START_TEST(test_chunk_hash)
{
chunk_t chunk;
u_int32_t hash_a, hash_b, hash_c;
chunk = chunk_from_str("asdf");
/* output is randomized, so there are no test-vectors we could use */
hash_a = chunk_hash(chunk);
hash_b = chunk_hash(chunk);
ck_assert(hash_a == hash_b);
hash_b = chunk_hash_inc(chunk, hash_a);
ck_assert(hash_a != hash_b);
hash_c = chunk_hash_inc(chunk, hash_a);
ck_assert(hash_b == hash_c);
}
END_TEST
/*******************************************************************************
* test for chunk_hash_static[_inc]()
*/
START_TEST(test_chunk_hash_static)
{
chunk_t in;
u_int32_t out, hash_a, hash_b, hash_inc = 0x7b891a95;
int i, count;
count = countof(sip_vectors);
in = chunk_alloca(count);
for (i = 0; i < count; ++i)
{
in.ptr[i] = i;
in.len = i;
/* compared to chunk_mac() we only get half the value back */
out = chunk_hash_static(in);
fail_unless(memeq(&out, sip_vectors[i], 4),
"test vector failed for %d bytes", i);
}
hash_a = chunk_hash_static_inc(in, out);
ck_assert_int_eq(hash_a, hash_inc);
hash_b = chunk_hash_static_inc(in, out);
ck_assert_int_eq(hash_a, hash_b);
}
END_TEST
/*******************************************************************************
* printf_hook tests
*/
static struct {
chunk_t in;
char *out;
char *out_plus;
} printf_hook_data[] = {
{chunk_from_chars(), "", ""},
{chunk_from_chars(0x00), "00", "00"},
{chunk_from_chars(0x00, 0x01), "00:01", "0001"},
{chunk_from_chars(0x00, 0x01, 0x02), "00:01:02", "000102"},
};
START_TEST(test_printf_hook_hash)
{
char buf[16];
int len;
len = snprintf(buf, sizeof(buf), "%#B", &printf_hook_data[_i].in);
ck_assert(len >= 0 && len < sizeof(buf));
ck_assert_str_eq(buf, printf_hook_data[_i].out);
}
END_TEST
START_TEST(test_printf_hook_plus)
{
char buf[16];
int len;
len = snprintf(buf, sizeof(buf), "%+B", &printf_hook_data[_i].in);
ck_assert(len >= 0 && len < sizeof(buf));
ck_assert_str_eq(buf, printf_hook_data[_i].out_plus);
}
END_TEST
START_TEST(test_printf_hook)
{
char buf[128], mem[128];
int len;
/* %B should be the same as %b, which is what we check, comparing the
* acutal result could be tricky as %b prints the chunk's memory address */
len = snprintf(buf, sizeof(buf), "%B", &printf_hook_data[_i].in);
ck_assert(len >= 0 && len < sizeof(buf));
len = snprintf(mem, sizeof(mem), "%b", printf_hook_data[_i].in.ptr,
(u_int)printf_hook_data[_i].in.len);
ck_assert(len >= 0 && len < sizeof(mem));
ck_assert_str_eq(buf, mem);
}
END_TEST
Suite *chunk_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("chunk");
tc = tcase_create("equals");
tcase_add_test(tc, test_chunk_equals);
suite_add_tcase(s, tc);
tc = tcase_create("chunk_compare");
tcase_add_loop_test(tc, test_compare, 0, countof(compare_data));
suite_add_tcase(s, tc);
tc = tcase_create("clear");
tcase_add_test(tc, test_chunk_clear);
suite_add_tcase(s, tc);
tc = tcase_create("chunk_length");
tcase_add_test(tc, test_chunk_length);
suite_add_tcase(s, tc);
tc = tcase_create("chunk_create_cat");
tcase_add_test(tc, test_chunk_create_cat);
suite_add_tcase(s, tc);
tc = tcase_create("chunk_split");
tcase_add_test(tc, test_chunk_split);
suite_add_tcase(s, tc);
tc = tcase_create("chunk_skip");
tcase_add_test(tc, test_chunk_skip);
tcase_add_test(tc, test_chunk_skip_zero);
suite_add_tcase(s, tc);
tc = tcase_create("chunk_increment");
tcase_add_loop_test(tc, test_increment, 0, countof(increment_data));
suite_add_tcase(s, tc);
tc = tcase_create("chunk_printable");
tcase_add_loop_test(tc, test_printable, 0, countof(printable_data));
tcase_add_loop_test(tc, test_printable_sanitize, 0, countof(printable_data));
tcase_add_test(tc, test_printable_empty);
suite_add_tcase(s, tc);
tc = tcase_create("baseXX");
tcase_add_test(tc, test_base64);
tcase_add_test(tc, test_base32);
tcase_add_test(tc, test_base16);
suite_add_tcase(s, tc);
tc = tcase_create("chunk_mac");
tcase_add_test(tc, test_chunk_mac);
suite_add_tcase(s, tc);
tc = tcase_create("chunk_hash");
tcase_add_test(tc, test_chunk_hash);
suite_add_tcase(s, tc);
tc = tcase_create("chunk_hash_static");
tcase_add_test(tc, test_chunk_hash_static);
suite_add_tcase(s, tc);
tc = tcase_create("printf_hook");
tcase_add_loop_test(tc, test_printf_hook_hash, 0, countof(printf_hook_data));
tcase_add_loop_test(tc, test_printf_hook_plus, 0, countof(printf_hook_data));
tcase_add_loop_test(tc, test_printf_hook, 0, countof(printf_hook_data));
suite_add_tcase(s, tc);
return s;
}
+237
View File
@@ -0,0 +1,237 @@
/*
* Copyright (C) 2013 Martin Willi
* Copyright (C) 2013 revosec AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <plugins/plugin_feature.h>
/**
* Signature schemes to test
*/
static struct {
/* key size for scheme, 0 for any */
int key_size;
signature_scheme_t scheme;
} schemes[] = {
{ 0, SIGN_ECDSA_WITH_SHA1_DER },
{ 0, SIGN_ECDSA_WITH_SHA256_DER },
{ 0, SIGN_ECDSA_WITH_SHA384_DER },
{ 0, SIGN_ECDSA_WITH_SHA512_DER },
{ 0, SIGN_ECDSA_WITH_NULL },
{ 256, SIGN_ECDSA_256 },
{ 384, SIGN_ECDSA_384 },
{ 521, SIGN_ECDSA_521 },
};
/**
* Perform a signature verification "good" test having a keypair
*/
static void test_good_sig(private_key_t *privkey, public_key_t *pubkey)
{
chunk_t sig, data = chunk_from_chars(0x01,0x02,0x03,0xFD,0xFE,0xFF);
int i;
for (i = 0; i < countof(schemes); i++)
{
if (!lib->plugins->has_feature(lib->plugins,
PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[i].scheme)) ||
!lib->plugins->has_feature(lib->plugins,
PLUGIN_PROVIDE(PRIVKEY_SIGN, schemes[i].scheme)))
{
continue;
}
if (schemes[i].key_size != 0 &&
schemes[i].scheme != privkey->get_keysize(privkey))
{
continue;
}
fail_unless(privkey->sign(privkey, schemes[i].scheme, data, &sig),
"sign %N", signature_scheme_names, schemes[i].scheme);
fail_unless(pubkey->verify(pubkey, schemes[i].scheme, data, sig),
"verify %N", signature_scheme_names, schemes[i].scheme);
free(sig.ptr);
}
}
/**
* Some special signatures that should never validate successfully
*/
static chunk_t invalid_sigs[] = {
chunk_from_chars(),
chunk_from_chars(0x00),
chunk_from_chars(0x00,0x00),
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
};
/**
* Check public key that it properly fails against some crafted sigs
*/
static void test_bad_sigs(public_key_t *pubkey)
{
chunk_t data = chunk_from_chars(0x01,0x02,0x03,0xFD,0xFE,0xFF);
int s, i;
for (s = 0; s < countof(schemes); s++)
{
if (schemes[s].key_size != 0 &&
schemes[s].scheme != pubkey->get_keysize(pubkey))
{
continue;
}
if (!lib->plugins->has_feature(lib->plugins,
PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[s].scheme)))
{
continue;
}
for (i = 0; i < countof(invalid_sigs); i++)
{
fail_if(
pubkey->verify(pubkey, schemes[s].scheme, data, invalid_sigs[i]),
"bad %N sig accepted %B",
signature_scheme_names, schemes[s].scheme,
&invalid_sigs[i]);
}
}
}
/**
* ECDSA key sizes to test
*/
static int key_sizes[] = {
256, 384, 521,
};
START_TEST(test_gen)
{
private_key_t *privkey;
public_key_t *pubkey;
privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
BUILD_KEY_SIZE, key_sizes[_i], BUILD_END);
ck_assert(privkey != NULL);
pubkey = privkey->get_public_key(privkey);
ck_assert(pubkey != NULL);
test_good_sig(privkey, pubkey);
test_bad_sigs(pubkey);
pubkey->destroy(pubkey);
privkey->destroy(privkey);
}
END_TEST
/**
* Private keys to load
*/
static chunk_t keys[] = {
chunk_from_chars( /* ECDSA-256 */
0x30,0x77,0x02,0x01,0x01,0x04,0x20,0x42,0xc6,0x8c,0xff,0x2b,0x8b,0x87,0xa1,0xfb,
0x50,0xf6,0xfe,0xd6,0x88,0xb3,0x0a,0x48,0xb2,0xc5,0x8f,0x50,0xe0,0xcf,0x40,0xfa,
0x57,0xd1,0xc6,0x6c,0x20,0x64,0xc5,0xa0,0x0a,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,
0x03,0x01,0x07,0xa1,0x44,0x03,0x42,0x00,0x04,0x9c,0xb2,0x52,0xcb,0xc0,0x5c,0xcf,
0x97,0xdd,0xd6,0xe7,0x49,0x32,0x47,0x0c,0x8e,0xdb,0x6d,0xbf,0xc8,0x1a,0x0a,0x01,
0xe8,0x5e,0x3f,0x8e,0x64,0x33,0xb4,0x15,0xbb,0x1b,0xa5,0xed,0xf9,0x4b,0xa7,0xe8,
0x5e,0x6f,0x49,0x24,0xf7,0x32,0xf4,0x9b,0x4c,0x47,0xdc,0xf1,0x28,0x44,0x1c,0x37,
0xdb,0xee,0xfb,0xd8,0xbd,0x4e,0x5c,0xeb,0x07),
chunk_from_chars( /* ECDSA-384 */
0x30,0x81,0xa4,0x02,0x01,0x01,0x04,0x30,0x4b,0xbf,0x6c,0xf5,0x24,0x78,0x53,0x4b,
0x1a,0x91,0x23,0xae,0x30,0xc8,0xb3,0xc9,0xc2,0x9b,0x23,0x07,0x10,0x6f,0x1b,0x47,
0x7c,0xa0,0xd4,0x79,0x3c,0xc4,0x83,0x10,0xd1,0x44,0x07,0xc2,0x1b,0x66,0xff,0xae,
0x76,0x57,0x72,0x90,0x53,0xc2,0xf5,0x29,0xa0,0x07,0x06,0x05,0x2b,0x81,0x04,0x00,
0x22,0xa1,0x64,0x03,0x62,0x00,0x04,0x1e,0xcf,0x1c,0x85,0x9d,0x06,0xa0,0x54,0xa2,
0x24,0x2f,0xd8,0x63,0x56,0x7b,0x70,0x0b,0x7f,0x81,0x96,0xce,0xb9,0x2e,0x35,0x03,
0x9c,0xf9,0x0a,0x5d,0x3b,0x10,0xf7,0x13,0x7a,0x0d,0xca,0x56,0xda,0x1d,0x44,0x84,
0x07,0x6f,0x58,0xdc,0x34,0x7b,0x1d,0x4c,0xdd,0x28,0x10,0xc0,0xe2,0xae,0xf4,0xd6,
0xda,0xea,0xaf,0xfc,0x7a,0xaf,0x59,0x5f,0xbc,0x91,0x65,0xd3,0x21,0x19,0x61,0xbb,
0xfe,0x3c,0xdb,0x47,0xcb,0x7a,0xe7,0x5d,0xbd,0x28,0xde,0x25,0x64,0x9e,0x3a,0xa9,
0x18,0xed,0x24,0xe1,0x1f,0x73,0xcc),
chunk_from_chars( /* ECDSA-521 */
0x30,0x81,0xdc,0x02,0x01,0x01,0x04,0x42,0x01,0xcf,0x38,0xaa,0xa7,0x7a,0x79,0x48,
0xa9,0x60,0x55,0x24,0xa8,0x7e,0xe1,0xbc,0x45,0x35,0x16,0xff,0x18,0xce,0x44,0xa2,
0x0b,0x72,0x6b,0xca,0x0a,0x40,0xb4,0x97,0x13,0x17,0x90,0x50,0x15,0xb9,0xba,0xfc,
0x08,0x0e,0xdb,0xf8,0xfc,0x06,0x35,0x37,0xbf,0xfb,0x25,0x74,0xfe,0x0f,0xe1,0x3c,
0x3a,0xf0,0x0d,0xe0,0x52,0x15,0xa8,0x07,0x6f,0x3e,0xa0,0x07,0x06,0x05,0x2b,0x81,
0x04,0x00,0x23,0xa1,0x81,0x89,0x03,0x81,0x86,0x00,0x04,0x00,0x56,0x81,0x28,0xd6,
0xac,0xe9,0xc8,0x82,0x2c,0xac,0x61,0x6d,0xdd,0x88,0x79,0x00,0xe3,0x7a,0x4d,0x25,
0xc4,0xea,0x05,0x80,0x75,0x48,0xbc,0x75,0x73,0xc4,0xe9,0x76,0x68,0xba,0x51,0xc3,
0x29,0xce,0x7d,0x1b,0xb0,0x8b,0xac,0xc1,0xcc,0x23,0xa7,0x2d,0xa7,0x2c,0x95,0xf6,
0x01,0x40,0x26,0x01,0x1c,0x1c,0x9c,0xe7,0xa7,0xb4,0x0f,0x8e,0xba,0x01,0x07,0xb3,
0xf7,0xbe,0x45,0x20,0xa9,0x9e,0x70,0xf0,0xcf,0x9b,0xa0,0x91,0xe3,0x88,0x8f,0x04,
0x69,0x3d,0x0f,0x2b,0xf3,0xb4,0x03,0x19,0x89,0xcf,0xfa,0x77,0x04,0x15,0xaf,0xdd,
0xf7,0x32,0x76,0x25,0x25,0x05,0x8d,0xfd,0x18,0x8a,0xda,0xd6,0xbc,0x71,0xb8,0x9f,
0x39,0xb0,0xaf,0xcc,0x54,0xb0,0x9c,0x4d,0x54,0xfb,0x46,0x53,0x5f,0xf8,0x45),
};
START_TEST(test_load)
{
private_key_t *privkey;
public_key_t *pubkey;
privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
BUILD_BLOB_ASN1_DER, keys[_i], BUILD_END);
ck_assert(privkey != NULL);
pubkey = privkey->get_public_key(privkey);
ck_assert(pubkey != NULL);
test_good_sig(privkey, pubkey);
test_bad_sigs(pubkey);
pubkey->destroy(pubkey);
privkey->destroy(privkey);
}
END_TEST
Suite *ecdsa_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("ecdsa");
tc = tcase_create("generate");
tcase_add_loop_test(tc, test_gen, 0, countof(key_sizes));
suite_add_tcase(s, tc);
tc = tcase_create("load");
tcase_add_loop_test(tc, test_load, 0, countof(keys));
suite_add_tcase(s, tc);
return s;
}
+248
View File
@@ -0,0 +1,248 @@
/*
* Copyright (C) 2013 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <utils/enum.h>
#include <utils/utils.h>
/*******************************************************************************
* continuous enum
*/
enum {
CONT1,
CONT2,
CONT3,
CONT4,
CONT5,
} test_enum_cont;
/* can't be static */
enum_name_t *test_enum_cont_names;
ENUM_BEGIN(test_enum_cont_names, CONT1, CONT5,
"CONT1", "CONT2", "CONT3", "CONT4", "CONT5");
ENUM_END(test_enum_cont_names, CONT5);
/*******************************************************************************
* split enum
*/
enum {
SPLIT1 = 1,
SPLIT2,
SPLIT3 = 5,
SPLIT4,
SPLIT5 = 255,
} test_enum_split;
/* can't be static */
enum_name_t *test_enum_split_names;
ENUM_BEGIN(test_enum_split_names, SPLIT1, SPLIT2,
"SPLIT1", "SPLIT2");
ENUM_NEXT(test_enum_split_names, SPLIT3, SPLIT4, SPLIT2,
"SPLIT3", "SPLIT4");
ENUM_NEXT(test_enum_split_names, SPLIT5, SPLIT5, SPLIT4,
"SPLIT5");
ENUM_END(test_enum_split_names, SPLIT5);
/*******************************************************************************
* enum_to_name
*/
static struct {
int val;
char *str;
} name_tests_cont[] = {
{-1, NULL},
{CONT1, "CONT1"},
{CONT2, "CONT2"},
{CONT3, "CONT3"},
{CONT4, "CONT4"},
{CONT5, "CONT5"},
{5, NULL},
}, name_tests_split[] = {
{-1, NULL},
{0, NULL},
{SPLIT1, "SPLIT1"},
{SPLIT2, "SPLIT2"},
{3, NULL},
{4, NULL},
{SPLIT3, "SPLIT3"},
{SPLIT4, "SPLIT4"},
{7, NULL},
{254, NULL},
{SPLIT5, "SPLIT5"},
{256, NULL},
};
START_TEST(test_enum_to_name_cont)
{
char *str = enum_to_name(test_enum_cont_names, name_tests_cont[_i].val);
if (str)
{
ck_assert_str_eq(str, name_tests_cont[_i].str);
}
else
{
ck_assert(str == name_tests_cont[_i].str);
}
}
END_TEST
START_TEST(test_enum_to_name_split)
{
char *str = enum_to_name(test_enum_split_names, name_tests_split[_i].val);
if (str)
{
ck_assert_str_eq(str, name_tests_split[_i].str);
}
else
{
ck_assert(str == name_tests_split[_i].str);
}
}
END_TEST
/*******************************************************************************
* enum_from_name
*/
static struct {
int val;
char *str;
} enum_tests_cont[] = {
{CONT1, "CONT1"},
{CONT2, "CONT2"},
{CONT2, "CoNt2"},
{CONT3, "CONT3"},
{CONT4, "CONT4"},
{CONT5, "CONT5"},
{-1, "asdf"},
{-1, ""},
{-1, NULL},
}, enum_tests_split[] = {
{SPLIT1, "SPLIT1"},
{SPLIT1, "split1"},
{SPLIT2, "SPLIT2"},
{SPLIT2, "SpLiT2"},
{SPLIT3, "SPLIT3"},
{SPLIT4, "SPLIT4"},
{SPLIT5, "SPLIT5"},
{-1, "asdf"},
{-1, ""},
{-1, NULL},
};
START_TEST(test_enum_from_name_cont)
{
int val = enum_from_name(test_enum_cont_names, enum_tests_cont[_i].str);
ck_assert_int_eq(val, enum_tests_cont[_i].val);
}
END_TEST
START_TEST(test_enum_from_name_split)
{
int val = enum_from_name(test_enum_split_names, enum_tests_split[_i].str);
ck_assert_int_eq(val, enum_tests_split[_i].val);
}
END_TEST
/*******************************************************************************
* enum_printf_hook
*/
static struct {
int val;
char *str;
} printf_tests_cont[] = {
{-1, "(-1)"},
{CONT1, "CONT1"},
{CONT2, "CONT2"},
{CONT3, "CONT3"},
{CONT4, "CONT4"},
{CONT5, "CONT5"},
{5, "(5)"},
}, printf_tests_split[] = {
{-1, "(-1)"},
{0, "(0)"},
{SPLIT1, "SPLIT1"},
{SPLIT2, "SPLIT2"},
{3, "(3)"},
{4, "(4)"},
{SPLIT3, "SPLIT3"},
{SPLIT4, "SPLIT4"},
{7, "(7)"},
{254, "(254)"},
{SPLIT5, "SPLIT5"},
{256, "(256)"},
};
START_TEST(test_enum_printf_hook_cont)
{
char buf[128];
snprintf(buf, sizeof(buf), "%N", test_enum_cont_names, printf_tests_cont[_i].val);
ck_assert_str_eq(printf_tests_cont[_i].str, buf);
}
END_TEST
START_TEST(test_enum_printf_hook_split)
{
char buf[128];
snprintf(buf, sizeof(buf), "%N", test_enum_split_names, printf_tests_split[_i].val);
ck_assert_str_eq(printf_tests_split[_i].str, buf);
}
END_TEST
START_TEST(test_enum_printf_hook_width)
{
char buf[128];
snprintf(buf, sizeof(buf), "%10N", test_enum_cont_names, CONT1);
ck_assert_str_eq(" CONT1", buf);
snprintf(buf, sizeof(buf), "%-*N", 10, test_enum_cont_names, CONT2);
ck_assert_str_eq("CONT2 ", buf);
snprintf(buf, sizeof(buf), "%3N", test_enum_cont_names, CONT3);
ck_assert_str_eq("CONT3", buf);
}
END_TEST
Suite *enum_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("enum");
tc = tcase_create("enum_to_name");
tcase_add_loop_test(tc, test_enum_to_name_cont, 0, countof(name_tests_cont));
tcase_add_loop_test(tc, test_enum_to_name_split, 0, countof(name_tests_split));
suite_add_tcase(s, tc);
tc = tcase_create("enum_from_name");
tcase_add_loop_test(tc, test_enum_from_name_cont, 0, countof(enum_tests_cont));
tcase_add_loop_test(tc, test_enum_from_name_split, 0, countof(enum_tests_split));
suite_add_tcase(s, tc);
tc = tcase_create("enum_printf_hook");
tcase_add_loop_test(tc, test_enum_printf_hook_cont, 0, countof(printf_tests_cont));
tcase_add_loop_test(tc, test_enum_printf_hook_split, 0, countof(printf_tests_split));
tcase_add_test(tc, test_enum_printf_hook_width);
suite_add_tcase(s, tc);
return s;
}
@@ -0,0 +1,409 @@
/*
* Copyright (C) 2013 Tobias Brunner
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <collections/enumerator.h>
#include <collections/linked_list.h>
/*******************************************************************************
* token test
*/
static const char *token_results1[] = { "abc", "cde", "efg" };
static const char *token_results2[] = { "a", "b", "c" };
static struct {
char *string;
char *sep;
char *trim;
const char **results;
} token_tests[] = {
{"abc, cde, efg", ",", " ", token_results1},
{" abc 1:2 cde;3 4efg5. ", ":;.,", " 12345", token_results1},
{"abc.cde,efg", ",.", "", token_results1},
{" abc cde efg ", " ", " ", token_results1},
{"a'abc' c 'cde' cefg", " ", " abcd", token_results1},
{"'abc' abc 'cde'd 'efg'", " ", " abcd", token_results1},
{"a, b, c", ",", " ", token_results2},
{"a,b,c", ",", " ", token_results2},
{" a 1:2 b;3 4c5. ", ":;.,", " 12345", token_results2},
{"a.b,c", ",.", "", token_results2},
{" a b c ", " ", " ", token_results2},
};
START_TEST(test_token)
{
enumerator_t *enumerator;
const char **results;
char *token;
int tok = 0;
enumerator = enumerator_create_token(token_tests[_i].string,
token_tests[_i].sep, token_tests[_i].trim);
results = token_tests[_i].results;
while (enumerator->enumerate(enumerator, &token))
{
switch (tok)
{
case 0:
case 1:
case 2:
ck_assert_str_eq(token, results[tok]);
break;
default:
fail("unexpected token '%s'", token);
}
tok++;
}
fail_if(tok != 3, "not enough tokens (%d) extracted from '%s'",
tok, token_tests[_i].string);
enumerator->destroy(enumerator);
}
END_TEST
/*******************************************************************************
* utilities for filtered, nested and cleaner tests
*/
static int destroy_data_called;
START_SETUP(setup_destroy_data)
{
destroy_data_called = 0;
}
END_SETUP
START_TEARDOWN(teardown_destroy_data)
{
ck_assert_int_eq(destroy_data_called, 1);
}
END_TEARDOWN
static void destroy_data(void *data)
{
fail_if(data != (void*)101, "data does not match '101' in destructor");
destroy_data_called++;
}
/*******************************************************************************
* filtered test
*/
static bool filter(void *data, int *v, int *vo, int *w, int *wo,
int *x, int *xo, int *y, int *yo, int *z, int *zo)
{
int val = *v;
*vo = val++;
*wo = val++;
*xo = val++;
*yo = val++;
*zo = val++;
fail_if(data != (void*)101, "data does not match '101' in filter function");
return TRUE;
}
static bool filter_odd(void *data, int *item, int *out)
{
fail_if(data != (void*)101, "data does not match '101' in filter function");
*out = *item;
return *item % 2 == 0;
}
START_TEST(test_filtered)
{
int round, v, w, x, y, z;
linked_list_t *list;
enumerator_t *enumerator;
list = linked_list_create_with_items((void*)1, (void*)2, (void*)3, (void*)4,
(void*)5, NULL);
round = 1;
enumerator = enumerator_create_filter(list->create_enumerator(list),
(void*)filter, (void*)101, destroy_data);
while (enumerator->enumerate(enumerator, &v, &w, &x, &y, &z))
{
ck_assert_int_eq(v, round);
ck_assert_int_eq(w, round + 1);
ck_assert_int_eq(x, round + 2);
ck_assert_int_eq(y, round + 3);
ck_assert_int_eq(z, round + 4);
round++;
}
enumerator->destroy(enumerator);
ck_assert_int_eq(round, 6);
list->destroy(list);
}
END_TEST
START_TEST(test_filtered_filter)
{
int count, x;
linked_list_t *list;
enumerator_t *enumerator;
list = linked_list_create_with_items((void*)1, (void*)2, (void*)3, (void*)4,
(void*)5, NULL);
count = 0;
/* should also work without destructor, so set this manually */
destroy_data_called = 1;
enumerator = enumerator_create_filter(list->create_enumerator(list),
(void*)filter_odd, (void*)101, NULL);
while (enumerator->enumerate(enumerator, &x))
{
ck_assert(x % 2 == 0);
count++;
}
enumerator->destroy(enumerator);
ck_assert_int_eq(count, 2);
list->destroy(list);
}
END_TEST
/*******************************************************************************
* nested test
*/
static enumerator_t* create_inner(linked_list_t *outer, void *data)
{
fail_if(data != (void*)101, "data does not match '101' in nested constr.");
return outer->create_enumerator(outer);
}
static enumerator_t* create_inner_null(void *outer, void *data)
{
ck_assert(outer == (void*)1);
fail_if(data != (void*)101, "data does not match '101' in nested constr.");
return NULL;
}
START_TEST(test_nested)
{
linked_list_t *list, *l1, *l2, *l3;
enumerator_t *enumerator;
intptr_t x;
int round;
l1 = linked_list_create_with_items((void*)1, (void*)2, NULL);
l2 = linked_list_create();
l3 = linked_list_create_with_items((void*)3, (void*)4, (void*)5, NULL);
list = linked_list_create_with_items(l1, l2, l3, NULL);
round = 1;
enumerator = enumerator_create_nested(list->create_enumerator(list),
(void*)create_inner, (void*)101, destroy_data);
while (enumerator->enumerate(enumerator, &x))
{
ck_assert_int_eq(round, x);
round++;
}
enumerator->destroy(enumerator);
ck_assert_int_eq(round, 6);
list->destroy(list);
l1->destroy(l1);
l2->destroy(l2);
l3->destroy(l3);
}
END_TEST
START_TEST(test_nested_reset)
{
linked_list_t *list, *l1, *l2, *l3;
enumerator_t *outer, *enumerator;
intptr_t x;
int count = 0;
l1 = linked_list_create_with_items((void*)1, (void*)2, NULL);
l2 = linked_list_create();
l3 = linked_list_create_with_items((void*)3, (void*)4, (void*)5, NULL);
list = linked_list_create_with_items(l1, l2, l3, NULL);
outer = list->create_enumerator(list);
enumerator = enumerator_create_nested(outer, (void*)create_inner,
(void*)101, destroy_data);
while (enumerator->enumerate(enumerator, &x))
{
count++;
}
ck_assert_int_eq(count, 5);
list->reset_enumerator(list, outer);
ck_assert(enumerator->enumerate(enumerator, &x));
ck_assert_int_eq(x, 1);
enumerator->destroy(enumerator);
list->destroy(list);
l1->destroy(l1);
l2->destroy(l2);
l3->destroy(l3);
}
END_TEST
START_TEST(test_nested_empty)
{
linked_list_t *list;
enumerator_t *enumerator;
intptr_t x;
int count;
list = linked_list_create();
count = 0;
enumerator = enumerator_create_nested(list->create_enumerator(list),
(void*)create_inner, (void*)101, destroy_data);
while (enumerator->enumerate(enumerator, &x))
{
count++;
}
enumerator->destroy(enumerator);
ck_assert_int_eq(count, 0);
list->destroy(list);
}
END_TEST
START_TEST(test_nested_null)
{
linked_list_t *list;
enumerator_t *enumerator;
intptr_t x;
int count;
list = linked_list_create_with_items((void*)1, NULL);
count = 0;
/* should also work without destructor, so set this manually */
destroy_data_called = 1;
enumerator = enumerator_create_nested(list->create_enumerator(list),
(void*)create_inner_null, (void*)101, NULL);
while (enumerator->enumerate(enumerator, &x))
{
count++;
}
enumerator->destroy(enumerator);
ck_assert_int_eq(count, 0);
list->destroy(list);
}
END_TEST
/*******************************************************************************
* cleaner test
*/
START_TEST(test_cleaner)
{
enumerator_t *enumerator;
linked_list_t *list;
intptr_t x;
int round;
list = linked_list_create_with_items((void*)1, (void*)2, NULL);
round = 1;
enumerator = enumerator_create_cleaner(list->create_enumerator(list),
destroy_data, (void*)101);
while (enumerator->enumerate(enumerator, &x))
{
ck_assert_int_eq(round, x);
round++;
}
ck_assert_int_eq(round, 3);
enumerator->destroy(enumerator);
list->destroy(list);
}
END_TEST
/*******************************************************************************
* single test
*/
static void single_cleanup(void *data)
{
ck_assert_int_eq((intptr_t)data, 1);
}
static void do_test_single(enumerator_t *enumerator)
{
intptr_t x;
ck_assert(enumerator->enumerate(enumerator, &x));
ck_assert_int_eq(x, 1);
ck_assert(!enumerator->enumerate(enumerator, &x));
enumerator->destroy(enumerator);
}
START_TEST(test_single)
{
enumerator_t *enumerator;
enumerator = enumerator_create_single((void*)1, NULL);
do_test_single(enumerator);
}
END_TEST
START_TEST(test_single_cleanup)
{
enumerator_t *enumerator;
enumerator = enumerator_create_single((void*)1, single_cleanup);
do_test_single(enumerator);
}
END_TEST
Suite *enumerator_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("enumerator");
tc = tcase_create("tokens");
tcase_add_loop_test(tc, test_token, 0, countof(token_tests));
suite_add_tcase(s, tc);
tc = tcase_create("filtered");
tcase_add_checked_fixture(tc, setup_destroy_data, teardown_destroy_data);
tcase_add_test(tc, test_filtered);
tcase_add_test(tc, test_filtered_filter);
suite_add_tcase(s, tc);
tc = tcase_create("nested");
tcase_add_checked_fixture(tc, setup_destroy_data, teardown_destroy_data);
tcase_add_test(tc, test_nested);
tcase_add_test(tc, test_nested_reset);
tcase_add_test(tc, test_nested_empty);
tcase_add_test(tc, test_nested_null);
suite_add_tcase(s, tc);
tc = tcase_create("cleaner");
tcase_add_checked_fixture(tc, setup_destroy_data, teardown_destroy_data);
tcase_add_test(tc, test_cleaner);
suite_add_tcase(s, tc);
tc = tcase_create("single");
tcase_add_test(tc, test_single);
tcase_add_test(tc, test_single_cleanup);
suite_add_tcase(s, tc);
return s;
}
@@ -0,0 +1,346 @@
/*
* Copyright (C) 2010-2013 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <collections/hashtable.h>
#include <utils/chunk.h>
/*******************************************************************************
* string hash table functions
*/
static u_int hash(char *key)
{
return chunk_hash(chunk_from_str(key));
}
static bool equals(char *key1, char *key2)
{
return streq(key1, key2);
}
/*******************************************************************************
* test fixture
*/
static hashtable_t *ht;
START_SETUP(setup_ht)
{
ht = hashtable_create((hashtable_hash_t)hash,
(hashtable_equals_t)equals, 0);
ck_assert_int_eq(ht->get_count(ht), 0);
}
END_SETUP
START_TEARDOWN(teardown_ht)
{
ht->destroy(ht);
}
END_TEARDOWN
/*******************************************************************************
* put/get
*/
START_TEST(test_put_get)
{
char *k1 = "key1", *k2 = "key2", *k3 = "key3";
char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
value = ht->put(ht, k1, v1);
ck_assert_int_eq(ht->get_count(ht), 1);
ck_assert(streq(ht->get(ht, k1), v1));
ck_assert(ht->get(ht, k2) == NULL);
ck_assert(ht->get(ht, k3) == NULL);
ck_assert(value == NULL);
ht->put(ht, k2, v2);
ht->put(ht, k3, v3);
ck_assert_int_eq(ht->get_count(ht), 3);
ck_assert(streq(ht->get(ht, k1), v1));
ck_assert(streq(ht->get(ht, k2), v2));
ck_assert(streq(ht->get(ht, k3), v3));
value = ht->put(ht, k2, v1);
ck_assert_int_eq(ht->get_count(ht), 3);
ck_assert(streq(value, v2));
ck_assert(streq(ht->get(ht, k2), v1));
}
END_TEST
/*******************************************************************************
* get_match
*/
static u_int hash_match(char *key)
{
return chunk_hash(chunk_create(key, 4));
}
static bool equal_match(char *key1, char *key2)
{
if (!strneq(key1, key2, 4))
{
return FALSE;
}
/* look for an item with a key < than what we look for */
return strcmp(key1, key2) >= 0;
}
START_TEST(test_get_match)
{
char *k1 = "key1_a", *k2 = "key2", *k3 = "key1_b", *k4 = "key1_c";
char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
ht = hashtable_create((hashtable_hash_t)hash_match,
(hashtable_equals_t)equals, 0);
ht->put(ht, k1, v1);
ht->put(ht, k2, v2);
value = ht->put(ht, k3, v3);
ck_assert_int_eq(ht->get_count(ht), 3);
ck_assert(streq(ht->get(ht, k1), v1));
ck_assert(streq(ht->get(ht, k2), v2));
ck_assert(streq(ht->get(ht, k3), v3));
ck_assert(value == NULL);
value = ht->get_match(ht, k1, (hashtable_equals_t)equal_match);
ck_assert(value != NULL);
ck_assert(streq(value, v1));
value = ht->get_match(ht, k2, (hashtable_equals_t)equal_match);
ck_assert(value != NULL);
ck_assert(streq(value, v2));
value = ht->get_match(ht, k3, (hashtable_equals_t)equal_match);
ck_assert(value != NULL);
ck_assert(streq(value, v1));
value = ht->get_match(ht, k4, (hashtable_equals_t)equal_match);
ck_assert(value != NULL);
ck_assert(streq(value, v1));
ht->destroy(ht);
}
END_TEST
/*******************************************************************************
* remove
*/
static void do_remove(char *k1, char *k2, char *k3)
{
char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
ht->put(ht, k1, v1);
ht->put(ht, k2, v2);
ht->put(ht, k3, v3);
value = ht->remove(ht, k2);
ck_assert_int_eq(ht->get_count(ht), 2);
ck_assert(streq(ht->get(ht, k1), v1));
ck_assert(streq(ht->get(ht, k3), v3));
ck_assert(streq(value, v2));
ck_assert(ht->get(ht, k2) == NULL);
value = ht->remove(ht, k2);
ck_assert_int_eq(ht->get_count(ht), 2);
ck_assert(value == NULL);
value = ht->remove(ht, k1);
value = ht->remove(ht, k3);
ck_assert_int_eq(ht->get_count(ht), 0);
ck_assert(ht->get(ht, k1) == NULL);
ck_assert(ht->get(ht, k2) == NULL);
ck_assert(ht->get(ht, k3) == NULL);
}
START_TEST(test_remove)
{
char *k1 = "key1", *k2 = "key2", *k3 = "key3";
do_remove(k1, k2, k3);
}
END_TEST
START_TEST(test_remove_one_bucket)
{
char *k1 = "key1_a", *k2 = "key1_b", *k3 = "key1_c";
ht->destroy(ht);
/* set a capacity to avoid rehashing, which would change the items' order */
ht = hashtable_create((hashtable_hash_t)hash_match,
(hashtable_equals_t)equals, 8);
do_remove(k1, k2, k3);
}
END_TEST
/*******************************************************************************
* enumerator
*/
START_TEST(test_enumerator)
{
char *k1 = "key1", *k2 = "key2", *k3 = "key3", *key;
char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
enumerator_t *enumerator;
int count;
ht->put(ht, k1, v1);
ht->put(ht, k2, v2);
ht->put(ht, k3, v3);
count = 0;
enumerator = ht->create_enumerator(ht);
while (enumerator->enumerate(enumerator, &key, &value))
{
ck_assert(streq(key, k1) || streq(key, k2) || streq(key, k3));
ck_assert(streq(value, v1) || streq(value, v2) || streq(value, v3));
ck_assert(!streq(key, k1) || streq(value, v1));
ck_assert(!streq(key, k2) || streq(value, v2));
ck_assert(!streq(key, k3) || streq(value, v3));
count++;
}
enumerator->destroy(enumerator);
ck_assert_int_eq(count, 3);
count = 0;
enumerator = ht->create_enumerator(ht);
while (enumerator->enumerate(enumerator, NULL, NULL))
{
count++;
}
enumerator->destroy(enumerator);
ck_assert_int_eq(count, 3);
value = ht->remove(ht, k1);
value = ht->remove(ht, k2);
value = ht->remove(ht, k3);
count = 0;
enumerator = ht->create_enumerator(ht);
while (enumerator->enumerate(enumerator, &key, &value))
{
count++;
}
enumerator->destroy(enumerator);
ck_assert_int_eq(count, 0);
}
END_TEST
/*******************************************************************************
* remove_at
*/
static void do_remove_at(char *k1, char *k2, char *k3)
{
char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value, *key;
enumerator_t *enumerator;
ht->put(ht, k1, v1);
ht->put(ht, k2, v2);
ht->put(ht, k3, v3);
enumerator = ht->create_enumerator(ht);
ht->remove_at(ht, enumerator);
while (enumerator->enumerate(enumerator, &key, &value))
{
if (streq(key, k2))
{
ht->remove_at(ht, enumerator);
}
}
enumerator->destroy(enumerator);
ck_assert_int_eq(ht->get_count(ht), 2);
ck_assert(ht->get(ht, k1) != NULL);
ck_assert(ht->get(ht, k3) != NULL);
ck_assert(ht->get(ht, k2) == NULL);
ht->put(ht, k2, v2);
ck_assert_int_eq(ht->get_count(ht), 3);
ck_assert(ht->get(ht, k1) != NULL);
ck_assert(ht->get(ht, k2) != NULL);
ck_assert(ht->get(ht, k3) != NULL);
enumerator = ht->create_enumerator(ht);
while (enumerator->enumerate(enumerator, &key, &value))
{
ht->remove_at(ht, enumerator);
}
enumerator->destroy(enumerator);
ck_assert_int_eq(ht->get_count(ht), 0);
ck_assert(ht->get(ht, k1) == NULL);
ck_assert(ht->get(ht, k2) == NULL);
ck_assert(ht->get(ht, k3) == NULL);
}
START_TEST(test_remove_at)
{
char *k1 = "key1", *k2 = "key2", *k3 = "key3";
do_remove_at(k1, k2, k3);
}
END_TEST
START_TEST(test_remove_at_one_bucket)
{
char *k1 = "key1_a", *k2 = "key1_b", *k3 = "key1_c";
ht->destroy(ht);
/* set a capacity to avoid rehashing, which would change the items' order */
ht = hashtable_create((hashtable_hash_t)hash_match,
(hashtable_equals_t)equals, 8);
do_remove_at(k1, k2, k3);
}
END_TEST
Suite *hashtable_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("hashtable");
tc = tcase_create("put/get");
tcase_add_checked_fixture(tc, setup_ht, teardown_ht);
tcase_add_test(tc, test_put_get);
suite_add_tcase(s, tc);
tc = tcase_create("get_match");
tcase_add_test(tc, test_get_match);
suite_add_tcase(s, tc);
tc = tcase_create("remove");
tcase_add_checked_fixture(tc, setup_ht, teardown_ht);
tcase_add_test(tc, test_remove);
tcase_add_test(tc, test_remove_one_bucket);
suite_add_tcase(s, tc);
tc = tcase_create("enumerator");
tcase_add_checked_fixture(tc, setup_ht, teardown_ht);
tcase_add_test(tc, test_enumerator);
suite_add_tcase(s, tc);
tc = tcase_create("remove_at");
tcase_add_checked_fixture(tc, setup_ht, teardown_ht);
tcase_add_test(tc, test_remove_at);
tcase_add_test(tc, test_remove_at_one_bucket);
suite_add_tcase(s, tc);
return s;
}
+651
View File
@@ -0,0 +1,651 @@
/*
* Copyright (C) 2013 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <networking/host.h>
/**
* Verify a netmask (a number of set bits starting at byte 0)
* Can also be used to check for %any (mask == 0)
*/
static void verify_netmask(chunk_t addr, int mask)
{
int byte, bit;
for (byte = 0; byte < addr.len; byte++)
{
for (bit = 7; bit >= 0; bit--)
{
int val = (addr.ptr[byte] >> bit) & 0x01;
if (mask-- > 0)
{
ck_assert_int_eq(val, 1);
}
else
{
ck_assert_int_eq(val, 0);
}
}
}
}
/*******************************************************************************
* host_create_any
*/
static void verify_any(host_t *host, int family, u_int16_t port)
{
verify_netmask(host->get_address(host), 0);
ck_assert(host->is_anyaddr(host));
ck_assert_int_eq(host->get_port(host), port);
ck_assert_int_eq(host->get_family(host), family);
}
static void test_create_any(int family)
{
host_t *host;
host = host_create_any(family);
verify_any(host, family, 0);
host->destroy(host);
}
START_TEST(test_create_any_v4)
{
test_create_any(AF_INET);
}
END_TEST
START_TEST(test_create_any_v6)
{
test_create_any(AF_INET6);
}
END_TEST
START_TEST(test_create_any_other)
{
host_t *host;
host = host_create_any(AF_UNSPEC);
ck_assert(host == NULL);
}
END_TEST
/*******************************************************************************
* host_create_from_string
*/
static void verify_address(host_t *host, chunk_t addr, int family, u_int16_t port)
{
ck_assert(chunk_equals(host->get_address(host), addr));
ck_assert(!host->is_anyaddr(host));
ck_assert_int_eq(host->get_port(host), port);
ck_assert_int_eq(host->get_family(host), family);
}
static const chunk_t addr_v4 = chunk_from_chars(0xc0, 0xa8, 0x00, 0x01);
static const chunk_t addr_v6 = chunk_from_chars(0xfe, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01);
START_TEST(test_create_from_string_v4)
{
host_t *host;
host = host_create_from_string("%any", 500);
verify_any(host, AF_INET, 500);
host->destroy(host);
host = host_create_from_string("%any4", 500);
verify_any(host, AF_INET, 500);
host->destroy(host);
host = host_create_from_string("0.0.0.0", 500);
verify_any(host, AF_INET, 500);
host->destroy(host);
host = host_create_from_string("192.168.0.1", 500);
verify_address(host, addr_v4, AF_INET, 500);
host->destroy(host);
host = host_create_from_string("192.168.0.1::500", 500);
ck_assert(host == NULL);
host = host_create_from_string("123.456.789.012", 500);
ck_assert(host == NULL);
host = host_create_from_string("1.1.1.1.1.1.1.1", 500);
ck_assert(host == NULL);
host = host_create_from_string("foo.b.a.r", 500);
ck_assert(host == NULL);
}
END_TEST
START_TEST(test_create_from_string_any_v6)
{
host_t *host;
host = host_create_from_string("%any6", 500);
verify_any(host, AF_INET6, 500);
host->destroy(host);
host = host_create_from_string("::", 500);
verify_any(host, AF_INET6, 500);
host->destroy(host);
host = host_create_from_string("fec1::1", 500);
verify_address(host, addr_v6, AF_INET6, 500);
host->destroy(host);
host = host_create_from_string("fec1::1.500", 500);
ck_assert(host == NULL);
host = host_create_from_string("f::e::c::1::1", 500);
ck_assert(host == NULL);
host = host_create_from_string("foo::bar", 500);
ck_assert(host == NULL);
}
END_TEST
/*******************************************************************************
* host_create_from_string_and_family
*/
static void test_create_from_string_and_family_any(char *string, int family,
int expected)
{
host_t *host;
host = host_create_from_string_and_family(string, family, 500);
if (expected == AF_UNSPEC)
{
ck_assert(host == NULL);
}
else
{
verify_any(host, expected, 500);
host->destroy(host);
}
}
static void test_create_from_string_and_family_addr(char *string, chunk_t addr,
int family, int expected)
{
host_t *host;
host = host_create_from_string_and_family(string, family, 500);
if (expected == AF_UNSPEC)
{
ck_assert(host == NULL);
}
else
{
verify_address(host, addr, expected, 500);
host->destroy(host);
}
}
START_TEST(test_create_from_string_and_family_v4)
{
test_create_from_string_and_family_any("%any", AF_INET, AF_INET);
test_create_from_string_and_family_any("%any4", AF_INET, AF_INET);
test_create_from_string_and_family_any("0.0.0.0", AF_INET, AF_INET);
test_create_from_string_and_family_any("%any4", AF_INET6, AF_UNSPEC);
test_create_from_string_and_family_any("0.0.0.0", AF_INET6, AF_UNSPEC);
test_create_from_string_and_family_addr("192.168.0.1", addr_v4, AF_INET, AF_INET);
test_create_from_string_and_family_addr("192.168.0.1", addr_v4, AF_INET6, AF_UNSPEC);
}
END_TEST
START_TEST(test_create_from_string_and_family_v6)
{
test_create_from_string_and_family_any("%any", AF_INET6, AF_INET6);
test_create_from_string_and_family_any("%any6", AF_INET6, AF_INET6);
test_create_from_string_and_family_any("::", AF_INET6, AF_INET6);
test_create_from_string_and_family_any("%any6", AF_INET, AF_UNSPEC);
test_create_from_string_and_family_any("::", AF_INET, AF_UNSPEC);
test_create_from_string_and_family_addr("fec1::1", addr_v6, AF_INET6, AF_INET6);
test_create_from_string_and_family_addr("fec1::1", addr_v6, AF_INET, AF_UNSPEC);
}
END_TEST
START_TEST(test_create_from_string_and_family_other)
{
test_create_from_string_and_family_any("%any", AF_UNSPEC, AF_INET);
test_create_from_string_and_family_any("%any4", AF_UNSPEC, AF_INET);
test_create_from_string_and_family_any("0.0.0.0", AF_UNSPEC, AF_INET);
test_create_from_string_and_family_any("%any6", AF_UNSPEC, AF_INET6);
test_create_from_string_and_family_any("::", AF_UNSPEC, AF_INET6);
test_create_from_string_and_family_addr("192.168.0.1", addr_v4, AF_UNSPEC, AF_INET);
test_create_from_string_and_family_addr("fec1::1", addr_v6, AF_UNSPEC, AF_INET6);
}
END_TEST
/*******************************************************************************
* host_create_from_sockaddr
*/
START_TEST(test_create_from_sockaddr_v4)
{
struct sockaddr_in addr = {
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
.sin_len = sizeof(struct sockaddr_in),
#endif
.sin_family = AF_INET,
.sin_port = htons(500),
}, *val;
socklen_t *socklen;
host_t *host;
host = host_create_from_sockaddr((sockaddr_t*)&addr);
verify_any(host, AF_INET, 500);
val = (struct sockaddr_in*)host->get_sockaddr(host);
ck_assert(memeq(&addr, val, sizeof(addr)));
socklen = host->get_sockaddr_len(host);
ck_assert(*socklen == sizeof(addr));
host->destroy(host);
}
END_TEST
START_TEST(test_create_from_sockaddr_v6)
{
struct sockaddr_in6 addr = {
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
.sin6_len = sizeof(struct sockaddr_in6),
#endif
.sin6_family = AF_INET6,
.sin6_port = htons(500),
}, *val;
socklen_t *socklen;
host_t *host;
host = host_create_from_sockaddr((sockaddr_t*)&addr);
verify_any(host, AF_INET6, 500);
val = (struct sockaddr_in6*)host->get_sockaddr(host);
ck_assert(memeq(&addr, val, sizeof(addr)));
socklen = host->get_sockaddr_len(host);
ck_assert(*socklen == sizeof(addr));
host->destroy(host);
}
END_TEST
START_TEST(test_create_from_sockaddr_other)
{
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
};
host_t *host;
host = host_create_from_sockaddr((sockaddr_t*)&addr);
ck_assert(host == NULL);
}
END_TEST
/*******************************************************************************
* host_create_from_chunk
*/
START_TEST(test_create_from_chunk_v4)
{
host_t *host;
host = host_create_from_chunk(AF_INET, addr_v4, 500);
verify_address(host, addr_v4, AF_INET, 500);
host->destroy(host);
host = host_create_from_chunk(AF_UNSPEC, addr_v4, 500);
verify_address(host, addr_v4, AF_INET, 500);
host->destroy(host);
host = host_create_from_chunk(AF_INET, chunk_empty, 500);
ck_assert(host == NULL);
host = host_create_from_chunk(AF_UNSPEC, chunk_empty, 500);
ck_assert(host == NULL);
}
END_TEST
START_TEST(test_create_from_chunk_v6)
{
host_t *host;
host = host_create_from_chunk(AF_INET6, addr_v6, 500);
verify_address(host, addr_v6, AF_INET6, 500);
host->destroy(host);
host = host_create_from_chunk(AF_UNSPEC, addr_v6, 500);
verify_address(host, addr_v6, AF_INET6, 500);
host->destroy(host);
host = host_create_from_chunk(AF_INET6, chunk_empty, 500);
ck_assert(host == NULL);
}
END_TEST
START_TEST(test_create_from_chunk_other)
{
host_t *host;
host = host_create_from_chunk(AF_UNIX, addr_v6, 500);
ck_assert(host == NULL);
}
END_TEST
/*******************************************************************************
* host_create_from_subnet
*/
START_TEST(test_create_from_subnet_v4)
{
host_t *host;
int bits = -1;
host = host_create_from_subnet("0.0.0.0/0", &bits);
verify_any(host, AF_INET, 0);
ck_assert_int_eq(bits, 0);
host->destroy(host);
host = host_create_from_subnet("192.168.0.1", &bits);
verify_address(host, addr_v4, AF_INET, 0);
ck_assert_int_eq(bits, 32);
host->destroy(host);
host = host_create_from_subnet("192.168.0.1/24", &bits);
verify_address(host, addr_v4, AF_INET, 0);
ck_assert_int_eq(bits, 24);
host->destroy(host);
host = host_create_from_subnet("foo.b.a.r", &bits);
ck_assert(host == NULL);
}
END_TEST
START_TEST(test_create_from_subnet_v6)
{
host_t *host;
int bits = -1;
host = host_create_from_subnet("::/0", &bits);
verify_any(host, AF_INET6, 0);
ck_assert_int_eq(bits, 0);
host->destroy(host);
host = host_create_from_subnet("fec1::1", &bits);
verify_address(host, addr_v6, AF_INET6, 0);
ck_assert_int_eq(bits, 128);
host->destroy(host);
host = host_create_from_subnet("fec1::1/64", &bits);
verify_address(host, addr_v6, AF_INET6, 0);
ck_assert_int_eq(bits, 64);
host->destroy(host);
host = host_create_from_subnet("foo::bar", &bits);
ck_assert(host == NULL);
}
END_TEST
/*******************************************************************************
* host_create_netmask
*/
static void test_create_netmask(int family)
{
host_t *netmask;
int i, len = (family == AF_INET) ? 32 : 128;
netmask = host_create_netmask(family, -1);
ck_assert(netmask == NULL);
for (i = 0; i <= len; i++)
{
netmask = host_create_netmask(family, i);
verify_netmask(netmask->get_address(netmask), i);
netmask->destroy(netmask);
}
netmask = host_create_netmask(family, len + 1);
ck_assert(netmask == NULL);
}
START_TEST(test_create_netmask_v4)
{
test_create_netmask(AF_INET);
}
END_TEST
START_TEST(test_create_netmask_v6)
{
test_create_netmask(AF_INET6);
}
END_TEST
START_TEST(test_create_netmask_other)
{
host_t *netmask;
netmask = host_create_netmask(AF_UNSPEC, 0);
ck_assert(netmask == NULL);
}
END_TEST
/*******************************************************************************
* equals, ip_equals
*/
START_TEST(test_equals)
{
host_t *a, *b;
a = host_create_from_string("192.168.0.1", 500);
b = host_create_from_string("192.168.0.1", 0);
ck_assert(!a->equals(a, b));
ck_assert(!b->equals(b, a));
ck_assert(a->ip_equals(a, b));
ck_assert(b->ip_equals(b, a));
b->set_port(b, 500);
ck_assert(a->equals(a, b));
ck_assert(b->equals(b, a));
ck_assert(a->ip_equals(a, b));
ck_assert(b->ip_equals(b, a));
b->destroy(b);
b = host_create_from_string("192.168.0.2", 500);
ck_assert(!a->ip_equals(a, b));
ck_assert(!a->equals(a, b));
b->destroy(b);
b = host_create_from_string("fec1::1", 500);
ck_assert(!a->ip_equals(a, b));
ck_assert(!a->equals(a, b));
a->destroy(a);
a = host_create_from_string("fec1::1", 500);
ck_assert(a->equals(a, b));
ck_assert(a->ip_equals(a, b));
a->destroy(a);
b->destroy(b);
}
END_TEST
START_TEST(test_equals_any)
{
host_t *a, *b;
a = host_create_from_string("%any", 500);
b = host_create_from_string("%any", 0);
ck_assert(!a->equals(a, b));
ck_assert(a->ip_equals(a, b));
b->set_port(b, 500);
ck_assert(a->equals(a, b));
ck_assert(a->ip_equals(a, b));
b->destroy(b);
b = host_create_from_string("%any6", 0);
ck_assert(a->ip_equals(a, b));
ck_assert(!a->equals(a, b));
b->set_port(b, 500);
ck_assert(a->ip_equals(a, b));
ck_assert(a->equals(a, b));
a->destroy(a);
b->destroy(b);
}
END_TEST
/*******************************************************************************
* clone
*/
START_TEST(test_clone)
{
host_t *a, *b;
a = host_create_from_string("192.168.0.1", 500);
b = a->clone(a);
ck_assert(a != b);
ck_assert(a->equals(a, b));
a->destroy(a);
b->destroy(b);
}
END_TEST
/*******************************************************************************
* printf hook
*/
static struct {
char *addr;
u_int16_t port;
/* results for %H, %+H, %#H (falls back to [0]) */
char *result[3];
} printf_data[] = {
{NULL, 0, { "(null)" }},
{NULL, 500, { "(null)" }},
{"%any", 0, { "%any", "0.0.0.0", "0.0.0.0[0]" }},
{"%any", 500, { "%any", "0.0.0.0", "0.0.0.0[500]" }},
{"%any6", 0, { "%any6", "::", "::[0]" }},
{"%any6", 500, { "%any6", "::", "::[500]" }},
{"192.168.0.1", 0, { "192.168.0.1", "192.168.0.1", "192.168.0.1[0]" }},
{"192.168.0.1", 500, { "192.168.0.1", "192.168.0.1", "192.168.0.1[500]" }},
{"fec1::1", 0, { "fec1::1", "fec1::1", "fec1::1[0]" }},
{"fec1::1", 500, { "fec1::1", "fec1::1", "fec1::1[500]" }},
};
static void verify_printf(host_t *host, const char *format, char *expected)
{
char buf[64];
snprintf(buf, sizeof(buf), format, host);
ck_assert_str_eq(expected, buf);
}
START_TEST(test_printf_hook)
{
static const char *formats[] = { "%H", "%+H", "%#H" };
host_t *host = NULL;
char *expected;
int i;
if (printf_data[_i].addr)
{
host = host_create_from_string(printf_data[_i].addr,
printf_data[_i].port);
}
for (i = 0; i < countof(formats); i++)
{
expected = printf_data[_i].result[i];
expected = expected ?: printf_data[_i].result[0];
verify_printf(host, formats[i], expected);
}
DESTROY_IF(host);
}
END_TEST
START_TEST(test_printf_hook_align)
{
host_t *host;
verify_printf(NULL, "%14H", " (null)");
verify_printf(NULL, "%-14H", "(null) ");
host = host_create_from_string("192.168.0.1", 0);
verify_printf(host, "%14H", " 192.168.0.1");
verify_printf(host, "%-14H", "192.168.0.1 ");
verify_printf(host, "%4H", "192.168.0.1");
verify_printf(host, "%-4H", "192.168.0.1");
host->destroy(host);
}
END_TEST
Suite *host_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("host");
tc = tcase_create("host_create_any");
tcase_add_test(tc, test_create_any_v4);
tcase_add_test(tc, test_create_any_v6);
tcase_add_test(tc, test_create_any_other);
suite_add_tcase(s, tc);
tc = tcase_create("host_create_from_string");
tcase_add_test(tc, test_create_from_string_v4);
tcase_add_test(tc, test_create_from_string_any_v6);
suite_add_tcase(s, tc);
tc = tcase_create("host_create_from_string_and_family");
tcase_add_test(tc, test_create_from_string_and_family_v4);
tcase_add_test(tc, test_create_from_string_and_family_v6);
tcase_add_test(tc, test_create_from_string_and_family_other);
suite_add_tcase(s, tc);
tc = tcase_create("host_create_from_sockaddr");
tcase_add_test(tc, test_create_from_sockaddr_v4);
tcase_add_test(tc, test_create_from_sockaddr_v6);
tcase_add_test(tc, test_create_from_sockaddr_other);
suite_add_tcase(s, tc);
tc = tcase_create("host_create_from_chunk");
tcase_add_test(tc, test_create_from_chunk_v4);
tcase_add_test(tc, test_create_from_chunk_v6);
tcase_add_test(tc, test_create_from_chunk_other);
suite_add_tcase(s, tc);
tc = tcase_create("host_create_from_subnet");
tcase_add_test(tc, test_create_from_subnet_v4);
tcase_add_test(tc, test_create_from_subnet_v6);
suite_add_tcase(s, tc);
tc = tcase_create("host_create_netmask");
tcase_add_test(tc, test_create_netmask_v4);
tcase_add_test(tc, test_create_netmask_v6);
tcase_add_test(tc, test_create_netmask_other);
suite_add_tcase(s, tc);
tc = tcase_create("equals, ip_equals");
tcase_add_test(tc, test_equals);
tcase_add_test(tc, test_equals_any);
suite_add_tcase(s, tc);
tc = tcase_create("clone");
tcase_add_test(tc, test_clone);
suite_add_tcase(s, tc);
tc = tcase_create("printf hook");
tcase_add_loop_test(tc, test_printf_hook, 0, countof(printf_data));
tcase_add_test(tc, test_printf_hook_align);
suite_add_tcase(s, tc);
return s;
}
@@ -0,0 +1,857 @@
/*
* Copyright (C) 2013 Tobias Brunner
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <utils/identification.h>
/*******************************************************************************
* create (_from_encoding, _from_data, _from_string, _from_sockaddr)
*/
START_TEST(test_from_encoding)
{
identification_t *a;
chunk_t expected, encoding;
/* only ID_ANY is handled differently, for all other types the following
* applies. should we perhaps test that this is in fact the case? */
expected = chunk_from_str("[email protected]");
a = identification_create_from_encoding(ID_RFC822_ADDR, expected);
ck_assert(ID_RFC822_ADDR == a->get_type(a));
encoding = a->get_encoding(a);
ck_assert(expected.ptr != encoding.ptr);
ck_assert(chunk_equals(expected, encoding));
a->destroy(a);
a = identification_create_from_encoding(ID_ANY, expected);
ck_assert(ID_ANY == a->get_type(a));
encoding = a->get_encoding(a);
ck_assert(encoding.ptr == NULL);
ck_assert(encoding.len == 0);
a->destroy(a);
}
END_TEST
START_TEST(test_from_data)
{
identification_t *a;
chunk_t expected, encoding;
/* this uses the DN parser (C=CH) */
expected = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48);
a = identification_create_from_data(expected);
ck_assert(ID_DER_ASN1_DN == a->get_type(a));
encoding = a->get_encoding(a);
ck_assert(expected.ptr != encoding.ptr);
ck_assert(chunk_equals(expected, encoding));
a->destroy(a);
/* everything else is handled by the string parser */
expected = chunk_from_str("[email protected]");
a = identification_create_from_data(expected);
ck_assert(ID_RFC822_ADDR == a->get_type(a));
encoding = a->get_encoding(a);
ck_assert(expected.ptr != encoding.ptr);
ck_assert(chunk_equals(expected, encoding));
a->destroy(a);
}
END_TEST
START_TEST(test_from_sockaddr)
{
identification_t *a;
chunk_t expected, encoding;
struct sockaddr_in in = {
.sin_family = AF_INET,
};
struct sockaddr_in6 in6 = {
.sin6_family = AF_INET6,
};
expected = chunk_from_chars(0xc0, 0xa8, 0x01, 0x01);
memcpy(&in.sin_addr, expected.ptr, sizeof(in.sin_addr));
a = identification_create_from_sockaddr((sockaddr_t*)&in);
ck_assert(ID_IPV4_ADDR == a->get_type(a));
encoding = a->get_encoding(a);
ck_assert(chunk_equals(expected, encoding));
a->destroy(a);
expected = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01);
memcpy(&in6.sin6_addr, expected.ptr, sizeof(in6.sin6_addr));
a = identification_create_from_sockaddr((sockaddr_t*)&in6);
ck_assert(ID_IPV6_ADDR == a->get_type(a));
encoding = a->get_encoding(a);
ck_assert(chunk_equals(expected, encoding));
a->destroy(a);
in6.sin6_family = AF_UNSPEC;
a = identification_create_from_sockaddr((sockaddr_t*)&in6);
ck_assert(ID_ANY == a->get_type(a));
a->destroy(a);
}
END_TEST
static struct {
char *id;
id_type_t type;
struct {
enum {
ENC_CHUNK,
ENC_STRING,
ENC_SIMPLE,
} type;
union {
chunk_t c;
char *s;
} data;
} result;
} string_data[] = {
{NULL, ID_ANY, { .type = ENC_CHUNK }},
{"", ID_ANY, { .type = ENC_CHUNK }},
{"%any", ID_ANY, { .type = ENC_CHUNK }},
{"%any6", ID_ANY, { .type = ENC_CHUNK }},
{"0.0.0.0", ID_ANY, { .type = ENC_CHUNK }},
{"0::0", ID_ANY, { .type = ENC_CHUNK }},
{"::", ID_ANY, { .type = ENC_CHUNK }},
{"*", ID_ANY, { .type = ENC_CHUNK }},
{"any", ID_FQDN, { .type = ENC_SIMPLE }},
{"any6", ID_FQDN, { .type = ENC_SIMPLE }},
{"0", ID_FQDN, { .type = ENC_SIMPLE }},
{"**", ID_FQDN, { .type = ENC_SIMPLE }},
{"192.168.1.1", ID_IPV4_ADDR, { .type = ENC_CHUNK,
.data.c = chunk_from_chars(0xc0, 0xa8, 0x01, 0x01) }},
{"192.168.",ID_FQDN, { .type = ENC_SIMPLE }},
{".", ID_FQDN, { .type = ENC_SIMPLE }},
{"fec0::1", ID_IPV6_ADDR, { .type = ENC_CHUNK,
.data.c = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01) }},
{"fec0::", ID_IPV6_ADDR, { .type = ENC_CHUNK,
.data.c = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) }},
{"fec0:", ID_KEY_ID, { .type = ENC_SIMPLE }},
{":", ID_KEY_ID, { .type = ENC_SIMPLE }},
{"[email protected]", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
{"alice@strongswan", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
{"alice@", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
{"alice", ID_FQDN, { .type = ENC_SIMPLE }},
{"@", ID_FQDN, { .type = ENC_CHUNK }},
{" @", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
{"@strongswan.org", ID_FQDN, { .type = ENC_STRING,
.data.s = "strongswan.org" }},
{"@#deadbeef", ID_KEY_ID, { .type = ENC_CHUNK,
.data.c = chunk_from_chars(0xde, 0xad, 0xbe, 0xef) }},
{"@#deadbee", ID_KEY_ID, { .type = ENC_CHUNK,
.data.c = chunk_from_chars(0x0d, 0xea, 0xdb, 0xee) }},
{"foo=bar", ID_KEY_ID, { .type = ENC_SIMPLE }},
{"foo=", ID_KEY_ID, { .type = ENC_SIMPLE }},
{"=bar", ID_KEY_ID, { .type = ENC_SIMPLE }},
{"C=", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
.data.c = chunk_from_chars(0x30, 0x0b, 0x31, 0x09, 0x30, 0x07, 0x06,
0x03, 0x55, 0x04, 0x06, 0x13, 0x00)}},
{"C=CH", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
.data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}},
{"C=CH,", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
.data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}},
{"C=CH, ", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
.data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}},
{"C=CH, O", ID_KEY_ID, { .type = ENC_SIMPLE }},
};
START_TEST(test_from_string)
{
identification_t *a;
chunk_t encoding, expected;
char *id;
id = string_data[_i].id;
a = identification_create_from_string(id);
fail_unless(a->get_type(a) == string_data[_i].type,
"type of id '%s' is %N, %N expected", id,
id_type_names, a->get_type(a),
id_type_names, string_data[_i].type);
encoding = a->get_encoding(a);
switch (string_data[_i].result.type)
{
case ENC_SIMPLE:
expected = chunk_from_str(string_data[_i].id);
break;
case ENC_STRING:
expected = chunk_from_str(string_data[_i].result.data.s);
break;
case ENC_CHUNK:
expected = string_data[_i].result.data.c;
break;
default:
fail("unexpected result type");
}
ck_assert(!id || (char*)encoding.ptr != id);
if (expected.ptr)
{
fail_unless(chunk_equals(encoding, expected),
"parsing '%s' failed\nencoding %B\nexpected %B\n",
id, &encoding, &expected);
}
else
{
ck_assert(encoding.ptr == NULL);
ck_assert(encoding.len == 0);
}
a->destroy(a);
}
END_TEST
/*******************************************************************************
* printf_hook
*/
static void string_equals(char *a_str, char *b_str)
{
identification_t *b;
char buf[128];
b = b_str ? identification_create_from_string(b_str) : NULL;
snprintf(buf, sizeof(buf), "%Y", b);
DESTROY_IF(b);
ck_assert_str_eq(a_str, buf);
}
static void string_equals_id(char *a_str, identification_t *b)
{
char buf[128];
snprintf(buf, sizeof(buf), "%Y", b);
DESTROY_IF(b);
ck_assert_str_eq(a_str, buf);
}
START_TEST(test_printf_hook)
{
string_equals("(null)", NULL);
string_equals("%any", "");
string_equals("%any", "%any");
string_equals("%any", "*");
string_equals("192.168.1.1", "192.168.1.1");
string_equals_id("(invalid ID_IPV4_ADDR)",
identification_create_from_encoding(ID_IPV4_ADDR, chunk_empty));
string_equals("fec0::1", "fec0::1");
string_equals("fec0::1", "fec0:0:0::1");
string_equals_id("(invalid ID_IPV6_ADDR)",
identification_create_from_encoding(ID_IPV6_ADDR, chunk_empty));
string_equals_id("(unknown ID type: 255)",
identification_create_from_encoding(255, chunk_empty));
string_equals("[email protected]", "[email protected]");
string_equals("[email protected]", "[email protected]");
/* non-printable characters */
string_equals_id("[email protected]", identification_create_from_encoding(ID_RFC822_ADDR,
chunk_from_chars(0xfa, 0xfb, 0xfc, 0xfd, 0x40, 0x73, 0x74, 0x72,
0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e,
0x6f, 0x72, 0x67)));
/* not a DN => ID_KEY_ID => no normalization */
string_equals("C=CH, AsdF=asdf", "C=CH, AsdF=asdf");
string_equals_id("[email protected]", identification_create_from_encoding(ID_KEY_ID,
chunk_from_str("[email protected]")));
/* non-printable characters */
string_equals_id("de:ad:be:ef", identification_create_from_encoding(ID_KEY_ID,
chunk_from_chars(0xde, 0xad, 0xbe, 0xef)));
/* printable characters */
string_equals_id("ABCDEFGHIJKLMNOPQRS",
identification_create_from_encoding(ID_KEY_ID,
chunk_from_chars(0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
0x51, 0x52, 0x53)));
/* ABCDEFGHIJKLMNOPQRST is printable but has the length of a SHA1 hash */
string_equals_id("41:42:43:44:45:46:47:48:49:4a:4b:4c:4d:4e:4f:50:51:52:53:54",
identification_create_from_encoding(ID_KEY_ID,
chunk_from_chars(0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
0x51, 0x52, 0x53, 0x54)));
string_equals_id("", identification_create_from_encoding(ID_DER_ASN1_DN, chunk_empty));
string_equals("C=", "C=");
string_equals("C=", "C=,");
string_equals("C=", "C=, ");
string_equals("C=", "C= , ");
string_equals("C=, O=strongSwan", "C=, O=strongSwan");
string_equals("C=CH, O=", "C=CH, O=");
string_equals("C=CH, O=strongSwan, CN=strongswan.org",
"C=CH, O=strongSwan, CN=strongswan.org");
string_equals("CN=strongswan.org, O=strongSwan, C=CH",
"cn=strongswan.org, o=strongSwan, c=CH");
string_equals("C=CH, O=strongSwan, CN=strongswan.org",
"C=CH,O=strongSwan,CN=strongswan.org");
string_equals("C=CH, O=strongSwan, CN=strongswan.org",
"/C=CH/O=strongSwan/CN=strongswan.org");
string_equals("CN=strongswan.org, O=strongSwan, C=CH",
"CN=strongswan.org,O=strongSwan,C=CH");
string_equals("C=CH, [email protected], CN=moon",
"C=CH, [email protected], CN=moon");
string_equals("C=CH, [email protected], CN=moon",
"C=CH, [email protected], CN=moon");
/* C=CH, pseudonym=ANO (pseudonym is currently not recognized) */
string_equals_id("C=CH, 55:04:41=ANO", identification_create_from_encoding(ID_DER_ASN1_DN,
chunk_from_chars(0x30, 0x19, 0x31, 0x17, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x30, 0x0a, 0x06,
0x03, 0x55, 0x04, 0x41, 0x13, 0x03, 0x41, 0x4e, 0x4f)));
/* C=CH, O=strongSwan (but instead of a 2nd OID -0x06- we got NULL -0x05) */
string_equals_id("C=CH, (invalid ID_DER_ASN1_DN)", identification_create_from_encoding(ID_DER_ASN1_DN,
chunk_from_chars(0x30, 0x20, 0x31, 0x1e, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x30, 0x11, 0x05,
0x03, 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x73, 0x74, 0x72,
0x6f, 0x6e, 0x67, 0x53, 0x77, 0x61, 0x6e)));
/* [email protected] as GN */
string_equals_id("(ASN.1 general name)", identification_create_from_encoding(ID_DER_ASN1_GN,
chunk_from_chars(0x81, 0x14, 0x6d, 0x6f, 0x6f, 0x6e, 0x40, 0x73, 0x74,
0x72, 0x6f, 0x6e, 0x67, 0x73, 0x77, 0x61, 0x6e, 0x2e,
0x6f, 0x72, 0x67)));
}
END_TEST
START_TEST(test_printf_hook_width)
{
identification_t *a;
char buf[128];
a = identification_create_from_string("[email protected]");
snprintf(buf, sizeof(buf), "%25Y", a);
ck_assert_str_eq(" [email protected]", buf);
snprintf(buf, sizeof(buf), "%-*Y", 25, a);
ck_assert_str_eq("[email protected] ", buf);
snprintf(buf, sizeof(buf), "%5Y", a);
ck_assert_str_eq("[email protected]", buf);
DESTROY_IF(a);
}
END_TEST
/*******************************************************************************
* equals
*/
static bool id_equals(identification_t *a, char *b_str)
{
identification_t *b;
bool equals;
b = identification_create_from_string(b_str);
equals = a->equals(a, b);
ck_assert_int_eq(equals, b->equals(b, a));
b->destroy(b);
return equals;
}
START_TEST(test_equals)
{
identification_t *a;
chunk_t encoding, fuzzed;
int i;
/* this test also tests identification_create_from_string with DNs */
a = identification_create_from_string(
"C=CH, [email protected], CN=moon");
ck_assert(id_equals(a, "C=CH, [email protected], CN=moon"));
ck_assert(id_equals(a, "C==CH, [email protected],,, CN==moon"));
ck_assert(id_equals(a, " C=CH, [email protected], CN=moon "));
ck_assert(id_equals(a, "C=ch, [email protected], CN=Moon"));
ck_assert(id_equals(a, "/C=CH/[email protected]/CN=moon"));
ck_assert(id_equals(a, "C=CH/[email protected]/CN=moon"));
ck_assert(id_equals(a, "C=CH/[email protected],CN=moon"));
ck_assert(id_equals(a, "C=CH / [email protected] , CN=moon"));
ck_assert(!id_equals(a, "C=CH [email protected] CN=moon"));
ck_assert(!id_equals(a, "C=CN, [email protected], CN=moon"));
ck_assert(!id_equals(a, "[email protected], C=CH, CN=moon"));
ck_assert(!id_equals(a, "[email protected], C=CH, CN=moon"));
encoding = chunk_clone(a->get_encoding(a));
a->destroy(a);
/* simple fuzzing, increment each byte of encoding */
for (i = 0; i < encoding.len; i++)
{
if (i == 11 || i == 30 || i == 60)
{ /* skip ASN.1 type fields, as equals() handles them graceful */
continue;
}
fuzzed = chunk_clone(encoding);
fuzzed.ptr[i]++;
a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
if (id_equals(a, "C=CH, [email protected], CN=moon"))
{
printf("%d %B\n%B\n", i, &fuzzed, &encoding);
}
ck_assert(!id_equals(a, "C=CH, [email protected], CN=moon"));
a->destroy(a);
free(fuzzed.ptr);
}
/* and decrement each byte of encoding */
for (i = 0; i < encoding.len; i++)
{
if (i == 11 || i == 30 || i == 60)
{
continue;
}
fuzzed = chunk_clone(encoding);
fuzzed.ptr[i]--;
a = identification_create_from_encoding(ID_DER_ASN1_DN, fuzzed);
ck_assert(!id_equals(a, "C=CH, [email protected], CN=moon"));
a->destroy(a);
free(fuzzed.ptr);
}
free(encoding.ptr);
}
END_TEST
START_TEST(test_equals_any)
{
identification_t *a, *b;
a = identification_create_from_string("%any");
b = identification_create_from_encoding(ID_ANY, chunk_empty);
ck_assert(a->equals(a, b));
ck_assert(b->equals(b, a));
b->destroy(b);
b = identification_create_from_string("C=CH, O=strongSwan, CN=strongswan.org");
ck_assert(!a->equals(a, b));
ck_assert(!b->equals(b, a));
a->destroy(a);
b->destroy(b);
}
END_TEST
START_TEST(test_equals_binary)
{
identification_t *a, *b;
chunk_t encoding;
encoding = chunk_from_str("foobar=");
/* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
a = identification_create_from_string("foobar=");
ck_assert(a->get_type(a) == ID_KEY_ID);
b = identification_create_from_encoding(ID_KEY_ID, encoding);
ck_assert(a->equals(a, b));
a->destroy(a);
b->destroy(b);
}
END_TEST
START_TEST(test_equals_fqdn)
{
identification_t *a;
a = identification_create_from_string("ipsec.strongswan.org");
ck_assert(id_equals(a, "IPSEC.strongswan.org"));
ck_assert(id_equals(a, "ipsec.strongSwan.org"));
ck_assert(id_equals(a, "ipsec.strongSwan.ORG"));
ck_assert(!id_equals(a, "strongswan.org"));
a->destroy(a);
}
END_TEST
START_TEST(test_equals_empty)
{
identification_t *a;
a = identification_create_from_encoding(_i, chunk_empty);
switch (_i)
{
case ID_ANY:
ck_assert(id_equals(a, "%any"));
break;
case ID_IPV4_ADDR:
ck_assert(!id_equals(a, "192.168.1.1"));
break;
case ID_FQDN:
ck_assert(!id_equals(a, "moon.strongswan.org"));
break;
case ID_USER_FQDN:
ck_assert(!id_equals(a, "[email protected]"));
break;
case ID_IPV6_ADDR:
ck_assert(!id_equals(a, "fec0::1"));
break;
case ID_DER_ASN1_DN:
ck_assert(!id_equals(a, "C=CH, [email protected], CN=moon"));
break;
case ID_KEY_ID:
ck_assert(!id_equals(a, "@#12345678"));
break;
case ID_DER_ASN1_GN:
case ID_IPV4_ADDR_SUBNET:
case ID_IPV6_ADDR_SUBNET:
case ID_IPV4_ADDR_RANGE:
case ID_IPV6_ADDR_RANGE:
/* currently not tested */
break;
}
a->destroy(a);
}
END_TEST
/*******************************************************************************
* matches
*/
static bool id_matches(identification_t *a, char *b_str, id_match_t expected)
{
identification_t *b;
id_match_t match;
b = identification_create_from_string(b_str);
match = a->matches(a, b);
b->destroy(b);
return match == expected;
}
START_TEST(test_matches)
{
identification_t *a;
a = identification_create_from_string("C=CH, [email protected], CN=moon");
ck_assert(id_matches(a, "C=CH, [email protected], CN=moon", ID_MATCH_PERFECT));
ck_assert(id_matches(a, "C=CH, E=*, CN=moon", ID_MATCH_ONE_WILDCARD));
ck_assert(id_matches(a, "C=CH, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 1));
ck_assert(id_matches(a, "C=*, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 2));
ck_assert(id_matches(a, "C=*, E=*, CN=*, O=BADInc", ID_MATCH_NONE));
ck_assert(id_matches(a, "C=*, E=*", ID_MATCH_NONE));
ck_assert(id_matches(a, "C=*, [email protected], CN=*", ID_MATCH_NONE));
ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
a->destroy(a);
}
END_TEST
START_TEST(test_matches_any)
{
identification_t *a;
a = identification_create_from_string("%any");
ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
ck_assert(id_matches(a, "", ID_MATCH_ANY));
ck_assert(id_matches(a, "*", ID_MATCH_ANY));
ck_assert(id_matches(a, "[email protected]", ID_MATCH_NONE));
ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_NONE));
a->destroy(a);
}
END_TEST
START_TEST(test_matches_binary)
{
identification_t *a;
/* strings containing = are parsed as KEY_ID if they aren't valid ASN.1 DNs */
a = identification_create_from_string("foo=bar");
ck_assert(a->get_type(a) == ID_KEY_ID);
ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
ck_assert(id_matches(a, "foo=bar", ID_MATCH_PERFECT));
ck_assert(id_matches(a, "bar=foo", ID_MATCH_NONE));
ck_assert(id_matches(a, "*=bar", ID_MATCH_NONE));
ck_assert(id_matches(a, "foo=*", ID_MATCH_NONE));
ck_assert(id_matches(a, "foo@bar", ID_MATCH_NONE));
a->destroy(a);
}
END_TEST
START_TEST(test_matches_string)
{
identification_t *a;
a = identification_create_from_string("[email protected]");
ck_assert(id_matches(a, "[email protected]", ID_MATCH_PERFECT));
ck_assert(id_matches(a, "*@strongswan.org", ID_MATCH_ONE_WILDCARD));
ck_assert(id_matches(a, "*@*.org", ID_MATCH_NONE));
ck_assert(id_matches(a, "*@*", ID_MATCH_NONE));
/* the following two are parsed as ID_FQDN, so no match */
ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_NONE));
ck_assert(id_matches(a, "*.org", ID_MATCH_NONE));
ck_assert(id_matches(a, "moon@*", ID_MATCH_NONE));
ck_assert(id_matches(a, "**", ID_MATCH_NONE));
ck_assert(id_matches(a, "*", ID_MATCH_ANY));
ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
a->destroy(a);
a = identification_create_from_string("vpn.strongswan.org");
ck_assert(id_matches(a, "vpn.strongswan.org", ID_MATCH_PERFECT));
ck_assert(id_matches(a, "*.strongswan.org", ID_MATCH_ONE_WILDCARD));
ck_assert(id_matches(a, "*strongswan.org", ID_MATCH_ONE_WILDCARD));
ck_assert(id_matches(a, "*.org", ID_MATCH_ONE_WILDCARD));
ck_assert(id_matches(a, "*.strongswan.*", ID_MATCH_NONE));
ck_assert(id_matches(a, "*vpn.strongswan.org", ID_MATCH_NONE));
ck_assert(id_matches(a, "vpn.strongswan.*", ID_MATCH_NONE));
ck_assert(id_matches(a, "**", ID_MATCH_NONE));
ck_assert(id_matches(a, "*", ID_MATCH_ANY));
ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
a->destroy(a);
}
END_TEST
START_TEST(test_matches_empty)
{
identification_t *a;
a = identification_create_from_encoding(_i, chunk_empty);
switch (_i)
{
case ID_ANY:
ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
break;
case ID_IPV4_ADDR:
ck_assert(id_matches(a, "192.168.1.1", ID_MATCH_NONE));
break;
case ID_FQDN:
ck_assert(id_matches(a, "moon.strongswan.org", ID_MATCH_NONE));
break;
case ID_USER_FQDN:
ck_assert(id_matches(a, "[email protected]", ID_MATCH_NONE));
break;
case ID_IPV6_ADDR:
ck_assert(id_matches(a, "fec0::1", ID_MATCH_NONE));
break;
case ID_DER_ASN1_DN:
ck_assert(id_matches(a, "C=CH, [email protected], CN=moon",
ID_MATCH_NONE));
break;
case ID_KEY_ID:
ck_assert(id_matches(a, "@#12345678", ID_MATCH_NONE));
break;
case ID_DER_ASN1_GN:
case ID_IPV4_ADDR_SUBNET:
case ID_IPV6_ADDR_SUBNET:
case ID_IPV4_ADDR_RANGE:
case ID_IPV6_ADDR_RANGE:
/* currently not tested */
break;
}
a->destroy(a);
}
END_TEST
static bool id_matches_rev(identification_t *a, char *b_str, id_match_t expected)
{
identification_t *b;
id_match_t match;
b = identification_create_from_string(b_str);
match = b->matches(b, a);
b->destroy(b);
return match == expected;
}
START_TEST(test_matches_empty_reverse)
{
identification_t *a;
a = identification_create_from_encoding(_i, chunk_empty);
switch (_i)
{
case ID_ANY:
ck_assert(id_matches_rev(a, "%any", ID_MATCH_ANY));
break;
case ID_IPV4_ADDR:
ck_assert(id_matches_rev(a, "192.168.1.1", ID_MATCH_NONE));
break;
case ID_FQDN:
ck_assert(id_matches_rev(a, "moon.strongswan.org", ID_MATCH_NONE));
break;
case ID_USER_FQDN:
ck_assert(id_matches_rev(a, "[email protected]", ID_MATCH_NONE));
break;
case ID_IPV6_ADDR:
ck_assert(id_matches_rev(a, "fec0::1", ID_MATCH_NONE));
break;
case ID_DER_ASN1_DN:
ck_assert(id_matches_rev(a, "C=CH, [email protected], CN=moon",
ID_MATCH_NONE));
break;
case ID_KEY_ID:
ck_assert(id_matches_rev(a, "@#12345678", ID_MATCH_NONE));
break;
case ID_DER_ASN1_GN:
case ID_IPV4_ADDR_SUBNET:
case ID_IPV6_ADDR_SUBNET:
case ID_IPV4_ADDR_RANGE:
case ID_IPV6_ADDR_RANGE:
/* currently not tested */
break;
}
a->destroy(a);
}
END_TEST
/*******************************************************************************
* identification part enumeration
*/
START_TEST(test_parts)
{
identification_t *id;
enumerator_t *enumerator;
id_part_t part;
chunk_t data;
int i = 0;
id = identification_create_from_string("C=CH, O=strongSwan, CN=tester");
enumerator = id->create_part_enumerator(id);
while (enumerator->enumerate(enumerator, &part, &data))
{
switch (i++)
{
case 0:
ck_assert(part == ID_PART_RDN_C &&
chunk_equals(data, chunk_create("CH", 2)));
break;
case 1:
ck_assert(part == ID_PART_RDN_O &&
chunk_equals(data, chunk_from_str("strongSwan")));
break;
case 2:
ck_assert(part == ID_PART_RDN_CN &&
chunk_equals(data, chunk_from_str("tester")));
break;
default:
fail("unexpected identification part %d", part);
}
}
ck_assert_int_eq(i, 3);
enumerator->destroy(enumerator);
id->destroy(id);
}
END_TEST
/*******************************************************************************
* wildcards
*/
static bool id_contains_wildcards(char *string)
{
identification_t *id;
bool contains;
id = identification_create_from_string(string);
contains = id->contains_wildcards(id);
id->destroy(id);
return contains;
}
START_TEST(test_contains_wildcards)
{
ck_assert(id_contains_wildcards("%any"));
ck_assert(id_contains_wildcards("C=*, O=strongSwan, CN=gw"));
ck_assert(id_contains_wildcards("C=CH, O=strongSwan, CN=*"));
ck_assert(id_contains_wildcards("*@strongswan.org"));
ck_assert(id_contains_wildcards("*.strongswan.org"));
ck_assert(!id_contains_wildcards("C=**, O=a*, CN=*a"));
}
END_TEST
/*******************************************************************************
* clone
*/
START_TEST(test_clone)
{
identification_t *a, *b;
chunk_t a_enc, b_enc;
a = identification_create_from_string("[email protected]");
a_enc = a->get_encoding(a);
b = a->clone(a);
ck_assert(b != NULL);
ck_assert(a != b);
b_enc = b->get_encoding(b);
ck_assert(a_enc.ptr != b_enc.ptr);
ck_assert(chunk_equals(a_enc, b_enc));
a->destroy(a);
b->destroy(b);
}
END_TEST
Suite *identification_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("identification");
tc = tcase_create("create");
tcase_add_test(tc, test_from_encoding);
tcase_add_test(tc, test_from_data);
tcase_add_test(tc, test_from_sockaddr);
tcase_add_loop_test(tc, test_from_string, 0, countof(string_data));
suite_add_tcase(s, tc);
tc = tcase_create("printf_hook");
tcase_add_test(tc, test_printf_hook);
tcase_add_test(tc, test_printf_hook_width);
suite_add_tcase(s, tc);
tc = tcase_create("equals");
tcase_add_test(tc, test_equals);
tcase_add_test(tc, test_equals_any);
tcase_add_test(tc, test_equals_binary);
tcase_add_test(tc, test_equals_fqdn);
tcase_add_loop_test(tc, test_equals_empty, ID_ANY, ID_KEY_ID + 1);
suite_add_tcase(s, tc);
tc = tcase_create("matches");
tcase_add_test(tc, test_matches);
tcase_add_test(tc, test_matches_any);
tcase_add_test(tc, test_matches_binary);
tcase_add_test(tc, test_matches_string);
tcase_add_loop_test(tc, test_matches_empty, ID_ANY, ID_KEY_ID + 1);
tcase_add_loop_test(tc, test_matches_empty_reverse, ID_ANY, ID_KEY_ID + 1);
suite_add_tcase(s, tc);
tc = tcase_create("part enumeration");
tcase_add_test(tc, test_parts);
suite_add_tcase(s, tc);
tc = tcase_create("wildcards");
tcase_add_test(tc, test_contains_wildcards);
suite_add_tcase(s, tc);
tc = tcase_create("clone");
tcase_add_test(tc, test_clone);
suite_add_tcase(s, tc);
return s;
}
@@ -0,0 +1,386 @@
/*
* Copyright (C) 2013 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <collections/linked_list.h>
/*******************************************************************************
* test fixture
*/
static linked_list_t *list;
START_SETUP(setup_list)
{
void *x = NULL;
list = linked_list_create();
ck_assert_int_eq(list->get_count(list), 0);
ck_assert(list->get_first(list, &x) == NOT_FOUND);
ck_assert(list->get_last(list, &x) == NOT_FOUND);
}
END_SETUP
START_TEARDOWN(teardown_list)
{
list->destroy(list);
}
END_TEARDOWN
/*******************************************************************************
* insert first/last
*/
START_TEST(test_insert_first)
{
void *a = (void*)1, *b = (void*)2, *x = NULL;
list->insert_first(list, a);
ck_assert_int_eq(list->get_count(list), 1);
ck_assert(list->get_first(list, &x) == SUCCESS);
ck_assert(x == a);
ck_assert(list->get_last(list, &x) == SUCCESS);
ck_assert(x == a);
list->insert_first(list, b);
ck_assert_int_eq(list->get_count(list), 2);
ck_assert(list->get_first(list, &x) == SUCCESS);
ck_assert(x == b);
ck_assert(list->get_last(list, &x) == SUCCESS);
ck_assert(x == a);
}
END_TEST
START_TEST(test_insert_last)
{
void *a = (void*)1, *b = (void*)2, *x = NULL;
list->insert_last(list, a);
ck_assert_int_eq(list->get_count(list), 1);
ck_assert(list->get_first(list, &x) == SUCCESS);
ck_assert(x == a);
ck_assert(list->get_last(list, &x) == SUCCESS);
ck_assert(x == a);
list->insert_last(list, b);
ck_assert_int_eq(list->get_count(list), 2);
ck_assert(list->get_first(list, &x) == SUCCESS);
ck_assert(x == a);
ck_assert(list->get_last(list, &x) == SUCCESS);
ck_assert(x == b);
}
END_TEST
/*******************************************************************************
* remove first/last
*/
START_TEST(test_remove_first)
{
void *a = (void*)1, *b = (void*)2, *x = NULL;
list->insert_first(list, a);
list->insert_first(list, b);
ck_assert(list->remove_first(list, &x) == SUCCESS);
ck_assert_int_eq(list->get_count(list), 1);
ck_assert(x == b);
ck_assert(list->remove_first(list, &x) == SUCCESS);
ck_assert_int_eq(list->get_count(list), 0);
ck_assert(x == a);
ck_assert(list->remove_first(list, &x) == NOT_FOUND);
ck_assert(list->remove_last(list, &x) == NOT_FOUND);
}
END_TEST
START_TEST(test_remove_last)
{
void *a = (void*)1, *b = (void*)2, *x = NULL;
list->insert_first(list, a);
list->insert_first(list, b);
ck_assert(list->remove_last(list, &x) == SUCCESS);
ck_assert_int_eq(list->get_count(list), 1);
ck_assert(x == a);
ck_assert(list->remove_last(list, &x) == SUCCESS);
ck_assert_int_eq(list->get_count(list), 0);
ck_assert(x == b);
ck_assert(list->remove_first(list, &x) == NOT_FOUND);
ck_assert(list->remove_last(list, &x) == NOT_FOUND);
}
END_TEST
/*******************************************************************************
* helper function for remove and find tests
*/
static bool match_a(void *item, void *a)
{
ck_assert(a == (void*)1);
return item == a;
}
static bool match_b(void *item, void *b)
{
ck_assert(b == (void*)2);
return item == b;
}
/*******************************************************************************
* remove
*/
START_TEST(test_remove)
{
void *a = (void*)1, *b = (void*)2;
list->insert_first(list, a);
ck_assert(list->remove(list, a, NULL) == 1);
ck_assert_int_eq(list->get_count(list), 0);
list->insert_last(list, a);
list->insert_last(list, a);
list->insert_last(list, a);
list->insert_last(list, b);
ck_assert(list->remove(list, a, NULL) == 3);
ck_assert(list->remove(list, a, NULL) == 0);
ck_assert_int_eq(list->get_count(list), 1);
ck_assert(list->remove(list, b, NULL) == 1);
ck_assert(list->remove(list, b, NULL) == 0);
}
END_TEST
START_TEST(test_remove_callback)
{
void *a = (void*)1, *b = (void*)2;
list->insert_last(list, a);
list->insert_last(list, b);
list->insert_last(list, a);
list->insert_last(list, b);
ck_assert(list->remove(list, a, match_a) == 2);
ck_assert(list->remove(list, a, match_a) == 0);
ck_assert_int_eq(list->get_count(list), 2);
ck_assert(list->remove(list, b, match_b) == 2);
ck_assert(list->remove(list, b, match_b) == 0);
ck_assert_int_eq(list->get_count(list), 0);
}
END_TEST
/*******************************************************************************
* find
*/
static bool match_a_b(void *item, void *a, void *b)
{
ck_assert(a == (void*)1);
ck_assert(b == (void*)2);
return item == a || item == b;
}
START_TEST(test_find)
{
void *a = (void*)1, *b = (void*)2;
ck_assert(list->find_first(list, NULL, &a) == NOT_FOUND);
list->insert_last(list, a);
ck_assert(list->find_first(list, NULL, &a) == SUCCESS);
ck_assert(list->find_first(list, NULL, &b) == NOT_FOUND);
list->insert_last(list, b);
ck_assert(list->find_first(list, NULL, &a) == SUCCESS);
ck_assert(list->find_first(list, NULL, &b) == SUCCESS);
ck_assert(list->find_first(list, NULL, NULL) == NOT_FOUND);
}
END_TEST
START_TEST(test_find_callback)
{
void *a = (void*)1, *b = (void*)2, *x = NULL;
ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == NOT_FOUND);
list->insert_last(list, a);
ck_assert(list->find_first(list, (linked_list_match_t)match_a, NULL, a) == SUCCESS);
x = NULL;
ck_assert(list->find_first(list, (linked_list_match_t)match_a, &x, a) == SUCCESS);
ck_assert(a == x);
ck_assert(list->find_first(list, (linked_list_match_t)match_b, &x, b) == NOT_FOUND);
ck_assert(a == x);
x = NULL;
ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS);
ck_assert(a == x);
list->insert_last(list, b);
ck_assert(list->find_first(list, (linked_list_match_t)match_a, &x, a) == SUCCESS);
ck_assert(a == x);
ck_assert(list->find_first(list, (linked_list_match_t)match_b, &x, b) == SUCCESS);
ck_assert(b == x);
x = NULL;
ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS);
ck_assert(a == x);
}
END_TEST
/*******************************************************************************
* invoke
*/
typedef struct invoke_t invoke_t;
struct invoke_t {
int val;
void (*invoke)(invoke_t *item, void *a, void *b, void *c, void *d, int *sum);
};
static void invoke(intptr_t item, void *a, void *b, void *c, void *d, int *sum)
{
ck_assert(a == (void*)1);
ck_assert(b == (void*)2);
ck_assert(c == (void*)3);
ck_assert(d == (void*)4);
*sum += item;
}
static void invoke_offset(invoke_t *item, void *a, void *b, void *c, void *d, int *sum)
{
invoke(item->val, a, b, c, d, sum);
}
START_TEST(test_invoke_function)
{
int sum = 0;
list->insert_last(list, (void*)1);
list->insert_last(list, (void*)2);
list->insert_last(list, (void*)3);
list->insert_last(list, (void*)4);
list->insert_last(list, (void*)5);
list->invoke_function(list, (linked_list_invoke_t)invoke, 1, 2, 3, 4, &sum);
ck_assert_int_eq(sum, 15);
}
END_TEST
START_TEST(test_invoke_offset)
{
invoke_t items[] = {
{ .val = 1, .invoke = invoke_offset, },
{ .val = 2, .invoke = invoke_offset, },
{ .val = 3, .invoke = invoke_offset, },
{ .val = 4, .invoke = invoke_offset, },
{ .val = 5, .invoke = invoke_offset, },
};
int i, sum = 0;
for (i = 0; i < countof(items); i++)
{
list->insert_last(list, &items[i]);
}
list->invoke_offset(list, offsetof(invoke_t, invoke), 1, 2, 3, 4, &sum);
ck_assert_int_eq(sum, 15);
}
END_TEST
/*******************************************************************************
* clone
*/
typedef struct clone_t clone_t;
struct clone_t {
void *val;
void *(*clone)(clone_t *item);
};
static void *clone(clone_t *item)
{
return item->val;
}
static void test_clone(linked_list_t *list)
{
intptr_t x;
int round = 1;
ck_assert_int_eq(list->get_count(list), 5);
while (list->remove_first(list, (void*)&x) == SUCCESS)
{
ck_assert_int_eq(round, x);
round++;
}
ck_assert_int_eq(round, 6);
}
START_TEST(test_clone_offset)
{
linked_list_t *other;
clone_t items[] = {
{ .val = (void*)1, .clone = clone, },
{ .val = (void*)2, .clone = clone, },
{ .val = (void*)3, .clone = clone, },
{ .val = (void*)4, .clone = clone, },
{ .val = (void*)5, .clone = clone, },
};
int i;
for (i = 0; i < countof(items); i++)
{
list->insert_last(list, &items[i]);
}
other = list->clone_offset(list, offsetof(clone_t, clone));
test_clone(other);
other->destroy(other);
}
END_TEST
Suite *linked_list_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("linked list");
tc = tcase_create("insert/get");
tcase_add_checked_fixture(tc, setup_list, teardown_list);
tcase_add_test(tc, test_insert_first);
tcase_add_test(tc, test_insert_last);
suite_add_tcase(s, tc);
tc = tcase_create("remove");
tcase_add_checked_fixture(tc, setup_list, teardown_list);
tcase_add_test(tc, test_remove_first);
tcase_add_test(tc, test_remove_last);
tcase_add_test(tc, test_remove);
tcase_add_test(tc, test_remove_callback);
suite_add_tcase(s, tc);
tc = tcase_create("find");
tcase_add_checked_fixture(tc, setup_list, teardown_list);
tcase_add_test(tc, test_find);
tcase_add_test(tc, test_find_callback);
suite_add_tcase(s, tc);
tc = tcase_create("invoke");
tcase_add_checked_fixture(tc, setup_list, teardown_list);
tcase_add_test(tc, test_invoke_function);
tcase_add_test(tc, test_invoke_offset);
suite_add_tcase(s, tc);
tc = tcase_create("clone");
tcase_add_checked_fixture(tc, setup_list, teardown_list);
tcase_add_test(tc, test_clone_offset);
suite_add_tcase(s, tc);
return s;
}
@@ -0,0 +1,361 @@
/*
* Copyright (C) 2013 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <collections/linked_list.h>
/*******************************************************************************
* test fixture
*/
static linked_list_t *list;
START_SETUP(setup_list)
{
list = linked_list_create_with_items((void*)1, (void*)2, (void*)3, (void*)4,
(void*)5, NULL);
ck_assert_int_eq(list->get_count(list), 5);
}
END_SETUP
START_TEARDOWN(teardown_list)
{
list->destroy(list);
}
END_TEARDOWN
/*******************************************************************************
* enumeration
*/
START_TEST(test_enumerate)
{
enumerator_t *enumerator;
intptr_t x;
int round;
round = 1;
enumerator = list->create_enumerator(list);
while (enumerator->enumerate(enumerator, &x))
{
ck_assert_int_eq(round, x);
round++;
}
ck_assert_int_eq(round, 6);
enumerator->destroy(enumerator);
}
END_TEST
START_TEST(test_enumerate_null)
{
enumerator_t *enumerator;
int round;
round = 1;
enumerator = list->create_enumerator(list);
while (enumerator->enumerate(enumerator, NULL))
{
round++;
}
ck_assert_int_eq(round, 6);
enumerator->destroy(enumerator);
}
END_TEST
START_TEST(test_reset_enumerator)
{
enumerator_t *enumerator;
intptr_t x;
int round;
enumerator = list->create_enumerator(list);
while (enumerator->enumerate(enumerator, &x))
{
}
list->reset_enumerator(list, enumerator);
round = 1;
while (enumerator->enumerate(enumerator, &x))
{
ck_assert_int_eq(round, x);
round++;
}
ck_assert_int_eq(round, 6);
enumerator->destroy(enumerator);
}
END_TEST
/*******************************************************************************
* insert before
*/
START_TEST(test_insert_before)
{
enumerator_t *enumerator;
intptr_t x;
int round;
round = 1;
enumerator = list->create_enumerator(list);
while (enumerator->enumerate(enumerator, &x))
{
ck_assert_int_eq(round, x);
round++;
if (x == _i)
{
list->insert_before(list, enumerator, (void*)6);
}
}
ck_assert_int_eq(list->get_count(list), 6);
list->reset_enumerator(list, enumerator);
round = 1;
while (enumerator->enumerate(enumerator, &x))
{
if (round == _i && x != _i)
{
ck_assert_int_eq(6, x);
}
else
{
ck_assert_int_eq(round, x);
round++;
}
}
enumerator->destroy(enumerator);
}
END_TEST
START_TEST(test_insert_before_ends)
{
enumerator_t *enumerator;
intptr_t x;
int round;
enumerator = list->create_enumerator(list);
list->insert_before(list, enumerator, (void*)0);
ck_assert_int_eq(list->get_count(list), 6);
ck_assert(list->get_first(list, (void*)&x) == SUCCESS);
ck_assert_int_eq(x, 0);
round = 0;
while (enumerator->enumerate(enumerator, &x))
{
ck_assert_int_eq(round, x);
round++;
}
list->insert_before(list, enumerator, (void*)6);
ck_assert_int_eq(list->get_count(list), 7);
ck_assert(list->get_last(list, (void*)&x) == SUCCESS);
ck_assert_int_eq(x, 6);
ck_assert(!enumerator->enumerate(enumerator, &x));
enumerator->destroy(enumerator);
}
END_TEST
START_TEST(test_insert_before_empty)
{
enumerator_t *enumerator;
intptr_t x;
list->destroy(list);
list = linked_list_create();
enumerator = list->create_enumerator(list);
list->insert_before(list, enumerator, (void*)1);
ck_assert_int_eq(list->get_count(list), 1);
ck_assert(list->get_first(list, (void*)&x) == SUCCESS);
ck_assert_int_eq(x, 1);
ck_assert(list->get_last(list, (void*)&x) == SUCCESS);
ck_assert_int_eq(x, 1);
ck_assert(enumerator->enumerate(enumerator, &x));
ck_assert_int_eq(x, 1);
ck_assert(!enumerator->enumerate(enumerator, NULL));
enumerator->destroy(enumerator);
}
END_TEST
/*******************************************************************************
* remove_at
*/
START_TEST(test_remove_at)
{
enumerator_t *enumerator;
intptr_t x;
int round;
round = 1;
enumerator = list->create_enumerator(list);
while (enumerator->enumerate(enumerator, &x))
{
ck_assert_int_eq(round, x);
if (round == 2)
{
list->remove_at(list, enumerator);
}
round++;
}
ck_assert_int_eq(list->get_count(list), 4);
list->reset_enumerator(list, enumerator);
round = 1;
while (enumerator->enumerate(enumerator, &x))
{
if (round == 2)
{ /* skip removed item */
round++;
}
ck_assert_int_eq(round, x);
round++;
}
enumerator->destroy(enumerator);
}
END_TEST
START_TEST(test_remove_at_ends)
{
enumerator_t *enumerator;
intptr_t x;
enumerator = list->create_enumerator(list);
list->remove_at(list, enumerator);
ck_assert_int_eq(list->get_count(list), 5);
ck_assert(list->get_first(list, (void*)&x) == SUCCESS);
ck_assert_int_eq(x, 1);
while (enumerator->enumerate(enumerator, &x))
{
}
list->remove_at(list, enumerator);
ck_assert_int_eq(list->get_count(list), 5);
ck_assert(list->get_last(list, (void*)&x) == SUCCESS);
ck_assert_int_eq(x, 5);
enumerator->destroy(enumerator);
}
END_TEST
START_TEST(test_insert_before_remove_at)
{
enumerator_t *enumerator;
intptr_t x;
int round;
round = 1;
enumerator = list->create_enumerator(list);
while (enumerator->enumerate(enumerator, &x))
{
ck_assert_int_eq(round, x);
if (round == 2)
{ /* this replaces the current item, as insert_before does not change
* the enumerator position */
list->insert_before(list, enumerator, (void*)42);
list->remove_at(list, enumerator);
}
else if (round == 4)
{ /* this does not replace the item, as remove_at moves the enumerator
* position to the previous item */
list->remove_at(list, enumerator);
list->insert_before(list, enumerator, (void*)21);
}
round++;
}
ck_assert_int_eq(list->get_count(list), 5);
list->reset_enumerator(list, enumerator);
round = 1;
while (enumerator->enumerate(enumerator, &x))
{
if (round == 2)
{ /* check replaced item */
ck_assert_int_eq(42, x);
}
else if (round == 3)
{ /* check misplaced item */
ck_assert_int_eq(21, x);
}
else if (round == 4)
{ /* check misplaced item */
ck_assert_int_eq(3, x);
}
else
{
ck_assert_int_eq(round, x);
}
round++;
}
enumerator->destroy(enumerator);
}
END_TEST
/*******************************************************************************
* create list from enumerator
*/
START_TEST(test_create_from_enumerator)
{
enumerator_t *enumerator, *enumerator_other;
linked_list_t *other;
intptr_t x, y;
int count = 0;
enumerator = list->create_enumerator(list);
other = linked_list_create_from_enumerator(enumerator);
ck_assert_int_eq(other->get_count(list), 5);
enumerator = list->create_enumerator(list);
enumerator_other = other->create_enumerator(other);
while (enumerator->enumerate(enumerator, &x) &&
enumerator_other->enumerate(enumerator_other, &y))
{
ck_assert_int_eq(x, y);
count++;
}
ck_assert_int_eq(count, 5);
enumerator_other->destroy(enumerator_other);
enumerator->destroy(enumerator);
other->destroy(other);
}
END_TEST
Suite *linked_list_enumerator_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("linked list and enumerators");
tc = tcase_create("enumerate");
tcase_add_checked_fixture(tc, setup_list, teardown_list);
tcase_add_test(tc, test_enumerate);
tcase_add_test(tc, test_enumerate_null);
tcase_add_test(tc, test_reset_enumerator);
suite_add_tcase(s, tc);
tc = tcase_create("insert_before()");
tcase_add_checked_fixture(tc, setup_list, teardown_list);
tcase_add_loop_test(tc, test_insert_before, 1, 5);
tcase_add_test(tc, test_insert_before_ends);
tcase_add_test(tc, test_insert_before_empty);
suite_add_tcase(s, tc);
tc = tcase_create("modify");
tcase_add_checked_fixture(tc, setup_list, teardown_list);
tcase_add_test(tc, test_remove_at);
tcase_add_test(tc, test_remove_at_ends);
tcase_add_test(tc, test_insert_before_remove_at);
suite_add_tcase(s, tc);
tc = tcase_create("create_from_enumerator");
tcase_add_checked_fixture(tc, setup_list, teardown_list);
tcase_add_test(tc, test_create_from_enumerator);
suite_add_tcase(s, tc);
return s;
}
+87
View File
@@ -0,0 +1,87 @@
/*
* Copyright (C) 2013 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <pen/pen.h>
/*******************************************************************************
* create
*/
START_TEST(test_pen_type_create)
{
pen_type_t ita_1 = pen_type_create(PEN_ITA, 100);
ck_assert(ita_1.vendor_id == PEN_ITA);
ck_assert(ita_1.type == 100);
}
END_TEST
/*******************************************************************************
* equals
*/
START_TEST(test_pen_type_equals)
{
pen_type_t ita_1 = pen_type_create(PEN_ITA, 100);
pen_type_t ita_2 = pen_type_create(PEN_ITA, 200);
pen_type_t fhh_1 = pen_type_create(PEN_FHH, 100);
pen_type_t fhh_2 = pen_type_create(PEN_FHH, 200);
ck_assert( pen_type_equals(ita_1, ita_1));
ck_assert(!pen_type_equals(ita_1, ita_2));
ck_assert(!pen_type_equals(ita_1, fhh_1));
ck_assert(!pen_type_equals(ita_1, fhh_2));
}
END_TEST
/*******************************************************************************
* is
*/
START_TEST(test_pen_type_is)
{
pen_type_t ita_1 = pen_type_create(PEN_ITA, 100);
ck_assert( pen_type_is(ita_1, PEN_ITA, 100));
ck_assert(!pen_type_is(ita_1, PEN_ITA, 200));
ck_assert(!pen_type_is(ita_1, PEN_FHH, 100));
ck_assert(!pen_type_is(ita_1, PEN_FHH, 200));
}
END_TEST
Suite *pen_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("pen");
tc = tcase_create("create");
tcase_add_test(tc, test_pen_type_create);
suite_add_tcase(s, tc);
tc = tcase_create("equals");
tcase_add_test(tc, test_pen_type_equals);
suite_add_tcase(s, tc);
tc = tcase_create("is");
tcase_add_test(tc, test_pen_type_is);
suite_add_tcase(s, tc);
return s;
}
@@ -0,0 +1,185 @@
/*
* Copyright (C) 2013 Martin Willi
* Copyright (C) 2013 revosec AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <errno.h>
#include <math.h>
static void verify(char *expected, char *format, ...)
{
FILE *mem;
char buf[128];
va_list args;
va_start(args, format);
vsnprintf(buf, sizeof(buf), format, args);
ck_assert_str_eq(expected, buf);
va_end(args);
mem = fmemopen(buf, sizeof(buf), "w");
va_start(args, format);
vfprintf(mem, format, args);
va_end(args);
fclose(mem);
ck_assert_str_eq(expected, buf);
}
START_TEST(test_printf_strings)
{
verify("a bc def", "%s %s %s", "a", "bc", "def");
verify("asd", "%.3s", "asdfg");
verify("asdf", "%.*s", (int)4, "asdfg");
verify(" asdf", "%6s", "asdf");
verify(" asdf", "%+6s", "asdf");
verify("asdf ", "%-6s", "asdf");
}
END_TEST
START_TEST(test_printf_err)
{
errno = EINVAL;
verify((char*)strerror(errno), "%m");
}
END_TEST
START_TEST(test_printf_unsigned)
{
verify("1 23 456", "%u %lu %llu", 1, (u_long)23, (u_int64_t)456);
verify("65535 255", "%hu %hhu", 0x1ffff, 0x1ff);
verify("123456789", "%zu", (size_t)123456789);
verify(" 12", "%5u", 12);
verify("12 ", "%-5u", 12);
verify("0012", "%04u", 12);
verify("0012", "%.4u", 12);
}
END_TEST
START_TEST(test_printf_signed)
{
verify("-1 -23 -456", "%d %ld %lld", -1, (long)-23, (int64_t)-456);
verify("-1 -1", "%hd %hhd", 0x1ffff, 0x1ff);
verify("123456789", "%zd", (ssize_t)123456789);
verify(" -12", "%5d", -12);
verify("-12 ", "%-5d", -12);
verify("-012", "%04d", -12);
verify("-0012", "%.4d", -12);
}
END_TEST
START_TEST(test_printf_hex)
{
verify("1 23 456", "%x %lx %llx", 1, (u_long)0x23, (u_int64_t)0x456);
verify("12abcdef 12ABCDEF", "%x %X", 0x12ABCDEF, 0x12ABCDEF);
verify("ffff ff", "%hx %hhx", 0x1ffff, 0x1ff);
verify("23456789", "%zx", (size_t)0x23456789);
verify(" ab", "%5x", 0xab);
verify("ab ", "%-5x", 0xab);
verify("00ab", "%04x", 0xab);
verify("00ab", "%.4x", 0xab);
}
END_TEST
START_TEST(test_printf_float)
{
verify("0.000000", "%f", 0.0);
verify("1.000000", "%f", 1.0);
verify("12345.1", "%.1f", 12345.123);
verify("1", "%.0f", 1.0);
verify("1.3", "%.1f", 1.346789);
verify("1.23", "%.2f", 1.23456789);
verify("1.123", "%.3f", 1.123456789);
verify("1.0123", "%.4f", 1.0123456789);
verify("-1.000000", "%f", -1.0);
verify("-12345.1", "%.1f", -12345.123);
verify("-1", "%.0f", -1.0);
verify("-1.3", "%.1f", -1.3456789);
verify("-1.23", "%.2f", -1.23456789);
verify("-1.123", "%.3f", -1.123456789);
verify("-1.0123", "%.4f", -1.0123456789);
verify(" 1.2", "%5.1f", 1.234);
verify("001.2", "%05.1f", 1.234);
verify("1.2 ", "%-5.1f", 1.234);
verify("12346", "%.0f", 12345.6789);
verify("2", "%.0f", 1.5);
verify("1", "%.0f", 1.49);
verify("1.2", "%.1f", 1.151);
verify("1.1", "%.1f", 1.149);
verify("1.13", "%.2f", 1.1251);
verify("1.12", "%.2f", 1.1249);
verify("1.124", "%.3f", 1.12351);
verify("1.123", "%.3f", 1.12349);
verify("-12346", "%.0f", -12345.6789);
verify("-2", "%.0f", -1.51);
verify("-1", "%.0f", -1.49);
verify("-1.2", "%.1f", -1.151);
verify("-1.1", "%.1f", -1.149);
verify("-1.13", "%.2f", -1.1251);
verify("-1.12", "%.2f", -1.1249);
verify("-1.124", "%.3f", -1.12351);
verify("-1.123", "%.3f", -1.12349);
#ifdef NAN
verify("nan", "%.3f", NAN);
verify(" nan", "%5.3f", NAN);
verify("NAN", "%.3F", NAN);
verify("NAN ", "%-5.3F", NAN);
#endif
#ifdef INFINITY
verify("inf", "%.3f", INFINITY);
verify("-inf", "%.4f", -INFINITY);
verify("INF", "%.3F", INFINITY);
verify("-INF", "%.4F", -INFINITY);
#endif
}
END_TEST
Suite *printf_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("printf");
tc = tcase_create("strings");
tcase_add_test(tc, test_printf_strings);
suite_add_tcase(s, tc);
tc = tcase_create("err");
tcase_add_test(tc, test_printf_err);
suite_add_tcase(s, tc);
tc = tcase_create("unsiged");
tcase_add_test(tc, test_printf_unsigned);
suite_add_tcase(s, tc);
tc = tcase_create("siged");
tcase_add_test(tc, test_printf_signed);
suite_add_tcase(s, tc);
tc = tcase_create("hex");
tcase_add_test(tc, test_printf_hex);
suite_add_tcase(s, tc);
tc = tcase_create("float");
tcase_add_test(tc, test_printf_float);
suite_add_tcase(s, tc);
return s;
}
+393
View File
@@ -0,0 +1,393 @@
/*
* Copyright (C) 2013 Martin Willi
* Copyright (C) 2013 revosec AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <plugins/plugin_feature.h>
/**
* Signature schemes to test
*/
static signature_scheme_t schemes[] = {
SIGN_RSA_EMSA_PKCS1_NULL,
SIGN_RSA_EMSA_PKCS1_MD5,
SIGN_RSA_EMSA_PKCS1_SHA1,
SIGN_RSA_EMSA_PKCS1_SHA224,
SIGN_RSA_EMSA_PKCS1_SHA256,
SIGN_RSA_EMSA_PKCS1_SHA384,
SIGN_RSA_EMSA_PKCS1_SHA512,
};
/**
* Perform a signature verification "good" test having a keypair
*/
static void test_good_sig(private_key_t *privkey, public_key_t *pubkey)
{
chunk_t sig, data = chunk_from_chars(0x01,0x02,0x03,0xFD,0xFE,0xFF);
int i;
for (i = 0; i < countof(schemes); i++)
{
if (!lib->plugins->has_feature(lib->plugins,
PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[i])) ||
!lib->plugins->has_feature(lib->plugins,
PLUGIN_PROVIDE(PRIVKEY_SIGN, schemes[i])))
{
continue;
}
fail_unless(privkey->sign(privkey, schemes[i], data, &sig),
"sign %N", signature_scheme_names, schemes[i]);
fail_unless(pubkey->verify(pubkey, schemes[i], data, sig),
"verify %N", signature_scheme_names, schemes[i]);
free(sig.ptr);
}
}
/**
* Some special signatures that should never validate successfully
*/
static chunk_t invalid_sigs[] = {
chunk_from_chars(),
chunk_from_chars(0x00),
chunk_from_chars(0x00,0x00),
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
};
/**
* Check public key that it properly fails against some crafted sigs
*/
static void test_bad_sigs(public_key_t *pubkey)
{
chunk_t data = chunk_from_chars(0x01,0x02,0x03,0xFD,0xFE,0xFF);
int s, i;
for (s = 0; s < countof(schemes); s++)
{
if (!lib->plugins->has_feature(lib->plugins,
PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[s])))
{
continue;
}
for (i = 0; i < countof(invalid_sigs); i++)
{
fail_if(
pubkey->verify(pubkey, schemes[s], data, invalid_sigs[i]),
"bad %N sig accepted %B", signature_scheme_names, schemes[s],
&invalid_sigs[i]);
}
}
}
/**
* RSA key sizes to test
*/
static int key_sizes[] = {
786, 1024, 1536, 2048, 3072, 4096,
};
START_TEST(test_gen)
{
private_key_t *privkey;
public_key_t *pubkey;
privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
BUILD_KEY_SIZE, key_sizes[_i], BUILD_END);
ck_assert(privkey != NULL);
pubkey = privkey->get_public_key(privkey);
ck_assert(pubkey != NULL);
test_good_sig(privkey, pubkey);
test_bad_sigs(pubkey);
pubkey->destroy(pubkey);
privkey->destroy(privkey);
}
END_TEST
/**
* Private keys to load
*/
static chunk_t keys[] = {
chunk_from_chars( /* RSA-768 */
0x30,0x82,0x01,0xcb,0x02,0x01,0x00,0x02,0x61,0x00,0xd1,0x5d,0x98,0x97,0x95,0x98,
0x19,0x87,0x20,0x3f,0x10,0xb0,0x05,0x36,0x1e,0x1b,0xcd,0xc8,0x93,0x66,0xd7,0x43,
0xed,0x84,0xb0,0x3e,0x96,0xd3,0xe7,0x27,0x0e,0xc0,0xba,0xdf,0x7e,0x32,0x05,0xd3,
0x08,0xd6,0x44,0xd5,0x01,0x2b,0x3e,0x5d,0xc0,0x37,0xae,0x4f,0xe0,0xea,0x8d,0x2c,
0x42,0x4c,0xa9,0xa2,0x42,0xbe,0xdd,0xdb,0xf7,0xd3,0x28,0x07,0x10,0x88,0x53,0x15,
0xb2,0x4f,0xb5,0x9d,0x47,0x9b,0xd6,0xc8,0xfe,0x5b,0xa2,0xd7,0xe1,0x13,0xca,0x0b,
0xce,0x7a,0xed,0xa2,0x3e,0xd5,0x9b,0xb8,0x8b,0x4f,0x02,0x03,0x01,0x00,0x01,0x02,
0x60,0x2d,0x83,0x82,0x53,0x99,0xb2,0xaa,0x02,0x05,0x11,0x90,0xa8,0x23,0x49,0xe3,
0x7b,0xb9,0xdd,0x9b,0xa5,0xa4,0xb0,0x60,0xa7,0x12,0xc5,0x58,0x76,0x92,0x6e,0x9c,
0x37,0x6b,0xa8,0x80,0x3f,0x91,0xa2,0x91,0xee,0x3a,0xa2,0x6f,0x91,0x9e,0x0a,0x35,
0x69,0xc0,0xa7,0xdc,0xd8,0x46,0xe4,0x29,0x1c,0x3d,0x34,0x30,0xa2,0xb9,0x0d,0x34,
0x94,0xa1,0x12,0xa7,0x85,0xd3,0x2c,0x47,0x1b,0xf0,0x78,0xd5,0x22,0xfc,0xa5,0xe0,
0x75,0xac,0x71,0x21,0xe8,0xe8,0x19,0x9f,0xbb,0x98,0x5c,0xa6,0x9d,0x42,0xd7,0x9c,
0x89,0x02,0x31,0x00,0xee,0xaa,0x9e,0x82,0xe1,0xb2,0xdd,0x05,0xbc,0x2e,0x53,0xe9,
0x64,0x4b,0x48,0x06,0x3a,0xfd,0x9e,0x91,0xce,0x1b,0x7f,0x66,0xbc,0xd2,0xc4,0xab,
0xbf,0xc5,0x5d,0x1a,0xbd,0xd6,0xb5,0x9c,0x5c,0x18,0x01,0xe6,0x79,0x19,0xf2,0xc3,
0x1d,0x66,0x88,0x2d,0x02,0x31,0x00,0xe0,0x92,0x34,0x1e,0x09,0xf2,0x1b,0xf9,0xbf,
0x11,0x65,0x3f,0xc8,0x85,0x5a,0xe6,0xc0,0xcf,0x93,0x44,0xb0,0x50,0xe4,0x8b,0x6f,
0x30,0xde,0x42,0x0c,0x8a,0x77,0x0d,0x98,0x7f,0x52,0x59,0x9e,0x87,0xb8,0x6e,0xdc,
0xed,0x15,0x80,0xbd,0xbb,0xf2,0xeb,0x02,0x31,0x00,0xb0,0x6b,0x36,0x98,0x90,0xb5,
0x62,0x63,0xa6,0xe2,0xa7,0xec,0x51,0xd2,0xc3,0xfe,0xb7,0x04,0x5a,0x7e,0x74,0xd8,
0x26,0xa8,0x8e,0xd3,0x4d,0xc5,0x97,0x10,0x10,0xee,0x7f,0x7d,0x82,0xe9,0x7d,0xb9,
0xd1,0x4d,0xc8,0x1e,0xc2,0x30,0x30,0x3f,0x66,0x51,0x02,0x31,0x00,0xaa,0x75,0x2f,
0x4c,0x11,0xbe,0x8d,0x0f,0x8f,0xc1,0x13,0x7a,0x4b,0xa9,0x35,0x6b,0x6b,0xb4,0xe3,
0x92,0xc2,0xc6,0x54,0x03,0xa6,0x5d,0x90,0x86,0xcf,0xe0,0x16,0x27,0xe2,0xb5,0xd9,
0xfb,0x1e,0x82,0xe4,0x32,0x7a,0x4d,0x17,0x02,0x46,0x82,0x30,0x0b,0x02,0x30,0x09,
0xf3,0xce,0x9b,0x02,0xc5,0x53,0xe9,0xa2,0x89,0xe2,0x3b,0x8c,0x8b,0xe9,0xc2,0xba,
0x94,0x76,0x60,0x27,0x2b,0xe9,0x92,0xc1,0x5e,0x3c,0xc3,0x77,0x9b,0xc7,0xce,0xc6,
0x67,0xd5,0x20,0x2c,0x54,0xa1,0x5d,0x2a,0x17,0x16,0x66,0xdf,0x5a,0xe9,0x87,
),
chunk_from_chars( /* RSA-1024 */
0x30,0x82,0x02,0x5c,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xc0,0xbd,0x48,0x83,0xbc,
0xea,0x0b,0x32,0x06,0x4b,0xf5,0x10,0x54,0x1b,0xba,0x88,0xc4,0x10,0x7e,0x47,0xec,
0x0e,0xf9,0xb4,0xcf,0x9a,0x02,0xc6,0xb3,0xaf,0x35,0xc8,0xaf,0x78,0x1a,0xbc,0x37,
0x1a,0x25,0x7a,0x37,0x24,0x73,0x53,0x9a,0xf0,0x44,0x64,0x5b,0x6b,0x64,0x4c,0xfa,
0x83,0x3a,0x0f,0x77,0x5d,0x7b,0x21,0xa2,0x25,0x00,0x11,0xae,0x72,0x36,0x35,0xd9,
0x0d,0xef,0x5a,0xdd,0x98,0x35,0x49,0xaf,0x44,0xa0,0x33,0x29,0xc0,0xca,0xf5,0x6f,
0xfe,0xc1,0x06,0x4c,0x80,0x9a,0x54,0xbe,0x46,0x1a,0x96,0xb1,0xf3,0x29,0xb8,0x9d,
0x07,0x84,0x03,0x68,0x6b,0x9f,0xbf,0xe5,0xd8,0x14,0x2a,0xe0,0xef,0xbd,0x1a,0x61,
0x0d,0x3a,0xc8,0x67,0xcd,0x99,0x90,0xe3,0xe6,0x52,0x83,0x02,0x03,0x01,0x00,0x01,
0x02,0x81,0x80,0x13,0xd2,0xa3,0xe5,0xa0,0xb0,0x0a,0xe2,0x0f,0x3c,0x65,0x57,0xa8,
0xe9,0x87,0xd5,0x79,0xcc,0xc9,0xca,0xc8,0x8a,0xd5,0xc0,0x74,0x90,0x3e,0x1e,0xda,
0x40,0xcd,0x42,0xf7,0x01,0x09,0x9c,0x37,0xfd,0x41,0x6e,0x2b,0x6e,0x5d,0x4a,0x1e,
0x52,0x53,0x1b,0xbb,0x3c,0x9f,0xfe,0x91,0x79,0x48,0xfc,0x69,0x90,0xbc,0xbc,0x3d,
0xcf,0xee,0x62,0x0a,0xbd,0x57,0x6b,0xa9,0x51,0x3e,0xc2,0x7f,0x26,0xb1,0xaa,0x38,
0xeb,0x40,0x91,0x3a,0x3c,0x80,0x1e,0x4e,0xe2,0xff,0xa2,0x8e,0x56,0xbb,0xb3,0xeb,
0x24,0x81,0x4c,0x19,0x2c,0x8f,0x51,0x4c,0x04,0x81,0xaf,0x5e,0xc2,0xa6,0xf9,0xd3,
0x48,0xee,0xe9,0x6d,0x9b,0xe1,0xe5,0x17,0x4f,0x07,0x18,0xea,0x96,0xd3,0x2c,0xce,
0x44,0x71,0x51,0x02,0x41,0x00,0xe9,0xe9,0x46,0x7e,0xe1,0xc2,0x86,0x94,0x65,0x77,
0x9c,0xc7,0x76,0x5d,0xa0,0xd3,0xcc,0x1f,0xa3,0xc7,0xfe,0xbb,0x4e,0x27,0xd6,0x43,
0x6b,0xbd,0x0d,0x05,0x7a,0x10,0xe8,0x48,0x97,0x30,0xaa,0x53,0x61,0x57,0x1f,0x8a,
0xf7,0x39,0x5e,0xa6,0xfe,0xe9,0x2c,0x19,0x5e,0x53,0xea,0xc2,0xb2,0xc2,0x11,0x3c,
0x18,0xab,0xcf,0xc4,0x91,0x1b,0x02,0x41,0x00,0xd2,0xf0,0xb1,0x49,0xa1,0x6f,0xf1,
0x83,0xa3,0xd2,0xa1,0x0e,0xb3,0xb3,0x33,0x01,0xed,0xd0,0x28,0xc1,0x2f,0x88,0x80,
0x9f,0x43,0x7c,0x7e,0x5d,0x4c,0x15,0x05,0x86,0xff,0x75,0x9b,0xf1,0x64,0xde,0x06,
0xbf,0xdd,0x98,0x50,0xd9,0x4a,0x3a,0xd6,0x25,0x1c,0xdd,0xc8,0x56,0x12,0x11,0xb9,
0x02,0x42,0xc7,0x1d,0x86,0xeb,0xd9,0xc2,0xb9,0x02,0x41,0x00,0x80,0x25,0x8c,0xb9,
0x76,0x75,0x5b,0xc5,0x70,0xd1,0x56,0xd2,0xef,0xc5,0xdb,0x96,0x2c,0xfe,0x28,0x7c,
0x28,0xd1,0xf4,0xbf,0x5e,0x63,0x11,0x63,0x40,0xfe,0xff,0x20,0xc4,0x21,0x00,0xb3,
0x68,0x9c,0xc5,0x77,0x35,0x90,0xac,0x60,0x81,0xba,0x7b,0x6c,0xc2,0xfc,0x22,0xf1,
0x56,0x6b,0xd4,0x02,0xfd,0xee,0x2e,0x95,0xf1,0xfd,0x7e,0x81,0x02,0x40,0x47,0xaf,
0x84,0x90,0x81,0x4c,0x89,0xc7,0x32,0xe5,0x61,0xd6,0x9d,0x3b,0x49,0x1a,0x5e,0xb7,
0x5f,0x22,0x48,0x05,0x1b,0xb1,0x04,0x3e,0x4a,0xb3,0x6a,0x27,0xba,0xb9,0x26,0x17,
0xd1,0xe7,0x37,0x60,0x3c,0xea,0xf7,0x63,0xcc,0x16,0x0c,0x23,0xf2,0xa2,0xaa,0x2c,
0xb4,0xe8,0x8b,0x3b,0x7a,0xa4,0x4a,0x0d,0x60,0xfb,0x79,0x2b,0x88,0x01,0x02,0x40,
0x42,0xee,0x12,0x91,0xf9,0x80,0x1e,0x60,0x0b,0xaa,0xbe,0xfd,0x09,0x84,0x93,0x0d,
0x09,0xd3,0x1e,0x37,0x52,0xb0,0xe8,0x51,0x4f,0xd3,0x9e,0xda,0x32,0x38,0x22,0x35,
0xdb,0x25,0x8b,0x9f,0x1a,0xb5,0xf1,0x75,0xfa,0x4d,0x09,0x42,0x01,0x64,0xe6,0xc4,
0x6e,0xba,0x2d,0x88,0x92,0xbe,0xa9,0x1f,0x85,0x38,0x10,0xa3,0x0e,0x1a,0x92,0x54,
),
chunk_from_chars( /* RSA-1536 */
0x30,0x82,0x03,0x7d,0x02,0x01,0x00,0x02,0x81,0xc1,0x00,0xba,0xe3,0x37,0x93,0x7e,
0x42,0x13,0x3c,0xba,0x41,0xc1,0x7b,0xf0,0xcc,0x7a,0x44,0xc6,0x54,0xc8,0x77,0x01,
0x70,0x2f,0x6e,0x4a,0xcf,0x2d,0x07,0xab,0x01,0xc0,0x43,0xab,0x8d,0x33,0xb3,0xd4,
0xeb,0xe3,0x90,0xf6,0x01,0x03,0x75,0x03,0x1d,0xe8,0x06,0x40,0x15,0xfa,0x96,0x0b,
0xd5,0x26,0x64,0xea,0x55,0x82,0x16,0x7b,0xd5,0x1e,0xaa,0x08,0xc7,0x30,0x1a,0x59,
0xf8,0xd9,0xe3,0x9e,0x89,0xd9,0x92,0x2c,0x32,0x79,0x0e,0xb3,0x25,0xbc,0x1d,0x7c,
0x59,0xde,0x05,0x47,0x8f,0x61,0x77,0xf5,0x4f,0xed,0x82,0x2c,0xf8,0x2a,0x3e,0x02,
0xf3,0xc0,0x15,0x51,0xde,0x05,0xc4,0xfc,0x80,0x91,0xae,0x06,0x1b,0xd7,0x39,0x8e,
0x9a,0x6d,0xb3,0x2f,0xb0,0xd0,0xc8,0x96,0xa6,0x88,0xb3,0x17,0xca,0x58,0xbe,0x38,
0x2c,0x64,0x35,0x5a,0x29,0xb7,0xf8,0x74,0x3d,0xbb,0xec,0x90,0x01,0x04,0x64,0x3d,
0x38,0x0f,0x87,0xce,0xd7,0xfc,0xd2,0x96,0x93,0x31,0x85,0x0d,0x2d,0xa5,0x91,0xe2,
0xfc,0x7b,0xea,0xb0,0x89,0x24,0xaa,0x00,0x29,0x8c,0x26,0x7c,0x94,0x54,0x74,0xe4,
0x11,0xa8,0x04,0x6f,0x40,0xeb,0xaf,0xed,0xac,0x75,0x33,0x02,0x03,0x01,0x00,0x01,
0x02,0x81,0xc0,0x0a,0x96,0xec,0x63,0xc1,0xa0,0x39,0xd9,0xd3,0x8d,0xfd,0x4a,0x2a,
0x13,0x54,0x0c,0x48,0x96,0xae,0x43,0x3c,0x04,0x20,0xd3,0xe5,0x8e,0x46,0xb5,0x6c,
0x05,0xad,0xe0,0xc7,0xbc,0x39,0x05,0x44,0x17,0xd7,0xad,0xb3,0x9a,0xcc,0x18,0xd9,
0xc3,0xdc,0x8d,0x5a,0x1d,0x44,0xb5,0x32,0xd7,0x71,0x94,0xff,0x48,0x38,0x16,0x51,
0x0e,0xfa,0xed,0x54,0x91,0x00,0xd3,0x45,0x6c,0xd9,0xdf,0xd1,0x70,0x6b,0x31,0x22,
0xaa,0xfb,0x7c,0x0f,0x3f,0xa0,0xa0,0xa5,0x16,0xac,0x83,0x6d,0x12,0x1d,0x4a,0x40,
0x4e,0xb6,0x9c,0xf4,0x67,0xaa,0xa9,0xb0,0xc8,0xb4,0x0a,0xd5,0x3b,0x5c,0x19,0xed,
0x86,0x83,0x5a,0x75,0xbc,0xeb,0x17,0xc8,0x16,0xa0,0x60,0x2e,0xb6,0x25,0xc5,0x4d,
0x59,0xba,0x62,0xcb,0x3d,0x91,0x7c,0x79,0x6a,0x4b,0x4a,0x54,0xbd,0xb7,0xa3,0x89,
0x7f,0xbf,0x0e,0x77,0xe1,0x54,0x29,0x0d,0x45,0x6d,0xa8,0x15,0xa5,0x17,0x8c,0xcf,
0x27,0x9e,0x47,0x4e,0x2a,0x91,0x7e,0x4e,0x14,0x59,0x8c,0x62,0x91,0xa3,0x40,0xa5,
0x9e,0x67,0xbb,0x02,0x97,0xb4,0xe7,0x06,0x04,0xbc,0x16,0x24,0x3d,0x49,0xb1,0xf0,
0xae,0xfc,0x1d,0x02,0x61,0x00,0xde,0x86,0x5d,0x49,0x88,0xeb,0x5c,0xd3,0xe5,0x11,
0x48,0x0b,0x1e,0x52,0x95,0xa9,0x65,0x99,0x89,0xcf,0x51,0xb0,0x08,0xdd,0xb5,0x5b,
0x64,0x1a,0x34,0xd2,0xee,0x4b,0x2d,0x8b,0xc1,0xd5,0xd6,0x1d,0x6c,0x0c,0x7e,0xa5,
0x66,0x12,0xec,0xaf,0x5d,0xe9,0x33,0xd4,0xba,0x18,0x71,0x84,0x97,0xbe,0xc0,0x75,
0x63,0x19,0xae,0xc6,0xc7,0x65,0xf3,0xf6,0xda,0x3f,0x91,0xfa,0x5e,0x87,0xf3,0xbc,
0xd2,0x64,0x8d,0xcf,0xfb,0xdd,0x7f,0x9b,0x6c,0x81,0xba,0x9b,0x4e,0x94,0x5e,0x83,
0xd1,0xcb,0xb9,0xf4,0x39,0x7f,0x02,0x61,0x00,0xd7,0x00,0x6d,0x8e,0x1b,0xa1,0x44,
0xd9,0xff,0xe6,0x42,0x72,0x18,0x55,0x26,0x3e,0x87,0x40,0x71,0xb2,0x67,0x37,0x16,
0xe9,0xbd,0x51,0x7f,0x0e,0x79,0x0e,0x75,0xa9,0x1f,0x0f,0x6b,0xa5,0x7c,0x5f,0xc8,
0xdc,0x17,0xde,0x53,0x88,0x97,0x90,0x88,0xf2,0x4d,0x66,0x5e,0x0e,0x11,0x16,0x92,
0x1e,0x61,0x56,0xe6,0xf0,0x74,0x81,0x58,0x95,0x05,0x29,0x71,0x9b,0xa0,0x69,0xed,
0x14,0x23,0xf6,0x36,0x9b,0x8f,0x06,0x3a,0x76,0xab,0xeb,0xce,0xe8,0xdc,0x79,0xc1,
0x29,0xb9,0xfc,0x49,0x7a,0x26,0x59,0xd6,0x4d,0x02,0x61,0x00,0xaf,0x3c,0xac,0xd6,
0x2d,0xe6,0xfb,0x91,0x3a,0xc1,0x23,0x34,0xee,0x4a,0x26,0xe5,0xe1,0xc6,0xc9,0xc9,
0xe4,0x10,0x76,0xca,0xf1,0xf8,0xe8,0x99,0xe2,0xa3,0x81,0x58,0xde,0xa3,0x42,0xa0,
0x3d,0x1f,0xaa,0x69,0x24,0x8a,0xe8,0x19,0x5b,0x1e,0xb7,0x1b,0xe0,0xdf,0x53,0x35,
0xd0,0x9f,0x94,0x48,0x79,0x93,0x77,0xd9,0x4f,0xd3,0xe6,0x4f,0x19,0x92,0x7a,0x48,
0xb9,0x92,0xab,0x42,0xf0,0xe4,0xef,0xe2,0x93,0xf3,0x07,0xeb,0x64,0x84,0x67,0x2c,
0xba,0x61,0x77,0xbe,0x4b,0xb8,0x0f,0x4d,0x1a,0x41,0x83,0xcd,0x02,0x60,0x56,0xec,
0x55,0x5e,0x9e,0xcd,0x14,0x89,0x0e,0x6c,0x89,0x70,0x97,0x65,0xd5,0x90,0x72,0x1e,
0x1b,0xd9,0x84,0xe1,0x40,0xe2,0x3f,0x28,0x33,0xb6,0x26,0x3b,0x32,0x56,0xad,0xb8,
0x0e,0x4d,0x59,0x7b,0x60,0x39,0x9b,0x6c,0xc7,0x58,0xf1,0xed,0xfd,0x6f,0xf8,0xda,
0xea,0x2b,0xc5,0xbc,0xda,0x56,0x6e,0x04,0x34,0x5a,0x02,0xc0,0x48,0x8f,0xf7,0x06,
0x4a,0x68,0x20,0xf2,0xb2,0x66,0xf2,0x23,0x18,0xf0,0xcb,0x62,0x39,0x40,0xc1,0x41,
0x14,0xe6,0x10,0x3d,0x29,0x5b,0x35,0x56,0x4a,0x5e,0x98,0x22,0xba,0x01,0x02,0x61,
0x00,0xcc,0x80,0xb7,0xb9,0xb9,0x4a,0xaf,0x47,0x00,0x3e,0x21,0x0f,0xb8,0x4e,0x7c,
0xb1,0xe4,0x25,0xd6,0x19,0x26,0x54,0xc6,0x8c,0x30,0x88,0x54,0x70,0xcf,0x1f,0x62,
0x75,0xcb,0x18,0x58,0x6c,0x14,0xb0,0x9b,0x13,0x90,0xa2,0x1a,0x5a,0x79,0xa3,0x82,
0xf0,0x9b,0xba,0xf0,0x90,0xaf,0xa1,0xe8,0xa8,0x70,0xef,0x60,0x6a,0x68,0xed,0x5a,
0x21,0x77,0x69,0x7a,0xf2,0xee,0x3e,0xe5,0x90,0xd2,0x33,0x71,0x3b,0x82,0x88,0x75,
0xdd,0x8e,0x6e,0xbc,0x17,0x83,0xef,0x37,0x82,0x4e,0x83,0x30,0xcb,0x8a,0xbc,0x6c,
0x41,
),
chunk_from_chars( /* RSA-2048 */
0x30,0x82,0x04,0xa2,0x02,0x01,0x00,0x02,0x82,0x01,0x01,0x00,0xba,0xbf,0x27,0x0b,
0x22,0x59,0xd8,0x6f,0xff,0x26,0x5d,0x41,0x3d,0xb0,0x94,0x58,0x5d,0xc0,0x46,0xb6,
0x77,0xa9,0x78,0x10,0x6d,0xe9,0xbf,0xca,0x6f,0x04,0xe1,0xda,0x85,0x12,0x1e,0xe0,
0xa6,0xc7,0xa2,0x71,0x04,0x8b,0x6e,0x84,0xf9,0x86,0x2b,0xeb,0x72,0x01,0x72,0xc8,
0x0a,0x83,0xa6,0xf7,0xc0,0xd6,0x76,0x1d,0x28,0x38,0xb5,0x7e,0x6c,0x8c,0x6a,0x13,
0xf4,0xf1,0x7f,0xf2,0x79,0xae,0x73,0xba,0x1a,0x3f,0x30,0x65,0xb6,0x23,0xa7,0x94,
0x34,0x29,0x87,0xce,0x06,0x99,0xee,0x85,0x10,0xce,0x08,0xe2,0x8d,0xd5,0x47,0xf3,
0xc8,0xf0,0x18,0x41,0xc0,0x59,0x66,0x06,0xda,0xb6,0x18,0xd2,0xa3,0xa0,0xbd,0x3a,
0x90,0x7f,0x37,0x39,0xdf,0x98,0x55,0xa2,0x19,0x5e,0x37,0xbc,0x86,0xf3,0x02,0xf8,
0x68,0x49,0x53,0xf2,0x4b,0x3d,0x7a,0xe3,0x1d,0xa4,0x15,0x10,0xa6,0xce,0x8c,0xb8,
0xfd,0x95,0x54,0xa2,0x50,0xa2,0xd9,0x35,0x12,0x56,0xae,0xbc,0x51,0x33,0x6d,0xb8,
0x63,0x7c,0x26,0xab,0x19,0x01,0xa5,0xda,0xfa,0x4b,0xb6,0x57,0xd3,0x4b,0xdd,0xc0,
0x62,0xc5,0x05,0xb7,0xc3,0x2e,0x1f,0x17,0xc8,0x09,0x87,0x12,0x37,0x21,0xd7,0x7a,
0x53,0xb0,0x47,0x60,0xa2,0xb5,0x23,0x3b,0x99,0xdf,0xea,0x8b,0x94,0xea,0x9d,0x53,
0x5d,0x02,0x52,0xf7,0x29,0xfb,0x63,0xb0,0xff,0x27,0x5e,0xde,0x54,0x7d,0x95,0xd6,
0x4e,0x58,0x12,0x06,0x60,0x22,0x33,0xf2,0x19,0x67,0x65,0xdd,0xf3,0x42,0xb5,0x00,
0x51,0x35,0xe5,0x62,0x4d,0x90,0x44,0xfb,0x7f,0x5b,0xb5,0xe5,0x02,0x03,0x01,0x00,
0x01,0x02,0x82,0x01,0x00,0x1c,0xf5,0x66,0xf5,0xce,0x4c,0x1d,0xe8,0xd2,0x29,0x6e,
0x15,0x1f,0x9e,0x9a,0x06,0x70,0xf5,0x4f,0xd1,0xdc,0x51,0x02,0x8e,0x13,0xa9,0x47,
0x85,0x39,0xfd,0x89,0x13,0x74,0x86,0xb8,0x94,0x90,0x30,0x4d,0x73,0x96,0xa7,0x93,
0x8a,0x19,0xd2,0x91,0x4d,0x77,0xb6,0x9b,0x48,0xc3,0x7e,0xa2,0x5d,0xf1,0x80,0xa0,
0x3c,0xc9,0xbf,0xaf,0x7f,0x4d,0x10,0x62,0x23,0xb9,0x9c,0x58,0x81,0xae,0x96,0x5b,
0x9a,0x4c,0x97,0x27,0x67,0x62,0x5c,0xf9,0x8f,0xdd,0x1d,0xe2,0x92,0x13,0x8a,0x7b,
0xc7,0x15,0x31,0xca,0x05,0x6d,0xc6,0x98,0xdb,0x88,0x39,0x99,0x1d,0x5b,0x19,0x51,
0xdd,0xb6,0xbd,0x3d,0xb0,0xae,0x50,0x8e,0xff,0x7d,0xa8,0x48,0x95,0x58,0x23,0xbc,
0x85,0xc0,0x46,0xd0,0xc0,0x0e,0xda,0xdd,0xa4,0x8e,0x8d,0x31,0x8b,0x89,0x0f,0x8b,
0x76,0x9a,0xb5,0x99,0x56,0x5e,0xd3,0x0c,0x88,0x0b,0x03,0xf1,0xc9,0xe3,0x05,0x05,
0x08,0x75,0xce,0x35,0x52,0xa0,0xc0,0xf2,0xf4,0xb9,0x87,0x22,0x21,0x3f,0x61,0xd6,
0x99,0xae,0x0e,0x76,0x5d,0x9c,0x16,0xa3,0xe9,0xde,0x2d,0x2a,0x46,0xf7,0x89,0xbf,
0x0d,0xb1,0x60,0xad,0xbc,0x24,0xe2,0xe5,0xb1,0xc1,0x1c,0x00,0x40,0x1c,0xbd,0xfa,
0x6e,0xc7,0x0d,0xc1,0xda,0x4d,0x54,0x45,0x96,0xac,0xf7,0xfe,0x1b,0xf2,0x47,0x1e,
0xf7,0x8b,0xcf,0x27,0xcc,0xe7,0x08,0xd6,0x43,0x60,0xea,0xda,0x19,0xd7,0x98,0x17,
0x7c,0xab,0x0c,0x90,0x60,0x75,0x9f,0x8b,0xaa,0x13,0x63,0x98,0x9e,0xc6,0x41,0x9f,
0xd4,0x85,0xa3,0xb2,0xb9,0x02,0x81,0x81,0x00,0xe1,0x20,0xf6,0xac,0xa9,0x01,0xbd,
0x31,0xe6,0xb2,0x4e,0xcf,0x66,0xc3,0x11,0x0e,0x5b,0xfe,0x58,0x6b,0xc6,0x2d,0x7a,
0x05,0x30,0x9a,0x6f,0xcc,0xcc,0xdf,0xd2,0x2c,0xe1,0x47,0x39,0x9e,0xf3,0x0c,0x81,
0xd9,0x76,0x00,0xe2,0xb1,0x08,0x91,0xfb,0x12,0x04,0xf6,0x1f,0xea,0xff,0x82,0xe5,
0x64,0x64,0x6f,0x14,0xbe,0x33,0x5f,0x41,0x5f,0x73,0x1f,0xa2,0x32,0xec,0x75,0xb3,
0x98,0x4b,0x88,0x4d,0x1e,0xec,0x78,0xda,0x4c,0x2d,0xf8,0xbb,0xcf,0x0e,0x8f,0x2f,
0x23,0xae,0xcd,0xe0,0x4c,0x13,0x1c,0x1c,0x16,0x8e,0xb9,0x9f,0x02,0x12,0x12,0xa5,
0xf4,0x21,0xfe,0x57,0x08,0x7a,0xe8,0xbe,0x15,0xe9,0xdd,0x2a,0xd1,0x7b,0x39,0xd6,
0x4f,0x70,0x74,0x7d,0xfd,0x39,0x97,0x80,0x8d,0x02,0x81,0x81,0x00,0xd4,0x5a,0xce,
0x05,0x93,0x51,0x15,0x44,0xdd,0x4d,0x79,0x92,0x04,0xe6,0x64,0x7e,0x6c,0xb5,0x61,
0x6b,0xc3,0xb3,0xae,0x4f,0x0a,0x75,0xbf,0x6c,0xec,0x47,0xf2,0xbc,0xea,0x76,0xc4,
0xc2,0xe7,0xd2,0x50,0xc4,0xe0,0xaf,0x56,0x05,0x72,0x3c,0x34,0x8c,0x5b,0xae,0xb8,
0x0e,0xfb,0x83,0x27,0xcf,0x61,0x05,0x44,0x97,0x3f,0x66,0x6d,0x26,0x7d,0xed,0xcd,
0x5a,0x87,0x04,0xbc,0xb3,0x70,0x75,0x15,0x51,0xe9,0x18,0x85,0xf7,0x2a,0x45,0xd5,
0xc7,0x93,0x32,0x07,0x2e,0x26,0x34,0x2d,0x18,0x63,0x45,0x06,0x6f,0xa9,0x75,0x5d,
0x20,0x6b,0x0b,0x13,0x45,0x81,0x7e,0x5c,0xc5,0x48,0x16,0x4b,0x82,0x7c,0xad,0xbe,
0xfd,0xa5,0x0a,0xd6,0xc2,0x21,0xfc,0xa5,0x84,0xaf,0xf3,0x10,0xb9,0x02,0x81,0x80,
0x29,0x20,0x20,0x6f,0xc2,0x1f,0xf3,0x33,0xde,0x74,0xcc,0x38,0xcf,0x08,0xeb,0x60,
0xb8,0x25,0x6a,0x79,0xa5,0xa6,0x41,0x18,0x19,0x9c,0xdc,0xb7,0x88,0xe5,0x8a,0x3b,
0x70,0x9b,0xd6,0x46,0xd7,0x17,0x7d,0xd0,0xff,0xe1,0x81,0x87,0xdd,0x8c,0xed,0x54,
0x89,0x5b,0x7c,0xd1,0x2d,0x03,0xf8,0x6b,0xb2,0x7d,0x28,0x48,0xe6,0x91,0x8c,0x1b,
0xa7,0xa8,0x2b,0xb5,0x29,0xc5,0x06,0x9d,0xd7,0x8e,0x7a,0xa8,0x1f,0x82,0xa4,0x3e,
0x2e,0x57,0xb5,0xd7,0x49,0x4d,0x96,0xca,0xe9,0xef,0xe9,0xfd,0x7b,0xb0,0x32,0xe1,
0x5c,0x09,0x44,0xa6,0xd8,0x2e,0x57,0xea,0x95,0x1b,0x25,0x43,0x03,0x50,0xe9,0x08,
0x8f,0xc4,0x3b,0x42,0x31,0x44,0x8b,0x85,0xcf,0x81,0x38,0x52,0xbd,0xe6,0x93,0x31,
0x02,0x81,0x80,0x18,0x3d,0x79,0x51,0x07,0x9c,0xf4,0xd9,0x94,0x8d,0x78,0x78,0x23,
0x99,0x0d,0x15,0xa5,0x61,0x1b,0x0a,0xcb,0x1f,0x22,0xa1,0xa1,0x27,0x09,0xbf,0xec,
0x44,0xd6,0x3f,0x9c,0x60,0x0c,0x5b,0xd7,0x4c,0x99,0xad,0xaf,0x9c,0x34,0x2c,0x90,
0xfa,0xb0,0x60,0xe9,0x42,0x4b,0x7e,0x62,0x55,0x79,0x60,0xe1,0xc9,0x51,0x28,0x16,
0xb3,0xa1,0x78,0x08,0x5d,0xf1,0xd8,0x08,0x9b,0x90,0xd2,0xc6,0xde,0x86,0x9d,0x80,
0x07,0x2d,0x9b,0xa6,0x36,0xac,0x8d,0x88,0x8e,0xe8,0x64,0xeb,0x35,0x7f,0x84,0x4e,
0x28,0x9d,0xf0,0x77,0x1e,0x8f,0x8f,0xd8,0xc8,0x3d,0xdd,0xec,0x47,0x39,0x5d,0xc7,
0xb9,0xcb,0xca,0xcc,0x62,0xa4,0xef,0x9d,0x3c,0x5c,0x81,0x72,0x91,0xbd,0x6f,0x25,
0x0a,0x90,0xf9,0x02,0x81,0x80,0x51,0x42,0x23,0x64,0x3d,0xbc,0xcb,0xcb,0x77,0xd4,
0x5c,0x6b,0xf4,0x16,0x3a,0x6b,0x05,0x5f,0xd4,0xf8,0x59,0xe6,0x98,0x0c,0x43,0x7e,
0x6b,0x17,0x0d,0x01,0x23,0x6e,0x4c,0xff,0x35,0xe4,0xc5,0xba,0xe8,0x9e,0x12,0x94,
0x34,0x78,0xe4,0x3d,0x35,0xa1,0xd4,0xa9,0xa3,0x7e,0xe4,0x57,0xef,0xa4,0x9a,0x6a,
0x32,0xb3,0x9f,0xf8,0x3a,0xcf,0xea,0xf4,0xc7,0x59,0x92,0xd4,0x2a,0x5b,0x26,0x83,
0x78,0x30,0x5f,0xdf,0x46,0xa6,0xb0,0x28,0x37,0x2b,0x55,0x08,0x4c,0xb6,0x6b,0xb8,
0xa9,0x11,0x7d,0x0b,0xab,0x97,0x4d,0x8c,0xc3,0xbf,0x3b,0xcd,0x3e,0xad,0x80,0xce,
0xe8,0xc6,0x01,0x35,0xd2,0x3e,0x31,0xdc,0x96,0xd7,0xc3,0xab,0x65,0xd1,0xc4,0xa3,
0x47,0x14,0xa9,0xba,0xd0,0x30,
),
};
START_TEST(test_load)
{
private_key_t *privkey;
public_key_t *pubkey;
privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
BUILD_BLOB_ASN1_DER, keys[_i], BUILD_END);
ck_assert(privkey != NULL);
pubkey = privkey->get_public_key(privkey);
ck_assert(pubkey != NULL);
test_good_sig(privkey, pubkey);
test_bad_sigs(pubkey);
pubkey->destroy(pubkey);
privkey->destroy(privkey);
}
END_TEST
Suite *rsa_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("rsa");
tc = tcase_create("generate");
tcase_add_loop_test(tc, test_gen, 0, countof(key_sizes));
tcase_set_timeout(tc, 8);
suite_add_tcase(s, tc);
tc = tcase_create("load");
tcase_add_loop_test(tc, test_load, 0, countof(keys));
suite_add_tcase(s, tc);
return s;
}
@@ -0,0 +1,110 @@
/*
* Copyright (C) 2013 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <sched.h>
#include <pthread.h>
#include "test_suite.h"
#include <threading/mutex.h>
/*******************************************************************************
* recursive mutex test
*/
#define THREADS 20
static mutex_t *mutex;
static pthread_barrier_t mutex_barrier;
static int mutex_locked = 0;
static void *mutex_run(void *data)
{
int i;
/* wait for all threads before getting in action */
pthread_barrier_wait(&mutex_barrier);
for (i = 0; i < 100; i++)
{
mutex->lock(mutex);
mutex->lock(mutex);
mutex->lock(mutex);
mutex_locked++;
sched_yield();
if (mutex_locked > 1)
{
fail("two threads locked the mutex concurrently");
}
mutex_locked--;
mutex->unlock(mutex);
mutex->unlock(mutex);
mutex->unlock(mutex);
}
return NULL;
}
START_TEST(test_mutex)
{
pthread_t threads[THREADS];
int i;
mutex = mutex_create(MUTEX_TYPE_RECURSIVE);
for (i = 0; i < 10; i++)
{
mutex->lock(mutex);
mutex->unlock(mutex);
}
for (i = 0; i < 10; i++)
{
mutex->lock(mutex);
}
for (i = 0; i < 10; i++)
{
mutex->unlock(mutex);
}
pthread_barrier_init(&mutex_barrier, NULL, THREADS);
for (i = 0; i < THREADS; i++)
{
pthread_create(&threads[i], NULL, mutex_run, NULL);
}
for (i = 0; i < THREADS; i++)
{
pthread_join(threads[i], NULL);
}
pthread_barrier_destroy(&mutex_barrier);
mutex->destroy(mutex);
}
END_TEST
Suite *threading_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("threading");
tc = tcase_create("recursive mutex");
tcase_add_test(tc, test_mutex);
suite_add_tcase(s, tc);
return s;
}
+556
View File
@@ -0,0 +1,556 @@
/*
* Copyright (C) 2013 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
#include <library.h>
#include <utils/utils.h>
#include <ipsec/ipsec_types.h>
#include <time.h>
/*******************************************************************************
* object storage on lib
*/
START_TEST(test_objects)
{
char *k1 = "key1", *k2 = "key2";
char *v1 = "val1", *val;
ck_assert(lib->get(lib, k1) == NULL);
ck_assert(lib->set(lib, k1, v1));
ck_assert(!lib->set(lib, k1, v1));
val = lib->get(lib, k1);
ck_assert(val != NULL);
ck_assert(streq(val, v1));
ck_assert(lib->set(lib, k1, NULL));
ck_assert(!lib->set(lib, k2, NULL));
ck_assert(lib->get(lib, k1) == NULL);
}
END_TEST
/*******************************************************************************
* test return_... functions
*/
START_TEST(test_return_functions)
{
ck_assert(return_null() == NULL);
ck_assert(return_null("asdf", 5, NULL, 1, "qwer") == NULL);
ck_assert(return_true() == TRUE);
ck_assert(return_true("asdf", 5, NULL, 1, "qwer") == TRUE);
ck_assert(return_false() == FALSE);
ck_assert(return_false("asdf", 5, NULL, 1, "qwer") == FALSE);
ck_assert(return_failed() == FAILED);
ck_assert(return_failed("asdf", 5, NULL, 1, "qwer") == FAILED);
ck_assert(return_success() == SUCCESS);
ck_assert(return_success("asdf", 5, NULL, 1, "qwer") == SUCCESS);
/* just make sure this works */
nop();
nop("asdf", 5, NULL, 1, "qwer");
}
END_TEST
/*******************************************************************************
* timeval_add_ms
*/
START_TEST(test_timeval_add_ms)
{
timeval_t tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
timeval_add_ms(&tv, 0);
ck_assert_int_eq(tv.tv_sec, 0);
ck_assert_int_eq(tv.tv_usec, 0);
timeval_add_ms(&tv, 1);
ck_assert_int_eq(tv.tv_sec, 0);
ck_assert_int_eq(tv.tv_usec, 1000);
timeval_add_ms(&tv, 0);
ck_assert_int_eq(tv.tv_sec, 0);
ck_assert_int_eq(tv.tv_usec, 1000);
timeval_add_ms(&tv, 999);
ck_assert_int_eq(tv.tv_sec, 1);
ck_assert_int_eq(tv.tv_usec, 0);
timeval_add_ms(&tv, 0);
ck_assert_int_eq(tv.tv_sec, 1);
ck_assert_int_eq(tv.tv_usec, 0);
timeval_add_ms(&tv, 1000);
ck_assert_int_eq(tv.tv_sec, 2);
ck_assert_int_eq(tv.tv_usec, 0);
timeval_add_ms(&tv, 1500);
ck_assert_int_eq(tv.tv_sec, 3);
ck_assert_int_eq(tv.tv_usec, 500000);
}
END_TEST
/*******************************************************************************
* htoun/untoh
*/
START_TEST(test_htoun)
{
chunk_t net64, expected;
u_int16_t host16 = 513;
u_int32_t net16 = 0, host32 = 67305985;
u_int64_t net32 = 0, host64 = 578437695752307201ULL;
net64 = chunk_alloca(16);
memset(net64.ptr, 0, net64.len);
expected = chunk_from_chars(0x00, 0x02, 0x01, 0x00);
htoun16((char*)&net16 + 1, host16);
ck_assert(chunk_equals(expected, chunk_from_thing(net16)));
expected = chunk_from_chars(0x00, 0x00, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00);
htoun32((u_int16_t*)&net32 + 1, host32);
ck_assert(chunk_equals(expected, chunk_from_thing(net32)));
expected = chunk_from_chars(0x00, 0x00, 0x00, 0x00,
0x08, 0x07, 0x06, 0x05,
0x04, 0x03, 0x02, 0x01,
0x00, 0x00, 0x00, 0x00);
htoun64((u_int32_t*)net64.ptr + 1, host64);
ck_assert(chunk_equals(expected, net64));
}
END_TEST
START_TEST(test_untoh)
{
chunk_t net;
u_int16_t host16;
u_int32_t host32;
u_int64_t host64;
net = chunk_from_chars(0x00, 0x02, 0x01, 0x00);
host16 = untoh16(net.ptr + 1);
ck_assert(host16 == 513);
net = chunk_from_chars(0x00, 0x00, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00);
host32 = untoh32(net.ptr + 2);
ck_assert(host32 == 67305985);
net = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05,
0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00);
host64 = untoh64(net.ptr + 4);
ck_assert(host64 == 578437695752307201ULL);
}
END_TEST
/*******************************************************************************
* pad_len/round_up/down
*/
START_TEST(test_round)
{
ck_assert_int_eq(pad_len(0, 4), 0);
ck_assert_int_eq(pad_len(1, 4), 3);
ck_assert_int_eq(pad_len(2, 4), 2);
ck_assert_int_eq(pad_len(3, 4), 1);
ck_assert_int_eq(pad_len(4, 4), 0);
ck_assert_int_eq(pad_len(5, 4), 3);
ck_assert_int_eq(round_up(0, 4), 0);
ck_assert_int_eq(round_up(1, 4), 4);
ck_assert_int_eq(round_up(2, 4), 4);
ck_assert_int_eq(round_up(3, 4), 4);
ck_assert_int_eq(round_up(4, 4), 4);
ck_assert_int_eq(round_up(5, 4), 8);
ck_assert_int_eq(round_down(0, 4), 0);
ck_assert_int_eq(round_down(1, 4), 0);
ck_assert_int_eq(round_down(2, 4), 0);
ck_assert_int_eq(round_down(3, 4), 0);
ck_assert_int_eq(round_down(4, 4), 4);
ck_assert_int_eq(round_down(5, 4), 4);
}
END_TEST
/*******************************************************************************
* strpfx
*/
static struct {
char *str;
char *pfx;
bool prefix;
bool case_prefix;
} strpfx_data[] = {
{"", "", TRUE, TRUE},
{"abc", "", TRUE, TRUE},
{"abc", "a", TRUE, TRUE},
{"abc", "ab", TRUE, TRUE},
{"abc", "abc", TRUE, TRUE},
{"abc", "abcd", FALSE, FALSE},
{"abc", "AB", FALSE, TRUE},
{"ABC", "ab", FALSE, TRUE},
{" abc", "abc", FALSE, FALSE},
};
START_TEST(test_strpfx)
{
bool prefix;
prefix = strpfx(strpfx_data[_i].str, strpfx_data[_i].pfx);
ck_assert(prefix == strpfx_data[_i].prefix);
prefix = strcasepfx(strpfx_data[_i].str, strpfx_data[_i].pfx);
ck_assert(prefix == strpfx_data[_i].case_prefix);
}
END_TEST
/*******************************************************************************
* memxor
*/
static void do_memxor(chunk_t a, chunk_t b, chunk_t exp)
{
chunk_t dst;
dst = chunk_clonea(a);
dst.len = b.len;
memxor(dst.ptr, b.ptr, b.len);
ck_assert(chunk_equals(dst, exp));
}
START_TEST(test_memxor)
{
chunk_t a, b, dst;
int i;
a = chunk_alloca(64);
memset(a.ptr, 0, a.len);
b = chunk_alloca(64);
for (i = 0; i < 64; i++)
{
b.ptr[i] = i;
b.len = i;
do_memxor(a, b, b);
}
b.len = 64;
do_memxor(a, b, b);
dst = chunk_clonea(a);
memxor(dst.ptr, b.ptr, b.len);
ck_assert(chunk_equals(dst, b));
memxor(dst.ptr, b.ptr, 0);
memxor(dst.ptr, b.ptr, 1);
memxor(dst.ptr + 1, b.ptr + 1, 1);
memxor(dst.ptr + 2, b.ptr + 2, b.len - 2);
ck_assert(chunk_equals(dst, a));
}
END_TEST
START_TEST(test_memxor_aligned)
{
u_int64_t a = 0, b = 0;
chunk_t ca, cb;
int i;
ca = chunk_from_thing(a);
cb = chunk_from_thing(b);
for (i = 0; i < 8; i++)
{
cb.ptr[i] = i + 1;
}
/* 64-bit aligned */
memxor(ca.ptr, cb.ptr, 8);
ck_assert(a == b);
/* 32-bit aligned source */
a = 0;
memxor(ca.ptr, cb.ptr + 4, 4);
ck_assert(chunk_equals(ca, chunk_from_chars(0x05, 0x06, 0x07, 0x08,
0x00, 0x00, 0x00, 0x00)));
/* 16-bit aligned source */
a = 0;
memxor(ca.ptr, cb.ptr + 2, 6);
ck_assert(chunk_equals(ca, chunk_from_chars(0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x00, 0x00)));
/* 8-bit aligned source */
a = 0;
memxor(ca.ptr, cb.ptr + 1, 7);
ck_assert(chunk_equals(ca, chunk_from_chars(0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x00)));
}
END_TEST
/*******************************************************************************
* memstr
*/
static struct {
char *haystack;
char *needle;
size_t n;
int offset;
} memstr_data[] = {
{NULL, NULL, 0, -1},
{NULL, NULL, 3, -1},
{NULL, "abc", 0, -1},
{NULL, "abc", 3, -1},
{"", "", 0, -1},
{"abc", NULL, 3, -1},
{"abc", "", 3, -1},
{"abc", "abc", 3, 0},
{" abc", "abc", 4, 1},
{" abc", "abc", 3, -1},
{"abcabc", "abc", 6, 0},
{" abc ", "abc", 5, 1},
};
START_TEST(test_memstr)
{
char *ret;
ret = memstr(memstr_data[_i].haystack, memstr_data[_i].needle, memstr_data[_i].n);
if (memstr_data[_i].offset >= 0)
{
ck_assert(ret == memstr_data[_i].haystack + memstr_data[_i].offset);
}
else
{
ck_assert(ret == NULL);
}
}
END_TEST
/*******************************************************************************
* translate
*/
static struct {
char *in;
char *from;
char *to;
char *out;
} translate_data[] = {
{NULL, "", "", NULL},
{"abc", "", "", "abc"},
{"abc", "", "x", "abc"},
{"abc", "x", "", "abc"},
{"abc", "abc", "xyz", "xyz"},
{"aabbcc", "abc", "xyz", "xxyyzz"},
{"abbaccb", "abc", "xyz", "xyyxzzy"},
{"abxyzc", "abc", "xyz", "xyxyzz"},
{"abcdef", "abc", "xyz", "xyzdef"},
{"aaa", "abc", "xyz", "xxx"},
{"abc", "aaa", "xyz", "xbc"},
{"abc", "abc", "xxx", "xxx"},
};
START_TEST(test_translate)
{
char *str, *ret;
str = strdupnull(translate_data[_i].in);
ret = translate(str, translate_data[_i].from, translate_data[_i].to);
ck_assert(ret == str);
if (ret != translate_data[_i].out)
{
ck_assert_str_eq(str, translate_data[_i].out);
}
free(str);
}
END_TEST
/*******************************************************************************
* time_printf_hook
*/
static struct {
time_t in;
bool utc;
char *out;
} time_data[] = {
{UNDEFINED_TIME, FALSE, "--- -- --:--:-- ----"},
{UNDEFINED_TIME, TRUE , "--- -- --:--:-- UTC ----"},
{1, FALSE, "Jan 01 01:00:01 1970"},
{1, TRUE , "Jan 01 00:00:01 UTC 1970"},
{1341150196, FALSE, "Jul 01 15:43:16 2012"},
{1341150196, TRUE , "Jul 01 13:43:16 UTC 2012"},
};
START_TEST(test_time_printf_hook)
{
char buf[32];
int len;
len = snprintf(buf, sizeof(buf), "%T", &time_data[_i].in, time_data[_i].utc);
ck_assert(len >= 0 && len < sizeof(buf));
ck_assert_str_eq(buf, time_data[_i].out);
}
END_TEST
/*******************************************************************************
* time_delta_printf_hook
*/
static struct {
time_t a;
time_t b;
char *out;
} time_delta_data[] = {
{0, 0, "0 seconds"},
{0, 1, "1 second"},
{0, -1, "1 second"},
{1, 0, "1 second"},
{0, 2, "2 seconds"},
{2, 0, "2 seconds"},
{0, 60, "60 seconds"},
{0, 120, "120 seconds"},
{0, 121, "2 minutes"},
{0, 3600, "60 minutes"},
{0, 7200, "120 minutes"},
{0, 7201, "2 hours"},
{0, 86400, "24 hours"},
{0, 172800, "48 hours"},
{0, 172801, "2 days"},
{172801, 86400, "24 hours"},
};
START_TEST(test_time_delta_printf_hook)
{
char buf[16];
int len;
len = snprintf(buf, sizeof(buf), "%V", &time_delta_data[_i].a, &time_delta_data[_i].b);
ck_assert(len >= 0 && len < sizeof(buf));
ck_assert_str_eq(buf, time_delta_data[_i].out);
}
END_TEST
/*******************************************************************************
* mark_from_string
*/
static struct {
char *s;
bool ok;
mark_t m;
} mark_data[] = {
{NULL, FALSE, { 0 }},
{"", TRUE, { 0, 0xffffffff }},
{"/", TRUE, { 0, 0 }},
{"42", TRUE, { 42, 0xffffffff }},
{"0x42", TRUE, { 0x42, 0xffffffff }},
{"x", FALSE, { 0 }},
{"42/", TRUE, { 0, 0 }},
{"42/0", TRUE, { 0, 0 }},
{"42/x", FALSE, { 0 }},
{"42/42", TRUE, { 42, 42 }},
{"42/0xff", TRUE, { 42, 0xff }},
{"0x42/0xff", TRUE, { 0x42, 0xff }},
{"/0xff", TRUE, { 0, 0xff }},
{"/x", FALSE, { 0 }},
{"x/x", FALSE, { 0 }},
{"0xffffffff/0x0000ffff", TRUE, { 0x0000ffff, 0x0000ffff }},
{"0xffffffff/0xffffffff", TRUE, { 0xffffffff, 0xffffffff }},
};
START_TEST(test_mark_from_string)
{
mark_t mark;
if (mark_from_string(mark_data[_i].s, &mark))
{
ck_assert_int_eq(mark.value, mark_data[_i].m.value);
ck_assert_int_eq(mark.mask, mark_data[_i].m.mask);
}
else
{
ck_assert(!mark_data[_i].ok);
}
}
END_TEST
Suite *utils_suite_create()
{
Suite *s;
TCase *tc;
/* force a timezone to match non-UTC conversions */
setenv("TZ", "Europe/Zurich", 1);
tzset();
s = suite_create("utils");
tc = tcase_create("objects");
tcase_add_test(tc, test_objects);
suite_add_tcase(s, tc);
tc = tcase_create("return functions");
tcase_add_test(tc, test_return_functions);
suite_add_tcase(s, tc);
tc = tcase_create("timeval_add_ms");
tcase_add_test(tc, test_timeval_add_ms);
suite_add_tcase(s, tc);
tc = tcase_create("htoun,untoh");
tcase_add_test(tc, test_htoun);
tcase_add_test(tc, test_untoh);
suite_add_tcase(s, tc);
tc = tcase_create("round");
tcase_add_test(tc, test_round);
suite_add_tcase(s, tc);
tc = tcase_create("string helper");
tcase_add_loop_test(tc, test_strpfx, 0, countof(strpfx_data));
suite_add_tcase(s, tc);
tc = tcase_create("memxor");
tcase_add_test(tc, test_memxor);
tcase_add_test(tc, test_memxor_aligned);
suite_add_tcase(s, tc);
tc = tcase_create("memstr");
tcase_add_loop_test(tc, test_memstr, 0, countof(memstr_data));
suite_add_tcase(s, tc);
tc = tcase_create("translate");
tcase_add_loop_test(tc, test_translate, 0, countof(translate_data));
suite_add_tcase(s, tc);
tc = tcase_create("printf_hooks");
tcase_add_loop_test(tc, test_time_printf_hook, 0, countof(time_data));
tcase_add_loop_test(tc, test_time_delta_printf_hook, 0, countof(time_delta_data));
suite_add_tcase(s, tc);
tc = tcase_create("mark_from_string");
tcase_add_loop_test(tc, test_mark_from_string, 0, countof(mark_data));
suite_add_tcase(s, tc);
return s;
}
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2013 Martin Willi
* Copyright (C) 2013 revosec AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "test_suite.h"
/*******************************************************************************
* Check if test vectors have been successful during transform registration
*/
START_TEST(test_vectors)
{
fail_if(lib->crypto->get_test_vector_failures(lib->crypto));
}
END_TEST
Suite *vectors_suite_create()
{
Suite *s;
TCase *tc;
s = suite_create("vectors");
tc = tcase_create("failures");
tcase_add_test(tc, test_vectors);
suite_add_tcase(s, tc);
return s;
}