From ab0f01c381c16ed61b8258582869912d4c38cbb7 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Wed, 28 Jun 2017 11:57:21 +0200 Subject: Adjust code to make compilation under MSVC 2017 --- CMakeLists.txt | 7 ++++++- NK_C_API.cc | 11 +++++++++++ NitrokeyManager.cc | 2 +- include/dissect.h | 4 ++-- include/misc.h | 2 +- include/stick10_commands.h | 10 +++++----- include/stick10_commands_0.8.h | 6 +++--- include/stick20_commands.h | 6 +++--- misc.cc | 14 +++++++------- 9 files changed, 39 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6741b18..11882f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,8 @@ +# https://cmake.org/pipermail/cmake/2011-May/044166.html + IF(NOT DEFINED CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS) + SET(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON) + ENDIF() + cmake_minimum_required(VERSION 3.1) IF (UNIX) OPTION(USE_CLANG "Use CLang" FALSE) @@ -111,7 +116,7 @@ install (FILES ${LIB_INCLUDES} DESTINATION "include") IF (COMPILE_TESTS) include_directories(unittest/Catch/include) - add_library(catch SHARED unittest/catch_main.cpp ) + add_library(catch STATIC unittest/catch_main.cpp ) add_executable (test_C_API unittest/test_C_API.cpp) target_link_libraries (test_C_API ${EXTRA_LIBS} ${LIBNAME}-log catch) diff --git a/NK_C_API.cc b/NK_C_API.cc index 0e3fa1f..db87d90 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -5,6 +5,17 @@ #include "include/LibraryException.h" #include "include/cxx_semantics.h" +#ifdef _WIN32 +#pragma message "Using own strndup" +char * strndup(const char* str, size_t maxlen) { + size_t len = strnlen(str, maxlen); + char* dup = (char *)malloc(len + 1); + memcpy(dup, str, len); + dup[len] = 0; + return dup; +} +#endif + using namespace nitrokey; static uint8_t NK_last_command_status = 0; diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 9a9d106..4393682 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -14,7 +14,7 @@ namespace nitrokey{ std::mutex mex_dev_com_manager; -#ifdef __WIN32 +#ifdef _WIN32 #pragma message "Using own strndup" char * strndup(const char* str, size_t maxlen){ size_t len = strnlen(str, maxlen); diff --git a/include/dissect.h b/include/dissect.h index 69a5129..06b99fa 100644 --- a/include/dissect.h +++ b/include/dissect.h @@ -22,7 +22,7 @@ class QueryDissector : semantics::non_constructible { #ifdef LOG_VOLATILE_DATA out << "Raw HID packet:" << std::endl; - out << ::nitrokey::misc::hexdump((const char *)(&pod), sizeof pod); + out << ::nitrokey::misc::hexdump((const uint8_t *)(&pod), sizeof pod); #endif out << "Contents:" << std::endl; @@ -87,7 +87,7 @@ class ResponseDissector : semantics::non_constructible { #ifdef LOG_VOLATILE_DATA out << "Raw HID packet:" << std::endl; - out << ::nitrokey::misc::hexdump((const char *)(&pod), sizeof pod); + out << ::nitrokey::misc::hexdump((const uint8_t *)(&pod), sizeof pod); #endif out << "Device status:\t" << pod.device_status + 0 << " " diff --git a/include/misc.h b/include/misc.h index 176b77c..25f3107 100644 --- a/include/misc.h +++ b/include/misc.h @@ -62,7 +62,7 @@ typename T::CommandPayload get_payload(){ CMDTYPE::CommandTransaction::run(stick, p); } - std::string hexdump(const char *p, size_t size, bool print_header=true, bool print_ascii=true, + std::string hexdump(const uint8_t *p, size_t size, bool print_header=true, bool print_ascii=true, bool print_empty=true); uint32_t stm_crc32(const uint8_t *data, size_t size); std::vector hex_string_to_byte(const char* hexString); diff --git a/include/stick10_commands.h b/include/stick10_commands.h index e863328..8f3ceef 100644 --- a/include/stick10_commands.h +++ b/include/stick10_commands.h @@ -130,7 +130,7 @@ class WriteToHOTPSlot : Command { ss << std::hex << std::setw(2) << std::setfill('0')<< (int) i << " " ; ss << std::endl; ss << "slot_counter:\t[" << (int)slot_counter << "]\t" - << ::nitrokey::misc::hexdump((const char *)(&slot_counter), sizeof slot_counter, false); + << ::nitrokey::misc::hexdump((const uint8_t *)(&slot_counter), sizeof slot_counter, false); return ss.str(); } @@ -334,7 +334,7 @@ class ReadSlot : Command { ss << std::hex << std::setw(2) << std::setfill('0')<< (int) i << " " ; ss << std::endl; ss << "slot_counter:\t[" << (int)slot_counter << "]\t" - << ::nitrokey::misc::hexdump((const char *)(&slot_counter), sizeof slot_counter, false); + << ::nitrokey::misc::hexdump((const uint8_t *)(&slot_counter), sizeof slot_counter, false); return ss.str(); } } __packed; @@ -372,13 +372,13 @@ class GetStatus : Command { ss << "firmware_version:\t" << "[" << firmware_version << "]" << "\t" << ::nitrokey::misc::hexdump( - (const char *)(&firmware_version), sizeof firmware_version, false); + (const uint8_t *)(&firmware_version), sizeof firmware_version, false); ss << "card_serial_u32:\t" << std::hex << card_serial_u32 << std::endl; ss << "card_serial:\t" - << ::nitrokey::misc::hexdump((const char *)(card_serial), + << ::nitrokey::misc::hexdump((const uint8_t *)(card_serial), sizeof card_serial, false); ss << "general_config:\t" - << ::nitrokey::misc::hexdump((const char *)(general_config), + << ::nitrokey::misc::hexdump((const uint8_t *)(general_config), sizeof general_config, false); ss << "numlock:\t" << (int)numlock << std::endl; ss << "capslock:\t" << (int)capslock << std::endl; diff --git a/include/stick10_commands_0.8.h b/include/stick10_commands_0.8.h index 4209380..361682d 100644 --- a/include/stick10_commands_0.8.h +++ b/include/stick10_commands_0.8.h @@ -94,7 +94,7 @@ namespace nitrokey { ss << "id:\t" << (int)id << std::endl; #ifdef LOG_VOLATILE_DATA ss << "data:" << std::endl - << ::nitrokey::misc::hexdump((const char *) (&data), sizeof data); + << ::nitrokey::misc::hexdump((const uint8_t *) (&data), sizeof data); #else ss << " Volatile data not logged" << std::endl; #endif @@ -113,7 +113,7 @@ namespace nitrokey { std::stringstream ss; #ifdef LOG_VOLATILE_DATA ss << "data:" << std::endl - << ::nitrokey::misc::hexdump((const char *) (&data), sizeof data); + << ::nitrokey::misc::hexdump((const uint8_t *) (&data), sizeof data); #else ss << " Volatile data not logged" << std::endl; #endif @@ -165,7 +165,7 @@ namespace nitrokey { ss << "\tuse_tokenID(2):\t" << use_tokenID << std::endl; ss << "slot_number:\t" << (int) (slot_number) << std::endl; ss << "slot_counter_or_interval:\t[" << (int) slot_counter_or_interval << "]\t" - << ::nitrokey::misc::hexdump((const char *) (&slot_counter_or_interval), sizeof slot_counter_or_interval, false); + << ::nitrokey::misc::hexdump((const uint8_t *) (&slot_counter_or_interval), sizeof slot_counter_or_interval, false); ss << "slot_token_id:\t"; for (auto i : slot_token_id) diff --git a/include/stick20_commands.h b/include/stick20_commands.h index 5f99d28..64df372 100644 --- a/include/stick20_commands.h +++ b/include/stick20_commands.h @@ -111,7 +111,7 @@ namespace nitrokey { std::string dissect() const { std::stringstream ss; ss << "_padding:" << std::endl - << ::nitrokey::misc::hexdump((const char *) (_padding), + << ::nitrokey::misc::hexdump((const uint8_t *) (_padding), sizeof _padding); print_to_ss((int) SendCounter_u8); print_to_ss((int) SendDataType_u8); @@ -138,9 +138,9 @@ namespace nitrokey { union{ uint8_t VersionInfo_au8[4]; struct { - uint8_t __reserved; + uint8_t _reserved; uint8_t minor; - uint8_t __reserved2; + uint8_t _reserved2; uint8_t major; } __packed versionInfo; } __packed; diff --git a/misc.cc b/misc.cc index 24f8514..d7278da 100644 --- a/misc.cc +++ b/misc.cc @@ -39,20 +39,20 @@ namespace misc { }; #include -::std::string hexdump(const char *p, size_t size, bool print_header, +::std::string hexdump(const uint8_t *p, size_t size, bool print_header, bool print_ascii, bool print_empty) { ::std::stringstream out; char formatbuf[128]; - const char *pstart = p; + const uint8_t *pstart = p; - for (const char *pend = p + size; p < pend;) { + for (const uint8_t *pend = p + size; p < pend;) { if (print_header){ snprintf(formatbuf, 128, "%04x\t", static_cast (p - pstart)); out << formatbuf; } - const char* pp = p; - for (const char *le = p + 16; p < le; p++) { + const uint8_t* pp = p; + for (const uint8_t *le = p + 16; p < le; p++) { if (p < pend){ snprintf(formatbuf, 128, "%02x ", uint8_t(*p)); out << formatbuf; @@ -63,8 +63,8 @@ namespace misc { } if(print_ascii){ - out << "\t"; - for (const char *le = pp + 16; pp < le && pp < pend; pp++) { + out << " "; + for (const uint8_t *le = pp + 16; pp < le && pp < pend; pp++) { if (std::isgraph(*pp)) out << uint8_t(*pp); else -- cgit v1.2.3 From 2da9ee14459d169fd033e36efe8780250b4283b1 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Wed, 28 Jun 2017 11:57:21 +0200 Subject: Run compilation using Qt Creator --- NK_C_API.cc | 20 ++++++------- NitrokeyManager.cc | 3 +- include/command.h | 2 +- libnitrokey.pro | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ unittest/test_issues.cc | 4 +-- 5 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 libnitrokey.pro diff --git a/NK_C_API.cc b/NK_C_API.cc index db87d90..3131db1 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -5,16 +5,16 @@ #include "include/LibraryException.h" #include "include/cxx_semantics.h" -#ifdef _WIN32 -#pragma message "Using own strndup" -char * strndup(const char* str, size_t maxlen) { - size_t len = strnlen(str, maxlen); - char* dup = (char *)malloc(len + 1); - memcpy(dup, str, len); - dup[len] = 0; - return dup; -} -#endif +//#ifdef _WIN32 +//#pragma message "Using own strndup" +//char * strndup(const char* str, size_t maxlen) { +// size_t len = strnlen(str, maxlen); +// char* dup = (char *)malloc(len + 1); +// memcpy(dup, str, len); +// dup[len] = 0; +// return dup; +//} +//#endif using namespace nitrokey; diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 4393682..4b3c7e1 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -14,6 +14,7 @@ namespace nitrokey{ std::mutex mex_dev_com_manager; +#ifndef strndup #ifdef _WIN32 #pragma message "Using own strndup" char * strndup(const char* str, size_t maxlen){ @@ -24,7 +25,7 @@ char * strndup(const char* str, size_t maxlen){ return dup; } #endif - +#endif using nitrokey::misc::strcpyT; diff --git a/include/command.h b/include/command.h index 3f711c0..279754a 100644 --- a/include/command.h +++ b/include/command.h @@ -11,7 +11,7 @@ #define print_to_ss_volatile(x) ( ss << " " << (#x) <<":\t" << "***********" << std::endl ); #endif #define hexdump_to_ss(x) (ss << #x":\n"\ - << ::nitrokey::misc::hexdump((const char *) (&x), sizeof x, false)); + << ::nitrokey::misc::hexdump((const uint8_t *) (&x), sizeof x, false)); namespace nitrokey { namespace proto { diff --git a/libnitrokey.pro b/libnitrokey.pro new file mode 100644 index 0000000..621a137 --- /dev/null +++ b/libnitrokey.pro @@ -0,0 +1,76 @@ +# Created by and for Qt Creator. This file was created for editing the project sources only. +# You may attempt to use it for building too, by modifying this file here. + +#TARGET = libnitrokey + +CONFIG += c++14 staticlib +#QT = + +TEMPLATE = lib +TARGET = nitrokey + +HEADERS = \ + $$PWD/hidapi/hidapi/hidapi.h \ +# $$PWD/include/hidapi/hidapi.h \ + $$PWD/include/command.h \ + $$PWD/include/command_id.h \ + $$PWD/include/CommandFailedException.h \ + $$PWD/include/cxx_semantics.h \ + $$PWD/include/device.h \ + $$PWD/include/device_proto.h \ + $$PWD/include/DeviceCommunicationExceptions.h \ + $$PWD/include/dissect.h \ + $$PWD/include/inttypes.h \ + $$PWD/include/LibraryException.h \ + $$PWD/include/log.h \ + $$PWD/include/LongOperationInProgressException.h \ + $$PWD/include/misc.h \ + $$PWD/include/NitrokeyManager.h \ + $$PWD/include/stick10_commands.h \ + $$PWD/include/stick10_commands_0.8.h \ + $$PWD/include/stick20_commands.h \ + $$PWD/NK_C_API.h + +SOURCES = \ + $$PWD/command_id.cc \ + $$PWD/device.cc \ + $$PWD/DeviceCommunicationExceptions.cpp \ + $$PWD/log.cc \ + $$PWD/misc.cc \ + $$PWD/NitrokeyManager.cc \ + $$PWD/NK_C_API.cc + + +tests { + SOURCES += \ + $$PWD/unittest/catch_main.cpp \ + $$PWD/unittest/test.cc \ + $$PWD/unittest/test2.cc \ + $$PWD/unittest/test3.cc \ + $$PWD/unittest/test_C_API.cpp \ + $$PWD/unittest/test_HOTP.cc +} + +unix:!macx{ + SOURCES += $$PWD/hidapi/linux/hid.c +} + +unix{ + SOURCES += $$PWD/hidapi/mac/hid.c +} + +#win32 { + SOURCES += $$PWD/hidapi/windows/hid.c + LIBS += -lsetupapi +#} + +INCLUDEPATH = \ + $$PWD/. \ + $$PWD/hidapi/hidapi \ + $$PWD/include \ + $$PWD/include/hidapi \ + $$PWD/unittest \ + $$PWD/unittest/Catch/single_include + +#DEFINES = + diff --git a/unittest/test_issues.cc b/unittest/test_issues.cc index ec3f933..63ce678 100644 --- a/unittest/test_issues.cc +++ b/unittest/test_issues.cc @@ -15,7 +15,7 @@ using namespace nitrokey; bool test_36(){ auto i = NitrokeyManager::instance(); - i->set_debug(true); + i->set_loglevel(3); REQUIRE(i->connect()); for (int j = 0; j < 200; ++j) { @@ -28,7 +28,7 @@ bool test_36(){ bool test_31(){ auto i = NitrokeyManager::instance(); - i->set_debug(true); + i->set_loglevel(3); REQUIRE(i->connect()); // i->unlock_encrypted_volume(default_user_pin); -- cgit v1.2.3 From c1f6abd59b33d8ac7d0c6bb24e00b82f8232810e Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Fri, 30 Jun 2017 18:44:17 +0200 Subject: Compile on both MSVC and MINGW (QtCreator) --- NK_C_API.cc | 879 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 442 insertions(+), 437 deletions(-) diff --git a/NK_C_API.cc b/NK_C_API.cc index 3131db1..1f8c12b 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -5,16 +5,18 @@ #include "include/LibraryException.h" #include "include/cxx_semantics.h" -//#ifdef _WIN32 -//#pragma message "Using own strndup" -//char * strndup(const char* str, size_t maxlen) { -// size_t len = strnlen(str, maxlen); -// char* dup = (char *)malloc(len + 1); -// memcpy(dup, str, len); -// dup[len] = 0; -// return dup; -//} -//#endif +#ifdef _MSC_VER +#ifdef _WIN32 +#pragma message "Using own strndup" +char * strndup(const char* str, size_t maxlen) { + size_t len = strnlen(str, maxlen); + char* dup = (char *)malloc(len + 1); + memcpy(dup, str, len); + dup[len] = 0; + return dup; +} +#endif +#endif using namespace nitrokey; @@ -91,430 +93,433 @@ uint8_t get_without_result(T func){ } -extern "C" -{ -NK_C_API uint8_t NK_get_last_command_status(){ - auto _copy = NK_last_command_status; - NK_last_command_status = 0; - return _copy; -} - -NK_C_API int NK_login(const char *device_model) { - auto m = NitrokeyManager::instance(); - try { - NK_last_command_status = 0; - return m->connect(device_model); - } - catch (CommandFailedException & commandFailedException){ - NK_last_command_status = commandFailedException.last_command_status; - return commandFailedException.last_command_status; - } - catch (std::runtime_error &e){ - cerr << e.what() << endl; - return 0; - } - return 0; -} - -NK_C_API int NK_logout() { - auto m = NitrokeyManager::instance(); - return get_without_result( [&](){ - m->disconnect(); - }); -} - -NK_C_API int NK_first_authenticate(const char* admin_password, const char* admin_temporary_password){ - auto m = NitrokeyManager::instance(); - return get_without_result( [&](){ - return m->first_authenticate(admin_password, admin_temporary_password); - }); -} - - -NK_C_API int NK_user_authenticate(const char* user_password, const char* user_temporary_password){ - auto m = NitrokeyManager::instance(); - return get_without_result( [&](){ - m->user_authenticate(user_password, user_temporary_password); - }); -} - -NK_C_API int NK_factory_reset(const char* admin_password){ - auto m = NitrokeyManager::instance(); - return get_without_result( [&](){ - m->factory_reset(admin_password); - }); -} -NK_C_API int NK_build_aes_key(const char* admin_password){ - auto m = NitrokeyManager::instance(); - return get_without_result( [&](){ - m->build_aes_key(admin_password); - }); -} - -NK_C_API int NK_unlock_user_password(const char *admin_password, const char *new_user_password) { - auto m = NitrokeyManager::instance(); - return get_without_result( [&](){ - m->unlock_user_password(admin_password, new_user_password); - }); -} - -NK_C_API int NK_write_config(uint8_t numlock, uint8_t capslock, uint8_t scrolllock, bool enable_user_password, - bool delete_user_password, - const char *admin_temporary_password) { - auto m = NitrokeyManager::instance(); - return get_without_result( [&](){ - return m->write_config(numlock, capslock, scrolllock, enable_user_password, delete_user_password, admin_temporary_password); - }); -} - - -NK_C_API uint8_t* NK_read_config(){ - auto m = NitrokeyManager::instance(); - return get_with_array_result( [&](){ - auto v = m->read_config(); - return duplicate_vector_and_clear(v); - }); -} - - -void clear_string(std::string &s){ - std::fill(s.begin(), s.end(), ' '); -} - - -NK_C_API const char * NK_status() { - auto m = NitrokeyManager::instance(); - return get_with_string_result([&](){ - string && s = m->get_status_as_string(); - char * rs = strndup(s.c_str(), max_string_field_length); - clear_string(s); - return rs; - }); -} - -NK_C_API const char * NK_device_serial_number(){ - auto m = NitrokeyManager::instance(); - return get_with_string_result([&](){ - string && s = m->get_serial_number(); - char * rs = strndup(s.c_str(), max_string_field_length); - clear_string(s); - return rs; - }); -} - -NK_C_API const char * NK_get_hotp_code(uint8_t slot_number) { - return NK_get_hotp_code_PIN(slot_number, ""); -} - -NK_C_API const char * NK_get_hotp_code_PIN(uint8_t slot_number, const char *user_temporary_password){ - auto m = NitrokeyManager::instance(); - return get_with_string_result([&](){ - string && s = m->get_HOTP_code(slot_number, user_temporary_password); - char * rs = strndup(s.c_str(), max_string_field_length); - clear_string(s); - return rs; - }); -} - -NK_C_API const char * NK_get_totp_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, - uint8_t last_interval){ - return NK_get_totp_code_PIN(slot_number, challenge, last_totp_time, last_interval, ""); -} - -NK_C_API const char * NK_get_totp_code_PIN(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, - uint8_t last_interval, const char *user_temporary_password){ - auto m = NitrokeyManager::instance(); - return get_with_string_result([&](){ - string && s = m->get_TOTP_code(slot_number, challenge, last_totp_time, last_interval, user_temporary_password); - char * rs = strndup(s.c_str(), max_string_field_length); - clear_string(s); - return rs; - }); -} - -NK_C_API int NK_erase_hotp_slot(uint8_t slot_number, const char *temporary_password) { - auto m = NitrokeyManager::instance(); - return get_without_result([&]{ - m->erase_hotp_slot(slot_number, temporary_password); - }); -} - -NK_C_API int NK_erase_totp_slot(uint8_t slot_number, const char *temporary_password) { - auto m = NitrokeyManager::instance(); - return get_without_result([&]{ - m->erase_totp_slot(slot_number, temporary_password); - }); -} - -NK_C_API int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter, - bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, - const char *temporary_password) { - auto m = NitrokeyManager::instance(); - return get_without_result([&]{ - m->write_HOTP_slot(slot_number, slot_name, secret, hotp_counter, use_8_digits, use_enter, use_tokenID, token_ID, - temporary_password); - }); -} - -NK_C_API int NK_write_totp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, - bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, - const char *temporary_password) { - auto m = NitrokeyManager::instance(); - return get_without_result([&]{ - m->write_TOTP_slot(slot_number, slot_name, secret, time_window, use_8_digits, use_enter, use_tokenID, token_ID, - temporary_password); - }); -} - -NK_C_API const char* NK_get_totp_slot_name(uint8_t slot_number){ - auto m = NitrokeyManager::instance(); - return get_with_string_result([&]() { - const auto slot_name = m->get_totp_slot_name(slot_number); - return slot_name; - }); -} -NK_C_API const char* NK_get_hotp_slot_name(uint8_t slot_number){ - auto m = NitrokeyManager::instance(); - return get_with_string_result([&]() { - const auto slot_name = m->get_hotp_slot_name(slot_number); - return slot_name; - }); -} - -NK_C_API void NK_set_debug(bool state){ - auto m = NitrokeyManager::instance(); - m->set_debug(state); -} - -NK_C_API int NK_totp_set_time(uint64_t time){ - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->set_time(time); - }); -} - -NK_C_API int NK_totp_get_time(){ - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->get_time(0); // FIXME check how that should work - }); -} - -NK_C_API int NK_change_admin_PIN(const char *current_PIN, const char *new_PIN){ - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->change_admin_PIN(current_PIN, new_PIN); - }); -} - -NK_C_API int NK_change_user_PIN(const char *current_PIN, const char *new_PIN){ - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->change_user_PIN(current_PIN, new_PIN); - }); -} - -NK_C_API int NK_enable_password_safe(const char *user_pin){ - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->enable_password_safe(user_pin); - }); -} -NK_C_API uint8_t * NK_get_password_safe_slot_status(){ - auto m = NitrokeyManager::instance(); - return get_with_array_result( [&](){ - auto slot_status = m->get_password_safe_slot_status(); - return duplicate_vector_and_clear(slot_status); - }); - -} - -NK_C_API uint8_t NK_get_user_retry_count(){ - auto m = NitrokeyManager::instance(); - return get_with_result([&](){ - return m->get_user_retry_count(); - }); -} - -NK_C_API uint8_t NK_get_admin_retry_count(){ - auto m = NitrokeyManager::instance(); - return get_with_result([&](){ - return m->get_admin_retry_count(); - }); -} - -NK_C_API int NK_lock_device(){ - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->lock_device(); - }); -} - -NK_C_API const char *NK_get_password_safe_slot_name(uint8_t slot_number) { - auto m = NitrokeyManager::instance(); - return get_with_string_result([&](){ - return m->get_password_safe_slot_name(slot_number); - }); -} - -NK_C_API const char *NK_get_password_safe_slot_login(uint8_t slot_number) { - auto m = NitrokeyManager::instance(); - return get_with_string_result([&](){ - return m->get_password_safe_slot_login(slot_number); - }); -} -NK_C_API const char *NK_get_password_safe_slot_password(uint8_t slot_number) { - auto m = NitrokeyManager::instance(); - return get_with_string_result([&](){ - return m->get_password_safe_slot_password(slot_number); - }); -} -NK_C_API int NK_write_password_safe_slot(uint8_t slot_number, const char *slot_name, const char *slot_login, - const char *slot_password) { - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->write_password_safe_slot(slot_number, slot_name, slot_login, slot_password); - }); -} - -NK_C_API int NK_erase_password_safe_slot(uint8_t slot_number) { - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->erase_password_safe_slot(slot_number); - }); -} - -NK_C_API int NK_is_AES_supported(const char *user_password) { - auto m = NitrokeyManager::instance(); - return get_with_result([&](){ - return (uint8_t) m->is_AES_supported(user_password); - }); -} - -NK_C_API int NK_login_auto() { - auto m = NitrokeyManager::instance(); - return get_with_result([&](){ - return (uint8_t) m->connect(); - }); -} - -// storage commands - -NK_C_API int NK_send_startup(uint64_t seconds_from_epoch){ - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->send_startup(seconds_from_epoch); - }); -} - -NK_C_API int NK_unlock_encrypted_volume(const char* user_pin){ - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->unlock_encrypted_volume(user_pin); - }); -} - -NK_C_API int NK_lock_encrypted_volume(){ - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->lock_encrypted_volume(); - }); -} - -NK_C_API 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); - }); -} - -NK_C_API int NK_lock_hidden_volume(){ - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->lock_hidden_volume(); - }); -} - -NK_C_API int NK_create_hidden_volume(uint8_t slot_nr, uint8_t start_percent, uint8_t 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); - }); -} - -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){ - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->set_unencrypted_read_write(user_pin); - }); -} - -NK_C_API int NK_export_firmware(const char* admin_pin) { - auto m = NitrokeyManager::instance(); - return get_without_result([&](){ - m->export_firmware(admin_pin) ; - }); -} - -NK_C_API 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); - }); -} - -NK_C_API 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); - }); -} - -NK_C_API 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); - }); -} - -NK_C_API const char* NK_get_status_storage_as_string() { - auto m = NitrokeyManager::instance(); - return get_with_string_result([&](){ - return m->get_status_storage_as_string(); - }); -} - -NK_C_API const char* NK_get_SD_usage_data_as_string() { - auto m = NitrokeyManager::instance(); - return get_with_string_result([&](){ - return m->get_SD_usage_data_as_string(); - }); -} - -NK_C_API int NK_get_progress_bar_value() { - auto m = NitrokeyManager::instance(); - return get_with_result([&](){ - return m->get_progress_bar_value(); - }); -} - -NK_C_API int NK_get_major_firmware_version(){ - auto m = NitrokeyManager::instance(); - return get_with_result([&](){ - return m->get_minor_firmware_version(); - }); -} - - -} - +#ifdef __cplusplus +extern "C" { +#endif + + NK_C_API uint8_t NK_get_last_command_status() { + auto _copy = NK_last_command_status; + NK_last_command_status = 0; + return _copy; + } + + NK_C_API int NK_login(const char *device_model) { + auto m = NitrokeyManager::instance(); + try { + NK_last_command_status = 0; + return m->connect(device_model); + } + catch (CommandFailedException & commandFailedException) { + NK_last_command_status = commandFailedException.last_command_status; + return commandFailedException.last_command_status; + } + catch (std::runtime_error &e) { + cerr << e.what() << endl; + return 0; + } + return 0; + } + + NK_C_API int NK_logout() { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->disconnect(); + }); + } + + NK_C_API int NK_first_authenticate(const char* admin_password, const char* admin_temporary_password) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + return m->first_authenticate(admin_password, admin_temporary_password); + }); + } + + + NK_C_API int NK_user_authenticate(const char* user_password, const char* user_temporary_password) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->user_authenticate(user_password, user_temporary_password); + }); + } + + NK_C_API int NK_factory_reset(const char* admin_password) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->factory_reset(admin_password); + }); + } + NK_C_API int NK_build_aes_key(const char* admin_password) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->build_aes_key(admin_password); + }); + } + + NK_C_API int NK_unlock_user_password(const char *admin_password, const char *new_user_password) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->unlock_user_password(admin_password, new_user_password); + }); + } + + NK_C_API int NK_write_config(uint8_t numlock, uint8_t capslock, uint8_t scrolllock, bool enable_user_password, + bool delete_user_password, + const char *admin_temporary_password) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + return m->write_config(numlock, capslock, scrolllock, enable_user_password, delete_user_password, admin_temporary_password); + }); + } + + + NK_C_API uint8_t* NK_read_config() { + auto m = NitrokeyManager::instance(); + return get_with_array_result([&]() { + auto v = m->read_config(); + return duplicate_vector_and_clear(v); + }); + } + + + void clear_string(std::string &s) { + std::fill(s.begin(), s.end(), ' '); + } + + + NK_C_API const char * NK_status() { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&]() { + string && s = m->get_status_as_string(); + char * rs = strndup(s.c_str(), max_string_field_length); + clear_string(s); + return rs; + }); + } + + NK_C_API const char * NK_device_serial_number() { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&]() { + string && s = m->get_serial_number(); + char * rs = strndup(s.c_str(), max_string_field_length); + clear_string(s); + return rs; + }); + } + + NK_C_API const char * NK_get_hotp_code(uint8_t slot_number) { + return NK_get_hotp_code_PIN(slot_number, ""); + } + + NK_C_API const char * NK_get_hotp_code_PIN(uint8_t slot_number, const char *user_temporary_password) { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&]() { + string && s = m->get_HOTP_code(slot_number, user_temporary_password); + char * rs = strndup(s.c_str(), max_string_field_length); + clear_string(s); + return rs; + }); + } + + NK_C_API const char * NK_get_totp_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, + uint8_t last_interval) { + return NK_get_totp_code_PIN(slot_number, challenge, last_totp_time, last_interval, ""); + } + + NK_C_API const char * NK_get_totp_code_PIN(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, + uint8_t last_interval, const char *user_temporary_password) { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&]() { + string && s = m->get_TOTP_code(slot_number, challenge, last_totp_time, last_interval, user_temporary_password); + char * rs = strndup(s.c_str(), max_string_field_length); + clear_string(s); + return rs; + }); + } + + NK_C_API int NK_erase_hotp_slot(uint8_t slot_number, const char *temporary_password) { + auto m = NitrokeyManager::instance(); + return get_without_result([&] { + m->erase_hotp_slot(slot_number, temporary_password); + }); + } + + NK_C_API int NK_erase_totp_slot(uint8_t slot_number, const char *temporary_password) { + auto m = NitrokeyManager::instance(); + return get_without_result([&] { + m->erase_totp_slot(slot_number, temporary_password); + }); + } + + NK_C_API int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter, + bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, + const char *temporary_password) { + auto m = NitrokeyManager::instance(); + return get_without_result([&] { + m->write_HOTP_slot(slot_number, slot_name, secret, hotp_counter, use_8_digits, use_enter, use_tokenID, token_ID, + temporary_password); + }); + } + + NK_C_API int NK_write_totp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, + bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, + const char *temporary_password) { + auto m = NitrokeyManager::instance(); + return get_without_result([&] { + m->write_TOTP_slot(slot_number, slot_name, secret, time_window, use_8_digits, use_enter, use_tokenID, token_ID, + temporary_password); + }); + } + + NK_C_API const char* NK_get_totp_slot_name(uint8_t slot_number) { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&]() { + const auto slot_name = m->get_totp_slot_name(slot_number); + return slot_name; + }); + } + NK_C_API const char* NK_get_hotp_slot_name(uint8_t slot_number) { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&]() { + const auto slot_name = m->get_hotp_slot_name(slot_number); + return slot_name; + }); + } + + NK_C_API void NK_set_debug(bool state) { + auto m = NitrokeyManager::instance(); + m->set_debug(state); + } + + NK_C_API int NK_totp_set_time(uint64_t time) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->set_time(time); + }); + } + + NK_C_API int NK_totp_get_time() { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->get_time(0); // FIXME check how that should work + }); + } + + NK_C_API int NK_change_admin_PIN(const char *current_PIN, const char *new_PIN) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->change_admin_PIN(current_PIN, new_PIN); + }); + } + + NK_C_API int NK_change_user_PIN(const char *current_PIN, const char *new_PIN) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->change_user_PIN(current_PIN, new_PIN); + }); + } + + NK_C_API int NK_enable_password_safe(const char *user_pin) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->enable_password_safe(user_pin); + }); + } + NK_C_API uint8_t * NK_get_password_safe_slot_status() { + auto m = NitrokeyManager::instance(); + return get_with_array_result([&]() { + auto slot_status = m->get_password_safe_slot_status(); + return duplicate_vector_and_clear(slot_status); + }); + + } + + NK_C_API uint8_t NK_get_user_retry_count() { + auto m = NitrokeyManager::instance(); + return get_with_result([&]() { + return m->get_user_retry_count(); + }); + } + + NK_C_API uint8_t NK_get_admin_retry_count() { + auto m = NitrokeyManager::instance(); + return get_with_result([&]() { + return m->get_admin_retry_count(); + }); + } + + NK_C_API int NK_lock_device() { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->lock_device(); + }); + } + + NK_C_API const char *NK_get_password_safe_slot_name(uint8_t slot_number) { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&]() { + return m->get_password_safe_slot_name(slot_number); + }); + } + + NK_C_API const char *NK_get_password_safe_slot_login(uint8_t slot_number) { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&]() { + return m->get_password_safe_slot_login(slot_number); + }); + } + NK_C_API const char *NK_get_password_safe_slot_password(uint8_t slot_number) { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&]() { + return m->get_password_safe_slot_password(slot_number); + }); + } + NK_C_API int NK_write_password_safe_slot(uint8_t slot_number, const char *slot_name, const char *slot_login, + const char *slot_password) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->write_password_safe_slot(slot_number, slot_name, slot_login, slot_password); + }); + } + + NK_C_API int NK_erase_password_safe_slot(uint8_t slot_number) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->erase_password_safe_slot(slot_number); + }); + } + + NK_C_API int NK_is_AES_supported(const char *user_password) { + auto m = NitrokeyManager::instance(); + return get_with_result([&]() { + return (uint8_t)m->is_AES_supported(user_password); + }); + } + + NK_C_API int NK_login_auto() { + auto m = NitrokeyManager::instance(); + return get_with_result([&]() { + return (uint8_t)m->connect(); + }); + } + + // storage commands + + NK_C_API int NK_send_startup(uint64_t seconds_from_epoch) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->send_startup(seconds_from_epoch); + }); + } + + NK_C_API int NK_unlock_encrypted_volume(const char* user_pin) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->unlock_encrypted_volume(user_pin); + }); + } + + NK_C_API int NK_lock_encrypted_volume() { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->lock_encrypted_volume(); + }); + } + + NK_C_API 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); + }); + } + + NK_C_API int NK_lock_hidden_volume() { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->lock_hidden_volume(); + }); + } + + NK_C_API int NK_create_hidden_volume(uint8_t slot_nr, uint8_t start_percent, uint8_t 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); + }); + } + + 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) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->set_unencrypted_read_write(user_pin); + }); + } + + NK_C_API int NK_export_firmware(const char* admin_pin) { + auto m = NitrokeyManager::instance(); + return get_without_result([&]() { + m->export_firmware(admin_pin); + }); + } + + NK_C_API 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); + }); + } + + NK_C_API 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); + }); + } + + NK_C_API 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); + }); + } + + NK_C_API const char* NK_get_status_storage_as_string() { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&]() { + return m->get_status_storage_as_string(); + }); + } + + NK_C_API const char* NK_get_SD_usage_data_as_string() { + auto m = NitrokeyManager::instance(); + return get_with_string_result([&]() { + return m->get_SD_usage_data_as_string(); + }); + } + + NK_C_API int NK_get_progress_bar_value() { + auto m = NitrokeyManager::instance(); + return get_with_result([&]() { + return m->get_progress_bar_value(); + }); + } + + NK_C_API int NK_get_major_firmware_version() { + auto m = NitrokeyManager::instance(); + return get_with_result([&]() { + return m->get_minor_firmware_version(); + }); + } + + +#ifdef __cplusplus +} +#endif -- cgit v1.2.3 From 3b37f0ea417b58e932b3261f64faff7bc3f4da75 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Fri, 30 Jun 2017 18:45:06 +0200 Subject: Export C API functions Guard extern to only C++ --- NK_C_API.h | 930 +++++++++++++++++++++++++++++++------------------------------ 1 file changed, 468 insertions(+), 462 deletions(-) diff --git a/NK_C_API.h b/NK_C_API.h index 430fa38..18f8d0a 100644 --- a/NK_C_API.h +++ b/NK_C_API.h @@ -3,468 +3,474 @@ #include -#define NK_C_API - -extern "C" -{ -/** - * Set debug level of messages written on stderr - * @param state state=True - all messages, state=False - only errors level - */ -NK_C_API void NK_set_debug(bool state); - -/** - * Connect to device of given model. Currently library can be connected only to one device at once. - * @param device_model char 'S': Nitrokey Storage, 'P': Nitrokey Pro - * @return 1 if connected, 0 if wrong model or cannot connect - */ -NK_C_API int NK_login(const char *device_model); - -/** - * Connect to first available device, starting checking from Pro 1st to Storage 2nd. - * @return 1 if connected, 0 if wrong model or cannot connect - */ -NK_C_API int NK_login_auto(); - -/** - * Disconnect from the device. - * @return command processing error code - */ -NK_C_API int NK_logout(); - -/** - * Return the debug status string. Debug purposes. - * @return command processing error code - */ -NK_C_API const char * NK_status(); - -/** - * Return the device's serial number string in hex. - * @return string device's serial number in hex - */ -NK_C_API const char * NK_device_serial_number(); - -/** - * Get last command processing status. Useful for commands which returns the results of their own and could not return - * an error code. - * @return previous command processing error code - */ -NK_C_API uint8_t NK_get_last_command_status(); - -/** - * Lock device - cancel any user device unlocking. - * @return command processing error code - */ -NK_C_API int NK_lock_device(); - -/** - * Authenticates the user on USER privilages with user_password and sets user's temporary password on device to user_temporary_password. - * @param user_password char[25](Pro) current user password - * @param user_temporary_password char[25](Pro) user temporary password to be set on device for further communication (authentication command) - * @return command processing error code - */ -NK_C_API int NK_user_authenticate(const char* user_password, const char* user_temporary_password); - -/** - * Authenticates the user on ADMIN privilages with admin_password and sets user's temporary password on device to admin_temporary_password. - * @param admin_password char[25](Pro) current administrator PIN - * @param admin_temporary_password char[25](Pro) admin temporary password to be set on device for further communication (authentication command) - * @return command processing error code - */ -NK_C_API int NK_first_authenticate(const char* admin_password, const char* admin_temporary_password); - -/** - * Execute a factory reset. - * @param admin_password char[20](Pro) current administrator PIN - * @return command processing error code - */ -NK_C_API int NK_factory_reset(const char* admin_password); - -/** - * Generates AES key on the device - * @param admin_password char[20](Pro) current administrator PIN - * @return command processing error code - */ -NK_C_API int NK_build_aes_key(const char* admin_password); - -/** - * Unlock user PIN locked after 3 incorrect codes tries. - * @param admin_password char[20](Pro) current administrator PIN - * @return command processing error code - */ -NK_C_API int NK_unlock_user_password(const char *admin_password, const char *new_user_password); - -/** - * Write general config to the device - * @param numlock set value in range [0-1] to send HOTP code from slot 'numlock' after double pressing numlock - * or outside the range to disable this function - * @param capslock similar to numlock but with capslock - * @param scrolllock similar to numlock but with scrolllock - * @param enable_user_password set True to enable OTP PIN protection (request PIN each OTP code request) - * @param delete_user_password set True to disable OTP PIN protection (request PIN each OTP code request) - * @param admin_temporary_password current admin temporary password - * @return command processing error code - */ -NK_C_API int NK_write_config(uint8_t numlock, uint8_t capslock, uint8_t scrolllock, - bool enable_user_password, bool delete_user_password, const char *admin_temporary_password); - -/** - * Get currently set config - status of function Numlock/Capslock/Scrollock OTP sending and is enabled PIN protected OTP - * @see NK_write_config - * @return uint8_t general_config[5]: - * uint8_t numlock; - uint8_t capslock; - uint8_t scrolllock; - uint8_t enable_user_password; - uint8_t delete_user_password; - - */ -NK_C_API uint8_t* NK_read_config(); - -//OTP - -/** - * Get name of given TOTP slot - * @param slot_number TOTP slot number, slot_number<15 - * @return char[20](Pro) the name of the slot - */ -NK_C_API const char * NK_get_totp_slot_name(uint8_t slot_number); - -/** - * - * @param slot_number HOTP slot number, slot_number<3 - * @return char[20](Pro) the name of the slot - */ -NK_C_API const char * NK_get_hotp_slot_name(uint8_t slot_number); - -/** - * Erase HOTP slot data from the device - * @param slot_number HOTP slot number, slot_number<3 - * @param temporary_password admin temporary password - * @return command processing error code - */ -NK_C_API int NK_erase_hotp_slot(uint8_t slot_number, const char *temporary_password); - -/** - * Erase TOTP slot data from the device - * @param slot_number TOTP slot number, slot_number<15 - * @param temporary_password admin temporary password - * @return command processing error code - */ -NK_C_API int NK_erase_totp_slot(uint8_t slot_number, const char *temporary_password); - -/** - * Write HOTP slot data to the device - * @param slot_number HOTP slot number, slot_number<3 - * @param slot_name char[15](Pro) desired slot name - * @param secret char[20](Pro) 160-bit secret - * @param hotp_counter uint32_t starting value of HOTP counter - * @param use_8_digits should returned codes be 6 (false) or 8 digits (true) - * @param use_enter press ENTER key after sending OTP code using double-pressed scroll/num/capslock - * @param use_tokenID @see token_ID - * @param token_ID @see https://openauthentication.org/token-specs/, 'Class A' section - * @param temporary_password char[25](Pro) admin temporary password - * @return command processing error code - */ -NK_C_API int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter, - bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, - const char *temporary_password); - -/** - * Write TOTP slot data to the device - * @param slot_number TOTP slot number, slot_number<15 - * @param slot_name char[15](Pro) desired slot name - * @param secret char[20](Pro) 160-bit secret - * @param time_window uint16_t time window for this TOTP - * @param use_8_digits should returned codes be 6 (false) or 8 digits (true) - * @param use_enter press ENTER key after sending OTP code using double-pressed scroll/num/capslock - * @param use_tokenID @see token_ID - * @param token_ID @see https://openauthentication.org/token-specs/, 'Class A' section - * @param temporary_password char[20](Pro) admin temporary password - * @return command processing error code - */ -NK_C_API int NK_write_totp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, - bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, - const char *temporary_password); - -/** - * Get HOTP code from the device - * @param slot_number HOTP slot number, slot_number<3 - * @return HOTP code - */ -NK_C_API const char * NK_get_hotp_code(uint8_t slot_number); - -/** - * Get HOTP code from the device (PIN protected) - * @param slot_number HOTP slot number, slot_number<3 - * @param user_temporary_password char[25](Pro) user temporary password if PIN protected OTP codes are enabled, - * otherwise should be set to empty string - '' - * @return HOTP code - */ -NK_C_API const char * NK_get_hotp_code_PIN(uint8_t slot_number, const char *user_temporary_password); - -/** - * Get TOTP code from the device - * @param slot_number TOTP slot number, slot_number<15 - * @param challenge TOTP challenge - * @param last_totp_time last time - * @param last_interval last interval - * @return TOTP code - */ -NK_C_API const char * NK_get_totp_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, - uint8_t last_interval); - -/** - * Get TOTP code from the device (PIN protected) - * @param slot_number TOTP slot number, slot_number<15 - * @param challenge TOTP challenge - * @param last_totp_time last time - * @param last_interval last interval - * @param user_temporary_password char[25](Pro) user temporary password if PIN protected OTP codes are enabled, - * otherwise should be set to empty string - '' - * @return TOTP code - */ -NK_C_API const char * NK_get_totp_code_PIN(uint8_t slot_number, uint64_t challenge, - uint64_t last_totp_time, uint8_t last_interval, - const char *user_temporary_password); - -/** - * Set time on the device (for TOTP requests) - * @param time seconds in unix epoch (from 01.01.1970) - * @return command processing error code - */ -NK_C_API int NK_totp_set_time(uint64_t time); - -NK_C_API int NK_totp_get_time(); -//passwords -/** - * Change administrator PIN - * @param current_PIN char[25](Pro) current PIN - * @param new_PIN char[25](Pro) new PIN - * @return command processing error code - */ -NK_C_API int NK_change_admin_PIN(const char *current_PIN, const char *new_PIN); - -/** - * Change user PIN - * @param current_PIN char[25](Pro) current PIN - * @param new_PIN char[25](Pro) new PIN - * @return command processing error code -*/ -NK_C_API int NK_change_user_PIN(const char *current_PIN, const char *new_PIN); - - -/** - * Get retry count of user PIN - * @return user PIN retry count - */ -NK_C_API uint8_t NK_get_user_retry_count(); - -/** - * Get retry count of admin PIN - * @return admin PIN retry count - */ -NK_C_API uint8_t NK_get_admin_retry_count(); -//password safe - -/** - * Enable password safe access - * @param user_pin char[30](Pro) current user PIN - * @return command processing error code - */ -NK_C_API int NK_enable_password_safe(const char *user_pin); - -/** - * Get password safe slots' status - * @return uint8_t[16] slot statuses - each byte represents one slot with 0 (not programmed) and 1 (programmed) - */ -NK_C_API uint8_t * NK_get_password_safe_slot_status(); - -/** - * Get password safe slot name - * @param slot_number password safe slot number, slot_number<16 - * @return slot name - */ -NK_C_API const char *NK_get_password_safe_slot_name(uint8_t slot_number); - -/** - * Get password safe slot login - * @param slot_number password safe slot number, slot_number<16 - * @return login from the PWS slot - */ -NK_C_API const char *NK_get_password_safe_slot_login(uint8_t slot_number); - -/** - * Get the password safe slot password - * @param slot_number password safe slot number, slot_number<16 - * @return password from the PWS slot - */ -NK_C_API const char *NK_get_password_safe_slot_password(uint8_t slot_number); - -/** - * Write password safe data to the slot - * @param slot_number password safe slot number, slot_number<16 - * @param slot_name char[11](Pro) name of the slot - * @param slot_login char[32](Pro) login string - * @param slot_password char[20](Pro) password string - * @return command processing error code - */ -NK_C_API int NK_write_password_safe_slot(uint8_t slot_number, const char *slot_name, - const char *slot_login, const char *slot_password); - -/** - * Erase the password safe slot from the device - * @param slot_number password safe slot number, slot_number<16 - * @return command processing error code - */ -NK_C_API int NK_erase_password_safe_slot(uint8_t slot_number); - -/** - * Check whether AES is supported by the device - * @return 0 for no and 1 for yes - */ -NK_C_API int NK_is_AES_supported(const char *user_password); - -/** - * Get device's major firmware version - * @return 7,8 for Pro and major for Storage - */ -NK_C_API int NK_get_major_firmware_version(); - - - -/** - * This command is typically run to initiate - * communication with the device (altough not required). - * It sets time on device and returns its current status - * - a combination of set_time and get_status_storage commands - * Storage only - * @param seconds_from_epoch date and time expressed in seconds - */ -NK_C_API int NK_send_startup(uint64_t seconds_from_epoch); - -/** - * Unlock encrypted volume. - * Storage only - * @param user_pin user pin 20 characters - * @return command processing error code - */ -NK_C_API int NK_unlock_encrypted_volume(const char* user_pin); - -/** - * Locks encrypted volume - * @return command processing error code - */ -NK_C_API int NK_lock_encrypted_volume(); - -/** - * Unlock hidden volume and lock encrypted volume. - * Requires encrypted volume to be unlocked. - * Storage only - * @param hidden_volume_password 20 characters - * @return command processing error code - */ -NK_C_API int NK_unlock_hidden_volume(const char* hidden_volume_password); - -/** - * Locks hidden volume - * @return command processing error code - */ -NK_C_API int NK_lock_hidden_volume(); - -/** - * Create hidden volume. - * Requires encrypted volume to be unlocked. - * Storage only - * @param slot_nr slot number in range 0-3 - * @param start_percent volume begin expressed in percent of total available storage, int in range 0-99 - * @param end_percent volume end expressed in percent of total available storage, int in range 1-100 - * @param hidden_volume_password 20 characters - * @return command processing error code - */ -NK_C_API int NK_create_hidden_volume(uint8_t slot_nr, uint8_t start_percent, uint8_t end_percent, - const char *hidden_volume_password); - -/** - * Make unencrypted volume read-only. - * Device hides unencrypted volume for a second therefore make sure - * buffers are flushed before running. - * Storage only - * @param user_pin 20 characters - * @return command processing error code - */ -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. - * Storage only - * @param user_pin 20 characters - * @return command processing error code - */ -NK_C_API int NK_set_unencrypted_read_write(const char* user_pin); - -/** - * Exports device's firmware to unencrypted volume. - * Storage only - * @param admin_pin 20 characters - * @return command processing error code - */ -NK_C_API int NK_export_firmware(const char* admin_pin) ; - -/** - * Clear new SD card notification. It is set after factory reset. - * Storage only - * @param admin_pin 20 characters - * @return command processing error code - */ -NK_C_API int NK_clear_new_sd_card_warning(const char* admin_pin) ; - -/** - * Fill SD card with random data. - * Should be done on first stick initialization after creating keys. - * Storage only - * @param admin_pin 20 characters - * @return command processing error code - */ -NK_C_API int NK_fill_SD_card_with_random_data(const char* admin_pin) ; - -/** - * Change update password. - * Update password is used for entering update mode, where firmware - * could be uploaded using dfu-programmer or other means. - * Storage only - * @param current_update_password 20 characters - * @param new_update_password 20 characters - * @return command processing error code - */ -NK_C_API int NK_change_update_password(const char* current_update_password, - const char* new_update_password); - -/** - * Get Storage stick status as string. - * Storage only - * @return string with devices attributes - */ -NK_C_API const char* NK_get_status_storage_as_string(); - -/** - * Get SD card usage attributes as string. - * Usable during hidden volumes creation. - * Storage only - * @return string with SD card usage attributes - */ -NK_C_API const char* NK_get_SD_usage_data_as_string(); - -/** - * Get progress value of current long operation. - * Storage only - * @return int in range 0-100 or -1 if device is not busy - */ -NK_C_API int NK_get_progress_bar_value(); - +#ifdef _MSC_VER +#define NK_C_API __declspec(dllexport) +#else +#define NK_C_API +#endif + +#ifdef __cplusplus +extern "C" { +#endif + /** + * Set debug level of messages written on stderr + * @param state state=True - all messages, state=False - only errors level + */ + NK_C_API void NK_set_debug(bool state); + + /** + * Connect to device of given model. Currently library can be connected only to one device at once. + * @param device_model char 'S': Nitrokey Storage, 'P': Nitrokey Pro + * @return 1 if connected, 0 if wrong model or cannot connect + */ + NK_C_API int NK_login(const char *device_model); + + /** + * Connect to first available device, starting checking from Pro 1st to Storage 2nd. + * @return 1 if connected, 0 if wrong model or cannot connect + */ + NK_C_API int NK_login_auto(); + + /** + * Disconnect from the device. + * @return command processing error code + */ + NK_C_API int NK_logout(); + + /** + * Return the debug status string. Debug purposes. + * @return command processing error code + */ + NK_C_API const char * NK_status(); + + /** + * Return the device's serial number string in hex. + * @return string device's serial number in hex + */ + NK_C_API const char * NK_device_serial_number(); + + /** + * Get last command processing status. Useful for commands which returns the results of their own and could not return + * an error code. + * @return previous command processing error code + */ + NK_C_API uint8_t NK_get_last_command_status(); + + /** + * Lock device - cancel any user device unlocking. + * @return command processing error code + */ + NK_C_API int NK_lock_device(); + + /** + * Authenticates the user on USER privilages with user_password and sets user's temporary password on device to user_temporary_password. + * @param user_password char[25](Pro) current user password + * @param user_temporary_password char[25](Pro) user temporary password to be set on device for further communication (authentication command) + * @return command processing error code + */ + NK_C_API int NK_user_authenticate(const char* user_password, const char* user_temporary_password); + + /** + * Authenticates the user on ADMIN privilages with admin_password and sets user's temporary password on device to admin_temporary_password. + * @param admin_password char[25](Pro) current administrator PIN + * @param admin_temporary_password char[25](Pro) admin temporary password to be set on device for further communication (authentication command) + * @return command processing error code + */ + NK_C_API int NK_first_authenticate(const char* admin_password, const char* admin_temporary_password); + + /** + * Execute a factory reset. + * @param admin_password char[20](Pro) current administrator PIN + * @return command processing error code + */ + NK_C_API int NK_factory_reset(const char* admin_password); + + /** + * Generates AES key on the device + * @param admin_password char[20](Pro) current administrator PIN + * @return command processing error code + */ + NK_C_API int NK_build_aes_key(const char* admin_password); + + /** + * Unlock user PIN locked after 3 incorrect codes tries. + * @param admin_password char[20](Pro) current administrator PIN + * @return command processing error code + */ + NK_C_API int NK_unlock_user_password(const char *admin_password, const char *new_user_password); + + /** + * Write general config to the device + * @param numlock set value in range [0-1] to send HOTP code from slot 'numlock' after double pressing numlock + * or outside the range to disable this function + * @param capslock similar to numlock but with capslock + * @param scrolllock similar to numlock but with scrolllock + * @param enable_user_password set True to enable OTP PIN protection (request PIN each OTP code request) + * @param delete_user_password set True to disable OTP PIN protection (request PIN each OTP code request) + * @param admin_temporary_password current admin temporary password + * @return command processing error code + */ + NK_C_API int NK_write_config(uint8_t numlock, uint8_t capslock, uint8_t scrolllock, + bool enable_user_password, bool delete_user_password, const char *admin_temporary_password); + + /** + * Get currently set config - status of function Numlock/Capslock/Scrollock OTP sending and is enabled PIN protected OTP + * @see NK_write_config + * @return uint8_t general_config[5]: + * uint8_t numlock; + uint8_t capslock; + uint8_t scrolllock; + uint8_t enable_user_password; + uint8_t delete_user_password; + + */ + NK_C_API uint8_t* NK_read_config(); + + //OTP + + /** + * Get name of given TOTP slot + * @param slot_number TOTP slot number, slot_number<15 + * @return char[20](Pro) the name of the slot + */ + NK_C_API const char * NK_get_totp_slot_name(uint8_t slot_number); + + /** + * + * @param slot_number HOTP slot number, slot_number<3 + * @return char[20](Pro) the name of the slot + */ + NK_C_API const char * NK_get_hotp_slot_name(uint8_t slot_number); + + /** + * Erase HOTP slot data from the device + * @param slot_number HOTP slot number, slot_number<3 + * @param temporary_password admin temporary password + * @return command processing error code + */ + NK_C_API int NK_erase_hotp_slot(uint8_t slot_number, const char *temporary_password); + + /** + * Erase TOTP slot data from the device + * @param slot_number TOTP slot number, slot_number<15 + * @param temporary_password admin temporary password + * @return command processing error code + */ + NK_C_API int NK_erase_totp_slot(uint8_t slot_number, const char *temporary_password); + + /** + * Write HOTP slot data to the device + * @param slot_number HOTP slot number, slot_number<3 + * @param slot_name char[15](Pro) desired slot name + * @param secret char[20](Pro) 160-bit secret + * @param hotp_counter uint32_t starting value of HOTP counter + * @param use_8_digits should returned codes be 6 (false) or 8 digits (true) + * @param use_enter press ENTER key after sending OTP code using double-pressed scroll/num/capslock + * @param use_tokenID @see token_ID + * @param token_ID @see https://openauthentication.org/token-specs/, 'Class A' section + * @param temporary_password char[25](Pro) admin temporary password + * @return command processing error code + */ + NK_C_API int NK_write_hotp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint64_t hotp_counter, + bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, + const char *temporary_password); + + /** + * Write TOTP slot data to the device + * @param slot_number TOTP slot number, slot_number<15 + * @param slot_name char[15](Pro) desired slot name + * @param secret char[20](Pro) 160-bit secret + * @param time_window uint16_t time window for this TOTP + * @param use_8_digits should returned codes be 6 (false) or 8 digits (true) + * @param use_enter press ENTER key after sending OTP code using double-pressed scroll/num/capslock + * @param use_tokenID @see token_ID + * @param token_ID @see https://openauthentication.org/token-specs/, 'Class A' section + * @param temporary_password char[20](Pro) admin temporary password + * @return command processing error code + */ + NK_C_API int NK_write_totp_slot(uint8_t slot_number, const char *slot_name, const char *secret, uint16_t time_window, + bool use_8_digits, bool use_enter, bool use_tokenID, const char *token_ID, + const char *temporary_password); + + /** + * Get HOTP code from the device + * @param slot_number HOTP slot number, slot_number<3 + * @return HOTP code + */ + NK_C_API const char * NK_get_hotp_code(uint8_t slot_number); + + /** + * Get HOTP code from the device (PIN protected) + * @param slot_number HOTP slot number, slot_number<3 + * @param user_temporary_password char[25](Pro) user temporary password if PIN protected OTP codes are enabled, + * otherwise should be set to empty string - '' + * @return HOTP code + */ + NK_C_API const char * NK_get_hotp_code_PIN(uint8_t slot_number, const char *user_temporary_password); + + /** + * Get TOTP code from the device + * @param slot_number TOTP slot number, slot_number<15 + * @param challenge TOTP challenge + * @param last_totp_time last time + * @param last_interval last interval + * @return TOTP code + */ + NK_C_API const char * NK_get_totp_code(uint8_t slot_number, uint64_t challenge, uint64_t last_totp_time, + uint8_t last_interval); + + /** + * Get TOTP code from the device (PIN protected) + * @param slot_number TOTP slot number, slot_number<15 + * @param challenge TOTP challenge + * @param last_totp_time last time + * @param last_interval last interval + * @param user_temporary_password char[25](Pro) user temporary password if PIN protected OTP codes are enabled, + * otherwise should be set to empty string - '' + * @return TOTP code + */ + NK_C_API const char * NK_get_totp_code_PIN(uint8_t slot_number, uint64_t challenge, + uint64_t last_totp_time, uint8_t last_interval, + const char *user_temporary_password); + + /** + * Set time on the device (for TOTP requests) + * @param time seconds in unix epoch (from 01.01.1970) + * @return command processing error code + */ + NK_C_API int NK_totp_set_time(uint64_t time); + + NK_C_API int NK_totp_get_time(); + //passwords + /** + * Change administrator PIN + * @param current_PIN char[25](Pro) current PIN + * @param new_PIN char[25](Pro) new PIN + * @return command processing error code + */ + NK_C_API int NK_change_admin_PIN(const char *current_PIN, const char *new_PIN); + + /** + * Change user PIN + * @param current_PIN char[25](Pro) current PIN + * @param new_PIN char[25](Pro) new PIN + * @return command processing error code + */ + NK_C_API int NK_change_user_PIN(const char *current_PIN, const char *new_PIN); + + + /** + * Get retry count of user PIN + * @return user PIN retry count + */ + NK_C_API uint8_t NK_get_user_retry_count(); + + /** + * Get retry count of admin PIN + * @return admin PIN retry count + */ + NK_C_API uint8_t NK_get_admin_retry_count(); + //password safe + + /** + * Enable password safe access + * @param user_pin char[30](Pro) current user PIN + * @return command processing error code + */ + NK_C_API int NK_enable_password_safe(const char *user_pin); + + /** + * Get password safe slots' status + * @return uint8_t[16] slot statuses - each byte represents one slot with 0 (not programmed) and 1 (programmed) + */ + NK_C_API uint8_t * NK_get_password_safe_slot_status(); + + /** + * Get password safe slot name + * @param slot_number password safe slot number, slot_number<16 + * @return slot name + */ + NK_C_API const char *NK_get_password_safe_slot_name(uint8_t slot_number); + + /** + * Get password safe slot login + * @param slot_number password safe slot number, slot_number<16 + * @return login from the PWS slot + */ + NK_C_API const char *NK_get_password_safe_slot_login(uint8_t slot_number); + + /** + * Get the password safe slot password + * @param slot_number password safe slot number, slot_number<16 + * @return password from the PWS slot + */ + NK_C_API const char *NK_get_password_safe_slot_password(uint8_t slot_number); + + /** + * Write password safe data to the slot + * @param slot_number password safe slot number, slot_number<16 + * @param slot_name char[11](Pro) name of the slot + * @param slot_login char[32](Pro) login string + * @param slot_password char[20](Pro) password string + * @return command processing error code + */ + NK_C_API int NK_write_password_safe_slot(uint8_t slot_number, const char *slot_name, + const char *slot_login, const char *slot_password); + + /** + * Erase the password safe slot from the device + * @param slot_number password safe slot number, slot_number<16 + * @return command processing error code + */ + NK_C_API int NK_erase_password_safe_slot(uint8_t slot_number); + + /** + * Check whether AES is supported by the device + * @return 0 for no and 1 for yes + */ + NK_C_API int NK_is_AES_supported(const char *user_password); + + /** + * Get device's major firmware version + * @return 7,8 for Pro and major for Storage + */ + NK_C_API int NK_get_major_firmware_version(); + + + + /** + * This command is typically run to initiate + * communication with the device (altough not required). + * It sets time on device and returns its current status + * - a combination of set_time and get_status_storage commands + * Storage only + * @param seconds_from_epoch date and time expressed in seconds + */ + NK_C_API int NK_send_startup(uint64_t seconds_from_epoch); + + /** + * Unlock encrypted volume. + * Storage only + * @param user_pin user pin 20 characters + * @return command processing error code + */ + NK_C_API int NK_unlock_encrypted_volume(const char* user_pin); + + /** + * Locks encrypted volume + * @return command processing error code + */ + NK_C_API int NK_lock_encrypted_volume(); + + /** + * Unlock hidden volume and lock encrypted volume. + * Requires encrypted volume to be unlocked. + * Storage only + * @param hidden_volume_password 20 characters + * @return command processing error code + */ + NK_C_API int NK_unlock_hidden_volume(const char* hidden_volume_password); + + /** + * Locks hidden volume + * @return command processing error code + */ + NK_C_API int NK_lock_hidden_volume(); + + /** + * Create hidden volume. + * Requires encrypted volume to be unlocked. + * Storage only + * @param slot_nr slot number in range 0-3 + * @param start_percent volume begin expressed in percent of total available storage, int in range 0-99 + * @param end_percent volume end expressed in percent of total available storage, int in range 1-100 + * @param hidden_volume_password 20 characters + * @return command processing error code + */ + NK_C_API int NK_create_hidden_volume(uint8_t slot_nr, uint8_t start_percent, uint8_t end_percent, + const char *hidden_volume_password); + + /** + * Make unencrypted volume read-only. + * Device hides unencrypted volume for a second therefore make sure + * buffers are flushed before running. + * Storage only + * @param user_pin 20 characters + * @return command processing error code + */ + 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. + * Storage only + * @param user_pin 20 characters + * @return command processing error code + */ + NK_C_API int NK_set_unencrypted_read_write(const char* user_pin); + + /** + * Exports device's firmware to unencrypted volume. + * Storage only + * @param admin_pin 20 characters + * @return command processing error code + */ + NK_C_API int NK_export_firmware(const char* admin_pin); + + /** + * Clear new SD card notification. It is set after factory reset. + * Storage only + * @param admin_pin 20 characters + * @return command processing error code + */ + NK_C_API int NK_clear_new_sd_card_warning(const char* admin_pin); + + /** + * Fill SD card with random data. + * Should be done on first stick initialization after creating keys. + * Storage only + * @param admin_pin 20 characters + * @return command processing error code + */ + NK_C_API int NK_fill_SD_card_with_random_data(const char* admin_pin); + + /** + * Change update password. + * Update password is used for entering update mode, where firmware + * could be uploaded using dfu-programmer or other means. + * Storage only + * @param current_update_password 20 characters + * @param new_update_password 20 characters + * @return command processing error code + */ + NK_C_API int NK_change_update_password(const char* current_update_password, + const char* new_update_password); + + /** + * Get Storage stick status as string. + * Storage only + * @return string with devices attributes + */ + NK_C_API const char* NK_get_status_storage_as_string(); + + /** + * Get SD card usage attributes as string. + * Usable during hidden volumes creation. + * Storage only + * @return string with SD card usage attributes + */ + NK_C_API const char* NK_get_SD_usage_data_as_string(); + + /** + * Get progress value of current long operation. + * Storage only + * @return int in range 0-100 or -1 if device is not busy + */ + NK_C_API int NK_get_progress_bar_value(); + +#ifdef __cplusplus } - +#endif #endif //LIBNITROKEY_NK_C_API_H -- cgit v1.2.3 From 7549606cf781c0b1966c5fab7a45e7573bc083b5 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Fri, 30 Jun 2017 18:45:40 +0200 Subject: Search for Windows DLLs --- unittest/conftest.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/unittest/conftest.py b/unittest/conftest.py index 67b45aa..c8d51af 100644 --- a/unittest/conftest.py +++ b/unittest/conftest.py @@ -24,7 +24,7 @@ def C(request): for declaration in a: if declaration.startswith('NK_C_API'): declaration = declaration.replace('NK_C_API', '').strip() - while not ';' in declaration: + while ';' not in declaration: declaration += (next(a)).strip() print(declaration) ffi.cdef(declaration, override=True) @@ -32,11 +32,19 @@ def C(request): 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")] + paths = [ + os.path.join(path_build,"libnitrokey-log.so"), + os.path.join(path_build,"libnitrokey.so"), + os.path.join(path_build,"libnitrokey-log.dll"), + os.path.join(path_build,"libnitrokey.dll"), + os.path.join(path_build,"nitrokey-log.dll"), + os.path.join(path_build,"nitrokey.dll"), + ] for p in paths: - print p + print(p) + p = os.path.abspath(p) if os.path.exists(p): + print("Found: "+p) C = ffi.dlopen(p) break else: -- cgit v1.2.3 From 9bad47a2a8383326258d8c808ba5e5684e839c9b Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Fri, 30 Jun 2017 18:47:33 +0200 Subject: Move to Python 3 Tested under Windows 8.1 and MSVC 2017 RC --- unittest/constants.py | 24 ++++---- unittest/requirements.txt | 1 - unittest/test_pro.py | 149 +++++++++++++++++++++++----------------------- unittest/test_storage.py | 36 +++++------ 4 files changed, 107 insertions(+), 103 deletions(-) diff --git a/unittest/constants.py b/unittest/constants.py index 0897b42..f3e876a 100644 --- a/unittest/constants.py +++ b/unittest/constants.py @@ -1,22 +1,26 @@ -from enum import Enum from misc import to_hex +def bb(x): + return bytes(x, encoding='ascii') + + RFC_SECRET_HR = '12345678901234567890' RFC_SECRET = to_hex(RFC_SECRET_HR) # '31323334353637383930...' +bbRFC_SECRET = bb(RFC_SECRET) # print( repr((RFC_SECRET, RFC_SECRET_, len(RFC_SECRET))) ) -class DefaultPasswords(Enum): - ADMIN = '12345678' - USER = '123456' - ADMIN_TEMP = '123123123' - USER_TEMP = '234234234' - UPDATE = '12345678' - UPDATE_TEMP = '123update123' +class DefaultPasswords: + ADMIN = b'12345678' + USER = b'123456' + ADMIN_TEMP = b'123123123' + USER_TEMP = b'234234234' + UPDATE = b'12345678' + UPDATE_TEMP = b'123update123' -class DeviceErrorCode(Enum): +class DeviceErrorCode: STATUS_OK = 0 BUSY = 1 # busy or busy progressbar in place of wrong_CRC status NOT_PROGRAMMED = 3 @@ -25,7 +29,7 @@ class DeviceErrorCode(Enum): STATUS_AES_DEC_FAILED = 0xa -class LibraryErrors(Enum): +class LibraryErrors: TOO_LONG_STRING = 200 INVALID_SLOT = 201 INVALID_HEX_STRING = 202 diff --git a/unittest/requirements.txt b/unittest/requirements.txt index 2cb9c05..5c0110b 100644 --- a/unittest/requirements.txt +++ b/unittest/requirements.txt @@ -1,5 +1,4 @@ cffi pytest-repeat pytest-randomly -enum oath \ No newline at end of file diff --git a/unittest/test_pro.py b/unittest/test_pro.py index 3f1f0a3..e94dc48 100644 --- a/unittest/test_pro.py +++ b/unittest/test_pro.py @@ -1,7 +1,7 @@ import pytest from conftest import skip_if_device_version_lower_than -from constants import DefaultPasswords, DeviceErrorCode, RFC_SECRET +from constants import DefaultPasswords, DeviceErrorCode, RFC_SECRET, bb, bbRFC_SECRET from misc import ffi, gs, wait, cast_pointer_to_tuple from misc import is_pro_rtm_07, is_pro_rtm_08, is_storage @@ -11,15 +11,15 @@ def test_enable_password_safe(C): All Password Safe tests depend on AES keys being initialized. They will fail otherwise. """ assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK - assert C.NK_enable_password_safe('wrong_password') == DeviceErrorCode.WRONG_PASSWORD + assert C.NK_enable_password_safe(b'wrong_password') == DeviceErrorCode.WRONG_PASSWORD assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK def test_write_password_safe_slot(C): assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK - assert C.NK_write_password_safe_slot(0, 'slotname1', 'login1', 'pass1') == DeviceErrorCode.STATUS_NOT_AUTHORIZED + assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_NOT_AUTHORIZED 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 + assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_OK @pytest.mark.slowtest @@ -29,7 +29,7 @@ def test_write_all_password_safe_slots_and_read_10_times(C): numbers = '1234567890'*4 s += numbers[:wid-len(s)] assert len(s) == wid - return s + return bb(s) def get_pass(suffix): return fill('pass' + suffix, 20) @@ -65,7 +65,7 @@ def test_read_all_password_safe_slots_10_times(C): numbers = '1234567890'*4 s += numbers[:wid-len(s)] assert len(s) == wid - return s + return bb(s) def get_pass(suffix): return fill('pass' + suffix, 20) @@ -90,31 +90,31 @@ def test_read_all_password_safe_slots_10_times(C): 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 + assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_OK assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK - assert gs(C.NK_get_password_safe_slot_name(0)) == '' + assert gs(C.NK_get_password_safe_slot_name(0)) == b'' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_NOT_AUTHORIZED assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK - assert gs(C.NK_get_password_safe_slot_name(0)) == 'slotname1' + assert gs(C.NK_get_password_safe_slot_name(0)) == b'slotname1' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK def test_get_password_safe_slot_login_password(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 + assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_OK slot_login = C.NK_get_password_safe_slot_login(0) assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK - assert gs(slot_login) == 'login1' + assert gs(slot_login) == b'login1' slot_password = gs(C.NK_get_password_safe_slot_password(0)) assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK - assert slot_password == 'pass1' + assert slot_password == b'pass1' def test_erase_password_safe_slot(C): assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_erase_password_safe_slot(0) == DeviceErrorCode.STATUS_OK - assert gs(C.NK_get_password_safe_slot_name(0)) == '' + assert gs(C.NK_get_password_safe_slot_name(0)) == b'' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK # TODO CHECK shouldn't this be DeviceErrorCode.NOT_PROGRAMMED ? @@ -122,7 +122,7 @@ def test_password_safe_slot_status(C): C.NK_set_debug(True) assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_erase_password_safe_slot(0) == DeviceErrorCode.STATUS_OK - assert C.NK_write_password_safe_slot(1, 'slotname2', 'login2', 'pass2') == DeviceErrorCode.STATUS_OK + assert C.NK_write_password_safe_slot(1, b'slotname2', b'login2', b'pass2') == DeviceErrorCode.STATUS_OK safe_slot_status = C.NK_get_password_safe_slot_status() assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK is_slot_programmed = list(ffi.cast("uint8_t [16]", safe_slot_status)[0:16]) @@ -131,6 +131,7 @@ def test_password_safe_slot_status(C): assert is_slot_programmed[1] == 1 +# TODO TOREGISTER 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 " @@ -171,13 +172,13 @@ def test_destroy_password_safe(C): C.NK_set_debug(True) assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK # write password safe slot - assert C.NK_write_password_safe_slot(0, 'slotname1', 'login1', 'pass1') == DeviceErrorCode.STATUS_OK + assert C.NK_write_password_safe_slot(0, b'slotname1', b'login1', b'pass1') == DeviceErrorCode.STATUS_OK # read slot - assert gs(C.NK_get_password_safe_slot_name(0)) == 'slotname1' + assert gs(C.NK_get_password_safe_slot_name(0)) == b'slotname1' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK slot_login = C.NK_get_password_safe_slot_login(0) assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK - assert gs(slot_login) == 'login1' + assert gs(slot_login) == b'login1' # destroy password safe by regenerating aes key assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK @@ -186,7 +187,7 @@ def test_destroy_password_safe(C): assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK - assert gs(C.NK_get_password_safe_slot_name(0)) != 'slotname1' + assert gs(C.NK_get_password_safe_slot_name(0)) != b'slotname1' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK # check was slot status cleared @@ -199,22 +200,22 @@ def test_destroy_password_safe(C): def test_is_AES_supported(C): if is_storage(C): pytest.skip("Storage does not implement this command") - assert C.NK_is_AES_supported('wrong password') != 1 + assert C.NK_is_AES_supported(b'wrong password') != 1 assert C.NK_get_last_command_status() == DeviceErrorCode.WRONG_PASSWORD assert C.NK_is_AES_supported(DefaultPasswords.USER) == 1 assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK def test_admin_PIN_change(C): - new_password = '123123123' - assert C.NK_change_admin_PIN('wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD + new_password = b'123123123' + assert C.NK_change_admin_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_change_admin_PIN(DefaultPasswords.ADMIN, new_password) == DeviceErrorCode.STATUS_OK assert C.NK_change_admin_PIN(new_password, DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK def test_user_PIN_change(C): - new_password = '123123123' - assert C.NK_change_user_PIN('wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD + new_password = b'123123123' + assert C.NK_change_user_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_change_user_PIN(DefaultPasswords.USER, new_password) == DeviceErrorCode.STATUS_OK assert C.NK_change_user_PIN(new_password, DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK @@ -223,7 +224,7 @@ def test_admin_retry_counts(C): default_admin_retry_count = 3 assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_get_admin_retry_count() == default_admin_retry_count - assert C.NK_change_admin_PIN('wrong_password', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.WRONG_PASSWORD + assert C.NK_change_admin_PIN(b'wrong_password', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_get_admin_retry_count() == default_admin_retry_count - 1 assert C.NK_change_admin_PIN(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK assert C.NK_get_admin_retry_count() == default_admin_retry_count @@ -231,7 +232,7 @@ def test_admin_retry_counts(C): def test_user_retry_counts_change_PIN(C): assert C.NK_change_user_PIN(DefaultPasswords.USER, DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK - wrong_password = 'wrong_password' + wrong_password = b'wrong_password' default_user_retry_count = 3 assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_get_user_retry_count() == default_user_retry_count @@ -244,7 +245,7 @@ def test_user_retry_counts_PWSafe(C): default_user_retry_count = 3 assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_get_user_retry_count() == default_user_retry_count - assert C.NK_enable_password_safe('wrong_password') == DeviceErrorCode.WRONG_PASSWORD + assert C.NK_enable_password_safe(b'wrong_password') == DeviceErrorCode.WRONG_PASSWORD assert C.NK_get_user_retry_count() == default_user_retry_count - 1 assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_get_user_retry_count() == default_user_retry_count @@ -254,15 +255,15 @@ def test_unlock_user_password(C): C.NK_set_debug(True) default_user_retry_count = 3 default_admin_retry_count = 3 - new_password = '123123123' + new_password = b'123123123' assert C.NK_get_user_retry_count() == default_user_retry_count - assert C.NK_change_user_PIN('wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD - assert C.NK_change_user_PIN('wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD - assert C.NK_change_user_PIN('wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD + assert C.NK_change_user_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD + assert C.NK_change_user_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD + assert C.NK_change_user_PIN(b'wrong_password', new_password) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_get_user_retry_count() == default_user_retry_count - 3 assert C.NK_get_admin_retry_count() == default_admin_retry_count - assert C.NK_unlock_user_password('wrong password', DefaultPasswords.USER) == DeviceErrorCode.WRONG_PASSWORD + assert C.NK_unlock_user_password(b'wrong password', DefaultPasswords.USER) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_get_admin_retry_count() == default_admin_retry_count - 1 assert C.NK_unlock_user_password(DefaultPasswords.ADMIN, DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK assert C.NK_get_user_retry_count() == default_user_retry_count @@ -270,12 +271,12 @@ def test_unlock_user_password(C): def test_admin_auth(C): - assert C.NK_first_authenticate('wrong_password', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.WRONG_PASSWORD + assert C.NK_first_authenticate(b'wrong_password', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK def test_user_auth(C): - assert C.NK_user_authenticate('wrong_password', DefaultPasswords.USER_TEMP) == DeviceErrorCode.WRONG_PASSWORD + assert C.NK_user_authenticate(b'wrong_password', DefaultPasswords.USER_TEMP) == DeviceErrorCode.WRONG_PASSWORD assert C.NK_user_authenticate(DefaultPasswords.USER, DefaultPasswords.USER_TEMP) == DeviceErrorCode.STATUS_OK @@ -284,7 +285,7 @@ def check_HOTP_RFC_codes(C, func, prep=None, use_8_digits=False): # https://tools.ietf.org/html/rfc4226#page-32 """ assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, use_8_digits, False, False, "", + assert C.NK_write_hotp_slot(1, b'python_test', bbRFC_SECRET, 0, use_8_digits, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK test_data = [ 1284755224, 1094287082, 137359152, 1726969429, 1640338314, 868254676, 1918287922, 82162583, 673399871, @@ -295,7 +296,7 @@ def check_HOTP_RFC_codes(C, func, prep=None, use_8_digits=False): prep() r = func(1) code = str(code)[-8:] if use_8_digits else str(code)[-6:] - assert code == r + assert bb(code) == r @pytest.mark.parametrize("use_8_digits", [False, True, ]) @@ -322,12 +323,12 @@ def test_HOTP_token(C): assert C.NK_write_config(255, 255, 255, use_pin_protection, not use_pin_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - token_ID = "AAV100000022" - assert C.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, False, False, True, token_ID, + token_ID = b"AAV100000022" + assert C.NK_write_hotp_slot(1, b'python_test', bbRFC_SECRET, 0, False, False, True, token_ID, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK for i in range(5): hotp_code = gs(C.NK_get_hotp_code(1)) - assert hotp_code != "" + assert hotp_code != b'' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK @@ -347,11 +348,11 @@ def test_HOTP_counters(C): slot_number = 1 for counter, code in enumerate(HOTP_test_data): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_hotp_slot(slot_number, 'python_test', RFC_SECRET, counter, use_8_digits, False, False, "", + assert C.NK_write_hotp_slot(slot_number, b'python_test', bbRFC_SECRET, counter, use_8_digits, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK r = gs(C.NK_get_hotp_code(slot_number)) code = str(code)[-8:] if use_8_digits else str(code)[-6:] - assert code == r + assert bb(code) == r INT32_MAX = 2 ** 31 - 1 @@ -360,7 +361,7 @@ def test_HOTP_64bit_counter(C): pytest.xfail('bug in NK Storage HOTP firmware - counter is set with a 8 digits string, ' 'however int32max takes 10 digits to be written') oath = pytest.importorskip("oath") - lib_at = lambda t: oath.hotp(RFC_SECRET, t, format='dec6') + lib_at = lambda t: bb(oath.hotp(RFC_SECRET, t, format='dec6')) PIN_protection = False use_8_digits = False slot_number = 1 @@ -371,7 +372,7 @@ def test_HOTP_64bit_counter(C): lib_res = [] for t in range(INT32_MAX - 5, INT32_MAX + 5, 1): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_hotp_slot(slot_number, 'python_test', RFC_SECRET, t, use_8_digits, False, False, "", + assert C.NK_write_hotp_slot(slot_number, b'python_test', bbRFC_SECRET, t, use_8_digits, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code_device = gs(C.NK_get_hotp_code(slot_number)) dev_res += (t, code_device) @@ -384,14 +385,14 @@ def test_TOTP_64bit_time(C): pytest.xfail('bug in NK Storage TOTP firmware') oath = pytest.importorskip("oath") T = 1 - lib_at = lambda t: oath.totp(RFC_SECRET, t=t) + lib_at = lambda t: bb(oath.totp(RFC_SECRET, t=t)) PIN_protection = False slot_number = 1 assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, PIN_protection, not PIN_protection, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_totp_slot(slot_number, 'python_test', RFC_SECRET, 30, False, False, False, "", + assert C.NK_write_totp_slot(slot_number, b'python_test', bbRFC_SECRET, 30, False, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK dev_res = [] lib_res = [] @@ -418,14 +419,14 @@ def test_TOTP_RFC_usepin(C, PIN_protection): DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK # test according to https://tools.ietf.org/html/rfc6238#appendix-B assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_totp_slot(slot_number, 'python_test', RFC_SECRET, 30, True, False, False, "", + assert C.NK_write_totp_slot(slot_number, b'python_test', bbRFC_SECRET, 30, True, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK get_func = None if PIN_protection: get_func = lambda x, y, z, r: gs(C.NK_get_totp_code_PIN(x, y, z, r, DefaultPasswords.USER_TEMP)) else: - get_func = lambda x: gs(C.NK_get_totp_code) + get_func = lambda x, y, z, r: gs(C.NK_get_totp_code(x, y, z, r)) # Mode: Sha1, time step X=30 test_data = [ @@ -446,7 +447,7 @@ def test_TOTP_RFC_usepin(C, PIN_protection): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_totp_set_time(t) == DeviceErrorCode.STATUS_OK code_from_device = get_func(slot_number, T, 0, 30) # FIXME T is not changing the outcome - data += [ (t, expected_code) ] + data += [ (t, bb(str(expected_code).zfill(8))) ] responses += [ (t, code_from_device) ] correct += expected_code == code_from_device assert data == responses or correct == len(test_data) @@ -475,12 +476,12 @@ def test_get_OTP_codes(C): assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK for i in range(15): code = gs(C.NK_get_totp_code(i, 0, 0, 0)) - if code == "": + if code == b'': assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED for i in range(3): code = gs(C.NK_get_hotp_code(i)) - if code == "": + if code == b'': assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED @@ -493,31 +494,31 @@ def test_get_OTP_code_from_not_programmed_slot(C): assert C.NK_erase_totp_slot(0, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code = gs(C.NK_get_hotp_code(0)) - assert code == "" + assert code == b'' assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED code = gs(C.NK_get_totp_code(0, 0, 0, 0)) - assert code == "" + assert code == b'' assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED def test_get_code_user_authorize(C): C.NK_set_debug(True) assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_totp_slot(0, 'python_otp_auth', RFC_SECRET, 30, True, False, False, "", + assert C.NK_write_totp_slot(0, b'python_otp_auth', bbRFC_SECRET, 30, True, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK # enable PIN protection of OTP codes with write_config # TODO create convinience function on C API side to enable/disable OTP USER_PIN protection assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, True, False, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code = gs(C.NK_get_totp_code(0, 0, 0, 0)) - assert code == "" + assert code == b'' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_NOT_AUTHORIZED # disable PIN protection with write_config assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code = gs(C.NK_get_totp_code(0, 0, 0, 0)) - assert code != "" + assert code != b'' assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK @@ -552,12 +553,12 @@ def test_factory_reset(C): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_config(255, 255, 255, False, True, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_hotp_slot(1, 'python_test', RFC_SECRET, 0, False, False, False, "", + assert C.NK_write_hotp_slot(1, b'python_test', bbRFC_SECRET, 0, False, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert gs(C.NK_get_hotp_code(1)) == "755224" + assert gs(C.NK_get_hotp_code(1)) == b"755224" assert C.NK_factory_reset(DefaultPasswords.ADMIN) == DeviceErrorCode.STATUS_OK wait(10) - assert gs(C.NK_get_hotp_code(1)) != "287082" + assert gs(C.NK_get_hotp_code(1)) != b"287082" assert C.NK_get_last_command_status() == DeviceErrorCode.NOT_PROGRAMMED # restore AES key assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK @@ -593,7 +594,7 @@ def test_OTP_secret_started_from_null(C, secret): skip_if_device_version_lower_than({'P': 8}) oath = pytest.importorskip("oath") - lib_at = lambda t: oath.hotp(secret, t, format='dec6') + lib_at = lambda t: bb(oath.hotp(secret, t, format='dec6')) PIN_protection = False use_8_digits = False slot_number = 1 @@ -604,7 +605,7 @@ def test_OTP_secret_started_from_null(C, secret): lib_res = [] for t in range(1,5): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_hotp_slot(slot_number, 'null_secret', secret, t, use_8_digits, False, False, "", + assert C.NK_write_hotp_slot(slot_number, b'null_secret', bb(secret), t, use_8_digits, False, False, b'', DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code_device = gs(C.NK_get_hotp_code(slot_number)) dev_res += (t, code_device) @@ -626,7 +627,7 @@ def test_HOTP_slots_read_write_counter(C, counter): secret = RFC_SECRET oath = pytest.importorskip("oath") - lib_at = lambda t: oath.hotp(secret, t, format='dec6') + lib_at = lambda t: bb(oath.hotp(secret, t, format='dec6')) PIN_protection = False use_8_digits = False assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK @@ -636,7 +637,7 @@ def test_HOTP_slots_read_write_counter(C, counter): lib_res = [] for slot_number in range(3): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_hotp_slot(slot_number, 'HOTP rw' + str(slot_number), secret, counter, use_8_digits, False, False, "", + assert C.NK_write_hotp_slot(slot_number, b'HOTP rw' + bytes(slot_number), bb(secret), counter, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code_device = gs(C.NK_get_hotp_code(slot_number)) dev_res += (counter, code_device) @@ -653,7 +654,7 @@ def test_TOTP_slots_read_write_at_time_period(C, time, period): """ secret = RFC_SECRET oath = pytest.importorskip("oath") - lib_at = lambda t: oath.totp(RFC_SECRET, t=t, period=period) + lib_at = lambda t: bb(oath.totp(RFC_SECRET, t=t, period=period)) PIN_protection = False use_8_digits = False T = 0 @@ -664,7 +665,7 @@ def test_TOTP_slots_read_write_at_time_period(C, time, period): lib_res = [] for slot_number in range(15): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_totp_slot(slot_number, 'TOTP rw' + str(slot_number), secret, period, use_8_digits, False, False, "", + assert C.NK_write_totp_slot(slot_number, b'TOTP rw' + bytes(slot_number), bb(secret), period, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_totp_set_time(time) == DeviceErrorCode.STATUS_OK @@ -688,7 +689,7 @@ def test_TOTP_secrets(C, secret): time = 0 period = 30 oath = pytest.importorskip("oath") - lib_at = lambda t: oath.totp(secret, t=t, period=period) + lib_at = lambda t: bb(oath.totp(secret, t=t, period=period)) PIN_protection = False use_8_digits = False T = 0 @@ -697,7 +698,7 @@ def test_TOTP_secrets(C, secret): DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK dev_res = [] lib_res = [] - assert C.NK_write_totp_slot(slot_number, 'secret' + str(len(secret)), secret, period, use_8_digits, False, False, "", + assert C.NK_write_totp_slot(slot_number, b'secret' + bytes(len(secret)), bb(secret), period, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_totp_set_time(time) == DeviceErrorCode.STATUS_OK code_device = gs(C.NK_get_totp_code(slot_number, T, 0, period)) @@ -718,7 +719,7 @@ def test_HOTP_secrets(C, secret): slot_number = 0 counter = 0 oath = pytest.importorskip("oath") - lib_at = lambda t: oath.hotp(secret, counter=t) + lib_at = lambda t: bb(oath.hotp(secret, counter=t)) PIN_protection = False use_8_digits = False T = 0 @@ -727,7 +728,7 @@ def test_HOTP_secrets(C, secret): DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK dev_res = [] lib_res = [] - assert C.NK_write_hotp_slot(slot_number, 'secret' + str(len(secret)), secret, counter, use_8_digits, False, False, "", + assert C.NK_write_hotp_slot(slot_number, b'secret' + bytes(len(secret)), bb(secret), counter, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code_device = gs(C.NK_get_hotp_code(slot_number)) dev_res += (counter, code_device) @@ -750,7 +751,7 @@ def test_special_double_press(C): DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK for slot_number in range(3): assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_hotp_slot(slot_number, 'double' + str(slot_number), secret, counter, use_8_digits, False, False, "", + assert C.NK_write_hotp_slot(slot_number, b'double' + bytes(slot_number), bb(secret), counter, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK # requires manual check @@ -771,17 +772,17 @@ def test_edit_OTP_slot(C): DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK slot_number = 0 assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - first_name = 'edit slot' - assert C.NK_write_hotp_slot(slot_number, first_name, secret, counter, use_8_digits, False, False, "", + first_name = b'edit slot' + assert C.NK_write_hotp_slot(slot_number, first_name, bb(secret), counter, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert gs(C.NK_get_hotp_slot_name(slot_number)) == first_name first_code = gs(C.NK_get_hotp_code(slot_number)) - changed_name = 'changedname' - empty_secret = '' + changed_name = b'changedname' + empty_secret = b'' assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK - assert C.NK_write_hotp_slot(slot_number, changed_name, empty_secret, counter, use_8_digits, False, False, "", + assert C.NK_write_hotp_slot(slot_number, changed_name, empty_secret, counter, use_8_digits, False, False, b"", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK second_code = gs(C.NK_get_hotp_code(slot_number)) assert first_code == second_code @@ -804,6 +805,6 @@ def test_TOTP_codes_from_nitrokeyapp(secret, C): code_device = gs(C.NK_get_totp_code(slot_number, 0, 0, period)) oath = pytest.importorskip("oath") - lib_at = lambda : oath.totp(secret, period=period) + lib_at = lambda : bb(oath.totp(secret, period=period)) print (lib_at()) assert lib_at() == code_device diff --git a/unittest/test_storage.py b/unittest/test_storage.py index da7c9a3..6671f5b 100644 --- a/unittest/test_storage.py +++ b/unittest/test_storage.py @@ -3,7 +3,7 @@ import pprint import pytest from conftest import skip_if_device_version_lower_than -from constants import DefaultPasswords, DeviceErrorCode +from constants import DefaultPasswords, DeviceErrorCode, bb from misc import gs, wait pprint = pprint.PrettyPrinter(indent=4).pprint @@ -28,7 +28,7 @@ def test_get_status_storage(C): assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK status_string = gs(status_pointer) assert len(status_string) > 0 - status_dict = get_dict_from_dissect(status_string) + 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 @@ -39,7 +39,7 @@ def test_sd_card_usage(C): assert C.NK_get_last_command_status() == DeviceErrorCode.STATUS_OK data_string = gs(data_pointer) assert len(data_string) > 0 - data_dict = get_dict_from_dissect(data_string) + data_dict = get_dict_from_dissect(data_string.decode("ascii")) assert int(data_dict['WriteLevelMax']) <= 100 @@ -51,7 +51,7 @@ def test_encrypted_volume_unlock(C): def test_encrypted_volume_unlock_hidden(C): skip_if_device_version_lower_than({'S': 43}) - hidden_volume_password = 'hiddenpassword' + hidden_volume_password = b'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 @@ -61,8 +61,8 @@ def test_encrypted_volume_unlock_hidden(C): 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) + hidden_volume_password = b'hiddenpassword' + bb(str(random.randint(0,100))) + p = lambda i: hidden_volume_password + bb(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): @@ -76,8 +76,8 @@ def test_encrypted_volume_setup_multiple_hidden_lock(C): @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) + hidden_volume_password = b'hiddenpassword' + p = lambda i: hidden_volume_password + bb(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): @@ -95,8 +95,8 @@ def test_encrypted_volume_setup_multiple_hidden_no_lock_device_volumes(C, volume @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) + hidden_volume_password = b'hiddenpassword' + p = lambda i: hidden_volume_password + bb(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): @@ -116,8 +116,8 @@ def test_encrypted_volume_setup_multiple_hidden_no_lock_device_volumes_unlock_at @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) + hidden_volume_password = b'hiddenpassword' + p = lambda i: hidden_volume_password + bb(str(i)) assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK assert C.NK_unlock_encrypted_volume(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK i = use_slot @@ -143,7 +143,7 @@ def test_password_safe_slot_name_corruption(C): numbers = '1234567890' * 4 s += numbers[:wid - len(s)] assert len(s) == wid - return s + return bb(s) def get_pass(suffix): return fill('pass' + suffix, 20) @@ -170,8 +170,8 @@ def test_password_safe_slot_name_corruption(C): 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) + hidden_volume_password = b'hiddenpassword' + p = lambda i: hidden_volume_password + bb(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 @@ -208,8 +208,8 @@ 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) + hidden_volume_password = b'hiddenpassword' + p = lambda i: hidden_volume_password + bb(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 @@ -261,7 +261,7 @@ def test_get_busy_progress_on_idle(C): def test_change_update_password(C): skip_if_device_version_lower_than({'S': 43}) - wrong_password = 'aaaaaaaaaaa' + wrong_password = b'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 -- cgit v1.2.3 From 6af29597ccc59c91e48a5f81a9ed474392cab8e8 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Mon, 3 Jul 2017 19:32:20 +0200 Subject: Ignore whitespace in C API header Signed-off-by: Szczepan Zalega --- unittest/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittest/conftest.py b/unittest/conftest.py index c8d51af..04e85ff 100644 --- a/unittest/conftest.py +++ b/unittest/conftest.py @@ -22,7 +22,7 @@ def C(request): a = iter(declarations) for declaration in a: - if declaration.startswith('NK_C_API'): + if declaration.strip().startswith('NK_C_API'): declaration = declaration.replace('NK_C_API', '').strip() while ';' not in declaration: declaration += (next(a)).strip() -- cgit v1.2.3 From b929268d67efeea7f68b7ff226db3ae83863eeb0 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Mon, 3 Jul 2017 19:38:07 +0200 Subject: Skip factory reset tests for now Not working due to CRC error bug Signed-off-by: Szczepan Zalega --- unittest/test_pro.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/unittest/test_pro.py b/unittest/test_pro.py index e94dc48..11873fe 100644 --- a/unittest/test_pro.py +++ b/unittest/test_pro.py @@ -147,6 +147,7 @@ def test_regenerate_aes_key(C): assert C.NK_enable_password_safe(DefaultPasswords.USER) == DeviceErrorCode.STATUS_OK +@pytest.mark.skip def test_enable_password_safe_after_factory_reset(C): assert C.NK_lock_device() == DeviceErrorCode.STATUS_OK if is_storage(C): @@ -548,6 +549,7 @@ def test_read_write_config(C): assert config == (255, 255, 255, False, True) +@pytest.mark.skip def test_factory_reset(C): C.NK_set_debug(True) assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK -- cgit v1.2.3 From 3cc0028870701cc862f3feeda781ea9e35281d87 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Wed, 20 Sep 2017 08:48:34 +0200 Subject: Guard Windows instructions Signed-off-by: Szczepan Zalega --- libnitrokey.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libnitrokey.pro b/libnitrokey.pro index 621a137..5af0526 100644 --- a/libnitrokey.pro +++ b/libnitrokey.pro @@ -59,10 +59,10 @@ unix{ SOURCES += $$PWD/hidapi/mac/hid.c } -#win32 { +win32 { SOURCES += $$PWD/hidapi/windows/hid.c LIBS += -lsetupapi -#} +} INCLUDEPATH = \ $$PWD/. \ -- cgit v1.2.3 From b4f269c67e8a93c22c94d50a04e800a0a56806b0 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Wed, 20 Sep 2017 10:44:32 +0200 Subject: Compilation documentation update Signed-off-by: Szczepan Zalega --- README.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 99c4a44..2848cc2 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,19 @@ Following libraries are needed to use libnitrokey on Linux (names of the package ## Compilation -libnitrokey uses CMake as its build system. To compile please run following sequence of commands: +libnitrokey uses CMake as its main build system. As a secondary option it offers building through Qt's qMake. +### Qt +A .pro project file is provided for direct compilation and for inclusion to other projects. + +### Windows MS Visual Studio 2017 +Lately Visual Studio has started handling CMake files directly. After opening the project's directory it should recognize it and initialize build system. Afterwards please run: +1. `CMake -> Cache -> View Cache CMakeLists.txt -> CMakeLists.txt` to edit settings +2. `CMake -> Build All` to build + +It is possible too to use CMake GUI directly with its settings editor. + +### Linux CLI +To compile please run following sequence of commands: ```bash # assuming current dir is ./libnitrokey/ mkdir -p build @@ -50,7 +62,7 @@ Other build options (all take either `ON` or `OFF`): -# Using with Python +# Using libnitrokey with Python To use libnitrokey with Python a [CFFI](http://cffi.readthedocs.io/en/latest/overview.html) library is required (either 2.7+ or 3.0+). It can be installed with: ```bash pip install --user cffi # for python 2.x @@ -137,7 +149,7 @@ Please check NK_C_API.h (C API) for high level commands and include/NitrokeyMana Warning! Before you run unittests please either change both your Admin and User PINs on your Nitrostick to defaults (`12345678` and `123456` respectively) or change the values in tests source code. If you do not change them the tests might lock your device. If it's too late, you can always reset your Nitrokey using instructions from [homepage](https://www.nitrokey.com/de/documentation/how-reset-nitrokey). ## Python tests -Libnitrokey has a great suite of tests written in Python under the path: `unittest/test_*.py`: +Libnitrokey has a great suite of tests written in Python 3 under the path: `unittest/test_*.py`: * `test_pro.py` - contains tests of OTP, Password Safe and PIN control functionality. Could be run on both Pro and Storage devices. * `test_storage.py` - contains tests of Encrypted Volumes functionality. Could be run only on Storage. The tests themselves show how to handle common requests to device. -- cgit v1.2.3 From a57ed65f90c2ffda245c93aaa4aa710b605550d7 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Wed, 20 Sep 2017 11:19:30 +0200 Subject: Qt project update Build shared library with debug symbols Fix build for Linux Remove commented lines Signed-off-by: Szczepan Zalega --- libnitrokey.pro | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libnitrokey.pro b/libnitrokey.pro index 5af0526..f7711bf 100644 --- a/libnitrokey.pro +++ b/libnitrokey.pro @@ -1,17 +1,13 @@ # Created by and for Qt Creator. This file was created for editing the project sources only. # You may attempt to use it for building too, by modifying this file here. -#TARGET = libnitrokey - -CONFIG += c++14 staticlib -#QT = +CONFIG += c++14 shared debug TEMPLATE = lib TARGET = nitrokey HEADERS = \ $$PWD/hidapi/hidapi/hidapi.h \ -# $$PWD/include/hidapi/hidapi.h \ $$PWD/include/command.h \ $$PWD/include/command_id.h \ $$PWD/include/CommandFailedException.h \ @@ -52,11 +48,13 @@ tests { } unix:!macx{ - SOURCES += $$PWD/hidapi/linux/hid.c +# SOURCES += $$PWD/hidapi/linux/hid.c + LIBS += -lhidapi-libusb } -unix{ +macx{ SOURCES += $$PWD/hidapi/mac/hid.c + LIBS+= -framework IOKit -framework CoreFoundation } win32 { -- cgit v1.2.3 From 36b563b8efa720f56739019778086762cc6aaa81 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Thu, 1 Jun 2017 19:47:53 +0200 Subject: Show more detailed status in debug log Signed-off-by: Szczepan Zalega --- include/stick20_commands.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/stick20_commands.h b/include/stick20_commands.h index 5f99d28..f4da337 100644 --- a/include/stick20_commands.h +++ b/include/stick20_commands.h @@ -184,14 +184,19 @@ namespace nitrokey { print_to_ss( MagicNumber_StickConfig_u16 ); 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) ReadWriteFlagHiddenVolume_u8 ); print_to_ss((int) FirmwareLocked_u8 ); print_to_ss((int) NewSDCardFound_u8 ); + print_to_ss((int) NewSDCardFound_st.NewCard ); + print_to_ss((int) NewSDCardFound_st.Counter ); print_to_ss((int) SDFillWithRandomChars_u8 ); print_to_ss( ActiveSD_CardID_u32 ); print_to_ss((int) VolumeActiceFlag_u8 ); + print_to_ss((int) VolumeActiceFlag_st.unencrypted ); + print_to_ss((int) VolumeActiceFlag_st.encrypted ); + print_to_ss((int) VolumeActiceFlag_st.hidden); print_to_ss((int) NewSmartCardFound_u8 ); print_to_ss((int) UserPwRetryCount ); print_to_ss((int) AdminPwRetryCount ); -- cgit v1.2.3 From 2a3e72179f1cadc01897d74a5fc87686863ec258 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Thu, 25 May 2017 13:10:36 +0200 Subject: Show warning message about invalid incoming packet's CRC Signed-off-by: Szczepan Zalega --- include/device_proto.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/include/device_proto.h b/include/device_proto.h index b557384..c126acd 100644 --- a/include/device_proto.h +++ b/include/device_proto.h @@ -352,12 +352,6 @@ namespace nitrokey { clear_packet(outp); - if (!resp.isCRCcorrect()) - LOGD(std::string("Accepting response from device with invalid CRC. ") - + "Command ID: " + std::to_string(resp.command_id) + " " + - commandid_to_string(static_cast(resp.command_id)) - ); - if (status <= 0) { dev->m_counters.receiving_error++; @@ -398,6 +392,14 @@ namespace nitrokey { dev->m_counters.successful_storage_commands++; } + if (!resp.isCRCcorrect()) + LOG(std::string("Accepting response from device with invalid CRC. ") + + "Command ID: " + std::to_string(resp.command_id) + " " + + commandid_to_string(static_cast(resp.command_id)) + " " + + "Reported and calculated: " + std::to_string(resp.crc) + "!=" + std::to_string(resp.calculate_CRC()), + Loglevel::WARNING + ); + // See: DeviceResponse return resp; } -- cgit v1.2.3 From bda5bab9646d3abc6e7209618d8e6f26208274a9 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Thu, 25 May 2017 13:12:15 +0200 Subject: Catch invalid CRC exception in C API To handle invalid response packets in C API Signed-off-by: Szczepan Zalega --- NK_C_API.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NK_C_API.cc b/NK_C_API.cc index 0e3fa1f..209b378 100644 --- a/NK_C_API.cc +++ b/NK_C_API.cc @@ -76,6 +76,12 @@ uint8_t get_without_result(T func){ catch (LibraryException & libraryException){ NK_last_command_status = libraryException.exception_id(); } + catch (const InvalidCRCReceived &invalidCRCException){ + ;;; + } + catch (const DeviceCommunicationException &deviceException){ + NK_last_command_status = -1; + } return NK_last_command_status; } -- cgit v1.2.3 From f53e5e799fe111bcf0b8ed71710e00000e097aca Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Tue, 27 Jun 2017 09:42:18 +0200 Subject: Tests: do additional authentication for Pro 0.7 Signed-off-by: Szczepan Zalega --- unittest/test_pro.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/unittest/test_pro.py b/unittest/test_pro.py index 3f1f0a3..c292940 100644 --- a/unittest/test_pro.py +++ b/unittest/test_pro.py @@ -727,6 +727,8 @@ def test_HOTP_secrets(C, secret): DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK dev_res = [] lib_res = [] + # repeat authentication for Pro 0.7 + assert C.NK_first_authenticate(DefaultPasswords.ADMIN, DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK assert C.NK_write_hotp_slot(slot_number, 'secret' + str(len(secret)), secret, counter, use_8_digits, False, False, "", DefaultPasswords.ADMIN_TEMP) == DeviceErrorCode.STATUS_OK code_device = gs(C.NK_get_hotp_code(slot_number)) -- cgit v1.2.3 From 74c547e08220a55878de74d7c304c3a5cee33b11 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Mon, 11 Sep 2017 10:55:49 +0200 Subject: Do not resend command to device Signed-off-by: Szczepan Zalega --- device.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device.cc b/device.cc index 5f1c9a0..e6edd73 100644 --- a/device.cc +++ b/device.cc @@ -27,7 +27,7 @@ Device::Device(const uint16_t vid, const uint16_t pid, const DeviceModel model, m_vid(vid), m_pid(pid), m_model(model), - m_retry_sending_count(3), + m_retry_sending_count(1), m_retry_receiving_count(retry_receiving_count), m_retry_timeout(retry_timeout), m_send_receive_delay(send_receive_delay), -- cgit v1.2.3 From e1d35ffdaa4147b18ab22a1acc70762c9434a2d7 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Mon, 11 Sep 2017 10:56:26 +0200 Subject: Log formatting: Enumerate from 1 Signed-off-by: Szczepan Zalega --- device.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device.cc b/device.cc index e6edd73..a7b68e1 100644 --- a/device.cc +++ b/device.cc @@ -93,7 +93,7 @@ int Device::send(const void *packet) { mp_devhandle, (const unsigned char *)(packet), HID_REPORT_SIZE); if (send_feature_report < 0) _reconnect(); //add thread sleep? - LOG(std::string("Sending attempt: ")+std::to_string(i) + " / 3" , Loglevel::DEBUG_L2); + LOG(std::string("Sending attempt: ")+std::to_string(i+1) + " / 3" , Loglevel::DEBUG_L2); } return send_feature_report; } -- cgit v1.2.3 From 8ea7214692243eadf18c4cdabf66500e8357ba0c Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Mon, 11 Sep 2017 10:57:08 +0200 Subject: Make only 10 retries on receiving Signed-off-by: Szczepan Zalega --- device.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/device.cc b/device.cc index a7b68e1..2fc55c7 100644 --- a/device.cc +++ b/device.cc @@ -200,7 +200,7 @@ Stick10::Stick10(): Stick20::Stick20(): - Device(0x20a0, 0x4109, DeviceModel::STORAGE, 20ms, 20, 20ms) + Device(0x20a0, 0x4109, DeviceModel::STORAGE, 20ms, 10, 20ms) { setDefaultDelay(); } -- cgit v1.2.3 From 7e9fb2806f301f98b48e462d18fd1d3531db024a Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Mon, 11 Sep 2017 10:57:30 +0200 Subject: Do not make longer waiting than 500ms on iteration Signed-off-by: Szczepan Zalega --- include/device_proto.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/device_proto.h b/include/device_proto.h index c126acd..691c17b 100644 --- a/include/device_proto.h +++ b/include/device_proto.h @@ -312,6 +312,7 @@ namespace nitrokey { std::to_string(receiving_retry_counter), Loglevel::DEBUG_L2); } else { retry_timeout *= 2; + retry_timeout = std::min(retry_timeout, 500ms); busy_counter = 0; LOG("Status busy, decreasing receiving_retry_counter counter: " + std::to_string(receiving_retry_counter) + ", current delay:" -- cgit v1.2.3 From 2e446c208e3522ff3b7a38eec40368fe15528a80 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Thu, 1 Jun 2017 19:50:19 +0200 Subject: Update hidapi Update to latest version with proper adjustments Signed-off-by: Szczepan Zalega --- hidapi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hidapi b/hidapi index 324dc7c..4e6cb25 160000 --- a/hidapi +++ b/hidapi @@ -1 +1 @@ -Subproject commit 324dc7c0d125f57a06e1107e90e49eb4377bd03c +Subproject commit 4e6cb25a8b48c500326c7d635e01c9f1bbd47306 -- cgit v1.2.3 From ff1f2248b830ad78833e347be8d8c8dc9cb03c85 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Fri, 15 Sep 2017 16:34:11 +0200 Subject: Correct mutex placement Move mutex from template instantation to single compilation unit to make it work as desired Signed-off-by: Szczepan Zalega --- NitrokeyManager.cc | 2 ++ include/device_proto.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/NitrokeyManager.cc b/NitrokeyManager.cc index 9a9d106..7985eb3 100644 --- a/NitrokeyManager.cc +++ b/NitrokeyManager.cc @@ -10,6 +10,8 @@ #include "include/cxx_semantics.h" #include +std::mutex nitrokey::proto::send_receive_mtx; + namespace nitrokey{ std::mutex mex_dev_com_manager; diff --git a/include/device_proto.h b/include/device_proto.h index 691c17b..4a548a0 100644 --- a/include/device_proto.h +++ b/include/device_proto.h @@ -37,6 +37,9 @@ namespace nitrokey { namespace proto { + extern std::mutex send_receive_mtx; + + /* * POD types for HID proto commands * Instances are meant to be __packed. @@ -215,7 +218,6 @@ namespace nitrokey { using namespace ::nitrokey::log; using namespace std::chrono_literals; - static std::mutex send_receive_mtx; std::lock_guard guard(send_receive_mtx); LOG(__FUNCTION__, Loglevel::DEBUG_L2); -- cgit v1.2.3 From 09d699a7c7edce60547a3e9900301e1ea62188f6 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Fri, 15 Sep 2017 16:35:46 +0200 Subject: Decrease busy-delay count Signed-off-by: Szczepan Zalega --- include/device_proto.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/device_proto.h b/include/device_proto.h index 4a548a0..6631d2f 100644 --- a/include/device_proto.h +++ b/include/device_proto.h @@ -308,7 +308,7 @@ namespace nitrokey { } if (resp.device_status == static_cast(stick10::device_status::busy)) { dev->m_counters.busy++; - if (busy_counter++<10) { + if (busy_counter++<3) { receiving_retry_counter++; LOG("Status busy, not decreasing receiving_retry_counter counter: " + std::to_string(receiving_retry_counter), Loglevel::DEBUG_L2); -- cgit v1.2.3 From a83419fe4a13bc77005d455dd89685b8c1443d96 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Fri, 15 Sep 2017 16:36:18 +0200 Subject: Set lower maximum between-sending delay Signed-off-by: Szczepan Zalega --- include/device_proto.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/device_proto.h b/include/device_proto.h index 6631d2f..bb14b42 100644 --- a/include/device_proto.h +++ b/include/device_proto.h @@ -314,7 +314,7 @@ namespace nitrokey { std::to_string(receiving_retry_counter), Loglevel::DEBUG_L2); } else { retry_timeout *= 2; - retry_timeout = std::min(retry_timeout, 500ms); + retry_timeout = std::min(retry_timeout, 300ms); busy_counter = 0; LOG("Status busy, decreasing receiving_retry_counter counter: " + std::to_string(receiving_retry_counter) + ", current delay:" -- cgit v1.2.3 From 7d0d03428f90d3f65452eb7035bb715efec87ac8 Mon Sep 17 00:00:00 2001 From: Szczepan Zalega Date: Wed, 20 Sep 2017 17:12:18 +0200 Subject: Update hidapi Open in enumeration mode under Windows Signed-off-by: Szczepan Zalega --- hidapi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hidapi b/hidapi index 4e6cb25..b767b43 160000 --- a/hidapi +++ b/hidapi @@ -1 +1 @@ -Subproject commit 4e6cb25a8b48c500326c7d635e01c9f1bbd47306 +Subproject commit b767b43f3e6f9c5b92ea7d738331deb8e03c4baf -- cgit v1.2.3