aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/connection.cpp13
-rw-r--r--lib/connection.h2
-rw-r--r--lib/database.cpp37
-rw-r--r--lib/database.h6
-rw-r--r--lib/room.cpp6
5 files changed, 51 insertions, 13 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index ae8532c3..45888bcb 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -216,7 +216,7 @@ public:
qCWarning(E2EE) << "Failed to pickle olm session. Error" << std::get<QOlmError>(pickleResult);
return;
}
- q->database()->saveOlmSession(senderKey, session->sessionId(), std::get<QByteArray>(pickleResult));
+ 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)
{
@@ -227,6 +227,7 @@ public:
qCDebug(E2EE) << "Found inbound session";
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);
} else {
qCDebug(E2EE) << "Failed to decrypt prekey message";
@@ -261,6 +262,7 @@ public:
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);
}
}
@@ -320,6 +322,11 @@ 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";
+ return {};
+ }
// TODO: keys to constants
const auto decryptedEventObject = decryptedEvent->fullJson();
@@ -2157,9 +2164,9 @@ UnorderedMap<std::pair<QString, QString>, QOlmInboundGroupSessionPtr> Connection
return database()->loadMegolmSessions(room->id(), picklingMode());
}
-void Connection::saveMegolmSession(Room* room, const QString& senderKey, QOlmInboundGroupSession* session)
+void Connection::saveMegolmSession(Room* room, const QString& senderKey, QOlmInboundGroupSession* session, const QString& ed25519Key)
{
- database()->saveMegolmSession(room->id(), senderKey, session->sessionId(), session->pickle(picklingMode()));
+ database()->saveMegolmSession(room->id(), senderKey, session->sessionId(), ed25519Key, session->pickle(picklingMode()));
}
QStringList Connection::devicesForUser(User* user) const
diff --git a/lib/connection.h b/lib/connection.h
index 4a475319..a4986b06 100644
--- a/lib/connection.h
+++ b/lib/connection.h
@@ -318,7 +318,7 @@ public:
QOlmAccount* olmAccount() const;
Database* database();
UnorderedMap<std::pair<QString, QString>, QOlmInboundGroupSessionPtr> loadRoomMegolmSessions(Room* room);
- void saveMegolmSession(Room* room, const QString& senderKey, QOlmInboundGroupSession* session);
+ void saveMegolmSession(Room* room, const QString& senderKey, QOlmInboundGroupSession* session, const QString& ed25519Key);
#endif // Quotient_E2EE_ENABLED
Q_INVOKABLE Quotient::SyncJob* syncJob() const;
Q_INVOKABLE int millisToReconnect() const;
diff --git a/lib/database.cpp b/lib/database.cpp
index 84c93046..70dc1b9b 100644
--- a/lib/database.cpp
+++ b/lib/database.cpp
@@ -28,6 +28,7 @@ Database::Database(const QString& matrixId, const QString& deviceId, QObject* pa
switch(version()) {
case 0: migrateTo1();
+ case 1: migrateTo2();
}
}
@@ -94,6 +95,22 @@ void Database::migrateTo1()
commit();
}
+void Database::migrateTo2()
+{
+ qCDebug(DATABASE) << "Migrating database to version 2";
+ transaction();
+ execute(QStringLiteral("ALTER TABLE inbound_megolm_sessions ADD ed25519Key TEXT"));
+ execute(QStringLiteral("ALTER TABLE olm_sessions ADD lastReceived TEXT"));
+
+ // Add indexes for improving queries speed on larger database
+ execute(QStringLiteral("CREATE INDEX sessions_session_idx ON olm_sessions(sessionId)"));
+ execute(QStringLiteral("CREATE INDEX outbound_room_idx ON outbound_megolm_sessions(roomId)"));
+ execute(QStringLiteral("CREATE INDEX inbound_room_idx ON inbound_megolm_sessions(roomId)"));
+ execute(QStringLiteral("CREATE INDEX group_session_idx ON group_session_record_index(roomId, sessionId, i)"));
+ execute(QStringLiteral("PRAGMA user_version = 2;"));
+ commit();
+}
+
QByteArray Database::accountPickle()
{
auto query = prepareQuery(QStringLiteral("SELECT pickle FROM accounts;"));
@@ -131,12 +148,13 @@ void Database::clear()
}
-void Database::saveOlmSession(const QString& senderKey, const QString& sessionId, const QByteArray &pickle)
+void Database::saveOlmSession(const QString& senderKey, const QString& sessionId, const QByteArray &pickle, const QDateTime& timestamp)
{
- auto query = prepareQuery(QStringLiteral("INSERT INTO olm_sessions(senderKey, sessionId, pickle) VALUES(:senderKey, :sessionId, :pickle);"));
+ auto query = prepareQuery(QStringLiteral("INSERT INTO olm_sessions(senderKey, sessionId, pickle, lastReceived) VALUES(:senderKey, :sessionId, :pickle, :lastReceived);"));
query.bindValue(":senderKey", senderKey);
query.bindValue(":sessionId", sessionId);
query.bindValue(":pickle", pickle);
+ query.bindValue(":lastReceived", timestamp);
transaction();
execute(query);
commit();
@@ -179,12 +197,13 @@ UnorderedMap<std::pair<QString, QString>, QOlmInboundGroupSessionPtr> Database::
return sessions;
}
-void Database::saveMegolmSession(const QString& roomId, const QString& senderKey, const QString& sessionId, const QByteArray& pickle)
+void Database::saveMegolmSession(const QString& roomId, const QString& senderKey, const QString& sessionId, const QString& ed25519Key, const QByteArray& pickle)
{
- auto query = prepareQuery(QStringLiteral("INSERT INTO inbound_megolm_sessions(roomId, senderKey, sessionId, pickle) VALUES(:roomId, :senderKey, :sessionId, :pickle);"));
+ auto query = prepareQuery(QStringLiteral("INSERT INTO inbound_megolm_sessions(roomId, senderKey, sessionId, ed25519Key, pickle) VALUES(:roomId, :senderKey, :sessionId, :ed25519Key, :pickle);"));
query.bindValue(":roomId", roomId);
query.bindValue(":senderKey", senderKey);
query.bindValue(":sessionId", sessionId);
+ query.bindValue(":ed25519Key", ed25519Key);
query.bindValue(":pickle", pickle);
transaction();
execute(query);
@@ -242,3 +261,13 @@ void Database::clearRoomData(const QString& roomId)
execute(query3);
commit();
}
+
+void Database::setOlmSessionLastReceived(const QString& sessionId, const QDateTime& timestamp)
+{
+ auto query = prepareQuery(QStringLiteral("UPDATE olm_sessions SET lastReceived=:lastReceived WHERE sessionId=:sessionId;"));
+ query.bindValue(":lastReceived", timestamp);
+ query.bindValue(":sessionId", sessionId);
+ transaction();
+ execute(query);
+ commit();
+}
diff --git a/lib/database.h b/lib/database.h
index d4d5fb56..cf241dbc 100644
--- a/lib/database.h
+++ b/lib/database.h
@@ -27,16 +27,18 @@ public:
QByteArray accountPickle();
void setAccountPickle(const QByteArray &pickle);
void clear();
- void saveOlmSession(const QString& senderKey, const QString& sessionId, const QByteArray &pickle);
+ 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 QByteArray& pickle);
+ void saveMegolmSession(const QString& roomId, const QString& senderKey, const QString& sessionKey, const QString& ed25519Key, const QByteArray& pickle);
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);
+ void setOlmSessionLastReceived(const QString& sessionId, const QDateTime& timestamp);
private:
void migrateTo1();
+ void migrateTo2();
QString m_matrixId;
};
}
diff --git a/lib/room.cpp b/lib/room.cpp
index 6197b3a2..88aa1d07 100644
--- a/lib/room.cpp
+++ b/lib/room.cpp
@@ -341,7 +341,7 @@ public:
UnorderedMap<std::pair<QString, QString>, QOlmInboundGroupSessionPtr> groupSessions;
bool addInboundGroupSession(QString senderKey, QString sessionId,
- QString sessionKey)
+ QString sessionKey, QString ed25519Key)
{
if (groupSessions.find({senderKey, sessionId}) != groupSessions.end()) {
qCWarning(E2EE) << "Inbound Megolm session" << sessionId
@@ -356,7 +356,7 @@ public:
return false;
}
qCWarning(E2EE) << "Adding inbound session";
- connection->saveMegolmSession(q, senderKey, megolmSession.get());
+ connection->saveMegolmSession(q, senderKey, megolmSession.get(), ed25519Key);
groupSessions[{senderKey, sessionId}] = std::move(megolmSession);
return true;
}
@@ -1509,7 +1509,7 @@ void Room::handleRoomKeyEvent(const RoomKeyEvent& roomKeyEvent,
<< roomKeyEvent.algorithm() << "in m.room_key event";
}
if (d->addInboundGroupSession(senderKey, roomKeyEvent.sessionId(),
- roomKeyEvent.sessionKey())) {
+ roomKeyEvent.sessionKey(), roomKeyEvent.fullJson()["keys"]["ed25519"].toString())) {
qCWarning(E2EE) << "added new inboundGroupSession:"
<< d->groupSessions.size();
for (const auto& eventId : d->undecryptedEvents[roomKeyEvent.sessionId()]) {