diff --git a/src/core/core.h b/src/core/core.h index f1b8055b5..aa65f2867 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -81,10 +81,10 @@ public: ToxId getSelfId() const; QPair getKeypair() const; - static std::unique_ptr createPasskey(const QString &password, uint8_t* salt = nullptr); - static QByteArray encryptData(const QByteArray& data, const TOX_PASS_KEY& encryptionKey); + static std::shared_ptr 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); - 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); bool isReady() const; diff --git a/src/core/coreencryption.cpp b/src/core/coreencryption.cpp index d2d5697a7..7581ce413 100644 --- a/src/core/coreencryption.cpp +++ b/src/core/coreencryption.cpp @@ -38,15 +38,15 @@ #include #include -std::unique_ptr Core::createPasskey(const QString& password, uint8_t* salt) +std::shared_ptr Core::createPasskey(const QString& password, uint8_t* salt) { - std::unique_ptr encryptionKey(new TOX_PASS_KEY); + std::shared_ptr encryptionKey(tox_pass_key_new(), tox_pass_key_free); CString str(password); 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 - 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; } @@ -62,11 +62,11 @@ QByteArray Core::encryptData(const QByteArray &data) 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]; - if (!tox_pass_key_encrypt(reinterpret_cast(data.data()), data.size(), - &encryptionKey, encrypted, nullptr)) + if (!tox_pass_key_encrypt(&encryptionKey, reinterpret_cast(data.data()), data.size(), + encrypted, nullptr)) { qWarning() << "Encryption failed"; return QByteArray(); @@ -85,7 +85,7 @@ QByteArray Core::decryptData(const QByteArray &data) 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) { @@ -94,8 +94,8 @@ QByteArray Core::decryptData(const QByteArray& data, const TOX_PASS_KEY& encrypt } int sz = data.size() - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; uint8_t decrypted[sz]; - if (!tox_pass_key_decrypt(reinterpret_cast(data.data()), data.size(), - &encryptionKey, decrypted, nullptr)) + if (!tox_pass_key_decrypt(&encryptionKey, reinterpret_cast(data.data()), data.size(), + decrypted, nullptr)) { qWarning() << "Decryption failed"; return QByteArray(); @@ -115,7 +115,7 @@ QByteArray Core::getSaltFromFile(QString filename) file.close(); uint8_t salt[TOX_PASS_SALT_LENGTH]; - if (!tox_get_salt(reinterpret_cast(data.data()), salt)) + if (!tox_get_salt(reinterpret_cast(data.data()), salt, nullptr)) { qWarning() << "can't get salt from" << filename << "header"; return QByteArray(); @@ -148,7 +148,7 @@ void Core::checkEncryptedHistory() QString dialogtxt; - if (!exists || HistoryKeeper::checkPassword(*passkey)) + if (!exists || HistoryKeeper::checkPassword(passkey)) return; 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(salt.data())); } - error = exists && !HistoryKeeper::checkPassword(*passkey); + error = exists && !HistoryKeeper::checkPassword(passkey); dialogtxt = a + "\n" + c + "\n" + b; } while (error); } diff --git a/src/persistence/db/encrypteddb.cpp b/src/persistence/db/encrypteddb.cpp index 1d0d4debb..9958d4ef1 100644 --- a/src/persistence/db/encrypteddb.cpp +++ b/src/persistence/db/encrypteddb.cpp @@ -30,14 +30,14 @@ #include /** - * @var static TOX_PASS_KEY EncryptedDb::decryptionKey + * @var static std::shared_ptr EncryptedDb::decryptionKey * @note When importing, the decryption key may not be the same as the profile key */ qint64 EncryptedDb::encryptedChunkSize = 4096; qint64 EncryptedDb::plainChunkSize = EncryptedDb::encryptedChunkSize - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; -TOX_PASS_KEY EncryptedDb::decryptionKey; +std::shared_ptr EncryptedDb::decryptionKey; EncryptedDb::EncryptedDb(const QString &fname, QList initList) : PlainDb(":memory:", initList), fileName(fname) @@ -99,7 +99,7 @@ bool EncryptedDb::pullFileContent(const QString &fname, QByteArray &buf) while (!dbFile.atEnd()) { QByteArray encrChunk = dbFile.read(encryptedChunkSize); - buf = Core::getInstance()->decryptData(encrChunk, decryptionKey); + buf = Core::getInstance()->decryptData(encrChunk, *decryptionKey); if (buf.size() > 0) { fileContent += buf; @@ -163,7 +163,7 @@ void EncryptedDb::appendToEncrypted(const QString &sql) encrFile.flush(); } -bool EncryptedDb::check(const TOX_PASS_KEY &passkey, const QString &fname) +bool EncryptedDb::check(std::shared_ptr passkey, const QString &fname) { QFile file(fname); file.open(QIODevice::ReadOnly); @@ -172,7 +172,7 @@ bool EncryptedDb::check(const TOX_PASS_KEY &passkey, const QString &fname) if (file.size() > 0) { QByteArray encrChunk = file.read(encryptedChunkSize); - QByteArray buf = Core::getInstance()->decryptData(encrChunk, passkey); + QByteArray buf = Core::getInstance()->decryptData(encrChunk, *passkey); if (buf.size() == 0) state = false; else diff --git a/src/persistence/db/encrypteddb.h b/src/persistence/db/encrypteddb.h index 9de25e029..69208dfbc 100644 --- a/src/persistence/db/encrypteddb.h +++ b/src/persistence/db/encrypteddb.h @@ -26,6 +26,8 @@ #include #include +#include + class EncryptedDb : public PlainDb { public: @@ -33,7 +35,7 @@ public: virtual ~EncryptedDb(); virtual QSqlQuery exec(const QString &query); - static bool check(const TOX_PASS_KEY &passkey, const QString &fname); + static bool check(std::shared_ptr passkey, const QString &fname); private: bool pullFileContent(const QString& fname, QByteArray &buf); @@ -46,7 +48,7 @@ private: static qint64 plainChunkSize; static qint64 encryptedChunkSize; - static TOX_PASS_KEY decryptionKey; + static std::shared_ptr decryptionKey; qint64 chunkPosition; QByteArray buffer; diff --git a/src/persistence/db/rawdatabase.cpp b/src/persistence/db/rawdatabase.cpp index 99ad2b971..56bc815e0 100644 --- a/src/persistence/db/rawdatabase.cpp +++ b/src/persistence/db/rawdatabase.cpp @@ -481,6 +481,13 @@ bool RawDatabase::remove() 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 * @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 const uint8_t expandConstant[TOX_PASS_SALT_LENGTH+1] = "L'ignorance est le pire des maux"; - TOX_PASS_KEY key; - tox_derive_key_with_salt(reinterpret_cast(passData.data()), - static_cast(passData.size()), expandConstant, &key, nullptr); - return QByteArray(reinterpret_cast(key.key), 32).toHex(); + std::unique_ptr key(tox_pass_key_new()); + tox_pass_key_derive_with_salt(key.get(), reinterpret_cast(passData.data()), + static_cast(passData.size()), expandConstant, nullptr); + return QByteArray(reinterpret_cast(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"); - TOX_PASS_KEY key; - tox_derive_key_with_salt(reinterpret_cast(passData.data()), - static_cast(passData.size()), - reinterpret_cast(salt.constData()), &key, nullptr); - return QByteArray(reinterpret_cast(key.key), 32).toHex(); + std::unique_ptr key(tox_pass_key_new()); + tox_pass_key_derive_with_salt(key.get(), reinterpret_cast(passData.data()), + static_cast(passData.size()), + reinterpret_cast(salt.constData()), nullptr); + return QByteArray(reinterpret_cast(key.get()) + 32, 32).toHex();; } /** diff --git a/src/persistence/historykeeper.cpp b/src/persistence/historykeeper.cpp index d91b1e902..85cd75b21 100644 --- a/src/persistence/historykeeper.cpp +++ b/src/persistence/historykeeper.cpp @@ -86,7 +86,7 @@ HistoryKeeper *HistoryKeeper::getInstance(const Profile& profile) return historyInstance; } -bool HistoryKeeper::checkPassword(const TOX_PASS_KEY &passkey, int encrypted) +bool HistoryKeeper::checkPassword(std::shared_ptr passkey, int encrypted) { if (!Settings::getInstance().getEnableLogging() && (encrypted == -1)) return true; diff --git a/src/persistence/historykeeper.h b/src/persistence/historykeeper.h index ea4c03116..1ec10cf07 100644 --- a/src/persistence/historykeeper.h +++ b/src/persistence/historykeeper.h @@ -27,6 +27,8 @@ #include #include +#include + class Profile; class GenericDdInterface; @@ -59,7 +61,7 @@ public: static void resetInstance(); 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 passkey, int encrypted = -1); static bool isFileExist(bool encrypted); void removeHistory(); static QList exportMessagesDeleteFile(); diff --git a/src/persistence/profile.cpp b/src/persistence/profile.cpp index b272d8e3b..3309273f8 100644 --- a/src/persistence/profile.cpp +++ b/src/persistence/profile.cpp @@ -56,7 +56,7 @@ Profile::Profile(QString name, const QString& password, bool isNewProfile) { if (!password.isEmpty()) { - passkey = *core->createPasskey(password); + passkey = core->createPasskey(password); } Settings& s = Settings::getInstance(); @@ -132,10 +132,10 @@ Profile* Profile::loadProfile(QString name, const QString& password) } uint8_t salt[TOX_PASS_SALT_LENGTH]; - tox_get_salt(reinterpret_cast(data.data()), salt); - auto tmpkey = *Core::createPasskey(password, salt); + tox_get_salt(reinterpret_cast(data.data()), salt, nullptr); + auto tmpkey = Core::createPasskey(password, salt); - data = Core::decryptData(data, tmpkey); + data = Core::decryptData(data, *tmpkey); if (data.isEmpty()) { qCritical() << "Failed to decrypt the tox save file"; @@ -324,10 +324,10 @@ QByteArray Profile::loadToxSave() } uint8_t salt[TOX_PASS_SALT_LENGTH]; - tox_get_salt(reinterpret_cast(data.data()), salt); - passkey = *core->createPasskey(password, salt); + tox_get_salt(reinterpret_cast(data.data()), salt, nullptr); + passkey = core->createPasskey(password, salt); - data = core->decryptData(data, passkey); + data = core->decryptData(data, *passkey); if (data.isEmpty()) { qCritical() << "Failed to decrypt the tox save file"; @@ -380,8 +380,8 @@ void Profile::saveToxSave(QByteArray data) if (!password.isEmpty()) { - passkey = *core->createPasskey(password); - data = core->encryptData(data, passkey); + passkey = core->createPasskey(password); + data = core->encryptData(data, *passkey); if (data.isEmpty()) { qCritical() << "Failed to encrypt, can't save!"; @@ -487,7 +487,7 @@ QByteArray Profile::loadAvatarData(const QString& ownerId, const QString& passwo if (encrypted && !pic.isEmpty()) { uint8_t salt[TOX_PASS_SALT_LENGTH]; - tox_get_salt(reinterpret_cast(pic.data()), salt); + tox_get_salt(reinterpret_cast(pic.data()), salt, nullptr); auto passkey = core->createPasskey(password, salt); pic = core->decryptData(pic, *passkey); } @@ -532,7 +532,7 @@ void Profile::saveAvatar(QByteArray pic, const QString& ownerId) { if (!password.isEmpty() && !pic.isEmpty()) { - pic = core->encryptData(pic, passkey); + pic = core->encryptData(pic, *passkey); } QString path = avatarPath(ownerId); @@ -764,9 +764,9 @@ QString Profile::getPassword() const 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); QString oldPassword = password; password = newPassword; - passkey = *core->createPasskey(password); + passkey = core->createPasskey(password); saveToxSave(); if (database) diff --git a/src/persistence/profile.h b/src/persistence/profile.h index fc48293f4..8173edd1b 100644 --- a/src/persistence/profile.h +++ b/src/persistence/profile.h @@ -52,7 +52,7 @@ public: bool checkPassword(); QString getPassword() const; void setPassword(const QString& newPassword); - const TOX_PASS_KEY& getPasskey() const; + const Tox_Pass_Key& getPasskey() const; QByteArray loadToxSave(); void saveToxSave(); @@ -92,7 +92,7 @@ private: Core* core; QThread* coreThread; QString name, password; - TOX_PASS_KEY passkey; + std::shared_ptr passkey; std::shared_ptr database; std::unique_ptr history; bool newProfile; diff --git a/src/persistence/settingsserializer.cpp b/src/persistence/settingsserializer.cpp index 24febaf6d..b2b210ca3 100644 --- a/src/persistence/settingsserializer.cpp +++ b/src/persistence/settingsserializer.cpp @@ -370,7 +370,7 @@ void SettingsSerializer::readSerialized() Core* core = Nexus::getCore(); uint8_t salt[TOX_PASS_SALT_LENGTH]; - tox_get_salt(reinterpret_cast(data.data()), salt); + tox_get_salt(reinterpret_cast(data.data()), salt, nullptr); auto passkey = core->createPasskey(password, salt); data = core->decryptData(data, *passkey);