From 5bd4c71bb1f8ca49a0101f4752b5933f320b201a Mon Sep 17 00:00:00 2001 From: Klas Lindfors Date: Tue, 18 Sep 2012 13:29:28 +0200 Subject: [PATCH] add function yk_challenge_response used for doing challenge-response with a key. used from ykchalresp.c --- configure.ac | 2 +- libykpers-1.map | 7 +++++++ ykchalresp.c | 32 +++++++------------------------- ykcore/ykcore.c | 43 ++++++++++++++++++++++++++++++++++++++++++- ykcore/ykcore.h | 5 +++++ 5 files changed, 62 insertions(+), 27 deletions(-) diff --git a/configure.ac b/configure.ac index b72ad4e..61490a2 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/libykpers-1.map b/libykpers-1.map index 2407744..5786fe9 100644 --- a/libykpers-1.map +++ b/libykpers-1.map @@ -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; diff --git a/ykchalresp.c b/ykchalresp.c index f85fa9c..b9a165c 100644 --- a/ykchalresp.c +++ b/ykchalresp.c @@ -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); diff --git a/ykcore/ykcore.c b/ykcore/ykcore.c index b4d4324..49dc728 100644 --- a/ykcore/ykcore.c +++ b/ykcore/ykcore.c @@ -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) { diff --git a/ykcore/ykcore.h b/ykcore/ykcore.h index dace4b6..94ad961 100644 --- a/ykcore/ykcore.h +++ b/ykcore/ykcore.h @@ -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. -- 2.39.5