From 7fd8154ea823fa4a4949df6b9ec2edcbe9b5c0fc Mon Sep 17 00:00:00 2001 From: Felix Geyer Date: Thu, 10 May 2012 19:33:16 +0200 Subject: [PATCH] Add support for parsing KeePass 1 keyfiles. Refs #2 --- src/format/KeePass1Reader.cpp | 58 +++++++++++++++++++++++++++++------ src/format/KeePass1Reader.h | 1 + 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/format/KeePass1Reader.cpp b/src/format/KeePass1Reader.cpp index dc968cdd0..03d7d6f84 100644 --- a/src/format/KeePass1Reader.cpp +++ b/src/format/KeePass1Reader.cpp @@ -26,6 +26,7 @@ #include "core/Entry.h" #include "core/Group.h" #include "core/Metadata.h" +#include "core/Tools.h" #include "crypto/CryptoHash.h" #include "format/KeePass1.h" #include "keys/CompositeKey.h" @@ -314,17 +315,13 @@ bool KeePass1Reader::verifyKey(SymmetricCipherStream* cipherStream) { CryptoHash contentHash(CryptoHash::Sha256); QByteArray buffer; - buffer.resize(16384); - qint64 readResult; + do { - readResult = cipherStream->read(buffer.data(), buffer.size()); - if (readResult > 0) { - if (readResult != buffer.size()) { - buffer.resize(readResult); - } - contentHash.addData(buffer); + if (!Tools::readFromDevice(cipherStream, buffer)) { + return false; } - } while (readResult == buffer.size()); + contentHash.addData(buffer); + } while (!buffer.isEmpty()); return contentHash.result() == m_contentHashHeader; } @@ -791,6 +788,49 @@ bool KeePass1Reader::isMetaStream(const Entry* entry) && entry->iconNumber() == 0; } +QByteArray KeePass1Reader::readKeyfile(QIODevice* device) +{ + if (device->size() == 0) { + return QByteArray(); + } + + if (device->size() == 32) { + QByteArray data = device->read(32); + if (data.size() != 32) { + return QByteArray(); + } + + return data; + } + + if (device->size() == 64) { + QByteArray data = device->read(64); + + if (data.size() != 64) { + return QByteArray(); + } + + if (Tools::isHex(data)) { + return QByteArray::fromHex(data); + } + else { + device->seek(0); + } + } + + CryptoHash cryptoHash(CryptoHash::Sha256); + QByteArray buffer; + + do { + if (!Tools::readFromDevice(device, buffer)) { + return QByteArray(); + } + cryptoHash.addData(buffer); + } while (!buffer.isEmpty()); + + return cryptoHash.result(); +} + QByteArray KeePass1Key::rawKey() const { diff --git a/src/format/KeePass1Reader.h b/src/format/KeePass1Reader.h index 95cb883f5..040343681 100644 --- a/src/format/KeePass1Reader.h +++ b/src/format/KeePass1Reader.h @@ -38,6 +38,7 @@ public: const QByteArray& keyfileData); Database* readDatabase(const QString& filename, const QString& password, const QByteArray& keyfileData); + static QByteArray readKeyfile(QIODevice* device); bool hasError(); QString errorString();