summary refs log tree commit diff
path: root/src/Olm.cpp
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2021-08-17 03:23:51 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2021-08-17 03:24:12 +0200
commit56db0dbc7d0878ce1621a4dc998024d470d200a5 (patch)
treefc941d540e26a6d2b5ae9ae67d04944d3f66c3a0 /src/Olm.cpp
parentUpdate translations (diff)
downloadnheko-56db0dbc7d0878ce1621a4dc998024d470d200a5.tar.xz
Allow downloading keys from key backup
Diffstat (limited to 'src/Olm.cpp')
-rw-r--r--src/Olm.cpp104
1 files changed, 101 insertions, 3 deletions
diff --git a/src/Olm.cpp b/src/Olm.cpp

index 2c9ac5a3..05eefce4 100644 --- a/src/Olm.cpp +++ b/src/Olm.cpp
@@ -833,6 +833,8 @@ import_inbound_megolm_session( data.forwarding_curve25519_key_chain = roomKey.content.forwarding_curve25519_key_chain; data.sender_claimed_ed25519_key = roomKey.content.sender_claimed_ed25519_key; + // may have come from online key backup, so we can't trust it... + data.trusted = false; cache::saveInboundMegolmSession(index, std::move(megolm_session), data); } catch (const lmdb::error &e) { @@ -857,6 +859,97 @@ mark_keys_as_published() } void +lookup_keybackup(const std::string room, const std::string session_id) +{ + 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, + room, + session_id, + [room, session_id, sessionDecryptionKey](const mtx::responses::backup::SessionBackup &bk, + mtx::http::RequestErr err) { + if (err) { + if (err->status_code != 404) + nhlog::crypto()->error( + "Failed to dowload key {}:{}: {} - {}", + room, + session_id, + mtx::errors::to_string(err->matrix_error.errcode), + err->matrix_error.error); + return; + } + try { + auto session = decrypt_session(bk.session_data, sessionDecryptionKey); + + if (session.algorithm != mtx::crypto::MEGOLM_ALGO) + // don't know this algorithm + return; + + MegolmSessionIndex index; + index.room_id = room; + index.session_id = session_id; + index.sender_key = session.sender_key; + + GroupSessionData data{}; + data.forwarding_curve25519_key_chain = + session.forwarding_curve25519_key_chain; + data.sender_claimed_ed25519_key = session.sender_claimed_keys["ed25519"]; + // online key backup can't be trusted, because anyone can upload to it. + data.trusted = false; + + auto megolm_session = + olm::client()->import_inbound_group_session(session.session_key); + + if (!cache::inboundMegolmSessionExists(index) || + olm_inbound_group_session_first_known_index(megolm_session.get()) < + olm_inbound_group_session_first_known_index( + cache::getInboundMegolmSession(index).get())) { + cache::saveInboundMegolmSession( + index, std::move(megolm_session), data); + + nhlog::crypto()->info("imported inbound megolm session " + "from key backup ({}, {})", + room, + session_id); + + // call on UI thread + QTimer::singleShot(0, ChatPage::instance(), [index] { + ChatPage::instance()->receivedSessionKey( + index.room_id, index.session_id); + }); + } + } catch (const lmdb::error &e) { + nhlog::crypto()->critical("failed to save inbound megolm session: {}", + e.what()); + return; + } catch (const mtx::crypto::olm_exception &e) { + nhlog::crypto()->critical("failed to import inbound megolm session: {}", + e.what()); + return; + } + }); +} + +void send_key_request_for(mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> e, const std::string &request_id, bool cancel) @@ -898,6 +991,8 @@ send_key_request_for(mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> e, e.sender, e.content.device_id); }); + + // http::client()->room_keys } void @@ -1095,12 +1190,15 @@ decryptEvent(const MegolmSessionIndex &index, } crypto::Trust -calculate_trust(const std::string &user_id, const std::string &curve25519) +calculate_trust(const std::string &user_id, const MegolmSessionIndex &index) { auto status = cache::client()->verificationStatus(user_id); + auto megolmData = cache::client()->getMegolmSessionData(index); crypto::Trust trustlevel = crypto::Trust::Unverified; - if (status.verified_device_keys.count(curve25519)) - trustlevel = status.verified_device_keys.at(curve25519); + + if (megolmData && megolmData->trusted && + status.verified_device_keys.count(index.sender_key)) + trustlevel = status.verified_device_keys.at(index.sender_key); return trustlevel; }