/* * 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 */ #include "catch.hpp" #include #include "device_proto.h" #include "log.h" #include "stick10_commands.h" #include #include "misc.h" using namespace std; using namespace nitrokey::device; using namespace nitrokey::proto::stick10; using namespace nitrokey::log; using namespace nitrokey::misc; void hexStringToByte(uint8_t data[], const char* hexString){ REQUIRE(strlen(hexString)%2==0); char buf[3]; buf[2] = '\0'; for(size_t i=0; i(slot_secret) ) == 0 ); } TEST_CASE("Test HOTP codes according to RFC", "[HOTP]") { std::shared_ptr stick = make_shared(); bool connected = stick->connect(); REQUIRE(connected == true); Log::instance().set_loglevel(Loglevel::DEBUG); auto resp = GetStatus::CommandTransaction::run(stick); const char * temporary_password = "123456789012345678901234"; { auto authreq = get_payload(); strcpy((char *)(authreq.card_password), "12345678"); strcpy((char *)(authreq.temporary_password), temporary_password); FirstAuthenticate::CommandTransaction::run(stick, authreq); } //test according to https://tools.ietf.org/html/rfc4226#page-32 { auto hwrite = get_payload(); hwrite.slot_number = 0x10; strcpy(reinterpret_cast(hwrite.slot_name), "rfc4226_lib"); //strcpy(reinterpret_cast(hwrite.slot_secret), ""); const char* secretHex = "3132333435363738393031323334353637383930"; hexStringToByte(hwrite.slot_secret, secretHex); //hwrite.slot_config; //TODO check various configs in separate test cases //strcpy(reinterpret_cast(hwrite.slot_token_id), ""); //strcpy(reinterpret_cast(hwrite.slot_counter), ""); //authorize writehotp first { auto auth = get_payload(); strcpy((char *)(auth.temporary_password), temporary_password); auth.crc_to_authorize = WriteToHOTPSlot::CommandTransaction::getCRC(hwrite); Authorize::CommandTransaction::run(stick, auth); } //run hotp command WriteToHOTPSlot::CommandTransaction::run(stick, hwrite); uint32_t codes[] = { 755224, 287082, 359152, 969429, 338314, 254676, 287922, 162583, 399871, 520489 }; for( auto code: codes){ auto gh = get_payload(); gh.slot_number = 0x10; auto resp = GetHOTP::CommandTransaction::run(stick, gh); REQUIRE( resp.data().code == code); } //checking slot programmed before with nitro-app /* for( auto code: codes){ GetHOTP::CommandTransaction::CommandPayload gh; gh.slot_number = 0x12; auto resp = GetHOTP::CommandTransaction::run(stick, gh); REQUIRE( resp.code == code); } */ } stick->disconnect(); }