# 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])
ykp_construct_ndef_text;
# Variables:
} LIBYKPERS_1.6;
+
+LIBYKPERS_1.8 {
+ global:
+# Functions:
+ yk_challenge_response;
+# Variables:
+} LIBYKPERS_1.7;
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) {
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);
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)
{
"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)
{
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);
#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.