From 103f71bb4e06132e70eb26fc2f1c5ca560068107 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Mon, 31 Oct 2016 20:47:23 +0100 Subject: Tests reorganization (Python) Signed-off-by: Szczepan Zalega --- unittest/constants.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 unittest/constants.py (limited to 'unittest/constants.py') diff --git a/unittest/constants.py b/unittest/constants.py new file mode 100644 index 0000000..e3caae3 --- /dev/null +++ b/unittest/constants.py @@ -0,0 +1,30 @@ +from enum import Enum +from misc import to_hex + +RFC_SECRET_HR = '12345678901234567890' +RFC_SECRET = to_hex(RFC_SECRET_HR) # '12345678901234567890' + + +# print( repr((RFC_SECRET, RFC_SECRET_, len(RFC_SECRET))) ) + +class DefaultPasswords(Enum): + ADMIN = '12345678' + USER = '123456' + ADMIN_TEMP = '123123123' + USER_TEMP = '234234234' + + +class DeviceErrorCode(Enum): + STATUS_OK = 0 + NOT_PROGRAMMED = 3 + WRONG_PASSWORD = 4 + STATUS_NOT_AUTHORIZED = 5 + STATUS_AES_DEC_FAILED = 0xa + + +class LibraryErrors(Enum): + TOO_LONG_STRING = 200 + INVALID_SLOT = 201 + INVALID_HEX_STRING = 202 + TARGET_BUFFER_SIZE_SMALLER_THAN_SOURCE = 203 + -- cgit v1.2.3 From 7d943d3e8717ba47af4b53787cc4c29ad6ee2f90 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Wed, 2 Nov 2016 21:52:40 +0100 Subject: Python bindings and tests for most of Storage functionality Signed-off-by: Szczepan Zalega --- NK_C_API.cc | 90 ++++++++++++++++++++++++++++++++++++++++++++++ NK_C_API.h | 17 +++++++++ NitrokeyManager.cc | 79 +++++++++++++++++++++++++++++++++++++++- include/NitrokeyManager.h | 25 ++++++++++++- unittest/constants.py | 2 ++ unittest/test_storage.py | 91 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 302 insertions(+), 2 deletions(-) (limited to 'unittest/constants.py') diff --git a/NK_C_API.cc b/NK_C_API.cc index 7110fca..fc6d3c5 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -375,5 +375,95 @@ extern int NK_login_auto() { }); } +// storage commands + +extern int NK_send_startup(uint64_t seconds_from_epoch){ + auto m = NitrokeyManager::instance(); + return get_without_result([&](){ + m->send_startup(seconds_from_epoch); + }); +} + +extern int NK_unlock_encrypted_volume(const char* user_pin){ + auto m = NitrokeyManager::instance(); + return get_without_result([&](){ + m->unlock_encrypted_volume(user_pin); + }); +} + +extern int NK_unlock_hidden_volume(const char* hidden_volume_password){ + auto m = NitrokeyManager::instance(); + return get_without_result([&](){ + m->unlock_hidden_volume(hidden_volume_password); + }); +} + +extern int NK_create_hidden_volume(int slot_nr, int start_percent, int end_percent, + const char* hidden_volume_password){ + auto m = NitrokeyManager::instance(); + return get_without_result([&](){ + m->create_hidden_volume( slot_nr, start_percent, end_percent, + hidden_volume_password); + }); +} + +extern 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); + }); +} + +extern 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); + }); +} + +extern int NK_export_firmware(const char* admin_pin) { + auto m = NitrokeyManager::instance(); + return get_without_result([&](){ + m->export_firmware(admin_pin) ; + }); +} + +extern int NK_clear_new_sd_card_warning(const char* admin_pin) { + auto m = NitrokeyManager::instance(); + return get_without_result([&](){ + m->clear_new_sd_card_warning(admin_pin); + }); +} + +extern int NK_fill_SD_card_with_random_data(const char* admin_pin) { + auto m = NitrokeyManager::instance(); + return get_without_result([&](){ + m->fill_SD_card_with_random_data(admin_pin); + }); +} + +extern int NK_change_update_password(const char* current_update_password, + const char* new_update_password) { + auto m = NitrokeyManager::instance(); + return get_without_result([&](){ + m->change_update_password(current_update_password, new_update_password); + }); +} + +extern const char* NK_get_status_storage() { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&](){ + return m->get_status_storage(); + }); +} + +extern const char* NK_get_SD_usage_data() { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&](){ + return m->get_SD_usage_data(); + }); +} + + } diff --git a/NK_C_API.h b/NK_C_API.h index 728824d..e5b414c 100644 --- a/NK_C_API.h +++ b/NK_C_API.h @@ -324,6 +324,23 @@ extern int NK_erase_password_safe_slot(uint8_t slot_number); */ extern int NK_is_AES_supported(const char *user_password); + +extern int NK_send_startup(uint64_t seconds_from_epoch); +extern int NK_unlock_encrypted_volume(const char* user_pin); +extern int NK_unlock_hidden_volume(const char* hidden_volume_password); +extern int NK_create_hidden_volume(int slot_nr, int start_percent, int end_percent, + const char* hidden_volume_password); +extern int NK_set_unencrypted_read_only(const char* user_pin); +extern int NK_set_unencrypted_read_write(const char* user_pin); +extern int NK_export_firmware(const char* admin_pin) ; +extern int NK_clear_new_sd_card_warning(const char* admin_pin) ; +extern int NK_fill_SD_card_with_random_data(const char* admin_pin) ; +extern int NK_change_update_password(const char* current_update_password, + const char* new_update_password); +extern const char* NK_get_status_storage(); +extern const char* NK_get_SD_usage_data(); + + } diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 606c4fb..49b34c4 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -3,6 +3,7 @@ #include "include/NitrokeyManager.h" #include "include/LibraryException.h" #include +#include "include/misc.h" namespace nitrokey{ @@ -486,4 +487,80 @@ namespace nitrokey{ return true; } -} + //storage commands + + /** + * TODO rename to set_time ? + * TODO check what exactly this one is doing + * @param seconds_from_epoch + */ + void NitrokeyManager::send_startup(uint64_t seconds_from_epoch){ + auto p = get_payload(); +// p.set_defaults(); + p.localtime = seconds_from_epoch; + //auto device_status = + stick20::SendStartup::CommandTransaction::run(*device, p); + } + + void NitrokeyManager::unlock_encrypted_volume(const char* user_pin){ + misc::execute_password_command(*device, user_pin); + } + + void NitrokeyManager::unlock_hidden_volume(const char* hidden_volume_password) { + misc::execute_password_command(*device, hidden_volume_password); + } + + //TODO check is encrypted volume unlocked before execution + //if not return library exception + void NitrokeyManager::create_hidden_volume(int slot_nr, int start_percent, int end_percent, + const char* hidden_volume_password) { + auto p = get_payload(); + p.SlotNr_u8 = slot_nr; + p.StartBlockPercent_u8 = start_percent; + p.EndBlockPercent_u8 = end_percent; + strcpyT(p.HiddenVolumePassword_au8, hidden_volume_password); + stick20::SetupHiddenVolume::CommandTransaction::run(*device, p); + } + + void NitrokeyManager::set_unencrypted_read_only(const char* user_pin) { + misc::execute_password_command(*device, user_pin); + } + + void NitrokeyManager::set_unencrypted_read_write(const char* user_pin) { + misc::execute_password_command(*device, user_pin); + } + + void NitrokeyManager::export_firmware(const char* admin_pin) { + misc::execute_password_command(*device, admin_pin); + } + + void NitrokeyManager::clear_new_sd_card_warning(const char* admin_pin) { + misc::execute_password_command(*device, admin_pin); + } + + void NitrokeyManager::fill_SD_card_with_random_data(const char* admin_pin) { + auto p = get_payload(); + p.set_defaults(); + strcpyT(p.admin_pin, admin_pin); + stick20::FillSDCardWithRandomChars::CommandTransaction::run(*device, p); + } + + void NitrokeyManager::change_update_password(const char* current_update_password, const char* new_update_password) { + auto p = get_payload(); + strcpyT(p.current_update_password, current_update_password); + strcpyT(p.new_update_password, new_update_password); + stick20::ChangeUpdatePassword::CommandTransaction::run(*device, p); + } + + const char * NitrokeyManager::get_status_storage(){ + auto p = stick20::GetDeviceStatus::CommandTransaction::run(*device); + return strdup(p.data().dissect().c_str()); + } + + const char * NitrokeyManager::get_SD_usage_data(){ + auto p = stick20::GetSDCardOccupancy::CommandTransaction::run(*device); + return strdup(p.data().dissect().c_str()); + } + + + } diff --git a/include/NitrokeyManager.h b/include/NitrokeyManager.h index 52c18d7..7a3ffcc 100644 --- a/include/NitrokeyManager.h +++ b/include/NitrokeyManager.h @@ -82,6 +82,30 @@ namespace nitrokey { bool is_AES_supported(const char *user_password); + void unlock_encrypted_volume(const char *user_password); + + void unlock_hidden_volume(const char *hidden_volume_password); + + void set_unencrypted_read_only(const char *user_pin); + + void set_unencrypted_read_write(const char *user_pin); + + void export_firmware(const char *admin_pin); + + void clear_new_sd_card_warning(const char *admin_pin); + + void fill_SD_card_with_random_data(const char *admin_pin); + + void change_update_password(const char *current_update_password, const char *new_update_password); + + void create_hidden_volume(int slot_nr, int start_percent, int end_percent, const char *hidden_volume_password); + + void send_startup(uint64_t seconds_from_epoch); + + const char * get_status_storage(); + + const char *get_SD_usage_data(); + ~NitrokeyManager(); private: NitrokeyManager(); @@ -101,7 +125,6 @@ namespace nitrokey { template void change_PIN_general(char *current_PIN, char *new_PIN); - }; } diff --git a/unittest/constants.py b/unittest/constants.py index e3caae3..258619e 100644 --- a/unittest/constants.py +++ b/unittest/constants.py @@ -12,6 +12,8 @@ class DefaultPasswords(Enum): USER = '123456' ADMIN_TEMP = '123123123' USER_TEMP = '234234234' + UPDATE = '12345678' + UPDATE_TEMP = '123update123' class DeviceErrorCode(Enum): diff --git a/unittest/test_storage.py b/unittest/test_storage.py index d6cc558..b02b1eb 100644 --- a/unittest/test_storage.py +++ b/unittest/test_storage.py @@ -3,5 +3,96 @@ import pytest from misc import ffi, gs, wait, cast_pointer_to_tuple from constants import DefaultPasswords, DeviceErrorCode, RFC_SECRET, LibraryErrors +import pprint +pprint = pprint.PrettyPrinter(indent=4).pprint +def get_dict_from_dissect(status): + x = [] + for s in status.split('\n'): + try: + if not ':' in s: continue + ss = s.replace('\t', '').replace(' (int) ', '').split(':') + if not len(ss) == 2: continue + x.append(ss) + except: + pass + d = {k.strip(): v.strip() for k, v in x} + return d + + +def test_get_status_storage(C): + status_pointer = C.NK_get_status_storage() + status_string = gs(status_pointer) + status_dict = get_dict_from_dissect(status_string) + default_admin_password_retry_count = 3 + assert int(status_dict['AdminPwRetryCount']) == default_admin_password_retry_count + + +def test_sd_card_usage(C): + data_pointer = C.NK_get_SD_usage_data() + data_string = gs(data_pointer) + assert len(data_string) > 0 + data_dict = get_dict_from_dissect(data_string) + assert int(data_dict['WriteLevelMax']) <= 100 + + +def test_encrypted_volume_unlock(C): + assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK + assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK + + +def test_encrypted_volume_unlock_hidden(C): + hidden_volume_password = 'hiddenpassword' + assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK + assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK + assert C.NK_create_hidden_volume(0, 20, 21, hidden_volume_password) == DeviceErrorCode.STATUS_OK + assert C.NK_unlock_hidden_volume(hidden_volume_password) == DeviceErrorCode.STATUS_OK + + +def test_encrypted_volume_setup_multiple_hidden(C): + hidden_volume_password = 'hiddenpassword' + p = lambda i: hidden_volume_password + str(i) + assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK + assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK + for i in range(4): + assert C.NK_create_hidden_volume(i, 20+i*10, 20+i*10+i+1, p(i) ) == DeviceErrorCode.STATUS_OK + for i in range(4): + assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK + assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK + assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK + + +def test_unencrypted_volume_set_read_only(C): + assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK + assert C.NK_set_unencrypted_read_only(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK + + +def test_unencrypted_volume_set_read_write(C): + assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK + assert C.NK_set_unencrypted_read_write(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK + + +def test_export_firmware(C): + assert C.NK_export_firmware(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK + + +def test_clear_new_sd_card_notification(C): + assert C.NK_clear_new_sd_card_warning(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK + + +@pytest.mark.skip +def test_fill_SD_card(C): + assert C.NK_fill_SD_card_with_random_data(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK + + +def test_change_update_password(C): + wrong_password = 'aaaaaaaaaaa' + assert C.NK_change_update_password(wrong_password, DefaultPasswords.UPDATE_TEMP) == DeviceErrorCode.WRONG_PASSWORD + assert C.NK_change_update_password(DefaultPasswords.UPDATE, DefaultPasswords.UPDATE_TEMP) == DeviceErrorCode.STATUS_OK + assert C.NK_change_update_password(DefaultPasswords.UPDATE_TEMP, DefaultPasswords.UPDATE) == DeviceErrorCode.STATUS_OK + + +def test_send_startup(C): + time_seconds_from_epoch = 0 # FIXME set proper date + assert C.NK_send_startup(time_seconds_from_epoch) == DeviceErrorCode.STATUS_OK -- cgit v1.2.3 From fe36daa38ab1995c8c7fc6470d06b8595efd2385 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Thu, 3 Nov 2016 13:51:59 +0100 Subject: Tests: remake fill SD card test. Get progress bar value when busy. Signed-off-by: Szczepan Zalega --- NK_C_API.cc | 7 +++++++ NK_C_API.h | 1 + NitrokeyManager.cc | 9 +++++++++ include/NitrokeyManager.h | 2 ++ unittest/constants.py | 1 + unittest/test_storage.py | 15 ++++++++++++++- 6 files changed, 34 insertions(+), 1 deletion(-) (limited to 'unittest/constants.py') diff --git a/NK_C_API.cc b/NK_C_API.cc index fc6d3c5..2a28ede 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -464,6 +464,13 @@ extern const char* NK_get_SD_usage_data() { }); } +extern int NK_get_progress_bar_value() { + auto m = NitrokeyManager::instance(); + return get_with_result([&](){ + return m->get_progress_bar_value(); + }); +} + } diff --git a/NK_C_API.h b/NK_C_API.h index e5b414c..b71aeb8 100644 --- a/NK_C_API.h +++ b/NK_C_API.h @@ -339,6 +339,7 @@ extern int NK_change_update_password(const char* current_update_password, const char* new_update_password); extern const char* NK_get_status_storage(); extern const char* NK_get_SD_usage_data(); +extern int NK_get_progress_bar_value(); } diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 49b34c4..fdf1e05 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -562,5 +562,14 @@ namespace nitrokey{ return strdup(p.data().dissect().c_str()); } + int NitrokeyManager::get_progress_bar_value(){ + try{ + stick20::GetDeviceStatus::CommandTransaction::run(*device); + return -1; + } + catch (LongOperationInProgressException &e){ + return e.progress_bar_value; + } + } } diff --git a/include/NitrokeyManager.h b/include/NitrokeyManager.h index 7a3ffcc..2d5859f 100644 --- a/include/NitrokeyManager.h +++ b/include/NitrokeyManager.h @@ -106,6 +106,8 @@ namespace nitrokey { const char *get_SD_usage_data(); + int get_progress_bar_value(); + ~NitrokeyManager(); private: NitrokeyManager(); diff --git a/unittest/constants.py b/unittest/constants.py index 258619e..78a219b 100644 --- a/unittest/constants.py +++ b/unittest/constants.py @@ -18,6 +18,7 @@ class DefaultPasswords(Enum): class DeviceErrorCode(Enum): STATUS_OK = 0 + BUSY = 1 # busy or busy progressbar in place of wrong_CRC status NOT_PROGRAMMED = 3 WRONG_PASSWORD = 4 STATUS_NOT_AUTHORIZED = 5 diff --git a/unittest/test_storage.py b/unittest/test_storage.py index b02b1eb..600faf2 100644 --- a/unittest/test_storage.py +++ b/unittest/test_storage.py @@ -83,7 +83,20 @@ def test_clear_new_sd_card_notification(C): @pytest.mark.skip def test_fill_SD_card(C): - assert C.NK_fill_SD_card_with_random_data(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK + status = C.NK_fill_SD_card_with_random_data(DefaultPasswords.ADMIN) + assert status == DeviceErrorCode.STATUS_OK or status == DeviceErrorCode.BUSY + while 1: + value = C.NK_get_progress_bar_value() + if value == -1: break + assert 0 <= value <= 100 + assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK + wait(5) + + +def test_get_busy_progress_on_idle(C): + value = C.NK_get_progress_bar_value() + assert value == -1 + assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK def test_change_update_password(C): -- cgit v1.2.3