aboutsummaryrefslogtreecommitdiff
path: root/lib/keyverificationsession.h
diff options
context:
space:
mode:
authorTobias Fella <fella@posteo.de>2022-04-18 20:07:12 +0200
committerTobias Fella <fella@posteo.de>2022-05-02 20:25:51 +0200
commit16d4f4e48304543a0ab59b235edba07f5f2c2204 (patch)
tree932845a7b9a6179c4a19ffe6954c6420bf406bbc /lib/keyverificationsession.h
parent3a81aea545ec014d597f3756c362913aad4421df (diff)
downloadlibquotient-16d4f4e48304543a0ab59b235edba07f5f2c2204.tar.gz
libquotient-16d4f4e48304543a0ab59b235edba07f5f2c2204.zip
Implement key verification
Diffstat (limited to 'lib/keyverificationsession.h')
-rw-r--r--lib/keyverificationsession.h140
1 files changed, 140 insertions, 0 deletions
diff --git a/lib/keyverificationsession.h b/lib/keyverificationsession.h
new file mode 100644
index 00000000..cb7a99e9
--- /dev/null
+++ b/lib/keyverificationsession.h
@@ -0,0 +1,140 @@
+// SPDX-FileCopyrightText: 2022 Tobias Fella <fella@posteo.de>
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#pragma once
+
+#include "events/keyverificationevent.h"
+#include <QtCore/QObject>
+#include <qchar.h>
+
+class OlmSAS;
+
+namespace Quotient {
+class Connection;
+
+/** A key verification session. Listen for incoming sessions by connecting to Connection::newKeyVerificationSession.
+ Start a new session using Connection::startKeyVerificationSession.
+ The object is delete after finished is emitted.
+*/
+class QUOTIENT_API KeyVerificationSession : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum State {
+ INCOMING, // There is a request for verification incoming
+ WAITINGFORREADY, // We sent a request for verification and are waiting for ready
+ READY, // Either party sent a ready as a response to a request; The user selects a method
+ WAITINGFORACCEPT, // We sent a start and are waiting for an accept
+ ACCEPTED, // The other party sent an accept and is waiting for a key
+ WAITINGFORKEY, // We're waiting for a key
+ WAITINGFORVERIFICATION, // We're waiting for the *user* to verify the emojis
+ WAITINGFORMAC, // We're waiting for the mac
+ CANCELED, // The session has been canceled
+ DONE, // The verification is done
+ };
+ Q_ENUM(State)
+
+ enum Error {
+ NONE,
+ TIMEOUT,
+ REMOTE_TIMEOUT,
+ USER,
+ REMOTE_USER,
+ UNEXPECTED_MESSAGE,
+ REMOTE_UNEXPECTED_MESSAGE,
+ UNKNOWN_TRANSACTION,
+ REMOTE_UNKNOWN_TRANSACTION,
+ UNKNOWN_METHOD,
+ REMOTE_UNKNOWN_METHOD,
+ KEY_MISMATCH,
+ REMOTE_KEY_MISMATCH,
+ USER_MISMATCH,
+ REMOTE_USER_MISMATCH,
+ INVALID_MESSAGE,
+ REMOTE_INVALID_MESSAGE,
+ SESSION_ACCEPTED,
+ REMOTE_SESSION_ACCEPTED,
+ MISMATCHED_COMMITMENT,
+ REMOTE_MISMATCHED_COMMITMENT,
+ MISMATCHED_SAS,
+ REMOTE_MISMATCHED_SAS,
+ };
+ Q_ENUM(Error);
+
+ //Q_PROPERTY(int timeLeft READ timeLeft NOTIFY timeLeftChanged)
+ Q_PROPERTY(QString remoteDeviceId MEMBER m_remoteDeviceId CONSTANT)
+ Q_PROPERTY(QList<QVariantMap> sasEmojis READ sasEmojis NOTIFY sasEmojisChanged)
+ Q_PROPERTY(State state READ state NOTIFY stateChanged)
+ Q_PROPERTY(Error error READ error NOTIFY errorChanged)
+
+ KeyVerificationSession(const QString& remoteUserId, const KeyVerificationRequestEvent& event, Connection* connection, bool encrypted, QObject* parent = nullptr);
+ KeyVerificationSession(const QString& userId, const QString& deviceId, Connection* connection, QObject* parent = nullptr);
+ ~KeyVerificationSession();
+
+ int timeLeft() const;
+ QList<QVariantMap> sasEmojis() const;
+ State state() const;
+
+ Error error() const;
+
+public Q_SLOTS:
+ void sendRequest();
+ void sendReady();
+ void sendMac();
+ void sendStartSas();
+ void sendKey();
+ void sendDone();
+ void cancelVerification(Error error);
+
+Q_SIGNALS:
+
+ void timeLeftChanged();
+ void startReceived();
+ void keyReceived();
+ void sasEmojisChanged();
+ void stateChanged();
+ void errorChanged();
+ void finished();
+
+private:
+ QString m_remoteUserId;
+ QString m_remoteDeviceId;
+ QString m_transactionId;
+ Connection* m_connection;
+ OlmSAS* m_sas = nullptr;
+ int timeleft = 0;
+ QList<QVariantMap> m_sasEmojis;
+ bool startSentByUs = false;
+ State m_state;
+ Error m_error;
+ QString m_startEvent;
+ QString m_commitment;
+ QString m_language;
+ int m_timeout;
+ bool macReceived = false;
+ bool m_encrypted;
+ QStringList m_remoteSupportedMethods;
+
+ void handleReady(const KeyVerificationReadyEvent& event);
+ void handleStart(const KeyVerificationStartEvent& event);
+ void handleAccept(const KeyVerificationAcceptEvent& event);
+ void handleKey(const KeyVerificationKeyEvent& event);
+ void handleMac(const KeyVerificationMacEvent& event);
+ void handleDone(const KeyVerificationDoneEvent& event);
+ void handleCancel(const KeyVerificationCancelEvent& event);
+ void init();
+ void setState(State state);
+ void setError(Error error);
+ QStringList commonSupportedMethods(const QStringList& remoteSupportedMethods) const;
+ QString errorToString(Error error) const;
+ Error stringToError(const QString& error) const;
+ QStringList m_supportedMethods = { "m.sas.v1"_ls };
+
+ QByteArray macInfo(bool verifying, const QString& key = "KEY_IDS"_ls);
+ QString calculateMac(const QString& input, bool verifying, const QString& keyId= "KEY_IDS"_ls);
+
+ std::pair<QString, QString> emojiForCode(int code);
+};
+
+}