diff options
Diffstat (limited to 'unittest/test_HOTP.cc')
-rw-r--r-- | unittest/test_HOTP.cc | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/unittest/test_HOTP.cc b/unittest/test_HOTP.cc new file mode 100644 index 0000000..e6f7d7c --- /dev/null +++ b/unittest/test_HOTP.cc @@ -0,0 +1,101 @@ +#include "catch.hpp" +#include <iostream> +#include "device_proto.h" +#include "log.h" +#include "stick10_commands.h" +#include <cstdlib> +#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<strlen(hexString); i++){ + buf[i%2] = hexString[i]; + if (i%2==1){ + data[i/2] = strtoul(buf, NULL, 16) & 0xFF; + } + } +}; + +TEST_CASE("test secret", "[functions]") { + uint8_t slot_secret[21]; + slot_secret[20] = 0; + const char* secretHex = "3132333435363738393031323334353637383930"; + hexStringToByte(slot_secret, secretHex); + CAPTURE(slot_secret); + REQUIRE(strcmp("12345678901234567890",reinterpret_cast<char *>(slot_secret) ) == 0 ); +} + +TEST_CASE("Test HOTP codes according to RFC", "[HOTP]") { + std::shared_ptr<Stick10> stick = make_shared<Stick10>(); + 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<FirstAuthenticate>(); + 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<WriteToHOTPSlot>(); + hwrite.slot_number = 0x10; + strcpy(reinterpret_cast<char *>(hwrite.slot_name), "rfc4226_lib"); + //strcpy(reinterpret_cast<char *>(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<char *>(hwrite.slot_token_id), ""); + //strcpy(reinterpret_cast<char *>(hwrite.slot_counter), ""); + + //authorize writehotp first + { + auto auth = get_payload<Authorize>(); + 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<GetHOTP>(); + 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(); +} |