summary refs log tree commit diff
path: root/src/encryption/Olm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/encryption/Olm.cpp')
-rw-r--r--src/encryption/Olm.cpp46
1 files changed, 32 insertions, 14 deletions
diff --git a/src/encryption/Olm.cpp b/src/encryption/Olm.cpp
index 0352d8d3..f336c2ba 100644
--- a/src/encryption/Olm.cpp
+++ b/src/encryption/Olm.cpp
@@ -629,6 +629,7 @@ 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.trusted                    = true;
         session_data.timestamp                  = QDateTime::currentMSecsSinceEpoch();
         session_data.sender_claimed_ed25519_key = olm::client()->identity_keys().ed25519;
         session_data.sender_key                 = olm::client()->identity_keys().curve25519;
@@ -753,13 +754,16 @@ create_inbound_megolm_session(const mtx::events::DeviceEvent<mtx::events::msg::R
     index.session_id = roomKey.content.session_id;
 
     try {
+        auto megolm_session =
+          olm::client()->init_inbound_group_session(roomKey.content.session_key);
+
         GroupSessionData data{};
         data.forwarding_curve25519_key_chain = {sender_key};
         data.sender_claimed_ed25519_key      = sender_ed25519;
         data.sender_key                      = sender_key;
 
-        auto megolm_session =
-          olm::client()->init_inbound_group_session(roomKey.content.session_key);
+        data.trusted = olm_inbound_group_session_is_verified(megolm_session.get());
+
         backup_session_key(index, data, megolm_session);
         cache::saveInboundMegolmSession(index, std::move(megolm_session), data);
     } catch (const lmdb::error &e) {
@@ -792,14 +796,9 @@ 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;
         data.sender_key                      = roomKey.content.sender_key;
-        // may have come from online key backup, so we can't trust it...
-        data.trusted = false;
-        // if we got it forwarded from the sender, assume it is trusted. They may still have
-        // used key backup, but it is unlikely.
-        if (roomKey.content.forwarding_curve25519_key_chain.size() == 1 &&
-            roomKey.content.forwarding_curve25519_key_chain.back() == roomKey.content.sender_key) {
-            data.trusted = true;
-        }
+        // Keys from online key backup won't have a signature, so they will be untrusted. But the
+        // original sender might send us a signed session.
+        data.trusted = olm_inbound_group_session_is_verified(megolm_session.get());
 
         backup_session_key(index, data, megolm_session);
         cache::saveInboundMegolmSession(index, std::move(megolm_session), data);
@@ -1023,6 +1022,7 @@ lookup_keybackup(const std::string &room, const std::string &session_id)
               data.forwarding_curve25519_key_chain = session.forwarding_curve25519_key_chain;
               data.sender_claimed_ed25519_key      = session.sender_claimed_keys["ed25519"];
               data.sender_key                      = session.sender_key;
+
               // online key backup can't be trusted, because anyone can upload to it.
               data.trusted = false;
 
@@ -1285,15 +1285,33 @@ decryptEvent(const MegolmSessionIndex &index,
 }
 
 crypto::Trust
-calculate_trust(const std::string &user_id, const MegolmSessionIndex &index)
+calculate_trust(const std::string &user_id,
+                const std::string &room_id,
+                const mtx::events::msg::Encrypted &event)
 {
-    auto status              = cache::client()->verificationStatus(user_id);
+    auto index               = MegolmSessionIndex(room_id, event);
     auto megolmData          = cache::client()->getMegolmSessionData(index);
-    crypto::Trust trustlevel = crypto::Trust::Unverified;
+    crypto::Trust trustlevel = crypto::Trust::MessageUnverified;
+
+    try {
+        auto session = cache::client()->getInboundMegolmSession(index);
+        if (!session) {
+            return trustlevel;
+        }
+
+        olm::client()->decrypt_group_message(session.get(), event.ciphertext);
+    } catch (const lmdb::error &e) {
+        return trustlevel;
+    } catch (const mtx::crypto::olm_exception &e) {
+        return trustlevel;
+    }
+
+    auto status = cache::client()->verificationStatus(user_id);
 
     if (megolmData && megolmData->trusted &&
-        status.verified_device_keys.count(megolmData->sender_key))
+        status.verified_device_keys.count(megolmData->sender_key)) {
         trustlevel = status.verified_device_keys.at(megolmData->sender_key);
+    }
 
     return trustlevel;
 }