libQuotient
A Qt library for building matrix clients
Loading...
Searching...
No Matches
keyverificationsession.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2022 Tobias Fella <fella@posteo.de>
2// SPDX-License-Identifier: LGPL-2.1-or-later
3
4#pragma once
5
6#include "events/keyverificationevent.h"
7#include "events/roommessageevent.h"
8
9#include <QtCore/QObject>
10#include <QtCore/QPointer>
11
12struct OlmSAS;
13
14namespace Quotient {
15class Connection;
16class Room;
17
21
25
26public:
27 friend bool operator==(const EmojiEntry&, const EmojiEntry&) = default;
28};
29
30/** A key verification session. Listen for incoming sessions by connecting to Connection::newKeyVerificationSession.
31 Start a new session using Connection::startKeyVerificationSession.
32 The object is delete after finished is emitted.
33*/
35{
36 Q_OBJECT
37
38public:
39 enum State {
40 INCOMING, ///< There is a request for verification incoming
41 //! We sent a request for verification and are waiting for ready
42 WAITINGFORREADY,
43 //! Either party sent a ready as a response to a request; the user
44 //! selects a method
45 READY,
46 WAITINGFORACCEPT, ///< We sent a start and are waiting for an accept
47 ACCEPTED, ///< The other party sent an accept and is waiting for a key
48 WAITINGFORKEY, ///< We're waiting for a key
49 //! We're waiting for the *user* to verify the emojis
50 WAITINGFORVERIFICATION,
51 WAITINGFORMAC, ///< We're waiting for the mac
52 CANCELED, ///< The session has been canceled
53 DONE, ///< The verification is done
54 };
55 Q_ENUM(State)
56
57 enum Error {
58 NONE,
59 TIMEOUT,
60 REMOTE_TIMEOUT,
61 USER,
62 REMOTE_USER,
63 UNEXPECTED_MESSAGE,
64 REMOTE_UNEXPECTED_MESSAGE,
65 UNKNOWN_TRANSACTION,
66 REMOTE_UNKNOWN_TRANSACTION,
67 UNKNOWN_METHOD,
68 REMOTE_UNKNOWN_METHOD,
69 KEY_MISMATCH,
70 REMOTE_KEY_MISMATCH,
71 USER_MISMATCH,
72 REMOTE_USER_MISMATCH,
73 INVALID_MESSAGE,
74 REMOTE_INVALID_MESSAGE,
75 SESSION_ACCEPTED,
76 REMOTE_SESSION_ACCEPTED,
77 MISMATCHED_COMMITMENT,
78 REMOTE_MISMATCHED_COMMITMENT,
79 MISMATCHED_SAS,
80 REMOTE_MISMATCHED_SAS,
81 };
82 Q_ENUM(Error)
83
84 Q_PROPERTY(QString remoteDeviceId MEMBER m_remoteDeviceId CONSTANT)
85 Q_PROPERTY(QString remoteUserId MEMBER m_remoteUserId CONSTANT)
86 Q_PROPERTY(QVector<EmojiEntry> sasEmojis READ sasEmojis NOTIFY sasEmojisChanged)
87 Q_PROPERTY(State state READ state NOTIFY stateChanged)
88 Q_PROPERTY(Error error READ error NOTIFY errorChanged)
89 // Whether this is a user verification (in contrast to a device verification)
90 Q_PROPERTY(bool userVerification READ userVerification CONSTANT)
91
92 // Incoming device verification
93 KeyVerificationSession(QString remoteUserId,
94 const KeyVerificationRequestEvent& event,
95 Connection* connection, bool encrypted);
96
97 // Outgoing device verification
98 KeyVerificationSession(QString userId, QString deviceId,
99 Connection* connection);
100
101 // Incoming user verification
102 KeyVerificationSession(const RoomMessageEvent *event, Room *room);
103
104 // Outgoing user verification
105 explicit KeyVerificationSession(Room *room);
106
107 void handleEvent(const KeyVerificationEvent& baseEvent);
108
109 QVector<EmojiEntry> sasEmojis() const;
110 State state() const;
111
112 Error error() const;
113
114 QString remoteDeviceId() const;
115 QString transactionId() const;
116 bool userVerification() const;
117
118 void setRequestEventId(const QString &eventId);
119
120public Q_SLOTS:
121 void sendRequest();
122 void sendReady();
123 void sendMac();
124 void sendStartSas();
125 void sendKey();
126 void sendDone();
127 void cancelVerification(Error error);
128
129Q_SIGNALS:
130 void keyReceived();
131 void sasEmojisChanged();
132 void stateChanged();
133 void errorChanged();
134 void finished();
135
136private:
137 // Internal delegating constructors
138
139 KeyVerificationSession(QString remoteUserId, Connection* connection, QString remoteDeviceId,
140 bool encrypted, QStringList methods, QDateTime startTimestamp,
141 QString transactionId, Room* room = nullptr, QString requestEventId = {});
142 KeyVerificationSession(QString remoteUserId, Connection* connection, Room* room,
143 QString remoteDeviceId = {}, QString transactionId = {});
144
145 Connection* const m_connection;
146 QPointer<Room> m_room;
147 const QString m_remoteUserId;
148 QString m_remoteDeviceId;
149 QString m_transactionId;
150 bool m_encrypted = false;
151 QStringList m_remoteSupportedMethods{};
152 QStringList m_commonMacCodes{};
153
154 CStructPtr<OlmSAS> olmDataHolder = makeOlmData();
155 OlmSAS* olmData = olmDataHolder.get();
156 QVector<EmojiEntry> m_sasEmojis;
157 bool startSentByUs = false;
158 State m_state = INCOMING;
159 Error m_error = NONE;
160 QString m_startEvent{};
161 QByteArray m_commitment{};
162 bool macReceived = false;
163 bool m_verified = false;
164 QString m_pendingEdKeyId{};
165 QString m_pendingMasterKey{};
166 QString m_requestEventId{};
167
168 static CStructPtr<OlmSAS> makeOlmData();
169 void handleReady(const KeyVerificationReadyEvent& event);
170 void handleStart(const KeyVerificationStartEvent& event);
171 void handleKey(const KeyVerificationKeyEvent& event);
172 void handleMac(const KeyVerificationMacEvent& event);
173 void setupTimeout(std::chrono::milliseconds timeout);
174 void setState(State state);
175 void setError(Error error);
176 static QString errorToString(Error error);
177 static Error stringToError(const QString& error);
178 void trustKeys();
179 void sendEvent(const QString &userId, const QString &deviceId, const KeyVerificationEvent &event, bool encrypted);
180
181 QByteArray macInfo(bool verifying, const QString& key = "KEY_IDS"_L1);
182 QString calculateMac(const QString& input, bool verifying, const QString& keyId= "KEY_IDS"_L1);
183};
184
185} // namespace Quotient
#define QUOTIENT_API