summaryrefslogtreecommitdiff
path: root/unittest
diff options
context:
space:
mode:
authorSzczepan Zalega <szczepan@nitrokey.com>2017-03-11 17:18:59 +0100
committerSzczepan Zalega <szczepan@nitrokey.com>2017-03-11 17:18:59 +0100
commit22d05ce647281056d71fbd3c31df3bcd6396188d (patch)
tree90208930f54c47987bfd5ffcf0a0acaaad2510da /unittest
parented5044da43172d86a1aa475473561a4818b7c69c (diff)
parentac6b9c18ef55f4cd36e85069cf0cf82c14e04404 (diff)
downloadlibnitrokey-22d05ce647281056d71fbd3c31df3bcd6396188d.tar.gz
libnitrokey-22d05ce647281056d71fbd3c31df3bcd6396188d.tar.bz2
Merge branch 'libnitrokey_3'
Diffstat (limited to 'unittest')
-rw-r--r--unittest/Makefile33
-rw-r--r--unittest/conftest.py22
-rw-r--r--unittest/requirements.txt1
-rw-r--r--unittest/setup_python_dependencies.sh3
-rw-r--r--unittest/test.cc10
-rw-r--r--unittest/test2.cc28
-rw-r--r--unittest/test3.cc27
-rw-r--r--unittest/test_C_API.cpp4
-rw-r--r--unittest/test_HOTP.cc9
-rw-r--r--unittest/test_pro.py83
-rw-r--r--unittest/test_storage.py155
11 files changed, 288 insertions, 87 deletions
diff --git a/unittest/Makefile b/unittest/Makefile
deleted file mode 100644
index dbd003e..0000000
--- a/unittest/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-CC = $(PREFIX)-gcc
-#CXX = $(PREFIX)-g++
-CXX = clang++-3.8
-LD = $(CXX)
-
-INCLUDE = -I../include -ICatch/single_include/
-LIB = -L../build
-LDLIBS = -lnitrokey
-BUILD = build
-
-CXXFLAGS = -std=c++14 -fPIC -Wno-gnu-variable-sized-type-not-at-end
-
-CXXSOURCES = $(wildcard *.cc)
-TARGETS = $(CXXSOURCES:%.cc=$(BUILD)/%)
-DEPENDS = $(CXXSOURCES:%.cc=$(BUILD)/%.d)
-
-$(BUILD)/%.d: %.cc
- $(CXX) -M $< -o $@ $(INCLUDE) $(CXXFLAGS)
-
-$(BUILD)/%: %.cc $(DEPENDS)
- $(CXX) $< -o $@ $(INCLUDE) $(LIB) $(CXXFLAGS) $(LDLIBS)
-
-all: $(TARGETS)
-
-clean:
- rm -f $(TARGETS)
-
-mrproper: clean
- rm -f $(BUILD)/*.d
-
-.PHONY: all clean mrproper
-
-include $(wildcard build/*.d)
diff --git a/unittest/conftest.py b/unittest/conftest.py
index 88bf7d0..67b45aa 100644
--- a/unittest/conftest.py
+++ b/unittest/conftest.py
@@ -22,14 +22,30 @@ def C(request):
a = iter(declarations)
for declaration in a:
- if declaration.startswith('extern') and not '"C"' in declaration:
- declaration = declaration.replace('extern', '').strip()
+ if declaration.startswith('NK_C_API'):
+ declaration = declaration.replace('NK_C_API', '').strip()
while not ';' in declaration:
declaration += (next(a)).strip()
print(declaration)
ffi.cdef(declaration, override=True)
- C = ffi.dlopen("../build/libnitrokey.so")
+ C = None
+ import os, sys
+ path_build = os.path.join("..", "build")
+ paths = [ os.path.join(path_build,"libnitrokey-log.so"),
+ os.path.join(path_build,"libnitrokey.so")]
+ for p in paths:
+ print p
+ if os.path.exists(p):
+ C = ffi.dlopen(p)
+ break
+ else:
+ print("File does not exist: " + p)
+ print("Trying another")
+ if not C:
+ print("No library file found")
+ sys.exit(1)
+
C.NK_set_debug(False)
nk_login = C.NK_login_auto()
if nk_login != 1:
diff --git a/unittest/requirements.txt b/unittest/requirements.txt
index 7224741..2cb9c05 100644
--- a/unittest/requirements.txt
+++ b/unittest/requirements.txt
@@ -2,3 +2,4 @@ cffi
pytest-repeat
pytest-randomly
enum
+oath \ No newline at end of file
diff --git a/unittest/setup_python_dependencies.sh b/unittest/setup_python_dependencies.sh
new file mode 100644
index 0000000..0f1a0f7
--- /dev/null
+++ b/unittest/setup_python_dependencies.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+pip install -r requirements.txt --user
diff --git a/unittest/test.cc b/unittest/test.cc
index 6744b45..15235bd 100644
--- a/unittest/test.cc
+++ b/unittest/test.cc
@@ -1,4 +1,3 @@
-#define CATCH_CONFIG_MAIN // This tells Catch to provide a main()
#include "catch.hpp"
#include <iostream>
@@ -13,8 +12,9 @@ using namespace nitrokey::proto::stick10;
using namespace nitrokey::log;
using namespace nitrokey::misc;
+using Dev10 = std::shared_ptr<Stick10>;
-std::string getSlotName(Stick10 &stick, int slotNo) {
+std::string getSlotName(Dev10 stick, int slotNo) {
auto slot_req = get_payload<ReadSlot>();
slot_req.slot_number = slotNo;
auto slot = ReadSlot::CommandTransaction::run(stick, slot_req);
@@ -23,8 +23,8 @@ std::string getSlotName(Stick10 &stick, int slotNo) {
}
TEST_CASE("Slot names are correct", "[slotNames]") {
- Stick10 stick;
- bool connected = stick.connect();
+ auto stick = make_shared<Stick10>();
+ bool connected = stick->connect();
REQUIRE(connected == true);
Log::instance().set_loglevel(Loglevel::DEBUG);
@@ -79,5 +79,5 @@ TEST_CASE("Slot names are correct", "[slotNames]") {
REQUIRE(sName == std::string("login1"));
}
- stick.disconnect();
+ stick->disconnect();
}
diff --git a/unittest/test2.cc b/unittest/test2.cc
index 00e70e3..31dbce8 100644
--- a/unittest/test2.cc
+++ b/unittest/test2.cc
@@ -1,4 +1,3 @@
-#define CATCH_CONFIG_MAIN // This tells Catch to provide a main()
static const char *const default_admin_pin = "12345678";
static const char *const default_user_pin = "123456";
@@ -20,9 +19,10 @@ using namespace nitrokey::proto::stick20;
using namespace nitrokey::log;
using namespace nitrokey::misc;
+#include <memory>
template<typename CMDTYPE>
-void execute_password_command(Device &stick, const char *password, const char kind = 'P') {
+void execute_password_command(std::shared_ptr<Device> stick, const char *password, const char kind = 'P') {
auto p = get_payload<CMDTYPE>();
if (kind == 'P'){
p.set_kind_user();
@@ -47,8 +47,8 @@ void SKIP_TEST() {
TEST_CASE("long operation test", "[test_long]") {
SKIP_TEST();
- Stick20 stick;
- bool connected = stick.connect();
+ auto stick = make_shared<Stick20>();
+ bool connected = stick->connect();
REQUIRE(connected == true);
Log::instance().set_loglevel(Loglevel::DEBUG);
try{
@@ -123,8 +123,8 @@ TEST_CASE("test device commands ids", "[fast]") {
}
TEST_CASE("test device internal status with various commands", "[fast]") {
- Stick20 stick;
- bool connected = stick.connect();
+ auto stick = make_shared<Stick20>();
+ bool connected = stick->connect();
REQUIRE(connected == true);
Log::instance().set_loglevel(Loglevel::DEBUG);
@@ -147,8 +147,8 @@ TEST_CASE("test device internal status with various commands", "[fast]") {
}
TEST_CASE("setup hidden volume test", "[hidden]") {
- Stick20 stick;
- bool connected = stick.connect();
+ auto stick = make_shared<Stick20>();
+ bool connected = stick->connect();
REQUIRE(connected == true);
Log::instance().set_loglevel(Loglevel::DEBUG);
stick10::LockDevice::CommandTransaction::run(stick);
@@ -170,8 +170,8 @@ TEST_CASE("setup hidden volume test", "[hidden]") {
}
TEST_CASE("setup multiple hidden volumes", "[hidden]") {
- Stick20 stick;
- bool connected = stick.connect();
+ auto stick = make_shared<Stick20>();
+ bool connected = stick->connect();
REQUIRE(connected == true);
Log::instance().set_loglevel(Loglevel::DEBUG);
@@ -207,8 +207,8 @@ TEST_CASE("setup multiple hidden volumes", "[hidden]") {
TEST_CASE("update password change", "[dangerous]") {
SKIP_TEST();
- Stick20 stick;
- bool connected = stick.connect();
+ auto stick = make_shared<Stick20>();
+ bool connected = stick->connect();
REQUIRE(connected == true);
Log::instance().set_loglevel(Loglevel::DEBUG);
@@ -228,8 +228,8 @@ TEST_CASE("update password change", "[dangerous]") {
}
TEST_CASE("general test", "[test]") {
- Stick20 stick;
- bool connected = stick.connect();
+ auto stick = make_shared<Stick20>();
+ bool connected = stick->connect();
REQUIRE(connected == true);
Log::instance().set_loglevel(Loglevel::DEBUG);
diff --git a/unittest/test3.cc b/unittest/test3.cc
index 9049365..9e0ef11 100644
--- a/unittest/test3.cc
+++ b/unittest/test3.cc
@@ -1,8 +1,3 @@
-//
-// Created by sz on 08.11.16.
-//
-
-#define CATCH_CONFIG_MAIN // This tells Catch to provide a main()
static const char *const default_admin_pin = "12345678";
static const char *const default_user_pin = "123456";
@@ -26,13 +21,16 @@ using namespace nitrokey::proto::stick10_08;
using namespace nitrokey::log;
using namespace nitrokey::misc;
-void connect_and_setup(Stick10 &stick) {
- bool connected = stick.connect();
+using Dev = Stick10;
+using Dev10 = std::shared_ptr<Dev>;
+
+void connect_and_setup(Dev10 stick) {
+ bool connected = stick->connect();
REQUIRE(connected == true);
Log::instance().set_loglevel(Loglevel::DEBUG);
}
-void authorize(Stick10 &stick) {
+void authorize(Dev10 stick) {
auto authreq = get_payload<FirstAuthenticate>();
strcpy((char *) (authreq.card_password), default_admin_pin);
strcpy((char *) (authreq.temporary_password), temporary_password);
@@ -45,7 +43,8 @@ void authorize(Stick10 &stick) {
}
TEST_CASE("write slot", "[pronew]"){
- Stick10 stick;
+ auto stick = make_shared<Dev>();
+
connect_and_setup(stick);
authorize(stick);
@@ -81,7 +80,7 @@ TEST_CASE("write slot", "[pronew]"){
TEST_CASE("erase slot", "[pronew]"){
- Stick10 stick;
+ auto stick = make_shared<Dev>();
connect_and_setup(stick);
authorize(stick);
@@ -107,7 +106,7 @@ TEST_CASE("erase slot", "[pronew]"){
}
TEST_CASE("write general config", "[pronew]") {
- Stick10 stick;
+ auto stick = make_shared<Dev>();
connect_and_setup(stick);
authorize(stick);
@@ -121,7 +120,7 @@ TEST_CASE("write general config", "[pronew]") {
}
TEST_CASE("authorize user HOTP", "[pronew]") {
- Stick10 stick;
+ auto stick = make_shared<Dev>();
connect_and_setup(stick);
authorize(stick);
@@ -164,7 +163,7 @@ TEST_CASE("authorize user HOTP", "[pronew]") {
}
TEST_CASE("check firmware version", "[pronew]") {
- Stick10 stick;
+ auto stick = make_shared<Dev>();
connect_and_setup(stick);
auto p = GetStatus::CommandTransaction::run(stick);
@@ -172,7 +171,7 @@ TEST_CASE("check firmware version", "[pronew]") {
}
TEST_CASE("authorize user TOTP", "[pronew]") {
- Stick10 stick;
+ auto stick = make_shared<Dev>();
connect_and_setup(stick);
authorize(stick);
diff --git a/unittest/test_C_API.cpp b/unittest/test_C_API.cpp
index 37d3c7f..160145b 100644
--- a/unittest/test_C_API.cpp
+++ b/unittest/test_C_API.cpp
@@ -24,8 +24,8 @@ TEST_CASE("Check retry count", "[BASIC]") {
}
TEST_CASE("Check long strings", "[STANDARD]") {
- char* longPin = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
- char *pin = "123123123";
+ const char* longPin = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ const char* pin = "123123123";
auto result = NK_change_user_PIN(longPin, pin);
REQUIRE(result == TOO_LONG_STRING);
result = NK_change_user_PIN(pin, longPin);
diff --git a/unittest/test_HOTP.cc b/unittest/test_HOTP.cc
index d31df55..e6f7d7c 100644
--- a/unittest/test_HOTP.cc
+++ b/unittest/test_HOTP.cc
@@ -1,4 +1,3 @@
-#define CATCH_CONFIG_MAIN // This tells Catch to provide a main()
#include "catch.hpp"
#include <iostream>
#include "device_proto.h"
@@ -14,7 +13,7 @@ using namespace nitrokey::log;
using namespace nitrokey::misc;
void hexStringToByte(uint8_t data[], const char* hexString){
- assert(strlen(hexString)%2==0);
+ REQUIRE(strlen(hexString)%2==0);
char buf[2];
for(int i=0; i<strlen(hexString); i++){
buf[i%2] = hexString[i];
@@ -34,8 +33,8 @@ TEST_CASE("test secret", "[functions]") {
}
TEST_CASE("Test HOTP codes according to RFC", "[HOTP]") {
- Stick10 stick;
- bool connected = stick.connect();
+ std::shared_ptr<Stick10> stick = make_shared<Stick10>();
+ bool connected = stick->connect();
REQUIRE(connected == true);
@@ -98,5 +97,5 @@ TEST_CASE("Test HOTP codes according to RFC", "[HOTP]") {
}
- stick.disconnect();
+ stick->disconnect();
}
diff --git a/unittest/test_pro.py b/unittest/test_pro.py
index 4a2a504..0140994 100644
--- a/unittest/test_pro.py
+++ b/unittest/test_pro.py
@@ -22,6 +22,72 @@ def test_write_password_safe_slot(C):
assert C.NK_write_password_safe_slot(0, 'slotname1', 'login1', 'pass1') == DeviceErrorCode.STATUS_OK
+@pytest.mark.slowtest
+def test_write_all_password_safe_slots_and_read_10_times(C):
+ def fill(s, wid):
+ assert wid >= len(s)
+ numbers = '1234567890'*4
+ s += numbers[:wid-len(s)]
+ assert len(s) == wid
+ return s
+
+ def get_pass(suffix):
+ return fill('pass' + suffix, 20)
+
+ def get_loginname(suffix):
+ return fill('login' + suffix, 32)
+
+ def get_slotname(suffix):
+ return fill('slotname' + suffix, 11)
+
+ assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
+ assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
+ PWS_slot_count = 16
+ for i in range(0, PWS_slot_count):
+ iss = str(i)
+ assert C.NK_write_password_safe_slot(i,
+ get_slotname(iss), get_loginname(iss),
+ get_pass(iss)) == DeviceErrorCode.STATUS_OK
+
+ for j in range(0, 10):
+ for i in range(0, PWS_slot_count):
+ iss = str(i)
+ assert gs(C.NK_get_password_safe_slot_name(i)) == get_slotname(iss)
+ assert gs(C.NK_get_password_safe_slot_login(i)) == get_loginname(iss)
+ assert gs(C.NK_get_password_safe_slot_password(i)) == get_pass(iss)
+
+
+@pytest.mark.slowtest
+@pytest.mark.xfail(reason="This test should be run directly after test_write_all_password_safe_slots_and_read_10_times")
+def test_read_all_password_safe_slots_10_times(C):
+ def fill(s, wid):
+ assert wid >= len(s)
+ numbers = '1234567890'*4
+ s += numbers[:wid-len(s)]
+ assert len(s) == wid
+ return s
+
+ def get_pass(suffix):
+ return fill('pass' + suffix, 20)
+
+ def get_loginname(suffix):
+ return fill('login' + suffix, 32)
+
+ def get_slotname(suffix):
+ return fill('slotname' + suffix, 11)
+
+ assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
+ assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
+ PWS_slot_count = 16
+
+ for j in range(0, 10):
+ for i in range(0, PWS_slot_count):
+ iss = str(i)
+ assert gs(C.NK_get_password_safe_slot_name(i)) == get_slotname(iss)
+ assert gs(C.NK_get_password_safe_slot_login(i)) == get_loginname(iss)
+ assert gs(C.NK_get_password_safe_slot_password(i)) == get_pass(iss)
+
+
def test_get_password_safe_slot_name(C):
assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
assert C.NK_write_password_safe_slot(0, 'slotname1', 'login1', 'pass1') == DeviceErrorCode.STATUS_OK
@@ -82,6 +148,9 @@ def test_regenerate_aes_key(C):
def test_enable_password_safe_after_factory_reset(C):
assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
+ if is_storage(C):
+ # for some reason storage likes to be authenticated before reset (to investigate)
+ assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK
assert C.NK_factory_reset(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK
wait(10)
if is_storage(C):
@@ -523,7 +592,7 @@ def test_OTP_secret_started_from_null(C, secret):
skip_if_device_version_lower_than({'S': 43, 'P': 8})
if len(secret) > 40:
# feature: 320 bit long secret handling
- skip_if_device_version_lower_than({'S': 44, 'P': 8})
+ skip_if_device_version_lower_than({'P': 8})
oath = pytest.importorskip("oath")
lib_at = lambda t: oath.hotp(secret, t, format='dec6')
@@ -617,8 +686,9 @@ def test_TOTP_secrets(C, secret):
'''
skip_if_device_version_lower_than({'S': 44, 'P': 8})
- if is_pro_rtm_07(C) and len(secret)>20*2: #*2 since secret is in hex
- pytest.skip("Secret lengths over 20 bytes are not supported by NK Pro 0.7 ")
+ if len(secret)>20*2: #*2 since secret is in hex
+ # pytest.skip("Secret lengths over 20 bytes are not supported by NK Pro 0.7 and NK Storage")
+ skip_if_device_version_lower_than({'P': 8})
slot_number = 0
time = 0
period = 30
@@ -645,10 +715,11 @@ def test_TOTP_secrets(C, secret):
@pytest.mark.parametrize("secret", [RFC_SECRET, 2*RFC_SECRET, '12'*10, '12'*30] )
def test_HOTP_secrets(C, secret):
"""
- NK Pro 0.8+, NK Storage 0.44+
+ NK Pro 0.8+
feature needed: support for 320bit secrets
"""
- skip_if_device_version_lower_than({'S': 44, 'P': 8})
+ if len(secret)>40:
+ skip_if_device_version_lower_than({'P': 8})
slot_number = 0
counter = 0
@@ -695,7 +766,7 @@ def test_edit_OTP_slot(C):
"""
should change slots counter and name without changing its secret (using null secret for second update)
"""
- # counter does not reset under Storage v0.43
+ # counter is not getting updated under Storage v0.43 - #TOREPORT
skip_if_device_version_lower_than({'S': 44, 'P': 7})
secret = RFC_SECRET
diff --git a/unittest/test_storage.py b/unittest/test_storage.py
index a1c59aa..da7c9a3 100644
--- a/unittest/test_storage.py
+++ b/unittest/test_storage.py
@@ -57,10 +57,11 @@ def test_encrypted_volume_unlock_hidden(C):
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
-@pytest.mark.skip(reason='hangs device, to report')
-def test_encrypted_volume_setup_multiple_hidden(C):
- skip_if_device_version_lower_than({'S': 43})
- hidden_volume_password = 'hiddenpassword'
+
+def test_encrypted_volume_setup_multiple_hidden_lock(C):
+ import random
+ skip_if_device_version_lower_than({'S': 45}) #hangs device on lower version
+ hidden_volume_password = 'hiddenpassword' + str(random.randint(0,100))
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
@@ -72,6 +73,149 @@ def test_encrypted_volume_setup_multiple_hidden(C):
assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK
+@pytest.mark.parametrize("volumes_to_setup", range(1, 5))
+def test_encrypted_volume_setup_multiple_hidden_no_lock_device_volumes(C, volumes_to_setup):
+ skip_if_device_version_lower_than({'S': 43})
+ 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(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_lock_encrypted_volume() == DeviceErrorCode.STATUS_OK
+ assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
+
+ for i in range(volumes_to_setup):
+ assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK
+ # TODO mount and test for files
+ assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK
+
+
+@pytest.mark.parametrize("volumes_to_setup", range(1, 5))
+def test_encrypted_volume_setup_multiple_hidden_no_lock_device_volumes_unlock_at_once(C, volumes_to_setup):
+ skip_if_device_version_lower_than({'S': 43})
+ 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(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
+ assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK
+
+ assert C.NK_lock_encrypted_volume() == DeviceErrorCode.STATUS_OK
+ assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
+
+ for i in range(volumes_to_setup):
+ assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK
+ # TODO mount and test for files
+ assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK
+
+
+@pytest.mark.parametrize("use_slot", range(4))
+def test_encrypted_volume_setup_one_hidden_no_lock_device_slot(C, use_slot):
+ skip_if_device_version_lower_than({'S': 43})
+ 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
+ i = use_slot
+ 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
+ assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK
+
+ assert C.NK_lock_encrypted_volume() == DeviceErrorCode.STATUS_OK
+ assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
+
+ for j in range(3):
+ assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK
+ # TODO mount and test for files
+ assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK
+
+
+def test_password_safe_slot_name_corruption(C):
+ skip_if_device_version_lower_than({'S': 43})
+ volumes_to_setup = 4
+ # connected with encrypted volumes, possible also with hidden
+ def fill(s, wid):
+ assert wid >= len(s)
+ numbers = '1234567890' * 4
+ s += numbers[:wid - len(s)]
+ assert len(s) == wid
+ return s
+
+ def get_pass(suffix):
+ return fill('pass' + suffix, 20)
+
+ def get_loginname(suffix):
+ return fill('login' + suffix, 32)
+
+ def get_slotname(suffix):
+ return fill('slotname' + suffix, 11)
+
+ assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
+ assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
+ PWS_slot_count = 16
+ for i in range(0, PWS_slot_count):
+ iss = str(i)
+ assert C.NK_write_password_safe_slot(i,
+ get_slotname(iss), get_loginname(iss),
+ get_pass(iss)) == DeviceErrorCode.STATUS_OK
+
+ def check_PWS_correctness(C):
+ for i in range(0, PWS_slot_count):
+ iss = str(i)
+ assert gs(C.NK_get_password_safe_slot_name(i)) == get_slotname(iss)
+ assert gs(C.NK_get_password_safe_slot_login(i)) == get_loginname(iss)
+ assert gs(C.NK_get_password_safe_slot_password(i)) == get_pass(iss)
+
+ hidden_volume_password = 'hiddenpassword'
+ p = lambda i: hidden_volume_password + str(i)
+ def check_volumes_correctness(C):
+ for i in range(volumes_to_setup):
+ assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK
+ # TODO mount and test for files
+ assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK
+
+ check_PWS_correctness(C)
+
+ 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
+ assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK
+
+ assert C.NK_lock_encrypted_volume() == DeviceErrorCode.STATUS_OK
+ assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
+
+ check_volumes_correctness(C)
+ check_PWS_correctness(C)
+ check_volumes_correctness(C)
+ check_PWS_correctness(C)
+
+ assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
+ assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
+ check_volumes_correctness(C)
+ check_PWS_correctness(C)
+ assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
+ assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
+ check_volumes_correctness(C)
+ check_PWS_correctness(C)
+
+def test_hidden_volume_corruption(C):
+ # bug: this should return error without unlocking encrypted volume each hidden volume lock, but it does not
+ assert C.NK_lock_encrypted_volume() == DeviceErrorCode.STATUS_OK
+ assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
+ hidden_volume_password = 'hiddenpassword'
+ p = lambda i: hidden_volume_password + str(i)
+ for i in range(4):
+ assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK
+ assert C.NK_unlock_hidden_volume(p(i)) == DeviceErrorCode.STATUS_OK
+ wait(2)
+ assert C.NK_lock_hidden_volume() == DeviceErrorCode.STATUS_OK
+
def test_unencrypted_volume_set_read_only(C):
skip_if_device_version_lower_than({'S': 43})
assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK
@@ -94,7 +238,8 @@ def test_clear_new_sd_card_notification(C):
assert C.NK_clear_new_sd_card_warning(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK
-@pytest.mark.skip
+@pytest.mark.slowtest
+@pytest.mark.skip(reason='long test (about 1h)')
def test_fill_SD_card(C):
skip_if_device_version_lower_than({'S': 43})
status = C.NK_fill_SD_card_with_random_data(DefaultPasswords.ADMIN)