diff options
author | Janek Bevendorff <janek@jbev.net> | 2018-01-10 23:24:53 +0300 |
---|---|---|
committer | Jonathan White <support@dmapps.us> | 2018-01-13 22:25:00 +0300 |
commit | b04c8c2b6e45610a4c26874025668d9d2b91cf71 (patch) | |
tree | d9b524d386aecf88be05606d50aa6bb2dbbfc54f /src/format/KeePass2.cpp | |
parent | d327c169049c0b56df237e6d8b31812ba0ce9d8b (diff) |
Explicitly support AES-KDF in KDBX4 and don't convert KDBX4 files with AES-KDF back to KDBX3 when saving
Diffstat (limited to 'src/format/KeePass2.cpp')
-rw-r--r-- | src/format/KeePass2.cpp | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/src/format/KeePass2.cpp b/src/format/KeePass2.cpp index aa081e7b5..9f0832fb0 100644 --- a/src/format/KeePass2.cpp +++ b/src/format/KeePass2.cpp @@ -25,7 +25,8 @@ const Uuid KeePass2::CIPHER_AES = Uuid(QByteArray::fromHex("31c1f2e6bf714350be58 const Uuid KeePass2::CIPHER_TWOFISH = Uuid(QByteArray::fromHex("ad68f29f576f4bb9a36ad47af965346c")); const Uuid KeePass2::CIPHER_CHACHA20 = Uuid(QByteArray::fromHex("D6038A2B8B6F4CB5A524339A31DBB59A")); -const Uuid KeePass2::KDF_AES = Uuid(QByteArray::fromHex("C9D9F39A628A4460BF740D08C18A4FEA")); +const Uuid KeePass2::KDF_AES_KDBX3 = Uuid(QByteArray::fromHex("C9D9F39A628A4460BF740D08C18A4FEA")); +const Uuid KeePass2::KDF_AES_KDBX4 = Uuid(QByteArray::fromHex("7C02BB8279A74AC0927D114A00648238")); const Uuid KeePass2::KDF_ARGON2 = Uuid(QByteArray::fromHex("EF636DDF8C29444B91F7A9A403E30A0C")); const QByteArray KeePass2::INNER_STREAM_SALSA20_IV("\xE8\x30\x09\x4B\x97\x20\x5D\x2A"); @@ -43,14 +44,16 @@ const QString KeePass2::KDFPARAM_ARGON2_VERSION("V"); const QString KeePass2::KDFPARAM_ARGON2_SECRET("K"); const QString KeePass2::KDFPARAM_ARGON2_ASSOCDATA("A"); -const QList<QPair<Uuid, QString>> KeePass2::CIPHERS { - qMakePair(KeePass2::CIPHER_AES, QObject::tr("AES: 256-bit")), - qMakePair(KeePass2::CIPHER_TWOFISH, QObject::tr("Twofish: 256-bit")), - qMakePair(KeePass2::CIPHER_CHACHA20, QObject::tr("ChaCha20: 256-bit")) +const QList<QPair<Uuid, QString>> KeePass2::CIPHERS{ + qMakePair(KeePass2::CIPHER_AES, QObject::tr("AES: 256-bit")), + qMakePair(KeePass2::CIPHER_TWOFISH, QObject::tr("Twofish: 256-bit")), + qMakePair(KeePass2::CIPHER_CHACHA20, QObject::tr("ChaCha20: 256-bit")) }; -const QList<QPair<Uuid, QString>> KeePass2::KDFS { - qMakePair(KeePass2::KDF_AES, QObject::tr("AES-KDF")), - qMakePair(KeePass2::KDF_ARGON2, QObject::tr("Argon2")), + +const QList<QPair<Uuid, QString>> KeePass2::KDFS{ + qMakePair(KeePass2::KDF_ARGON2, QObject::tr("Argon2 (recommended)")), + qMakePair(KeePass2::KDF_AES_KDBX4, QObject::tr("AES-KDF (KDBX 4)")), + qMakePair(KeePass2::KDF_AES_KDBX3, QObject::tr("AES-KDF (KDBX 3.1)")) }; QByteArray KeePass2::hmacKey(QByteArray masterSeed, QByteArray transformedMasterKey) { @@ -61,6 +64,12 @@ QByteArray KeePass2::hmacKey(QByteArray masterSeed, QByteArray transformedMaster return hmacKeyHash.result(); } +/** + * Create KDF object from KDBX4+ KDF parameters. + * + * @param p variant map containing parameters + * @return initialized KDF + */ QSharedPointer<Kdf> KeePass2::kdfFromParameters(const QVariantMap &p) { QByteArray uuidBytes = p.value(KDFPARAM_UUID).toByteArray(); @@ -68,7 +77,12 @@ QSharedPointer<Kdf> KeePass2::kdfFromParameters(const QVariantMap &p) return {}; } - QSharedPointer<Kdf> kdf(uuidToKdf(Uuid(uuidBytes))); + Uuid kdfUuid(uuidBytes); + if (kdfUuid == KDF_AES_KDBX3) { + // upgrade to non-legacy AES-KDF, since KDBX3 doesn't have any KDF parameters + kdfUuid = KDF_AES_KDBX4; + } + QSharedPointer<Kdf> kdf = uuidToKdf(kdfUuid); if (kdf.isNull()) { return {}; } @@ -87,7 +101,10 @@ QVariantMap KeePass2::kdfToParameters(QSharedPointer<Kdf> kdf) QSharedPointer<Kdf> KeePass2::uuidToKdf(const Uuid& uuid) { - if (uuid == KDF_AES) { + if (uuid == KDF_AES_KDBX3) { + return QSharedPointer<AesKdf>::create(true); + } + if (uuid == KDF_AES_KDBX4) { return QSharedPointer<AesKdf>::create(); } if (uuid == KDF_ARGON2) { |