diff --git a/NK_C_API.cc b/NK_C_API.cc index c84e402..7fc784e 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -336,6 +336,38 @@ extern "C" { }); } + NK_C_API uint8_t NK_get_pws_slot_count() { + return NitrokeyManager::instance()->get_pws_slot_count(); + } + + NK_C_API size_t NK_get_pws_name_length() { + return NitrokeyManager::instance()->get_pws_name_length(); + } + + NK_C_API size_t NK_get_pws_login_length() { + return NitrokeyManager::instance()->get_pws_login_length(); + } + + NK_C_API size_t NK_get_pws_password_length() { + return NitrokeyManager::instance()->get_pws_password_length(); + } + + NK_C_API uint8_t NK_get_totp_slot_count() { + return NitrokeyManager::instance()->get_totp_slot_count(); + } + + NK_C_API uint8_t NK_get_hotp_slot_count() { + return NitrokeyManager::instance()->get_hotp_slot_count(); + } + + NK_C_API size_t NK_get_otp_name_length() { + return NitrokeyManager::instance()->get_otp_name_length(); + } + + NK_C_API size_t NK_get_otp_secret_length() { + return NitrokeyManager::instance()->get_otp_secret_length(); + } + NK_C_API char * NK_get_hotp_code(uint8_t slot_number) { return NK_get_hotp_code_PIN(slot_number, ""); } diff --git a/NK_C_API.h b/NK_C_API.h index 275f272..c2a6555 100644 --- a/NK_C_API.h +++ b/NK_C_API.h @@ -23,6 +23,7 @@ #define LIBNITROKEY_NK_C_API_H #include +#include #include #include "deprecated.h" @@ -527,6 +528,56 @@ extern "C" { */ NK_C_API int NK_read_config_struct(struct NK_config* out); + // OTP and PWS properties + + /** + * Returns the number of PWS slots provided by the connected device or + * zero if no device is connected. + */ + NK_C_API uint8_t NK_get_pws_slot_count(); + + /** + * Returns the maximum length of a PWS slot name in bytes for the + * connected device or zero if no device is connected. + */ + NK_C_API size_t NK_get_pws_name_length(); + + /** + * Returns the maximum length of a PWS login in bytes for the connected + * device or zero if no device is connected. + */ + NK_C_API size_t NK_get_pws_login_length(); + + /** + * Returns the maximum length of a PWS password in bytes for the + * connected device or zero if no device is connected. + */ + NK_C_API size_t NK_get_pws_password_length(); + + /** + * Returns the number of TOTP slots provided by the connected device or + * zero if no device is connected. + */ + NK_C_API uint8_t NK_get_totp_slot_count(); + + /** + * Returns the number of HOTP slots provided by the connected device or + * zero if no device is connected. + */ + NK_C_API uint8_t NK_get_hotp_slot_count(); + + /** + * Returns the maximum length of an OTP slot name in bytes for the + * connected device or zero if no device is connected. + */ + NK_C_API size_t NK_get_otp_name_length(); + + /** + * Returns the maximum length of an OTP secret in bytes for the + * connected device or zero if no device is connected. + */ + NK_C_API size_t NK_get_otp_secret_length(); + //OTP /** diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 80b3537..5b685bb 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -390,6 +390,69 @@ using nitrokey::misc::strcpyT; } } + uint8_t NitrokeyManager::get_pws_slot_count() { + if (device == nullptr) { + return 0; + } else { + return PWS_SLOT_COUNT; + } + } + + size_t NitrokeyManager::get_pws_name_length() { + if (device == nullptr) { + return 0; + } else { + return PWS_SLOTNAME_LENGTH; + } + } + + size_t NitrokeyManager::get_pws_login_length() { + if (device == nullptr) { + return 0; + } else { + return PWS_LOGINNAME_LENGTH; + } + } + + size_t NitrokeyManager::get_pws_password_length() { + if (device == nullptr) { + return 0; + } else { + return PWS_PASSWORD_LENGTH; + } + } + + uint8_t NitrokeyManager::get_totp_slot_count() { + if (device == nullptr) { + return 0; + } else { + return 15; + } + } + + uint8_t NitrokeyManager::get_hotp_slot_count() { + if (device == nullptr) { + return 0; + } else { + return 3; + } + } + + size_t NitrokeyManager::get_otp_name_length() { + if (device == nullptr) { + return 0; + } else { + return 15; + } + } + + size_t NitrokeyManager::get_otp_secret_length() { + if (device == nullptr) { + return 0; + } else { + return 40; + } + } string NitrokeyManager::get_serial_number() { try { diff --git a/libnitrokey/NitrokeyManager.h b/libnitrokey/NitrokeyManager.h index cb7cfce..e660f36 100644 --- a/libnitrokey/NitrokeyManager.h +++ b/libnitrokey/NitrokeyManager.h @@ -28,6 +28,7 @@ #include "stick10_commands.h" #include "stick10_commands_0.8.h" #include "stick20_commands.h" +#include #include #include #include @@ -64,6 +65,54 @@ char * strndup(const char* str, size_t maxlen); stick10::ReadSlot::ResponsePayload get_TOTP_slot_data(const uint8_t slot_number); stick10::ReadSlot::ResponsePayload get_HOTP_slot_data(const uint8_t slot_number); + /** + * Returns the number of PWS slots provided by the connected device or + * zero if no device is connected. + */ + uint8_t get_pws_slot_count(); + + /** + * Returns the maximum length of a PWS slot name in bytes for the + * connected device or zero if no device is connected. + */ + size_t get_pws_name_length(); + + /** + * Returns the maximum length of a PWS login in bytes for the connected + * device or zero if no device is connected. + */ + size_t get_pws_login_length(); + + /** + * Returns the maximum length of a PWS password in bytes for the + * connected device or zero if no device is connected. + */ + size_t get_pws_password_length(); + + /** + * Returns the number of TOTP slots provided by the connected device or + * zero if no device is connected. + */ + uint8_t get_totp_slot_count(); + + /** + * Returns the number of HOTP slots provided by the connected device or + * zero if no device is connected. + */ + uint8_t get_hotp_slot_count(); + + /** + * Returns the maximum length of an OTP slot name in bytes for the + * connected device or zero if no device is connected. + */ + size_t get_otp_name_length(); + + /** + * Returns the maximum length of an OTP secret in bytes for the + * connected device or zero if no device is connected. + */ + size_t get_otp_secret_length(); + bool set_time(uint64_t time); /** * Set the device time used for TOTP to the given time. Contrary to diff --git a/unittest/test_offline.py b/unittest/test_offline.py index 51fe67d..0dfbd9f 100644 --- a/unittest/test_offline.py +++ b/unittest/test_offline.py @@ -36,4 +36,14 @@ def test_offline(C_offline): # v3.4.1-29-g1f3d search = re.search(b'v\d\.\d(\.\d)?', libnk_version) - assert search is not None \ No newline at end of file + assert search is not None + + assert C_offline.NK_get_pws_slot_count() == 0 + assert C_offline.NK_get_pws_name_length() == 0 + assert C_offline.NK_get_pws_login_length() == 0 + assert C_offline.NK_get_pws_password_length() == 0 + + assert C_offline.NK_get_hotp_slot_count() == 0 + assert C_offline.NK_get_totp_slot_count() == 0 + assert C_offline.NK_get_otp_name_length() == 0 + assert C_offline.NK_get_otp_secret_length() == 0 diff --git a/unittest/test_pro.py b/unittest/test_pro.py index 0d8c536..717affe 100644 --- a/unittest/test_pro.py +++ b/unittest/test_pro.py @@ -132,6 +132,14 @@ def test_password_safe_slot_status(C): assert is_slot_programmed[1] == 1 +@pytest.mark.PWS +def test_password_safe_properties(C): + assert C.NK_get_pws_slot_count() == 16 + assert C.NK_get_pws_name_length() == 11 + assert C.NK_get_pws_login_length() == 32 + assert C.NK_get_pws_password_length() == 20 + + @pytest.mark.aes def test_issue_device_locks_on_second_key_generation_in_sequence(C): # if is_pro_rtm_07(C) or is_pro_rtm_08(C): @@ -1070,3 +1078,11 @@ def test_OTP_all_rw(C): all_codes.append(this_loop_codes) from pprint import pprint pprint(all_codes) + + +@pytest.mark.otp +def test_otp_properties(C): + assert C.NK_get_hotp_slot_count() == 3 + assert C.NK_get_totp_slot_count() == 15 + assert C.NK_get_otp_name_length() == 15 + assert C.NK_get_otp_secret_length() == 40