mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-12-27 08:19:47 -05:00
113c8eb702
The CLI module was lacking unit test coverage and showed some severe coding style violations, which this patch addresses. In addition, all uses of qCritical() with untranslatble raw char* sequences were removed in favor of proper locale strings. These are written to STDERR through QTextStreams and support output redirection for testing purposes. With this change, error messages don't depend on the global Qt logging settings and targets anymore and go directly to the terminal or into a file if needed. This patch also fixes a bug discovered during unit test development, where the extract command would just dump the raw XML contents without decrypting embedded Salsa20-protected values first, making the XML export mostly useless, since passwords are scrambled. Lastly, all CLI commands received a dedicated -h/--help option.
429 lines
18 KiB
C++
429 lines
18 KiB
C++
/*
|
|
* Copyright (C) 2018 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 "TestKdbx4.h"
|
|
#include "TestGlobal.h"
|
|
|
|
#include "config-keepassx-tests.h"
|
|
#include "core/Metadata.h"
|
|
#include "format/KdbxXmlReader.h"
|
|
#include "format/KdbxXmlWriter.h"
|
|
#include "format/KeePass2.h"
|
|
#include "format/KeePass2Reader.h"
|
|
#include "format/KeePass2Writer.h"
|
|
#include "keys/FileKey.h"
|
|
#include "keys/PasswordKey.h"
|
|
#include "mock/MockChallengeResponseKey.h"
|
|
|
|
QTEST_GUILESS_MAIN(TestKdbx4)
|
|
|
|
void TestKdbx4::initTestCaseImpl()
|
|
{
|
|
m_xmlDb->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2)));
|
|
m_kdbxSourceDb->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2)));
|
|
}
|
|
|
|
Database* TestKdbx4::readXml(const QString& path, bool strictMode, bool& hasError, QString& errorString)
|
|
{
|
|
KdbxXmlReader reader(KeePass2::FILE_VERSION_4);
|
|
reader.setStrictMode(strictMode);
|
|
auto db = reader.readDatabase(path);
|
|
hasError = reader.hasError();
|
|
errorString = reader.errorString();
|
|
return db;
|
|
}
|
|
|
|
Database* TestKdbx4::readXml(QBuffer* buf, bool strictMode, bool& hasError, QString& errorString)
|
|
{
|
|
KdbxXmlReader reader(KeePass2::FILE_VERSION_4);
|
|
reader.setStrictMode(strictMode);
|
|
auto db = reader.readDatabase(buf);
|
|
hasError = reader.hasError();
|
|
errorString = reader.errorString();
|
|
return db;
|
|
}
|
|
|
|
void TestKdbx4::writeXml(QBuffer* buf, Database* db, bool& hasError, QString& errorString)
|
|
{
|
|
KdbxXmlWriter writer(KeePass2::FILE_VERSION_4);
|
|
writer.writeDatabase(buf, db);
|
|
hasError = writer.hasError();
|
|
errorString = writer.errorString();
|
|
}
|
|
|
|
void TestKdbx4::readKdbx(QIODevice* device,
|
|
QSharedPointer<const CompositeKey> key,
|
|
QScopedPointer<Database>& db,
|
|
bool& hasError,
|
|
QString& errorString)
|
|
{
|
|
KeePass2Reader reader;
|
|
db.reset(reader.readDatabase(device, key));
|
|
hasError = reader.hasError();
|
|
if (hasError) {
|
|
errorString = reader.errorString();
|
|
}
|
|
QCOMPARE(reader.version(), KeePass2::FILE_VERSION_4);
|
|
}
|
|
|
|
void TestKdbx4::readKdbx(const QString& path,
|
|
QSharedPointer<const CompositeKey> key,
|
|
QScopedPointer<Database>& db,
|
|
bool& hasError,
|
|
QString& errorString)
|
|
{
|
|
KeePass2Reader reader;
|
|
db.reset(reader.readDatabase(path, key));
|
|
hasError = reader.hasError();
|
|
if (hasError) {
|
|
errorString = reader.errorString();
|
|
}
|
|
QCOMPARE(reader.version(), KeePass2::FILE_VERSION_4);
|
|
}
|
|
|
|
void TestKdbx4::writeKdbx(QIODevice* device, Database* db, bool& hasError, QString& errorString)
|
|
{
|
|
if (db->kdf()->uuid() == KeePass2::KDF_AES_KDBX3) {
|
|
db->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2)));
|
|
}
|
|
KeePass2Writer writer;
|
|
hasError = writer.writeDatabase(device, db);
|
|
hasError = writer.hasError();
|
|
if (hasError) {
|
|
errorString = writer.errorString();
|
|
}
|
|
QCOMPARE(writer.version(), KeePass2::FILE_VERSION_4);
|
|
}
|
|
|
|
Q_DECLARE_METATYPE(QUuid)
|
|
void TestKdbx4::testFormat400()
|
|
{
|
|
QString filename = QString(KEEPASSX_TEST_DATA_DIR).append("/Format400.kdbx");
|
|
auto key = QSharedPointer<CompositeKey>::create();
|
|
key->addKey(QSharedPointer<PasswordKey>::create("t"));
|
|
KeePass2Reader reader;
|
|
QScopedPointer<Database> db(reader.readDatabase(filename, key));
|
|
QCOMPARE(reader.version(), KeePass2::FILE_VERSION_4);
|
|
QVERIFY(db.data());
|
|
QVERIFY(!reader.hasError());
|
|
|
|
QCOMPARE(db->rootGroup()->name(), QString("Format400"));
|
|
QCOMPARE(db->metadata()->name(), QString("Format400"));
|
|
QCOMPARE(db->rootGroup()->entries().size(), 1);
|
|
auto entry = db->rootGroup()->entries().at(0);
|
|
|
|
QCOMPARE(entry->title(), QString("Format400"));
|
|
QCOMPARE(entry->username(), QString("Format400"));
|
|
QCOMPARE(entry->attributes()->keys().size(), 6);
|
|
QCOMPARE(entry->attributes()->value("Format400"), QString("Format400"));
|
|
QCOMPARE(entry->attachments()->keys().size(), 1);
|
|
QCOMPARE(entry->attachments()->value("Format400"), QByteArray("Format400\n"));
|
|
}
|
|
|
|
void TestKdbx4::testFormat400Upgrade()
|
|
{
|
|
QFETCH(QUuid, kdfUuid);
|
|
QFETCH(QUuid, cipherUuid);
|
|
QFETCH(bool, addCustomData);
|
|
QFETCH(quint32, expectedVersion);
|
|
|
|
QScopedPointer<Database> sourceDb(new Database());
|
|
sourceDb->changeKdf(fastKdf(sourceDb->kdf()));
|
|
sourceDb->metadata()->setName("Wubba lubba dub dub");
|
|
QCOMPARE(sourceDb->kdf()->uuid(), KeePass2::KDF_AES_KDBX3); // default is legacy AES-KDF
|
|
|
|
auto key = QSharedPointer<CompositeKey>::create();
|
|
key->addKey(QSharedPointer<PasswordKey>::create("I am in great pain, please help me!"));
|
|
sourceDb->setKey(key, true, true);
|
|
|
|
QBuffer buffer;
|
|
buffer.open(QBuffer::ReadWrite);
|
|
|
|
// upgrade to KDBX 4 by changing KDF and Cipher
|
|
sourceDb->changeKdf(fastKdf(KeePass2::uuidToKdf(kdfUuid)));
|
|
sourceDb->setCipher(cipherUuid);
|
|
|
|
// CustomData in meta should not cause any version change
|
|
sourceDb->metadata()->customData()->set("CustomPublicData", "Hey look, I turned myself into a pickle!");
|
|
if (addCustomData) {
|
|
// this, however, should
|
|
sourceDb->rootGroup()->customData()->set("CustomGroupData",
|
|
"I just killed my family! I don't care who they were!");
|
|
}
|
|
|
|
KeePass2Writer writer;
|
|
writer.writeDatabase(&buffer, sourceDb.data());
|
|
if (writer.hasError()) {
|
|
QFAIL(qPrintable(QString("Error while writing database: %1").arg(writer.errorString())));
|
|
}
|
|
|
|
// read buffer back
|
|
buffer.seek(0);
|
|
KeePass2Reader reader;
|
|
QScopedPointer<Database> targetDb(reader.readDatabase(&buffer, key));
|
|
if (reader.hasError()) {
|
|
QFAIL(qPrintable(QString("Error while reading database: %1").arg(reader.errorString())));
|
|
}
|
|
|
|
QVERIFY(targetDb->rootGroup());
|
|
QCOMPARE(targetDb->metadata()->name(), sourceDb->metadata()->name());
|
|
|
|
QCOMPARE(reader.version(), expectedVersion);
|
|
QCOMPARE(targetDb->cipher(), cipherUuid);
|
|
QCOMPARE(*targetDb->metadata()->customData(), *sourceDb->metadata()->customData());
|
|
QCOMPARE(*targetDb->rootGroup()->customData(), *sourceDb->rootGroup()->customData());
|
|
}
|
|
|
|
// clang-format off
|
|
void TestKdbx4::testFormat400Upgrade_data()
|
|
{
|
|
QTest::addColumn<QUuid>("kdfUuid");
|
|
QTest::addColumn<QUuid>("cipherUuid");
|
|
QTest::addColumn<bool>("addCustomData");
|
|
QTest::addColumn<quint32>("expectedVersion");
|
|
|
|
auto constexpr kdbx3 = KeePass2::FILE_VERSION_3_1 & KeePass2::FILE_VERSION_CRITICAL_MASK;
|
|
auto constexpr kdbx4 = KeePass2::FILE_VERSION_4 & KeePass2::FILE_VERSION_CRITICAL_MASK;
|
|
|
|
QTest::newRow("Argon2 + AES") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_AES256 << false << kdbx4;
|
|
QTest::newRow("AES-KDF + AES") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_AES256 << false << kdbx4;
|
|
QTest::newRow("AES-KDF (legacy) + AES") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_AES256 << false << kdbx3;
|
|
QTest::newRow("Argon2 + AES + CustomData") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_AES256 << true << kdbx4;
|
|
QTest::newRow("AES-KDF + AES + CustomData") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_AES256 << true << kdbx4;
|
|
QTest::newRow("AES-KDF (legacy) + AES + CustomData") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_AES256 << true << kdbx4;
|
|
|
|
QTest::newRow("Argon2 + ChaCha20") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_CHACHA20 << false << kdbx4;
|
|
QTest::newRow("AES-KDF + ChaCha20") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_CHACHA20 << false << kdbx4;
|
|
QTest::newRow("AES-KDF (legacy) + ChaCha20") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_CHACHA20 << false << kdbx3;
|
|
QTest::newRow("Argon2 + ChaCha20 + CustomData") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_CHACHA20 << true << kdbx4;
|
|
QTest::newRow("AES-KDF + ChaCha20 + CustomData") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_CHACHA20 << true << kdbx4;
|
|
QTest::newRow("AES-KDF (legacy) + ChaCha20 + CustomData") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_CHACHA20 << true << kdbx4;
|
|
|
|
QTest::newRow("Argon2 + Twofish") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_TWOFISH << false << kdbx4;
|
|
QTest::newRow("AES-KDF + Twofish") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_TWOFISH << false << kdbx4;
|
|
QTest::newRow("AES-KDF (legacy) + Twofish") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_TWOFISH << false << kdbx3;
|
|
QTest::newRow("Argon2 + Twofish + CustomData") << KeePass2::KDF_ARGON2 << KeePass2::CIPHER_TWOFISH << true << kdbx4;
|
|
QTest::newRow("AES-KDF + Twofish + CustomData") << KeePass2::KDF_AES_KDBX4 << KeePass2::CIPHER_TWOFISH << true << kdbx4;
|
|
QTest::newRow("AES-KDF (legacy) + Twofish + CustomData") << KeePass2::KDF_AES_KDBX3 << KeePass2::CIPHER_TWOFISH << true << kdbx4;
|
|
}
|
|
// clang-format on
|
|
|
|
void TestKdbx4::testUpgradeMasterKeyIntegrity()
|
|
{
|
|
QFETCH(QString, upgradeAction);
|
|
QFETCH(quint32, expectedVersion);
|
|
|
|
// prepare composite key
|
|
auto passwordKey = QSharedPointer<PasswordKey>::create("turXpGMQiUE6CkPvWacydAKsnp4cxz");
|
|
|
|
QByteArray fileKeyBytes("Ma6hHov98FbPeyAL22XhcgmpJk8xjQ");
|
|
QBuffer fileKeyBuffer(&fileKeyBytes);
|
|
fileKeyBuffer.open(QBuffer::ReadOnly);
|
|
auto fileKey = QSharedPointer<FileKey>::create();
|
|
fileKey->load(&fileKeyBuffer);
|
|
|
|
auto crKey = QSharedPointer<MockChallengeResponseKey>::create(QByteArray("azdJnbVCFE76vV6t9RJ2DS6xvSS93k"));
|
|
|
|
auto compositeKey = QSharedPointer<CompositeKey>::create();
|
|
compositeKey->addKey(passwordKey);
|
|
compositeKey->addKey(fileKey);
|
|
compositeKey->addChallengeResponseKey(crKey);
|
|
|
|
QScopedPointer<Database> db(new Database());
|
|
db->changeKdf(fastKdf(db->kdf()));
|
|
db->setKey(compositeKey);
|
|
|
|
// upgrade the database by a specific method
|
|
if (upgradeAction == "none") {
|
|
// do nothing
|
|
} else if (upgradeAction == "meta-customdata") {
|
|
db->metadata()->customData()->set("abc", "def");
|
|
} else if (upgradeAction == "kdf-aes-kdbx3") {
|
|
db->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_AES_KDBX3)));
|
|
} else if (upgradeAction == "kdf-argon2") {
|
|
db->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_ARGON2)));
|
|
} else if (upgradeAction == "kdf-aes-kdbx4") {
|
|
db->changeKdf(fastKdf(KeePass2::uuidToKdf(KeePass2::KDF_AES_KDBX4)));
|
|
} else if (upgradeAction == "public-customdata") {
|
|
db->publicCustomData().insert("abc", "def");
|
|
} else if (upgradeAction == "rootgroup-customdata") {
|
|
db->rootGroup()->customData()->set("abc", "def");
|
|
} else if (upgradeAction == "group-customdata") {
|
|
auto group = new Group();
|
|
group->setParent(db->rootGroup());
|
|
group->setUuid(QUuid::createUuid());
|
|
group->customData()->set("abc", "def");
|
|
} else if (upgradeAction == "rootentry-customdata") {
|
|
auto entry = new Entry();
|
|
entry->setGroup(db->rootGroup());
|
|
entry->setUuid(QUuid::createUuid());
|
|
entry->customData()->set("abc", "def");
|
|
} else if (upgradeAction == "entry-customdata") {
|
|
auto group = new Group();
|
|
group->setParent(db->rootGroup());
|
|
group->setUuid(QUuid::createUuid());
|
|
auto entry = new Entry();
|
|
entry->setGroup(group);
|
|
entry->setUuid(QUuid::createUuid());
|
|
entry->customData()->set("abc", "def");
|
|
} else {
|
|
QFAIL(qPrintable(QString("Unknown action: %s").arg(upgradeAction)));
|
|
}
|
|
|
|
QBuffer buffer;
|
|
buffer.open(QBuffer::ReadWrite);
|
|
KeePass2Writer writer;
|
|
QVERIFY(writer.writeDatabase(&buffer, db.data()));
|
|
|
|
// paranoid check that we cannot decrypt the database without a key
|
|
buffer.seek(0);
|
|
KeePass2Reader reader;
|
|
QScopedPointer<Database> db2;
|
|
db2.reset(reader.readDatabase(&buffer, QSharedPointer<CompositeKey>::create()));
|
|
QVERIFY(reader.hasError());
|
|
|
|
// check that we can read back the database with the original composite key,
|
|
// i.e., no components have been lost on the way
|
|
buffer.seek(0);
|
|
db2.reset(reader.readDatabase(&buffer, compositeKey));
|
|
if (reader.hasError()) {
|
|
QFAIL(qPrintable(reader.errorString()));
|
|
}
|
|
QCOMPARE(reader.version(), expectedVersion & KeePass2::FILE_VERSION_CRITICAL_MASK);
|
|
}
|
|
|
|
void TestKdbx4::testUpgradeMasterKeyIntegrity_data()
|
|
{
|
|
QTest::addColumn<QString>("upgradeAction");
|
|
QTest::addColumn<quint32>("expectedVersion");
|
|
|
|
QTest::newRow("Upgrade: none") << QString("none") << KeePass2::FILE_VERSION_3;
|
|
QTest::newRow("Upgrade: none (meta-customdata)") << QString("meta-customdata") << KeePass2::FILE_VERSION_3;
|
|
QTest::newRow("Upgrade: none (explicit kdf-aes-kdbx3)") << QString("kdf-aes-kdbx3") << KeePass2::FILE_VERSION_3;
|
|
QTest::newRow("Upgrade (explicit): kdf-argon2") << QString("kdf-argon2") << KeePass2::FILE_VERSION_4;
|
|
QTest::newRow("Upgrade (explicit): kdf-aes-kdbx4") << QString("kdf-aes-kdbx4") << KeePass2::FILE_VERSION_4;
|
|
QTest::newRow("Upgrade (implicit): public-customdata") << QString("public-customdata") << KeePass2::FILE_VERSION_4;
|
|
QTest::newRow("Upgrade (implicit): rootgroup-customdata") << QString("rootgroup-customdata")
|
|
<< KeePass2::FILE_VERSION_4;
|
|
QTest::newRow("Upgrade (implicit): group-customdata") << QString("group-customdata") << KeePass2::FILE_VERSION_4;
|
|
QTest::newRow("Upgrade (implicit): rootentry-customdata") << QString("rootentry-customdata")
|
|
<< KeePass2::FILE_VERSION_4;
|
|
QTest::newRow("Upgrade (implicit): entry-customdata") << QString("entry-customdata") << KeePass2::FILE_VERSION_4;
|
|
}
|
|
|
|
void TestKdbx4::testCustomData()
|
|
{
|
|
Database db;
|
|
|
|
// test public custom data
|
|
QVariantMap publicCustomData;
|
|
publicCustomData.insert("CD1", 123);
|
|
publicCustomData.insert("CD2", true);
|
|
publicCustomData.insert("CD3", "abcäöü");
|
|
db.setPublicCustomData(publicCustomData);
|
|
publicCustomData.insert("CD4", QByteArray::fromHex("ababa123ff"));
|
|
db.publicCustomData().insert("CD4", publicCustomData.value("CD4"));
|
|
QCOMPARE(db.publicCustomData(), publicCustomData);
|
|
|
|
const QString customDataKey1 = "CD1";
|
|
const QString customDataKey2 = "CD2";
|
|
const QString customData1 = "abcäöü";
|
|
const QString customData2 = "Hello World";
|
|
const int dataSize = customDataKey1.toUtf8().size() + customDataKey1.toUtf8().size() + customData1.toUtf8().size()
|
|
+ customData2.toUtf8().size();
|
|
|
|
// test custom database data
|
|
db.metadata()->customData()->set(customDataKey1, customData1);
|
|
db.metadata()->customData()->set(customDataKey2, customData2);
|
|
QCOMPARE(db.metadata()->customData()->size(), 2);
|
|
QCOMPARE(db.metadata()->customData()->dataSize(), dataSize);
|
|
|
|
// test custom root group data
|
|
Group* root = db.rootGroup();
|
|
root->customData()->set(customDataKey1, customData1);
|
|
root->customData()->set(customDataKey2, customData2);
|
|
QCOMPARE(root->customData()->size(), 2);
|
|
QCOMPARE(root->customData()->dataSize(), dataSize);
|
|
|
|
// test copied custom group data
|
|
auto* group = new Group();
|
|
group->setParent(root);
|
|
group->setUuid(QUuid::createUuid());
|
|
group->customData()->copyDataFrom(root->customData());
|
|
QCOMPARE(*group->customData(), *root->customData());
|
|
|
|
// test copied custom entry data
|
|
auto* entry = new Entry();
|
|
entry->setGroup(group);
|
|
entry->setUuid(QUuid::createUuid());
|
|
entry->customData()->copyDataFrom(group->customData());
|
|
QCOMPARE(*entry->customData(), *root->customData());
|
|
|
|
// test custom data deletion
|
|
entry->customData()->set("additional item", "foobar");
|
|
QCOMPARE(entry->customData()->size(), 3);
|
|
entry->customData()->remove("additional item");
|
|
QCOMPARE(entry->customData()->size(), 2);
|
|
QCOMPARE(entry->customData()->dataSize(), dataSize);
|
|
|
|
// test custom data on cloned groups
|
|
QScopedPointer<Group> clonedGroup(group->clone());
|
|
QCOMPARE(*clonedGroup->customData(), *group->customData());
|
|
|
|
// test custom data on cloned entries
|
|
QScopedPointer<Entry> clonedEntry(entry->clone(Entry::CloneNoFlags));
|
|
QCOMPARE(*clonedEntry->customData(), *entry->customData());
|
|
|
|
QBuffer buffer;
|
|
buffer.open(QBuffer::ReadWrite);
|
|
KeePass2Writer writer;
|
|
writer.writeDatabase(&buffer, &db);
|
|
|
|
// read buffer back
|
|
buffer.seek(0);
|
|
KeePass2Reader reader;
|
|
QSharedPointer<Database> newDb(reader.readDatabase(&buffer, QSharedPointer<CompositeKey>::create()));
|
|
|
|
// test all custom data are read back successfully from KDBX
|
|
QCOMPARE(newDb->publicCustomData(), publicCustomData);
|
|
|
|
QCOMPARE(newDb->metadata()->customData()->value(customDataKey1), customData1);
|
|
QCOMPARE(newDb->metadata()->customData()->value(customDataKey2), customData2);
|
|
|
|
QCOMPARE(newDb->rootGroup()->customData()->value(customDataKey1), customData1);
|
|
QCOMPARE(newDb->rootGroup()->customData()->value(customDataKey2), customData2);
|
|
|
|
auto* newGroup = newDb->rootGroup()->children()[0];
|
|
QCOMPARE(newGroup->customData()->value(customDataKey1), customData1);
|
|
QCOMPARE(newGroup->customData()->value(customDataKey2), customData2);
|
|
|
|
auto* newEntry = newDb->rootGroup()->children()[0]->entries()[0];
|
|
QCOMPARE(newEntry->customData()->value(customDataKey1), customData1);
|
|
QCOMPARE(newEntry->customData()->value(customDataKey2), customData2);
|
|
}
|
|
|
|
QSharedPointer<Kdf> TestKdbx4::fastKdf(QSharedPointer<Kdf> kdf)
|
|
{
|
|
kdf->setRounds(1);
|
|
|
|
if (kdf->uuid() == KeePass2::KDF_ARGON2) {
|
|
kdf->processParameters({{KeePass2::KDFPARAM_ARGON2_MEMORY, 1024}, {KeePass2::KDFPARAM_ARGON2_PARALLELISM, 1}});
|
|
}
|
|
|
|
return kdf;
|
|
}
|