1 /* ykparse.c --- Example command line interface for authentication token.
2  *
3  * Written by Simon Josefsson <simon@josefsson.org>.
4  * Copyright (c) 2006-2012 Yubico AB
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are
9  * met:
10  *
11  *    * Redistributions of source code must retain the above copyright
12  *      notice, this list of conditions and the following disclaimer.
13  *
14  *    * Redistributions in binary form must reproduce the above
15  *      copyright notice, this list of conditions and the following
16  *      disclaimer in the documentation and/or other materials provided
17  *      with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 #include "yubikey.h"
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdint.h>
38 #include <string.h>
39 
40 int
main(int argc,char * argv[])41 main (int argc, char *argv[])
42 {
43   uint8_t buf[128];
44   uint8_t key[YUBIKEY_KEY_SIZE];
45   char *aeskey, *token;
46   yubikey_token_st tok;
47 
48   /* Parse command line parameters. */
49   if (argc < 2)
50     {
51       printf ("Usage: %s <aeskey> <token>\n", argv[0]);
52       printf (" AESKEY:\tHex encoded AES-key.\n");
53       printf (" TOKEN:\t\tModHex encoded token.\n");
54       return EXIT_FAILURE;
55     }
56 
57   aeskey = argv[1];
58   token = argv[2];
59 
60   if (strlen (aeskey) != 32)
61     {
62       printf ("error: Hex encoded AES-key must be 32 characters.\n");
63       return EXIT_FAILURE;
64     }
65 
66   if (strlen (token) > 32)
67     {
68       printf ("warning: overlong token, ignoring prefix: %.*s\n",
69 	      (int) strlen (token) - 32, token);
70       token = token + (strlen (token) - 32);
71     }
72 
73   if (strlen (token) != 32)
74     {
75       printf ("error: ModHex encoded token must be 32 characters.\n");
76       return EXIT_FAILURE;
77     }
78 
79   /* Debug. */
80   printf ("Input:\n");
81   printf ("  token: %s\n", token);
82 
83   yubikey_modhex_decode ((char *) key, token, YUBIKEY_KEY_SIZE);
84 
85   {
86     size_t i;
87     printf ("          ");
88     for (i = 0; i < YUBIKEY_KEY_SIZE; i++)
89       printf ("%02x ", key[i] & 0xFF);
90     printf ("\n");
91   }
92 
93   printf ("  aeskey: %s\n", aeskey);
94 
95   yubikey_hex_decode ((char *) key, aeskey, YUBIKEY_KEY_SIZE);
96 
97   {
98     size_t i;
99     printf ("          ");
100     for (i = 0; i < YUBIKEY_KEY_SIZE; i++)
101       printf ("%02x ", key[i] & 0xFF);
102     printf ("\n");
103   }
104 
105   /* Pack up dynamic password, decrypt it and verify checksum */
106   yubikey_parse ((uint8_t *) token, key, &tok);
107 
108   printf ("Output:\n");
109   {
110     size_t i;
111     printf ("          ");
112     for (i = 0; i < YUBIKEY_BLOCK_SIZE; i++)
113       printf ("%02x ", ((uint8_t *) & tok)[i] & 0xFF);
114     printf ("\n");
115   }
116 
117   printf ("\nStruct:\n");
118   /* Debug */
119   {
120     size_t i;
121     printf ("  uid: ");
122     for (i = 0; i < YUBIKEY_UID_SIZE; i++)
123       printf ("%02x ", tok.uid[i] & 0xFF);
124     printf ("\n");
125   }
126   printf ("  counter: %d (0x%04x)\n", tok.ctr, tok.ctr);
127   printf ("  timestamp (low): %d (0x%04x)\n", tok.tstpl, tok.tstpl);
128   printf ("  timestamp (high): %d (0x%02x)\n", tok.tstph, tok.tstph);
129   printf ("  session use: %d (0x%02x)\n", tok.use, tok.use);
130   printf ("  random: %d (0x%02x)\n", tok.rnd, tok.rnd);
131   printf ("  crc: %d (0x%04x)\n", tok.crc, tok.crc);
132 
133   printf ("\nDerived:\n");
134   printf ("  cleaned counter: %d (0x%04x)\n",
135 	  yubikey_counter (tok.ctr), yubikey_counter (tok.ctr));
136   yubikey_modhex_encode ((char *) buf, (char *) tok.uid, YUBIKEY_UID_SIZE);
137   printf ("  modhex uid: %s\n", buf);
138   printf ("  triggered by caps lock: %s\n",
139 	  yubikey_capslock (tok.ctr) ? "yes" : "no");
140   printf ("  crc: %04X\n", yubikey_crc16 ((void *) &tok, YUBIKEY_KEY_SIZE));
141 
142   printf ("  crc check: ");
143   if (yubikey_crc_ok_p ((uint8_t *) & tok))
144     {
145       printf ("ok\n");
146       return EXIT_SUCCESS;
147     }
148 
149   printf ("fail\n");
150   return EXIT_FAILURE;
151 }
152