From: joernchen of Phenoelit Date: Wed, 15 Jan 2014 23:17:36 +0000 (+0100) Subject: Added TOTP (6 digits) functionality to ykchalresp.c X-Git-Tag: v1.15.1~43 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=366137257c6290f7fd0169a97ef0f563816bf35e;p=yubikey-personalization Added TOTP (6 digits) functionality to ykchalresp.c --- diff --git a/ykchalresp.c b/ykchalresp.c index fdeeb4b..b669ea6 100644 --- a/ykchalresp.c +++ b/ykchalresp.c @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -52,6 +53,7 @@ const char *usage = "\t-Y Send a 6 byte Yubico challenge.\n" "\t-N Abort if Yubikey requires button press.\n" "\t-x Challenge is hex encoded.\n" + "\t-t Calculate TOTP (length 6, implies -H)\n" "\n" "\t-v verbose\n" "\t-V tool version\n" @@ -59,7 +61,7 @@ const char *usage = "\n" "\n" ; -const char *optstring = "12xvhHYNV"; +const char *optstring = "12xvhHtYNV"; static void report_yk_error(void) { @@ -77,7 +79,7 @@ static void report_yk_error(void) static int parse_args(int argc, char **argv, int *slot, bool *verbose, unsigned char **challenge, unsigned int *challenge_len, - bool *hmac, bool *may_block, + bool *hmac, bool *may_block, bool *totp, int *exit_code) { int c; @@ -97,8 +99,13 @@ static int parse_args(int argc, char **argv, case 'N': *may_block = false; break; + case 't': + *totp = true; + *hmac = true; + break; case 'Y': *hmac = false; + *totp = false; break; case 'x': hex_encoded = true; @@ -118,13 +125,25 @@ static int parse_args(int argc, char **argv, } } - if (optind >= argc) { + if (optind >= argc && !*totp) { /* No challenge */ fputs(usage, stderr); return 0; } - - if (hex_encoded) { + if (*totp && *hmac) { + unsigned int t_counter; + static unsigned char t_buf[8]; + t_counter = (int) time(NULL); + t_counter = t_counter / 30; + memset(t_buf, 0, sizeof(t_buf)); + t_buf[7] = t_counter & 0x000000ff; + t_buf[6] = (t_counter & 0x0000ff00) >> 8; + t_buf[5] = (t_counter & 0x00ff0000) >>16; + t_buf[4] = (t_counter & 0xff000000) >>24; + *challenge = (unsigned char *) &t_buf; + *challenge_len = 8; + } + else if (hex_encoded) { static unsigned char decoded[SHA1_MAX_BLOCK_SIZE]; size_t strl = strlen(argv[optind]); @@ -189,12 +208,14 @@ static int check_firmware(YK_KEY *yk, bool verbose) static int challenge_response(YK_KEY *yk, int slot, unsigned char *challenge, unsigned int len, - bool hmac, bool may_block, bool verbose) + bool hmac, bool may_block, bool verbose, bool totp) { unsigned char response[64]; unsigned char output_buf[(SHA1_MAX_BLOCK_SIZE * 2) + 1]; int yk_cmd; unsigned int expect_bytes = 0; + unsigned int offset; + unsigned int bin_code; memset(response, 0, sizeof(response)); memset(output_buf, 0, sizeof(output_buf)); @@ -221,6 +242,16 @@ static int challenge_response(YK_KEY *yk, int slot, /* HMAC responses are 160 bits, Yubico 128 */ expect_bytes = (hmac == true) ? 20 : 16; + if(totp){ + offset = response[19] & 0xf ; + bin_code = (response[offset] & 0x7f) << 24 + | (response[offset+1] & 0xff) << 16 + | (response[offset+2] & 0xff) << 8 + | (response[offset+3] & 0xff) ; + bin_code = bin_code % 1000000; + printf("%06i\n", bin_code); + return 1; + } if (hmac) { yubikey_hex_encode((char *)output_buf, (char *)response, expect_bytes); } else { @@ -241,6 +272,7 @@ int main(int argc, char **argv) bool verbose = false; bool hmac = true; bool may_block = true; + bool totp = false; unsigned char *challenge; unsigned int challenge_len; int slot = 1; @@ -250,7 +282,7 @@ int main(int argc, char **argv) if (! parse_args(argc, argv, &slot, &verbose, &challenge, &challenge_len, - &hmac, &may_block, + &hmac, &may_block, &totp, &exit_code)) exit(exit_code); @@ -271,7 +303,7 @@ int main(int argc, char **argv) if (! challenge_response(yk, slot, challenge, challenge_len, - hmac, may_block, verbose)) { + hmac, may_block, verbose, totp)) { exit_code = 1; goto err; }