Support Twofish encrypted KeePass 1 databases.

Refs #2
This commit is contained in:
Felix Geyer 2012-05-10 21:06:33 +02:00
parent 225e5dac66
commit cf4e574c50
9 changed files with 39 additions and 5 deletions

View File

@ -38,6 +38,7 @@ SymmetricCipherBackend* SymmetricCipher::createBackend(SymmetricCipher::Algorith
{ {
switch (algo) { switch (algo) {
case SymmetricCipher::Aes256: case SymmetricCipher::Aes256:
case SymmetricCipher::Twofish:
return new SymmetricCipherGcrypt(algo, mode, direction); return new SymmetricCipherGcrypt(algo, mode, direction);
case SymmetricCipher::Salsa20: case SymmetricCipher::Salsa20:

View File

@ -29,6 +29,7 @@ public:
enum Algorithm enum Algorithm
{ {
Aes256, Aes256,
Twofish,
Salsa20 Salsa20
}; };

View File

@ -21,12 +21,11 @@
SymmetricCipherGcrypt::SymmetricCipherGcrypt(SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode, SymmetricCipherGcrypt::SymmetricCipherGcrypt(SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode,
SymmetricCipher::Direction direction) SymmetricCipher::Direction direction)
: m_algo(GCRY_CIPHER_AES256) : m_algo(gcryptAlgo(algo))
, m_mode(gcryptMode(mode)) , m_mode(gcryptMode(mode))
, m_direction(direction) , m_direction(direction)
{ {
Q_ASSERT(Crypto::initalized()); Q_ASSERT(Crypto::initalized());
Q_ASSERT(algo == SymmetricCipher::Aes256);
} }
SymmetricCipherGcrypt::~SymmetricCipherGcrypt() SymmetricCipherGcrypt::~SymmetricCipherGcrypt()
@ -34,6 +33,21 @@ SymmetricCipherGcrypt::~SymmetricCipherGcrypt()
gcry_cipher_close(m_ctx); gcry_cipher_close(m_ctx);
} }
int SymmetricCipherGcrypt::gcryptAlgo(SymmetricCipher::Algorithm algo)
{
switch (algo) {
case SymmetricCipher::Aes256:
return GCRY_CIPHER_AES256;
case SymmetricCipher::Twofish:
return GCRY_CIPHER_TWOFISH;
default:
Q_ASSERT(false);
return -1;
}
}
int SymmetricCipherGcrypt::gcryptMode(SymmetricCipher::Mode mode) int SymmetricCipherGcrypt::gcryptMode(SymmetricCipher::Mode mode)
{ {
switch (mode) { switch (mode) {

View File

@ -41,6 +41,7 @@ public:
int blockSize() const; int blockSize() const;
private: private:
static int gcryptAlgo(SymmetricCipher::Algorithm algo);
static int gcryptMode(SymmetricCipher::Mode mode); static int gcryptMode(SymmetricCipher::Mode mode);
gcry_cipher_hd_t m_ctx; gcry_cipher_hd_t m_ctx;

View File

@ -20,8 +20,6 @@
#include <QtCore/QtGlobal> #include <QtCore/QtGlobal>
#include "core/Uuid.h"
namespace KeePass1 namespace KeePass1
{ {
const quint32 SIGNATURE_1 = 0x9AA2D903; const quint32 SIGNATURE_1 = 0x9AA2D903;

View File

@ -272,7 +272,8 @@ SymmetricCipherStream* KeePass1Reader::testKeys(const QString& password, const Q
SymmetricCipher::Cbc, SymmetricCipher::Decrypt, finalKey, m_encryptionIV)); SymmetricCipher::Cbc, SymmetricCipher::Decrypt, finalKey, m_encryptionIV));
} }
else { else {
// TODO twofish cipherStream.reset(new SymmetricCipherStream(m_device, SymmetricCipher::Twofish,
SymmetricCipher::Cbc, SymmetricCipher::Decrypt, finalKey, m_encryptionIV));
} }
cipherStream->open(QIODevice::ReadOnly); cipherStream->open(QIODevice::ReadOnly);

View File

@ -179,6 +179,23 @@ void TestKeePass1Reader::testCompositeKey()
delete db; delete db;
} }
void TestKeePass1Reader::testTwofish()
{
QString name = "Twofish";
KeePass1Reader reader;
QString dbFilename = QString("%1/%2.kdb").arg(QString(KEEPASSX_TEST_DATA_DIR), name);
Database* db = reader.readDatabase(dbFilename, "masterpw", QByteArray());
QVERIFY(db);
QVERIFY(!reader.hasError());
QCOMPARE(db->rootGroup()->children().size(), 1);
QCOMPARE(db->rootGroup()->children().at(0)->name(), name);
delete db;
}
void TestKeePass1Reader::cleanupTestCase() void TestKeePass1Reader::cleanupTestCase()
{ {
delete m_db; delete m_db;

View File

@ -35,6 +35,7 @@ private Q_SLOTS:
void testFileKey(); void testFileKey();
void testFileKey_data(); void testFileKey_data();
void testCompositeKey(); void testCompositeKey();
void testTwofish();
void cleanupTestCase(); void cleanupTestCase();
private: private:

BIN
tests/data/Twofish.kdb Normal file

Binary file not shown.