1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

chore: Update qTox to the latest toxencryptsave API.

Since ownership is somewhat unclear, we now use shared_ptr to pass
these around instead of unique_ptr.
This commit is contained in:
iphydf 2016-12-13 23:00:17 +00:00 committed by Diadlo
parent fe8671f35e
commit de407c4714
No known key found for this signature in database
GPG Key ID: 5AF9F2E29107C727
10 changed files with 62 additions and 51 deletions

View File

@ -81,10 +81,10 @@ public:
ToxId getSelfId() const; ToxId getSelfId() const;
QPair<QByteArray, QByteArray> getKeypair() const; QPair<QByteArray, QByteArray> getKeypair() const;
static std::unique_ptr<TOX_PASS_KEY> createPasskey(const QString &password, uint8_t* salt = nullptr); static std::shared_ptr<Tox_Pass_Key> createPasskey(const QString &password, uint8_t* salt = nullptr);
static QByteArray encryptData(const QByteArray& data, const TOX_PASS_KEY& encryptionKey); static QByteArray encryptData(const QByteArray& data, const Tox_Pass_Key& encryptionKey);
static QByteArray encryptData(const QByteArray& data); static QByteArray encryptData(const QByteArray& data);
static QByteArray decryptData(const QByteArray& data, const TOX_PASS_KEY &encryptionKey); static QByteArray decryptData(const QByteArray& data, const Tox_Pass_Key &encryptionKey);
static QByteArray decryptData(const QByteArray& data); static QByteArray decryptData(const QByteArray& data);
bool isReady() const; bool isReady() const;

View File

