mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 03:00:46 +03:00
Request full online keybackup when turning it on
This commit is contained in:
parent
2b5b6ca551
commit
ead10cd0fd
5 changed files with 113 additions and 4 deletions
|
@ -635,6 +635,9 @@ Cache::exportSessionKeys()
|
||||||
void
|
void
|
||||||
Cache::importSessionKeys(const mtx::crypto::ExportedSessionKeys &keys)
|
Cache::importSessionKeys(const mtx::crypto::ExportedSessionKeys &keys)
|
||||||
{
|
{
|
||||||
|
std::size_t importCount = 0;
|
||||||
|
|
||||||
|
auto txn = lmdb::txn::begin(env_);
|
||||||
for (const auto &s : keys.sessions) {
|
for (const auto &s : keys.sessions) {
|
||||||
MegolmSessionIndex index;
|
MegolmSessionIndex index;
|
||||||
index.room_id = s.room_id;
|
index.room_id = s.room_id;
|
||||||
|
@ -643,14 +646,49 @@ Cache::importSessionKeys(const mtx::crypto::ExportedSessionKeys &keys)
|
||||||
GroupSessionData data{};
|
GroupSessionData data{};
|
||||||
data.sender_key = s.sender_key;
|
data.sender_key = s.sender_key;
|
||||||
data.forwarding_curve25519_key_chain = s.forwarding_curve25519_key_chain;
|
data.forwarding_curve25519_key_chain = s.forwarding_curve25519_key_chain;
|
||||||
|
data.trusted = false;
|
||||||
|
|
||||||
if (s.sender_claimed_keys.count("ed25519"))
|
if (s.sender_claimed_keys.count("ed25519"))
|
||||||
data.sender_claimed_ed25519_key = s.sender_claimed_keys.at("ed25519");
|
data.sender_claimed_ed25519_key = s.sender_claimed_keys.at("ed25519");
|
||||||
|
|
||||||
auto exported_session = mtx::crypto::import_session(s.session_key);
|
try {
|
||||||
|
auto exported_session = mtx::crypto::import_session(s.session_key);
|
||||||
|
|
||||||
saveInboundMegolmSession(index, std::move(exported_session), data);
|
using namespace mtx::crypto;
|
||||||
ChatPage::instance()->receivedSessionKey(index.room_id, index.session_id);
|
const auto key = nlohmann::json(index).dump();
|
||||||
|
const auto pickled =
|
||||||
|
pickle<InboundSessionObject>(exported_session.get(), pickle_secret_);
|
||||||
|
|
||||||
|
std::string_view value;
|
||||||
|
if (inboundMegolmSessionDb_.get(txn, key, value)) {
|
||||||
|
auto oldSession =
|
||||||
|
unpickle<InboundSessionObject>(std::string(value), pickle_secret_);
|
||||||
|
if (olm_inbound_group_session_first_known_index(exported_session.get()) >=
|
||||||
|
olm_inbound_group_session_first_known_index(oldSession.get())) {
|
||||||
|
nhlog::crypto()->warn(
|
||||||
|
"Not storing inbound session with newer or equal first known index");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inboundMegolmSessionDb_.put(txn, key, pickled);
|
||||||
|
megolmSessionDataDb_.put(txn, key, nlohmann::json(data).dump());
|
||||||
|
|
||||||
|
ChatPage::instance()->receivedSessionKey(index.room_id, index.session_id);
|
||||||
|
importCount++;
|
||||||
|
} catch (const mtx::crypto::olm_exception &e) {
|
||||||
|
nhlog::crypto()->critical(
|
||||||
|
"failed to import inbound megolm session {}: {}", index.session_id, e.what());
|
||||||
|
continue;
|
||||||
|
} catch (const lmdb::error &e) {
|
||||||
|
nhlog::crypto()->critical(
|
||||||
|
"failed to save inbound megolm session {}: {}", index.session_id, e.what());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
txn.commit();
|
||||||
|
|
||||||
|
nhlog::crypto()->info("Imported {} out of {} keys", importCount, keys.sessions.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -548,6 +548,9 @@ UserSettings::setUseOnlineKeyBackup(bool useBackup)
|
||||||
useOnlineKeyBackup_ = useBackup;
|
useOnlineKeyBackup_ = useBackup;
|
||||||
emit useOnlineKeyBackupChanged(useBackup);
|
emit useOnlineKeyBackupChanged(useBackup);
|
||||||
save();
|
save();
|
||||||
|
|
||||||
|
if (useBackup)
|
||||||
|
olm::download_full_keybackup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -873,6 +873,73 @@ mark_keys_as_published()
|
||||||
cache::saveOlmAccount(olm::client()->save(cache::client()->pickleSecret()));
|
cache::saveOlmAccount(olm::client()->save(cache::client()->pickleSecret()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
download_full_keybackup()
|
||||||
|
{
|
||||||
|
if (!UserSettings::instance()->useOnlineKeyBackup()) {
|
||||||
|
// Online key backup disabled
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto backupVersion = cache::client()->backupVersion();
|
||||||
|
if (!backupVersion) {
|
||||||
|
// no trusted OKB
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace mtx::crypto;
|
||||||
|
|
||||||
|
auto decryptedSecret = cache::secret(mtx::secret_storage::secrets::megolm_backup_v1);
|
||||||
|
if (!decryptedSecret) {
|
||||||
|
// no backup key available
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto sessionDecryptionKey = to_binary_buf(base642bin(*decryptedSecret));
|
||||||
|
|
||||||
|
http::client()->room_keys(
|
||||||
|
backupVersion->version,
|
||||||
|
[sessionDecryptionKey](const mtx::responses::backup::KeysBackup &bk,
|
||||||
|
mtx::http::RequestErr err) {
|
||||||
|
if (err) {
|
||||||
|
if (err->status_code != 404)
|
||||||
|
nhlog::crypto()->error("Failed to dowload backup {}:{}: {} - {}",
|
||||||
|
mtx::errors::to_string(err->matrix_error.errcode),
|
||||||
|
err->matrix_error.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mtx::crypto::ExportedSessionKeys allKeys;
|
||||||
|
try {
|
||||||
|
for (const auto &[room, roomKey] : bk.rooms) {
|
||||||
|
for (const auto &[session_id, encSession] : roomKey.sessions) {
|
||||||
|
auto session = decrypt_session(encSession.session_data, sessionDecryptionKey);
|
||||||
|
|
||||||
|
if (session.algorithm != mtx::crypto::MEGOLM_ALGO)
|
||||||
|
// don't know this algorithm
|
||||||
|
return;
|
||||||
|
|
||||||
|
ExportedSession sess{};
|
||||||
|
sess.session_id = session_id;
|
||||||
|
sess.room_id = room;
|
||||||
|
sess.algorithm = mtx::crypto::MEGOLM_ALGO;
|
||||||
|
sess.forwarding_curve25519_key_chain =
|
||||||
|
std::move(session.forwarding_curve25519_key_chain);
|
||||||
|
sess.sender_claimed_keys = std::move(session.sender_claimed_keys);
|
||||||
|
sess.sender_key = std::move(session.sender_key);
|
||||||
|
sess.session_key = std::move(session.session_key);
|
||||||
|
allKeys.sessions.push_back(std::move(sess));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// call on UI thread
|
||||||
|
QTimer::singleShot(0, ChatPage::instance(), [keys = std::move(allKeys)] {
|
||||||
|
cache::importSessionKeys(keys);
|
||||||
|
});
|
||||||
|
} catch (const lmdb::error &e) {
|
||||||
|
nhlog::crypto()->critical("failed to save inbound megolm session: {}", e.what());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
void
|
void
|
||||||
lookup_keybackup(const std::string room, const std::string session_id)
|
lookup_keybackup(const std::string room, const std::string session_id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,6 +73,8 @@ import_inbound_megolm_session(
|
||||||
const mtx::events::DeviceEvent<mtx::events::msg::ForwardedRoomKey> &roomKey);
|
const mtx::events::DeviceEvent<mtx::events::msg::ForwardedRoomKey> &roomKey);
|
||||||
void
|
void
|
||||||
lookup_keybackup(const std::string room, const std::string session_id);
|
lookup_keybackup(const std::string room, const std::string session_id);
|
||||||
|
void
|
||||||
|
download_full_keybackup();
|
||||||
|
|
||||||
nlohmann::json
|
nlohmann::json
|
||||||
handle_pre_key_olm_message(const std::string &sender,
|
handle_pre_key_olm_message(const std::string &sender,
|
||||||
|
|
|
@ -754,7 +754,6 @@ EventStore::requestSession(const mtx::events::EncryptedEvent<mtx::events::msg::E
|
||||||
if (suppressKeyRequests)
|
if (suppressKeyRequests)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: Look in key backup
|
|
||||||
auto copy = ev;
|
auto copy = ev;
|
||||||
copy.room_id = room_id_;
|
copy.room_id = room_id_;
|
||||||
if (pending_key_requests.count(ev.content.session_id)) {
|
if (pending_key_requests.count(ev.content.session_id)) {
|
||||||
|
|
Loading…
Reference in a new issue