Replace all crypto libraries with Botan
Selected the [Botan crypto library](https://github.com/randombit/botan) due to its feature list, maintainer support, availability across all deployment platforms, and ease of use. Also evaluated Crypto++ as a viable candidate, but the additional features of Botan (PKCS#11, TPM, etc) won out. The random number generator received a backend upgrade. Botan prefers hardware-based RNG's and will provide one if available. This is transparent to KeePassXC and a significant improvement over gcrypt. Replaced Argon2 library with built-in Botan implementation that supports i, d, and id. This requires Botan 2.11.0 or higher. Also simplified the parameter test across KDF's. Aligned SymmetricCipher parameters with available modes. All encrypt and decrypt operations are done in-place instead of returning new objects. This allows use of secure vectors in the future with no additional overhead. Took this opportunity to decouple KeeShare from SSH Agent. Removed leftover code from OpenSSHKey and consolidated the SSH Agent code into the same directory. Removed bcrypt and blowfish inserts since they are provided by Botan. Additionally simplified KeeShare settings interface by removing raw certificate byte data from the user interface. KeeShare will be further refactored in a future PR. NOTE: This PR breaks backwards compatibility with KeeShare certificates due to different RSA key storage with Botan. As a result, new "own" certificates will need to be generated and trust re-established. Removed YKChallengeResponseKeyCLI in favor of just using the original implementation with signal/slots. Removed TestRandom stub since it was just faking random numbers and not actually using the backend. TestRandomGenerator now uses the actual RNG. Greatly simplified Secret Service plugin's use of crypto functions with Botan.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QUuid>
|
||||
#include <botan/secmem.h>
|
||||
|
||||
class ChallengeResponseKey
|
||||
{
|
||||
@@ -31,9 +32,13 @@ public:
|
||||
}
|
||||
virtual ~ChallengeResponseKey() = default;
|
||||
|
||||
virtual QByteArray rawKey() const = 0;
|
||||
virtual bool challenge(const QByteArray& challenge) = 0;
|
||||
virtual QUuid uuid() const
|
||||
|
||||
Botan::secure_vector<char>& rawKey()
|
||||
{
|
||||
return m_key;
|
||||
}
|
||||
QUuid uuid() const
|
||||
{
|
||||
return m_uuid;
|
||||
}
|
||||
@@ -44,6 +49,7 @@ public:
|
||||
|
||||
protected:
|
||||
QString m_error;
|
||||
Botan::secure_vector<char> m_key;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(ChallengeResponseKey);
|
||||
|
||||
@@ -143,7 +143,7 @@ bool CompositeKey::challenge(const QByteArray& seed, QByteArray& result, QString
|
||||
qWarning() << "Failed to issue challenge: " << key->error();
|
||||
return false;
|
||||
}
|
||||
cryptoHash.addData(key->rawKey());
|
||||
cryptoHash.addData(key->rawKey().data());
|
||||
}
|
||||
|
||||
result = cryptoHash.result();
|
||||
|
||||
@@ -24,29 +24,16 @@
|
||||
|
||||
#include <QFile>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <gcrypt.h>
|
||||
#include <sodium.h>
|
||||
|
||||
QUuid FileKey::UUID("a584cbc4-c9b4-437e-81bb-362ca9709273");
|
||||
|
||||
constexpr int FileKey::SHA256_SIZE;
|
||||
|
||||
FileKey::FileKey()
|
||||
: Key(UUID)
|
||||
, m_key(static_cast<char*>(gcry_malloc_secure(SHA256_SIZE)))
|
||||
, m_key(SHA256_SIZE)
|
||||
{
|
||||
}
|
||||
|
||||
FileKey::~FileKey()
|
||||
{
|
||||
if (m_key) {
|
||||
gcry_free(m_key);
|
||||
m_key = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read key file from device while trying to detect its file format.
|
||||
*
|
||||
@@ -169,10 +156,7 @@ bool FileKey::load(const QString& fileName, QString* errorMsg)
|
||||
*/
|
||||
QByteArray FileKey::rawKey() const
|
||||
{
|
||||
if (!m_key) {
|
||||
return {};
|
||||
}
|
||||
return QByteArray::fromRawData(m_key, SHA256_SIZE);
|
||||
return QByteArray(m_key.data(), m_key.size());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,7 +209,7 @@ void FileKey::createXMLv2(QIODevice* device, int size)
|
||||
}
|
||||
w.writeCharacters(QChar(key[i]));
|
||||
}
|
||||
sodium_memzero(key.data(), static_cast<std::size_t>(key.capacity()));
|
||||
Botan::secure_scrub_memory(key.data(), static_cast<std::size_t>(key.capacity()));
|
||||
w.writeCharacters("\n ");
|
||||
|
||||
w.writeEndElement();
|
||||
@@ -315,12 +299,12 @@ bool FileKey::loadXml(QIODevice* device, QString* errorMsg)
|
||||
while (!xmlReader.error() && xmlReader.readNextStartElement()) {
|
||||
if (xmlReader.name() == "Data") {
|
||||
keyFileData.hash = QByteArray::fromHex(xmlReader.attributes().value("Hash").toLatin1());
|
||||
QByteArray rawData = xmlReader.readElementText().simplified().replace(" ", "").toLatin1();
|
||||
keyFileData.data = xmlReader.readElementText().simplified().replace(" ", "").toLatin1();
|
||||
|
||||
if (keyFileData.version.startsWith("1.0") && Tools::isBase64(rawData)) {
|
||||
keyFileData.data = QByteArray::fromBase64(rawData);
|
||||
} else if (keyFileData.version == "2.0" && Tools::isHex(rawData)) {
|
||||
keyFileData.data = QByteArray::fromHex(rawData);
|
||||
if (keyFileData.version.startsWith("1.0") && Tools::isBase64(keyFileData.data)) {
|
||||
keyFileData.data = QByteArray::fromBase64(keyFileData.data);
|
||||
} else if (keyFileData.version == "2.0" && Tools::isHex(keyFileData.data)) {
|
||||
keyFileData.data = QByteArray::fromHex(keyFileData.data);
|
||||
|
||||
CryptoHash hash(CryptoHash::Sha256);
|
||||
hash.addData(keyFileData.data);
|
||||
@@ -337,8 +321,6 @@ bool FileKey::loadXml(QIODevice* device, QString* errorMsg)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
sodium_memzero(rawData.data(), static_cast<std::size_t>(rawData.capacity()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -346,11 +328,11 @@ bool FileKey::loadXml(QIODevice* device, QString* errorMsg)
|
||||
|
||||
bool ok = false;
|
||||
if (!xmlReader.error() && !keyFileData.data.isEmpty()) {
|
||||
std::memcpy(m_key, keyFileData.data.data(), std::min(SHA256_SIZE, keyFileData.data.size()));
|
||||
std::memcpy(m_key.data(), keyFileData.data.data(), std::min(SHA256_SIZE, keyFileData.data.size()));
|
||||
ok = true;
|
||||
}
|
||||
|
||||
sodium_memzero(keyFileData.data.data(), static_cast<std::size_t>(keyFileData.data.capacity()));
|
||||
Botan::secure_scrub_memory(keyFileData.data.data(), static_cast<std::size_t>(keyFileData.data.capacity()));
|
||||
|
||||
return ok;
|
||||
}
|
||||
@@ -368,13 +350,12 @@ bool FileKey::loadBinary(QIODevice* device)
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data;
|
||||
if (!Tools::readAllFromDevice(device, data) || data.size() != 32) {
|
||||
Botan::secure_vector<char> data(32);
|
||||
if (device->read(data.data(), 32) != 32 || !device->atEnd()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::memcpy(m_key, data.data(), std::min(SHA256_SIZE, data.size()));
|
||||
sodium_memzero(data.data(), static_cast<std::size_t>(data.capacity()));
|
||||
m_key = data;
|
||||
m_type = FixedBinary;
|
||||
return true;
|
||||
}
|
||||
@@ -401,15 +382,13 @@ bool FileKey::loadHex(QIODevice* device)
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray key = QByteArray::fromHex(data);
|
||||
sodium_memzero(data.data(), static_cast<std::size_t>(data.capacity()));
|
||||
|
||||
if (key.size() != 32) {
|
||||
data = QByteArray::fromHex(data);
|
||||
if (data.size() != 32) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::memcpy(m_key, key.data(), std::min(SHA256_SIZE, key.size()));
|
||||
sodium_memzero(key.data(), static_cast<std::size_t>(key.capacity()));
|
||||
std::memcpy(m_key.data(), data.data(), std::min(SHA256_SIZE, data.size()));
|
||||
Botan::secure_scrub_memory(data.data(), static_cast<std::size_t>(data.capacity()));
|
||||
|
||||
m_type = FixedBinaryHex;
|
||||
return true;
|
||||
@@ -433,9 +412,9 @@ bool FileKey::loadHashed(QIODevice* device)
|
||||
cryptoHash.addData(buffer);
|
||||
} while (!buffer.isEmpty());
|
||||
|
||||
auto result = cryptoHash.result();
|
||||
std::memcpy(m_key, result.data(), std::min(SHA256_SIZE, result.size()));
|
||||
sodium_memzero(result.data(), static_cast<std::size_t>(result.capacity()));
|
||||
buffer = cryptoHash.result();
|
||||
std::memcpy(m_key.data(), buffer.data(), std::min(SHA256_SIZE, buffer.size()));
|
||||
Botan::secure_scrub_memory(buffer.data(), static_cast<std::size_t>(buffer.capacity()));
|
||||
|
||||
m_type = Hashed;
|
||||
return true;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define KEEPASSX_FILEKEY_H
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
#include <botan/secmem.h>
|
||||
|
||||
#include "keys/Key.h"
|
||||
|
||||
@@ -41,7 +42,7 @@ public:
|
||||
};
|
||||
|
||||
FileKey();
|
||||
~FileKey() override;
|
||||
~FileKey() override = default;
|
||||
bool load(QIODevice* device, QString* errorMsg = nullptr);
|
||||
bool load(const QString& fileName, QString* errorMsg = nullptr);
|
||||
QByteArray rawKey() const override;
|
||||
@@ -58,7 +59,7 @@ private:
|
||||
bool loadHex(QIODevice* device);
|
||||
bool loadHashed(QIODevice* device);
|
||||
|
||||
char* m_key = nullptr;
|
||||
Botan::secure_vector<char> m_key;
|
||||
Type m_type = None;
|
||||
};
|
||||
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
#include "core/Tools.h"
|
||||
|
||||
#include "crypto/CryptoHash.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <gcrypt.h>
|
||||
|
||||
QUuid PasswordKey::UUID("77e90411-303a-43f2-b773-853b05635ead");
|
||||
|
||||
@@ -29,31 +29,23 @@ constexpr int PasswordKey::SHA256_SIZE;
|
||||
|
||||
PasswordKey::PasswordKey()
|
||||
: Key(UUID)
|
||||
, m_key(static_cast<char*>(gcry_malloc_secure(SHA256_SIZE)))
|
||||
, m_key(SHA256_SIZE)
|
||||
{
|
||||
}
|
||||
|
||||
PasswordKey::PasswordKey(const QString& password)
|
||||
: Key(UUID)
|
||||
, m_key(static_cast<char*>(gcry_malloc_secure(SHA256_SIZE)))
|
||||
, m_key(SHA256_SIZE)
|
||||
{
|
||||
setPassword(password);
|
||||
}
|
||||
|
||||
PasswordKey::~PasswordKey()
|
||||
{
|
||||
if (m_key) {
|
||||
gcry_free(m_key);
|
||||
m_key = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray PasswordKey::rawKey() const
|
||||
{
|
||||
if (!m_isInitialized) {
|
||||
return {};
|
||||
}
|
||||
return QByteArray::fromRawData(m_key, SHA256_SIZE);
|
||||
return QByteArray(m_key.data(), m_key.size());
|
||||
}
|
||||
|
||||
void PasswordKey::setPassword(const QString& password)
|
||||
@@ -64,7 +56,7 @@ void PasswordKey::setPassword(const QString& password)
|
||||
void PasswordKey::setHash(const QByteArray& hash)
|
||||
{
|
||||
Q_ASSERT(hash.size() == SHA256_SIZE);
|
||||
std::memcpy(m_key, hash.data(), std::min(SHA256_SIZE, hash.size()));
|
||||
std::memcpy(m_key.data(), hash.data(), std::min(SHA256_SIZE, hash.size()));
|
||||
m_isInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#ifndef KEEPASSX_PASSWORDKEY_H
|
||||
#define KEEPASSX_PASSWORDKEY_H
|
||||
|
||||
#include <botan/secmem.h>
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QString>
|
||||
|
||||
@@ -30,7 +32,7 @@ public:
|
||||
|
||||
PasswordKey();
|
||||
explicit PasswordKey(const QString& password);
|
||||
~PasswordKey() override;
|
||||
~PasswordKey() override = default;
|
||||
QByteArray rawKey() const override;
|
||||
void setPassword(const QString& password);
|
||||
void setHash(const QByteArray& hash);
|
||||
@@ -40,7 +42,7 @@ public:
|
||||
private:
|
||||
static constexpr int SHA256_SIZE = 32;
|
||||
|
||||
char* m_key = nullptr;
|
||||
Botan::secure_vector<char> m_key;
|
||||
bool m_isInitialized = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -31,10 +31,6 @@
|
||||
#include <QXmlStreamReader>
|
||||
#include <QtConcurrent>
|
||||
|
||||
#include <cstring>
|
||||
#include <gcrypt.h>
|
||||
#include <sodium.h>
|
||||
|
||||
QUuid YkChallengeResponseKey::UUID("e092495c-e77d-498b-84a1-05ae0d955508");
|
||||
|
||||
YkChallengeResponseKey::YkChallengeResponseKey(YubiKeySlot keySlot)
|
||||
@@ -43,37 +39,15 @@ YkChallengeResponseKey::YkChallengeResponseKey(YubiKeySlot keySlot)
|
||||
{
|
||||
}
|
||||
|
||||
YkChallengeResponseKey::~YkChallengeResponseKey()
|
||||
{
|
||||
if (m_key) {
|
||||
gcry_free(m_key);
|
||||
m_keySize = 0;
|
||||
m_key = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray YkChallengeResponseKey::rawKey() const
|
||||
{
|
||||
return QByteArray::fromRawData(m_key, static_cast<int>(m_keySize));
|
||||
}
|
||||
|
||||
bool YkChallengeResponseKey::challenge(const QByteArray& challenge)
|
||||
{
|
||||
m_error.clear();
|
||||
QByteArray key;
|
||||
auto result =
|
||||
AsyncTask::runAndWaitForFuture([&] { return YubiKey::instance()->challenge(m_keySlot, challenge, key); });
|
||||
AsyncTask::runAndWaitForFuture([&] { return YubiKey::instance()->challenge(m_keySlot, challenge, m_key); });
|
||||
|
||||
if (result == YubiKey::SUCCESS) {
|
||||
if (m_key) {
|
||||
gcry_free(m_key);
|
||||
}
|
||||
m_keySize = static_cast<std::size_t>(key.size());
|
||||
m_key = static_cast<char*>(gcry_malloc_secure(m_keySize));
|
||||
std::memcpy(m_key, key.data(), m_keySize);
|
||||
sodium_memzero(key.data(), static_cast<std::size_t>(key.capacity()));
|
||||
} else {
|
||||
if (result != YubiKey::SUCCESS) {
|
||||
// Record the error message
|
||||
m_key.clear();
|
||||
m_error = YubiKey::instance()->errorMessage();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,24 +22,17 @@
|
||||
#include "keys/ChallengeResponseKey.h"
|
||||
#include "keys/drivers/YubiKey.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class YkChallengeResponseKey : public QObject, public ChallengeResponseKey
|
||||
class YkChallengeResponseKey : public ChallengeResponseKey
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static QUuid UUID;
|
||||
|
||||
explicit YkChallengeResponseKey(YubiKeySlot keySlot = {});
|
||||
~YkChallengeResponseKey() override;
|
||||
~YkChallengeResponseKey() override = default;
|
||||
|
||||
QByteArray rawKey() const override;
|
||||
bool challenge(const QByteArray& challenge) override;
|
||||
|
||||
private:
|
||||
char* m_key = nullptr;
|
||||
std::size_t m_keySize = 0;
|
||||
YubiKeySlot m_keySlot;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "keys/YkChallengeResponseKeyCLI.h"
|
||||
#include "keys/drivers/YubiKey.h"
|
||||
|
||||
#include "core/Tools.h"
|
||||
#include "crypto/CryptoHash.h"
|
||||
#include "crypto/Random.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
QUuid YkChallengeResponseKeyCLI::UUID("e2be77c0-c810-417a-8437-32f41d00bd1d");
|
||||
|
||||
YkChallengeResponseKeyCLI::YkChallengeResponseKeyCLI(YubiKeySlot keySlot, QString interactionMessage, QTextStream& out)
|
||||
: ChallengeResponseKey(UUID)
|
||||
, m_keySlot(keySlot)
|
||||
, m_interactionMessage(interactionMessage)
|
||||
, m_out(out.device())
|
||||
{
|
||||
connect(YubiKey::instance(), SIGNAL(userInteractionRequest()), SLOT(showInteractionMessage()));
|
||||
}
|
||||
|
||||
void YkChallengeResponseKeyCLI::showInteractionMessage()
|
||||
{
|
||||
m_out << m_interactionMessage << "\n\n" << flush;
|
||||
}
|
||||
|
||||
QByteArray YkChallengeResponseKeyCLI::rawKey() const
|
||||
{
|
||||
return m_key;
|
||||
}
|
||||
|
||||
bool YkChallengeResponseKeyCLI::challenge(const QByteArray& challenge)
|
||||
{
|
||||
auto result = YubiKey::instance()->challenge(m_keySlot, challenge, m_key);
|
||||
return result == YubiKey::SUCCESS;
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSX_YK_CHALLENGERESPONSEKEYCLI_H
|
||||
#define KEEPASSX_YK_CHALLENGERESPONSEKEYCLI_H
|
||||
|
||||
#include "core/Global.h"
|
||||
#include "keys/ChallengeResponseKey.h"
|
||||
#include "keys/drivers/YubiKey.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
#include <QTextStream>
|
||||
|
||||
class YkChallengeResponseKeyCLI : public QObject, public ChallengeResponseKey
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static QUuid UUID;
|
||||
|
||||
explicit YkChallengeResponseKeyCLI(YubiKeySlot keySlot, QString interactionMessage, QTextStream& out);
|
||||
|
||||
QByteArray rawKey() const override;
|
||||
bool challenge(const QByteArray& challenge) override;
|
||||
|
||||
private slots:
|
||||
void showInteractionMessage();
|
||||
|
||||
private:
|
||||
QByteArray m_key;
|
||||
YubiKeySlot m_keySlot;
|
||||
QString m_interactionMessage;
|
||||
QTextStream m_out;
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_YK_CHALLENGERESPONSEKEYCLI_H
|
||||
@@ -265,7 +265,7 @@ bool YubiKey::testChallenge(YubiKeySlot slot, bool* wouldBlock)
|
||||
bool YubiKey::performTestChallenge(void* key, int slot, bool* wouldBlock)
|
||||
{
|
||||
auto chall = randomGen()->randomArray(1);
|
||||
QByteArray resp;
|
||||
Botan::secure_vector<char> resp;
|
||||
auto ret = performChallenge(static_cast<YK_KEY*>(key), slot, false, chall, resp);
|
||||
if (ret == SUCCESS || ret == WOULDBLOCK) {
|
||||
if (wouldBlock) {
|
||||
@@ -285,7 +285,8 @@ bool YubiKey::performTestChallenge(void* key, int slot, bool* wouldBlock)
|
||||
* @param response response output from YubiKey
|
||||
* @return challenge result
|
||||
*/
|
||||
YubiKey::ChallengeResult YubiKey::challenge(YubiKeySlot slot, const QByteArray& challenge, QByteArray& response)
|
||||
YubiKey::ChallengeResult
|
||||
YubiKey::challenge(YubiKeySlot slot, const QByteArray& challenge, Botan::secure_vector<char>& response)
|
||||
{
|
||||
m_error.clear();
|
||||
if (!m_initialized) {
|
||||
@@ -318,8 +319,11 @@ YubiKey::ChallengeResult YubiKey::challenge(YubiKeySlot slot, const QByteArray&
|
||||
return ret;
|
||||
}
|
||||
|
||||
YubiKey::ChallengeResult
|
||||
YubiKey::performChallenge(void* key, int slot, bool mayBlock, const QByteArray& challenge, QByteArray& response)
|
||||
YubiKey::ChallengeResult YubiKey::performChallenge(void* key,
|
||||
int slot,
|
||||
bool mayBlock,
|
||||
const QByteArray& challenge,
|
||||
Botan::secure_vector<char>& response)
|
||||
{
|
||||
m_error.clear();
|
||||
int yk_cmd = (slot == 1) ? SLOT_CHAL_HMAC1 : SLOT_CHAL_HMAC2;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <QMutex>
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <botan/secmem.h>
|
||||
|
||||
typedef QPair<unsigned int, int> YubiKeySlot;
|
||||
Q_DECLARE_METATYPE(YubiKeySlot);
|
||||
@@ -50,7 +51,7 @@ public:
|
||||
QList<YubiKeySlot> foundKeys();
|
||||
QString getDisplayName(YubiKeySlot slot);
|
||||
|
||||
ChallengeResult challenge(YubiKeySlot slot, const QByteArray& challenge, QByteArray& response);
|
||||
ChallengeResult challenge(YubiKeySlot slot, const QByteArray& challenge, Botan::secure_vector<char>& response);
|
||||
bool testChallenge(YubiKeySlot slot, bool* wouldBlock = nullptr);
|
||||
|
||||
QString errorMessage();
|
||||
@@ -86,8 +87,11 @@ private:
|
||||
|
||||
static YubiKey* m_instance;
|
||||
|
||||
ChallengeResult
|
||||
performChallenge(void* key, int slot, bool mayBlock, const QByteArray& challenge, QByteArray& response);
|
||||
ChallengeResult performChallenge(void* key,
|
||||
int slot,
|
||||
bool mayBlock,
|
||||
const QByteArray& challenge,
|
||||
Botan::secure_vector<char>& response);
|
||||
bool performTestChallenge(void* key, int slot, bool* wouldBlock);
|
||||
|
||||
QHash<unsigned int, QList<QPair<int, QString>>> m_foundKeys;
|
||||
|
||||
Reference in New Issue
Block a user