diff --git a/src/core/Database.cpp b/src/core/Database.cpp index db13e2499..fd9e02dd1 100644 --- a/src/core/Database.cpp +++ b/src/core/Database.cpp @@ -176,9 +176,9 @@ QByteArray Database::transformedMasterKey() const return m_data.transformedMasterKey; } -QByteArray Database::challengeMasterSeed(const QByteArray& masterSeed) const +bool Database::challengeMasterSeed(const QByteArray& masterSeed, QByteArray& result) const { - return m_data.key.challenge(masterSeed); + return m_data.key.challenge(masterSeed, result); } void Database::setCipher(const Uuid& cipher) diff --git a/src/core/Database.h b/src/core/Database.h index 607792332..e2eb0fb14 100644 --- a/src/core/Database.h +++ b/src/core/Database.h @@ -89,7 +89,7 @@ public: quint64 transformRounds() const; QByteArray transformedMasterKey() const; const CompositeKey & key() const; - QByteArray challengeMasterSeed(const QByteArray& masterSeed) const; + bool challengeMasterSeed(const QByteArray& masterSeed, QByteArray& result) const; void setCipher(const Uuid& cipher); void setCompressionAlgo(Database::CompressionAlgorithm algo); diff --git a/src/format/KeePass2Reader.cpp b/src/format/KeePass2Reader.cpp index 17e007d76..8ac983276 100644 --- a/src/format/KeePass2Reader.cpp +++ b/src/format/KeePass2Reader.cpp @@ -113,9 +113,15 @@ Database* KeePass2Reader::readDatabase(QIODevice* device, const CompositeKey& ke return nullptr; } + QByteArray challengeResult; + if (m_db->challengeMasterSeed(m_masterSeed, challengeResult) == false) { + raiseError(tr("Unable to issue challenge-response.")); + return Q_NULLPTR; + } + CryptoHash hash(CryptoHash::Sha256); hash.addData(m_masterSeed); - hash.addData(m_db->challengeMasterSeed(m_masterSeed)); + hash.addData(challengeResult); hash.addData(m_db->transformedMasterKey()); QByteArray finalKey = hash.result(); diff --git a/src/format/KeePass2Writer.cpp b/src/format/KeePass2Writer.cpp index 3a3195a0b..6c0bf2e1b 100644 --- a/src/format/KeePass2Writer.cpp +++ b/src/format/KeePass2Writer.cpp @@ -51,9 +51,15 @@ void KeePass2Writer::writeDatabase(QIODevice* device, Database* db) QByteArray startBytes = randomGen()->randomArray(32); QByteArray endOfHeader = "\r\n\r\n"; + QByteArray challengeResult; + if (db->challengeMasterSeed(masterSeed, challengeResult) == false) { + raiseError("Unable to issue challenge-response."); + return; + } + CryptoHash hash(CryptoHash::Sha256); hash.addData(masterSeed); - hash.addData(db->challengeMasterSeed(masterSeed)); + hash.addData(challengeResult); Q_ASSERT(!db->transformedMasterKey().isEmpty()); hash.addData(db->transformedMasterKey()); QByteArray finalKey = hash.result(); diff --git a/src/keys/CompositeKey.cpp b/src/keys/CompositeKey.cpp index 2270d96eb..ed64b8ef4 100644 --- a/src/keys/CompositeKey.cpp +++ b/src/keys/CompositeKey.cpp @@ -146,23 +146,27 @@ QByteArray CompositeKey::transformKeyRaw(const QByteArray& key, const QByteArray return result; } -QByteArray CompositeKey::challenge(const QByteArray& seed) const +bool CompositeKey::challenge(const QByteArray& seed, QByteArray& result) const { /* If no challenge response was requested, return nothing to * maintain backwards compatability with regular databases. */ if (m_challengeResponseKeys.length() == 0) { - return QByteArray(); + return true; } CryptoHash cryptoHash(CryptoHash::Sha256); Q_FOREACH (ChallengeResponseKey* key, m_challengeResponseKeys) { - key->challenge(seed); + /* If the device isn't present or fails, return an error */ + if (key->challenge(seed) == false) { + return false; + } cryptoHash.addData(key->rawKey()); } - return cryptoHash.result(); + result = cryptoHash.result(); + return true; } void CompositeKey::addKey(const Key& key) diff --git a/src/keys/CompositeKey.h b/src/keys/CompositeKey.h index 66ad91ad9..b5f973d20 100644 --- a/src/keys/CompositeKey.h +++ b/src/keys/CompositeKey.h @@ -37,7 +37,7 @@ public: QByteArray rawKey() const; QByteArray transform(const QByteArray& seed, quint64 rounds, bool* ok, QString* errorString) const; - QByteArray challenge(const QByteArray& seed) const; + bool challenge(const QByteArray& seed, QByteArray &result) const; void addKey(const Key& key); void addChallengeResponseKey(const ChallengeResponseKey& key);