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}) | 
