diff options
author | Alexey Rusakov <Kitsune-Ral@users.sf.net> | 2022-04-16 22:23:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-16 22:23:53 +0200 |
commit | 87e8d6d6ef325f176a7d3b5da441569f9b24c847 (patch) | |
tree | 671133c8974569b182a27d82d627929addeb5ad6 | |
parent | fc3ad90a054e3c674127a0cdd385ddbb98cf2010 (diff) | |
parent | c0c4cd014718fdb54ee691ccbdab46981e15d25f (diff) | |
download | libquotient-87e8d6d6ef325f176a7d3b5da441569f9b24c847.tar.gz libquotient-87e8d6d6ef325f176a7d3b5da441569f9b24c847.zip |
Merge pull request #544 from TobiasFella/checkedkey
Check edKey when receiving an olm message and prepare for MSC 3700
-rw-r--r-- | lib/connection.cpp | 120 | ||||
-rw-r--r-- | lib/connection.h | 6 | ||||
-rw-r--r-- | lib/database.cpp | 33 | ||||
-rw-r--r-- | lib/database.h | 7 | ||||
-rw-r--r-- | lib/e2ee/qolminboundsession.cpp | 18 | ||||
-rw-r--r-- | lib/e2ee/qolminboundsession.h | 11 | ||||
-rw-r--r-- | lib/room.cpp | 46 | ||||
-rw-r--r-- | lib/room.h | 2 |
8 files changed, 175 insertions, 68 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp index 45888bcb..d99ab64d 100644 --- a/lib/connection.cpp +++ b/lib/connection.cpp @@ -118,6 +118,8 @@ public: PicklingMode picklingMode = Unencrypted {}; Database *database = nullptr; QHash<QString, int> oneTimeKeysCount; + std::vector<std::unique_ptr<EncryptedEvent>> pendingEncryptedEvents; + void handleEncryptedToDeviceEvent(const EncryptedEvent& event); // A map from SenderKey to vector of InboundSession UnorderedMap<QString, std::vector<QOlmSessionPtr>> olmSessions; @@ -218,7 +220,7 @@ public: } q->database()->saveOlmSession(senderKey, session->sessionId(), std::get<QByteArray>(pickleResult), QDateTime::currentDateTime()); } - QString sessionDecryptPrekey(const QOlmMessage& message, const QString &senderKey, std::unique_ptr<QOlmAccount>& olmAccount) + std::pair<QString, QString> sessionDecryptPrekey(const QOlmMessage& message, const QString &senderKey, std::unique_ptr<QOlmAccount>& olmAccount) { Q_ASSERT(message.type() == QOlmMessage::PreKey); for(auto& session : olmSessions[senderKey]) { @@ -228,7 +230,7 @@ public: const auto result = session->decrypt(message); if(std::holds_alternative<QString>(result)) { q->database()->setOlmSessionLastReceived(QString(session->sessionId()), QDateTime::currentDateTime()); - return std::get<QString>(result); + return { std::get<QString>(result), session->sessionId() }; } else { qCDebug(E2EE) << "Failed to decrypt prekey message"; return {}; @@ -247,47 +249,53 @@ public: qWarning(E2EE) << "Failed to remove one time key for session" << newSession->sessionId(); } const auto result = newSession->decrypt(message); + QString sessionId = newSession->sessionId(); saveSession(newSession, senderKey); olmSessions[senderKey].push_back(std::move(newSession)); if(std::holds_alternative<QString>(result)) { - return std::get<QString>(result); + return { std::get<QString>(result), sessionId }; } else { qCDebug(E2EE) << "Failed to decrypt prekey message with new session"; return {}; } } - QString sessionDecryptGeneral(const QOlmMessage& message, const QString &senderKey) + std::pair<QString, QString> sessionDecryptGeneral(const QOlmMessage& message, const QString &senderKey) { Q_ASSERT(message.type() == QOlmMessage::General); for(auto& session : olmSessions[senderKey]) { const auto result = session->decrypt(message); if(std::holds_alternative<QString>(result)) { q->database()->setOlmSessionLastReceived(QString(session->sessionId()), QDateTime::currentDateTime()); - return std::get<QString>(result); + return { std::get<QString>(result), session->sessionId() }; } } qCWarning(E2EE) << "Failed to decrypt message"; return {}; } - QString sessionDecryptMessage( + std::pair<QString, QString> sessionDecryptMessage( const QJsonObject& personalCipherObject, const QByteArray& senderKey, std::unique_ptr<QOlmAccount>& account) { QString decrypted; + QString olmSessionId; int type = personalCipherObject.value(TypeKeyL).toInt(-1); QByteArray body = personalCipherObject.value(BodyKeyL).toString().toLatin1(); if (type == QOlmMessage::PreKey) { QOlmMessage preKeyMessage(body, QOlmMessage::PreKey); - decrypted = sessionDecryptPrekey(preKeyMessage, senderKey, account); + auto result = sessionDecryptPrekey(preKeyMessage, senderKey, account); + decrypted = result.first; + olmSessionId = result.second; } else if (type == QOlmMessage::General) { QOlmMessage message(body, QOlmMessage::General); - decrypted = sessionDecryptGeneral(message, senderKey); + auto result = sessionDecryptGeneral(message, senderKey); + decrypted = result.first; + olmSessionId = result.second; } - return decrypted; + return { decrypted, olmSessionId }; } #endif - EventPtr sessionDecryptMessage(const EncryptedEvent& encryptedEvent) + std::pair<EventPtr, QString> sessionDecryptMessage(const EncryptedEvent& encryptedEvent) { #ifndef Quotient_E2EE_ENABLED qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off."; @@ -303,7 +311,7 @@ public: qCDebug(E2EE) << "Encrypted event is not for the current device"; return {}; } - const auto decrypted = sessionDecryptMessage( + const auto [decrypted, olmSessionId] = sessionDecryptMessage( personalCipherObject, encryptedEvent.senderKey().toLatin1(), olmAccount); if (decrypted.isEmpty()) { qCDebug(E2EE) << "Problem with new session from senderKey:" @@ -322,9 +330,17 @@ public: << "in Olm plaintext"; return {}; } - //TODO make this do the check mentioned in the E2EE Implementation guide instead - if (decryptedEvent->fullJson()["keys"]["ed25519"].toString().isEmpty()) { - qCDebug(E2EE) << "Event does not contain an ed25519 key"; + + auto query = database->prepareQuery(QStringLiteral("SELECT edKey FROM tracked_devices WHERE curveKey=:curveKey;")); + query.bindValue(":curveKey", encryptedEvent.contentJson()["sender_key"].toString()); + database->execute(query); + if (!query.next()) { + qCWarning(E2EE) << "Received olm message from unknown device" << encryptedEvent.contentJson()["sender_key"].toString(); + return {}; + } + auto edKey = decryptedEvent->fullJson()["keys"]["ed25519"].toString(); + if (edKey.isEmpty() || query.value(QStringLiteral("edKey")).toString() != edKey) { + qCDebug(E2EE) << "Received olm message with invalid ed key"; return {}; } @@ -346,7 +362,7 @@ public: return {}; } - return std::move(decryptedEvent); + return { std::move(decryptedEvent), olmSessionId }; #endif // Quotient_E2EE_ENABLED } #ifdef Quotient_E2EE_ENABLED @@ -929,30 +945,46 @@ void Connection::Private::consumeToDeviceEvents(Events&& toDeviceEvents) qCDebug(E2EE) << "Unsupported algorithm" << event.id() << "for event" << event.algorithm(); return; } - const auto decryptedEvent = sessionDecryptMessage(event); - if(!decryptedEvent) { - qCWarning(E2EE) << "Failed to decrypt event" << event.id(); + if (q->isKnownCurveKey(event.senderId(), event.senderKey())) { + handleEncryptedToDeviceEvent(event); return; } - - switchOnType(*decryptedEvent, - [this, senderKey = event.senderKey()](const RoomKeyEvent& roomKeyEvent) { - if (auto* detectedRoom = q->room(roomKeyEvent.roomId())) { - detectedRoom->handleRoomKeyEvent(roomKeyEvent, senderKey); - } else { - qCDebug(E2EE) << "Encrypted event room id" << roomKeyEvent.roomId() - << "is not found at the connection" << q->objectName(); - } - }, - [](const Event& evt) { - qCDebug(E2EE) << "Skipping encrypted to_device event, type" - << evt.matrixType(); - }); + trackedUsers += event.senderId(); + outdatedUsers += event.senderId(); + encryptionUpdateRequired = true; + pendingEncryptedEvents.push_back(std::make_unique<EncryptedEvent>(event.fullJson())); + }, [](const Event& e){ + // Unhandled }); } #endif } +#ifdef Quotient_E2EE_ENABLED +void Connection::Private::handleEncryptedToDeviceEvent(const EncryptedEvent& event) +{ + const auto [decryptedEvent, olmSessionId] = sessionDecryptMessage(event); + if(!decryptedEvent) { + qCWarning(E2EE) << "Failed to decrypt event" << event.id(); + return; + } + + switchOnType(*decryptedEvent, + [this, senderKey = event.senderKey(), &event, olmSessionId = olmSessionId](const RoomKeyEvent& roomKeyEvent) { + if (auto* detectedRoom = q->room(roomKeyEvent.roomId())) { + detectedRoom->handleRoomKeyEvent(roomKeyEvent, event.senderId(), olmSessionId); + } else { + qCDebug(E2EE) << "Encrypted event room id" << roomKeyEvent.roomId() + << "is not found at the connection" << q->objectName(); + } + }, + [](const Event& evt) { + qCDebug(E2EE) << "Skipping encrypted to_device event, type" + << evt.matrixType(); + }); +} +#endif + void Connection::Private::consumeDevicesList(DevicesList&& devicesList) { #ifdef Quotient_E2EE_ENABLED @@ -2038,6 +2070,15 @@ void Connection::Private::loadOutdatedUserDevices() outdatedUsers -= user; } saveDevicesList(); + + for(size_t i = 0; i < pendingEncryptedEvents.size();) { + if (q->isKnownCurveKey(pendingEncryptedEvents[i]->fullJson()[SenderKeyL].toString(), pendingEncryptedEvents[i]->contentJson()["sender_key"].toString())) { + handleEncryptedToDeviceEvent(*(pendingEncryptedEvents[i].get())); + pendingEncryptedEvents.erase(pendingEncryptedEvents.begin() + i); + } else { + i++; + } + } }); } @@ -2159,14 +2200,14 @@ Database* Connection::database() return d->database; } -UnorderedMap<std::pair<QString, QString>, QOlmInboundGroupSessionPtr> Connection::loadRoomMegolmSessions(Room* room) +UnorderedMap<QString, QOlmInboundGroupSessionPtr> Connection::loadRoomMegolmSessions(Room* room) { return database()->loadMegolmSessions(room->id(), picklingMode()); } -void Connection::saveMegolmSession(Room* room, const QString& senderKey, QOlmInboundGroupSession* session, const QString& ed25519Key) +void Connection::saveMegolmSession(Room* room, QOlmInboundGroupSession* session) { - database()->saveMegolmSession(room->id(), senderKey, session->sessionId(), ed25519Key, session->pickle(picklingMode())); + database()->saveMegolmSession(room->id(), session->sessionId(), session->pickle(picklingMode()), session->senderId(), session->olmSessionId()); } QStringList Connection::devicesForUser(User* user) const @@ -2184,4 +2225,13 @@ QString Connection::edKeyForUserDevice(const QString& user, const QString& devic return d->deviceKeys[user][device].keys["ed25519:" % device]; } +bool Connection::isKnownCurveKey(const QString& user, const QString& curveKey) +{ + auto query = database()->prepareQuery(QStringLiteral("SELECT * FROM tracked_devices WHERE matrixId=:matrixId AND curveKey=:curveKey")); + query.bindValue(":matrixId", user); + query.bindValue(":curveKey", curveKey); + database()->execute(query); + return query.next(); +} + #endif diff --git a/lib/connection.h b/lib/connection.h index a4986b06..29731593 100644 --- a/lib/connection.h +++ b/lib/connection.h @@ -317,8 +317,8 @@ public: #ifdef Quotient_E2EE_ENABLED QOlmAccount* olmAccount() const; Database* database(); - UnorderedMap<std::pair<QString, QString>, QOlmInboundGroupSessionPtr> loadRoomMegolmSessions(Room* room); - void saveMegolmSession(Room* room, const QString& senderKey, QOlmInboundGroupSession* session, const QString& ed25519Key); + UnorderedMap<QString, QOlmInboundGroupSessionPtr> loadRoomMegolmSessions(Room* room); + void saveMegolmSession(Room* room, QOlmInboundGroupSession* session); #endif // Quotient_E2EE_ENABLED Q_INVOKABLE Quotient::SyncJob* syncJob() const; Q_INVOKABLE int millisToReconnect() const; @@ -684,6 +684,7 @@ public Q_SLOTS: QStringList devicesForUser(User* user) const; QString curveKeyForUserDevice(const QString &user, const QString& device) const; QString edKeyForUserDevice(const QString& user, const QString& device) const; + bool isKnownCurveKey(const QString& user, const QString& curveKey); #endif Q_SIGNALS: /// \brief Initial server resolution has failed @@ -841,6 +842,7 @@ Q_SIGNALS: void cacheStateChanged(); void lazyLoadingChanged(); void turnServersChanged(const QJsonObject& servers); + void devicesListLoaded(); protected: /** diff --git a/lib/database.cpp b/lib/database.cpp index 70dc1b9b..3189b3f1 100644 --- a/lib/database.cpp +++ b/lib/database.cpp @@ -29,6 +29,7 @@ Database::Database(const QString& matrixId, const QString& deviceId, QObject* pa switch(version()) { case 0: migrateTo1(); case 1: migrateTo2(); + case 2: migrateTo3(); } } @@ -99,6 +100,7 @@ void Database::migrateTo2() { qCDebug(DATABASE) << "Migrating database to version 2"; transaction(); + //TODO remove this column again - we don't need it after all execute(QStringLiteral("ALTER TABLE inbound_megolm_sessions ADD ed25519Key TEXT")); execute(QStringLiteral("ALTER TABLE olm_sessions ADD lastReceived TEXT")); @@ -111,6 +113,20 @@ void Database::migrateTo2() commit(); } +void Database::migrateTo3() +{ + qCDebug(DATABASE) << "Migrating database to version 3"; + transaction(); + + execute(QStringLiteral("CREATE TABLE inbound_megolm_sessions_temp AS SELECT roomId, sessionId, pickle FROM inbound_megolm_sessions;")); + execute(QStringLiteral("DROP TABLE inbound_megolm_sessions;")); + execute(QStringLiteral("ALTER TABLE inbound_megolm_sessions_temp RENAME TO inbound_megolm_sessions;")); + execute(QStringLiteral("ALTER TABLE inbound_megolm_sessions ADD olmSessionId TEXT;")); + execute(QStringLiteral("ALTER TABLE inbound_megolm_sessions ADD senderId TEXT;")); + execute(QStringLiteral("PRAGMA user_version = 3;")); + commit(); +} + QByteArray Database::accountPickle() { auto query = prepareQuery(QStringLiteral("SELECT pickle FROM accounts;")); @@ -178,33 +194,36 @@ UnorderedMap<QString, std::vector<QOlmSessionPtr>> Database::loadOlmSessions(con return sessions; } -UnorderedMap<std::pair<QString, QString>, QOlmInboundGroupSessionPtr> Database::loadMegolmSessions(const QString& roomId, const PicklingMode& picklingMode) +UnorderedMap<QString, QOlmInboundGroupSessionPtr> Database::loadMegolmSessions(const QString& roomId, const PicklingMode& picklingMode) { auto query = prepareQuery(QStringLiteral("SELECT * FROM inbound_megolm_sessions WHERE roomId=:roomId;")); query.bindValue(":roomId", roomId); transaction(); execute(query); commit(); - UnorderedMap<std::pair<QString, QString>, QOlmInboundGroupSessionPtr> sessions; + UnorderedMap<QString, QOlmInboundGroupSessionPtr> sessions; while (query.next()) { auto session = QOlmInboundGroupSession::unpickle(query.value("pickle").toByteArray(), picklingMode); if (std::holds_alternative<QOlmError>(session)) { qCWarning(E2EE) << "Failed to unpickle megolm session"; continue; } - sessions[{query.value("senderKey").toString(), query.value("sessionId").toString()}] = std::move(std::get<QOlmInboundGroupSessionPtr>(session)); + + sessions[query.value("sessionId").toString()] = std::move(std::get<QOlmInboundGroupSessionPtr>(session)); + sessions[query.value("sessionId").toString()]->setOlmSessionId(query.value("olmSessionId").toString()); + sessions[query.value("sessionId").toString()]->setSenderId(query.value("senderId").toString()); } return sessions; } -void Database::saveMegolmSession(const QString& roomId, const QString& senderKey, const QString& sessionId, const QString& ed25519Key, const QByteArray& pickle) +void Database::saveMegolmSession(const QString& roomId, const QString& sessionId, const QByteArray& pickle, const QString& senderId, const QString& olmSessionId) { - auto query = prepareQuery(QStringLiteral("INSERT INTO inbound_megolm_sessions(roomId, senderKey, sessionId, ed25519Key, pickle) VALUES(:roomId, :senderKey, :sessionId, :ed25519Key, :pickle);")); + auto query = prepareQuery(QStringLiteral("INSERT INTO inbound_megolm_sessions(roomId, sessionId, pickle, senderId, olmSessionId) VALUES(:roomId, :sessionId, :pickle, :senderId, :olmSessionId);")); query.bindValue(":roomId", roomId); - query.bindValue(":senderKey", senderKey); query.bindValue(":sessionId", sessionId); - query.bindValue(":ed25519Key", ed25519Key); query.bindValue(":pickle", pickle); + query.bindValue(":senderId", senderId); + query.bindValue(":olmSessionId", olmSessionId); transaction(); execute(query); commit(); diff --git a/lib/database.h b/lib/database.h index cf241dbc..08fe49f3 100644 --- a/lib/database.h +++ b/lib/database.h @@ -8,7 +8,6 @@ #include <QtCore/QVector> #include "e2ee/e2ee.h" - namespace Quotient { class QUOTIENT_API Database : public QObject { @@ -29,8 +28,8 @@ public: void clear(); void saveOlmSession(const QString& senderKey, const QString& sessionId, const QByteArray &pickle, const QDateTime& timestamp); UnorderedMap<QString, std::vector<QOlmSessionPtr>> loadOlmSessions(const PicklingMode& picklingMode); - UnorderedMap<std::pair<QString, QString>, QOlmInboundGroupSessionPtr> loadMegolmSessions(const QString& roomId, const PicklingMode& picklingMode); - void saveMegolmSession(const QString& roomId, const QString& senderKey, const QString& sessionKey, const QString& ed25519Key, const QByteArray& pickle); + UnorderedMap<QString, QOlmInboundGroupSessionPtr> loadMegolmSessions(const QString& roomId, const PicklingMode& picklingMode); + void saveMegolmSession(const QString& roomId, const QString& sessionId, const QByteArray& pickle, const QString& senderId, const QString& olmSessionId); void addGroupSessionIndexRecord(const QString& roomId, const QString& sessionId, uint32_t index, const QString& eventId, qint64 ts); std::pair<QString, qint64> groupSessionIndexRecord(const QString& roomId, const QString& sessionId, qint64 index); void clearRoomData(const QString& roomId); @@ -39,6 +38,8 @@ public: private: void migrateTo1(); void migrateTo2(); + void migrateTo3(); + QString m_matrixId; }; } diff --git a/lib/e2ee/qolminboundsession.cpp b/lib/e2ee/qolminboundsession.cpp index 2e9cc716..60d871ef 100644 --- a/lib/e2ee/qolminboundsession.cpp +++ b/lib/e2ee/qolminboundsession.cpp @@ -149,3 +149,21 @@ bool QOlmInboundGroupSession::isVerified() const { return olm_inbound_group_session_is_verified(m_groupSession) != 0; } + +QString QOlmInboundGroupSession::olmSessionId() const +{ + return m_olmSessionId; +} +void QOlmInboundGroupSession::setOlmSessionId(const QString& olmSessionId) +{ + m_olmSessionId = olmSessionId; +} + +QString QOlmInboundGroupSession::senderId() const +{ + return m_senderId; +} +void QOlmInboundGroupSession::setSenderId(const QString& senderId) +{ + m_senderId = senderId; +} diff --git a/lib/e2ee/qolminboundsession.h b/lib/e2ee/qolminboundsession.h index 437f753d..32112b97 100644 --- a/lib/e2ee/qolminboundsession.h +++ b/lib/e2ee/qolminboundsession.h @@ -41,9 +41,20 @@ public: QByteArray sessionId() const; bool isVerified() const; + //! The olm session that this session was received from. + //! Required to get the device this session is from. + QString olmSessionId() const; + void setOlmSessionId(const QString& setOlmSessionId); + + //! The sender of this session. + QString senderId() const; + void setSenderId(const QString& senderId); + QOlmInboundGroupSession(OlmInboundGroupSession* session); private: OlmInboundGroupSession* m_groupSession; + QString m_olmSessionId; + QString m_senderId; }; using QOlmInboundGroupSessionPtr = std::unique_ptr<QOlmInboundGroupSession>; diff --git a/lib/room.cpp b/lib/room.cpp index 88aa1d07..183e242a 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -337,27 +337,25 @@ public: bool isLocalUser(const User* u) const { return u == q->localUser(); } #ifdef Quotient_E2EE_ENABLED - // A map from (senderKey, sessionId) to InboundGroupSession - UnorderedMap<std::pair<QString, QString>, QOlmInboundGroupSessionPtr> groupSessions; + UnorderedMap<QString, QOlmInboundGroupSessionPtr> groupSessions; - bool addInboundGroupSession(QString senderKey, QString sessionId, - QString sessionKey, QString ed25519Key) + bool addInboundGroupSession(QString sessionId, QString sessionKey, const QString& senderId, const QString& olmSessionId) { - if (groupSessions.find({senderKey, sessionId}) != groupSessions.end()) { - qCWarning(E2EE) << "Inbound Megolm session" << sessionId - << "with senderKey" << senderKey << "already exists"; + if (groupSessions.find(sessionId) != groupSessions.end()) { + qCWarning(E2EE) << "Inbound Megolm session" << sessionId << "already exists"; return false; } auto megolmSession = QOlmInboundGroupSession::create(sessionKey.toLatin1()); if (megolmSession->sessionId() != sessionId) { - qCWarning(E2EE) << "Session ID mismatch in m.room_key event sent " - "from sender with key" << senderKey; + qCWarning(E2EE) << "Session ID mismatch in m.room_key event"; return false; } + megolmSession->setSenderId(senderId); + megolmSession->setOlmSessionId(olmSessionId); qCWarning(E2EE) << "Adding inbound session"; - connection->saveMegolmSession(q, senderKey, megolmSession.get(), ed25519Key); - groupSessions[{senderKey, sessionId}] = std::move(megolmSession); + connection->saveMegolmSession(q, megolmSession.get()); + groupSessions[sessionId] = std::move(megolmSession); return true; } @@ -365,9 +363,10 @@ public: const QString& senderKey, const QString& sessionId, const QString& eventId, - QDateTime timestamp) + QDateTime timestamp, + const QString& senderId) { - auto groupSessionIt = groupSessions.find({ senderKey, sessionId }); + auto groupSessionIt = groupSessions.find(sessionId); if (groupSessionIt == groupSessions.end()) { // qCWarning(E2EE) << "Unable to decrypt event" << eventId // << "The sender's device has not sent us the keys for " @@ -375,6 +374,10 @@ public: return QString(); } auto& senderSession = groupSessionIt->second; + if (senderSession->senderId() != senderId) { + qCWarning(E2EE) << "Sender from event does not match sender from session"; + return {}; + } auto decryptResult = senderSession->decrypt(cipher); if(std::holds_alternative<QOlmError>(decryptResult)) { qCWarning(E2EE) << "Unable to decrypt event" << eventId @@ -1482,7 +1485,7 @@ RoomEventPtr Room::decryptMessage(const EncryptedEvent& encryptedEvent) QString decrypted = d->groupSessionDecryptMessage( encryptedEvent.ciphertext(), encryptedEvent.senderKey(), encryptedEvent.sessionId(), encryptedEvent.id(), - encryptedEvent.originTimestamp()); + encryptedEvent.originTimestamp(), encryptedEvent.senderId()); if (decrypted.isEmpty()) { // qCWarning(E2EE) << "Encrypted message is empty"; return {}; @@ -1497,22 +1500,25 @@ RoomEventPtr Room::decryptMessage(const EncryptedEvent& encryptedEvent) } void Room::handleRoomKeyEvent(const RoomKeyEvent& roomKeyEvent, - const QString& senderKey) + const QString& senderId, + const QString& olmSessionId) { #ifndef Quotient_E2EE_ENABLED Q_UNUSED(roomKeyEvent) - Q_UNUSED(senderKey) + Q_UNUSED(senderId) + Q_UNUSED(olmSessionId) qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off."; #else // Quotient_E2EE_ENABLED if (roomKeyEvent.algorithm() != MegolmV1AesSha2AlgoKey) { qCWarning(E2EE) << "Ignoring unsupported algorithm" << roomKeyEvent.algorithm() << "in m.room_key event"; } - if (d->addInboundGroupSession(senderKey, roomKeyEvent.sessionId(), - roomKeyEvent.sessionKey(), roomKeyEvent.fullJson()["keys"]["ed25519"].toString())) { + if (d->addInboundGroupSession(roomKeyEvent.sessionId(), + roomKeyEvent.sessionKey(), senderId, olmSessionId)) { qCWarning(E2EE) << "added new inboundGroupSession:" << d->groupSessions.size(); - for (const auto& eventId : d->undecryptedEvents[roomKeyEvent.sessionId()]) { + auto undecryptedEvents = d->undecryptedEvents[roomKeyEvent.sessionId()]; + for (const auto& eventId : undecryptedEvents) { const auto pIdx = d->eventsIndex.constFind(eventId); if (pIdx == d->eventsIndex.cend()) continue; @@ -1524,7 +1530,7 @@ void Room::handleRoomKeyEvent(const RoomKeyEvent& roomKeyEvent, auto& decryptedEvent = *decrypted; auto oldEvent = ti.replaceEvent(std::move(decrypted)); decryptedEvent.setOriginalEvent(std::move(oldEvent)); - emit replacedEvent(ti.event(), decrypted->originalEvent()); + emit replacedEvent(ti.event(), decryptedEvent.originalEvent()); d->undecryptedEvents[roomKeyEvent.sessionId()] -= eventId; } } @@ -277,7 +277,7 @@ public: int timelineSize() const; bool usesEncryption() const; RoomEventPtr decryptMessage(const EncryptedEvent& encryptedEvent); - void handleRoomKeyEvent(const RoomKeyEvent& roomKeyEvent, const QString& senderKey); + void handleRoomKeyEvent(const RoomKeyEvent& roomKeyEvent, const QString& senderId, const QString& olmSessionId); int joinedCount() const; int invitedCount() const; int totalMemberCount() const; |