diff options
-rw-r--r-- | NK_C_API.cc | 39 | ||||
-rw-r--r-- | NK_C_API.h | 66 | ||||
-rw-r--r-- | NitrokeyManager.cc | 86 | ||||
-rw-r--r-- | command_id.cc | 11 | ||||
-rw-r--r-- | include/CommandFailedException.h | 5 | ||||
-rw-r--r-- | include/NitrokeyManager.h | 53 | ||||
-rw-r--r-- | include/command_id.h | 7 | ||||
-rw-r--r-- | include/device_proto.h | 10 | ||||
-rw-r--r-- | include/stick10_commands.h | 8 | ||||
-rw-r--r-- | include/stick20_commands.h | 24 | ||||
-rw-r--r-- | unittest/conftest.py | 13 | ||||
-rw-r--r-- | unittest/test_C_API.cpp | 6 | ||||
-rw-r--r-- | unittest/test_storage.py | 34 |
13 files changed, 335 insertions, 27 deletions
diff --git a/NK_C_API.cc b/NK_C_API.cc index 33a5fbb..f881caf 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -495,20 +495,48 @@ extern "C" { }); } - NK_C_API int NK_set_unencrypted_read_only(const char* user_pin) { + NK_C_API int NK_set_unencrypted_read_only(const char *user_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->set_unencrypted_read_only(user_pin); }); } - NK_C_API int NK_set_unencrypted_read_write(const char* user_pin) { + NK_C_API int NK_set_unencrypted_read_write(const char *user_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { m->set_unencrypted_read_write(user_pin); }); } + NK_C_API int NK_set_unencrypted_read_only_admin(const char *admin_pin) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->set_unencrypted_read_only_admin(admin_pin); + }); + } + + NK_C_API int NK_set_unencrypted_read_write_admin(const char *admin_pin) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->set_unencrypted_read_write_admin(admin_pin); + }); + } + + NK_C_API int NK_set_encrypted_read_only(const char* admin_pin) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->set_encrypted_volume_read_only(admin_pin); + }); + } + + NK_C_API int NK_set_encrypted_read_write(const char* admin_pin) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->set_encrypted_volume_read_write(admin_pin); + }); + } + NK_C_API int NK_export_firmware(const char* admin_pin) { auto m = NitrokeyManager::instance(); return get_without_result([&]() { @@ -569,6 +597,13 @@ extern "C" { NK_C_API int NK_get_major_firmware_version() { auto m = NitrokeyManager::instance(); return get_with_result([&]() { + return m->get_major_firmware_version(); + }); + } + + NK_C_API int NK_get_minor_firmware_version() { + auto m = NitrokeyManager::instance(); + return get_with_result([&]() { return m->get_minor_firmware_version(); }); } @@ -360,10 +360,16 @@ extern "C" { /** * Get device's major firmware version - * @return 7,8 for Pro and major for Storage + * @return major part of the version number (e.g. 0 from 0.48, 0 from 0.7 etc.) */ NK_C_API int NK_get_major_firmware_version(); + /** + * Get device's minor firmware version + * @return minor part of the version number (e.g. 7 from 0.7, 48 from 0.48 etc.) + */ + NK_C_API int NK_get_minor_firmware_version(); + /** @@ -422,21 +428,71 @@ extern "C" { * Make unencrypted volume read-only. * Device hides unencrypted volume for a second therefore make sure * buffers are flushed before running. + * Does nothing if firmware version is not matched + * Firmware range: Storage v0.50, v0.48 and below * Storage only - * @param user_pin 20 characters + * @param user_pin 20 characters User PIN * @return command processing error code */ - NK_C_API int NK_set_unencrypted_read_only(const char* user_pin); + NK_C_API int NK_set_unencrypted_read_only(const char *user_pin); /** * Make unencrypted volume read-write. * Device hides unencrypted volume for a second therefore make sure * buffers are flushed before running. + * Does nothing if firmware version is not matched + * Firmware range: Storage v0.50, v0.48 and below * Storage only - * @param user_pin 20 characters + * @param user_pin 20 characters User PIN + * @return command processing error code + */ + NK_C_API int NK_set_unencrypted_read_write(const char *user_pin); + + /** + * Make unencrypted volume read-only. + * Device hides unencrypted volume for a second therefore make sure + * buffers are flushed before running. + * Does nothing if firmware version is not matched + * Firmware range: Storage v0.49, v0.51+ + * Storage only + * @param admin_pin 20 characters Admin PIN + * @return command processing error code + */ + NK_C_API int NK_set_unencrypted_read_only_admin(const char* admin_pin); + + /** + * Make unencrypted volume read-write. + * Device hides unencrypted volume for a second therefore make sure + * buffers are flushed before running. + * Does nothing if firmware version is not matched + * Firmware range: Storage v0.49, v0.51+ + * Storage only + * @param admin_pin 20 characters Admin PIN + * @return command processing error code + */ + NK_C_API int NK_set_unencrypted_read_write_admin(const char* admin_pin); + + /** + * Make encrypted volume read-only. + * Device hides encrypted volume for a second therefore make sure + * buffers are flushed before running. + * Firmware range: v0.49 only, future (see firmware release notes) + * Storage only + * @param admin_pin 20 characters + * @return command processing error code + */ + NK_C_API int NK_set_encrypted_read_only(const char* admin_pin); + + /** + * Make encrypted volume read-write. + * Device hides encrypted volume for a second therefore make sure + * buffers are flushed before running. + * Firmware range: v0.49 only, future (see firmware release notes) + * Storage only + * @param admin_pin 20 characters * @return command processing error code */ - NK_C_API int NK_set_unencrypted_read_write(const char* user_pin); + NK_C_API int NK_set_encrypted_read_write(const char* admin_pin); /** * Exports device's firmware to unencrypted volume. diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 814c4a6..d563b26 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -30,6 +30,7 @@ #include <mutex> #include "include/cxx_semantics.h" #include <functional> +#include <stick10_commands.h> std::mutex nitrokey::proto::send_receive_mtx; @@ -751,15 +752,41 @@ using nitrokey::misc::strcpyT; return device->get_device_model(); } + bool NitrokeyManager::is_smartcard_in_use(){ + try{ + stick20::CheckSmartcardUsage::CommandTransaction::run(device); + } + catch(const CommandFailedException & e){ + return e.reason_smartcard_busy(); + } + return false; + } + int NitrokeyManager::get_minor_firmware_version(){ switch(device->get_device_model()){ case DeviceModel::PRO:{ auto status_p = GetStatus::CommandTransaction::run(device); - return status_p.data().firmware_version; //7 or 8 + return status_p.data().firmware_version_st.minor; //7 or 8 + } + case DeviceModel::STORAGE:{ + auto status = stick20::GetDeviceStatus::CommandTransaction::run(device); + auto test_firmware = status.data().versionInfo.build_iteration != 0; + if (test_firmware) + LOG("Development firmware detected. Increasing minor version number.", nitrokey::log::Loglevel::WARNING); + return status.data().versionInfo.minor + (test_firmware? 1 : 0); + } + } + return 0; + } + int NitrokeyManager::get_major_firmware_version(){ + switch(device->get_device_model()){ + case DeviceModel::PRO:{ + auto status_p = GetStatus::CommandTransaction::run(device); + return status_p.data().firmware_version_st.major; //0 } case DeviceModel::STORAGE:{ auto status = stick20::GetDeviceStatus::CommandTransaction::run(device); - return status.data().versionInfo.minor; + return status.data().versionInfo.major; } } return 0; @@ -789,6 +816,14 @@ using nitrokey::misc::strcpyT; misc::execute_password_command<stick20::EnableHiddenEncryptedPartition>(device, hidden_volume_password); } + void NitrokeyManager::set_encrypted_volume_read_only(const char* admin_pin) { + misc::execute_password_command<stick20::SetEncryptedVolumeReadOnly>(device, admin_pin); + } + + void NitrokeyManager::set_encrypted_volume_read_write(const char* admin_pin) { + misc::execute_password_command<stick20::SetEncryptedVolumeReadWrite>(device, admin_pin); + } + //TODO check is encrypted volume unlocked before execution //if not return library exception void NitrokeyManager::create_hidden_volume(uint8_t slot_nr, uint8_t start_percent, uint8_t end_percent, @@ -801,15 +836,56 @@ using nitrokey::misc::strcpyT; stick20::SetupHiddenVolume::CommandTransaction::run(device, p); } - void NitrokeyManager::set_unencrypted_read_only(const char* user_pin) { + void NitrokeyManager::set_unencrypted_read_only_admin(const char* admin_pin) { + //from v0.49, v0.51+ it needs Admin PIN + if (set_unencrypted_volume_rorw_pin_type_user()){ + LOG("set_unencrypted_read_only_admin is not supported for this version of Storage device. " + "Please update firmware to v0.51+", nitrokey::log::Loglevel::WARNING); + return; + } + misc::execute_password_command<stick20::SetUnencryptedVolumeReadOnlyAdmin>(device, admin_pin); + } + + void NitrokeyManager::set_unencrypted_read_only(const char *user_pin) { + //until v0.48 (incl. v0.50) User PIN was sufficient + LOG("set_unencrypted_read_only is deprecated. Use set_unencrypted_read_only_admin instead.", + nitrokey::log::Loglevel::WARNING); + if (!set_unencrypted_volume_rorw_pin_type_user()){ + LOG("set_unencrypted_read_only is not supported for this version of Storage device. Doing nothing.", + nitrokey::log::Loglevel::WARNING); + return; + } misc::execute_password_command<stick20::SendSetReadonlyToUncryptedVolume>(device, user_pin); } - void NitrokeyManager::set_unencrypted_read_write(const char* user_pin) { + void NitrokeyManager::set_unencrypted_read_write_admin(const char* admin_pin) { + //from v0.49, v0.51+ it needs Admin PIN + if (set_unencrypted_volume_rorw_pin_type_user()){ + LOG("set_unencrypted_read_write_admin is not supported for this version of Storage device. " + "Please update firmware to v0.51+.", nitrokey::log::Loglevel::WARNING); + return; + } + misc::execute_password_command<stick20::SetUnencryptedVolumeReadWriteAdmin>(device, admin_pin); + } + + void NitrokeyManager::set_unencrypted_read_write(const char *user_pin) { + //until v0.48 (incl. v0.50) User PIN was sufficient + LOG("set_unencrypted_read_write is deprecated. Use set_unencrypted_read_write_admin instead.", + nitrokey::log::Loglevel::WARNING); + if (!set_unencrypted_volume_rorw_pin_type_user()){ + LOG("set_unencrypted_read_write is not supported for this version of Storage device. Doing nothing.", + nitrokey::log::Loglevel::WARNING); + return; + } misc::execute_password_command<stick20::SendSetReadwriteToUncryptedVolume>(device, user_pin); } - void NitrokeyManager::export_firmware(const char* admin_pin) { + bool NitrokeyManager::set_unencrypted_volume_rorw_pin_type_user(){ + auto minor_firmware_version = get_minor_firmware_version(); + return minor_firmware_version <= 48 || minor_firmware_version == 50; + } + + void NitrokeyManager::export_firmware(const char* admin_pin) { misc::execute_password_command<stick20::ExportFirmware>(device, admin_pin); } diff --git a/command_id.cc b/command_id.cc index 9c6c590..d81d487 100644 --- a/command_id.cc +++ b/command_id.cc @@ -134,6 +134,17 @@ const char *commandid_to_string(CommandID id) { case CommandID::CHANGE_UPDATE_PIN: return "CHANGE_UPDATE_PIN"; + case CommandID::ENABLE_ADMIN_READONLY_UNCRYPTED_LUN: + return "ENABLE_ADMIN_READONLY_UNCRYPTED_LUN"; + case CommandID::ENABLE_ADMIN_READWRITE_UNCRYPTED_LUN: + return "ENABLE_ADMIN_READWRITE_UNCRYPTED_LUN"; + case CommandID::ENABLE_ADMIN_READONLY_ENCRYPTED_LUN: + return "ENABLE_ADMIN_READONLY_ENCRYPTED_LUN"; + case CommandID::ENABLE_ADMIN_READWRITE_ENCRYPTED_LUN: + return "ENABLE_ADMIN_READWRITE_ENCRYPTED_LUN"; + case CommandID::CHECK_SMARTCARD_USAGE: + return "CHECK_SMARTCARD_USAGE"; + case CommandID::GET_PW_SAFE_SLOT_STATUS: return "GET_PW_SAFE_SLOT_STATUS"; case CommandID::GET_PW_SAFE_SLOT_NAME: diff --git a/include/CommandFailedException.h b/include/CommandFailedException.h index 42fad73..32bd6b7 100644 --- a/include/CommandFailedException.h +++ b/include/CommandFailedException.h @@ -28,6 +28,7 @@ #include "command_id.h" using cs = nitrokey::proto::stick10::command_status; +using cs2 = nitrokey::proto::stick20::device_status; class CommandFailedException : public std::exception { public: @@ -65,6 +66,10 @@ public: return last_command_status == static_cast<uint8_t>(cs::wrong_password); } + bool reason_smartcard_busy() const throw(){ + return last_command_status == static_cast<uint8_t>(cs2::smartcard_error); + } + }; diff --git a/include/NitrokeyManager.h b/include/NitrokeyManager.h index 9a1686c..0db0856 100644 --- a/include/NitrokeyManager.h +++ b/include/NitrokeyManager.h @@ -126,10 +126,38 @@ char * strndup(const char* str, size_t maxlen); void unlock_hidden_volume(const char *hidden_volume_password); void lock_hidden_volume(); + /** + * Sets unencrypted volume read-only. + * Works until v0.48 (incl. v0.50), where User PIN was sufficient + * Does nothing otherwise. + * @param user_pin User PIN + */ void set_unencrypted_read_only(const char *user_pin); + /** + * Sets unencrypted volume read-only. + * Works from v0.49 (except v0.50) accepts Admin PIN + * Does nothing otherwise. + * @param admin_pin Admin PIN + */ + void set_unencrypted_read_only_admin(const char *admin_pin); + + /** + * Sets unencrypted volume read-write. + * Works until v0.48 (incl. v0.50), where User PIN was sufficient + * Does nothing otherwise. + * @param user_pin User PIN + */ void set_unencrypted_read_write(const char *user_pin); + /** + * Sets unencrypted volume read-write. + * Works from v0.49 (except v0.50) accepts Admin PIN + * Does nothing otherwise. + * @param admin_pin Admin PIN + */ + void set_unencrypted_read_write_admin(const char *admin_pin); + void export_firmware(const char *admin_pin); void enable_firmware_update(const char *firmware_pin); @@ -202,6 +230,31 @@ char * strndup(const char* str, size_t maxlen); void set_loglevel(Loglevel loglevel); void set_loglevel(int loglevel); + + /** + * Sets encrypted volume read-only. + * Supported from future versions of Storage. + * @param admin_pin Admin PIN + */ + void set_encrypted_volume_read_only(const char *admin_pin); + + /** + * Sets encrypted volume read-write. + * Supported from future versions of Storage. + * @param admin_pin Admin PIN + */ + void set_encrypted_volume_read_write(const char *admin_pin); + + int get_major_firmware_version(); + + bool is_smartcard_in_use(); + + /** + * Function to determine unencrypted volume PIN type + * @param minor_firmware_version + * @return Returns true, if set unencrypted volume ro/rw pin type is User, false otherwise. + */ + bool set_unencrypted_volume_rorw_pin_type_user(); }; } diff --git a/include/command_id.h b/include/command_id.h index 7608201..1092ea9 100644 --- a/include/command_id.h +++ b/include/command_id.h @@ -124,6 +124,13 @@ enum class CommandID : uint8_t { CHANGE_UPDATE_PIN = 0x20 + 26, + //added in v0.48.5 + ENABLE_ADMIN_READONLY_UNCRYPTED_LUN = 0x20 + 28, + ENABLE_ADMIN_READWRITE_UNCRYPTED_LUN = 0x20 + 29, + ENABLE_ADMIN_READONLY_ENCRYPTED_LUN = 0x20 + 30, + ENABLE_ADMIN_READWRITE_ENCRYPTED_LUN = 0x20 + 31, + CHECK_SMARTCARD_USAGE = 0x20 + 32, + GET_PW_SAFE_SLOT_STATUS = 0x60, GET_PW_SAFE_SLOT_NAME = 0x61, GET_PW_SAFE_SLOT_PASSWORD = 0x62, diff --git a/include/device_proto.h b/include/device_proto.h index 7873a0a..ebdcdbd 100644 --- a/include/device_proto.h +++ b/include/device_proto.h @@ -351,12 +351,14 @@ namespace nitrokey { LOG("Status busy, decreasing receiving_retry_counter counter: " + std::to_string(receiving_retry_counter) + ", current delay:" + std::to_string(retry_timeout.count()), Loglevel::DEBUG); - LOG(std::string("Busy retry ") + LOG(std::string("Busy retry: status ") + std::to_string(resp.storage_status.device_status) - + " " + + ", " + std::to_string(retry_timeout.count()) - + " " + + "ms, counter " + std::to_string(receiving_retry_counter) + + ", progress: " + + std::to_string(resp.storage_status.progress_bar_value) , Loglevel::DEBUG_L1); } } @@ -454,7 +456,7 @@ namespace nitrokey { if (resp.last_command_status != static_cast<uint8_t>(stick10::command_status::ok)){ dev->m_counters.command_result_not_equal_0_recv++; - LOG(std::string("Throw: CommandFailedException"), Loglevel::DEBUG_L1); + LOG(std::string("Throw: CommandFailedException ") + std::to_string(resp.last_command_status), Loglevel::DEBUG_L1); throw CommandFailedException(resp.command_id, resp.last_command_status); } diff --git a/include/stick10_commands.h b/include/stick10_commands.h index c9a5e5b..893b98f 100644 --- a/include/stick10_commands.h +++ b/include/stick10_commands.h @@ -367,7 +367,13 @@ class ReadSlot : Command<CommandID::READ_SLOT> { class GetStatus : Command<CommandID::GET_STATUS> { public: struct ResponsePayload { - uint16_t firmware_version; + union { + uint16_t firmware_version; + struct { + uint8_t minor; + uint8_t major; + } firmware_version_st; + }; union{ uint8_t card_serial[4]; uint32_t card_serial_u32; diff --git a/include/stick20_commands.h b/include/stick20_commands.h index 34bd547..4b75e6a 100644 --- a/include/stick20_commands.h +++ b/include/stick20_commands.h @@ -52,6 +52,15 @@ namespace nitrokey { class EnableEncryptedPartition : public PasswordCommand<CommandID::ENABLE_CRYPTED_PARI> {}; class EnableHiddenEncryptedPartition : public PasswordCommand<CommandID::ENABLE_HIDDEN_CRYPTED_PARI> {}; + class SetUnencryptedVolumeReadOnlyAdmin : + public PasswordCommand<CommandID::ENABLE_ADMIN_READONLY_UNCRYPTED_LUN, PasswordKind::Admin> {}; + class SetUnencryptedVolumeReadWriteAdmin : + public PasswordCommand<CommandID::ENABLE_ADMIN_READWRITE_UNCRYPTED_LUN, PasswordKind::Admin> {}; + class SetEncryptedVolumeReadOnly : + public PasswordCommand<CommandID::ENABLE_ADMIN_READONLY_ENCRYPTED_LUN, PasswordKind::Admin> {}; + class SetEncryptedVolumeReadWrite : + public PasswordCommand<CommandID::ENABLE_ADMIN_READWRITE_ENCRYPTED_LUN, PasswordKind::Admin> {}; + //FIXME the volume disabling commands do not need password class DisableEncryptedPartition : public PasswordCommand<CommandID::DISABLE_CRYPTED_PARI> {}; class DisableHiddenEncryptedPartition : public PasswordCommand<CommandID::DISABLE_HIDDEN_CRYPTED_PARI> {}; @@ -159,10 +168,10 @@ namespace nitrokey { union{ uint8_t VersionInfo_au8[4]; struct { - uint8_t _reserved; + uint8_t major; uint8_t minor; uint8_t _reserved2; - uint8_t major; + uint8_t build_iteration; } __packed versionInfo; } __packed; @@ -206,8 +215,9 @@ namespace nitrokey { print_to_ss((int) ReadWriteFlagUncryptedVolume_u8 ); print_to_ss((int) ReadWriteFlagCryptedVolume_u8 ); print_to_ss((int) ReadWriteFlagHiddenVolume_u8 ); - print_to_ss((int) VersionInfo_au8[1] ); - print_to_ss((int) VersionInfo_au8[3] ); + print_to_ss((int) versionInfo.major ); + print_to_ss((int) versionInfo.minor ); + print_to_ss((int) versionInfo.build_iteration ); print_to_ss((int) FirmwareLocked_u8 ); print_to_ss((int) NewSDCardFound_u8 ); print_to_ss((int) NewSDCardFound_st.NewCard ); @@ -265,6 +275,12 @@ namespace nitrokey { CommandTransaction; }; + class CheckSmartcardUsage : Command<CommandID::CHECK_SMARTCARD_USAGE> { + public: + typedef Transaction<command_id(), struct EmptyPayload, EmptyPayload> + CommandTransaction; + }; + class GetSDCardOccupancy : Command<CommandID::SD_CARD_HIGH_WATERMARK> { public: struct ResponsePayload { diff --git a/unittest/conftest.py b/unittest/conftest.py index 8f386e0..49f1502 100644 --- a/unittest/conftest.py +++ b/unittest/conftest.py @@ -34,7 +34,7 @@ def skip_if_device_version_lower_than(allowed_devices): @pytest.fixture(scope="module") -def C(request): +def C(request=None): fp = '../NK_C_API.h' declarations = [] @@ -77,15 +77,17 @@ def C(request): print("No library file found") sys.exit(1) - C.NK_set_debug(False) + C.NK_set_debug_level(int(os.environ.get('LIBNK_DEBUG', 2))) + nk_login = C.NK_login_auto() if nk_login != 1: print('No devices detected!') assert nk_login != 0 # returns 0 if not connected or wrong model or 1 when connected global device_type - firmware_version = C.NK_get_major_firmware_version() + firmware_version = C.NK_get_minor_firmware_version() model = 'P' if firmware_version in [7,8] else 'S' device_type = (model, firmware_version) + print('Connected device: {} {}'.format(model, firmware_version)) # assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK # assert C.NK_user_authenticate(DefaultPasswords.USER, DefaultPasswords.USER_TEMP) == DeviceErrorCode.STATUS_OK @@ -97,8 +99,9 @@ def C(request): C.NK_logout() print('Finished') - request.addfinalizer(fin) + if request: + request.addfinalizer(fin) # C.NK_set_debug(True) - C.NK_set_debug_level(3) + C.NK_set_debug_level(int(os.environ.get('LIBNK_DEBUG', 3))) return C diff --git a/unittest/test_C_API.cpp b/unittest/test_C_API.cpp index d5076c4..be47f08 100644 --- a/unittest/test_C_API.cpp +++ b/unittest/test_C_API.cpp @@ -28,8 +28,10 @@ static const int TOO_LONG_STRING = 200; #include "log.h" #include "../NK_C_API.h" +int login; + TEST_CASE("C API connect", "[BASIC]") { - auto login = NK_login_auto(); + login = NK_login_auto(); REQUIRE(login != 0); NK_logout(); login = NK_login_auto(); @@ -40,11 +42,13 @@ TEST_CASE("C API connect", "[BASIC]") { } TEST_CASE("Check retry count", "[BASIC]") { + REQUIRE(login != 0); REQUIRE(NK_get_admin_retry_count() == 3); REQUIRE(NK_get_user_retry_count() == 3); } TEST_CASE("Check long strings", "[STANDARD]") { + REQUIRE(login != 0); const char* longPin = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; const char* pin = "123123123"; auto result = NK_change_user_PIN(longPin, pin); diff --git a/unittest/test_storage.py b/unittest/test_storage.py index 67bbf8b..096709d 100644 --- a/unittest/test_storage.py +++ b/unittest/test_storage.py @@ -53,6 +53,8 @@ def test_get_status_storage(C): status_dict = get_dict_from_dissect(status_string.decode('ascii')) default_admin_password_retry_count = 3 assert int(status_dict['AdminPwRetryCount']) == default_admin_password_retry_count + print('C.NK_get_major_firmware_version(): {}'.format(C.NK_get_major_firmware_version())) + print('C.NK_get_minor_firmware_version(): {}'.format(C.NK_get_minor_firmware_version())) @pytest.mark.other @@ -244,6 +246,8 @@ def test_hidden_volume_corruption(C): hidden_volume_password = b'hiddenpassword' p = lambda i: hidden_volume_password + bb(str(i)) volumes_to_setup = 4 + assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK + assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK for i in range(volumes_to_setup): assert C.NK_create_hidden_volume(i, 20 + i * 10, 20 + i * 10 + i + 1, p(i)) == DeviceErrorCode.STATUS_OK assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK @@ -273,6 +277,36 @@ def test_unencrypted_volume_set_read_write(C): assert C.NK_set_unencrypted_read_write(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK +@pytest.mark.unencrypted +def test_unencrypted_volume_set_read_only_admin(C): + skip_if_device_version_lower_than({'S': 51}) + assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK + assert C.NK_set_unencrypted_read_only_admin(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK + + +@pytest.mark.unencrypted +def test_unencrypted_volume_set_read_write_admin(C): + skip_if_device_version_lower_than({'S': 51}) + assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK + assert C.NK_set_unencrypted_read_write_admin(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK + + +@pytest.mark.encrypted +@pytest.mark.skip(reason='not supported on recent firmware, except v0.49') +def test_encrypted_volume_set_read_only(C): + skip_if_device_version_lower_than({'S': 99}) + assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK + assert C.NK_set_encrypted_read_only(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK + + +@pytest.mark.encrypted +@pytest.mark.skip(reason='not supported on recent firmware, except v0.49') +def test_encrypted_volume_set_read_write(C): + skip_if_device_version_lower_than({'S': 99}) + assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK + assert C.NK_set_encrypted_read_write(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK + + @pytest.mark.other def test_export_firmware(C): skip_if_device_version_lower_than({'S': 43}) |