/*
* Copyright (c) 2017-2018 Nitrokey UG
*
* This file is part of libnitrokey.
*
* libnitrokey is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* libnitrokey is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libnitrokey. If not, see .
*
* SPDX-License-Identifier: LGPL-3.0
*/
static const char *const default_admin_pin = "12345678";
static const char *const default_user_pin = "123456";
const char * temporary_password = "123456789012345678901234";
const char * RFC_SECRET = "12345678901234567890";
#include "catch2/catch.hpp"
#include
#include
#include
#include "../NK_C_API.h"
using namespace nitrokey;
TEST_CASE("List devices", "[BASIC]") {
auto v = Device::enumerate();
REQUIRE(v.size() > 0);
for (auto i : v){
auto d = Device::create(i.m_deviceModel);
if (!d) {
std::cout << "Could not create device with model " << i.m_deviceModel << "\n";
continue;
}
std::cout << i.m_deviceModel << " " << i.m_path << " "
<< i.m_serialNumber << " |";
d->set_path(i.m_path);
d->connect();
auto res = GetStatus::CommandTransaction::run(d);
std::cout << " " << res.data().card_serial_u32 << " "
<< res.data().get_card_serial_hex()
<< std::endl;
d->disconnect();
}
}
TEST_CASE("List Storage devices", "[BASIC]") {
shared_ptr d = make_shared();
auto v = Device::enumerate();
REQUIRE(v.size() > 0);
for (auto i : v){
if (i.m_deviceModel != DeviceModel::STORAGE)
continue;
auto a = i.m_path;
std::cout << a;
d->set_path(a);
d->connect();
auto res = GetStatus::CommandTransaction::run(d);
auto res2 = GetDeviceStatus::CommandTransaction::run(d);
std::cout << " " << res.data().card_serial_u32 << " "
<< res.data().get_card_serial_hex()
<< " " << std::to_string(res2.data().versionInfo.minor)
<< std::endl;
d->disconnect();
}
}
TEST_CASE("Regenerate AES keys", "[BASIC]") {
shared_ptr d = make_shared();
auto v = Device::enumerate();
REQUIRE(v.size() > 0);
std::vector> devices;
for (auto i : v){
if (i.m_deviceModel != DeviceModel::STORAGE)
continue;
auto a = i.m_path;
std::cout << a << endl;
d = make_shared();
d->set_path(a);
d->connect();
devices.push_back(d);
}
for (auto d : devices){
auto res2 = GetDeviceStatus::CommandTransaction::run(d);
std::cout << std::to_string(res2.data().versionInfo.minor) << std::endl;
// nitrokey::proto::stick20::CreateNewKeys::CommandPayload p;
// p.set_defaults();
// memcpy(p.password, "12345678", 8);
// auto res3 = nitrokey::proto::stick20::CreateNewKeys::CommandTransaction::run(d, p);
}
for (auto d : devices){
//TODO watch out for multiple hid_exit calls
d->disconnect();
}
}
TEST_CASE("Use C API", "[BASIC]") {
auto ptr = NK_list_devices();
auto first_ptr = ptr;
REQUIRE(ptr != nullptr);
while (ptr) {
std::cout << "Connect with: " << ptr->model << " " << ptr->path << " "
<< ptr->serial_number << " | " << NK_connect_with_path(ptr->path) << " | ";
auto status = NK_get_status_as_string();
std::cout << status << std::endl;
free(status);
ptr = ptr->next;
}
NK_free_device_info(first_ptr);
}
TEST_CASE("Use API", "[BASIC]") {
auto nm = NitrokeyManager::instance();
nm->set_loglevel(2);
auto v = nm->list_devices();
REQUIRE(v.size() > 0);
for (auto i : v) {
std::cout << "Connect with: " << i.m_deviceModel << " " << i.m_path << " "
<< i.m_serialNumber << " | " << std::boolalpha << nm->connect_with_path(i.m_path) << " |";
try {
auto status = nm->get_status();
std::cout << " " << status.card_serial_u32 << " "
<< status.get_card_serial_hex()
<< std::endl;
} catch (const LongOperationInProgressException &e) {
std::cout << "long operation in progress on " << i.m_path
<< " " << std::to_string(e.progress_bar_value) << std::endl;
}
}
}
TEST_CASE("Use Storage API", "[BASIC]") {
auto nm = NitrokeyManager::instance();
nm->set_loglevel(2);
auto v = nm->list_devices();
REQUIRE(v.size() > 0);
for (int i=0; i<10; i++){
for (auto i : v) {
if (i.m_deviceModel != DeviceModel::STORAGE)
continue;
auto a = i.m_path;
std::cout <<"Connect with: " << a <<
" " << std::boolalpha << nm->connect_with_path(a) << " ";
try{
auto status_storage = nm->get_status_storage();
std::cout << status_storage.ActiveSmartCardID_u32
<< " " << status_storage.ActiveSD_CardID_u32
<< std::endl;
// nm->fill_SD_card_with_random_data("12345678");
}
catch (const LongOperationInProgressException &e){
std::cout << "long operation in progress on " << a
<< " " << std::to_string(e.progress_bar_value) << std::endl;
// this_thread::sleep_for(1000ms);
}
}
std::cout <<"Iteration: " << i << std::endl;
}
}
TEST_CASE("Use API ID", "[BASIC]") {
auto nm = NitrokeyManager::instance();
nm->set_loglevel(2);
auto v = nm->list_devices_by_cpuID();
REQUIRE(v.size() > 0);
//no refresh - should not reconnect to new devices
// Scenario:
// 1. Run test
// 2. Remove one of the devices and reinsert it after a while
// 3. Device should not be reconnected and test should not crash
// 4. Remove all devices - test should continue
for (int j = 0; j < 100; j++) {
for (auto i : v) {
if (!nm->connect_with_ID(i)) continue;
int retry_count = 99;
try {
retry_count = nm->get_admin_retry_count();
std::cout << j << " " << i << " " << to_string(retry_count) << std::endl;
}
catch (...) {
retry_count = 99;
//pass
}
}
}
std::cout << "finished" << std::endl;
}
TEST_CASE("Use API ID refresh", "[BASIC]") {
auto nm = NitrokeyManager::instance();
nm->set_loglevel(2);
//refresh in each iteration - should reconnect to new devices
// Scenario:
// 1. Run test
// 2. Remove one of the devices and reinsert it after a while
// 3. Device should be reconnected
for(int j=0; j<100; j++) {
auto v = nm->list_devices_by_cpuID();
REQUIRE(v.size() > 0);
for (auto i : v) {
nm->connect_with_ID(i);
int retry_count = 99;
try {
retry_count = nm->get_admin_retry_count();
std::cout << j <<" " << i << " " << to_string(retry_count) << std::endl;
}
catch (...){
retry_count = 99;
//pass
}
}
}
std::cout << "finished" << std::endl;
}