summaryrefslogtreecommitdiff
path: root/unittest
diff options
context:
space:
mode:
authorSzczepan Zalega <szczepan@nitrokey.com>2018-03-02 11:41:13 +0100
committerSzczepan Zalega <szczepan@nitrokey.com>2018-03-02 11:41:13 +0100
commit379daf936caa7fc8d7311a5dda101edb40d35ca5 (patch)
tree2d186dec6976b12a9f7b37e589c02703275a30ef /unittest
parentd5486ba77235a874245fbee07a75cea89fa59ea2 (diff)
parentc3d615b659b608f3a1d624f6fc78c303efbe1f8e (diff)
downloadlibnitrokey-379daf936caa7fc8d7311a5dda101edb40d35ca5.tar.gz
libnitrokey-379daf936caa7fc8d7311a5dda101edb40d35ca5.tar.bz2
Merge branch 'wip-multiple_devices'
Allow to use multiple devices, iteratively. Storage only.
Diffstat (limited to 'unittest')
-rw-r--r--unittest/misc.py7
-rw-r--r--unittest/test_C_API.cpp28
-rw-r--r--unittest/test_multiple.py60
-rw-r--r--unittest/test_multiple_devices.cc152
-rw-r--r--unittest/test_pro.py6
5 files changed, 247 insertions, 6 deletions
diff --git a/unittest/misc.py b/unittest/misc.py
index a41f2b2..8be915d 100644
--- a/unittest/misc.py
+++ b/unittest/misc.py
@@ -43,7 +43,7 @@ def cast_pointer_to_tuple(obj, typen, len):
def get_devices_firmware_version(C):
- firmware = C.NK_get_major_firmware_version()
+ firmware = C.NK_get_minor_firmware_version()
return firmware
@@ -54,7 +54,7 @@ def is_pro_rtm_07(C):
def is_pro_rtm_08(C):
firmware = get_devices_firmware_version(C)
- return firmware == 8
+ return firmware in [8,9]
def is_storage(C):
@@ -62,7 +62,8 @@ def is_storage(C):
exact firmware storage is sent by other function
"""
# TODO identify connected device directly
- return not is_pro_rtm_08(C) and not is_pro_rtm_07(C)
+ firmware = get_devices_firmware_version(C)
+ return firmware >= 45
def is_long_OTP_secret_handled(C):
diff --git a/unittest/test_C_API.cpp b/unittest/test_C_API.cpp
index be47f08..2d83ef4 100644
--- a/unittest/test_C_API.cpp
+++ b/unittest/test_C_API.cpp
@@ -43,6 +43,7 @@ TEST_CASE("C API connect", "[BASIC]") {
TEST_CASE("Check retry count", "[BASIC]") {
REQUIRE(login != 0);
+ NK_set_debug_level(3);
REQUIRE(NK_get_admin_retry_count() == 3);
REQUIRE(NK_get_user_retry_count() == 3);
}
@@ -56,4 +57,31 @@ TEST_CASE("Check long strings", "[STANDARD]") {
result = NK_change_user_PIN(pin, longPin);
REQUIRE(result == TOO_LONG_STRING);
CAPTURE(result);
+}
+
+#include <string.h>
+
+TEST_CASE("multiple devices with ID", "[BASIC]") {
+ NK_logout();
+ NK_set_debug_level(3);
+ auto s = NK_list_devices_by_cpuID();
+ REQUIRE(s!=nullptr);
+ REQUIRE(strnlen(s, 4096) < 4096);
+ REQUIRE(strnlen(s, 4096) > 2*4);
+ std::cout << s << std::endl;
+
+ char *string, *token;
+ int t;
+
+ string = strndup(s, 4096);
+ free ( (void*) s);
+
+ while ((token = strsep(&string, ";")) != nullptr){
+ if (strnlen(token, 4096) < 3) continue;
+ std::cout << token << " connecting: ";
+ std::cout << (t=NK_connect_with_ID(token)) << std::endl;
+ REQUIRE(t == 1);
+ }
+
+ free (string);
} \ No newline at end of file
diff --git a/unittest/test_multiple.py b/unittest/test_multiple.py
new file mode 100644
index 0000000..7ea195e
--- /dev/null
+++ b/unittest/test_multiple.py
@@ -0,0 +1,60 @@
+import pprint
+from time import sleep
+
+import pytest
+from collections import defaultdict
+
+from tqdm import tqdm
+
+from conftest import skip_if_device_version_lower_than
+from constants import DefaultPasswords, DeviceErrorCode, bb
+from misc import gs, wait
+
+pprint = pprint.PrettyPrinter(indent=4).pprint
+
+
+@pytest.mark.other
+@pytest.mark.info
+def test_get_status_storage_multiple(C):
+ ids = gs(C.NK_list_devices_by_cpuID())
+ print(ids)
+ devices_list = ids.split(b';')
+ #
+ # for s in devices_list:
+ # res = C.NK_connect_with_ID(s)
+ # assert res == 1
+ # # st = gs(C.NK_get_status_storage_as_string())
+ # # print(len(st))
+ # C.NK_lock_device()
+ #
+ for s in devices_list:
+ res = C.NK_connect_with_ID(s)
+ assert res == 1
+ v = C.NK_fill_SD_card_with_random_data(b'12345678')
+ # print(v)
+
+ devices_count = len(devices_list)
+ assert devices_count != 0
+ b = 0
+
+ last_b = 0
+ with tqdm(total=devices_count*100) as pbar:
+ while b/devices_count < 100:
+ pbar.update(b - last_b)
+
+ b = defaultdict (lambda: 0)
+
+ ids = gs(C.NK_list_devices_by_cpuID())
+ devices_list = ids.split(b';')
+ devices_count = len(devices_list)
+
+ for s in devices_list:
+ res = C.NK_connect_with_ID(s)
+ if res != 1: continue
+ b[s] += C.NK_get_progress_bar_value()
+ print(b)
+ b = sum(b.values())
+ print('{}: {}'.format(b, int(b/devices_count) * '='))
+ sleep(5)
+
+
diff --git a/unittest/test_multiple_devices.cc b/unittest/test_multiple_devices.cc
new file mode 100644
index 0000000..f497908
--- /dev/null
+++ b/unittest/test_multiple_devices.cc
@@ -0,0 +1,152 @@
+
+static const char *const default_admin_pin = "12345678";
+static const char *const default_user_pin = "123456";
+const char * temporary_password = "123456789012345678901234";
+const char * RFC_SECRET = "12345678901234567890";
+
+#include "catch.hpp"
+
+#include <iostream>
+#include <NitrokeyManager.h>
+#include <stick20_commands.h>
+
+using namespace nitrokey;
+
+
+TEST_CASE("List devices", "[BASIC]") {
+ shared_ptr<Stick20> d = make_shared<Stick20>();
+ auto v = d->enumerate();
+ REQUIRE(v.size() > 0);
+ for (auto a : v){
+ std::cout << a;
+ d->set_path(a);
+ d->connect();
+ auto res = GetStatus::CommandTransaction::run(d);
+ auto res2 = GetDeviceStatus::CommandTransaction::run(d);
+ std::cout << " " << res.data().card_serial_u32 << " "
+ << res.data().get_card_serial_hex()
+ << " " << std::to_string(res2.data().versionInfo.minor)
+ << std::endl;
+ d->disconnect();
+ }
+}
+
+TEST_CASE("Regenerate AES keys", "[BASIC]") {
+ shared_ptr<Stick20> d = make_shared<Stick20>();
+ auto v = d->enumerate();
+ REQUIRE(v.size() > 0);
+
+ std::vector<shared_ptr<Stick20>> devices;
+ for (auto a : v){
+ std::cout << a << endl;
+ d = make_shared<Stick20>();
+ d->set_path(a);
+ d->connect();
+ devices.push_back(d);
+ }
+
+ for (auto d : devices){
+ auto res2 = GetDeviceStatus::CommandTransaction::run(d);
+ std::cout << std::to_string(res2.data().versionInfo.minor) << std::endl;
+// nitrokey::proto::stick20::CreateNewKeys::CommandPayload p;
+// p.set_defaults();
+// memcpy(p.password, "12345678", 8);
+// auto res3 = nitrokey::proto::stick20::CreateNewKeys::CommandTransaction::run(d, p);
+ }
+
+ for (auto d : devices){
+ //TODO watch out for multiple hid_exit calls
+ d->disconnect();
+ }
+}
+
+
+TEST_CASE("Use API", "[BASIC]") {
+ auto nm = NitrokeyManager::instance();
+ nm->set_loglevel(2);
+ auto v = nm->list_devices();
+ REQUIRE(v.size() > 0);
+
+ for (int i=0; i<10; i++){
+ for (auto a : v) {
+ std::cout <<"Connect with: " << a <<
+ " " << std::boolalpha << nm->connect_with_path(a) << " ";
+ try{
+ auto status_storage = nm->get_status_storage();
+ std::cout << status_storage.ActiveSmartCardID_u32
+ << " " << status_storage.ActiveSD_CardID_u32
+ << std::endl;
+
+// nm->fill_SD_card_with_random_data("12345678");
+ }
+ catch (const LongOperationInProgressException &e){
+ std::cout << "long operation in progress on " << a
+ << " " << std::to_string(e.progress_bar_value) << std::endl;
+// this_thread::sleep_for(1000ms);
+ }
+ }
+ std::cout <<"Iteration: " << i << std::endl;
+ }
+
+}
+
+
+TEST_CASE("Use API ID", "[BASIC]") {
+ auto nm = NitrokeyManager::instance();
+ nm->set_loglevel(2);
+
+ auto v = nm->list_devices_by_cpuID();
+ REQUIRE(v.size() > 0);
+
+ //no refresh - should not reconnect to new devices
+ // Scenario:
+ // 1. Run test
+ // 2. Remove one of the devices and reinsert it after a while
+ // 3. Device should not be reconnected and test should not crash
+ // 4. Remove all devices - test should continue
+
+ for (int j = 0; j < 100; j++) {
+ for (auto i : v) {
+ if (!nm->connect_with_ID(i)) continue;
+ int retry_count = 99;
+ try {
+ retry_count = nm->get_admin_retry_count();
+ std::cout << j << " " << i << " " << to_string(retry_count) << std::endl;
+ }
+ catch (...) {
+ retry_count = 99;
+ //pass
+ }
+ }
+ }
+ std::cout << "finished" << std::endl;
+}
+
+TEST_CASE("Use API ID refresh", "[BASIC]") {
+ auto nm = NitrokeyManager::instance();
+ nm->set_loglevel(2);
+
+ //refresh in each iteration - should reconnect to new devices
+ // Scenario:
+ // 1. Run test
+ // 2. Remove one of the devices and reinsert it after a while
+ // 3. Device should be reconnected
+
+ for(int j=0; j<100; j++) {
+ auto v = nm->list_devices_by_cpuID();
+ REQUIRE(v.size() > 0);
+ for (auto i : v) {
+ nm->connect_with_ID(i);
+ int retry_count = 99;
+ try {
+ retry_count = nm->get_admin_retry_count();
+ std::cout << j <<" " << i << " " << to_string(retry_count) << std::endl;
+ }
+ catch (...){
+ retry_count = 99;
+ //pass
+ }
+ }
+ }
+ std::cout << "finished" << std::endl;
+} \ No newline at end of file
diff --git a/unittest/test_pro.py b/unittest/test_pro.py
index 12a34e9..53588f6 100644
--- a/unittest/test_pro.py
+++ b/unittest/test_pro.py
@@ -164,9 +164,9 @@ def test_password_safe_slot_status(C):
@pytest.mark.aes
def test_issue_device_locks_on_second_key_generation_in_sequence(C):
- if is_pro_rtm_07(C) or is_pro_rtm_08(C):
- pytest.skip("issue to register: device locks up "
- "after below commands sequence (reinsertion fixes), skipping for now")
+# if is_pro_rtm_07(C) or is_pro_rtm_08(C):
+ pytest.skip("issue to register: device locks up "
+ "after below commands sequence (reinsertion fixes), skipping for now")
assert C.NK_build_aes_key(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK
assert C.NK_build_aes_key(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK