diff options
author | n-peugnet <n.peugnet@free.fr> | 2022-10-06 19:27:24 +0200 |
---|---|---|
committer | n-peugnet <n.peugnet@free.fr> | 2022-10-06 19:27:24 +0200 |
commit | d911b207f49e936b3e992200796110f0749ed150 (patch) | |
tree | 96d20ebb4d074a4c1755e21cb316a52d584daee3 /lib/events/keyverificationevent.h | |
parent | 8ad8a74152c5701b6ca1f9a00487ba9257a439b4 (diff) | |
parent | 56c2f2e2b809b9077393eb617828f33d144f5634 (diff) | |
download | libquotient-d911b207f49e936b3e992200796110f0749ed150.tar.gz libquotient-d911b207f49e936b3e992200796110f0749ed150.zip |
New upstream version 0.7.0
Diffstat (limited to 'lib/events/keyverificationevent.h')
-rw-r--r-- | lib/events/keyverificationevent.h | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/lib/events/keyverificationevent.h b/lib/events/keyverificationevent.h new file mode 100644 index 00000000..80aebcf3 --- /dev/null +++ b/lib/events/keyverificationevent.h @@ -0,0 +1,258 @@ +// SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org> +// SPDX-License-Identifier: LGPL-2.1-or-later + +#pragma once + +#include "event.h" + +namespace Quotient { + +static constexpr auto SasV1Method = "m.sas.v1"_ls; + +class QUOTIENT_API KeyVerificationEvent : public Event { +public: + QUO_BASE_EVENT(KeyVerificationEvent, "m.key.*"_ls, Event::BaseMetaType) + + using Event::Event; + + /// An opaque identifier for the verification request. Must + /// be unique with respect to the devices involved. + QUO_CONTENT_GETTER(QString, transactionId) +}; + +/// Requests a key verification with another user's devices. +/// Typically sent as a to-device event. +class QUOTIENT_API KeyVerificationRequestEvent : public KeyVerificationEvent { +public: + QUO_EVENT(KeyVerificationRequestEvent, "m.key.verification.request") + + using KeyVerificationEvent::KeyVerificationEvent; + KeyVerificationRequestEvent(const QString& transactionId, + const QString& fromDevice, + const QStringList& methods, + const QDateTime& timestamp) + : KeyVerificationRequestEvent( + basicJson(TypeId, { { "transaction_id"_ls, transactionId }, + { "from_device"_ls, fromDevice }, + { "methods"_ls, toJson(methods) }, + { "timestamp"_ls, toJson(timestamp) } })) + {} + + /// The device ID which is initiating the request. + QUO_CONTENT_GETTER(QString, fromDevice) + + /// The verification methods supported by the sender. + QUO_CONTENT_GETTER(QStringList, methods) + + /// The POSIX timestamp in milliseconds for when the request was + /// made. If the request is in the future by more than 5 minutes or + /// more than 10 minutes in the past, the message should be ignored + /// by the receiver. + QUO_CONTENT_GETTER(QDateTime, timestamp) +}; + +class QUOTIENT_API KeyVerificationReadyEvent : public KeyVerificationEvent { +public: + QUO_EVENT(KeyVerificationReadyEvent, "m.key.verification.ready") + + using KeyVerificationEvent::KeyVerificationEvent; + KeyVerificationReadyEvent(const QString& transactionId, + const QString& fromDevice, + const QStringList& methods) + : KeyVerificationReadyEvent( + basicJson(TypeId, { { "transaction_id"_ls, transactionId }, + { "from_device"_ls, fromDevice }, + { "methods"_ls, toJson(methods) } })) + {} + + /// The device ID which is accepting the request. + QUO_CONTENT_GETTER(QString, fromDevice) + + /// The verification methods supported by the sender. + QUO_CONTENT_GETTER(QStringList, methods) +}; + +/// Begins a key verification process. +class QUOTIENT_API KeyVerificationStartEvent : public KeyVerificationEvent { +public: + QUO_EVENT(KeyVerificationStartEvent, "m.key.verification.start") + + using KeyVerificationEvent::KeyVerificationEvent; + KeyVerificationStartEvent(const QString& transactionId, + const QString& fromDevice) + : KeyVerificationStartEvent( + basicJson(TypeId, { { "transaction_id"_ls, transactionId }, + { "from_device"_ls, fromDevice }, + { "method"_ls, SasV1Method }, + { "hashes"_ls, QJsonArray{ "sha256"_ls } }, + { "key_agreement_protocols"_ls, + QJsonArray{ "curve25519-hkdf-sha256"_ls } }, + { "message_authentication_codes"_ls, + QJsonArray{ "hkdf-hmac-sha256"_ls } }, + { "short_authentication_string"_ls, + QJsonArray{ "decimal"_ls, "emoji"_ls } } })) + {} + + /// The device ID which is initiating the process. + QUO_CONTENT_GETTER(QString, fromDevice) + + /// The verification method to use. + QUO_CONTENT_GETTER(QString, method) + + /// Optional method to use to verify the other user's key with. + QUO_CONTENT_GETTER(Omittable<QString>, nextMethod) + + // SAS.V1 methods + + /// The key agreement protocols the sending device understands. + /// \note Only exist if method is m.sas.v1 + QStringList keyAgreementProtocols() const + { + Q_ASSERT(method() == SasV1Method); + return contentPart<QStringList>("key_agreement_protocols"_ls); + } + + /// The hash methods the sending device understands. + /// \note Only exist if method is m.sas.v1 + QStringList hashes() const + { + Q_ASSERT(method() == SasV1Method); + return contentPart<QStringList>("hashes"_ls); + } + + /// The message authentication codes that the sending device understands. + /// \note Only exist if method is m.sas.v1 + QStringList messageAuthenticationCodes() const + { + Q_ASSERT(method() == SasV1Method); + return contentPart<QStringList>("message_authentication_codes"_ls); + } + + /// The SAS methods the sending device (and the sending device's + /// user) understands. + /// \note Only exist if method is m.sas.v1 + QString shortAuthenticationString() const + { + Q_ASSERT(method() == SasV1Method); + return contentPart<QString>("short_authentification_string"_ls); + } +}; + +/// Accepts a previously sent m.key.verification.start message. +/// Typically sent as a to-device event. +class QUOTIENT_API KeyVerificationAcceptEvent : public KeyVerificationEvent { +public: + QUO_EVENT(KeyVerificationAcceptEvent, "m.key.verification.accept") + + using KeyVerificationEvent::KeyVerificationEvent; + KeyVerificationAcceptEvent(const QString& transactionId, + const QString& commitment) + : KeyVerificationAcceptEvent(basicJson( + TypeId, { { "transaction_id"_ls, transactionId }, + { "method"_ls, SasV1Method }, + { "key_agreement_protocol"_ls, "curve25519-hkdf-sha256" }, + { "hash"_ls, "sha256" }, + { "message_authentication_code"_ls, "hkdf-hmac-sha256" }, + { "short_authentication_string"_ls, + QJsonArray{ "decimal"_ls, "emoji"_ls, } }, + { "commitment"_ls, commitment } })) + {} + + /// The verification method to use. Must be 'm.sas.v1'. + QUO_CONTENT_GETTER(QString, method) + + /// The key agreement protocol the device is choosing to use, out of + /// the options in the m.key.verification.start message. + QUO_CONTENT_GETTER(QString, keyAgreementProtocol) + + /// The hash method the device is choosing to use, out of the + /// options in the m.key.verification.start message. + QUO_CONTENT_GETTER_X(QString, hashData, "hash"_ls) + + /// The message authentication code the device is choosing to use, out + /// of the options in the m.key.verification.start message. + QUO_CONTENT_GETTER(QString, messageAuthenticationCode) + + /// The SAS methods both devices involved in the verification process understand. + QUO_CONTENT_GETTER(QStringList, shortAuthenticationString) + + /// The hash (encoded as unpadded base64) of the concatenation of the + /// device's ephemeral public key (encoded as unpadded base64) and the + /// canonical JSON representation of the m.key.verification.start message. + QUO_CONTENT_GETTER(QString, commitment) +}; + +class QUOTIENT_API KeyVerificationCancelEvent : public KeyVerificationEvent { +public: + QUO_EVENT(KeyVerificationCancelEvent, "m.key.verification.cancel") + + using KeyVerificationEvent::KeyVerificationEvent; + KeyVerificationCancelEvent(const QString& transactionId, + const QString& reason) + : KeyVerificationCancelEvent( + basicJson(TypeId, { + { "transaction_id"_ls, transactionId }, + { "reason"_ls, reason }, + { "code"_ls, reason } // Not a typo + })) + {} + + /// A human readable description of the code. The client should only + /// rely on this string if it does not understand the code. + QUO_CONTENT_GETTER(QString, reason) + + /// The error code for why the process/request was cancelled by the user. + QUO_CONTENT_GETTER(QString, code) +}; + +/// Sends the ephemeral public key for a device to the partner device. +/// Typically sent as a to-device event. +class QUOTIENT_API KeyVerificationKeyEvent : public KeyVerificationEvent { +public: + QUO_EVENT(KeyVerificationKeyEvent, "m.key.verification.key") + + using KeyVerificationEvent::KeyVerificationEvent; + KeyVerificationKeyEvent(const QString& transactionId, const QString& key) + : KeyVerificationKeyEvent( + basicJson(TypeId, { { "transaction_id"_ls, transactionId }, + { "key"_ls, key } })) + {} + + /// The device's ephemeral public key, encoded as unpadded base64. + QUO_CONTENT_GETTER(QString, key) +}; + +/// Sends the MAC of a device's key to the partner device. +class QUOTIENT_API KeyVerificationMacEvent : public KeyVerificationEvent { +public: + QUO_EVENT(KeyVerificationMacEvent, "m.key.verification.mac") + + using KeyVerificationEvent::KeyVerificationEvent; + KeyVerificationMacEvent(const QString& transactionId, const QString& keys, + const QJsonObject& mac) + : KeyVerificationMacEvent( + basicJson(TypeId, { { "transaction_id"_ls, transactionId }, + { "keys"_ls, keys }, + { "mac"_ls, mac } })) + {} + + /// The device's ephemeral public key, encoded as unpadded base64. + QUO_CONTENT_GETTER(QString, keys) + + QHash<QString, QString> mac() const + { + return contentPart<QHash<QString, QString>>("mac"_ls); + } +}; + +class QUOTIENT_API KeyVerificationDoneEvent : public KeyVerificationEvent { +public: + QUO_EVENT(KeyVerificationDoneEvent, "m.key.verification.done") + + using KeyVerificationEvent::KeyVerificationEvent; + explicit KeyVerificationDoneEvent(const QString& transactionId) + : KeyVerificationDoneEvent( + basicJson(TypeId, { { "transaction_id"_ls, transactionId } })) + {} +}; +} // namespace Quotient |