diff --git a/src/Cache.cpp b/src/Cache.cpp
index 1c156104..7b6a6135 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -582,6 +582,25 @@ Cache::getOutboundMegolmSession(const std::string &room_id)
}
}
+std::optional<GroupSessionData>
+Cache::getMegolmSessionData(const MegolmSessionIndex &index)
+{
+ try {
+ using namespace mtx::crypto;
+
+ auto txn = ro_txn(env_);
+
+ std::string_view value;
+ if (megolmSessionDataDb_.get(txn, json(index).dump(), value)) {
+ return nlohmann::json::parse(value).get<GroupSessionData>();
+ }
+
+ return std::nullopt;
+ } catch (std::exception &e) {
+ nhlog::db()->error("Failed to retrieve Megolm Session Data: {}", e.what());
+ return std::nullopt;
+ }
+}
//
// OLM sessions.
//
@@ -4622,6 +4641,11 @@ inboundMegolmSessionExists(const MegolmSessionIndex &index)
{
return instance_->inboundMegolmSessionExists(index);
}
+std::optional<GroupSessionData>
+getMegolmSessionData(const MegolmSessionIndex &index)
+{
+ return instance_->getMegolmSessionData(index);
+}
//
// Olm Sessions
diff --git a/src/Cache.h b/src/Cache.h
index 2b547876..57a36d73 100644
--- a/src/Cache.h
+++ b/src/Cache.h
@@ -229,6 +229,8 @@ mtx::crypto::InboundGroupSessionPtr
getInboundMegolmSession(const MegolmSessionIndex &index);
bool
inboundMegolmSessionExists(const MegolmSessionIndex &index);
+std::optional<GroupSessionData>
+getMegolmSessionData(const MegolmSessionIndex &index);
//
// Olm Sessions
diff --git a/src/Cache_p.h b/src/Cache_p.h
index 6f208925..d1f6307d 100644
--- a/src/Cache_p.h
+++ b/src/Cache_p.h
@@ -259,6 +259,7 @@ public:
mtx::crypto::InboundGroupSessionPtr getInboundMegolmSession(
const MegolmSessionIndex &index);
bool inboundMegolmSessionExists(const MegolmSessionIndex &index);
+ std::optional<GroupSessionData> getMegolmSessionData(const MegolmSessionIndex &index);
//
// Olm Sessions
diff --git a/src/Olm.cpp b/src/Olm.cpp
index d9447031..18e2ddcf 100644
--- a/src/Olm.cpp
+++ b/src/Olm.cpp
@@ -631,8 +631,9 @@ encrypt_group_message(const std::string &room_id, const std::string &device_id,
// Saving the new megolm session.
GroupSessionData session_data{};
- session_data.message_index = 0;
- session_data.timestamp = QDateTime::currentMSecsSinceEpoch();
+ session_data.message_index = 0;
+ session_data.timestamp = QDateTime::currentMSecsSinceEpoch();
+ session_data.sender_claimed_ed25519_key = olm::client()->identity_keys().ed25519;
sendSessionTo.clear();
@@ -886,30 +887,33 @@ handle_key_request_message(const mtx::events::DeviceEvent<mtx::events::msg::KeyR
return;
}
- // Check if we were the sender of the session being requested.
- if (req.content.sender_key != olm::client()->identity_keys().curve25519) {
- nhlog::crypto()->debug("ignoring key request {} because we were not the sender: "
- "\nrequested({}) ours({})",
- req.content.request_id,
- req.content.sender_key,
- olm::client()->identity_keys().curve25519);
+ // Check if we were the sender of the session being requested (unless it is actually us
+ // requesting the session).
+ if (req.sender != http::client()->user_id().to_string() &&
+ req.content.sender_key != olm::client()->identity_keys().curve25519) {
+ nhlog::crypto()->debug(
+ "ignoring key request {} because we did not create the requested session: "
+ "\nrequested({}) ours({})",
+ req.content.request_id,
+ req.content.sender_key,
+ olm::client()->identity_keys().curve25519);
return;
}
+ // Check that the requested session_id and the one we have saved match.
+ MegolmSessionIndex index{};
+ index.room_id = req.content.room_id;
+ index.session_id = req.content.session_id;
+ index.sender_key = req.content.sender_key;
+
// Check if we have the keys for the requested session.
- auto outboundSession = cache::getOutboundMegolmSession(req.content.room_id);
- if (!outboundSession.session) {
+ auto sessionData = cache::getMegolmSessionData(index);
+ if (!sessionData) {
nhlog::crypto()->warn("requested session not found in room: {}",
req.content.room_id);
return;
}
- // Check that the requested session_id and the one we have saved match.
- MegolmSessionIndex index{};
- index.room_id = req.content.room_id;
- index.session_id = req.content.session_id;
- index.sender_key = olm::client()->identity_keys().curve25519;
-
const auto session = cache::getInboundMegolmSession(index);
if (!session) {
nhlog::crypto()->warn("No session with id {} in db", req.content.session_id);
@@ -942,11 +946,11 @@ handle_key_request_message(const mtx::events::DeviceEvent<mtx::events::msg::KeyR
bool shouldSeeKeys = false;
uint64_t minimumIndex = -1;
- if (outboundSession.data.currently.keys.count(req.sender)) {
- if (outboundSession.data.currently.keys.at(req.sender)
+ if (sessionData->currently.keys.count(req.sender)) {
+ if (sessionData->currently.keys.at(req.sender)
.deviceids.count(req.content.requesting_device_id)) {
shouldSeeKeys = true;
- minimumIndex = outboundSession.data.currently.keys.at(req.sender)
+ minimumIndex = sessionData->currently.keys.at(req.sender)
.deviceids.at(req.content.requesting_device_id);
}
}
@@ -976,8 +980,9 @@ handle_key_request_message(const mtx::events::DeviceEvent<mtx::events::msg::KeyR
forward_key.sender_key = index.sender_key;
// TODO(Nico): Figure out if this is correct
- forward_key.sender_claimed_ed25519_key = olm::client()->identity_keys().ed25519;
- forward_key.forwarding_curve25519_key_chain = {};
+ forward_key.sender_claimed_ed25519_key = sessionData->sender_claimed_ed25519_key;
+ forward_key.forwarding_curve25519_key_chain =
+ sessionData->forwarding_curve25519_key_chain;
send_megolm_key_to_device(
req.sender, req.content.requesting_device_id, forward_key);
@@ -998,6 +1003,7 @@ send_megolm_key_to_device(const std::string &user_id,
std::map<std::string, std::vector<std::string>> targets;
targets[user_id] = {device_id};
send_encrypted_to_device_messages(targets, room_key);
+ nhlog::crypto()->debug("Forwarded key to {}:{}", user_id, device_id);
}
DecryptionResult
|