Reformat code, fix minor style issues, make kdf() getter const

This commit is contained in:
Janek Bevendorff 2017-12-16 17:36:33 +01:00 committed by Jonathan White
parent d1a19a1009
commit 0d6ca0945b
No known key found for this signature in database
GPG Key ID: 440FC65F2E0C6E01
24 changed files with 324 additions and 473 deletions

View File

@ -485,7 +485,7 @@ QString Database::saveToFile(QString filePath)
}
}
Kdf* Database::kdf() {
Kdf* Database::kdf() const {
return m_data.kdf;
}

View File

@ -92,7 +92,7 @@ public:
Uuid cipher() const;
Database::CompressionAlgorithm compressionAlgo() const;
Kdf* kdf();
Kdf* kdf() const;
QByteArray transformedMasterKey() const;
const CompositeKey& key() const;
QByteArray challengeResponseKey() const;

View File

@ -28,10 +28,7 @@ public:
int hashLen;
};
CryptoHash::CryptoHash(CryptoHash::Algorithm algo)
: CryptoHash::CryptoHash(algo, false) {}
CryptoHash::CryptoHash(CryptoHash::Algorithm algo, bool hmac)
CryptoHash::CryptoHash(Algorithm algo, bool hmac)
: d_ptr(new CryptoHashPrivate())
{
Q_D(CryptoHash);
@ -86,14 +83,14 @@ void CryptoHash::addData(const QByteArray& data)
return;
}
gcry_md_write(d->ctx, data.constData(), data.size());
gcry_md_write(d->ctx, data.constData(), static_cast<size_t>(data.size()));
}
void CryptoHash::setKey(const QByteArray& data)
{
Q_D(CryptoHash);
gcry_error_t error = gcry_md_setkey(d->ctx, data.constData(), data.size());
gcry_error_t error = gcry_md_setkey(d->ctx, data.constData(), static_cast<size_t>(data.size()));
if (error) {
qWarning("Gcrypt error (setKey): %s", gcry_strerror(error));
qWarning("Gcrypt error (setKey): %s", gcry_strsource(error));
@ -112,11 +109,11 @@ QByteArray CryptoHash::result() const
{
Q_D(const CryptoHash);
const char* result = reinterpret_cast<const char*>(gcry_md_read(d->ctx, 0));
const auto* result = reinterpret_cast<const char*>(gcry_md_read(d->ctx, 0));
return QByteArray(result, d->hashLen);
}
QByteArray CryptoHash::hash(const QByteArray& data, CryptoHash::Algorithm algo)
QByteArray CryptoHash::hash(const QByteArray& data, Algorithm algo)
{
// replace with gcry_md_hash_buffer()?
CryptoHash cryptoHash(algo);
@ -124,7 +121,7 @@ QByteArray CryptoHash::hash(const QByteArray& data, CryptoHash::Algorithm algo)
return cryptoHash.result();
}
QByteArray CryptoHash::hmac(const QByteArray& data, const QByteArray& key, CryptoHash::Algorithm algo)
QByteArray CryptoHash::hmac(const QByteArray& data, const QByteArray& key, Algorithm algo)
{
// replace with gcry_md_hash_buffer()?
CryptoHash cryptoHash(algo, true);

View File

@ -31,15 +31,14 @@ public:
Sha512
};
explicit CryptoHash(CryptoHash::Algorithm algo);
explicit CryptoHash(CryptoHash::Algorithm algo, bool hmac);
explicit CryptoHash(Algorithm algo, bool hmac = false);
~CryptoHash();
void addData(const QByteArray& data);
void reset();
QByteArray result() const;
void setKey(const QByteArray& data);
static QByteArray hash(const QByteArray& data, CryptoHash::Algorithm algo);
static QByteArray hash(const QByteArray& data, Algorithm algo);
static QByteArray hmac(const QByteArray& data, const QByteArray& key, Algorithm algo);
private:

View File

@ -20,8 +20,7 @@
#include "config-keepassx.h"
#include "crypto/SymmetricCipherGcrypt.h"
SymmetricCipher::SymmetricCipher(SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode,
SymmetricCipher::Direction direction)
SymmetricCipher::SymmetricCipher(Algorithm algo, Mode mode, Direction direction)
: m_backend(createBackend(algo, mode, direction))
, m_initialized(false)
, m_algo(algo)
@ -55,14 +54,13 @@ bool SymmetricCipher::isInitalized() const
return m_initialized;
}
SymmetricCipherBackend* SymmetricCipher::createBackend(SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode,
SymmetricCipher::Direction direction)
SymmetricCipherBackend* SymmetricCipher::createBackend(Algorithm algo, Mode mode, Direction direction)
{
switch (algo) {
case SymmetricCipher::Aes256:
case SymmetricCipher::Twofish:
case SymmetricCipher::Salsa20:
case SymmetricCipher::ChaCha20:
case Aes256:
case Twofish:
case Salsa20:
case ChaCha20:
return new SymmetricCipherGcrypt(algo, mode, direction);
default:
@ -94,25 +92,25 @@ QString SymmetricCipher::errorString() const
SymmetricCipher::Algorithm SymmetricCipher::cipherToAlgorithm(Uuid cipher)
{
if (cipher == KeePass2::CIPHER_AES) {
return SymmetricCipher::Aes256;
return Aes256;
} else if (cipher == KeePass2::CIPHER_CHACHA20) {
return SymmetricCipher::ChaCha20;
return ChaCha20;
} else if (cipher == KeePass2::CIPHER_TWOFISH) {
return SymmetricCipher::Twofish;
return Twofish;
}
qWarning("SymmetricCipher::cipherToAlgorithm: invalid Uuid %s", cipher.toByteArray().toHex().data());
return InvalidAlgorithm;
}
Uuid SymmetricCipher::algorithmToCipher(SymmetricCipher::Algorithm algo)
Uuid SymmetricCipher::algorithmToCipher(Algorithm algo)
{
switch (algo) {
case SymmetricCipher::Aes256:
case Aes256:
return KeePass2::CIPHER_AES;
case SymmetricCipher::ChaCha20:
case ChaCha20:
return KeePass2::CIPHER_CHACHA20;
case SymmetricCipher::Twofish:
case Twofish:
return KeePass2::CIPHER_TWOFISH;
default:
qWarning("SymmetricCipher::algorithmToCipher: invalid algorithm %d", algo);
@ -120,12 +118,14 @@ Uuid SymmetricCipher::algorithmToCipher(SymmetricCipher::Algorithm algo)
}
}
int SymmetricCipher::algorithmIvSize(SymmetricCipher::Algorithm algo) {
int SymmetricCipher::algorithmIvSize(Algorithm algo)
{
switch (algo) {
case SymmetricCipher::ChaCha20:
case ChaCha20:
return 12;
case SymmetricCipher::Aes256:
case SymmetricCipher::Twofish:
case Aes256:
return 16;
case Twofish:
return 16;
default:
qWarning("SymmetricCipher::algorithmIvSize: invalid algorithm %d", algo);
@ -133,19 +133,21 @@ int SymmetricCipher::algorithmIvSize(SymmetricCipher::Algorithm algo) {
}
}
SymmetricCipher::Mode SymmetricCipher::algorithmMode(SymmetricCipher::Algorithm algo) {
SymmetricCipher::Mode SymmetricCipher::algorithmMode(Algorithm algo)
{
switch (algo) {
case SymmetricCipher::ChaCha20:
return SymmetricCipher::Stream;
case SymmetricCipher::Aes256:
case SymmetricCipher::Twofish:
return SymmetricCipher::Cbc;
case ChaCha20:
return Stream;
case Aes256:
case Twofish:
return Cbc;
default:
qWarning("SymmetricCipher::algorithmMode: invalid algorithm %d", algo);
return SymmetricCipher::InvalidMode;
return InvalidMode;
}
}
SymmetricCipher::Algorithm SymmetricCipher::algorithm() const {
SymmetricCipher::Algorithm SymmetricCipher::algorithm() const
{
return m_algo;
}

View File

@ -53,22 +53,25 @@ public:
Encrypt
};
SymmetricCipher(SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode,
SymmetricCipher::Direction direction);
SymmetricCipher(Algorithm algo, Mode mode, Direction direction);
~SymmetricCipher();
Q_DISABLE_COPY(SymmetricCipher)
bool init(const QByteArray& key, const QByteArray& iv);
bool isInitalized() const;
inline QByteArray process(const QByteArray& data, bool* ok) {
inline QByteArray process(const QByteArray& data, bool* ok)
{
return m_backend->process(data, ok);
}
Q_REQUIRED_RESULT inline bool processInPlace(QByteArray& data) {
Q_REQUIRED_RESULT inline bool processInPlace(QByteArray& data)
{
return m_backend->processInPlace(data);
}
Q_REQUIRED_RESULT inline bool processInPlace(QByteArray& data, quint64 rounds) {
Q_REQUIRED_RESULT inline bool processInPlace(QByteArray& data, quint64 rounds)
{
Q_ASSERT(rounds > 0);
return m_backend->processInPlace(data, rounds);
}
@ -85,14 +88,11 @@ public:
static Mode algorithmMode(Algorithm algo);
private:
static SymmetricCipherBackend* createBackend(SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode,
SymmetricCipher::Direction direction);
static SymmetricCipherBackend* createBackend(Algorithm algo, Mode mode, Direction direction);
const QScopedPointer<SymmetricCipherBackend> m_backend;
bool m_initialized;
Algorithm m_algo;
Q_DISABLE_COPY(SymmetricCipher)
};
#endif // KEEPASSX_SYMMETRICCIPHER_H

View File

@ -145,8 +145,7 @@ QByteArray SymmetricCipherGcrypt::process(const QByteArray& data, bool* ok)
if (m_direction == SymmetricCipher::Decrypt) {
error = gcry_cipher_decrypt(m_ctx, result.data(), data.size(), data.constData(), data.size());
}
else {
} else {
error = gcry_cipher_encrypt(m_ctx, result.data(), data.size(), data.constData(), data.size());
}
@ -154,7 +153,7 @@ QByteArray SymmetricCipherGcrypt::process(const QByteArray& data, bool* ok)
setErrorString(error);
*ok = false;
} else {
*ok = true;
*ok = true;
}
return result;
@ -168,8 +167,7 @@ bool SymmetricCipherGcrypt::processInPlace(QByteArray& data)
if (m_direction == SymmetricCipher::Decrypt) {
error = gcry_cipher_decrypt(m_ctx, data.data(), data.size(), nullptr, 0);
}
else {
} else {
error = gcry_cipher_encrypt(m_ctx, data.data(), data.size(), nullptr, 0);
}
@ -199,8 +197,7 @@ bool SymmetricCipherGcrypt::processInPlace(QByteArray& data, quint64 rounds)
return false;
}
}
}
else {
} else {
for (quint64 i = 0; i != rounds; ++i) {
error = gcry_cipher_encrypt(m_ctx, rawData, size, nullptr, 0);

View File

@ -23,7 +23,7 @@
#include "crypto/SymmetricCipher.h"
#include "crypto/SymmetricCipherBackend.h"
class SymmetricCipherGcrypt : public SymmetricCipherBackend
class SymmetricCipherGcrypt: public SymmetricCipherBackend
{
public:
SymmetricCipherGcrypt(SymmetricCipher::Algorithm algo, SymmetricCipher::Mode mode,

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 KeePassXC Team
* Copyright (C) 2017 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
@ -28,7 +28,7 @@ const QList<Kdf::Field> AesKdf::FIELDS = AesKdf::initFields();
QList<Kdf::Field> AesKdf::initFields()
{
return QList<Kdf::Field> {
Kdf::Field(static_cast<quint32>(Fields::ROUNDS), "Transform rounds", 1, UINT64_MAX, true),
Kdf::Field(static_cast<quint32>(Fields::ROUNDS), "Transform rounds", 1, UINT64_MAX, true),
};
}
@ -67,7 +67,8 @@ bool AesKdf::transformKeyRaw(const QByteArray& key, const QByteArray& seed, quin
*result = key;
if (!cipher.processInPlace(*result, rounds)) {
qWarning("AesKdf::transformKeyRaw: error in SymmetricCipher::processInPlace: %s", cipher.errorString().toUtf8().data());
qWarning("AesKdf::transformKeyRaw: error in SymmetricCipher::processInPlace: %s",
cipher.errorString().toUtf8().data());
return false;
}
@ -129,20 +130,20 @@ const QList<Kdf::Field> AesKdf::fields() const
quint64 AesKdf::field(quint32 id) const
{
switch (static_cast<Fields>(id)) {
case Fields::ROUNDS:
return m_rounds;
default:
return 0;
case Fields::ROUNDS:
return m_rounds;
default:
return 0;
}
}
bool AesKdf::setField(quint32 id, quint64 val)
{
switch (static_cast<Fields>(id)) {
case Fields::ROUNDS:
return setRounds(val);
default:
return false;
case Fields::ROUNDS:
return setRounds(val);
default:
return false;
}
}
@ -165,7 +166,8 @@ int AesKdf::benchmarkImpl(int msec) const
break;
}
rounds += 10000;
} while (!t.hasExpired(msec));
}
while (!t.hasExpired(msec));
return rounds;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 KeePassXC Team
* Copyright (C) 2017 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
@ -20,7 +20,7 @@
#include "Kdf.h"
class AesKdf : public Kdf
class AesKdf: public Kdf
{
public:
AesKdf();
@ -40,7 +40,7 @@ public:
bool setRounds(quint64 rounds);
bool setSeed(const QByteArray& seed);
enum class Fields : quint32
enum class Fields: quint32
{
ROUNDS,
SEED
@ -55,7 +55,10 @@ private:
quint64 m_rounds;
QByteArray m_seed;
static bool transformKeyRaw(const QByteArray& key, const QByteArray& seed, quint64 rounds, QByteArray* result) Q_REQUIRED_RESULT;
static bool transformKeyRaw(const QByteArray& key,
const QByteArray& seed,
quint64 rounds,
QByteArray* result) Q_REQUIRED_RESULT;
static QList<Kdf::Field> initFields();
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 KeePassXC Team
* Copyright (C) 2017 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
@ -23,11 +23,11 @@
#include <QtConcurrent>
Kdf::Field::Field(quint32 id, const QString& name, quint64 min, quint64 max, bool benchmark)
: m_id(id)
, m_name(name)
, m_min(min)
, m_max(max)
, m_benchmark(benchmark)
: m_id(id)
, m_name(name)
, m_min(min)
, m_max(max)
, m_benchmark(benchmark)
{
}
@ -71,8 +71,7 @@ int Kdf::benchmark(int msec) const
}
Kdf::BenchmarkThread::BenchmarkThread(int msec, const Kdf* kdf)
: m_msec(msec)
, m_kdf(kdf)
: m_msec(msec), m_kdf(kdf)
{
}
@ -81,6 +80,7 @@ int Kdf::BenchmarkThread::rounds()
return m_rounds;
}
void Kdf::BenchmarkThread::run() {
void Kdf::BenchmarkThread::run()
{
m_rounds = m_kdf->benchmarkImpl(m_msec);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 KeePassXC Team
* Copyright (C) 2017 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
@ -25,11 +25,13 @@
class Kdf
{
public:
enum class Type {
enum class Type
{
AES
};
class Field {
class Field
{
public:
Field(quint32 id, const QString& name, quint64 min, quint64 max, bool benchmark = false);
@ -48,9 +50,11 @@ public:
};
virtual ~Kdf() {}
virtual QByteArray seed() const = 0;
virtual Type type() const = 0;
virtual bool transform(const QByteArray& raw, QByteArray& result) const = 0;
virtual void randomizeTransformSalt() = 0;
virtual Type type() const = 0;
virtual Kdf* clone() const = 0;
virtual const QList<Field> fields() const = 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 KeePassXC Team
* Copyright (C) 2017 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
@ -22,9 +22,9 @@
#ifndef KEEPASSXC_KDF_P_H
#define KEEPASSXC_KDF_P_H
class Kdf::BenchmarkThread : public QThread
class Kdf::BenchmarkThread: public QThread
{
Q_OBJECT
Q_OBJECT
public:
explicit BenchmarkThread(int msec, const Kdf* kdf);

View File

@ -71,18 +71,17 @@ Database* Kdbx3Reader::readDatabase(QIODevice* device, const CompositeKey& key,
quint32 signature2 = Endian::readSizedInt<quint32>(m_headerStream, KeePass2::BYTEORDER, &ok);
if (ok && signature2 == KeePass1::SIGNATURE_2) {
raiseError(tr("The selected file is an old KeePass 1 database (.kdb).\n\n"
"You can import it by clicking on Database > 'Import KeePass 1 database...'.\n"
"This is a one-way migration. You won't be able to open the imported "
"database with the old KeePassX 0.4 version."));
"You can import it by clicking on Database > 'Import KeePass 1 database...'.\n"
"This is a one-way migration. You won't be able to open the imported "
"database with the old KeePassX 0.4 version."));
return nullptr;
}
else if (!ok || signature2 != KeePass2::SIGNATURE_2) {
} else if (!ok || signature2 != KeePass2::SIGNATURE_2) {
raiseError(tr("Not a KeePass database."));
return nullptr;
}
quint32 version = Endian::readSizedInt<quint32>(m_headerStream, KeePass2::BYTEORDER, &ok)
& KeePass2::FILE_VERSION_CRITICAL_MASK;
& KeePass2::FILE_VERSION_CRITICAL_MASK;
quint32 maxVersion = KeePass2::FILE_VERSION & KeePass2::FILE_VERSION_CRITICAL_MASK;
if (!ok || (version < KeePass2::FILE_VERSION_MIN) || (version > maxVersion)) {
raiseError(tr("Unsupported KeePass KDBX 2 or 3 database version."));
@ -100,8 +99,8 @@ Database* Kdbx3Reader::readDatabase(QIODevice* device, const CompositeKey& key,
// check if all required headers were present
if (m_masterSeed.isEmpty() || m_encryptionIV.isEmpty()
|| m_streamStartBytes.isEmpty() || m_protectedStreamKey.isEmpty()
|| m_db->cipher().isNull()) {
|| m_streamStartBytes.isEmpty() || m_protectedStreamKey.isEmpty()
|| m_db->cipher().isNull()) {
raiseError("missing database headers");
return nullptr;
}
@ -152,8 +151,7 @@ Database* Kdbx3Reader::readDatabase(QIODevice* device, const CompositeKey& key,
if (m_db->compressionAlgo() == Database::CompressionNone) {
xmlDevice = &hashedStream;
}
else {
} else {
ioCompressor.reset(new QtIOCompressor(&hashedStream));
ioCompressor->setStreamFormat(QtIOCompressor::GzipFormat);
if (!ioCompressor->open(QIODevice::ReadOnly)) {
@ -185,8 +183,7 @@ Database* Kdbx3Reader::readDatabase(QIODevice* device, const CompositeKey& key,
raiseError(xmlReader.errorString());
if (keepDatabase) {
return db.take();
}
else {
} else {
return nullptr;
}
}
@ -297,14 +294,12 @@ void Kdbx3Reader::setCompressionFlags(const QByteArray& data)
{
if (data.size() != 4) {
raiseError("Invalid compression flags length");
}
else {
} else {
quint32 id = Endian::bytesToSizedInt<quint32>(data, KeePass2::BYTEORDER);
if (id > Database::CompressionAlgorithmMax) {
raiseError("Unsupported compression algorithm");
}
else {
} else {
m_db->setCompressionAlgo(static_cast<Database::CompressionAlgorithm>(id));
}
}
@ -314,8 +309,7 @@ void Kdbx3Reader::setMasterSeed(const QByteArray& data)
{
if (data.size() != 32) {
raiseError("Invalid master seed size");
}
else {
} else {
m_masterSeed = data;
}
}
@ -324,8 +318,7 @@ void Kdbx3Reader::setTransformSeed(const QByteArray& data)
{
if (data.size() != 32) {
raiseError("Invalid transform seed size");
}
else {
} else {
AesKdf* aesKdf;
if (m_db->kdf()->type() == Kdf::Type::AES) {
aesKdf = static_cast<AesKdf*>(m_db->kdf());
@ -342,8 +335,7 @@ void Kdbx3Reader::setTransformRounds(const QByteArray& data)
{
if (data.size() != 8) {
raiseError("Invalid transform rounds size");
}
else {
} else {
quint64 rounds = Endian::bytesToSizedInt<quint64>(data, KeePass2::BYTEORDER);
AesKdf* aesKdf;
@ -352,10 +344,10 @@ void Kdbx3Reader::setTransformRounds(const QByteArray& data)
} else {
aesKdf = new AesKdf();
m_db->setKdf(aesKdf);
}
}
aesKdf->setRounds(rounds);
}
}
}
void Kdbx3Reader::setEncryptionIV(const QByteArray& data)
@ -372,8 +364,7 @@ void Kdbx3Reader::setStreamStartBytes(const QByteArray& data)
{
if (data.size() != 32) {
raiseError("Invalid start bytes size");
}
else {
} else {
m_streamStartBytes = data;
}
}

View File

@ -26,9 +26,9 @@
class Database;
class QIODevice;
class Kdbx3Reader : public BaseKeePass2Reader
class Kdbx3Reader: public BaseKeePass2Reader
{
Q_DECLARE_TR_FUNCTIONS(Kdbx3Reader)
Q_DECLARE_TR_FUNCTIONS(Kdbx3Reader)
public:
Kdbx3Reader();

View File

@ -78,20 +78,20 @@ bool Kdbx3Writer::writeDatabase(QIODevice* device, Database* db)
CHECK_RETURN_FALSE(writeHeaderField(KeePass2::CipherID, db->cipher().toByteArray()));
CHECK_RETURN_FALSE(writeHeaderField(KeePass2::CompressionFlags,
Endian::sizedIntToBytes<qint32>(db->compressionAlgo(),
KeePass2::BYTEORDER)));
Endian::sizedIntToBytes<qint32>(db->compressionAlgo(),
KeePass2::BYTEORDER)));
AesKdf* kdf = static_cast<AesKdf*>(db->kdf());
CHECK_RETURN_FALSE(writeHeaderField(KeePass2::MasterSeed, masterSeed));
CHECK_RETURN_FALSE(writeHeaderField(KeePass2::TransformSeed, kdf->seed()));
CHECK_RETURN_FALSE(writeHeaderField(KeePass2::TransformRounds,
Endian::sizedIntToBytes<qint64>(kdf->rounds(),
KeePass2::BYTEORDER)));
Endian::sizedIntToBytes<qint64>(kdf->rounds(),
KeePass2::BYTEORDER)));
CHECK_RETURN_FALSE(writeHeaderField(KeePass2::EncryptionIV, encryptionIV));
CHECK_RETURN_FALSE(writeHeaderField(KeePass2::ProtectedStreamKey, protectedStreamKey));
CHECK_RETURN_FALSE(writeHeaderField(KeePass2::StreamStartBytes, startBytes));
CHECK_RETURN_FALSE(writeHeaderField(KeePass2::InnerRandomStreamID,
Endian::sizedIntToBytes<qint32>(KeePass2::Salsa20,
KeePass2::BYTEORDER)));
Endian::sizedIntToBytes<qint32>(KeePass2::Salsa20,
KeePass2::BYTEORDER)));
CHECK_RETURN_FALSE(writeHeaderField(KeePass2::EndOfHeader, endOfHeader));
header.close();
@ -120,8 +120,7 @@ bool Kdbx3Writer::writeDatabase(QIODevice* device, Database* db)
if (db->compressionAlgo() == Database::CompressionNone) {
m_device = &hashedStream;
}
else {
} else {
ioCompressor.reset(new QtIOCompressor(&hashedStream));
ioCompressor->setStreamFormat(QtIOCompressor::GzipFormat);
if (!ioCompressor->open(QIODevice::WriteOnly)) {
@ -166,8 +165,7 @@ bool Kdbx3Writer::writeData(const QByteArray& data)
if (m_device->write(data) != data.size()) {
raiseError(m_device->errorString());
return false;
}
else {
} else {
return true;
}
}
@ -180,7 +178,7 @@ bool Kdbx3Writer::writeHeaderField(KeePass2::HeaderFieldID fieldId, const QByteA
fieldIdArr[0] = fieldId;
CHECK_RETURN_FALSE(writeData(fieldIdArr));
CHECK_RETURN_FALSE(writeData(Endian::sizedIntToBytes<qint16>(static_cast<quint16>(data.size()),
KeePass2::BYTEORDER)));
KeePass2::BYTEORDER)));
CHECK_RETURN_FALSE(writeData(data));
return true;

View File

@ -27,9 +27,9 @@
class Database;
class QIODevice;
class Kdbx3Writer : public BaseKeePass2Writer
class Kdbx3Writer: public BaseKeePass2Writer
{
Q_DECLARE_TR_FUNCTIONS(Kdbx3Writer)
Q_DECLARE_TR_FUNCTIONS(Kdbx3Writer)
public:
Kdbx3Writer();

View File

@ -150,14 +150,12 @@ QString Kdbx3XmlReader::errorString()
{
if (m_error) {
return m_errorStr;
}
else if (m_xml.hasError()) {
} else if (m_xml.hasError()) {
return QString("XML error:\n%1\nLine %2, column %3")
.arg(m_xml.errorString())
.arg(m_xml.lineNumber())
.arg(m_xml.columnNumber());
}
else {
.arg(m_xml.errorString())
.arg(m_xml.lineNumber())
.arg(m_xml.columnNumber());
} else {
return QString();
}
}
@ -183,18 +181,15 @@ bool Kdbx3XmlReader::parseKeePassFile()
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Meta") {
parseMeta();
}
else if (m_xml.name() == "Root") {
} else if (m_xml.name() == "Root") {
if (rootElementFound) {
rootParsedSuccessfully = false;
raiseError("Multiple root elements");
}
else {
} else {
rootParsedSuccessfully = parseRoot();
rootElementFound = true;
}
}
else {
} else {
skipCurrentElement();
}
}
@ -209,95 +204,67 @@ void Kdbx3XmlReader::parseMeta()
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Generator") {
m_meta->setGenerator(readString());
}
else if (m_xml.name() == "HeaderHash") {
} else if (m_xml.name() == "HeaderHash") {
m_headerHash = readBinary();
}
else if (m_xml.name() == "DatabaseName") {
} else if (m_xml.name() == "DatabaseName") {
m_meta->setName(readString());
}
else if (m_xml.name() == "DatabaseNameChanged") {
} else if (m_xml.name() == "DatabaseNameChanged") {
m_meta->setNameChanged(readDateTime());
}
else if (m_xml.name() == "DatabaseDescription") {
} else if (m_xml.name() == "DatabaseDescription") {
m_meta->setDescription(readString());
}
else if (m_xml.name() == "DatabaseDescriptionChanged") {
} else if (m_xml.name() == "DatabaseDescriptionChanged") {
m_meta->setDescriptionChanged(readDateTime());
}
else if (m_xml.name() == "DefaultUserName") {
} else if (m_xml.name() == "DefaultUserName") {
m_meta->setDefaultUserName(readString());
}
else if (m_xml.name() == "DefaultUserNameChanged") {
} else if (m_xml.name() == "DefaultUserNameChanged") {
m_meta->setDefaultUserNameChanged(readDateTime());
}
else if (m_xml.name() == "MaintenanceHistoryDays") {
} else if (m_xml.name() == "MaintenanceHistoryDays") {
m_meta->setMaintenanceHistoryDays(readNumber());
}
else if (m_xml.name() == "Color") {
} else if (m_xml.name() == "Color") {
m_meta->setColor(readColor());
}
else if (m_xml.name() == "MasterKeyChanged") {
} else if (m_xml.name() == "MasterKeyChanged") {
m_meta->setMasterKeyChanged(readDateTime());
}
else if (m_xml.name() == "MasterKeyChangeRec") {
} else if (m_xml.name() == "MasterKeyChangeRec") {
m_meta->setMasterKeyChangeRec(readNumber());
}
else if (m_xml.name() == "MasterKeyChangeForce") {
} else if (m_xml.name() == "MasterKeyChangeForce") {
m_meta->setMasterKeyChangeForce(readNumber());
}
else if (m_xml.name() == "MemoryProtection") {
} else if (m_xml.name() == "MemoryProtection") {
parseMemoryProtection();
}
else if (m_xml.name() == "CustomIcons") {
} else if (m_xml.name() == "CustomIcons") {
parseCustomIcons();
}
else if (m_xml.name() == "RecycleBinEnabled") {
} else if (m_xml.name() == "RecycleBinEnabled") {
m_meta->setRecycleBinEnabled(readBool());
}
else if (m_xml.name() == "RecycleBinUUID") {
} else if (m_xml.name() == "RecycleBinUUID") {
m_meta->setRecycleBin(getGroup(readUuid()));
}
else if (m_xml.name() == "RecycleBinChanged") {
} else if (m_xml.name() == "RecycleBinChanged") {
m_meta->setRecycleBinChanged(readDateTime());
}
else if (m_xml.name() == "EntryTemplatesGroup") {
} else if (m_xml.name() == "EntryTemplatesGroup") {
m_meta->setEntryTemplatesGroup(getGroup(readUuid()));
}
else if (m_xml.name() == "EntryTemplatesGroupChanged") {
} else if (m_xml.name() == "EntryTemplatesGroupChanged") {
m_meta->setEntryTemplatesGroupChanged(readDateTime());
}
else if (m_xml.name() == "LastSelectedGroup") {
} else if (m_xml.name() == "LastSelectedGroup") {
m_meta->setLastSelectedGroup(getGroup(readUuid()));
}
else if (m_xml.name() == "LastTopVisibleGroup") {
} else if (m_xml.name() == "LastTopVisibleGroup") {
m_meta->setLastTopVisibleGroup(getGroup(readUuid()));
}
else if (m_xml.name() == "HistoryMaxItems") {
} else if (m_xml.name() == "HistoryMaxItems") {
int value = readNumber();
if (value >= -1) {
m_meta->setHistoryMaxItems(value);
}
else {
} else {
raiseError("HistoryMaxItems invalid number");
}
}
else if (m_xml.name() == "HistoryMaxSize") {
} else if (m_xml.name() == "HistoryMaxSize") {
int value = readNumber();
if (value >= -1) {
m_meta->setHistoryMaxSize(value);
}
else {
} else {
raiseError("HistoryMaxSize invalid number");
}
}
else if (m_xml.name() == "Binaries") {
} else if (m_xml.name() == "Binaries") {
parseBinaries();
}
else if (m_xml.name() == "CustomData") {
} else if (m_xml.name() == "CustomData") {
parseCustomData();
}
else {
} else {
skipCurrentElement();
}
}
@ -310,20 +277,15 @@ void Kdbx3XmlReader::parseMemoryProtection()
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "ProtectTitle") {
m_meta->setProtectTitle(readBool());
}
else if (m_xml.name() == "ProtectUserName") {
} else if (m_xml.name() == "ProtectUserName") {
m_meta->setProtectUsername(readBool());
}
else if (m_xml.name() == "ProtectPassword") {
} else if (m_xml.name() == "ProtectPassword") {
m_meta->setProtectPassword(readBool());
}
else if (m_xml.name() == "ProtectURL") {
} else if (m_xml.name() == "ProtectURL") {
m_meta->setProtectUrl(readBool());
}
else if (m_xml.name() == "ProtectNotes") {
} else if (m_xml.name() == "ProtectNotes") {
m_meta->setProtectNotes(readBool());
}
else {
} else {
skipCurrentElement();
}
}
@ -336,8 +298,7 @@ void Kdbx3XmlReader::parseCustomIcons()
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Icon") {
parseIcon();
}
else {
} else {
skipCurrentElement();
}
}
@ -356,20 +317,17 @@ void Kdbx3XmlReader::parseIcon()
if (m_xml.name() == "UUID") {
uuid = readUuid();
uuidSet = !uuid.isNull();
}
else if (m_xml.name() == "Data") {
} else if (m_xml.name() == "Data") {
icon.loadFromData(readBinary());
iconSet = true;
}
else {
} else {
skipCurrentElement();
}
}
if (uuidSet && iconSet) {
m_meta->addCustomIcon(uuid, icon);
}
else {
} else {
raiseError("Missing icon uuid or data");
}
}
@ -387,8 +345,7 @@ void Kdbx3XmlReader::parseBinaries()
QByteArray data;
if (attr.value("Compressed").compare(QLatin1String("True"), Qt::CaseInsensitive) == 0) {
data = readCompressedBinary();
}
else {
} else {
data = readBinary();
}
@ -398,8 +355,7 @@ void Kdbx3XmlReader::parseBinaries()
}
m_binaryPool.insert(id, data);
}
else {
} else {
skipCurrentElement();
}
}
@ -412,8 +368,7 @@ void Kdbx3XmlReader::parseCustomData()
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Item") {
parseCustomDataItem();
}
else {
} else {
skipCurrentElement();
}
}
@ -432,20 +387,17 @@ void Kdbx3XmlReader::parseCustomDataItem()
if (m_xml.name() == "Key") {
key = readString();
keySet = true;
}
else if (m_xml.name() == "Value") {
} else if (m_xml.name() == "Value") {
value = readString();
valueSet = true;
}
else {
} else {
skipCurrentElement();
}
}
if (keySet && valueSet) {
m_meta->addCustomField(key, value);
}
else {
} else {
raiseError("Missing custom data key or value");
}
}
@ -474,11 +426,9 @@ bool Kdbx3XmlReader::parseRoot()
}
groupElementFound = true;
}
else if (m_xml.name() == "DeletedObjects") {
} else if (m_xml.name() == "DeletedObjects") {
parseDeletedObjects();
}
else {
} else {
skipCurrentElement();
}
}
@ -500,99 +450,77 @@ Group* Kdbx3XmlReader::parseGroup()
if (uuid.isNull()) {
if (m_strictMode) {
raiseError("Null group uuid");
}
else {
} else {
group->setUuid(Uuid::random());
}
}
else {
} else {
group->setUuid(uuid);
}
}
else if (m_xml.name() == "Name") {
} else if (m_xml.name() == "Name") {
group->setName(readString());
}
else if (m_xml.name() == "Notes") {
} else if (m_xml.name() == "Notes") {
group->setNotes(readString());
}
else if (m_xml.name() == "IconID") {
} else if (m_xml.name() == "IconID") {
int iconId = readNumber();
if (iconId < 0) {
if (m_strictMode) {
raiseError("Invalid group icon number");
}
iconId = 0;
}
else {
} else {
if (iconId >= DatabaseIcons::IconCount) {
qWarning("Kdbx3XmlReader::parseGroup: icon id \"%d\" not supported", iconId);
}
group->setIcon(iconId);
}
}
else if (m_xml.name() == "CustomIconUUID") {
} else if (m_xml.name() == "CustomIconUUID") {
Uuid uuid = readUuid();
if (!uuid.isNull()) {
group->setIcon(uuid);
}
}
else if (m_xml.name() == "Times") {
} else if (m_xml.name() == "Times") {
group->setTimeInfo(parseTimes());
}
else if (m_xml.name() == "IsExpanded") {
} else if (m_xml.name() == "IsExpanded") {
group->setExpanded(readBool());
}
else if (m_xml.name() == "DefaultAutoTypeSequence") {
} else if (m_xml.name() == "DefaultAutoTypeSequence") {
group->setDefaultAutoTypeSequence(readString());
}
else if (m_xml.name() == "EnableAutoType") {
} else if (m_xml.name() == "EnableAutoType") {
QString str = readString();
if (str.compare("null", Qt::CaseInsensitive) == 0) {
group->setAutoTypeEnabled(Group::Inherit);
}
else if (str.compare("true", Qt::CaseInsensitive) == 0) {
} else if (str.compare("true", Qt::CaseInsensitive) == 0) {
group->setAutoTypeEnabled(Group::Enable);
}
else if (str.compare("false", Qt::CaseInsensitive) == 0) {
} else if (str.compare("false", Qt::CaseInsensitive) == 0) {
group->setAutoTypeEnabled(Group::Disable);
}
else {
} else {
raiseError("Invalid EnableAutoType value");
}
}
else if (m_xml.name() == "EnableSearching") {
} else if (m_xml.name() == "EnableSearching") {
QString str = readString();
if (str.compare("null", Qt::CaseInsensitive) == 0) {
group->setSearchingEnabled(Group::Inherit);
}
else if (str.compare("true", Qt::CaseInsensitive) == 0) {
} else if (str.compare("true", Qt::CaseInsensitive) == 0) {
group->setSearchingEnabled(Group::Enable);
}
else if (str.compare("false", Qt::CaseInsensitive) == 0) {
} else if (str.compare("false", Qt::CaseInsensitive) == 0) {
group->setSearchingEnabled(Group::Disable);
}
else {
} else {
raiseError("Invalid EnableSearching value");
}
}
else if (m_xml.name() == "LastTopVisibleEntry") {
} else if (m_xml.name() == "LastTopVisibleEntry") {
group->setLastTopVisibleEntry(getEntry(readUuid()));
}
else if (m_xml.name() == "Group") {
} else if (m_xml.name() == "Group") {
Group* newGroup = parseGroup();
if (newGroup) {
children.append(newGroup);
}
}
else if (m_xml.name() == "Entry") {
} else if (m_xml.name() == "Entry") {
Entry* newEntry = parseEntry(false);
if (newEntry) {
entries.append(newEntry);
}
}
else {
} else {
skipCurrentElement();
}
}
@ -607,8 +535,7 @@ Group* Kdbx3XmlReader::parseGroup()
group->copyDataFrom(tmpGroup);
group->setUpdateTimeinfo(false);
delete tmpGroup;
}
else if (!hasError()) {
} else if (!hasError()) {
raiseError("No group uuid found");
}
@ -630,8 +557,7 @@ void Kdbx3XmlReader::parseDeletedObjects()
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "DeletedObject") {
parseDeletedObject();
}
else {
} else {
skipCurrentElement();
}
}
@ -650,23 +576,19 @@ void Kdbx3XmlReader::parseDeletedObject()
if (m_strictMode) {
raiseError("Null DeleteObject uuid");
}
}
else {
} else {
delObj.uuid = uuid;
}
}
else if (m_xml.name() == "DeletionTime") {
} else if (m_xml.name() == "DeletionTime") {
delObj.deletionTime = readDateTime();
}
else {
} else {
skipCurrentElement();
}
}
if (!delObj.uuid.isNull() && !delObj.deletionTime.isNull()) {
m_db->addDeletedObject(delObj);
}
else if (m_strictMode) {
} else if (m_strictMode) {
raiseError("Missing DeletedObject uuid or time");
}
}
@ -686,69 +608,53 @@ Entry* Kdbx3XmlReader::parseEntry(bool history)
if (uuid.isNull()) {
if (m_strictMode) {
raiseError("Null entry uuid");
}
else {
} else {
entry->setUuid(Uuid::random());
}
}
else {
} else {
entry->setUuid(uuid);
}
}
else if (m_xml.name() == "IconID") {
} else if (m_xml.name() == "IconID") {
int iconId = readNumber();
if (iconId < 0) {
if (m_strictMode) {
raiseError("Invalid entry icon number");
}
iconId = 0;
}
else {
} else {
entry->setIcon(iconId);
}
}
else if (m_xml.name() == "CustomIconUUID") {
} else if (m_xml.name() == "CustomIconUUID") {
Uuid uuid = readUuid();
if (!uuid.isNull()) {
entry->setIcon(uuid);
}
}
else if (m_xml.name() == "ForegroundColor") {
} else if (m_xml.name() == "ForegroundColor") {
entry->setForegroundColor(readColor());
}
else if (m_xml.name() == "BackgroundColor") {
} else if (m_xml.name() == "BackgroundColor") {
entry->setBackgroundColor(readColor());
}
else if (m_xml.name() == "OverrideURL") {
} else if (m_xml.name() == "OverrideURL") {
entry->setOverrideUrl(readString());
}
else if (m_xml.name() == "Tags") {
} else if (m_xml.name() == "Tags") {
entry->setTags(readString());
}
else if (m_xml.name() == "Times") {
} else if (m_xml.name() == "Times") {
entry->setTimeInfo(parseTimes());
}
else if (m_xml.name() == "String") {
} else if (m_xml.name() == "String") {
parseEntryString(entry);
}
else if (m_xml.name() == "Binary") {
} else if (m_xml.name() == "Binary") {
QPair<QString, QString> ref = parseEntryBinary(entry);
if (!ref.first.isNull() && !ref.second.isNull()) {
binaryRefs.append(ref);
}
}
else if (m_xml.name() == "AutoType") {
} else if (m_xml.name() == "AutoType") {
parseAutoType(entry);
}
else if (m_xml.name() == "History") {
} else if (m_xml.name() == "History") {
if (history) {
raiseError("History element in history entry");
}
else {
} else {
historyItems = parseEntryHistory();
}
}
else {
} else {
skipCurrentElement();
}
}
@ -760,8 +666,7 @@ Entry* Kdbx3XmlReader::parseEntry(bool history)
if (!entry->uuid().isNull()) {
if (history) {
entry->setUpdateTimeinfo(false);
}
else {
} else {
Entry* tmpEntry = entry;
entry = getEntry(tmpEntry->uuid());
@ -770,8 +675,7 @@ Entry* Kdbx3XmlReader::parseEntry(bool history)
delete tmpEntry;
}
}
else if (!hasError()) {
} else if (!hasError()) {
raiseError("No entry uuid found");
}
@ -807,8 +711,7 @@ void Kdbx3XmlReader::parseEntryString(Entry* entry)
if (m_xml.name() == "Key") {
key = readString();
keySet = true;
}
else if (m_xml.name() == "Value") {
} else if (m_xml.name() == "Value") {
QXmlStreamAttributes attr = m_xml.attributes();
value = readString();
@ -823,20 +726,17 @@ void Kdbx3XmlReader::parseEntryString(Entry* entry)
if (!ok) {
value.clear();
raiseError(m_randomStream->errorString());
}
else {
} else {
value = QString::fromUtf8(plaintext);
}
}
else {
} else {
raiseError("Unable to decrypt entry string");
}
}
protect = isProtected || protectInMemory;
valueSet = true;
}
else {
} else {
skipCurrentElement();
}
}
@ -845,12 +745,10 @@ void Kdbx3XmlReader::parseEntryString(Entry* entry)
// the default attributes are always there so additionally check if it's empty
if (entry->attributes()->hasKey(key) && !entry->attributes()->value(key).isEmpty()) {
raiseError("Duplicate custom attribute found");
}
else {
} else {
entry->attributes()->set(key, value, protect);
}
}
else {
} else {
raiseError("Entry string key or value missing");
}
}
@ -870,19 +768,17 @@ QPair<QString, QString> Kdbx3XmlReader::parseEntryBinary(Entry* entry)
if (m_xml.name() == "Key") {
key = readString();
keySet = true;
}
else if (m_xml.name() == "Value") {
} else if (m_xml.name() == "Value") {
QXmlStreamAttributes attr = m_xml.attributes();
if (attr.hasAttribute("Ref")) {
poolRef = qMakePair(attr.value("Ref").toString(), key);
m_xml.skipCurrentElement();
}
else {
} else {
// format compatibility
value = readBinary();
bool isProtected = attr.hasAttribute("Protected")
&& (attr.value("Protected") == "True");
&& (attr.value("Protected") == "True");
if (isProtected && !value.isEmpty()) {
if (!m_randomStream->processInPlace(value)) {
@ -892,8 +788,7 @@ QPair<QString, QString> Kdbx3XmlReader::parseEntryBinary(Entry* entry)
}
valueSet = true;
}
else {
} else {
skipCurrentElement();
}
}
@ -901,12 +796,10 @@ QPair<QString, QString> Kdbx3XmlReader::parseEntryBinary(Entry* entry)
if (keySet && valueSet) {
if (entry->attachments()->hasKey(key)) {
raiseError("Duplicate attachment found");
}
else {
} else {
entry->attachments()->set(key, value);
}
}
else {
} else {
raiseError("Entry binary key or value missing");
}
@ -920,17 +813,13 @@ void Kdbx3XmlReader::parseAutoType(Entry* entry)
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Enabled") {
entry->setAutoTypeEnabled(readBool());
}
else if (m_xml.name() == "DataTransferObfuscation") {
} else if (m_xml.name() == "DataTransferObfuscation") {
entry->setAutoTypeObfuscation(readNumber());
}
else if (m_xml.name() == "DefaultSequence") {
} else if (m_xml.name() == "DefaultSequence") {
entry->setDefaultAutoTypeSequence(readString());
}
else if (m_xml.name() == "Association") {
} else if (m_xml.name() == "Association") {
parseAutoTypeAssoc(entry);
}
else {
} else {
skipCurrentElement();
}
}
@ -948,20 +837,17 @@ void Kdbx3XmlReader::parseAutoTypeAssoc(Entry* entry)
if (m_xml.name() == "Window") {
assoc.window = readString();
windowSet = true;
}
else if (m_xml.name() == "KeystrokeSequence") {
} else if (m_xml.name() == "KeystrokeSequence") {
assoc.sequence = readString();
sequenceSet = true;
}
else {
} else {
skipCurrentElement();
}
}
if (windowSet && sequenceSet) {
entry->autoTypeAssociations()->add(assoc);
}
else {
} else {
raiseError("Auto-type association window or sequence missing");
}
}
@ -975,8 +861,7 @@ QList<Entry*> Kdbx3XmlReader::parseEntryHistory()
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Entry") {
historyItems.append(parseEntry(true));
}
else {
} else {
skipCurrentElement();
}
}
@ -992,26 +877,19 @@ TimeInfo Kdbx3XmlReader::parseTimes()
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "LastModificationTime") {
timeInfo.setLastModificationTime(readDateTime());
}
else if (m_xml.name() == "CreationTime") {
} else if (m_xml.name() == "CreationTime") {
timeInfo.setCreationTime(readDateTime());
}
else if (m_xml.name() == "LastAccessTime") {
} else if (m_xml.name() == "LastAccessTime") {
timeInfo.setLastAccessTime(readDateTime());
}
else if (m_xml.name() == "ExpiryTime") {
} else if (m_xml.name() == "ExpiryTime") {
timeInfo.setExpiryTime(readDateTime());
}
else if (m_xml.name() == "Expires") {
} else if (m_xml.name() == "Expires") {
timeInfo.setExpires(readBool());
}
else if (m_xml.name() == "UsageCount") {
} else if (m_xml.name() == "UsageCount") {
timeInfo.setUsageCount(readNumber());
}
else if (m_xml.name() == "LocationChanged") {
} else if (m_xml.name() == "LocationChanged") {
timeInfo.setLocationChanged(readDateTime());
}
else {
} else {
skipCurrentElement();
}
}
@ -1030,14 +908,11 @@ bool Kdbx3XmlReader::readBool()
if (str.compare("True", Qt::CaseInsensitive) == 0) {
return true;
}
else if (str.compare("False", Qt::CaseInsensitive) == 0) {
} else if (str.compare("False", Qt::CaseInsensitive) == 0) {
return false;
}
else if (str.length() == 0) {
} else if (str.length() == 0) {
return false;
}
else {
} else {
raiseError("Invalid bool value");
return false;
}
@ -1051,8 +926,7 @@ QDateTime Kdbx3XmlReader::readDateTime()
if (!dt.isValid()) {
if (m_strictMode) {
raiseError("Invalid date time value");
}
else {
} else {
dt = QDateTime::currentDateTimeUtc();
}
}
@ -1077,7 +951,7 @@ QColor Kdbx3XmlReader::readColor()
QColor color;
for (int i = 0; i <= 2; i++) {
QString rgbPartStr = colorStr.mid(1 + 2*i, 2);
QString rgbPartStr = colorStr.mid(1 + 2 * i, 2);
bool ok;
int rgbPart = rgbPartStr.toInt(&ok, 16);
if (!ok || rgbPart > 255) {
@ -1089,11 +963,9 @@ QColor Kdbx3XmlReader::readColor()
if (i == 0) {
color.setRed(rgbPart);
}
else if (i == 1) {
} else if (i == 1) {
color.setGreen(rgbPart);
}
else {
} else {
color.setBlue(rgbPart);
}
}
@ -1116,14 +988,12 @@ Uuid Kdbx3XmlReader::readUuid()
QByteArray uuidBin = readBinary();
if (uuidBin.isEmpty()) {
return Uuid();
}
else if (uuidBin.length() != Uuid::Length) {
} else if (uuidBin.length() != Uuid::Length) {
if (m_strictMode) {
raiseError("Invalid uuid value");
}
return Uuid();
}
else {
} else {
return Uuid(uuidBin);
}
}
@ -1159,8 +1029,7 @@ Group* Kdbx3XmlReader::getGroup(const Uuid& uuid)
if (m_groups.contains(uuid)) {
return m_groups.value(uuid);
}
else {
} else {
Group* group = new Group();
group->setUpdateTimeinfo(false);
group->setUuid(uuid);
@ -1178,8 +1047,7 @@ Entry* Kdbx3XmlReader::getEntry(const Uuid& uuid)
if (m_entries.contains(uuid)) {
return m_entries.value(uuid);
}
else {
} else {
Entry* entry = new Entry();
entry->setUpdateTimeinfo(false);
entry->setUuid(uuid);

View File

@ -36,7 +36,7 @@ class Metadata;
class Kdbx3XmlReader
{
Q_DECLARE_TR_FUNCTIONS(Kdbx3XmlReader)
Q_DECLARE_TR_FUNCTIONS(Kdbx3XmlReader)
public:
Kdbx3XmlReader();

View File

@ -36,7 +36,7 @@ Kdbx3XmlWriter::Kdbx3XmlWriter()
}
void Kdbx3XmlWriter::writeDatabase(QIODevice* device, Database* db, KeePass2RandomStream* randomStream,
const QByteArray& headerHash)
const QByteArray& headerHash)
{
m_db = db;
m_meta = db->metadata();
@ -66,7 +66,7 @@ void Kdbx3XmlWriter::writeDatabase(QIODevice* device, Database* db, KeePass2Rand
void Kdbx3XmlWriter::writeDatabase(const QString& filename, Database* db)
{
QFile file(filename);
file.open(QIODevice::WriteOnly|QIODevice::Truncate);
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
writeDatabase(&file, db);
}
@ -202,8 +202,7 @@ void Kdbx3XmlWriter::writeBinaries()
buffer.seek(0);
data = buffer.readAll();
}
else {
} else {
data = i.key();
}
@ -346,12 +345,12 @@ void Kdbx3XmlWriter::writeEntry(const Entry* entry)
for (const QString& key : attributesKeyList) {
m_xml.writeStartElement("String");
bool protect = ( ((key == "Title") && m_meta->protectTitle()) ||
((key == "UserName") && m_meta->protectUsername()) ||
((key == "Password") && m_meta->protectPassword()) ||
((key == "URL") && m_meta->protectUrl()) ||
((key == "Notes") && m_meta->protectNotes()) ||
entry->attributes()->isProtected(key) );
bool protect = (((key == "Title") && m_meta->protectTitle()) ||
((key == "UserName") && m_meta->protectUsername()) ||
((key == "Password") && m_meta->protectPassword()) ||
((key == "URL") && m_meta->protectUrl()) ||
((key == "Notes") && m_meta->protectNotes()) ||
entry->attributes()->isProtected(key));
writeString("Key", key);
@ -367,13 +366,11 @@ void Kdbx3XmlWriter::writeEntry(const Entry* entry)
raiseError(m_randomStream->errorString());
}
value = QString::fromLatin1(rawData.toBase64());
}
else {
} else {
m_xml.writeAttribute("ProtectInMemory", "True");
value = entry->attributes()->value(key);
}
}
else {
} else {
value = entry->attributes()->value(key);
}
@ -449,8 +446,7 @@ void Kdbx3XmlWriter::writeString(const QString& qualifiedName, const QString& st
{
if (string.isEmpty()) {
m_xml.writeEmptyElement(qualifiedName);
}
else {
} else {
m_xml.writeTextElement(qualifiedName, stripInvalidXml10Chars(string));
}
}
@ -464,8 +460,7 @@ void Kdbx3XmlWriter::writeBool(const QString& qualifiedName, bool b)
{
if (b) {
writeString(qualifiedName, "True");
}
else {
} else {
writeString(qualifiedName, "False");
}
}
@ -494,8 +489,7 @@ void Kdbx3XmlWriter::writeUuid(const QString& qualifiedName, const Group* group)
{
if (group) {
writeUuid(qualifiedName, group->uuid());
}
else {
} else {
writeUuid(qualifiedName, Uuid());
}
}
@ -504,8 +498,7 @@ void Kdbx3XmlWriter::writeUuid(const QString& qualifiedName, const Entry* entry)
{
if (entry) {
writeUuid(qualifiedName, entry->uuid());
}
else {
} else {
writeUuid(qualifiedName, Uuid());
}
}
@ -520,9 +513,9 @@ void Kdbx3XmlWriter::writeColor(const QString& qualifiedName, const QColor& colo
QString colorStr;
if (color.isValid()) {
colorStr = QString("#%1%2%3").arg(colorPartToString(color.red()),
colorPartToString(color.green()),
colorPartToString(color.blue()));
colorStr = QString("#%1%2%3").arg(colorPartToString(color.red()),
colorPartToString(color.green()),
colorPartToString(color.blue()));
}
writeString(qualifiedName, colorStr);
@ -534,11 +527,9 @@ void Kdbx3XmlWriter::writeTriState(const QString& qualifiedName, Group::TriState
if (triState == Group::Inherit) {
value = "null";
}
else if (triState == Group::Enable) {
} else if (triState == Group::Enable) {
value = "true";
}
else {
} else {
value = "false";
}
@ -564,13 +555,12 @@ QString Kdbx3XmlWriter::stripInvalidXml10Chars(QString str)
if (ch.isLowSurrogate() && i != 0 && str.at(i - 1).isHighSurrogate()) {
// keep valid surrogate pair
i--;
}
else if ((uc < 0x20 && uc != 0x09 && uc != 0x0A && uc != 0x0D) // control characters
|| (uc >= 0x7F && uc <= 0x84) // control characters, valid but discouraged by XML
|| (uc >= 0x86 && uc <= 0x9F) // control characters, valid but discouraged by XML
|| (uc > 0xFFFD) // noncharacter
|| ch.isLowSurrogate() // single low surrogate
|| ch.isHighSurrogate()) // single high surrogate
} else if ((uc < 0x20 && uc != 0x09 && uc != 0x0A && uc != 0x0D) // control characters
|| (uc >= 0x7F && uc <= 0x84) // control characters, valid but discouraged by XML
|| (uc >= 0x86 && uc <= 0x9F) // control characters, valid but discouraged by XML
|| (uc > 0xFFFD) // noncharacter
|| ch.isLowSurrogate() // single low surrogate
|| ch.isHighSurrogate()) // single high surrogate
{
qWarning("Stripping invalid XML 1.0 codepoint %x", uc);
str.remove(i, 1);

View File

@ -48,24 +48,24 @@ Kdf* KeePass2::uuidToKdf(const Uuid& uuid) {
Uuid KeePass2::kdfToUuid(const Kdf& kdf)
{
switch (kdf.type()) {
case Kdf::Type::AES:
return KDF_AES;
default:
return Uuid();
case Kdf::Type::AES:
return KDF_AES;
default:
return Uuid();
}
}
KeePass2::ProtectedStreamAlgo KeePass2::idToProtectedStreamAlgo(quint32 id)
{
switch (id) {
case static_cast<quint32>(KeePass2::ArcFourVariant):
return KeePass2::ArcFourVariant;
case static_cast<quint32>(KeePass2::Salsa20):
return KeePass2::Salsa20;
case static_cast<quint32>(KeePass2::ChaCha20):
return KeePass2::ChaCha20;
default:
return KeePass2::InvalidProtectedStreamAlgo;
case static_cast<quint32>(KeePass2::ArcFourVariant):
return KeePass2::ArcFourVariant;
case static_cast<quint32>(KeePass2::Salsa20):
return KeePass2::Salsa20;
case static_cast<quint32>(KeePass2::ChaCha20):
return KeePass2::ChaCha20;
default:
return KeePass2::InvalidProtectedStreamAlgo;
}
}

View File

@ -29,16 +29,16 @@ KeePass2RandomStream::KeePass2RandomStream(KeePass2::ProtectedStreamAlgo algo)
bool KeePass2RandomStream::init(const QByteArray& key)
{
switch (m_cipher.algorithm()) {
case SymmetricCipher::Salsa20:
return m_cipher.init(CryptoHash::hash(key, CryptoHash::Sha256),
KeePass2::INNER_STREAM_SALSA20_IV);
case SymmetricCipher::ChaCha20: {
QByteArray keyIv = CryptoHash::hash(key, CryptoHash::Sha512);
return m_cipher.init(keyIv.left(32), keyIv.mid(32, 12));
}
default:
qWarning("Invalid stream algorithm (%d)", m_cipher.algorithm());
break;
case SymmetricCipher::Salsa20:
return m_cipher.init(CryptoHash::hash(key, CryptoHash::Sha256),
KeePass2::INNER_STREAM_SALSA20_IV);
case SymmetricCipher::ChaCha20: {
QByteArray keyIv = CryptoHash::hash(key, CryptoHash::Sha512);
return m_cipher.init(keyIv.left(32), keyIv.mid(32, 12));
}
default:
qWarning("Invalid stream algorithm (%d)", m_cipher.algorithm());
break;
}
return false;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 KeePassXC Team
* Copyright (C) 2017 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
@ -24,7 +24,7 @@ const QSysInfo::Endian HmacBlockStream::ByteOrder = QSysInfo::LittleEndian;
HmacBlockStream::HmacBlockStream(QIODevice* baseDevice, QByteArray key)
: LayeredStream(baseDevice)
, m_blockSize(1024*1024)
, m_blockSize(1024 * 1024)
, m_key(key)
{
init();
@ -94,8 +94,7 @@ qint64 HmacBlockStream::readData(char* data, qint64 maxSize)
{
if (m_error) {
return -1;
}
else if (m_eof) {
} else if (m_eof) {
return 0;
}
@ -107,8 +106,7 @@ qint64 HmacBlockStream::readData(char* data, qint64 maxSize)
if (!readHashedBlock()) {
if (m_error) {
return -1;
}
else {
} else {
return maxSize - bytesRemaining;
}
}
@ -204,8 +202,7 @@ qint64 HmacBlockStream::writeData(const char* data, qint64 maxSize)
if (!writeHashedBlock()) {
if (m_error) {
return -1;
}
else {
} else {
return maxSize - bytesRemaining;
}
}
@ -249,11 +246,13 @@ bool HmacBlockStream::writeHashedBlock()
return true;
}
QByteArray HmacBlockStream::getCurrentHmacKey() const {
QByteArray HmacBlockStream::getCurrentHmacKey() const
{
return getHmacKey(m_blockIndex, m_key);
}
QByteArray HmacBlockStream::getHmacKey(quint64 blockIndex, QByteArray key) {
QByteArray HmacBlockStream::getHmacKey(quint64 blockIndex, QByteArray key)
{
Q_ASSERT(key.size() == 64);
QByteArray indexBytes = Endian::sizedIntToBytes<quint64>(blockIndex, ByteOrder);
CryptoHash hasher(CryptoHash::Sha512);
@ -262,6 +261,7 @@ QByteArray HmacBlockStream::getHmacKey(quint64 blockIndex, QByteArray key) {
return hasher.result();
}
bool HmacBlockStream::atEnd() const {
bool HmacBlockStream::atEnd() const
{
return m_eof;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 KeePassXC Team
* Copyright (C) 2017 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
@ -22,9 +22,9 @@
#include "streams/LayeredStream.h"
class HmacBlockStream : public LayeredStream
class HmacBlockStream: public LayeredStream
{
Q_OBJECT
Q_OBJECT
public:
explicit HmacBlockStream(QIODevice* baseDevice, QByteArray key);