diff options
-rw-r--r-- | NK_C_API.cc | 3 | ||||
-rw-r--r-- | NK_C_API.h | 12 | ||||
-rw-r--r-- | NitrokeyManager.cc | 3 | ||||
-rw-r--r-- | include/NitrokeyManager.h | 2 | ||||
-rw-r--r-- | include/stick10_commands.h | 26 | ||||
-rw-r--r-- | unittest/test_bindings.py | 23 |
6 files changed, 37 insertions, 32 deletions
diff --git a/NK_C_API.cc b/NK_C_API.cc index c576fb8..d2aa38a 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -130,7 +130,8 @@ extern int NK_unlock_user_password(const char *admin_password, const char *new_u }); } -extern int NK_write_config(bool numlock, bool capslock, bool scrolllock, bool enable_user_password, bool delete_user_password, +extern int NK_write_config(uint8_t numlock, uint8_t capslock, uint8_t scrolllock, bool enable_user_password, + bool delete_user_password, const char *admin_temporary_password) { auto m = NitrokeyManager::instance(); return get_without_result( [&](){ @@ -85,19 +85,21 @@ extern int NK_unlock_user_password(const char *admin_password, const char *new_u /** * Write general config to the device - * @param numlock set True to send OTP code after double pressing numlock - * @param capslock set True to send OTP code after double pressing capslock - * @param scrolllock set True to send OTP code after double pressing scrolllock + * @param numlock set value in range [0-1] to send HOTP code from slot 'numlock' after double pressing numlock + * or outside the range to disable this function + * @param capslock similar to numlock but with capslock + * @param scrolllock similar to numlock but with scrolllock * @param enable_user_password set True to enable OTP PIN protection (request PIN each OTP code request) * @param delete_user_password set True to disable OTP PIN protection (request PIN each OTP code request) * @param admin_temporary_password current admin temporary password * @return command processing error code */ -extern int NK_write_config(bool numlock, bool capslock, bool scrolllock, +extern int NK_write_config(uint8_t numlock, uint8_t capslock, uint8_t scrolllock, bool enable_user_password, bool delete_user_password, const char *admin_temporary_password); /** - * Get currently set config - status of function Numlock/Capslock/Scrollock OTP sending and PIN protected OTP + * Get currently set config - status of function Numlock/Capslock/Scrollock OTP sending and is enabled PIN protected OTP + * @see NK_write_config * @return uint8_t general_config[5]: * uint8_t numlock; uint8_t capslock; diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 84a769b..ed9c7b4 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -382,7 +382,8 @@ namespace nitrokey{ } - void NitrokeyManager::write_config(bool numlock, bool capslock, bool scrolllock, bool enable_user_password, bool delete_user_password, const char *admin_temporary_password) { + void NitrokeyManager::write_config(uint8_t numlock, uint8_t capslock, uint8_t scrolllock, bool enable_user_password, + bool delete_user_password, const char *admin_temporary_password) { auto p = get_payload<WriteGeneralConfig>(); p.numlock = (uint8_t) numlock; p.capslock = (uint8_t) capslock; diff --git a/include/NitrokeyManager.h b/include/NitrokeyManager.h index 4dc6a81..7bc2673 100644 --- a/include/NitrokeyManager.h +++ b/include/NitrokeyManager.h @@ -72,7 +72,7 @@ namespace nitrokey { void unlock_user_password(const char *admin_password, const char *new_user_password); - void write_config(bool numlock, bool capslock, bool scrolllock, bool enable_user_password, + void write_config(uint8_t numlock, uint8_t capslock, uint8_t scrolllock, bool enable_user_password, bool delete_user_password, const char *admin_temporary_password); vector<uint8_t> read_config(); diff --git a/include/stick10_commands.h b/include/stick10_commands.h index f7813c4..2d52352 100644 --- a/include/stick10_commands.h +++ b/include/stick10_commands.h @@ -299,14 +299,14 @@ class GetStatus : Command<CommandID::GET_STATUS> { union { uint8_t general_config[5]; struct{ - uint8_t numlock; - uint8_t capslock; - uint8_t scrolllock; + uint8_t numlock; /** 0-1: HOTP slot number from which the code will be get on double press, other value - function disabled */ + uint8_t capslock; /** same as numlock */ + uint8_t scrolllock; /** same as numlock */ uint8_t enable_user_password; uint8_t delete_user_password; }; }; - bool isValid() const { return true; } + bool isValid() const { return enable_user_password!=delete_user_password; } std::string dissect() const { std::stringstream ss; @@ -317,9 +317,9 @@ class GetStatus : Command<CommandID::GET_STATUS> { ss << "general_config:\t" << ::nitrokey::misc::hexdump((const char *)(general_config), sizeof general_config); - ss << "numlock:\t" << (bool)numlock << std::endl; - ss << "capslock:\t" << (bool)capslock << std::endl; - ss << "scrolllock:\t" << (bool)scrolllock << std::endl; + ss << "numlock:\t" << (uint8_t)numlock << std::endl; + ss << "capslock:\t" << (uint8_t)capslock << std::endl; + ss << "scrolllock:\t" << (uint8_t)scrolllock << std::endl; ss << "enable_user_password:\t" << (bool) enable_user_password << std::endl; ss << "delete_user_password:\t" << (bool) delete_user_password << std::endl; @@ -587,18 +587,18 @@ class WriteGeneralConfig : Command<CommandID::WRITE_CONFIG> { union{ uint8_t config[5]; struct{ - uint8_t numlock; - uint8_t capslock; - uint8_t scrolllock; + uint8_t numlock; /** 0-1: HOTP slot number from which the code will be get on double press, other value - function disabled */ + uint8_t capslock; /** same as numlock */ + uint8_t scrolllock; /** same as numlock */ uint8_t enable_user_password; uint8_t delete_user_password; }; }; std::string dissect() const { std::stringstream ss; - ss << "numlock:\t" << (bool)numlock << std::endl; - ss << "capslock:\t" << (bool)capslock << std::endl; - ss << "scrolllock:\t" << (bool)scrolllock << std::endl; + ss << "numlock:\t" << (uint8_t)numlock << std::endl; + ss << "capslock:\t" << (uint8_t)capslock << std::endl; + ss << "scrolllock:\t" << (uint8_t)scrolllock << std::endl; ss << "enable_user_password:\t" << (bool) enable_user_password << std::endl; ss << "delete_user_password:\t" << (bool) delete_user_password << std::endl; return ss.str(); diff --git a/unittest/test_bindings.py b/unittest/test_bindings.py index 1fddba7..205fc22 100644 --- a/unittest/test_bindings.py +++ b/unittest/test_bindings.py @@ -115,7 +115,7 @@ def test_password_safe_slot_status(C): assert is_slot_programmed[1] == 1 -@pytest.mark.skip(reason="issue to register, skipping for now") +@pytest.mark.xfail(run=False, reason="issue to register, skipping for now") def test_issue_device_locks_on_second_key_generation_in_sequence(C): assert C.NK_build_aes_key(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK assert C.NK_build_aes_key(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK @@ -251,7 +251,7 @@ def check_HOTP_RFC_codes(C, func, prep=None, use_8_digits=False): @pytest.mark.parametrize("use_pin_protection", [False, True, ]) def test_HOTP_RFC_8digits_pin(C, use_8_digits, use_pin_protection): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_config(True, True, True, use_pin_protection, not use_pin_protection, + assert C.NK_write_config(255, 255, 255, use_pin_protection, not use_pin_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK if use_pin_protection: check_HOTP_RFC_codes(C, @@ -265,7 +265,7 @@ def test_HOTP_RFC_8digits_pin(C, use_8_digits, use_pin_protection): @pytest.mark.parametrize("PIN_protection", [False, True, ]) def test_TOTP_RFC(C, PIN_protection): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_config(True, True, True, PIN_protection, not PIN_protection, + assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection, 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 @@ -318,7 +318,8 @@ def test_get_slot_names(C): def test_get_OTP_codes(C): - C.NK_set_debug(True) + assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK + assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_erase_hotp_slot(0, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK @@ -342,13 +343,13 @@ def test_get_code_user_authorize(C): # enable PIN protection of OTP codes with write_config # TODO create convinience function on C API side to enable/disable OTP USER_PIN protection 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_write_config(255, 255, 255, True, False, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code = C.NK_get_totp_code(0, 0, 0, 0) assert code == 0 assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_NOT_AUTHORIZED # disable PIN protection with write_config 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 + assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code = C.NK_get_totp_code(0, 0, 0, 0) assert code != 0 assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK @@ -363,18 +364,18 @@ def cast_pointer_to_tuple(obj, typen, len): def test_read_write_config(C): C.NK_set_debug(True) - # let's set sample config with pin protection and disabled capslock + # let's set sample config with pin protection and disabled scrolllock assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_config(True, False, True, True, False, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK + assert C.NK_write_config(0, 1, 2, True, False, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK config_raw_data = C.NK_read_config() assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK config = cast_pointer_to_tuple(config_raw_data, 'uint8_t', 5) - assert config == (True, False, True, True, False) + assert config == (0, 1, 2, True, False) # restore defaults and check 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 + assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK config_raw_data = C.NK_read_config() assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK config = cast_pointer_to_tuple(config_raw_data, 'uint8_t', 5) - assert config == (True, True, True, False, True) + assert config == (255, 255, 255, False, True) |