summary refs log tree commit diff
path: root/src/Olm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Olm.cpp')
-rw-r--r--src/Olm.cpp133
1 files changed, 130 insertions, 3 deletions
diff --git a/src/Olm.cpp b/src/Olm.cpp

index 22df3911..9dd4705e 100644 --- a/src/Olm.cpp +++ b/src/Olm.cpp
@@ -18,13 +18,13 @@ #include "UserSettingsPage.h" #include "Utils.h" -static const std::string STORAGE_SECRET_KEY("secret"); -constexpr auto MEGOLM_ALGO = "m.megolm.v1.aes-sha2"; - namespace { auto client_ = std::make_unique<mtx::crypto::OlmClient>(); std::map<std::string, std::string> request_id_to_secret_name; + +const std::string STORAGE_SECRET_KEY("secret"); +constexpr auto MEGOLM_ALGO = "m.megolm.v1.aes-sha2"; } namespace olm { @@ -221,6 +221,133 @@ handle_olm_message(const OlmMessage &msg) } else if (auto roomKey = std::get_if<DeviceEvent<msg::ForwardedRoomKey>>( &device_event)) { import_inbound_megolm_session(*roomKey); + } else if (auto e = + std::get_if<DeviceEvent<msg::SecretSend>>(&device_event)) { + auto local_user = http::client()->user_id(); + + if (msg.sender != local_user.to_string()) + continue; + + auto secret_name = + request_id_to_secret_name.find(e->content.request_id); + + if (secret_name != request_id_to_secret_name.end()) { + nhlog::crypto()->info("Received secret: {}", + secret_name->second); + + mtx::events::msg::SecretRequest secretRequest{}; + secretRequest.action = + mtx::events::msg::RequestAction::Cancellation; + secretRequest.requesting_device_id = + http::client()->device_id(); + secretRequest.request_id = e->content.request_id; + + auto verificationStatus = + cache::verificationStatus(local_user.to_string()); + + if (!verificationStatus) + continue; + + auto deviceKeys = cache::userKeys(local_user.to_string()); + std::string sender_device_id; + if (deviceKeys) { + for (auto &[dev, key] : deviceKeys->device_keys) { + if (key.keys["curve25519:" + dev] == + msg.sender_key) { + sender_device_id = dev; + break; + } + } + } + + std::map< + mtx::identifiers::User, + std::map<std::string, mtx::events::msg::SecretRequest>> + body; + + for (const auto &dev : + verificationStatus->verified_devices) { + if (dev != secretRequest.requesting_device_id && + dev != sender_device_id) + body[local_user][dev] = secretRequest; + } + + http::client() + ->send_to_device<mtx::events::msg::SecretRequest>( + http::client()->generate_txn_id(), + body, + [name = + secret_name->second](mtx::http::RequestErr err) { + if (err) { + nhlog::net()->error( + "Failed to send request cancellation " + "for secrect " + "'{}'", + name); + return; + } + }); + + cache::client()->storeSecret(secret_name->second, + e->content.secret); + + request_id_to_secret_name.erase(secret_name); + } + + } else if (auto e = + std::get_if<DeviceEvent<msg::SecretRequest>>(&device_event)) { + if (e->content.action != mtx::events::msg::RequestAction::Request) + continue; + + auto local_user = http::client()->user_id(); + + if (msg.sender != local_user.to_string()) + continue; + + auto verificationStatus = + cache::verificationStatus(local_user.to_string()); + + if (!verificationStatus) + continue; + + auto deviceKeys = cache::userKeys(local_user.to_string()); + if (!deviceKeys) + continue; + + for (auto &[dev, key] : deviceKeys->device_keys) { + if (key.keys["curve25519:" + dev] == msg.sender_key) { + if (std::find( + verificationStatus->verified_devices.begin(), + verificationStatus->verified_devices.end(), + dev) == + verificationStatus->verified_devices.end()) + break; + + // this is a verified device + mtx::events::DeviceEvent< + mtx::events::msg::SecretSend> + secretSend; + secretSend.type = EventType::SecretSend; + secretSend.content.request_id = + e->content.request_id; + + auto secret = + cache::client()->secret(e->content.name); + if (!secret) + break; + + secretSend.content.secret = secret.value(); + + send_encrypted_to_device_messages( + {{local_user.to_string(), {{dev}}}}, secretSend); + + nhlog::net()->info("Sent secret to ({},{})", + local_user.to_string(), + dev); + + break; + } + } } return;