CLI: set decryption time on create.

Added an option to set the target decryption time on database creation
for the CLI create command. This required some refactoring, in
particular the extraction of the min, max and defaut decryption times in
the `Kdf` module. Some work was done to allow changing those constant
only in the `Kdf` module, should we ever want to change them.
This commit is contained in:
louib 2020-01-06 21:00:39 -05:00 committed by Jonathan White
parent a41c26e9cd
commit 0b6d9cb472
8 changed files with 138 additions and 24 deletions

View file

@ -30,12 +30,19 @@
#include "keys/CompositeKey.h"
#include "keys/Key.h"
const QCommandLineOption Create::DecryptionTimeOption =
QCommandLineOption(QStringList() << "t"
<< "decryption-time",
QObject::tr("Target decryption time in MS for the database."),
QObject::tr("time"));
Create::Create()
{
name = QString("create");
description = QObject::tr("Create a new database.");
positionalArguments.append({QString("database"), QObject::tr("Path of the database."), QString("")});
options.append(Command::KeyFileOption);
options.append(Create::DecryptionTimeOption);
}
/**
@ -53,14 +60,16 @@ Create::Create()
*/
int Create::execute(const QStringList& arguments)
{
QTextStream out(Utils::STDOUT, QIODevice::WriteOnly);
QTextStream err(Utils::STDERR, QIODevice::WriteOnly);
QSharedPointer<QCommandLineParser> parser = getCommandLineParser(arguments);
if (parser.isNull()) {
return EXIT_FAILURE;
}
bool quiet = parser->isSet(Command::QuietOption);
QTextStream out(quiet ? Utils::DEVNULL : Utils::STDOUT, QIODevice::WriteOnly);
QTextStream err(Utils::STDERR, QIODevice::WriteOnly);
const QStringList args = parser->positionalArguments();
const QString& databaseFilename = args.at(0);
@ -69,6 +78,23 @@ int Create::execute(const QStringList& arguments)
return EXIT_FAILURE;
}
// Validate the decryption time before asking for a password.
QString decryptionTimeValue = parser->value(Create::DecryptionTimeOption);
int decryptionTime = 0;
if (decryptionTimeValue.length() != 0) {
decryptionTime = decryptionTimeValue.toInt();
if (decryptionTime <= 0) {
err << QObject::tr("Invalid decryption time %1.").arg(decryptionTimeValue) << endl;
return EXIT_FAILURE;
}
if (decryptionTime < Kdf::MIN_ENCRYPTION_TIME || decryptionTime > Kdf::MAX_ENCRYPTION_TIME) {
err << QObject::tr("Target decryption time must be between %1 and %2.")
.arg(QString::number(Kdf::MIN_ENCRYPTION_TIME), QString::number(Kdf::MAX_ENCRYPTION_TIME))
<< endl;
return EXIT_FAILURE;
}
}
auto key = QSharedPointer<CompositeKey>::create();
auto password = Utils::getPasswordFromStdin();
@ -96,6 +122,23 @@ int Create::execute(const QStringList& arguments)
QSharedPointer<Database> db(new Database);
db->setKey(key);
if (decryptionTime != 0) {
auto kdf = db->kdf();
Q_ASSERT(kdf);
out << QObject::tr("Benchmarking key derivation function for %1ms delay.").arg(decryptionTimeValue) << endl;
int rounds = kdf->benchmark(decryptionTime);
out << QObject::tr("Setting %1 rounds for key derivation function.").arg(QString::number(rounds)) << endl;
kdf->setRounds(rounds);
bool ok = db->changeKdf(kdf);
if (!ok) {
err << QObject::tr("Error while setting database key derivation settings.") << endl;
return EXIT_FAILURE;
}
}
QString errorMessage;
if (!db->saveAs(databaseFilename, &errorMessage, true, false)) {
err << QObject::tr("Failed to save the database: %1.").arg(errorMessage) << endl;

View file

@ -28,6 +28,8 @@ public:
Create();
int execute(const QStringList& arguments) override;
static const QCommandLineOption DecryptionTimeOption;
private:
bool loadFileKey(const QString& path, QSharedPointer<FileKey>& fileKey);
};