diff options
-rw-r--r-- | NK_C_API.cc | 36 | ||||
-rw-r--r-- | NK_C_API.h | 11 | ||||
-rw-r--r-- | NitrokeyManager.cc | 26 | ||||
-rw-r--r-- | include/NitrokeyManager.h | 5 | ||||
-rw-r--r-- | include/stick10_commands.h | 2 | ||||
-rw-r--r-- | unittest/test_bindings.py | 21 |
6 files changed, 91 insertions, 10 deletions
diff --git a/NK_C_API.cc b/NK_C_API.cc index c2e7df0..f01f0f5 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -1,11 +1,21 @@ #include <cstring> #include "NK_C_API.h" -#include <functional> using namespace nitrokey; static uint8_t NK_last_command_status = 0; template <typename T> +const char* get_with_string_result(T func){ + try { + return func(); + } + catch (CommandFailedException & commandFailedException){ + NK_last_command_status = commandFailedException.last_command_status; + return ""; + } +} + +template <typename T> auto get_with_result(T func){ try { return func(); @@ -264,6 +274,30 @@ extern int NK_lock_device(){ }); } +extern const char *NK_get_password_safe_slot_name(uint8_t slot_number, const char *temporary_password) { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&](){ + return m->get_password_safe_slot_name(slot_number, temporary_password); + }); +} + +extern const char *NK_get_password_safe_slot_login(uint8_t slot_number) { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&](){ + return m->get_password_safe_slot_login(slot_number); + }); +} +extern const char *NK_get_password_safe_slot_password(uint8_t slot_number) { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&](){ + return m->get_password_safe_slot_password(slot_number); + }); +} +extern int NK_write_password_safe_slot(){ + auto m = NitrokeyManager::instance(); + //TODO +} + } @@ -13,6 +13,9 @@ extern void NK_set_debug(bool state); extern int NK_login(const char *admin_pin, const char *temporary_password); extern int NK_logout(); extern const char * NK_status(); +extern uint8_t NK_get_last_command_status(); +extern int NK_lock_device(); +//otp extern const char * NK_get_totp_slot_name(uint8_t slot_number); extern const char * NK_get_hotp_slot_name(uint8_t slot_number); extern int NK_erase_slot(uint8_t slot_number); @@ -22,14 +25,18 @@ extern uint32_t NK_get_hotp_code(uint8_t slot_number); extern uint32_t NK_get_totp_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, uint8_t last_interval); extern int NK_totp_set_time(uint64_t time); extern int NK_totp_get_time(); -extern uint8_t NK_get_last_command_status(); +//passwords extern int NK_change_admin_PIN(char *current_PIN, char *new_PIN); extern int NK_change_user_PIN(char *current_PIN, char *new_PIN); extern uint8_t NK_get_user_retry_count(); extern uint8_t NK_get_admin_retry_count(); +//password safe extern int NK_enable_password_safe(const char *user_pin); extern int NK_get_password_safe_slot_status(); -extern int NK_lock_device(); +extern const char *NK_get_password_safe_slot_name(uint8_t slot_number, const char *temporary_password); +extern const char *NK_get_password_safe_slot_login(uint8_t slot_number); +extern const char *NK_get_password_safe_slot_password(uint8_t slot_number); +extern int NK_write_password_safe_slot(); } diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 15f09b8..8f5db6f 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -236,5 +236,31 @@ namespace nitrokey{ LockDevice::CommandTransaction::run(*device); } + const char *NitrokeyManager::get_password_safe_slot_name(uint8_t slot_number, const char *temporary_password) { + auto p = get_payload<GetPasswordSafeSlotName>(); + p.slot_number = slot_number; + + auto auth = get_payload<UserAuthorize>(); + strcpyT(auth.temporary_password, temporary_password); + auth.crc_to_authorize = GetPasswordSafeSlotName::CommandTransaction::getCRC(p); + UserAuthorize::CommandTransaction::run(*device, auth); + + auto response = GetPasswordSafeSlotName::CommandTransaction::run(*device, p); + return strdup((const char *) response.slot_name); + } + + const char *NitrokeyManager::get_password_safe_slot_login(uint8_t slot_number) { + auto p = get_payload<GetPasswordSafeSlotLogin>(); + p.slot_number = slot_number; + auto response = GetPasswordSafeSlotLogin::CommandTransaction::run(*device, p); + return strdup((const char *) response.slot_login); + } + + const char *NitrokeyManager::get_password_safe_slot_password(uint8_t slot_number) { + auto p = get_payload<GetPasswordSafeSlotPassword>(); + p.slot_number = slot_number; + auto response = GetPasswordSafeSlotPassword::CommandTransaction::run(*device, p); + return strdup((const char *) response.slot_password); + } }
\ No newline at end of file diff --git a/include/NitrokeyManager.h b/include/NitrokeyManager.h index ecc397d..d9844c9 100644 --- a/include/NitrokeyManager.h +++ b/include/NitrokeyManager.h @@ -49,6 +49,10 @@ namespace nitrokey { void lock_device(); + const char *get_password_safe_slot_name(uint8_t slot_number, const char *temporary_password); + const char *get_password_safe_slot_password(uint8_t slot_number); + const char *get_password_safe_slot_login(uint8_t slot_number); + private: NitrokeyManager(); ~NitrokeyManager(); @@ -63,7 +67,6 @@ namespace nitrokey { uint8_t get_internal_slot_number_for_totp(uint8_t slot_number) const; bool erase_slot(uint8_t slot_number); uint8_t *get_slot_name(uint8_t slot_number) const; - }; } diff --git a/include/stick10_commands.h b/include/stick10_commands.h index 31041d0..d350044 100644 --- a/include/stick10_commands.h +++ b/include/stick10_commands.h @@ -596,7 +596,7 @@ class Authorize : Command<CommandID::AUTHORIZE> { class UserAuthorize : Command<CommandID::USER_AUTHORIZE> { public: struct CommandPayload { - uint8_t crc_to_authorize[4]; + uint64_t crc_to_authorize; uint8_t temporary_password[25]; std::string dissect() const { std::stringstream ss; diff --git a/unittest/test_bindings.py b/unittest/test_bindings.py index ec7608e..f5d5cf7 100644 --- a/unittest/test_bindings.py +++ b/unittest/test_bindings.py @@ -2,8 +2,10 @@ import pytest import cffi from enum import Enum -RFC_SECRET = '12345678901234567890' +ffi = cffi.FFI() +gs = ffi.string +RFC_SECRET = '12345678901234567890' class DefaultPasswords(Enum): ADMIN = '12345678' @@ -14,10 +16,7 @@ class DeviceErrorCode(Enum): STATUS_OK = 0 NOT_PROGRAMMED = 3 WRONG_PASSWORD = 4 - - -ffi = cffi.FFI() - + STATUS_NOT_AUTHORIZED = 5 @pytest.fixture(scope="module") def C(request): @@ -55,6 +54,18 @@ def test_enable_password_safe(C): assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK +def test_get_password_safe_slot_name(C): + C.NK_set_debug(True) + assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK + assert gs(C.NK_get_password_safe_slot_name(0, '123123123')) == '' + assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_NOT_AUTHORIZED + + assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK + assert gs(C.NK_get_password_safe_slot_name(0, '123123123')) == '1' + assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK + C.NK_set_debug(False) + + def test_password_safe_slot_status(C): C.NK_set_debug(True) assert C.NK_get_password_safe_slot_status() == DeviceErrorCode.STATUS_OK |