libQuotient
A Qt library for building matrix clients
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 
12 namespace Quotient {
13 
14 struct DevicesList;
15 
16 namespace _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