diff options
Diffstat (limited to 'src/libstrongswan/tests/suites')
-rw-r--r-- | src/libstrongswan/tests/suites/test_certnames.c | 398 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_certpolicy.c | 637 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_chunk.c | 13 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_enum.c | 166 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_hasher.c | 3 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_host.c | 137 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_identification.c | 114 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_mgf1.c | 268 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_ntru.c | 222 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_settings.c | 4 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_threading.c | 236 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_traffic_selector.c | 284 | ||||
-rw-r--r-- | src/libstrongswan/tests/suites/test_utils.c | 45 |
13 files changed, 2291 insertions, 236 deletions
diff --git a/src/libstrongswan/tests/suites/test_certnames.c b/src/libstrongswan/tests/suites/test_certnames.c new file mode 100644 index 000000000..e30702864 --- /dev/null +++ b/src/libstrongswan/tests/suites/test_certnames.c @@ -0,0 +1,398 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 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 <asn1/asn1.h> +#include <credentials/sets/mem_cred.h> +#include <credentials/certificates/x509.h> + +/** + * RSA private key, so we don't have to generate one + */ +static char keydata[] = { + 0x30,0x82,0x02,0x5e,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xb1,0x9b,0xd4,0x51,0x24, + 0xfc,0x56,0x1d,0x3d,0xfb,0xa2,0xea,0x37,0x02,0x70,0x72,0x87,0x84,0x2f,0x3b,0x2d, + 0x6e,0x22,0xef,0x3f,0x37,0x04,0xb2,0x6f,0xb7,0xe7,0xd8,0x58,0x05,0xde,0x34,0xbf, + 0x99,0xe6,0x40,0x7a,0x56,0xa7,0x73,0xf5,0x98,0xcb,0xb0,0x37,0x90,0x5e,0xd1,0x3f, + 0xf4,0x73,0x50,0x7f,0x53,0x8e,0xf1,0x04,0x25,0xb4,0x77,0x22,0x4e,0x8a,0x9d,0x27, + 0x8f,0x6f,0xaf,0x59,0xbd,0xb0,0x0f,0xf0,0xaa,0x11,0x94,0x66,0x16,0x10,0x58,0xad, + 0x77,0xa1,0xac,0x58,0xb4,0xd0,0x0d,0xbc,0x11,0xe0,0xc0,0xe9,0x29,0xdc,0x42,0x63, + 0x01,0x23,0x4f,0x28,0x41,0x6d,0x34,0x9e,0x0c,0x4a,0xc8,0x62,0x83,0xb5,0x71,0x71, + 0x0b,0x51,0xc0,0x4c,0x37,0xd4,0x68,0x19,0x52,0x9a,0x8b,0x02,0x03,0x01,0x00,0x01, + 0x02,0x81,0x81,0x00,0x82,0xca,0x33,0x16,0xb2,0x3a,0xd4,0x1b,0x62,0x9a,0x9c,0xc5, + 0x07,0x4f,0x57,0x89,0x2f,0x7c,0x4a,0xdf,0xb4,0x3b,0xc7,0xa4,0x11,0x14,0x2d,0xf4, + 0x4c,0xca,0xcc,0x03,0x88,0x06,0x82,0x34,0xab,0xe7,0xe4,0x24,0x15,0x33,0x1c,0xcb, + 0x0a,0xcf,0xc3,0x27,0x78,0x33,0x6b,0x6f,0x82,0x3e,0x3c,0x70,0xc9,0xe2,0xb9,0x7f, + 0x88,0xc3,0x4f,0x59,0xb5,0x8e,0xa3,0x81,0xd9,0x88,0x1f,0xc0,0x38,0xbc,0xc8,0x93, + 0x40,0x0f,0x43,0xd8,0x72,0x12,0xb4,0xcc,0x6d,0x76,0x0a,0x6f,0x01,0x05,0xa8,0x88, + 0xf4,0x57,0x44,0xd2,0x05,0xc4,0x77,0xf5,0xfb,0x1b,0xf3,0xb2,0x0d,0x90,0xb8,0xb4, + 0x63,0x62,0x70,0x2c,0xe4,0x28,0xd8,0x20,0x10,0x85,0x4a,0x5e,0x63,0xa9,0xb0,0xdd, + 0xba,0xd0,0x32,0x49,0x02,0x41,0x00,0xdb,0x77,0xf1,0xdd,0x1a,0x12,0xc5,0xfb,0x2b, + 0x5b,0xb2,0xcd,0xb6,0xd0,0x4c,0xc4,0xe5,0x93,0xd6,0xf8,0x88,0xfc,0x18,0x40,0x21, + 0x9c,0xf7,0x2d,0x60,0x6f,0x91,0xf5,0x73,0x3c,0xf7,0x7f,0x67,0x1d,0x5b,0xb5,0xee, + 0x29,0xc1,0xd4,0xc6,0xdb,0x44,0x4c,0x40,0x05,0x63,0xaa,0x71,0x95,0x18,0x14,0xa7, + 0x23,0x9f,0x7a,0xee,0x7f,0xb5,0xc7,0x02,0x41,0x00,0xcf,0x2c,0x24,0x50,0x65,0xf4, + 0x94,0x7b,0xe9,0xf3,0x13,0x77,0xea,0x27,0x3c,0x6f,0x03,0x84,0xa7,0x7d,0xa2,0x54, + 0x40,0x97,0x82,0x0e,0xd9,0x09,0x9f,0x4a,0xa6,0x75,0xe5,0x66,0xe4,0x9c,0x59,0xd9, + 0x3a,0xe6,0xf7,0xd8,0x8b,0x68,0xb0,0x21,0x52,0x31,0xb3,0x4a,0xa0,0x2c,0x41,0xd7, + 0x1f,0x7b,0xe2,0x0f,0x15,0xc9,0x6e,0xc0,0xe5,0x1d,0x02,0x41,0x00,0x9c,0x1a,0x61, + 0x9f,0x89,0xc7,0x26,0xa9,0x33,0xba,0xe2,0xa0,0x6d,0xd3,0x15,0x77,0xcb,0x6f,0xef, + 0xad,0x12,0x0a,0x75,0xd9,0x4f,0xcf,0x4d,0x05,0x2a,0x9d,0xd1,0x2c,0xcb,0xcd,0xe6, + 0xa0,0xe9,0x20,0x39,0xb6,0x5a,0xf3,0xba,0x99,0xf4,0xe3,0xcb,0x5d,0x8d,0x00,0x08, + 0x57,0x18,0xb9,0x1a,0xca,0xbd,0xe3,0x99,0xb1,0x1f,0xe9,0x18,0xcb,0x02,0x40,0x65, + 0x35,0x1b,0x48,0x6b,0x86,0x60,0x43,0x68,0xb6,0xe6,0xfb,0xdd,0xd7,0xed,0x1e,0x0e, + 0x89,0xef,0x88,0xe0,0x94,0x68,0x39,0x9b,0xbf,0xc5,0x27,0x7e,0x39,0xe9,0xb8,0x0e, + 0xa9,0x85,0x65,0x1c,0x3f,0x93,0x16,0xe2,0x5d,0x57,0x3d,0x7d,0x4d,0xc9,0xe9,0x9d, + 0xbd,0x07,0x22,0x97,0xc7,0x90,0x09,0xe5,0x15,0x99,0x7f,0x1e,0x2b,0xfd,0xc1,0x02, + 0x41,0x00,0x92,0x78,0xfe,0x04,0xa0,0x53,0xed,0x36,0x97,0xbd,0x16,0xce,0x91,0x9b, + 0xbe,0x1f,0x8e,0x40,0x00,0x99,0x0c,0x49,0x15,0xca,0x59,0xd3,0xe3,0xd4,0xeb,0x71, + 0xcf,0xda,0xd7,0xc8,0x99,0x74,0xfc,0x6b,0xe8,0xfd,0xe5,0xe0,0x49,0x61,0xcb,0xda, + 0xe3,0xe7,0x8b,0x72,0xb5,0x69,0x73,0x2b,0x8b,0x54,0xcb,0xd9,0x48,0x6d,0x61,0x02, + 0x49,0xe8, +}; + +/** + * Issue a certificate with permitted/excluded name constraints + */ +static certificate_t* create_cert(certificate_t *ca, char *subject, char *san, + x509_flag_t flags, identification_t *permitted, + identification_t *excluded) +{ + private_key_t *privkey; + public_key_t *pubkey; + certificate_t *cert; + identification_t *id; + linked_list_t *plist, *elist, *sans; + + privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, + BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata), + BUILD_END); + ck_assert(privkey); + pubkey = privkey->get_public_key(privkey); + ck_assert(pubkey); + plist = linked_list_create(); + if (permitted) + { + plist->insert_last(plist, permitted); + } + elist = linked_list_create(); + if (excluded) + { + elist->insert_last(elist, excluded); + } + sans = linked_list_create(); + if (san) + { + id = identification_create_from_string(san); + sans->insert_last(sans, id); + } + id = identification_create_from_string(subject); + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_SIGNING_KEY, privkey, + BUILD_PUBLIC_KEY, pubkey, + BUILD_SUBJECT, id, + BUILD_X509_FLAG, flags, + BUILD_SIGNING_CERT, ca, + BUILD_SUBJECT_ALTNAMES, sans, + BUILD_PERMITTED_NAME_CONSTRAINTS, plist, + BUILD_EXCLUDED_NAME_CONSTRAINTS, elist, + BUILD_END); + ck_assert(cert); + id->destroy(id); + sans->destroy_offset(sans, offsetof(identification_t, destroy)); + plist->destroy_offset(plist, offsetof(identification_t, destroy)); + elist->destroy_offset(elist, offsetof(identification_t, destroy)); + privkey->destroy(privkey); + pubkey->destroy(pubkey); + + return cert; +} + +/** + * Check if a certificate with given subject has a valid trustchain + */ +static bool check_trust(identification_t *subject) +{ + enumerator_t *certs; + certificate_t *cert; + bool trusted; + + certs = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY, + subject, FALSE); + trusted = certs->enumerate(certs, &cert, NULL); + certs->destroy(certs); + + return trusted; +} + +static mem_cred_t *creds; + +START_SETUP(setup) +{ + creds = mem_cred_create(); + lib->credmgr->add_set(lib->credmgr, &creds->set); +} +END_SETUP + +START_TEARDOWN(teardown) +{ + lib->credmgr->remove_set(lib->credmgr, &creds->set); + creds->destroy(creds); + lib->credmgr->flush_cache(lib->credmgr, CERT_ANY); +} +END_TEARDOWN + +static struct { + char *constraint; + char *subject; + bool good; +} permitted_dn[] = { + { "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", TRUE }, + { "C=CH, O=strongSwan", "C=CH, O=strong", FALSE }, + { "C=CH, O=strongSwan", "C=CH, O=strong, CN=tester", FALSE }, + { "C=CH, O=strongSwan", "C=CH, O=another, CN=tester", FALSE }, + { "C=CH, O=strongSwan", "C=CH, CN=tester, O=strongSwan", FALSE }, +}; + +START_TEST(test_permitted_dn) +{ + certificate_t *ca, *im, *sj; + identification_t *id; + + id = identification_create_from_string(permitted_dn[_i].constraint); + ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, id, NULL); + id = identification_create_from_string(permitted_dn[_i].constraint); + im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, id, NULL); + sj = create_cert(im, permitted_dn[_i].subject, NULL, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_trust(sj->get_subject(sj)) == permitted_dn[_i].good); +} +END_TEST + +static struct { + id_type_t ctype; + char *cdata; + char *subject; + bool good; +} permitted_san[] = { + { ID_FQDN, ".strongswan.org", "test.strongswan.org", TRUE }, + { ID_FQDN, "strongswan.org", "test.strongswan.org", TRUE }, + { ID_FQDN, "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", TRUE }, + { ID_FQDN, "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", FALSE }, + { ID_FQDN, "strongswan.org", "strongswan.org.com", FALSE }, + { ID_FQDN, ".strongswan.org", "strongswan.org", FALSE }, + { ID_FQDN, "strongswan.org", "nostrongswan.org", FALSE }, + { ID_FQDN, "strongswan.org", "swan.org", FALSE }, + { ID_FQDN, "strongswan.org", "swan.org", FALSE }, + { ID_RFC822_ADDR, "tester@strongswan.org", "tester@strongswan.org", TRUE }, + { ID_RFC822_ADDR, "tester@strongswan.org", "atester@strongswan.org", FALSE }, + { ID_RFC822_ADDR, "strongswan.org", "tester@strongswan.org", TRUE }, + { ID_RFC822_ADDR, "strongswan.org", "tester@test.strongswan.org", FALSE }, + { ID_RFC822_ADDR, ".strongswan.org", "tester@test.strongswan.org", TRUE }, + { ID_RFC822_ADDR, ".strongswan.org", "tester@strongswan.org", FALSE }, +}; + +START_TEST(test_permitted_san) +{ + certificate_t *ca, *sj; + identification_t *id; + + id = identification_create_from_encoding(permitted_san[_i].ctype, + chunk_from_str(permitted_san[_i].cdata)); + ca = create_cert(NULL, "CN=CA", NULL, X509_CA, id, NULL); + sj = create_cert(ca, "CN=SJ", permitted_san[_i].subject, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_trust(sj->get_subject(sj)) == permitted_san[_i].good); +} +END_TEST + +static struct { + char *constraint; + char *subject; + bool good; +} excluded_dn[] = { + { "C=CH, O=another", "C=CH, O=strongSwan, CN=tester", TRUE }, + { "C=CH, O=another", "C=CH, O=anot", TRUE }, + { "C=CH, O=another", "C=CH, O=anot, CN=tester", TRUE }, + { "C=CH, O=another", "C=CH, O=another, CN=tester", FALSE }, + { "C=CH, O=another", "C=CH, CN=tester, O=another", TRUE }, +}; + +START_TEST(test_excluded_dn) +{ + certificate_t *ca, *im, *sj; + identification_t *id; + + id = identification_create_from_string(excluded_dn[_i].constraint); + ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, NULL, id); + id = identification_create_from_string(excluded_dn[_i].constraint); + im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, NULL, id); + sj = create_cert(im, excluded_dn[_i].subject, NULL, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_trust(sj->get_subject(sj)) == excluded_dn[_i].good); +} +END_TEST + +static struct { + id_type_t ctype; + char *cdata; + char *subject; + bool good; +} excluded_san[] = { + { ID_FQDN, ".strongswan.org", "test.strongswan.org", FALSE }, + { ID_FQDN, "strongswan.org", "test.strongswan.org", FALSE }, + { ID_FQDN, "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", FALSE }, + { ID_FQDN, "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", TRUE }, + { ID_FQDN, "strongswan.org", "strongswan.org.com", TRUE }, + { ID_FQDN, ".strongswan.org", "strongswan.org", TRUE }, + { ID_FQDN, "strongswan.org", "nostrongswan.org", TRUE }, + { ID_FQDN, "strongswan.org", "swan.org", TRUE }, + { ID_FQDN, "strongswan.org", "swan.org", TRUE }, + { ID_RFC822_ADDR, "tester@strongswan.org", "tester@strongswan.org", FALSE }, + { ID_RFC822_ADDR, "tester@strongswan.org", "atester@strongswan.org", TRUE }, + { ID_RFC822_ADDR, "strongswan.org", "tester@strongswan.org", FALSE }, + { ID_RFC822_ADDR, "strongswan.org", "tester@test.strongswan.org", TRUE }, + { ID_RFC822_ADDR, ".strongswan.org", "tester@test.strongswan.org", FALSE }, + { ID_RFC822_ADDR, ".strongswan.org", "tester@strongswan.org", TRUE }, +}; + +START_TEST(test_excluded_san) +{ + certificate_t *ca, *sj; + identification_t *id; + + id = identification_create_from_encoding(excluded_san[_i].ctype, + chunk_from_str(excluded_san[_i].cdata)); + ca = create_cert(NULL, "CN=CA", NULL, X509_CA, NULL, id); + sj = create_cert(ca, "CN=SJ", excluded_san[_i].subject, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_trust(sj->get_subject(sj)) == excluded_san[_i].good); +} +END_TEST + +static struct { + char *caconst; + char *imconst; + char *subject; + bool good; +} permitted_dninh[] = { + { "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", TRUE }, + { "C=CH", "C=DE, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE }, + { "C=CH, O=strongSwan", "C=CH", "C=CH", FALSE }, +}; + +START_TEST(test_permitted_dninh) +{ + certificate_t *ca, *im, *sj; + identification_t *id; + + id = identification_create_from_string(permitted_dninh[_i].caconst); + ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, id, NULL); + id = identification_create_from_string(permitted_dninh[_i].imconst); + im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, id, NULL); + sj = create_cert(im, permitted_dninh[_i].subject, NULL, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_trust(sj->get_subject(sj)) == permitted_dninh[_i].good); +} +END_TEST + +static struct { + char *caconst; + char *imconst; + char *subject; + bool good; +} excluded_dninh[] = { + { "C=CH, O=strongSwan", "C=CH", "C=DE", TRUE }, + { "C=CH, O=strongSwan", "C=DE", "C=CH", FALSE }, + { "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE }, +}; + +START_TEST(test_excluded_dninh) +{ + certificate_t *ca, *im, *sj; + identification_t *id; + + id = identification_create_from_string(excluded_dninh[_i].caconst); + ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, NULL, id); + id = identification_create_from_string(excluded_dninh[_i].imconst); + im = create_cert(ca, "C=DE, CN=IM", NULL, X509_CA, NULL, id); + sj = create_cert(im, excluded_dninh[_i].subject, NULL, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_trust(sj->get_subject(sj)) == excluded_dninh[_i].good); +} +END_TEST + +Suite *certnames_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("certnames"); + + tc = tcase_create("permitted DN name constraints"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_loop_test(tc, test_permitted_dn, 0, countof(permitted_dn)); + suite_add_tcase(s, tc); + + tc = tcase_create("permitted subjectAltName constraints"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_loop_test(tc, test_permitted_san, 0, countof(permitted_san)); + suite_add_tcase(s, tc); + + tc = tcase_create("excluded DN constraints"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_loop_test(tc, test_excluded_dn, 0, countof(excluded_dn)); + suite_add_tcase(s, tc); + + tc = tcase_create("excluded subjectAltName constraints"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_loop_test(tc, test_excluded_san, 0, countof(excluded_san)); + suite_add_tcase(s, tc); + + tc = tcase_create("permitted DN name constraint inherit"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_loop_test(tc, test_permitted_dninh, 0, countof(permitted_dninh)); + suite_add_tcase(s, tc); + + tc = tcase_create("excluded DN name constraint inherit"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_loop_test(tc, test_excluded_dninh, 0, countof(excluded_dninh)); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/tests/suites/test_certpolicy.c b/src/libstrongswan/tests/suites/test_certpolicy.c new file mode 100644 index 000000000..7501e1a8b --- /dev/null +++ b/src/libstrongswan/tests/suites/test_certpolicy.c @@ -0,0 +1,637 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 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 <asn1/asn1.h> +#include <credentials/sets/mem_cred.h> +#include <credentials/certificates/x509.h> + +/** + * RSA private key, so we don't have to generate one + */ +static char keydata[] = { + 0x30,0x82,0x02,0x5e,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xb1,0x9b,0xd4,0x51,0x24, + 0xfc,0x56,0x1d,0x3d,0xfb,0xa2,0xea,0x37,0x02,0x70,0x72,0x87,0x84,0x2f,0x3b,0x2d, + 0x6e,0x22,0xef,0x3f,0x37,0x04,0xb2,0x6f,0xb7,0xe7,0xd8,0x58,0x05,0xde,0x34,0xbf, + 0x99,0xe6,0x40,0x7a,0x56,0xa7,0x73,0xf5,0x98,0xcb,0xb0,0x37,0x90,0x5e,0xd1,0x3f, + 0xf4,0x73,0x50,0x7f,0x53,0x8e,0xf1,0x04,0x25,0xb4,0x77,0x22,0x4e,0x8a,0x9d,0x27, + 0x8f,0x6f,0xaf,0x59,0xbd,0xb0,0x0f,0xf0,0xaa,0x11,0x94,0x66,0x16,0x10,0x58,0xad, + 0x77,0xa1,0xac,0x58,0xb4,0xd0,0x0d,0xbc,0x11,0xe0,0xc0,0xe9,0x29,0xdc,0x42,0x63, + 0x01,0x23,0x4f,0x28,0x41,0x6d,0x34,0x9e,0x0c,0x4a,0xc8,0x62,0x83,0xb5,0x71,0x71, + 0x0b,0x51,0xc0,0x4c,0x37,0xd4,0x68,0x19,0x52,0x9a,0x8b,0x02,0x03,0x01,0x00,0x01, + 0x02,0x81,0x81,0x00,0x82,0xca,0x33,0x16,0xb2,0x3a,0xd4,0x1b,0x62,0x9a,0x9c,0xc5, + 0x07,0x4f,0x57,0x89,0x2f,0x7c,0x4a,0xdf,0xb4,0x3b,0xc7,0xa4,0x11,0x14,0x2d,0xf4, + 0x4c,0xca,0xcc,0x03,0x88,0x06,0x82,0x34,0xab,0xe7,0xe4,0x24,0x15,0x33,0x1c,0xcb, + 0x0a,0xcf,0xc3,0x27,0x78,0x33,0x6b,0x6f,0x82,0x3e,0x3c,0x70,0xc9,0xe2,0xb9,0x7f, + 0x88,0xc3,0x4f,0x59,0xb5,0x8e,0xa3,0x81,0xd9,0x88,0x1f,0xc0,0x38,0xbc,0xc8,0x93, + 0x40,0x0f,0x43,0xd8,0x72,0x12,0xb4,0xcc,0x6d,0x76,0x0a,0x6f,0x01,0x05,0xa8,0x88, + 0xf4,0x57,0x44,0xd2,0x05,0xc4,0x77,0xf5,0xfb,0x1b,0xf3,0xb2,0x0d,0x90,0xb8,0xb4, + 0x63,0x62,0x70,0x2c,0xe4,0x28,0xd8,0x20,0x10,0x85,0x4a,0x5e,0x63,0xa9,0xb0,0xdd, + 0xba,0xd0,0x32,0x49,0x02,0x41,0x00,0xdb,0x77,0xf1,0xdd,0x1a,0x12,0xc5,0xfb,0x2b, + 0x5b,0xb2,0xcd,0xb6,0xd0,0x4c,0xc4,0xe5,0x93,0xd6,0xf8,0x88,0xfc,0x18,0x40,0x21, + 0x9c,0xf7,0x2d,0x60,0x6f,0x91,0xf5,0x73,0x3c,0xf7,0x7f,0x67,0x1d,0x5b,0xb5,0xee, + 0x29,0xc1,0xd4,0xc6,0xdb,0x44,0x4c,0x40,0x05,0x63,0xaa,0x71,0x95,0x18,0x14,0xa7, + 0x23,0x9f,0x7a,0xee,0x7f,0xb5,0xc7,0x02,0x41,0x00,0xcf,0x2c,0x24,0x50,0x65,0xf4, + 0x94,0x7b,0xe9,0xf3,0x13,0x77,0xea,0x27,0x3c,0x6f,0x03,0x84,0xa7,0x7d,0xa2,0x54, + 0x40,0x97,0x82,0x0e,0xd9,0x09,0x9f,0x4a,0xa6,0x75,0xe5,0x66,0xe4,0x9c,0x59,0xd9, + 0x3a,0xe6,0xf7,0xd8,0x8b,0x68,0xb0,0x21,0x52,0x31,0xb3,0x4a,0xa0,0x2c,0x41,0xd7, + 0x1f,0x7b,0xe2,0x0f,0x15,0xc9,0x6e,0xc0,0xe5,0x1d,0x02,0x41,0x00,0x9c,0x1a,0x61, + 0x9f,0x89,0xc7,0x26,0xa9,0x33,0xba,0xe2,0xa0,0x6d,0xd3,0x15,0x77,0xcb,0x6f,0xef, + 0xad,0x12,0x0a,0x75,0xd9,0x4f,0xcf,0x4d,0x05,0x2a,0x9d,0xd1,0x2c,0xcb,0xcd,0xe6, + 0xa0,0xe9,0x20,0x39,0xb6,0x5a,0xf3,0xba,0x99,0xf4,0xe3,0xcb,0x5d,0x8d,0x00,0x08, + 0x57,0x18,0xb9,0x1a,0xca,0xbd,0xe3,0x99,0xb1,0x1f,0xe9,0x18,0xcb,0x02,0x40,0x65, + 0x35,0x1b,0x48,0x6b,0x86,0x60,0x43,0x68,0xb6,0xe6,0xfb,0xdd,0xd7,0xed,0x1e,0x0e, + 0x89,0xef,0x88,0xe0,0x94,0x68,0x39,0x9b,0xbf,0xc5,0x27,0x7e,0x39,0xe9,0xb8,0x0e, + 0xa9,0x85,0x65,0x1c,0x3f,0x93,0x16,0xe2,0x5d,0x57,0x3d,0x7d,0x4d,0xc9,0xe9,0x9d, + 0xbd,0x07,0x22,0x97,0xc7,0x90,0x09,0xe5,0x15,0x99,0x7f,0x1e,0x2b,0xfd,0xc1,0x02, + 0x41,0x00,0x92,0x78,0xfe,0x04,0xa0,0x53,0xed,0x36,0x97,0xbd,0x16,0xce,0x91,0x9b, + 0xbe,0x1f,0x8e,0x40,0x00,0x99,0x0c,0x49,0x15,0xca,0x59,0xd3,0xe3,0xd4,0xeb,0x71, + 0xcf,0xda,0xd7,0xc8,0x99,0x74,0xfc,0x6b,0xe8,0xfd,0xe5,0xe0,0x49,0x61,0xcb,0xda, + 0xe3,0xe7,0x8b,0x72,0xb5,0x69,0x73,0x2b,0x8b,0x54,0xcb,0xd9,0x48,0x6d,0x61,0x02, + 0x49,0xe8, +}; + +/** + * Issue a certificate fr given policy, including extended flags + */ +static certificate_t* create_cert_ext(certificate_t *ca, char *subject, + char *oid, x509_flag_t flags, + char *map_s, char *map_i, + u_int require_explicit, + u_int inhibit_mapping, + u_int inhibit_any) +{ + private_key_t *privkey; + public_key_t *pubkey; + certificate_t *cert; + identification_t *id; + linked_list_t *policies, *maps; + x509_cert_policy_t policy = {}; + x509_policy_mapping_t map = {}; + + privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, + BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata), + BUILD_END); + ck_assert(privkey); + pubkey = privkey->get_public_key(privkey); + ck_assert(pubkey); + policies = linked_list_create(); + if (oid) + { + policy.oid = asn1_oid_from_string(oid); + ck_assert(policy.oid.ptr); + policies->insert_last(policies, &policy); + } + maps = linked_list_create(); + if (map_s && map_i) + { + map.subject = asn1_oid_from_string(map_s); + ck_assert(map.subject.ptr); + map.issuer = asn1_oid_from_string(map_i); + ck_assert(map.issuer.ptr); + maps->insert_last(maps, &map); + } + id = identification_create_from_string(subject); + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_SIGNING_KEY, privkey, + BUILD_PUBLIC_KEY, pubkey, + BUILD_SUBJECT, id, + BUILD_X509_FLAG, flags, + BUILD_CERTIFICATE_POLICIES, policies, + BUILD_POLICY_MAPPINGS, maps, + BUILD_SIGNING_CERT, ca, + BUILD_POLICY_REQUIRE_EXPLICIT, require_explicit, + BUILD_POLICY_INHIBIT_MAPPING, inhibit_mapping, + BUILD_POLICY_INHIBIT_ANY, inhibit_any, + BUILD_END); + ck_assert(cert); + id->destroy(id); + policies->destroy(policies); + maps->destroy(maps); + privkey->destroy(privkey); + pubkey->destroy(pubkey); + free(policy.oid.ptr); + free(map.subject.ptr); + free(map.issuer.ptr); + + return cert; +} + +/** + * Issue a certificate with given certificate policy and flags + */ +static certificate_t* create_cert(certificate_t *ca, char *subject, + char *oid, x509_flag_t flags, + char *map_s, char *map_i) +{ + return create_cert_ext(ca, subject, oid, flags, map_s, map_i, + X509_NO_CONSTRAINT, X509_NO_CONSTRAINT, + X509_NO_CONSTRAINT); +} + +/** + * Check if a certificate with given subject has an oid + */ +static bool check_oid(identification_t *subject, char *oid) +{ + enumerator_t *certs, *auths; + certificate_t *cert; + auth_cfg_t *auth; + bool found = FALSE; + auth_rule_t type; + char *current; + + certs = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY, + subject, FALSE); + if (!certs->enumerate(certs, &cert, &auth)) + { + certs->destroy(certs); + ck_assert_msg(FALSE, "no trusted certificate found for %Y", subject); + } + auths = auth->create_enumerator(auth); + while (auths->enumerate(auths, &type, ¤t)) + { + if (type == AUTH_RULE_CERT_POLICY) + { + if (streq(current, oid)) + { + found = TRUE; + break; + } + } + } + auths->destroy(auths); + certs->destroy(certs); + + return found; +} + +/** + * Check if a certificate with given subject has a valid trustchain + */ +static bool check_trust(identification_t *subject) +{ + enumerator_t *certs; + certificate_t *cert; + bool trusted; + + certs = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY, + subject, FALSE); + trusted = certs->enumerate(certs, &cert, NULL); + certs->destroy(certs); + + return trusted; +} + +static mem_cred_t *creds; + +static char *anyPolicy = "2.5.29.32.0"; +static char *extended = "2.23.140.1.1"; +static char *baseline = "2.23.140.1.2"; + +START_SETUP(setup) +{ + creds = mem_cred_create(); + lib->credmgr->add_set(lib->credmgr, &creds->set); +} +END_SETUP + +START_TEARDOWN(teardown) +{ + lib->credmgr->remove_set(lib->credmgr, &creds->set); + creds->destroy(creds); + lib->credmgr->flush_cache(lib->credmgr, CERT_ANY); +} +END_TEARDOWN + +START_TEST(test_valid_fixed) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_valid_any1) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_valid_any2) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_invalid_missing) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", NULL, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_invalid_wrong) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), extended)); +} +END_TEST + +START_TEST(test_invalid_any1) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", NULL, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_invalid_any2) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", anyPolicy, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_badchain_wrong) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", extended, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", extended, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); + ck_assert(!check_oid(sj->get_subject(sj), extended)); +} +END_TEST + +START_TEST(test_badchain_gap) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", NULL, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_badchain_any) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", extended, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), extended)); +} +END_TEST + +START_TEST(test_valid_mapping) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_valid_mapping_twice) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", "2.23.140.1.3", X509_CA, + extended, "2.23.140.1.3"); + im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_invalid_mapping_loop) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, baseline); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_invalid_mapping_notallowed) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_invalid_mapping_nopolicy) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", "2.23.140.1.3", X509_CA, baseline, extended); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_inhibit_mapping_good) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert_ext(NULL, "CN=CA", extended, X509_CA, NULL, NULL, + X509_NO_CONSTRAINT, 1, X509_NO_CONSTRAINT); + im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_inhibit_mapping_bad) +{ + certificate_t *ca, *i1, *i2, *sj; + + ca = create_cert_ext(NULL, "CN=CA", extended, X509_CA, NULL, NULL, + X509_NO_CONSTRAINT, 1, X509_NO_CONSTRAINT); + i1 = create_cert(ca, "CN=IM1", extended, X509_CA, NULL, NULL); + i2 = create_cert(i1, "CN=IM2", extended, X509_CA, baseline, extended); + sj = create_cert(i2, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, i1); + creds->add_cert(creds, FALSE, i2); + creds->add_cert(creds, FALSE, sj); + + /* TODO: we currently reject the certificate completely, but should + * actually just invalidate the policy not mapped properly */ + ck_assert(!check_trust(sj->get_subject(sj))); +} +END_TEST + +START_TEST(test_inhibit_any_good) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL, + X509_NO_CONSTRAINT, X509_NO_CONSTRAINT, 1); + im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_inhibit_any_bad) +{ + certificate_t *ca, *i1, *i2, *sj; + + ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL, + X509_NO_CONSTRAINT, X509_NO_CONSTRAINT, 1); + i1 = create_cert(ca, "CN=IM1", anyPolicy, X509_CA, NULL, NULL); + i2 = create_cert(i1, "CN=IM2", anyPolicy, X509_CA, NULL, NULL); + sj = create_cert(i2, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, i1); + creds->add_cert(creds, FALSE, i2); + creds->add_cert(creds, FALSE, sj); + + /* TODO: we currently reject the certificate completely, but should + * actually just invalidate the policy relying on inhibited anyPolicy */ + ck_assert(!check_trust(sj->get_subject(sj))); +} +END_TEST + +START_TEST(test_require_explicit_good) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL, + 1, X509_NO_CONSTRAINT, X509_NO_CONSTRAINT); + im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_require_explicit_bad) +{ + certificate_t *ca, *i1, *i2, *sj; + + ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL, + 1, X509_NO_CONSTRAINT, X509_NO_CONSTRAINT); + i1 = create_cert(ca, "CN=IM1", extended, X509_CA, NULL, NULL); + i2 = create_cert(i1, "CN=IM2", extended, X509_CA, NULL, NULL); + sj = create_cert(i2, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, i1); + creds->add_cert(creds, FALSE, i2); + creds->add_cert(creds, FALSE, sj); + + /* TODO: we currently reject the certificate completely, but should + * actually just invalidate the policy violating requireExplicit */ + ck_assert(!check_trust(sj->get_subject(sj))); +} +END_TEST + +Suite *certpolicy_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("certpolicy"); + + tc = tcase_create("policy valid"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_valid_fixed); + tcase_add_test(tc, test_valid_any1); + tcase_add_test(tc, test_valid_any2); + suite_add_tcase(s, tc); + + tc = tcase_create("policy invalid"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_invalid_missing); + tcase_add_test(tc, test_invalid_wrong); + tcase_add_test(tc, test_invalid_any1); + tcase_add_test(tc, test_invalid_any2); + suite_add_tcase(s, tc); + + tc = tcase_create("policy badchain"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_badchain_wrong); + tcase_add_test(tc, test_badchain_gap); + tcase_add_test(tc, test_badchain_any); + suite_add_tcase(s, tc); + + tc = tcase_create("policy valid mapping"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_valid_mapping); + tcase_add_test(tc, test_valid_mapping_twice); + suite_add_tcase(s, tc); + + tc = tcase_create("policy invalid mapping"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_invalid_mapping_loop); + tcase_add_test(tc, test_invalid_mapping_notallowed); + tcase_add_test(tc, test_invalid_mapping_nopolicy); + suite_add_tcase(s, tc); + + tc = tcase_create("inhibit policy mapping"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_inhibit_mapping_good); + tcase_add_test(tc, test_inhibit_mapping_bad); + suite_add_tcase(s, tc); + + tc = tcase_create("inhibit any policy"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_inhibit_any_good); + tcase_add_test(tc, test_inhibit_any_bad); + suite_add_tcase(s, tc); + + tc = tcase_create("require explicit policy"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_require_explicit_good); + tcase_add_test(tc, test_require_explicit_bad); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/tests/suites/test_chunk.c b/src/libstrongswan/tests/suites/test_chunk.c index d71e010a2..b5d23658d 100644 --- a/src/libstrongswan/tests/suites/test_chunk.c +++ b/src/libstrongswan/tests/suites/test_chunk.c @@ -787,6 +787,11 @@ END_TEST * test for chunk_internet_checksum[_inc]() */ +static inline u_int16_t compensate_alignment(u_int16_t val) +{ + return ((val & 0xff) << 8) | (val >> 8); +} + START_TEST(test_chunk_internet_checksum) { chunk_t chunk; @@ -804,9 +809,9 @@ START_TEST(test_chunk_internet_checksum) /* need to compensate for even/odd alignment */ sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9)); - sum = ntohs(sum); + sum = compensate_alignment(sum); sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 11), sum); - sum = ntohs(sum); + sum = compensate_alignment(sum); ck_assert_int_eq(0x442e, ntohs(sum)); chunk = chunk_from_chars(0x45,0x00,0x00,0x30,0x44,0x22,0x40,0x00,0x80,0x06, @@ -821,9 +826,9 @@ START_TEST(test_chunk_internet_checksum) /* need to compensate for even/odd alignment */ sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9)); - sum = ntohs(sum); + sum = compensate_alignment(sum); sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 10), sum); - sum = ntohs(sum); + sum = compensate_alignment(sum); ck_assert_int_eq(0x4459, ntohs(sum)); } END_TEST diff --git a/src/libstrongswan/tests/suites/test_enum.c b/src/libstrongswan/tests/suites/test_enum.c index b48b51c0e..53ebd2931 100644 --- a/src/libstrongswan/tests/suites/test_enum.c +++ b/src/libstrongswan/tests/suites/test_enum.c @@ -58,6 +58,39 @@ ENUM_NEXT(test_enum_split_names, SPLIT5, SPLIT5, SPLIT4, ENUM_END(test_enum_split_names, SPLIT5); /******************************************************************************* + * enum flags + */ +enum { + FLAG1 = (1 << 0), + FLAG2 = (1 << 1), + FLAG3 = (1 << 2), + FLAG4 = (1 << 3), + FLAG5 = (1 << 4), + FLAG6 = (1 << 5), + FLAG7 = (1 << 6), + FLAG8 = (1 << 7), + FLAG9 = (1 << 8), + FLAG10 = (1 << 9), + FLAG11 = (1 << 10), + FLAG12 = (1 << 11), +} test_enum_flags; + +ENUM_FLAGS(test_enum_flags_names, FLAG1, FLAG5, + "FLAG1", "FLAG2", "FLAG3", "FLAG4", "FLAG5"); + +ENUM_FLAGS(test_enum_flags_incomplete_names, FLAG3, FLAG4, + "FLAG3", "FLAG4"); + +ENUM_FLAGS(test_enum_flags_null_names, FLAG1, FLAG4, + "FLAG1", NULL, "FLAG3", NULL); + +ENUM_FLAGS(test_enum_flags_overflow_names, FLAG1, FLAG12, + "OVERFLOWFLAGLONGNAME1", "OVERFLOWFLAGLONGNAME2", "OVERFLOWFLAGLONGNAME3", + "OVERFLOWFLAGLONGNAME4", "OVERFLOWFLAGLONGNAME5", "OVERFLOWFLAGLONGNAME6", + "OVERFLOWFLAGLONGNAME7", "OVERFLOWFLAGLONGNAME8", "OVERFLOWFLAGLONGNAME9", + "OVERFLOWFLAGLONGNAME10", "OVERFLOWFLAGLONGNAME11", "OVERFLOWFLAGLONGNAME12"); + +/******************************************************************************* * enum_to_name */ @@ -198,11 +231,52 @@ static struct { {256, "(256)"}, }; +/******************************************************************************* + * flag_to_name + */ + +static struct { + int val; + char *str; +} printf_tests_flags[] = { + {0, "(unset)"}, + {FLAG1, "FLAG1"}, + {FLAG2, "FLAG2"}, + {FLAG3, "FLAG3"}, + {FLAG4, "FLAG4"}, + {FLAG5, "FLAG5"}, + {FLAG1 | FLAG3, "FLAG1 | FLAG3"}, + {FLAG1 | FLAG3 | 32, "FLAG1 | FLAG3 | (0x20)"}, + {FLAG1 | FLAG3 | 32 | 64, "FLAG1 | FLAG3 | (0x20) | (0x40)"}, + {0x20, "(0x20)"}, + {0x80000000, "(0x80000000)"}, + {0xFFFFF, "FLAG1 | FLAG2 | FLAG3 | FLAG4 | " + "FLAG5 | (0x20) | (0x40) | (0x80) | " + "(0x100) | (0x200) | (0x400) | (0x800) | " + "(0x1000) | (0x2000) | (0x4000) | (0x8000) | " + "(0x10000) | (0x20000) | (0x40000) | (0x80000)"}, +}, printf_tests_flags_incomplete[] = { + {FLAG1, "(0x1)"}, + {FLAG1 | FLAG2 | FLAG3, "(0x1) | (0x2) | FLAG3"}, + {FLAG3 | FLAG4 | FLAG5, "FLAG3 | FLAG4 | (0x10)"}, +}, printf_tests_flags_null[] = { + {FLAG1 | FLAG2 | FLAG3 | FLAG4, "FLAG1 | FLAG3"}, +}, printf_tests_flags_overflow[] = { + {0xFFFFFFFF, "(0xFFFFFFFF)"}, +}, printf_tests_flags_noflagenum[] = { + {-1, "(-1)"}, + {6435, "(6435)"}, +}, enum_flags_to_string_tests[] = { + {-1, NULL}, + {6435, NULL}, +}; + START_TEST(test_enum_printf_hook_cont) { char buf[128]; - snprintf(buf, sizeof(buf), "%N", test_enum_cont_names, printf_tests_cont[_i].val); + 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 @@ -211,11 +285,89 @@ START_TEST(test_enum_printf_hook_split) { char buf[128]; - snprintf(buf, sizeof(buf), "%N", test_enum_split_names, printf_tests_split[_i].val); + 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_flags) +{ + char buf[1024]; + + snprintf(buf, sizeof(buf), "%N", test_enum_flags_names, + printf_tests_flags[_i].val); + ck_assert_str_eq(printf_tests_flags[_i].str, buf); +} +END_TEST + +START_TEST(test_enum_printf_hook_flags_incomplete) +{ + char buf[1024]; + + snprintf(buf, sizeof(buf), "%N", test_enum_flags_incomplete_names, + printf_tests_flags_incomplete[_i].val); + ck_assert_str_eq(printf_tests_flags_incomplete[_i].str, buf); +} +END_TEST + +START_TEST(test_enum_printf_hook_flags_null) +{ + char buf[1024]; + + snprintf(buf, sizeof(buf), "%N", test_enum_flags_null_names, + printf_tests_flags_null[_i].val); + ck_assert_str_eq(printf_tests_flags_null[_i].str, buf); +} +END_TEST + +START_TEST(test_enum_printf_hook_flags_overflow) +{ + char buf[1024]; + + snprintf(buf, sizeof(buf), "%N", test_enum_flags_overflow_names, + printf_tests_flags_overflow[_i].val); + ck_assert_str_eq(printf_tests_flags_overflow[_i].str, buf); +} +END_TEST + +START_TEST(test_enum_printf_hook_flags_noflagenum) +{ + char buf[1024]; + + snprintf(buf, sizeof(buf), "%N", test_enum_cont_names, + printf_tests_flags_noflagenum[_i].val); + ck_assert_str_eq(printf_tests_flags_noflagenum[_i].str, buf); +} +END_TEST + +START_TEST(test_enum_flags_to_string) +{ + char buf[1], *str; + + str = enum_flags_to_string(test_enum_flags_names, + enum_flags_to_string_tests[_i].val, buf, sizeof(buf)); + if (str) + { + ck_assert_str_eq(enum_flags_to_string_tests[_i].str, str); + } + else + { + ck_assert(str == enum_flags_to_string_tests[_i].str); + } +} +END_TEST + +START_TEST(test_enum_flags_to_string_noflagenum) +{ + char buf[1024]; + + enum_flags_to_string(test_enum_cont_names, + printf_tests_flags_noflagenum[_i].val, buf, sizeof(buf)); + ck_assert_str_eq(printf_tests_flags_noflagenum[_i].str, buf); +} +END_TEST + START_TEST(test_enum_printf_hook_width) { char buf[128]; @@ -246,9 +398,19 @@ Suite *enum_suite_create() tcase_add_loop_test(tc, test_enum_from_name_split, 0, countof(enum_tests_split)); suite_add_tcase(s, tc); + tc = tcase_create("enum_flags_to_string"); + tcase_add_loop_test(tc, test_enum_flags_to_string, 0, countof(enum_flags_to_string_tests)); + tcase_add_loop_test(tc, test_enum_flags_to_string_noflagenum, 0, countof(printf_tests_flags_noflagenum)); + 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_loop_test(tc, test_enum_printf_hook_flags, 0, countof(printf_tests_flags)); + tcase_add_loop_test(tc, test_enum_printf_hook_flags_incomplete, 0, countof(printf_tests_flags_incomplete)); + tcase_add_loop_test(tc, test_enum_printf_hook_flags_null, 0, countof(printf_tests_flags_null)); + tcase_add_loop_test(tc, test_enum_printf_hook_flags_overflow, 0, countof(printf_tests_flags_overflow)); + tcase_add_loop_test(tc, test_enum_printf_hook_flags_noflagenum, 0, countof(printf_tests_flags_noflagenum)); tcase_add_test(tc, test_enum_printf_hook_width); suite_add_tcase(s, tc); diff --git a/src/libstrongswan/tests/suites/test_hasher.c b/src/libstrongswan/tests/suites/test_hasher.c index 41a9d64ef..14cc32122 100644 --- a/src/libstrongswan/tests/suites/test_hasher.c +++ b/src/libstrongswan/tests/suites/test_hasher.c @@ -48,6 +48,9 @@ static hasher_oid_t oids[] = { { OID_ECDSA_WITH_SHA256, HASH_SHA256, KEY_ECDSA }, { OID_ECDSA_WITH_SHA384, HASH_SHA384, KEY_ECDSA }, { OID_ECDSA_WITH_SHA512, HASH_SHA512, KEY_ECDSA }, + { OID_BLISS_WITH_SHA256, HASH_SHA256, KEY_BLISS }, + { OID_BLISS_WITH_SHA384, HASH_SHA384, KEY_BLISS }, + { OID_BLISS_WITH_SHA512, HASH_SHA512, KEY_BLISS }, { OID_UNKNOWN, HASH_UNKNOWN, KEY_ECDSA } }; diff --git a/src/libstrongswan/tests/suites/test_host.c b/src/libstrongswan/tests/suites/test_host.c index 63442083a..7161b2c5b 100644 --- a/src/libstrongswan/tests/suites/test_host.c +++ b/src/libstrongswan/tests/suites/test_host.c @@ -237,6 +237,48 @@ START_TEST(test_create_from_string_and_family_other) END_TEST /******************************************************************************* + * host_create_from_dns + */ + +static void test_create_from_dns(int family, chunk_t addr) +{ + host_t *host; + + host = host_create_from_dns("localhost", family, 500); + if (family != AF_INET6) + { + ck_assert(host != NULL); + } + if (host) + { + if (family != AF_UNSPEC) + { + verify_address(host, addr, family, 500); + } + host->destroy(host); + } +} + +START_TEST(test_create_from_dns_any) +{ + test_create_from_dns(AF_UNSPEC, chunk_empty); +} +END_TEST + +START_TEST(test_create_from_dns_v4) +{ + test_create_from_dns(AF_INET, chunk_from_chars(127,0,0,1)); +} +END_TEST + +START_TEST(test_create_from_dns_v6) +{ + test_create_from_dns(AF_INET6, + chunk_from_chars(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1)); +} +END_TEST + +/******************************************************************************* * host_create_from_sockaddr */ @@ -400,6 +442,90 @@ START_TEST(test_create_from_subnet_v6) END_TEST /******************************************************************************* + * host_create_from_range + */ + +static const chunk_t addr_v4_to = chunk_from_chars(0xc0, 0xa8, 0x00, 0x05); +static const chunk_t addr_v6_to = chunk_from_chars(0xfe, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05); + +static void verify_range(char *str, int family, chunk_t from_addr, + chunk_t to_addr) +{ + host_t *from, *to; + + if (!family) + { + ck_assert(!host_create_from_range(str, &from, &to)); + } + else + { + ck_assert(host_create_from_range(str, &from, &to)); + verify_address(from, from_addr, family, 0); + verify_address(to, to_addr, family, 0); + from->destroy(from); + to->destroy(to); + } +} + +START_TEST(test_create_from_range_v4) +{ + host_t *from, *to; + + ck_assert(host_create_from_range("0.0.0.0-0.0.0.0", &from, &to)); + verify_any(from, AF_INET, 0); + verify_any(to, AF_INET, 0); + from->destroy(from); + to->destroy(to); + + verify_range("192.168.0.1-192.168.0.1", AF_INET, addr_v4, addr_v4); + verify_range("192.168.0.1-192.168.0.5", AF_INET, addr_v4, addr_v4_to); + verify_range("192.168.0.1- 192.168.0.5", AF_INET, addr_v4, addr_v4_to); + verify_range("192.168.0.1 -192.168.0.5", AF_INET, addr_v4, addr_v4_to); + verify_range("192.168.0.1 - 192.168.0.5", AF_INET, addr_v4, addr_v4_to); + verify_range("192.168.0.5-192.168.0.1", AF_INET, addr_v4_to, addr_v4); + + verify_range("192.168.0.1", 0, chunk_empty, chunk_empty); + verify_range("192.168.0.1-", 0, chunk_empty, chunk_empty); + verify_range("-192.168.0.1", 0, chunk_empty, chunk_empty); + verify_range("192.168.0.1-192", 0, chunk_empty, chunk_empty); + verify_range("192.168.0.1-192.168", 0, chunk_empty, chunk_empty); + verify_range("192.168.0.1-192.168.0", 0, chunk_empty, chunk_empty); + verify_range("foo.b.a.r", 0, chunk_empty, chunk_empty); + verify_range("foo.b.a.r-b.a.r.f", 0, chunk_empty, chunk_empty); +} +END_TEST + +START_TEST(test_create_from_range_v6) +{ + host_t *from, *to; + + ck_assert(host_create_from_range("::-::", &from, &to)); + verify_any(from, AF_INET6, 0); + verify_any(to, AF_INET6, 0); + from->destroy(from); + to->destroy(to); + + verify_range("fec1::1-fec1::1", AF_INET6, addr_v6, addr_v6); + verify_range("fec1::1-fec1::5", AF_INET6, addr_v6, addr_v6_to); + verify_range("fec1::1- fec1::5", AF_INET6, addr_v6, addr_v6_to); + verify_range("fec1::1 -fec1::5", AF_INET6, addr_v6, addr_v6_to); + verify_range("fec1::1 - fec1::5", AF_INET6, addr_v6, addr_v6_to); + verify_range("fec1::5-fec1::1", AF_INET6, addr_v6_to, addr_v6); + + verify_range("fec1::1", 0, chunk_empty, chunk_empty); + verify_range("fec1::1-", 0, chunk_empty, chunk_empty); + verify_range("-fec1::1", 0, chunk_empty, chunk_empty); + verify_range("fec1::1-fec1", 0, chunk_empty, chunk_empty); + verify_range("foo::bar", 0, chunk_empty, chunk_empty); + verify_range("foo::bar-bar::foo", 0, chunk_empty, chunk_empty); + + verify_range("fec1::1-192.168.0.1", 0, chunk_empty, chunk_empty); + verify_range("192.168.0.1-fec1::1", 0, chunk_empty, chunk_empty); +} +END_TEST + +/******************************************************************************* * host_create_netmask */ @@ -610,6 +736,12 @@ Suite *host_suite_create() tcase_add_test(tc, test_create_from_string_and_family_other); suite_add_tcase(s, tc); + tc = tcase_create("host_create_from_dns"); + tcase_add_test(tc, test_create_from_dns_any); + tcase_add_test(tc, test_create_from_dns_v4); + tcase_add_test(tc, test_create_from_dns_v6); + 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); @@ -627,6 +759,11 @@ Suite *host_suite_create() tcase_add_test(tc, test_create_from_subnet_v6); suite_add_tcase(s, tc); + tc = tcase_create("host_create_from_range"); + tcase_add_test(tc, test_create_from_range_v4); + tcase_add_test(tc, test_create_from_range_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); diff --git a/src/libstrongswan/tests/suites/test_identification.c b/src/libstrongswan/tests/suites/test_identification.c index 5de785710..de00e4afd 100644 --- a/src/libstrongswan/tests/suites/test_identification.c +++ b/src/libstrongswan/tests/suites/test_identification.c @@ -122,58 +122,68 @@ static struct { } 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 }}, - {"alice@strongswan.org", 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 }}, + {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 }}, + {"alice@strongswan.org", 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 }}, + {"IPv4:#c0a80101", ID_IPV4_ADDR, { .type = ENC_CHUNK, + .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }}, + { "email:tester", ID_RFC822_ADDR, { .type = ENC_STRING, + .data.s = "tester" }}, + { "{1}:#c0a80101", ID_IPV4_ADDR, { .type = ENC_CHUNK, + .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }}, + { "{0x02}:tester", ID_FQDN, { .type = ENC_STRING, + .data.s = "tester" }}, + { "{99}:somedata", 99, { .type = ENC_STRING, + .data.s = "somedata" }}, }; START_TEST(test_from_string) diff --git a/src/libstrongswan/tests/suites/test_mgf1.c b/src/libstrongswan/tests/suites/test_mgf1.c new file mode 100644 index 000000000..9388b95d4 --- /dev/null +++ b/src/libstrongswan/tests/suites/test_mgf1.c @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2014 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 <tests/utils/test_rng.h> +#include <utils/test.h> +#include <crypto/mgf1/mgf1.h> +#include <crypto/mgf1/mgf1_bitspender.h> + +typedef struct { + hash_algorithm_t alg; + size_t hash_size; + size_t ml1, ml2, ml3, seed_len; + chunk_t seed; + chunk_t hashed_seed; + chunk_t mask; + uint32_t bits[22]; +} mgf1_test_t; + +/** + * MGF1 Mask Generation Function Test Vectors + */ +mgf1_test_t mgf1_tests[] = { + { HASH_SHA1, 20, 60, 20, 15, 24, + chunk_from_chars( + 0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D, + 0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D, + 0x8C, 0x9B, 0xD5, 0x63, 0x57, 0x38, 0x11, 0xC2, + 0xB5, 0xCA, 0xBF, 0x06, 0x43, 0x45, 0x19, 0xD5, + 0xE7, 0x36, 0xD0, 0x29, 0x21, 0xDA, 0x02, 0x20, + 0x45, 0xF6, 0x5F, 0x0F, 0x10, 0x04, 0x2A, 0xE3, + 0x6A, 0x1D, 0xD5, 0x9F, 0x1D, 0x66, 0x44, 0x8F, + 0xFA, 0xC6, 0xCA, 0xA4, 0x6E, 0x3B, 0x00, 0x66, + 0xA6, 0xC9, 0x80, 0x5C, 0xF5, 0x2D, 0xD7, 0x72, + 0xC6, 0xD4, 0x4F, 0x30, 0x72, 0xA2, 0xAD, 0xE0, + 0x33, 0xE8, 0x55, 0xD5, 0xE6, 0xD6, 0x00, 0x1D, + 0xA8, 0x68, 0xFF, 0x97, 0x36, 0x8A, 0xF4, 0xD6, + 0xF1, 0xB6, 0x7E, 0x1F, 0x06, 0xCB, 0x57, 0xCB, + 0x35, 0x38, 0xF2, 0x2D, 0xF6, 0x20), + chunk_from_chars( + 0xF3, 0x9B, 0x0B, 0xB4, 0x97, 0x50, 0xB5, 0xA7, + 0xE6, 0xBD, 0xDA, 0xD0, 0x9A, 0x52, 0xBE, 0xA0, + 0x21, 0xC4, 0x90, 0xB6), + chunk_from_chars( + 0x10, 0x43, 0x76, 0x72, 0x6C, 0xDE, 0xA0, 0x0E, + 0x77, 0x51, 0xFB, 0x58, 0x39, 0x8A, 0x36, 0xE1, + 0x63, 0x2B, 0xC9, 0x17, 0x56, 0x0C, 0x4B, 0x46, + 0xA4, 0x07, 0xA4, 0x3B, 0x8E, 0x33, 0x4D, 0xD1, + 0x65, 0xF1, 0xAC, 0xC8, 0x59, 0x21, 0x32, 0x16, + 0x44, 0x2B, 0x7F, 0xB2, 0xA8, 0xA7, 0x26, 0x5D, + 0xE8, 0x02, 0xBE, 0x8E, 0xDC, 0x34, 0xEB, 0x10, + 0x76, 0x16, 0x8C, 0xDD, 0x90, 0x92, 0x3D, 0x29, + 0x90, 0x98, 0x46, 0x11, 0x73, 0x53, 0x47, 0xB1, + 0x2C, 0xD4, 0x83, 0x78, 0x9B, 0x93, 0x2F, 0x5B, + 0xFC, 0x26, 0xFF, 0x42, 0x08, 0x1F, 0x70, 0x66, + 0x40, 0x4B, 0xE7, 0x22, 0x3A, 0x56, 0x10, 0x6D, + 0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C, + 0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92, + 0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14), + { 0, 0, 0, 4, 1, 1, 46, 103, 38, 411, 848, 57, 3540, 4058, 12403, + 0x63, 0x2B, 0xC9, 0x17, 0x56, 669409, 0xA407A43B }, + }, + { HASH_SHA256, 32, 64, 32, 33, 40, + chunk_from_chars( + 0x52, 0xC5, 0xDD, 0x1E, 0xEF, 0x76, 0x1B, 0x53, + 0x08, 0xE4, 0x86, 0x3F, 0x91, 0x12, 0x98, 0x69, + 0xC5, 0x9D, 0xDE, 0xF6, 0xFC, 0xFA, 0x93, 0xCE, + 0x32, 0x52, 0x66, 0xF9, 0xC9, 0x97, 0xF6, 0x42, + 0x00, 0x2C, 0x64, 0xED, 0x1A, 0x6B, 0x14, 0x0A, + 0x4B, 0x04, 0xCF, 0x6D, 0x2D, 0x82, 0x0A, 0x07, + 0xA2, 0x3B, 0xDE, 0xCE, 0x19, 0x8A, 0x39, 0x43, + 0x16, 0x61, 0x29, 0x98, 0x68, 0xEA, 0xE5, 0xCC, + 0x0A, 0xF8, 0xE9, 0x71, 0x26, 0xF1, 0x07, 0x36, + 0x2C, 0x07, 0x1E, 0xEB, 0xE4, 0x28, 0xA2, 0xF4, + 0xA8, 0x12, 0xC0, 0xC8, 0x20, 0x37, 0xF8, 0xF2, + 0x6C, 0xAF, 0xDC, 0x6F, 0x2E, 0xD0, 0x62, 0x58, + 0xD2, 0x37, 0x03, 0x6D, 0xFA, 0x6E, 0x1A, 0xAC, + 0x9F, 0xCA, 0x56, 0xC6, 0xA4, 0x52, 0x41, 0xE8, + 0x0F, 0x1B, 0x0C, 0xB9, 0xE6, 0xBA, 0xDE, 0xE1, + 0x03, 0x5E, 0xC2, 0xE5, 0xF8, 0xF4, 0xF3, 0x46, + 0x3A, 0x12, 0xC0, 0x1F, 0x3A, 0x00, 0xD0, 0x91, + 0x18, 0xDD, 0x53, 0xE4, 0x22, 0xF5, 0x26, 0xA4, + 0x54, 0xEE, 0x20, 0xF0, 0x80), + chunk_from_chars( + 0x76, 0x89, 0x8B, 0x1B, 0x60, 0xEC, 0x10, 0x9D, + 0x8F, 0x13, 0xF2, 0xFE, 0xD9, 0x85, 0xC1, 0xAB, + 0x7E, 0xEE, 0xB1, 0x31, 0xDD, 0xF7, 0x7F, 0x0C, + 0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28), + chunk_from_chars( + 0xF1, 0x19, 0x02, 0x4F, 0xDA, 0x58, 0x05, 0x9A, + 0x07, 0xDF, 0x61, 0x81, 0x22, 0x0E, 0x15, 0x46, + 0xCB, 0x35, 0x3C, 0xDC, 0xAD, 0x20, 0xD9, 0x3F, + 0x0D, 0xD1, 0xAA, 0x64, 0x66, 0x5C, 0xFA, 0x4A, + 0xFE, 0xD6, 0x8F, 0x55, 0x57, 0x15, 0xB2, 0xA6, + 0xA0, 0xE6, 0xA8, 0xC6, 0xBD, 0x28, 0xB4, 0xD5, + 0x6E, 0x5B, 0x4B, 0xB0, 0x97, 0x09, 0xF5, 0xAC, + 0x57, 0x65, 0x13, 0x97, 0x71, 0x2C, 0x45, 0x13, + 0x3D, 0xEE, 0xFB, 0xBF, 0xFE, 0xAF, 0xBB, 0x4B, + 0x0D, 0x5C, 0x45, 0xD4, 0x2F, 0x17, 0x92, 0x07, + 0x66, 0x11, 0xF5, 0x46, 0xF8, 0x0C, 0x03, 0x92, + 0xF5, 0xF5, 0xFF, 0xA4, 0xF3, 0x52, 0xF4, 0x08, + 0x2C, 0x49, 0x32, 0x1A, 0x93, 0x51, 0x98, 0xB6, + 0x94, 0x83, 0x39, 0xCF, 0x6B, 0x1F, 0x2F, 0xFC, + 0x2B, 0xFF, 0x10, 0x71, 0x7D, 0x35, 0x6C, 0xEA, + 0xC5, 0x66, 0xC7, 0x26, 0x7D, 0x9E, 0xAC, 0xDD, + 0x35, 0xD7, 0x06, 0x3F, 0x40, 0x82, 0xDA, 0xC3, + 0x2B, 0x3C, 0x91, 0x3A, 0x32, 0xF8, 0xB2, 0xC6, + 0x44, 0x4D, 0xCD, 0xB6, 0x54, 0x5F, 0x81, 0x95, + 0x59, 0xA1, 0xE5, 0x4E, 0xA5, 0x0A, 0x4A, 0x42), + { 0, 1, 3, 4, 4, 12, 32, 36, 253, 331, 2, 1640, 503, 6924, 580, + 0xCB, 0x35, 0x3C, 0xDC, 0xAD, 922950, 0x0DD1AA64 } + } +}; + +START_TEST(mgf1_test_mgf1) +{ + mgf1_t *mgf1; + chunk_t mask, mask1, mask2, mask3; + + mask1 = mgf1_tests[_i].mask; + mask2 = chunk_skip(mask1, mgf1_tests[_i].ml1); + mask3 = chunk_skip(mask2, mgf1_tests[_i].ml2); + mask1.len = mgf1_tests[_i].ml1; + mask2.len = mgf1_tests[_i].ml2; + mask3.len = mgf1_tests[_i].ml3; + + mgf1 = mgf1_create(HASH_UNKNOWN, mgf1_tests[_i].seed, TRUE); + ck_assert(mgf1 == NULL); + + mgf1 = mgf1_create(mgf1_tests[_i].alg, chunk_empty, TRUE); + ck_assert(mgf1 == NULL); + + /* return mask in allocated chunk */ + mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE); + ck_assert(mgf1); + + /* check hash size */ + ck_assert(mgf1->get_hash_size(mgf1) == mgf1_tests[_i].hash_size); + + /* get zero number of octets */ + ck_assert(mgf1->allocate_mask(mgf1, 0, &mask)); + ck_assert(mask.len == 0 && mask.ptr == NULL); + + /* get non-zero number of octets */ + ck_assert(mgf1->allocate_mask(mgf1, mgf1_tests[_i].mask.len, &mask)); + ck_assert(chunk_equals(mask, mgf1_tests[_i].mask)); + mgf1->destroy(mgf1); + + /* copy mask to pre-allocated buffer */ + mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE); + ck_assert(mgf1); + ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr)); + ck_assert(chunk_equals(mask, mgf1_tests[_i].mask)); + mgf1->destroy(mgf1); + + /* get mask in batches without hashing the seed */ + mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].hashed_seed, FALSE); + ck_assert(mgf1); + + /* first batch */ + ck_assert(mgf1->get_mask(mgf1, mask1.len, mask.ptr)); + mask.len = mask1.len; + ck_assert(chunk_equals(mask, mask1)); + + /* second batch */ + ck_assert(mgf1->get_mask(mgf1, mask2.len, mask.ptr)); + mask.len = mask2.len; + ck_assert(chunk_equals(mask, mask2)); + + /* third batch */ + ck_assert(mgf1->get_mask(mgf1, mask3.len, mask.ptr)); + mask.len = mask3.len; + ck_assert(chunk_equals(mask, mask3)); + + mgf1->destroy(mgf1); + chunk_free(&mask); +} +END_TEST + +START_TEST(mgf1_test_bitspender) +{ + mgf1_bitspender_t *bitspender; + uint32_t bits; + uint8_t byte; + int j; + + bitspender = mgf1_bitspender_create(HASH_UNKNOWN, + mgf1_tests[_i].hashed_seed, FALSE); + ck_assert(bitspender == NULL); + + bitspender = mgf1_bitspender_create(mgf1_tests[_i].alg, + mgf1_tests[_i].hashed_seed, FALSE); + ck_assert(bitspender); + + for (j = 0; j < 15; j++) + { + ck_assert(bitspender->get_bits(bitspender, j, &bits)); + DBG1(DBG_LIB, "bits[%d] = %u, bits = %u", j, mgf1_tests[_i].bits[j], + bits); + ck_assert(bits == mgf1_tests[_i].bits[j]); + } + ck_assert(!bitspender->get_bits(bitspender, 33, &bits)); + + for (j = 15; j < 20; j++) + { + ck_assert(bitspender->get_byte(bitspender, &byte)); + DBG1(DBG_LIB, "bits[%d] = 0x%02x, byte = 0x%02x", j, + mgf1_tests[_i].bits[j], byte); + ck_assert(byte == mgf1_tests[_i].bits[j]); + } + + j = 20; /* 23 remaining bits */ + ck_assert(bitspender->get_bits(bitspender, 23, &bits)); + DBG1(DBG_LIB, "bits[%d] = %u, bits = %u", j, + mgf1_tests[_i].bits[j], bits); + ck_assert(bits == mgf1_tests[_i].bits[j]); + + j = 21; /* 32 aligned bits */ + ck_assert(bitspender->get_bits(bitspender, 32, &bits)); + DBG1(DBG_LIB, "bits[%d] = 0x%08x, bits = 0x%08x", j, + mgf1_tests[_i].bits[j], bits); + ck_assert(bits == mgf1_tests[_i].bits[j]); + + bitspender->destroy(bitspender); +} +END_TEST + + +Suite *mgf1_suite_create(char *name, int n) +{ + Suite *s; + TCase *tc; + + s = suite_create(name); + + tc = tcase_create("mgf1"); + tcase_add_loop_test(tc, mgf1_test_mgf1, n, n + 1); + suite_add_tcase(s, tc); + + tc = tcase_create("bitspender"); + tcase_add_loop_test(tc, mgf1_test_bitspender, n, n + 1); + suite_add_tcase(s, tc); + + return s; +} + +Suite *mgf1_sha1_suite_create() +{ + return mgf1_suite_create("mgf1-sha1", 0); +} + +Suite *mgf1_sha256_suite_create() +{ + return mgf1_suite_create("mgf1-sha256", 1); +} diff --git a/src/libstrongswan/tests/suites/test_ntru.c b/src/libstrongswan/tests/suites/test_ntru.c index 7c0cb81bf..d209fa2bc 100644 --- a/src/libstrongswan/tests/suites/test_ntru.c +++ b/src/libstrongswan/tests/suites/test_ntru.c @@ -16,20 +16,17 @@ #include "test_suite.h" #include <tests/utils/test_rng.h> +#include <utils/test.h> +#include <crypto/mgf1/mgf1.h> #include <plugins/ntru/ntru_drbg.h> -#include <plugins/ntru/ntru_mgf1.h> #include <plugins/ntru/ntru_trits.h> #include <plugins/ntru/ntru_poly.h> #include <plugins/ntru/ntru_param_set.h> #include <plugins/ntru/ntru_private_key.h> -#include <utils/test.h> IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_drbg_create, ntru_drbg_t*, u_int32_t strength, chunk_t pers_str, rng_t *entropy) -IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_mgf1_create, ntru_mgf1_t*, - hash_algorithm_t alg, chunk_t seed, bool hash_seed) - IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_trits_create, ntru_trits_t*, size_t len, hash_algorithm_t alg, chunk_t seed) @@ -334,13 +331,11 @@ typedef struct { typedef struct { hash_algorithm_t alg; size_t hash_size; - size_t ml1, ml2, ml3, seed_len; + size_t seed_len; chunk_t seed; - chunk_t hashed_seed; - chunk_t mask; chunk_t trits; poly_test_t poly_test[2]; -} mgf1_test_t; +} trits_test_t; uint16_t indices_ees439ep1[] = { 367, 413, 16, 214, 114, 128, 42, 268, 346, 329, 119, 303, 208, 287, 150, @@ -386,10 +381,10 @@ uint16_t indices_ees1171ep1[] = { }; /** - * MGF1 Mask Generation Function Test Vectors + * Trits and Polynomial Test Vectors */ -mgf1_test_t mgf1_tests[] = { - { HASH_SHA1, 20, 60, 20, 15, 24, +static trits_test_t trits_tests[] = { + { HASH_SHA1, 20, 24, chunk_from_chars( 0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D, 0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D, @@ -406,26 +401,6 @@ mgf1_test_t mgf1_tests[] = { 0xF1, 0xB6, 0x7E, 0x1F, 0x06, 0xCB, 0x57, 0xCB, 0x35, 0x38, 0xF2, 0x2D, 0xF6, 0x20), chunk_from_chars( - 0xF3, 0x9B, 0x0B, 0xB4, 0x97, 0x50, 0xB5, 0xA7, - 0xE6, 0xBD, 0xDA, 0xD0, 0x9A, 0x52, 0xBE, 0xA0, - 0x21, 0xC4, 0x90, 0xB6), - chunk_from_chars( - 0x10, 0x43, 0x76, 0x72, 0x6C, 0xDE, 0xA0, 0x0E, - 0x77, 0x51, 0xFB, 0x58, 0x39, 0x8A, 0x36, 0xE1, - 0x63, 0x2B, 0xC9, 0x17, 0x56, 0x0C, 0x4B, 0x46, - 0xA4, 0x07, 0xA4, 0x3B, 0x8E, 0x33, 0x4D, 0xD1, - 0x65, 0xF1, 0xAC, 0xC8, 0x59, 0x21, 0x32, 0x16, - 0x44, 0x2B, 0x7F, 0xB2, 0xA8, 0xA7, 0x26, 0x5D, - 0xE8, 0x02, 0xBE, 0x8E, 0xDC, 0x34, 0xEB, 0x10, - 0x76, 0x16, 0x8C, 0xDD, 0x90, 0x92, 0x3D, 0x29, - 0x90, 0x98, 0x46, 0x11, 0x73, 0x53, 0x47, 0xB1, - 0x2C, 0xD4, 0x83, 0x78, 0x9B, 0x93, 0x2F, 0x5B, - 0xFC, 0x26, 0xFF, 0x42, 0x08, 0x1F, 0x70, 0x66, - 0x40, 0x4B, 0xE7, 0x22, 0x3A, 0x56, 0x10, 0x6D, - 0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C, - 0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92, - 0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14), - chunk_from_chars( 1, 2, 1, 0, 0, 1, 1, 1, 2, 0, 1, 0, 1, 1, 1, 0, 2, 0, 1, 1, 0, 0, 0, 1, 1, 0, 2, 0, 2, 2, 1, 2, 2, 2, 1, 2, 1, 1, 0, 0, 2, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 2, 0, 0, 1, 0, 1, 0, 2, 0, @@ -457,7 +432,7 @@ mgf1_test_t mgf1_tests[] = { } } }, - { HASH_SHA256, 32, 64, 32, 33, 40, + { HASH_SHA256, 32, 40, chunk_from_chars( 0x52, 0xC5, 0xDD, 0x1E, 0xEF, 0x76, 0x1B, 0x53, 0x08, 0xE4, 0x86, 0x3F, 0x91, 0x12, 0x98, 0x69, @@ -479,32 +454,6 @@ mgf1_test_t mgf1_tests[] = { 0x18, 0xDD, 0x53, 0xE4, 0x22, 0xF5, 0x26, 0xA4, 0x54, 0xEE, 0x20, 0xF0, 0x80), chunk_from_chars( - 0x76, 0x89, 0x8B, 0x1B, 0x60, 0xEC, 0x10, 0x9D, - 0x8F, 0x13, 0xF2, 0xFE, 0xD9, 0x85, 0xC1, 0xAB, - 0x7E, 0xEE, 0xB1, 0x31, 0xDD, 0xF7, 0x7F, 0x0C, - 0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28), - chunk_from_chars( - 0xF1, 0x19, 0x02, 0x4F, 0xDA, 0x58, 0x05, 0x9A, - 0x07, 0xDF, 0x61, 0x81, 0x22, 0x0E, 0x15, 0x46, - 0xCB, 0x35, 0x3C, 0xDC, 0xAD, 0x20, 0xD9, 0x3F, - 0x0D, 0xD1, 0xAA, 0x64, 0x66, 0x5C, 0xFA, 0x4A, - 0xFE, 0xD6, 0x8F, 0x55, 0x57, 0x15, 0xB2, 0xA6, - 0xA0, 0xE6, 0xA8, 0xC6, 0xBD, 0x28, 0xB4, 0xD5, - 0x6E, 0x5B, 0x4B, 0xB0, 0x97, 0x09, 0xF5, 0xAC, - 0x57, 0x65, 0x13, 0x97, 0x71, 0x2C, 0x45, 0x13, - 0x3D, 0xEE, 0xFB, 0xBF, 0xFE, 0xAF, 0xBB, 0x4B, - 0x0D, 0x5C, 0x45, 0xD4, 0x2F, 0x17, 0x92, 0x07, - 0x66, 0x11, 0xF5, 0x46, 0xF8, 0x0C, 0x03, 0x92, - 0xF5, 0xF5, 0xFF, 0xA4, 0xF3, 0x52, 0xF4, 0x08, - 0x2C, 0x49, 0x32, 0x1A, 0x93, 0x51, 0x98, 0xB6, - 0x94, 0x83, 0x39, 0xCF, 0x6B, 0x1F, 0x2F, 0xFC, - 0x2B, 0xFF, 0x10, 0x71, 0x7D, 0x35, 0x6C, 0xEA, - 0xC5, 0x66, 0xC7, 0x26, 0x7D, 0x9E, 0xAC, 0xDD, - 0x35, 0xD7, 0x06, 0x3F, 0x40, 0x82, 0xDA, 0xC3, - 0x2B, 0x3C, 0x91, 0x3A, 0x32, 0xF8, 0xB2, 0xC6, - 0x44, 0x4D, 0xCD, 0xB6, 0x54, 0x5F, 0x81, 0x95, - 0x59, 0xA1, 0xE5, 0x4E, 0xA5, 0x0A, 0x4A, 0x42), - chunk_from_chars( 1, 2, 2, 2, 2, 1, 2, 2, 0, 0, 2, 0, 0, 0, 0, 1, 2, 2, 2, 0, 2, 0, 0, 2, 2, 1, 2, 0, 0, 1, 2, 1, 0, 0, 0, 1, 0, 2, 2, 1, 1, 2, 0, 0, 0, 1, 2, 0, 2, 2, 1, 2, 1, 0, 1, 0, 1, 2, 1, 1, @@ -546,104 +495,34 @@ mgf1_test_t mgf1_tests[] = { } }; -START_TEST(test_ntru_mgf1) -{ - ntru_mgf1_t *mgf1; - chunk_t mask, mask1, mask2, mask3; - - mask1 = mgf1_tests[_i].mask; - mask2 = chunk_skip(mask1, mgf1_tests[_i].ml1); - mask3 = chunk_skip(mask2, mgf1_tests[_i].ml2); - mask1.len = mgf1_tests[_i].ml1; - mask2.len = mgf1_tests[_i].ml2; - mask3.len = mgf1_tests[_i].ml3; - - mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, HASH_UNKNOWN, - mgf1_tests[_i].seed, TRUE); - ck_assert(mgf1 == NULL); - - mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg, - chunk_empty, TRUE); - ck_assert(mgf1 == NULL); - - /* return mask in allocated chunk */ - mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg, - mgf1_tests[_i].seed, TRUE); - ck_assert(mgf1); - - /* check hash size */ - ck_assert(mgf1->get_hash_size(mgf1) == mgf1_tests[_i].hash_size); - - /* get zero number of octets */ - ck_assert(mgf1->allocate_mask(mgf1, 0, &mask)); - ck_assert(mask.len == 0 && mask.ptr == NULL); - - /* get non-zero number of octets */ - ck_assert(mgf1->allocate_mask(mgf1, mgf1_tests[_i].mask.len, &mask)); - ck_assert(chunk_equals(mask, mgf1_tests[_i].mask)); - mgf1->destroy(mgf1); - - /* copy mask to pre-allocated buffer */ - mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg, - mgf1_tests[_i].seed, TRUE); - ck_assert(mgf1); - ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr)); - ck_assert(chunk_equals(mask, mgf1_tests[_i].mask)); - mgf1->destroy(mgf1); - - /* get mask in batches without hashing the seed */ - mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg, - mgf1_tests[_i].hashed_seed, FALSE); - ck_assert(mgf1); - - /* first batch */ - ck_assert(mgf1->get_mask(mgf1, mask1.len, mask.ptr)); - mask.len = mask1.len; - ck_assert(chunk_equals(mask, mask1)); - - /* second batch */ - ck_assert(mgf1->get_mask(mgf1, mask2.len, mask.ptr)); - mask.len = mask2.len; - ck_assert(chunk_equals(mask, mask2)); - - /* third batch */ - ck_assert(mgf1->get_mask(mgf1, mask3.len, mask.ptr)); - mask.len = mask3.len; - ck_assert(chunk_equals(mask, mask3)); - - mgf1->destroy(mgf1); - chunk_free(&mask); -} -END_TEST - START_TEST(test_ntru_trits) { ntru_trits_t *mask; chunk_t trits; - mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len, - HASH_UNKNOWN, mgf1_tests[_i].seed); + mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len, + HASH_UNKNOWN, trits_tests[_i].seed); ck_assert(mask == NULL); - mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len, - mgf1_tests[_i].alg, chunk_empty); + mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len, + trits_tests[_i].alg, chunk_empty); ck_assert(mask == NULL); - mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len, - mgf1_tests[_i].alg, mgf1_tests[_i].seed); + mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len, + trits_tests[_i].alg, trits_tests[_i].seed); ck_assert(mask); trits = chunk_create(mask->get_trits(mask), mask->get_size(mask)); - ck_assert(chunk_equals(trits, mgf1_tests[_i].trits)); + ck_assert(chunk_equals(trits, trits_tests[_i].trits)); mask->destroy(mask); /* generate a multiple of 5 trits */ - mask = TEST_FUNCTION(ntru, ntru_trits_create, 10, mgf1_tests[_i].alg, - mgf1_tests[_i].seed); + mask = TEST_FUNCTION(ntru, ntru_trits_create, 10, trits_tests[_i].alg, + trits_tests[_i].seed); ck_assert(mask); trits = chunk_create(mask->get_trits(mask), mask->get_size(mask)); - ck_assert(chunk_equals(trits, chunk_create(mgf1_tests[_i].trits.ptr, 10))); + ck_assert(chunk_equals(trits, chunk_create(trits_tests[_i].trits.ptr, 10))); mask->destroy(mask); } END_TEST @@ -656,10 +535,10 @@ START_TEST(test_ntru_poly) poly_test_t *p; int j, n; - seed = mgf1_tests[_i].seed; - seed.len = mgf1_tests[_i].seed_len; + seed = trits_tests[_i].seed; + seed.len = trits_tests[_i].seed_len; - p = &mgf1_tests[_i].poly_test[0]; + p = &trits_tests[_i].poly_test[0]; poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed, HASH_UNKNOWN, seed, p->c_bits, p->N, p->q, p->indices_len, p->indices_len, p->is_product_form); @@ -667,9 +546,9 @@ START_TEST(test_ntru_poly) for (n = 0; n < 2; n++) { - p = &mgf1_tests[_i].poly_test[n]; + p = &trits_tests[_i].poly_test[n]; poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed, - mgf1_tests[_i].alg, seed, p->c_bits, p->N, p->q, + trits_tests[_i].alg, seed, p->c_bits, p->N, p->q, p->indices_len, p->indices_len, p->is_product_form); ck_assert(poly != NULL && poly->get_size(poly) == p->indices_size); @@ -1182,7 +1061,6 @@ START_TEST(test_ntru_ke) diffie_hellman_t *i_ntru, *r_ntru; char buf[10]; int k, n, len; - status_t status; k = (_i) / countof(parameter_sets); n = (_i) % countof(parameter_sets); @@ -1199,23 +1077,21 @@ START_TEST(test_ntru_ke) ck_assert(i_ntru != NULL); ck_assert(i_ntru->get_dh_group(i_ntru) == params[k].group); - i_ntru->get_my_public_value(i_ntru, &pub_key); + ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key)); ck_assert(pub_key.len > 0); r_ntru = lib->crypto->create_dh(lib->crypto, params[k].group); ck_assert(r_ntru != NULL); - r_ntru->set_other_public_value(r_ntru, pub_key); - r_ntru->get_my_public_value(r_ntru, &cipher_text); + ck_assert(r_ntru->set_other_public_value(r_ntru, pub_key)); + ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text)); ck_assert(cipher_text.len > 0); - status = r_ntru->get_shared_secret(r_ntru, &r_shared_secret); - ck_assert(status == SUCCESS); + ck_assert(r_ntru->get_shared_secret(r_ntru, &r_shared_secret)); ck_assert(r_shared_secret.len > 0); - i_ntru->set_other_public_value(i_ntru, cipher_text); - status = i_ntru->get_shared_secret(i_ntru, &i_shared_secret); - ck_assert(status == SUCCESS); + ck_assert(i_ntru->set_other_public_value(i_ntru, cipher_text)); + ck_assert(i_ntru->get_shared_secret(i_ntru, &i_shared_secret)); ck_assert(chunk_equals(i_shared_secret, r_shared_secret)); chunk_clear(&i_shared_secret); @@ -1233,8 +1109,8 @@ START_TEST(test_ntru_retransmission) chunk_t pub_key1, pub_key2; i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_256_BIT); - i_ntru->get_my_public_value(i_ntru, &pub_key1); - i_ntru->get_my_public_value(i_ntru, &pub_key2); + ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key1)); + ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key2)); ck_assert(chunk_equals(pub_key1, pub_key2)); chunk_free(&pub_key1); @@ -1260,8 +1136,8 @@ START_TEST(test_ntru_pubkey_oid) chunk_t cipher_text; r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT); - r_ntru->set_other_public_value(r_ntru, oid_tests[_i]); - r_ntru->get_my_public_value(r_ntru, &cipher_text); + ck_assert(!r_ntru->set_other_public_value(r_ntru, oid_tests[_i])); + ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text)); ck_assert(cipher_text.len == 0); r_ntru->destroy(r_ntru); } @@ -1276,14 +1152,14 @@ START_TEST(test_ntru_wrong_set) "libstrongswan.plugins.ntru.parameter_set", "x9_98_bandwidth"); i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT); - i_ntru->get_my_public_value(i_ntru, &pub_key); + ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key)); lib->settings->set_str(lib->settings, "libstrongswan.plugins.ntru.parameter_set", "optimum"); r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT); - r_ntru->set_other_public_value(r_ntru, pub_key); - r_ntru->get_my_public_value(r_ntru, &cipher_text); + ck_assert(!r_ntru->set_other_public_value(r_ntru, pub_key)); + ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text)); ck_assert(cipher_text.len == 0); chunk_free(&pub_key); @@ -1314,9 +1190,9 @@ START_TEST(test_ntru_ciphertext) for (i = 0; i < countof(test); i++) { i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT); - i_ntru->get_my_public_value(i_ntru, &pub_key); - i_ntru->set_other_public_value(i_ntru, test[i]); - ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS); + ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key)); + ck_assert(!i_ntru->set_other_public_value(i_ntru, test[i])); + ck_assert(!i_ntru->get_shared_secret(i_ntru, &shared_secret)); ck_assert(shared_secret.len == 0); chunk_free(&pub_key); @@ -1334,12 +1210,12 @@ START_TEST(test_ntru_wrong_ciphertext) r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT); m_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT); - i_ntru->get_my_public_value(i_ntru, &pub_key_i); - m_ntru->get_my_public_value(m_ntru, &pub_key_m); - r_ntru->set_other_public_value(r_ntru, pub_key_m); - r_ntru->get_my_public_value(r_ntru, &cipher_text); - i_ntru->set_other_public_value(i_ntru, cipher_text); - ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS); + ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key_i)); + ck_assert(m_ntru->get_my_public_value(m_ntru, &pub_key_m)); + ck_assert(r_ntru->set_other_public_value(r_ntru, pub_key_m)); + ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text)); + ck_assert(!i_ntru->set_other_public_value(i_ntru, cipher_text)); + ck_assert(!i_ntru->get_shared_secret(i_ntru, &shared_secret)); ck_assert(shared_secret.len == 0); chunk_free(&pub_key_i); @@ -1370,16 +1246,12 @@ Suite *ntru_suite_create() tcase_add_test(tc, test_ntru_drbg_reseed); suite_add_tcase(s, tc); - tc = tcase_create("mgf1"); - tcase_add_loop_test(tc, test_ntru_mgf1, 0, countof(mgf1_tests)); - suite_add_tcase(s, tc); - tc = tcase_create("trits"); - tcase_add_loop_test(tc, test_ntru_trits, 0, countof(mgf1_tests)); + tcase_add_loop_test(tc, test_ntru_trits, 0, countof(trits_tests)); suite_add_tcase(s, tc); tc = tcase_create("poly"); - tcase_add_loop_test(tc, test_ntru_poly, 0, countof(mgf1_tests)); + tcase_add_loop_test(tc, test_ntru_poly, 0, countof(trits_tests)); suite_add_tcase(s, tc); tc = tcase_create("ring_mult"); diff --git a/src/libstrongswan/tests/suites/test_settings.c b/src/libstrongswan/tests/suites/test_settings.c index b9d429a24..9601a34a9 100644 --- a/src/libstrongswan/tests/suites/test_settings.c +++ b/src/libstrongswan/tests/suites/test_settings.c @@ -908,7 +908,7 @@ START_SETUP(setup_string_config) "special = \"all { special } characters # can be used.\"\n" "unterminated = \"is fine\n" "but = produces a warning\n" - "newlines = \"can either be encoded\\nor\\\n" + "newlines = \"can either be encoded\\nor \\\n" "escaped\"\n" "quotes = \"\\\"and\\\" slashes \\\\ can \\\\ be\" # escaped too\n" "multiple = \"strings\" are \"combined\"\n" @@ -922,7 +922,7 @@ START_TEST(test_strings) verify_string("all { special } characters # can be used.", "special"); verify_string("is fine", "unterminated"); verify_string("produces a warning", "but"); - verify_string("can either be encoded\nor\nescaped", "newlines"); + verify_string("can either be encoded\nor escaped", "newlines"); verify_string("\"and\" slashes \\ can \\ be", "quotes"); verify_string("strings are combined", "multiple"); } diff --git a/src/libstrongswan/tests/suites/test_threading.c b/src/libstrongswan/tests/suites/test_threading.c index 47e448484..55a4cd797 100644 --- a/src/libstrongswan/tests/suites/test_threading.c +++ b/src/libstrongswan/tests/suites/test_threading.c @@ -553,6 +553,49 @@ START_TEST(test_rwlock) } END_TEST +static void *rwlock_try_run(void *param) +{ + if (rwlock->try_write_lock(rwlock)) + { + rwlock->unlock(rwlock); + return param; + } + return NULL; +} + +START_TEST(test_rwlock_try) +{ + uintptr_t magic = 0xcafebabe; + thread_t *thread; + + rwlock = rwlock_create(RWLOCK_TYPE_DEFAULT); + + thread = thread_create(rwlock_try_run, (void*)magic); + ck_assert_int_eq((uintptr_t)thread->join(thread), magic); + + rwlock->read_lock(rwlock); + thread = thread_create(rwlock_try_run, (void*)magic); + ck_assert(thread->join(thread) == NULL); + rwlock->unlock(rwlock); + + rwlock->read_lock(rwlock); + rwlock->read_lock(rwlock); + rwlock->read_lock(rwlock); + thread = thread_create(rwlock_try_run, (void*)magic); + ck_assert(thread->join(thread) == NULL); + rwlock->unlock(rwlock); + rwlock->unlock(rwlock); + rwlock->unlock(rwlock); + + rwlock->write_lock(rwlock); + thread = thread_create(rwlock_try_run, (void*)magic); + ck_assert(thread->join(thread) == NULL); + rwlock->unlock(rwlock); + + rwlock->destroy(rwlock); +} +END_TEST + /** * Rwlock condvar */ @@ -1132,6 +1175,191 @@ START_TEST(test_cancel_point) } END_TEST +static void close_fd_ptr(void *fd) +{ + close(*(int*)fd); +} + +static void cancellation_recv() +{ + int sv[2]; + char buf[1]; + + ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); + + thread_cleanup_push(close_fd_ptr, &sv[0]); + thread_cleanup_push(close_fd_ptr, &sv[1]); + + thread_cancelability(TRUE); + while (TRUE) + { + ck_assert(recv(sv[0], buf, sizeof(buf), 0) == 1); + } +} + +static void cancellation_read() +{ + int sv[2]; + char buf[1]; + + ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); + + thread_cleanup_push(close_fd_ptr, &sv[0]); + thread_cleanup_push(close_fd_ptr, &sv[1]); + + thread_cancelability(TRUE); + while (TRUE) + { + ck_assert(read(sv[0], buf, sizeof(buf)) == 1); + } +} + +static void cancellation_select() +{ + int sv[2]; + fd_set set; + + ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); + + thread_cleanup_push(close_fd_ptr, &sv[0]); + thread_cleanup_push(close_fd_ptr, &sv[1]); + + FD_ZERO(&set); + FD_SET(sv[0], &set); + thread_cancelability(TRUE); + while (TRUE) + { + ck_assert(select(sv[0] + 1, &set, NULL, NULL, NULL) == 1); + } +} + +static void cancellation_poll() +{ + int sv[2]; + struct pollfd pfd; + + ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); + + thread_cleanup_push(close_fd_ptr, &sv[0]); + thread_cleanup_push(close_fd_ptr, &sv[1]); + + pfd.fd = sv[0]; + pfd.events = POLLIN; + thread_cancelability(TRUE); + while (TRUE) + { + ck_assert(poll(&pfd, 1, -1) == 1); + } +} + +static void cancellation_accept() +{ + host_t *host; + int fd, c; + + fd = socket(AF_INET, SOCK_STREAM, 0); + ck_assert(fd >= 0); + host = host_create_from_string("127.0.0.1", 0); + ck_assert_msg(bind(fd, host->get_sockaddr(host), + *host->get_sockaddr_len(host)) == 0, "%m"); + host->destroy(host); + ck_assert(listen(fd, 5) == 0); + + thread_cleanup_push(close_fd_ptr, &fd); + + thread_cancelability(TRUE); + while (TRUE) + { + c = accept(fd, NULL, NULL); + ck_assert(c >= 0); + close(c); + } +} + +static void cancellation_cond() +{ + mutex_t *mutex; + condvar_t *cond; + + mutex = mutex_create(MUTEX_TYPE_DEFAULT); + cond = condvar_create(CONDVAR_TYPE_DEFAULT); + mutex->lock(mutex); + + thread_cleanup_push((void*)mutex->destroy, mutex); + thread_cleanup_push((void*)cond->destroy, cond); + + thread_cancelability(TRUE); + while (TRUE) + { + cond->wait(cond, mutex); + } +} + +static void cancellation_rwcond() +{ + rwlock_t *lock; + rwlock_condvar_t *cond; + + lock = rwlock_create(RWLOCK_TYPE_DEFAULT); + cond = rwlock_condvar_create(); + lock->write_lock(lock); + + thread_cleanup_push((void*)lock->destroy, lock); + thread_cleanup_push((void*)cond->destroy, cond); + + thread_cancelability(TRUE); + while (TRUE) + { + cond->wait(cond, lock); + } +} + +static void (*cancellation_points[])() = { + cancellation_read, + cancellation_recv, + cancellation_select, + cancellation_poll, + cancellation_accept, + cancellation_cond, + cancellation_rwcond, +}; + +static void* run_cancellation_point(void (*fn)()) +{ + fn(); + return NULL; +} + +static void* run_cancellation_point_pre(void (*fn)()) +{ + usleep(5000); + fn(); + return NULL; +} + +START_TEST(test_cancellation_point) +{ + thread_t *thread; + + thread = thread_create((void*)run_cancellation_point, + cancellation_points[_i]); + usleep(5000); + thread->cancel(thread); + thread->join(thread); +} +END_TEST + +START_TEST(test_cancellation_point_pre) +{ + thread_t *thread; + + thread = thread_create((void*)run_cancellation_point_pre, + cancellation_points[_i]); + thread->cancel(thread); + thread->join(thread); +} +END_TEST + static void cleanup1(void *data) { uintptr_t *value = (uintptr_t*)data; @@ -1423,6 +1651,7 @@ Suite *threading_suite_create() tc = tcase_create("rwlock"); tcase_add_test(tc, test_rwlock); + tcase_add_test(tc, test_rwlock_try); suite_add_tcase(s, tc); tc = tcase_create("rwlock condvar"); @@ -1456,6 +1685,13 @@ Suite *threading_suite_create() tcase_add_test(tc, test_cancel_point); suite_add_tcase(s, tc); + tc = tcase_create("thread cancellation point"); + tcase_add_loop_test(tc, test_cancellation_point, + 0, countof(cancellation_points)); + tcase_add_loop_test(tc, test_cancellation_point_pre, + 0, countof(cancellation_points)); + suite_add_tcase(s, tc); + tc = tcase_create("thread cleanup"); tcase_add_test(tc, test_cleanup); tcase_add_test(tc, test_cleanup_exit); diff --git a/src/libstrongswan/tests/suites/test_traffic_selector.c b/src/libstrongswan/tests/suites/test_traffic_selector.c new file mode 100644 index 000000000..4312c6ce1 --- /dev/null +++ b/src/libstrongswan/tests/suites/test_traffic_selector.c @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2015 Martin Willi + * Copyright (C) 2015 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 <selectors/traffic_selector.h> + + +static void verify(const char *str, const char *alt, traffic_selector_t *ts) +{ + char buf[512]; + + ck_assert(ts != NULL); + snprintf(buf, sizeof(buf), "%R", ts); + ts->destroy(ts); + if (!streq(buf, str) && !streq(buf, alt)) + { + fail("%s != %s or %s", buf, str, alt); + } +} + +START_TEST(test_create_from_string) +{ + verify("10.1.0.0/16[tcp/http]", "10.1.0.0/16[6/80]", + traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV4_ADDR_RANGE, + "10.1.0.0", 80, "10.1.255.255", 80)); + verify("10.1.0.1..10.1.0.99[udp/1234-1235]", + "10.1.0.1..10.1.0.99[17/1234-1235]", + traffic_selector_create_from_string(IPPROTO_UDP, TS_IPV4_ADDR_RANGE, + "10.1.0.1", 1234, "10.1.0.99", 1235)); + verify("fec1::/64", NULL, + traffic_selector_create_from_string(0, TS_IPV6_ADDR_RANGE, + "fec1::", 0, "fec1::ffff:ffff:ffff:ffff", 65535)); +} +END_TEST + +START_TEST(test_create_from_cidr) +{ + verify("10.1.0.0/16", NULL, + traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535)); + verify("10.1.0.1/32[udp/1234-1235]", "10.1.0.1/32[17/1234-1235]", + traffic_selector_create_from_cidr("10.1.0.1/32", IPPROTO_UDP, + 1234, 1235)); +} +END_TEST + +START_TEST(test_create_from_bytes) +{ + verify("10.1.0.0/16", NULL, + traffic_selector_create_from_bytes(0, TS_IPV4_ADDR_RANGE, + chunk_from_chars(0x0a,0x01,0x00,0x00), 0, + chunk_from_chars(0x0a,0x01,0xff,0xff), 65535)); +} +END_TEST + +START_TEST(test_create_from_subnet) +{ + verify("10.1.0.0/16", NULL, + traffic_selector_create_from_subnet( + host_create_from_string("10.1.0.0", 0), 16, 0, 0, 65535)); +} +END_TEST + + +START_TEST(test_subset) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535); + b = traffic_selector_create_from_cidr("10.1.5.0/24", 0, 0, 65535); + verify("10.1.5.0/24", NULL, a->get_subset(a, b)); + a->destroy(a); + b->destroy(b); +} +END_TEST + +START_TEST(test_subset_port) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("10.0.0.0/8", IPPROTO_TCP, 55, 60); + b = traffic_selector_create_from_cidr("10.2.7.16/30", 0, 0, 65535); + verify("10.2.7.16/30[tcp/55-60]", "10.2.7.16/30[6/55-60]", + a->get_subset(a, b)); + a->destroy(a); + b->destroy(b); +} +END_TEST + +START_TEST(test_subset_equal) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 80, 80); + b = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 80, 80); + verify("10.1.0.0/16[tcp/http]", "10.1.0.0/16[6/80]", a->get_subset(a, b)); + a->destroy(a); + b->destroy(b); +} +END_TEST + +START_TEST(test_subset_nonet) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535); + b = traffic_selector_create_from_cidr("10.2.0.0/16", 0, 0, 65535); + ck_assert(a->get_subset(a, b) == NULL); + a->destroy(a); + b->destroy(b); +} +END_TEST + +START_TEST(test_subset_noport) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 9999); + b = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 10000, 65535); + ck_assert(a->get_subset(a, b) == NULL); + a->destroy(a); + b->destroy(b); +} +END_TEST + +START_TEST(test_subset_noproto) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 0, 65535); + b = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_UDP, 0, 65535); + ck_assert(a->get_subset(a, b) == NULL); + a->destroy(a); + b->destroy(b); +} +END_TEST + +START_TEST(test_subset_nofamily) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535); + b = traffic_selector_create_from_cidr("::/0", 0, 0, 65535); + ck_assert(a->get_subset(a, b) == NULL); + a->destroy(a); + b->destroy(b); +} +END_TEST + +struct { + char *net; + char *host; + bool inc; +} include_tests[] = { + { "0.0.0.0/0", "192.168.1.2", TRUE }, + { "::/0", "fec2::1", TRUE }, + { "fec2::/64", "fec2::afaf", TRUE }, + { "10.1.0.0/16", "10.1.0.1", TRUE }, + { "10.5.6.7/32", "10.5.6.7", TRUE }, + { "0.0.0.0/0", "fec2::1", FALSE }, + { "::/0", "1.2.3.4", FALSE }, + { "10.0.0.0/16", "10.1.0.0", FALSE }, + { "fec2::/64", "fec2:0:0:1::afaf", FALSE }, +}; + +START_TEST(test_includes) +{ + traffic_selector_t *ts; + host_t *h; + + ts = traffic_selector_create_from_cidr(include_tests[_i].net, 0, 0, 65535); + h = host_create_from_string(include_tests[_i].host, 0); + ck_assert(ts->includes(ts, h) == include_tests[_i].inc); + ts->destroy(ts); + h->destroy(h); +} +END_TEST + +struct { + int res; + struct { + char *net; + u_int8_t proto; + u_int16_t from_port; + u_int16_t to_port; + } a, b; +} cmp_tests[] = { + { 0, { "10.0.0.0/8", 0, 0, 65535 }, { "10.0.0.0/8", 0, 0, 65535 }, }, + { 0, { "10.0.0.0/8", 17, 123, 456 }, { "10.0.0.0/8", 17, 123, 456 }, }, + { 0, { "fec2::/64", 0, 0, 65535 }, { "fec2::/64", 0, 0, 65535 }, }, + { 0, { "fec2::/64", 4, 0, 65535 }, { "fec2::/64", 4, 0, 65535 }, }, + + { -1, { "1.0.0.0/8", 0, 0, 65535 }, { "2.0.0.0/8", 0, 0, 65535 }, }, + { 1, { "2.0.0.0/8", 0, 0, 65535 }, { "1.0.0.0/8", 0, 0, 65535 }, }, + { -1, { "1.0.0.0/8", 0, 0, 65535 }, { "1.0.0.0/16", 0, 0, 65535 }, }, + { 1, { "1.0.0.0/16", 0, 0, 65535 }, { "1.0.0.0/8", 0, 0, 65535 }, }, + + { -1, { "10.0.0.0/8", 0, 0, 65535 }, { "fec2::/64", 0, 0, 65535 }, }, + { 1, { "fec2::/64", 0, 0, 65535 }, { "10.0.0.0/8", 0, 0, 65535 }, }, + + { -1, { "10.0.0.0/8", 16, 123, 456 }, { "10.0.0.0/8", 17, 123, 456 }, }, + { 1, { "fec2::/64", 5, 0, 65535 }, { "fec2::/64", 4, 0, 65535 }, }, + + { -1, { "10.0.0.0/8", 17, 111, 456 }, { "10.0.0.0/8", 17, 222, 456 }, }, + { 1, { "fec2::/64", 17, 555, 65535 }, { "fec2::/64", 17, 444, 65535 },}, + + { -1, { "10.0.0.0/8", 17, 55, 65535 }, { "10.0.0.0/8", 17, 55, 666 }, }, + { 1, { "fec2::/64", 17, 55, 111 }, { "fec2::/64", 17, 55, 4567 }, }, + +}; + +START_TEST(test_cmp) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr( + cmp_tests[_i].a.net, cmp_tests[_i].a.proto, + cmp_tests[_i].a.from_port, cmp_tests[_i].a.to_port); + b = traffic_selector_create_from_cidr( + cmp_tests[_i].b.net, cmp_tests[_i].b.proto, + cmp_tests[_i].b.from_port, cmp_tests[_i].b.to_port); + switch (cmp_tests[_i].res) + { + case 0: + ck_assert(traffic_selector_cmp(a, b, NULL) == 0); + break; + case 1: + ck_assert(traffic_selector_cmp(a, b, NULL) > 0); + break; + case -1: + ck_assert(traffic_selector_cmp(a, b, NULL) < 0); + break; + } + a->destroy(a); + b->destroy(b); +} +END_TEST + +Suite *traffic_selector_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("traffic selector"); + + tc = tcase_create("create"); + tcase_add_test(tc, test_create_from_string); + tcase_add_test(tc, test_create_from_cidr); + tcase_add_test(tc, test_create_from_bytes); + tcase_add_test(tc, test_create_from_subnet); + suite_add_tcase(s, tc); + + tc = tcase_create("subset"); + tcase_add_test(tc, test_subset); + tcase_add_test(tc, test_subset_port); + tcase_add_test(tc, test_subset_equal); + tcase_add_test(tc, test_subset_nonet); + tcase_add_test(tc, test_subset_noport); + tcase_add_test(tc, test_subset_noproto); + tcase_add_test(tc, test_subset_nofamily); + suite_add_tcase(s, tc); + + tc = tcase_create("includes"); + tcase_add_loop_test(tc, test_includes, 0, countof(include_tests)); + suite_add_tcase(s, tc); + + tc = tcase_create("cmp"); + tcase_add_loop_test(tc, test_cmp, 0, countof(cmp_tests)); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/tests/suites/test_utils.c b/src/libstrongswan/tests/suites/test_utils.c index abca4620e..85a854456 100644 --- a/src/libstrongswan/tests/suites/test_utils.c +++ b/src/libstrongswan/tests/suites/test_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Tobias Brunner + * Copyright (C) 2013-2015 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -18,6 +18,7 @@ #include <library.h> #include <utils/utils.h> #include <ipsec/ipsec_types.h> +#include <credentials/keys/public_key.h> #include <time.h> @@ -695,6 +696,44 @@ START_TEST(test_mark_from_string) } END_TEST +/******************************************************************************* + * signature_schemes_for_key + */ + +static struct { + key_type_t type; + int size; + signature_scheme_t expected[4]; +} scheme_data[] = { + {KEY_RSA, 1024, { SIGN_RSA_EMSA_PKCS1_SHA256, SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }}, + {KEY_RSA, 2048, { SIGN_RSA_EMSA_PKCS1_SHA256, SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }}, + {KEY_RSA, 4096, { SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }}, + {KEY_RSA, 8192, { SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }}, + {KEY_ECDSA, 256, { SIGN_ECDSA_WITH_SHA256_DER, SIGN_ECDSA_WITH_SHA384_DER, SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }}, + {KEY_ECDSA, 384, { SIGN_ECDSA_WITH_SHA384_DER, SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }}, + {KEY_ECDSA, 512, { SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }}, + {KEY_BLISS, 128, { SIGN_BLISS_WITH_SHA256, SIGN_BLISS_WITH_SHA384, SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }}, + {KEY_BLISS, 192, { SIGN_BLISS_WITH_SHA384, SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }}, + {KEY_BLISS, 256, { SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }}, +}; + +START_TEST(test_signature_schemes_for_key) +{ + enumerator_t *enumerator; + signature_scheme_t scheme; + int i; + + enumerator = signature_schemes_for_key(scheme_data[_i].type, scheme_data[_i].size); + for (i = 0; scheme_data[_i].expected[i] != SIGN_UNKNOWN; i++) + { + ck_assert(enumerator->enumerate(enumerator, &scheme)); + ck_assert_int_eq(scheme_data[_i].expected[i], scheme); + } + ck_assert(!enumerator->enumerate(enumerator, &scheme)); + enumerator->destroy(enumerator); +} +END_TEST + Suite *utils_suite_create() { Suite *s; @@ -777,5 +816,9 @@ Suite *utils_suite_create() tcase_add_loop_test(tc, test_mark_from_string, 0, countof(mark_data)); suite_add_tcase(s, tc); + tc = tcase_create("signature_schemes_for_key"); + tcase_add_loop_test(tc, test_signature_schemes_for_key, 0, countof(scheme_data)); + suite_add_tcase(s, tc); + return s; } |