From f7ee528d41325d335b5cada4b4dfe514d76cc9e8 Mon Sep 17 00:00:00 2001 From: Kyle Manna Date: Sat, 6 Sep 2014 22:09:06 -0700 Subject: [PATCH] YubiKey: Retry to recover hotplugging * Attempt one retry in the event the event the device was removed and re-inserted. Signed-off-by: Kyle Manna --- src/keys/YkChallengeResponseKey.cpp | 22 ++++++++++++++++++++++ src/keys/YkChallengeResponseKey.h | 3 ++- src/keys/drivers/YubiKey.cpp | 5 +++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/keys/YkChallengeResponseKey.cpp b/src/keys/YkChallengeResponseKey.cpp index 5f495a34..17982ab6 100644 --- a/src/keys/YkChallengeResponseKey.cpp +++ b/src/keys/YkChallengeResponseKey.cpp @@ -26,6 +26,8 @@ #include "keys/YkChallengeResponseKey.h" #include "keys/drivers/YubiKey.h" +#include + YkChallengeResponseKey::YkChallengeResponseKey(int slot, bool blocking) : m_slot(slot), @@ -46,11 +48,31 @@ YkChallengeResponseKey* YkChallengeResponseKey::clone() const /** Assumes yubikey()->init() was called */ bool YkChallengeResponseKey::challenge(const QByteArray& chal) +{ + return challenge(chal, 1); +} + +bool YkChallengeResponseKey::challenge(const QByteArray& chal, int retries) { if (YubiKey::instance()->challenge(m_slot, true, chal, m_key) != YubiKey::ERROR) { return true; } + /* If challenge failed, retry to detect YubiKeys int the event the YubiKey + * was un-plugged and re-plugged */ + while (retries > 0) { + qDebug() << "Attempt" << retries << "to re-detect YubiKey(s)"; + retries--; + + if (YubiKey::instance()->init() != true) { + continue; + } + + if (YubiKey::instance()->challenge(m_slot, true, chal, m_key) != YubiKey::ERROR) { + return true; + } + } + return false; } diff --git a/src/keys/YkChallengeResponseKey.h b/src/keys/YkChallengeResponseKey.h index a5236748..8acb0f9e 100644 --- a/src/keys/YkChallengeResponseKey.h +++ b/src/keys/YkChallengeResponseKey.h @@ -31,7 +31,8 @@ public: QByteArray rawKey() const; YkChallengeResponseKey* clone() const; - bool challenge(const QByteArray& challenge); + bool challenge(const QByteArray& chal); + bool challenge(const QByteArray& chal, int retries); QString getName() const; bool isBlocking() const; diff --git a/src/keys/drivers/YubiKey.cpp b/src/keys/drivers/YubiKey.cpp index 1d69bb5b..9c87ec15 100644 --- a/src/keys/drivers/YubiKey.cpp +++ b/src/keys/drivers/YubiKey.cpp @@ -182,6 +182,11 @@ YubiKey::ChallengeResult YubiKey::challenge(int slot, bool mayBlock, int yk_cmd = (slot == 1) ? SLOT_CHAL_HMAC1 : SLOT_CHAL_HMAC2; QByteArray paddedChal = chal; + /* Ensure that YubiKey::init() succeeded */ + if (m_yk == NULL) { + return ERROR; + } + /* yk_challenge_response() insists on 64 byte response buffer */ resp.resize(64);