summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzczepan Zalega <szczepan@nitrokey.com>2018-02-23 16:03:16 +0100
committerSzczepan Zalega <szczepan@nitrokey.com>2018-02-23 16:03:16 +0100
commitd5486ba77235a874245fbee07a75cea89fa59ea2 (patch)
tree7f2df53da4c018fbfa6ec57809bcd2fcefaf0624
parent102ee60cd8ee9e5ce263de1d4a775acf29f37fbc (diff)
parenta262472826830ea0a98a4da2fa8f665d359b8789 (diff)
downloadlibnitrokey-d5486ba77235a874245fbee07a75cea89fa59ea2.tar.gz
libnitrokey-d5486ba77235a874245fbee07a75cea89fa59ea2.tar.bz2
Merge branch 'wip-support_storage_v0.51'
Support for functionality added in v0.49/v0.51
-rw-r--r--NK_C_API.cc39
-rw-r--r--NK_C_API.h66
-rw-r--r--NitrokeyManager.cc86
-rw-r--r--command_id.cc11
-rw-r--r--include/CommandFailedException.h5
-rw-r--r--include/NitrokeyManager.h53
-rw-r--r--include/command_id.h7
-rw-r--r--include/device_proto.h10
-rw-r--r--include/stick10_commands.h8
-rw-r--r--include/stick20_commands.h24
-rw-r--r--unittest/conftest.py13
-rw-r--r--unittest/test_C_API.cpp6
-rw-r--r--unittest/test_storage.py34
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();
});
}
diff --git a/NK_C_API.h b/NK_C_API.h
index a4fb088..73022b2 100644
--- a/NK_C_API.h
+++ b/NK_C_API.h
@@ -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})