libQuotient
A Qt library for building matrix clients
Loading...
Searching...
No Matches
connectionencryptiondata_p.h
Go to the documentation of this file.
1#pragma once
2
3#include "connection.h"
4#include "database.h"
6
7#include "e2ee/qolmaccount.h"
8#include "e2ee/qolmsession.h"
9
10#include "events/encryptedevent.h"
11
12namespace Quotient {
13
14struct DevicesList;
15
16namespace _impl {
17 class ConnectionEncryptionData {
18 public:
19 static QFuture<bool> setup(Connection* connection,
20 std::unique_ptr<ConnectionEncryptionData>& result,
21 bool clearDatabase = false);
22
23 Connection* q;
24 QOlmAccount olmAccount;
25 // No easy way in C++ to discern between SQL SELECT from UPDATE, too bad
26 mutable Database database;
27 std::unordered_map<QByteArray, std::vector<QOlmSession>> olmSessions;
28 //! A map from SenderKey to vector of InboundSession
29 QHash<QString, KeyVerificationSession*> verificationSessions{};
30 QSet<QString> trackedUsers{};
31 QSet<QString> outdatedUsers{};
32 QHash<QString, QHash<QString, DeviceKeys>> deviceKeys{};
33 JobHandle<QueryKeysJob> currentQueryKeysJob{};
34 QSet<std::pair<QString, QString>> triedDevices{};
35 //! An update of internal tracking structures (trackedUsers, e.g.) is
36 //! needed
37 bool encryptionUpdateRequired = false;
38 QHash<QString, int> oneTimeKeysCount{};
39 std::vector<std::unique_ptr<EncryptedEvent>> pendingEncryptedEvents{};
40 bool isUploadingKeys = false;
41 bool firstSync = true;
42 QHash<QString, QHash<QString, bool>> selfVerifiedDevices;
43 QHash<QString, QHash<QString, bool>> verifiedDevices;
44
45 void saveDevicesList();
46 void loadDevicesList();
47 QString curveKeyForUserDevice(const QString& userId,
48 const QString& device) const;
49 bool isKnownCurveKey(const QString& userId,
50 const QString& curveKey) const;
51 bool hasOlmSession(const QString &user, const QString &deviceId) const;
52
53 void onSyncSuccess(SyncData &syncResponse);
54 void loadOutdatedUserDevices();
55 void consumeToDeviceEvent(EventPtr toDeviceEvent);
56 void encryptionUpdate(const QList<QString>& forUsers);
57
58 bool createOlmSession(const QString& targetUserId,
59 const QString& targetDeviceId,
60 const OneTimeKeys& oneTimeKeyObject);
61 void saveSession(const QOlmSession& session, const QByteArray& senderKey)
62 {
63 database.saveOlmSession(senderKey, session,
64 QDateTime::currentDateTime());
65 }
66 void saveOlmAccount();
67 void reloadDevices();
68
69 std::pair<QByteArray, QByteArray> sessionDecryptMessage(
70 const QJsonObject& personalCipherObject,
71 const QByteArray& senderKey);
72 std::pair<EventPtr, QByteArray> sessionDecryptMessage(const EncryptedEvent& encryptedEvent);
73
74 QJsonObject assembleEncryptedContent(
75 QJsonObject payloadJson, const QString& targetUserId,
76 const QString& targetDeviceId) const;
77 void sendSessionKeyToDevices(
78 const QString& roomId,
79 const QOlmOutboundGroupSession& outboundSession,
80 const QMultiHash<QString, QString>& devices);
81
82 template <typename... ArgTs>
83 KeyVerificationSession* setupKeyVerificationSession(
84 ArgTs&&... sessionArgs)
85 {
86 auto session =
87 new KeyVerificationSession(std::forward<ArgTs>(sessionArgs)...);
88 qCDebug(E2EE) << "Incoming key verification session from" << session->remoteDeviceId();
89 verificationSessions.insert(session->transactionId(), session);
90 QObject::connect(session, &QObject::destroyed, q,
91 [this, txnId = session->transactionId()] {
92 verificationSessions.remove(txnId);
93 });
94 emit q->newKeyVerificationSession(session);
95 return session;
96 }
97
98 // This is only public to enable std::make_unique; do not use directly,
99 // get an instance from setup() instead
100 ConnectionEncryptionData(Connection* connection,
101 PicklingKey&& picklingKey);
102 bool hasConflictingDeviceIdsAndCrossSigningKeys(const QString& userId);
103
104 void handleQueryKeys(const QueryKeysJob::Response& keys);
105
106 void handleMasterKeys(const QHash<QString, CrossSigningKey>& masterKeys);
107 void handleSelfSigningKeys(const QHash<QString, CrossSigningKey>& selfSigningKeys);
108 void handleUserSigningKeys(const QHash<QString, CrossSigningKey>& userSigningKeys);
109 void handleDevicesList(
110 const QHash<QString, QHash<QString, QueryKeysJob::DeviceInformation>>& newDeviceKeys);
111 void checkVerifiedMasterKeys(const QHash<QString, CrossSigningKey>& masterKeys);
112
113 private:
114 void consumeDevicesList(const DevicesList &devicesList);
115 bool processIfVerificationEvent(const Event& evt, bool encrypted);
116 void handleEncryptedToDeviceEvent(const EncryptedEvent& event);
117
118 // This function assumes that an olm session with (user, device) exists
119 std::pair<QOlmMessage::Type, QByteArray> olmEncryptMessage(
120 const QString& userId, const QString& device,
121 const QByteArray& message) const;
122
123 void doSendSessionKeyToDevices(const QString& roomId, const QByteArray& sessionId,
124 const QByteArray &sessionKey, uint32_t messageIndex,
125 const QMultiHash<QString, QString>& devices);
126 };
127} // namespace _impl
128} // namespace Quotient