#include "catch.hpp" #include #include "device_proto.h" #include "log.h" #include "NKPro_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[2]; for(int 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(); }