@ -38,15 +38,15 @@
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
std::unique_ptr<TOX_PASS_KEY> Core::createPasskey(const QString& password, uint8_t* salt) std::shared_ptr<Tox_Pass_Key> Core::createPasskey(const QString& password, uint8_t* salt)
{ {
std::unique_ptr<TOX_PASS_KEY> encryptionKey(new TOX_PASS_KEY); std::shared_ptr<Tox_Pass_Key> encryptionKey(tox_pass_key_new(), tox_pass_key_free);
CString str(password); CString str(password);
if (salt) if (salt)
tox_derive_key_with_salt(str.data(), str.size(), salt, encryptionKey.get(), nullptr); tox_pass_key_derive_with_salt(encryptionKey.get(), str.data(), str.size(), salt, nullptr);
else else
tox_derive_key_from_pass(str.data(), str.size(), encryptionKey.get(), nullptr); tox_pass_key_derive(encryptionKey.get(), str.data(), str.size(), nullptr);
return encryptionKey; return encryptionKey;
} }
@ -62,11 +62,11 @@ QByteArray Core::encryptData(const QByteArray &data)
return encryptData(data, Nexus::getProfile()->getPasskey()); return encryptData(data, Nexus::getProfile()->getPasskey());
} }
QByteArray Core::encryptData(const QByteArray& data, const TOX_PASS_KEY& encryptionKey) QByteArray Core::encryptData(const QByteArray& data, const Tox_Pass_Key& encryptionKey)
{ {
uint8_t encrypted[data.size() + TOX_PASS_ENCRYPTION_EXTRA_LENGTH]; uint8_t encrypted[data.size() + TOX_PASS_ENCRYPTION_EXTRA_LENGTH];
if (!tox_pass_key_encrypt(reinterpret_cast<const uint8_t*>(data.data()), data.size(), if (!tox_pass_key_encrypt(&encryptionKey, reinterpret_cast<const uint8_t*>(data.data()), data.size(),
&encryptionKey, encrypted, nullptr)) encrypted, nullptr))
{ {
qWarning() << "Encryption failed"; qWarning() << "Encryption failed";
return QByteArray(); return QByteArray();
@ -85,7 +85,7 @@ QByteArray Core::decryptData(const QByteArray &data)
return decryptData(data, Nexus::getProfile()->getPasskey()); return decryptData(data, Nexus::getProfile()->getPasskey());
} }
QByteArray Core::decryptData(const QByteArray& data, const TOX_PASS_KEY& encryptionKey) QByteArray Core::decryptData(const QByteArray& data, const Tox_Pass_Key& encryptionKey)
{ {
if (data.size() < TOX_PASS_ENCRYPTION_EXTRA_LENGTH) if (data.size() < TOX_PASS_ENCRYPTION_EXTRA_LENGTH)
{ {
@ -94,8 +94,8 @@ QByteArray Core::decryptData(const QByteArray& data, const TOX_PASS_KEY& encrypt
} }
int sz = data.size() - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; int sz = data.size() - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
uint8_t decrypted[sz]; uint8_t decrypted[sz];
if (!tox_pass_key_decrypt(reinterpret_cast<const uint8_t*>(data.data()), data.size(), if (!tox_pass_key_decrypt(&encryptionKey, reinterpret_cast<const uint8_t*>(data.data()), data.size(),
&encryptionKey, decrypted, nullptr)) decrypted, nullptr))
{ {
qWarning() << "Decryption failed"; qWarning() << "Decryption failed";
return QByteArray(); return QByteArray();
@ -115,7 +115,7 @@ QByteArray Core::getSaltFromFile(QString filename)
file.close(); file.close();
uint8_t salt[TOX_PASS_SALT_LENGTH]; uint8_t salt[TOX_PASS_SALT_LENGTH];
if (!tox_get_salt(reinterpret_cast<uint8_t *>(data.data()), salt)) if (!tox_get_salt(reinterpret_cast<uint8_t *>(data.data()), salt, nullptr))
{ {
qWarning() << "can't get salt from" << filename << "header"; qWarning() << "can't get salt from" << filename << "header";
return QByteArray(); return QByteArray();
@ -148,7 +148,7 @@ void Core::checkEncryptedHistory()
QString dialogtxt; QString dialogtxt;
if (!exists || HistoryKeeper::checkPassword(*passkey)) if (!exists || HistoryKeeper::checkPassword(passkey))
return; return;
dialogtxt = tr("The chat history password failed. Please try another?", "used only when pw set before load() doesn't work"); dialogtxt = tr("The chat history password failed. Please try another?", "used only when pw set before load() doesn't work");
@ -169,7 +169,7 @@ void Core::checkEncryptedHistory()
passkey = createPasskey(pw, reinterpret_cast<uint8_t*>(salt.data())); passkey = createPasskey(pw, reinterpret_cast<uint8_t*>(salt.data()));
} }
error = exists && !HistoryKeeper::checkPassword(*passkey); error = exists && !HistoryKeeper::checkPassword(passkey);
dialogtxt = a + "\n" + c + "\n" + b; dialogtxt = a + "\n" + c + "\n" + b;
} while (error); } while (error);
} }

View File

@ -30,14 +30,14 @@
#include <QSqlError> #include <QSqlError>
/** /**
* @var static TOX_PASS_KEY EncryptedDb::decryptionKey * @var static std::shared_ptr<Tox_Pass_Key> EncryptedDb::decryptionKey
* @note When importing, the decryption key may not be the same as the profile key * @note When importing, the decryption key may not be the same as the profile key
*/ */
qint64 EncryptedDb::encryptedChunkSize = 4096; qint64 EncryptedDb::encryptedChunkSize = 4096;
qint64 EncryptedDb::plainChunkSize = EncryptedDb::encryptedChunkSize - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; qint64 EncryptedDb::plainChunkSize = EncryptedDb::encryptedChunkSize - TOX_PASS_ENCRYPTION_EXTRA_LENGTH;
TOX_PASS_KEY EncryptedDb::decryptionKey; std::shared_ptr<Tox_Pass_Key> EncryptedDb::decryptionKey;
EncryptedDb::EncryptedDb(const QString &fname, QList<QString> initList) : EncryptedDb::EncryptedDb(const QString &fname, QList<QString> initList) :
PlainDb(":memory:", initList), fileName(fname) PlainDb(":memory:", initList), fileName(fname)
@ -99,7 +99,7 @@ bool EncryptedDb::pullFileContent(const QString &fname, QByteArray &buf)
while (!dbFile.atEnd()) while (!dbFile.atEnd())
{ {
QByteArray encrChunk = dbFile.read(encryptedChunkSize); QByteArray encrChunk = dbFile.read(encryptedChunkSize);
buf = Core::getInstance()->decryptData(encrChunk, decryptionKey); buf = Core::getInstance()->decryptData(encrChunk, *decryptionKey);
if (buf.size() > 0) if (buf.size() > 0)
{ {
fileContent += buf; fileContent += buf;
@ -163,7 +163,7 @@ void EncryptedDb::appendToEncrypted(const QString &sql)
encrFile.flush(); encrFile.flush();
} }
bool EncryptedDb::check(const TOX_PASS_KEY &passkey, const QString &fname) bool EncryptedDb::check(std::shared_ptr<Tox_Pass_Key> passkey, const QString &fname)
{ {
QFile file(fname); QFile file(fname);
file.open(QIODevice::ReadOnly); file.open(QIODevice::ReadOnly);
@ -172,7 +172,7 @@ bool EncryptedDb::check(const TOX_PASS_KEY &passkey, const QString &fname)
if (file.size() > 0) if (file.size() > 0)
{ {
QByteArray encrChunk = file.read(encryptedChunkSize); QByteArray encrChunk = file.read(encryptedChunkSize);
QByteArray buf = Core::getInstance()->decryptData(encrChunk, passkey); QByteArray buf = Core::getInstance()->decryptData(encrChunk, *passkey);
if (buf.size() == 0) if (buf.size() == 0)
state = false; state = false;
else else

View File

@ -26,6 +26,8 @@
#include <QList> #include <QList>
#include <QFile> #include <QFile>
#include <memory>
class EncryptedDb : public PlainDb class EncryptedDb : public PlainDb
{ {
public: public:
@ -33,7 +35,7 @@ public:
virtual ~EncryptedDb(); virtual ~EncryptedDb();
virtual QSqlQuery exec(const QString &query); virtual QSqlQuery exec(const QString &query);
static bool check(const TOX_PASS_KEY &passkey, const QString &fname); static bool check(std::shared_ptr<Tox_Pass_Key> passkey, const QString &fname);
private: private:
bool pullFileContent(const QString& fname, QByteArray &buf); bool pullFileContent(const QString& fname, QByteArray &buf);
@ -46,7 +48,7 @@ private:
static qint64 plainChunkSize; static qint64 plainChunkSize;
static qint64 encryptedChunkSize; static qint64 encryptedChunkSize;
static TOX_PASS_KEY decryptionKey; static std::shared_ptr<Tox_Pass_Key> decryptionKey;
qint64 chunkPosition; qint64 chunkPosition;
QByteArray buffer; QByteArray buffer;

View File

@ -481,6 +481,13 @@ bool RawDatabase::remove()
return QFile::remove(path); return QFile::remove(path);
} }
struct PassKeyDeleter
{
void operator()(Tox_Pass_Key *pass_key) {
tox_pass_key_free(pass_key);
}
};
/** /**
* @brief Derives a 256bit key from the password and returns it hex-encoded * @brief Derives a 256bit key from the password and returns it hex-encoded
* @param password Password to decrypt database * @param password Password to decrypt database
@ -497,10 +504,10 @@ QString RawDatabase::deriveKey(const QString &password)
static_assert(TOX_PASS_KEY_LENGTH >= 32, "toxcore must provide 256bit or longer keys"); static_assert(TOX_PASS_KEY_LENGTH >= 32, "toxcore must provide 256bit or longer keys");
static const uint8_t expandConstant[TOX_PASS_SALT_LENGTH+1] = "L'ignorance est le pire des maux"; static const uint8_t expandConstant[TOX_PASS_SALT_LENGTH+1] = "L'ignorance est le pire des maux";
TOX_PASS_KEY key; std::unique_ptr<Tox_Pass_Key, PassKeyDeleter> key(tox_pass_key_new());
tox_derive_key_with_salt(reinterpret_cast<uint8_t*>(passData.data()), tox_pass_key_derive_with_salt(key.get(), reinterpret_cast<uint8_t*>(passData.data()),
static_cast<std::size_t>(passData.size()), expandConstant, &key, nullptr); static_cast<std::size_t>(passData.size()), expandConstant, nullptr);
return QByteArray(reinterpret_cast<char*>(key.key), 32).toHex(); return QByteArray(reinterpret_cast<char*>(key.get()) + 32, 32).toHex();;
} }
/** /**
@ -526,11 +533,11 @@ QString RawDatabase::deriveKey(const QString& password, const QByteArray& salt)
static_assert(TOX_PASS_KEY_LENGTH >= 32, "toxcore must provide 256bit or longer keys"); static_assert(TOX_PASS_KEY_LENGTH >= 32, "toxcore must provide 256bit or longer keys");
TOX_PASS_KEY key; std::unique_ptr<Tox_Pass_Key, PassKeyDeleter> key(tox_pass_key_new());
tox_derive_key_with_salt(reinterpret_cast<uint8_t*>(passData.data()), tox_pass_key_derive_with_salt(key.get(), reinterpret_cast<uint8_t*>(passData.data()),
static_cast<std::size_t>(passData.size()), static_cast<std::size_t>(passData.size()),
reinterpret_cast<const uint8_t*>(salt.constData()), &key, nullptr); reinterpret_cast<const uint8_t*>(salt.constData()), nullptr);
return QByteArray(reinterpret_cast<char*>(key.key), 32).toHex(); return QByteArray(reinterpret_cast<char*>(key.get()) + 32, 32).toHex();;
} }
/** /**

View File

@ -86,7 +86,7 @@ HistoryKeeper *HistoryKeeper::getInstance(const Profile& profile)
return historyInstance; return historyInstance;
} }
bool HistoryKeeper::checkPassword(const TOX_PASS_KEY &passkey, int encrypted) bool HistoryKeeper::checkPassword(std::shared_ptr<Tox_Pass_Key> passkey, int encrypted)
{ {
if (!Settings::getInstance().getEnableLogging() && (encrypted == -1)) if (!Settings::getInstance().getEnableLogging() && (encrypted == -1))
return true; return true;

View File

@ -27,6 +27,8 @@
#include <QMutex> #include <QMutex>
#include <tox/toxencryptsave.h> #include <tox/toxencryptsave.h>
#include <memory>
class Profile; class Profile;
class GenericDdInterface; class GenericDdInterface;
@ -59,7 +61,7 @@ public:
static void resetInstance(); static void resetInstance();
static QString getHistoryPath(QString currentProfile = QString(), int encrypted = -1); // -1 defaults to checking settings, 0 or 1 to specify static QString getHistoryPath(QString currentProfile = QString(), int encrypted = -1); // -1 defaults to checking settings, 0 or 1 to specify
static bool checkPassword(const TOX_PASS_KEY& passkey, int encrypted = -1); static bool checkPassword(std::shared_ptr<Tox_Pass_Key> passkey, int encrypted = -1);
static bool isFileExist(bool encrypted); static bool isFileExist(bool encrypted);
void removeHistory(); void removeHistory();
static QList<HistMessage> exportMessagesDeleteFile(); static QList<HistMessage> exportMessagesDeleteFile();

View File

@ -56,7 +56,7 @@ Profile::Profile(QString name, const QString& password, bool isNewProfile)
{ {
if (!password.isEmpty()) if (!password.isEmpty())
{ {
passkey = *core->createPasskey(password); passkey = core->createPasskey(password);
} }
Settings& s = Settings::getInstance(); Settings& s = Settings::getInstance();
@ -132,10 +132,10 @@ Profile* Profile::loadProfile(QString name, const QString& password)
} }
uint8_t salt[TOX_PASS_SALT_LENGTH]; uint8_t salt[TOX_PASS_SALT_LENGTH];
tox_get_salt(reinterpret_cast<uint8_t*>(data.data()), salt); tox_get_salt(reinterpret_cast<uint8_t*>(data.data()), salt, nullptr);
auto tmpkey = *Core::createPasskey(password, salt); auto tmpkey = Core::createPasskey(password, salt);
data = Core::decryptData(data, tmpkey); data = Core::decryptData(data, *tmpkey);
if (data.isEmpty()) if (data.isEmpty())
{ {
qCritical() << "Failed to decrypt the tox save file"; qCritical() << "Failed to decrypt the tox save file";
@ -324,10 +324,10 @@ QByteArray Profile::loadToxSave()
} }
uint8_t salt[TOX_PASS_SALT_LENGTH]; uint8_t salt[TOX_PASS_SALT_LENGTH];
tox_get_salt(reinterpret_cast<uint8_t*>(data.data()), salt); tox_get_salt(reinterpret_cast<uint8_t*>(data.data()), salt, nullptr);
passkey = *core->createPasskey(password, salt); passkey = core->createPasskey(password, salt);
data = core->decryptData(data, passkey); data = core->decryptData(data, *passkey);
if (data.isEmpty()) if (data.isEmpty())
{ {
qCritical() << "Failed to decrypt the tox save file"; qCritical() << "Failed to decrypt the tox save file";
@ -380,8 +380,8 @@ void Profile::saveToxSave(QByteArray data)
if (!password.isEmpty()) if (!password.isEmpty())
{ {
passkey = *core->createPasskey(password); passkey = core->createPasskey(password);
data = core->encryptData(data, passkey); data = core->encryptData(data, *passkey);
if (data.isEmpty()) if (data.isEmpty())
{ {
qCritical() << "Failed to encrypt, can't save!"; qCritical() << "Failed to encrypt, can't save!";
@ -487,7 +487,7 @@ QByteArray Profile::loadAvatarData(const QString& ownerId, const QString& passwo
if (encrypted && !pic.isEmpty()) if (encrypted && !pic.isEmpty())
{ {
uint8_t salt[TOX_PASS_SALT_LENGTH]; uint8_t salt[TOX_PASS_SALT_LENGTH];
tox_get_salt(reinterpret_cast<uint8_t*>(pic.data()), salt); tox_get_salt(reinterpret_cast<uint8_t*>(pic.data()), salt, nullptr);
auto passkey = core->createPasskey(password, salt); auto passkey = core->createPasskey(password, salt);
pic = core->decryptData(pic, *passkey); pic = core->decryptData(pic, *passkey);
} }
@ -532,7 +532,7 @@ void Profile::saveAvatar(QByteArray pic, const QString& ownerId)
{ {
if (!password.isEmpty() && !pic.isEmpty()) if (!password.isEmpty() && !pic.isEmpty())
{ {
pic = core->encryptData(pic, passkey); pic = core->encryptData(pic, *passkey);
} }
QString path = avatarPath(ownerId); QString path = avatarPath(ownerId);
@ -764,9 +764,9 @@ QString Profile::getPassword() const
return password; return password;
} }
const TOX_PASS_KEY& Profile::getPasskey() const const Tox_Pass_Key& Profile::getPasskey() const
{ {
return passkey; return *passkey;
} }
/** /**
@ -792,7 +792,7 @@ void Profile::setPassword(const QString& newPassword)
QByteArray avatar = loadAvatarData(core->getSelfId().publicKey); QByteArray avatar = loadAvatarData(core->getSelfId().publicKey);
QString oldPassword = password; QString oldPassword = password;
password = newPassword; password = newPassword;
passkey = *core->createPasskey(password); passkey = core->createPasskey(password);
saveToxSave(); saveToxSave();
if (database) if (database)

View File

@ -52,7 +52,7 @@ public:
bool checkPassword(); bool checkPassword();
QString getPassword() const; QString getPassword() const;
void setPassword(const QString& newPassword); void setPassword(const QString& newPassword);
const TOX_PASS_KEY& getPasskey() const; const Tox_Pass_Key& getPasskey() const;
QByteArray loadToxSave(); QByteArray loadToxSave();
void saveToxSave(); void saveToxSave();
@ -92,7 +92,7 @@ private:
Core* core; Core* core;
QThread* coreThread; QThread* coreThread;
QString name, password; QString name, password;
TOX_PASS_KEY passkey; std::shared_ptr<Tox_Pass_Key> passkey;
std::shared_ptr<RawDatabase> database; std::shared_ptr<RawDatabase> database;
std::unique_ptr<History> history; std::unique_ptr<History> history;
bool newProfile; bool newProfile;

View File

@ -370,7 +370,7 @@ void SettingsSerializer::readSerialized()
Core* core = Nexus::getCore(); Core* core = Nexus::getCore();
uint8_t salt[TOX_PASS_SALT_LENGTH]; uint8_t salt[TOX_PASS_SALT_LENGTH];
tox_get_salt(reinterpret_cast<uint8_t *>(data.data()), salt); tox_get_salt(reinterpret_cast<uint8_t *>(data.data()), salt, nullptr);
auto passkey = core->createPasskey(password, salt); auto passkey = core->createPasskey(password, salt);
data = core->decryptData(data, *passkey); data = core->decryptData(data, *passkey);