]> err.no Git - yubikey-personalization/commitdiff
add function yk_challenge_response
authorKlas Lindfors <klas@yubico.com>
Tue, 18 Sep 2012 11:29:28 +0000 (13:29 +0200)
committerKlas Lindfors <klas@yubico.com>
Tue, 18 Sep 2012 11:40:31 +0000 (13:40 +0200)
used for doing challenge-response with a key. used from ykchalresp.c

configure.ac
libykpers-1.map
ykchalresp.c
ykcore/ykcore.c
ykcore/ykcore.h

index b72ad4e49babda719ce47b0e587d7ef78148c149..61490a2338cfb1032bd3015cf8dba21d4430db47 100644 (file)
@@ -38,7 +38,7 @@ AC_CONFIG_MACRO_DIR([m4])
 # Interfaces removed:                           AGE=0
 AC_SUBST(LT_CURRENT, 8)
 AC_SUBST(LT_REVISION, 1)
-AC_SUBST(LT_AGE, 7)
+AC_SUBST(LT_AGE, 8)
 
 AM_INIT_AUTOMAKE([-Wall -Werror])
 AM_SILENT_RULES([yes])
index 2407744f6d2767055a4b193a4dab3ebddea049c8..5786fe9d4079e9e4e31c3cabe41df72892ce8697 100644 (file)
@@ -144,3 +144,10 @@ LIBYKPERS_1.7 {
   ykp_construct_ndef_text;
 # Variables:
 } LIBYKPERS_1.6;
+
+LIBYKPERS_1.8 {
+  global:
+# Functions:
+  yk_challenge_response;
+# Variables:
+} LIBYKPERS_1.7;
index f85fa9c5cb450a920eeb4bddb6074136319a7e69..b9a165c100ff48e5fc9c23fa2f3c7c9bbf1d7d84 100644 (file)
@@ -190,18 +190,12 @@ static int challenge_response(YK_KEY *yk, int slot,
        unsigned char response[64];
        unsigned char output_buf[(SHA1_MAX_BLOCK_SIZE * 2) + 1];
        int yk_cmd;
-       unsigned int flags = 0;
-       unsigned int response_len = 0;
        unsigned int expect_bytes = 0;
-
        memset(response, 0, sizeof(response));
-
-       if (may_block)
-               flags |= YK_FLAG_MAYBLOCK;
+       memset(output_buf, 0, sizeof(output_buf));
 
        if (verbose) {
                fprintf(stderr, "Sending %i bytes %s challenge to slot %i\n", len, (hmac == true)?"HMAC":"Yubico", slot);
-               //_yk_hexdump(challenge, len);
        }
 
        switch(slot) {
@@ -211,34 +205,22 @@ static int challenge_response(YK_KEY *yk, int slot,
        case 2:
                yk_cmd = (hmac == true) ? SLOT_CHAL_HMAC2 : SLOT_CHAL_OTP2;
                break;
+       default:
+               return 0;
        }
 
-       if (!yk_write_to_key(yk, yk_cmd, challenge, len))
+       if(! yk_challenge_response(yk, yk_cmd, may_block, len,
+                               challenge, sizeof(response), response)) {
                return 0;
-
-       if (verbose) {
-               fprintf(stderr, "Reading response...\n");
        }
 
        /* HMAC responses are 160 bits, Yubico 128 */
        expect_bytes = (hmac == true) ? 20 : 16;
 
-       if (! yk_read_response_from_key(yk, slot, flags,
-                                       &response, sizeof(response),
-                                       expect_bytes,
-                                       &response_len))
-               return 0;
-
-       if (hmac && response_len > 20)
-               response_len = 20;
-       if (! hmac && response_len > 16)
-               response_len = 16;
-
-       memset(output_buf, 0, sizeof(output_buf));
        if (hmac) {
-               yubikey_hex_encode((char *)output_buf, (char *)response, response_len);
+               yubikey_hex_encode((char *)output_buf, (char *)response, expect_bytes);
        } else {
-               yubikey_modhex_encode((char *)output_buf, (char *)response, response_len);
+               yubikey_modhex_encode((char *)output_buf, (char *)response, expect_bytes);
        }
        printf("%s\n", output_buf);
 
index b4d4324e9476735bd325b62b1f9d383d22b48a29..49dc728c5f9d9abae0eeb5a0765410e8fd9a0e42 100644 (file)
@@ -277,6 +277,46 @@ int yk_write_ndef(YK_KEY *yk, YKNDEF *ndef)
        return stat.pgmSeq != seq;
 }
 
+/*
+ * This function is for doing HMAC-SHA1 or Yubico challenge-response with a key.
+ */
+int yk_challenge_response(YK_KEY *yk, uint8_t yk_cmd, int may_block,
+               unsigned int challenge_len, unsigned char *challenge,
+               unsigned int response_len, unsigned char *response)
+{
+       unsigned int flags = 0;
+       unsigned int bytes_read = 0;
+       unsigned int expect_bytes = 0;
+
+       switch(yk_cmd) {
+       case SLOT_CHAL_HMAC1:
+       case SLOT_CHAL_HMAC2:
+               expect_bytes = 20;
+               break;
+       case SLOT_CHAL_OTP1:
+       case SLOT_CHAL_OTP2:
+               expect_bytes = 16;
+               break;
+       default:
+               yk_errno = YK_EINVALIDCMD;
+               return 0;
+       }
+
+       if (may_block)
+               flags |= YK_FLAG_MAYBLOCK;
+
+       if (! yk_write_to_key(yk, yk_cmd, challenge, challenge_len)) {
+               return 0;
+       }
+
+       if (! yk_read_response_from_key(yk, yk_cmd, flags,
+                               response, response_len,
+                               expect_bytes,
+                               &bytes_read)) {
+               return 0;
+       }
+       return 1;
+}
 
 int * const _yk_errno_location(void)
 {
@@ -319,7 +359,8 @@ static const char *errtext[] = {
        "no status structure given",
        "not yet implemented",
        "checksum mismatch",
-       "operation would block"
+       "operation would block",
+       "invalid command for operation"
 };
 const char *yk_strerror(int errnum)
 {
index dace4b691ceea1e85f02253ea9bcec7c947b2a69..94ad961df02603964317c28691d6e79120c5c36c 100644 (file)
@@ -116,6 +116,10 @@ extern int yk_write_config(YK_KEY *k, YK_CONFIG *cfg, int confnum,
                           unsigned char *acc_code);
 /* Write something to the YubiKey (a command that is). */
 extern int yk_write_to_key(YK_KEY *yk, uint8_t slot, const void *buf, int bufcount);
+/* Do a challenge-response round with the key. */
+extern int yk_challenge_response(YK_KEY *yk, uint8_t yk_cmd, int may_block,
+                                unsigned int challenge_len, unsigned char *challenge,
+                                unsigned int response_len, unsigned char *response);
 
 extern int yk_force_key_update(YK_KEY *yk);
 
@@ -143,6 +147,7 @@ const char *yk_usb_strerror(void);
 #define YK_ENOTYETIMPL 0x09
 #define YK_ECHECKSUM   0x0a    /* checksum validation failed */
 #define YK_EWOULDBLOCK 0x0b    /* operation would block */
+#define YK_EINVALIDCMD 0x0c    /* supplied command is invalid for this operation */
 
 /* Flags for response reading. Use high numbers to not exclude the possibility
  * to combine these with for example SLOT commands from ykdef.h in the future.