From 42446e1a384d3391e4240afe349c34958e5fabed Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Fri, 5 Aug 2016 10:39:05 +0200 Subject: Support writing token id to OTP slots in API Signed-off-by: Szczepan Zalega --- NK_C_API.cc | 10 ++++++---- NK_C_API.h | 6 ++++-- NitrokeyManager.cc | 16 +++++++++------- include/NitrokeyManager.h | 8 ++++---- unittest/test_bindings.py | 10 +++++----- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/NK_C_API.cc b/NK_C_API.cc index 049e200..c576fb8 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -225,11 +225,12 @@ extern int NK_erase_totp_slot(uint8_t slot_number, const char *temporary_passwor } extern int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint8_t hotp_counter, - bool use_8_digits, bool use_enter, bool use_tokenID, const char *temporary_password) { + bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, + const char *temporary_password) { NK_last_command_status = 0; auto m = NitrokeyManager::instance(); try { - m->write_HOTP_slot(slot_number, slot_name, secret, hotp_counter, use_8_digits, use_enter, use_tokenID, + m->write_HOTP_slot(slot_number, slot_name, secret, hotp_counter, use_8_digits, use_enter, use_tokenID, token_ID, temporary_password); } catch (CommandFailedException & commandFailedException){ @@ -240,11 +241,12 @@ extern int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const } extern int NK_write_totp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, - bool use_8_digits, bool use_enter, bool use_tokenID, const char *temporary_password) { + bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, + const char *temporary_password) { NK_last_command_status = 0; auto m = NitrokeyManager::instance(); try { - m->write_TOTP_slot(slot_number, slot_name, secret, time_window, use_8_digits, use_enter, use_tokenID, + m->write_TOTP_slot(slot_number, slot_name, secret, time_window, use_8_digits, use_enter, use_tokenID, token_ID, temporary_password); } catch (CommandFailedException & commandFailedException){ diff --git a/NK_C_API.h b/NK_C_API.h index 7610d29..6f04b74 100644 --- a/NK_C_API.h +++ b/NK_C_API.h @@ -151,7 +151,8 @@ extern int NK_erase_totp_slot(uint8_t slot_number, const char *temporary_passwor * @return command processing error code */ extern int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint8_t hotp_counter, - bool use_8_digits, bool use_enter, bool use_tokenID, const char *temporary_password); + bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, + const char *temporary_password); /** * Write TOTP slot data to the device @@ -164,7 +165,8 @@ extern int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const * @return command processing error code */ extern int NK_write_totp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, - bool use_8_digits, bool use_enter, bool use_tokenID, const char *temporary_password); + bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, + const char *temporary_password); /** * Get HOTP code from the device diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index e56f03f..84a769b 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -6,6 +6,7 @@ namespace nitrokey{ template void strcpyT(T& dest, const char* src){ + assert(src != nullptr); const int s = sizeof dest; assert(strlen(src) <= s); strncpy((char*) &dest, src, s); @@ -138,9 +139,9 @@ namespace nitrokey{ } - bool NitrokeyManager::write_HOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, - uint8_t hotp_counter, bool use_8_digits, - bool use_enter, bool use_tokenID, const char *temporary_password) { + bool NitrokeyManager::write_HOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint8_t hotp_counter, + bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, + const char *temporary_password) { assert(is_valid_hotp_slot_number(slot_number)); assert(strlen(secret)==20); //160 bits assert(strlen(slot_name)<=15); @@ -150,6 +151,7 @@ namespace nitrokey{ payload.slot_number = slot_number; strcpyT(payload.slot_secret, secret); strcpyT(payload.slot_name, slot_name); + strcpyT(payload.slot_token_id, token_ID); payload.slot_counter = hotp_counter; payload.use_8_digits = use_8_digits; payload.use_enter = use_enter; @@ -164,9 +166,9 @@ namespace nitrokey{ return true; } - bool NitrokeyManager::write_TOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, - uint16_t time_window, bool use_8_digits, - bool use_enter, bool use_tokenID, const char *temporary_password) { + bool NitrokeyManager::write_TOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, + bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, + const char *temporary_password) { auto payload = get_payload(); assert(is_valid_totp_slot_number(slot_number)); assert(strlen(secret) == sizeof payload.slot_secret); //160 bits @@ -176,11 +178,11 @@ namespace nitrokey{ payload.slot_number = slot_number; strcpyT(payload.slot_secret, secret); strcpyT(payload.slot_name, slot_name); + strcpyT(payload.slot_token_id, token_ID); payload.slot_interval = time_window; //FIXME naming payload.use_8_digits = use_8_digits; payload.use_enter = use_enter; payload.use_tokenID = use_tokenID; - payload.slot_token_id; //FIXME add slot token id to function headers auto auth = get_payload(); strcpyT(auth.temporary_password, temporary_password); diff --git a/include/NitrokeyManager.h b/include/NitrokeyManager.h index 5f89614..4dc6a81 100644 --- a/include/NitrokeyManager.h +++ b/include/NitrokeyManager.h @@ -22,11 +22,11 @@ namespace nitrokey { bool first_authenticate(const char *pin, const char *temporary_password); bool write_HOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint8_t hotp_counter, - bool use_8_digits, - bool use_enter, bool use_tokenID, const char *temporary_password); + bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, + const char *temporary_password); bool write_TOTP_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, - bool use_8_digits, - bool use_enter, bool use_tokenID, const char *temporary_password); + bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, + const char *temporary_password); uint32_t get_HOTP_code(uint8_t slot_number, const char *user_temporary_password); uint32_t get_TOTP_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval, const char *user_temporary_password); diff --git a/unittest/test_bindings.py b/unittest/test_bindings.py index 0f8c0ff..7093eda 100644 --- a/unittest/test_bindings.py +++ b/unittest/test_bindings.py @@ -230,7 +230,7 @@ def test_user_auth(C): def check_RFC_codes(C, func, prep=None): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, False, False, False, + assert C.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, False, False, False, "", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK test_data = [ 755224, 287082, 359152, 969429, 338314, 254676, 287922, 162583, 399871, 520489, @@ -248,7 +248,7 @@ def test_HOTP_RFC_pin_protection(C): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(True, True, True, True, False, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, False, False, False, + assert C.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, False, False, False, "", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK # check_RFC_codes(C, lambda x: C.NK_get_hotp_code_PIN(x, DefaultPasswords.USER_TEMP), lambda: C.NK_user_authenticate(DefaultPasswords.USER, DefaultPasswords.USER_TEMP)) assert C.NK_user_authenticate(DefaultPasswords.USER, DefaultPasswords.USER_TEMP) == DeviceErrorCode.STATUS_OK @@ -263,7 +263,7 @@ def test_HOTP_RFC_no_pin_protection_8digits(C): def test_HOTP_RFC_no_pin_protection(C): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, False, False, False, + assert C.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, False, False, False, "", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(True, True, True, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK @@ -276,7 +276,7 @@ def test_TOTP_RFC_no_pin_protection(C): assert C.NK_write_config(True, True, True, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK # test according to https://tools.ietf.org/html/rfc6238#appendix-B assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_totp_slot(1, 'python_test', RFC_SECRET, 30, True, False, False, + assert C.NK_write_totp_slot(1, 'python_test', RFC_SECRET, 30, True, False, False, "", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK test_data = [ (59, 1, 94287082), @@ -328,7 +328,7 @@ def test_get_OTP_codes(C): def test_get_code_user_authorize(C): C.NK_set_debug(True) assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_totp_slot(0, 'python_otp_auth', RFC_SECRET, 30, True, False, False, + assert C.NK_write_totp_slot(0, 'python_otp_auth', RFC_SECRET, 30, True, False, False, "", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK # enable PIN protection of OTP codes with write_config # TODO create convinience function on C API side to enable/disable OTP USER_PIN protection -- cgit v1.2.1