From bfafb926a3847964eb2081b94c3e195160f10211 Mon Sep 17 00:00:00 2001 From: Trevor Bentley Date: Wed, 12 Jul 2017 13:19:15 +0200 Subject: [PATCH] Added tests for authenticate and reset. Fixed bug in reset (always returned success). --- lib/tests/util.c | 84 ++++++++++++++++++++++++++++++++++++++++++------ lib/util.c | 4 +-- 2 files changed, 76 insertions(+), 12 deletions(-) diff --git a/lib/tests/util.c b/lib/tests/util.c index f8049d2..4409333 100644 --- a/lib/tests/util.c +++ b/lib/tests/util.c @@ -38,6 +38,8 @@ #include +int confirm_destruction(void); + ykpiv_state *g_state; const uint8_t g_cert[] = { "0123456789ABCDEFGHIK0123456789ABCDEFGHIK0123456789ABCDEFGHIK0123456789ABCDEFGHIK" @@ -49,22 +51,18 @@ const uint8_t g_cert[] = { void setup(void) { ykpiv_rc res; - const char *mgm_key = "010203040506070801020304050607080102030405060708"; - unsigned char key[24]; - size_t key_len = sizeof(key); + + // Require user confirmation to continue, since this test suite will clear + // any data stored on connected keys. + ck_assert(confirm_destruction()); res = ykpiv_init(&g_state, true); ck_assert_int_eq(res, YKPIV_OK); res = ykpiv_connect(g_state, NULL); ck_assert_int_eq(res, YKPIV_OK); - - res = ykpiv_hex_decode(mgm_key, strlen(mgm_key), key, &key_len); - ck_assert_int_eq(res, YKPIV_OK); - - res = ykpiv_authenticate(g_state, key); - ck_assert_int_eq(res, YKPIV_OK); } + void teardown(void) { ykpiv_done(g_state); } @@ -173,10 +171,68 @@ START_TEST(test_read_write_msroots) { } END_TEST -START_TEST(test_reset) { +START_TEST(test_authenticate) { + ykpiv_rc res; + const char *mgm_key = "010203040506070801020304050607080102030405060708"; + unsigned char key[24]; + size_t key_len = sizeof(key); + + res = ykpiv_hex_decode(mgm_key, strlen(mgm_key), key, &key_len); + ck_assert_int_eq(res, YKPIV_OK); + + res = ykpiv_authenticate(g_state, key); + ck_assert_int_eq(res, YKPIV_OK); } END_TEST +START_TEST(test_reset) { + ykpiv_rc res; + int tries = 100; + int i; + + while (tries) { + res = ykpiv_verify(g_state, "AAAAAA", &tries); + if (res == YKPIV_PIN_LOCKED) + break; + ck_assert_int_eq(res, YKPIV_WRONG_PIN); + } + tries = 100; + while (tries) { + res = ykpiv_change_puk(g_state, "AAAAAAAA", 8, "AAAAAAAA", 8, &tries); + if (res == YKPIV_PIN_LOCKED) + break; + ck_assert_int_eq(res, YKPIV_WRONG_PIN); + } + res = ykpiv_util_reset(g_state); + ck_assert_int_eq(res, YKPIV_OK); +} +END_TEST + +int confirm_destruction(void) { + char verify[16]; + + // Use dprintf() to write directly to stdout, since automake eats the standard stdout/stderr pointers. + dprintf(0, "******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* *******\n"); + dprintf(0, "WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n"); + dprintf(0, "WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n"); + dprintf(0, "\n"); + + dprintf(0, "******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* *******\n"); + dprintf(0, "\n"); + dprintf(0, " ALL DATA WILL BE ERASED ON CONNECTED YUBIKEYS \n"); + dprintf(0, "\n"); + dprintf(0, "******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* *******\n"); + dprintf(0, "\n"); + + dprintf(0, "WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n"); + dprintf(0, "WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n"); + dprintf(0, "******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* ******* *******\n"); + dprintf(0, "\n"); + dprintf(0, "Are you SURE you wish to proceed? If so, type 'CONFIRM': "); + fgets(verify, 32, stdin); + return strncmp(verify, "CONFIRM", 7) == 0; +} + Suite *test_suite(void) { Suite *s; TCase *tc; @@ -185,6 +241,13 @@ Suite *test_suite(void) { tc = tcase_create("util"); #ifdef HW_TESTS tcase_add_unchecked_fixture(tc, setup, teardown); + + // Reset first. Tests run serially, and depend on a clean slate. + tcase_add_test(tc, test_reset); + + // Authenticate after reset. + tcase_add_test(tc, test_authenticate); + tcase_add_test(tc, test_devicemodel); tcase_add_test(tc, test_get_set_cardid); tcase_add_test(tc, test_read_write_list_delete_cert); @@ -207,5 +270,6 @@ int main(void) srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/lib/util.c b/lib/util.c index dd58add..b431132 100644 --- a/lib/util.c +++ b/lib/util.c @@ -878,10 +878,10 @@ ykpiv_rc ykpiv_util_reset(ykpiv_state *state) { /* note: the reset function is only available when both pins are blocked. */ res = ykpiv_transfer_data(state, templ, NULL, 0, data, &recv_len, &sw); - if (SW_SUCCESS == sw) { + if (YKPIV_OK == res && SW_SUCCESS == sw) { return YKPIV_OK; } - return res; + return YKPIV_GENERIC_ERROR; } static int _slot2object(uint8_t slot) {