]> err.no Git - yubikey-personalization/commitdiff
Added TOTP (6 digits) functionality to ykchalresp.c
authorjoernchen of Phenoelit <joernchen@phenoelit.de>
Wed, 15 Jan 2014 23:17:36 +0000 (00:17 +0100)
committerjoernchen of Phenoelit <joernchen@phenoelit.de>
Wed, 15 Jan 2014 23:17:36 +0000 (00:17 +0100)
ykchalresp.c

index fdeeb4babed0592b2f5df208593f4c6d8f8bd45a..b669ea6de82b95c498808106d3ddc4cf98a418fe 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <stdio.h>
 #include <unistd.h>
+#include <time.h>
 
 #include <yubikey.h>
 #include <ykdef.h>
@@ -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;
        }