diff --git a/src/Cache.cpp b/src/Cache.cpp
index a966fe57..be79a0e0 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -36,8 +36,7 @@
//! Should be changed when a breaking change occurs in the cache format.
//! This will reset client's data.
-static const std::string CURRENT_CACHE_FORMAT_VERSION("2021.08.22");
-static const std::string SECRET("secret");
+static const std::string CURRENT_CACHE_FORMAT_VERSION("2021.08.31");
//! Keys used for the DB
static const std::string_view NEXT_BATCH_KEY("next_batch");
@@ -370,7 +369,8 @@ Cache::exportSessionKeys()
ExportedSession exported;
MegolmSessionIndex index;
- auto saved_session = unpickle<InboundSessionObject>(std::string(value), SECRET);
+ auto saved_session =
+ unpickle<InboundSessionObject>(std::string(value), pickle_secret_);
try {
index = nlohmann::json::parse(key).get<MegolmSessionIndex>();
@@ -424,13 +424,14 @@ Cache::saveInboundMegolmSession(const MegolmSessionIndex &index,
{
using namespace mtx::crypto;
const auto key = json(index).dump();
- const auto pickled = pickle<InboundSessionObject>(session.get(), SECRET);
+ const auto pickled = pickle<InboundSessionObject>(session.get(), pickle_secret_);
auto txn = lmdb::txn::begin(env_);
std::string_view value;
if (inboundMegolmSessionDb_.get(txn, key, value)) {
- auto oldSession = unpickle<InboundSessionObject>(std::string(value), SECRET);
+ auto oldSession =
+ unpickle<InboundSessionObject>(std::string(value), pickle_secret_);
if (olm_inbound_group_session_first_known_index(session.get()) >
olm_inbound_group_session_first_known_index(oldSession.get())) {
nhlog::crypto()->warn(
@@ -455,7 +456,8 @@ Cache::getInboundMegolmSession(const MegolmSessionIndex &index)
std::string_view value;
if (inboundMegolmSessionDb_.get(txn, key, value)) {
- auto session = unpickle<InboundSessionObject>(std::string(value), SECRET);
+ auto session =
+ unpickle<InboundSessionObject>(std::string(value), pickle_secret_);
return session;
}
} catch (std::exception &e) {
@@ -502,7 +504,7 @@ Cache::updateOutboundMegolmSession(const std::string &room_id,
// Save the updated pickled data for the session.
json j;
- j["session"] = pickle<OutboundSessionObject>(ptr.get(), SECRET);
+ j["session"] = pickle<OutboundSessionObject>(ptr.get(), pickle_secret_);
auto txn = lmdb::txn::begin(env_);
outboundMegolmSessionDb_.put(txn, room_id, j.dump());
@@ -532,7 +534,7 @@ Cache::saveOutboundMegolmSession(const std::string &room_id,
mtx::crypto::OutboundGroupSessionPtr &session)
{
using namespace mtx::crypto;
- const auto pickled = pickle<OutboundSessionObject>(session.get(), SECRET);
+ const auto pickled = pickle<OutboundSessionObject>(session.get(), pickle_secret_);
GroupSessionData data = data_;
data.message_index = olm_outbound_group_session_message_index(session.get());
@@ -575,7 +577,7 @@ Cache::getOutboundMegolmSession(const std::string &room_id)
auto obj = json::parse(value);
OutboundGroupSessionDataRef ref{};
- ref.session = unpickle<OutboundSessionObject>(obj.at("session"), SECRET);
+ ref.session = unpickle<OutboundSessionObject>(obj.at("session"), pickle_secret_);
MegolmSessionIndex index;
index.room_id = room_id;
@@ -626,7 +628,7 @@ Cache::saveOlmSession(const std::string &curve25519,
auto txn = lmdb::txn::begin(env_);
auto db = getOlmSessionsDb(txn, curve25519);
- const auto pickled = pickle<SessionObject>(session.get(), SECRET);
+ const auto pickled = pickle<SessionObject>(session.get(), pickle_secret_);
const auto session_id = mtx::crypto::session_id(session.get());
StoredOlmSession stored_session;
@@ -653,7 +655,7 @@ Cache::getOlmSession(const std::string &curve25519, const std::string &session_i
if (found) {
auto data = json::parse(pickled).get<StoredOlmSession>();
- return unpickle<SessionObject>(data.pickled_session, SECRET);
+ return unpickle<SessionObject>(data.pickled_session, pickle_secret_);
}
return std::nullopt;
@@ -681,9 +683,9 @@ Cache::getLatestOlmSession(const std::string &curve25519)
txn.commit();
- return currentNewest
- ? std::optional(unpickle<SessionObject>(currentNewest->pickled_session, SECRET))
- : std::nullopt;
+ return currentNewest ? std::optional(unpickle<SessionObject>(currentNewest->pickled_session,
+ pickle_secret_))
+ : std::nullopt;
}
std::vector<std::string>
@@ -719,6 +721,7 @@ std::string
Cache::restoreOlmAccount()
{
auto txn = ro_txn(env_);
+
std::string_view pickled;
syncStateDb_.get(txn, OLM_ACCOUNT_KEY, pickled);
@@ -774,7 +777,7 @@ fatalSecretError()
}
void
-Cache::storeSecret(const std::string name, const std::string secret)
+Cache::storeSecret(const std::string name, const std::string secret, bool internal)
{
auto settings = UserSettings::instance();
auto job = new QKeychain::WritePasswordJob(QCoreApplication::applicationName());
@@ -783,7 +786,7 @@ Cache::storeSecret(const std::string name, const std::string secret)
job->setSettings(UserSettings::instance()->qsettings());
job->setKey(
- "matrix." +
+ (internal ? "nheko." : "matrix.") +
QString(QCryptographicHash::hash(settings->profile().toUtf8(), QCryptographicHash::Sha256)
.toBase64()) +
"." + QString::fromStdString(name));
@@ -812,7 +815,7 @@ Cache::storeSecret(const std::string name, const std::string secret)
}
void
-Cache::deleteSecret(const std::string name)
+Cache::deleteSecret(const std::string name, bool internal)
{
auto settings = UserSettings::instance();
QKeychain::DeletePasswordJob job(QCoreApplication::applicationName());
@@ -821,7 +824,7 @@ Cache::deleteSecret(const std::string name)
job.setSettings(UserSettings::instance()->qsettings());
job.setKey(
- "matrix." +
+ (internal ? "nheko." : "matrix.") +
QString(QCryptographicHash::hash(settings->profile().toUtf8(), QCryptographicHash::Sha256)
.toBase64()) +
"." + QString::fromStdString(name));
@@ -837,7 +840,7 @@ Cache::deleteSecret(const std::string name)
}
std::optional<std::string>
-Cache::secret(const std::string name)
+Cache::secret(const std::string name, bool internal)
{
auto settings = UserSettings::instance();
QKeychain::ReadPasswordJob job(QCoreApplication::applicationName());
@@ -846,7 +849,7 @@ Cache::secret(const std::string name)
job.setSettings(UserSettings::instance()->qsettings());
job.setKey(
- "matrix." +
+ (internal ? "nheko." : "matrix.") +
QString(QCryptographicHash::hash(settings->profile().toUtf8(), QCryptographicHash::Sha256)
.toBase64()) +
"." + QString::fromStdString(name));
@@ -878,6 +881,22 @@ Cache::secret(const std::string name)
return secret.toStdString();
}
+std::string
+Cache::pickleSecret()
+{
+ if (pickle_secret_.empty()) {
+ auto s = secret("pickle_secret", true);
+ if (!s) {
+ this->pickle_secret_ = mtx::client::utils::random_token(64, true);
+ storeSecret("pickle_secret", pickle_secret_, true);
+ } else {
+ this->pickle_secret_ = *s;
+ }
+ }
+
+ return pickle_secret_;
+};
+
void
Cache::removeInvite(lmdb::txn &txn, const std::string &room_id)
{
@@ -979,6 +998,7 @@ Cache::deleteData()
deleteSecret(mtx::secret_storage::secrets::cross_signing_master);
deleteSecret(mtx::secret_storage::secrets::cross_signing_user_signing);
deleteSecret(mtx::secret_storage::secrets::cross_signing_self_signing);
+ deleteSecret("pickle_secret", true);
}
//! migrates db to the current format
@@ -1202,6 +1222,11 @@ Cache::runMigrations()
"Successfully cleared the cache. Will do a clean sync after startup.");
return true;
}},
+ {"2021.08.31",
+ [this]() {
+ storeSecret("pickle_secret", "secret", true);
+ return true;
+ }},
};
nhlog::db()->info("Running migrations, this may take a while!");
|