/* * Copyright (c) 2015-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 "catch.hpp" #include #include #include #include "device_proto.h" #include "log.h" #include "stick10_commands_0.8.h" //#include "stick20_commands.h" using namespace std; using namespace nitrokey::device; using namespace nitrokey::proto; using namespace nitrokey::proto::stick10_08; using namespace nitrokey::log; using namespace nitrokey::misc; using Dev = Stick10; using Dev10 = std::shared_ptr; void connect_and_setup(Dev10 stick) { bool connected = stick->connect(); REQUIRE(connected == true); Log::instance().set_loglevel(Loglevel::DEBUG); } void authorize(Dev10 stick) { auto authreq = get_payload(); strcpy((char *) (authreq.card_password), default_admin_pin); strcpy((char *) (authreq.temporary_password), temporary_password); FirstAuthenticate::CommandTransaction::run(stick, authreq); auto user_auth = get_payload(); strcpyT(user_auth.temporary_password, temporary_password); strcpyT(user_auth.card_password, default_user_pin); UserAuthenticate::CommandTransaction::run(stick, user_auth); } TEST_CASE("write slot", "[pronew]"){ auto stick = make_shared(); connect_and_setup(stick); authorize(stick); auto p2 = get_payload(); strcpyT(p2.temporary_admin_password, temporary_password); p2.setTypeName(); strcpyT(p2.data, "test name aaa"); stick10_08::SendOTPData::CommandTransaction::run(stick, p2); p2 = get_payload(); strcpyT(p2.temporary_admin_password, temporary_password); strcpyT(p2.data, RFC_SECRET); p2.setTypeSecret(); stick10_08::SendOTPData::CommandTransaction::run(stick, p2); auto p = get_payload(); strcpyT(p.temporary_admin_password, temporary_password); p.use_8_digits = true; p.slot_number = 0 + 0x10; p.slot_counter_or_interval = 0; stick10_08::WriteToOTPSlot::CommandTransaction::run(stick, p); auto pc = get_payload(); pc.enable_user_password = 0; strcpyT(pc.temporary_admin_password, temporary_password); WriteGeneralConfig::CommandTransaction::run(stick, pc); auto p3 = get_payload(); p3.slot_number = 0 + 0x10; GetHOTP::CommandTransaction::run(stick, p3); } TEST_CASE("erase slot", "[pronew]"){ auto stick = make_shared(); connect_and_setup(stick); authorize(stick); auto p = get_payload(); p.enable_user_password = 0; strcpyT(p.temporary_admin_password, temporary_password); WriteGeneralConfig::CommandTransaction::run(stick, p); auto p3 = get_payload(); p3.slot_number = 0 + 0x10; GetHOTP::CommandTransaction::run(stick, p3); auto erase_payload = get_payload(); erase_payload.slot_number = 0 + 0x10; strcpyT(erase_payload.temporary_admin_password, temporary_password); EraseSlot::CommandTransaction::run(stick, erase_payload); auto p4 = get_payload(); p4.slot_number = 0 + 0x10; REQUIRE_THROWS( GetHOTP::CommandTransaction::run(stick, p4) ); } TEST_CASE("write general config", "[pronew]") { auto stick = make_shared(); connect_and_setup(stick); authorize(stick); auto p = get_payload(); p.enable_user_password = 1; REQUIRE_THROWS( WriteGeneralConfig::CommandTransaction::run(stick, p) ); strcpyT(p.temporary_admin_password, temporary_password); WriteGeneralConfig::CommandTransaction::run(stick, p); } TEST_CASE("authorize user HOTP", "[pronew]") { auto stick = make_shared(); connect_and_setup(stick); authorize(stick); { auto p = get_payload(); p.enable_user_password = 1; strcpyT(p.temporary_admin_password, temporary_password); WriteGeneralConfig::CommandTransaction::run(stick, p); } auto p2 = get_payload(); strcpyT(p2.temporary_admin_password, temporary_password); p2.setTypeName(); strcpyT(p2.data, "test name aaa"); stick10_08::SendOTPData::CommandTransaction::run(stick, p2); p2 = get_payload(); strcpyT(p2.temporary_admin_password, temporary_password); strcpyT(p2.data, RFC_SECRET); p2.setTypeSecret(); stick10_08::SendOTPData::CommandTransaction::run(stick, p2); auto p = get_payload(); strcpyT(p.temporary_admin_password, temporary_password); p.use_8_digits = true; p.slot_number = 0 + 0x10; p.slot_counter_or_interval = 0; stick10_08::WriteToOTPSlot::CommandTransaction::run(stick, p); auto p3 = get_payload(); p3.slot_number = 0 + 0x10; REQUIRE_THROWS( GetHOTP::CommandTransaction::run(stick, p3) ); strcpyT(p3.temporary_user_password, temporary_password); auto code_response = GetHOTP::CommandTransaction::run(stick, p3); REQUIRE(code_response.data().code == 84755224); } TEST_CASE("check firmware version", "[pronew]") { auto stick = make_shared(); connect_and_setup(stick); auto p = GetStatus::CommandTransaction::run(stick); REQUIRE(p.data().firmware_version == 8); } TEST_CASE("authorize user TOTP", "[pronew]") { auto stick = make_shared(); connect_and_setup(stick); authorize(stick); { auto p = get_payload(); p.enable_user_password = 1; strcpyT(p.temporary_admin_password, temporary_password); WriteGeneralConfig::CommandTransaction::run(stick, p); } auto p2 = get_payload(); strcpyT(p2.temporary_admin_password, temporary_password); p2.setTypeName(); strcpyT(p2.data, "test name TOTP"); stick10_08::SendOTPData::CommandTransaction::run(stick, p2); p2 = get_payload(); strcpyT(p2.temporary_admin_password, temporary_password); strcpyT(p2.data, RFC_SECRET); p2.setTypeSecret(); stick10_08::SendOTPData::CommandTransaction::run(stick, p2); auto p = get_payload(); strcpyT(p.temporary_admin_password, temporary_password); p.use_8_digits = true; p.slot_number = 0 + 0x20; p.slot_counter_or_interval = 30; stick10_08::WriteToOTPSlot::CommandTransaction::run(stick, p); auto p_get_totp = get_payload(); p_get_totp.slot_number = 0 + 0x20; REQUIRE_THROWS( GetTOTP::CommandTransaction::run(stick, p_get_totp) ); strcpyT(p_get_totp.temporary_user_password, temporary_password); auto p_set_time = get_payload(); p_set_time.reset = 1; p_set_time.time = 59; SetTime::CommandTransaction::run(stick, p_set_time); auto code = GetTOTP::CommandTransaction::run(stick, p_get_totp); REQUIRE(code.data().code == 94287082); }