Newer
Older
/// @file
/// @brief Various event types used in E2EE.
#if __has_include(<nlohmann/json_fwd.hpp>)
#include <nlohmann/json_fwd.hpp>
#else
#include "mtx/events.hpp"
#include "mtx/events/common.hpp"
namespace mtx {
namespace events {
namespace msg {
Decimal, //!< Display 3 times 4 digits
Emoji, //! Display 7 emoji
Unsupported
};
void
from_json(const nlohmann::json &obj, SASMethods &method);
void
to_json(nlohmann::json &obj, const SASMethods &method);
enum class VerificationMethods
{
SASv1, //!< Short Authentication Strings
Unsupported //!< Unsupported method
};
void
from_json(const nlohmann::json &obj, VerificationMethods &method);
void
to_json(nlohmann::json &obj, const VerificationMethods &method);
//! Content of an individual message encrypted for a certain key.
struct OlmCipherContent
{
//! Ciphertext of the message.
std::string body;
/// @brief Olm message type.
///
/// `0` for initial pre-key messages.
/// `1` for normal messages after the initial exchange.
uint8_t type;
friend void from_json(const nlohmann::json &obj, OlmCipherContent &event);
friend void to_json(nlohmann::json &obj, const OlmCipherContent &event);
};
//! Content of the `m.room.encrypted` Olm event.
struct OlmEncrypted
{
//! Algorithm used for encrypting this event.
std::string algorithm;
//! curve25519 key of the sender.
std::string sender_key;
using RecipientKey = std::string;
//! Map of recipient curve25519 key to the encrypted message.
std::map<RecipientKey, OlmCipherContent> ciphertext;
friend void from_json(const nlohmann::json &obj, OlmEncrypted &event);
friend void to_json(nlohmann::json &obj, const OlmEncrypted &event);
};
//! Content of the `m.room.encrypted` event.
struct Encrypted
{
//! Used for one-on-one exchanges.
std::string algorithm;
//! The actual encrypted payload.
std::string ciphertext;
//! Sender's device id.
std::string device_id;
//! The curve25519 device key.
std::string sender_key;
//! Outbound group session id.
std::string session_id;
//! Relations like rich replies
common::Relations relations;
friend void from_json(const nlohmann::json &obj, Encrypted &event);
friend void to_json(nlohmann::json &obj, const Encrypted &event);
};
//! Content of the `m.dummy` event.
struct Dummy
{
friend void from_json(const nlohmann::json &obj, Dummy &event);
friend void to_json(nlohmann::json &obj, const Dummy &event);
};
//! Content of the `m.room_key` event.
struct RoomKey
{
/// @brief *Required.* The encryption algorithm the key in this event is to be used with.
///
/// Must be 'm.megolm.v1.aes-sha2'.
std::string algorithm;
std::string room_id; //!< *Required.* The room where the key is used.
std::string session_id; //!< *Required.* The ID of the session that the key is for.
std::string session_key; //!< *Required.* The key to be exchanged.
friend void from_json(const nlohmann::json &obj, RoomKey &event);
friend void to_json(nlohmann::json &obj, const RoomKey &event);
};
//! Content of the `m.forwarded_room_key` event.
struct ForwardedRoomKey
{
/// @brief *Required.* The encryption algorithm the key in this event is to be used with.
std::string algorithm;
std::string room_id; //!< *Required.* The room where the key is used.
std::string session_id; //!< *Required.* The ID of the session that the key is for.
std::string session_key; //!< *Required.* The key to be exchanged.
//! *Required.* The Curve25519 key of the device which initiated the session originally.
std::string sender_key;
/// @brief *Required.* The Ed25519 key of the device which initiated the session originally.
///
/// It is 'claimed' because the receiving device has no way to tell that the original
/// room_key actually came from a device which owns the private part of this key unless they
/// have done device verification.
std::string sender_claimed_ed25519_key;
/// @brief *Required.* Chain of Curve25519 keys.
///
/// It starts out empty, but each time the key is forwarded to another device, the previous
/// sender in the chain is added to the end of the list. For example, if the key is
/// forwarded from A to B to C, this field is empty between A and B, and contains A's
/// Curve25519 key between B and C.
std::vector<std::string> forwarding_curve25519_key_chain;
friend void from_json(const nlohmann::json &obj, ForwardedRoomKey &event);
friend void to_json(nlohmann::json &obj, const ForwardedRoomKey &event);
};
enum class RequestAction
{
Request, //!< request
Cancellation, //!< request_cancellation
Unknown, //!< Unknown request action
void
from_json(const nlohmann::json &obj, RequestAction &action);
void
to_json(nlohmann::json &obj, const RequestAction &action);
//! The type of request.
RequestAction action;
/// @brief The encryption algorithm of the session we want keys for.
///
/// Always m.megolm.v1.aes-sha2.
std::string algorithm;
//! The room in which the session was created.
std::string room_id;
//! The curve25519 key of the session creator.
std::string sender_key;
//! The session_id of the outbound megolm session.
std::string session_id;
//! A unique identifier for this request.
std::string request_id;
//! The device requesting the keys.
std::string requesting_device_id;
friend void from_json(const nlohmann::json &obj, KeyRequest &event);
friend void to_json(nlohmann::json &obj, const KeyRequest &event);
};
//! Content of the `m.key.verification.request` event
struct KeyVerificationRequest
{
std::optional<std::string> body;
//! The device ID which is initiating the request.
std::string from_device;
//! The device ID to which the key verification request is meant,used only for to-device
//! verification
std::optional<std::string> to;
//! An opaque identifier for the verification request. Must be unique with respect to the
//! devices involved.
std::optional<std::string> transaction_id;
//! must be `key.verification.request`, this field will be needed only in room verification
std::optional<std::string> msgtype;
//! The verification methods supported by the sender.
std::vector<VerificationMethods> 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.
std::optional<uint64_t> timestamp;
friend void from_json(const nlohmann::json &obj, KeyVerificationRequest &event);
friend void to_json(nlohmann::json &obj, const KeyVerificationRequest &event);
};
//! Content of the `m.key.verification.start` event
struct KeyVerificationStart
{
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
//! The device ID which is initiating the process.
std::string from_device;
/// @brief An opaque identifier for the verification process.
///
/// Must be unique with respect to the devices involved. Must be the same as the
/// transaction_id given in the `m.key.verification.request` if this process is originating
/// from a request.
/// @note Used in verification via to_device messaging
std::optional<std::string> transaction_id;
//! The verification method to use. Must be 'm.sas.v1'
VerificationMethods method = VerificationMethods::SASv1;
/// @brief Optional method to use to verify the other user's key with.
//
// Applicable when the method chosen only verifies one user's key. This field will never be
// present if the method verifies keys both ways.
/// @note This appears to be unused in SAS verification
std::optional<std::string> next_method;
/// @brief The key agreement protocols the sending device understands.
///
/// Must include at least curve25519.
std::vector<std::string> key_agreement_protocols;
//! The hash methods the sending device understands. Must include at least sha256.
std::vector<std::string> hashes;
/// @brief The message authentication codes that the sending device understands.
///
/// Must include at least hkdf-hmac-sha256.
std::vector<std::string> message_authentication_codes;
/// @brief The SAS methods the sending device (and the sending device's user) understands.
///
/// Must include at least decimal. Optionally can include emoji.
///
/// One of:
/// - `decimal`
/// - `emoji`
std::vector<SASMethods> short_authentication_string;
/// @brief This is used for relating this message with previously sent
/// `key.verification.request`
///
/// @note Will be used only for room-verification msgs where this is used in place of
/// transaction_id.
common::Relations relations;
friend void from_json(const nlohmann::json &obj, KeyVerificationStart &event);
friend void to_json(nlohmann::json &obj, const KeyVerificationStart &event);
};
//! Implements the `m.key.verification.ready` event
struct KeyVerificationReady
{
//! the deviceId of the device which send the `m.key.verification.request`
std::string from_device;
//! transactionId of the current flow
std::optional<std::string> transaction_id;
//! Sends the user the supported methods
std::vector<VerificationMethods> methods;
//! this is used for relating this message with previously sent
//! key.verification.request will be used only for room-verification msgs where this
//! is used in place of txnid
common::Relations relations;
friend void from_json(const nlohmann::json &obj, KeyVerificationReady &event);
friend void to_json(nlohmann::json &obj, const KeyVerificationReady &event);
};
// ! Implements the `m.key.verification.done` event
struct KeyVerificationDone
//! transactionId of the current flow
std::optional<std::string> transaction_id;
//! this is used for relating this message with previously sent key.verification.request
//! will be used only for room-verification msgs where this is used in place of txnid
common::Relations relations;
friend void from_json(const nlohmann::json &obj, KeyVerificationDone &event);
friend void to_json(nlohmann::json &obj, const KeyVerificationDone &event);
};
//! Implements the `m.key.verification.accept` event
struct KeyVerificationAccept
{
//! when the method chosen only verifies one user's key. This field will never be present
//! if the method verifies keys both ways.
std::optional<std::string> transaction_id;
//! The verification method to use. Must be 'm.sas.v1'
VerificationMethods method = VerificationMethods::SASv1;
//! The key agreement protocol the device is choosing to use, out of the options in the
//! m.key.verification.start message.
std::string key_agreement_protocol;
//! The hash method the device is choosing to use, out of the options in the
//! m.key.verification.start message.
std::string hash;
//! The message authentication code the device is choosing to use, out of the options in
//! the m.key.verification.start message.
std::string message_authentication_code;
//! The SAS methods both devices involed in the verification process understand. Must be
//! a subset of the options in the m.key.verification.start message.
//! One of: ["decimal", "emoji"]
std::vector<SASMethods> short_authentication_string;
//! 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.
std::string commitment;
//! this is used for relating this message with previously sent key.verification.request
//! will be used only for room-verification msgs where this is used in place of txnid
common::Relations relations;
friend void from_json(const nlohmann::json &obj, KeyVerificationAccept &event);
friend void to_json(nlohmann::json &obj, const KeyVerificationAccept &event);
};
//! implementation of the `m.key.verification.cancel` event
struct KeyVerificationCancel
{
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
//! The opaque identifier for the verification process/request.
std::optional<std::string> transaction_id;
//! A human readable description of the code. The client should only rely on this string
//! if it does not understand the code.
std::string reason;
//! The error code for why the process/request was cancelled by the user. Error codes
//! should use the Java package naming convention if not in the following list:
//! m.user: The user cancelled the verification.
//! m.timeout: The verification process timed out. Verification processes can define
//! their own timeout parameters.
//! m.unknown_transaction: The device does not know about the given transaction ID.
//! m.unknown_method: The device does not know how to handle the requested method.
//! This should be sent for m.key.verification.start messages and messages
//! defined by individual verification processes.
//! m.unexpected_message: The device received an unexpected message. Typically raised
//! when one of the parties is handling the verification out of order.
//! m.key_mismatch: The key was not verified.
//! m.user_mismatch: The expected user did not match the user verified.
//! m.invalid_message: The message received was invalid.
//! m.accepted: A m.key.verification.request was accepted by a different device.
//! The device receiving this error can ignore the verification request.
//! m.unknown_method: The devices are unable to agree on the key agreement,
//! hash, MAC, or SAS method.
//! m.mismatched_commitment: The hash commitment did not match.
//! m.mismatched_sas: The SAS did not match.
//! Clients should be careful to avoid error loops. For example, if a device sends an
//! incorrect message and the client returns m.invalid_message to which it gets an
//! unexpected response with m.unexpected_message, the client should not respond
//! again with m.unexpected_message to avoid the other device potentially sending
//! another error response.
std::string code;
//! this is used for relating this message with previously sent key.verification.request
//! will be used only for room-verification msgs where this is used in place of txnid
common::Relations relations;
friend void from_json(const nlohmann::json &obj, KeyVerificationCancel &event);
friend void to_json(nlohmann::json &obj, const KeyVerificationCancel &event);
};
struct KeyVerificationKey
{
//! An opaque identifier for the verification process. Must be the same as the one
//! used for the m.key.verification.start message.
std::optional<std::string> transaction_id;
//! The device's ephemeral public key, encoded as unpadded base64.
std::string key;
//! this is used for relating this message with previously sent key.verification.request
//! will be used only for room-verification msgs where this is used in place of txnid
common::Relations relations;
friend void from_json(const nlohmann::json &obj, KeyVerificationKey &event);
friend void to_json(nlohmann::json &obj, const KeyVerificationKey &event);
};
struct KeyVerificationMac
{
//! An opaque identifier for the verification process. Must be the same as the one
//! used for the m.key.verification.start message.
std::optional<std::string> transaction_id;
//! A map of the key ID to the MAC of the key, using the algorithm in the
//! verification process. The MAC is encoded as unpadded base64.
std::map<std::string, std::string> mac;
//! The MAC of the comma-separated, sorted, list of key IDs given in the mac
//! property, encoded as unpadded base64.
std::string keys;
//! this is used for relating this message with previously sent key.verification.request
//! will be used only for room-verification msgs where this is used in place of txnid
common::Relations relations;
friend void from_json(const nlohmann::json &obj, KeyVerificationMac &event);
friend void to_json(nlohmann::json &obj, const KeyVerificationMac &event);
};
//! The type of request.
RequestAction action;
//! Required if action is request. The name of the secret that is being requested.
std::string name;
//! A unique identifier for this request.
std::string request_id;
//! The device requesting the keys.
std::string requesting_device_id;
friend void from_json(const nlohmann::json &obj, SecretRequest &event);
friend void to_json(nlohmann::json &obj, const SecretRequest &event);
};
//! Required. The contents of the secret.
std::string secret;
//! A unique identifier for this request.
std::string request_id;
friend void from_json(const nlohmann::json &obj, SecretSend &event);
friend void to_json(nlohmann::json &obj, const SecretSend &event);
};
} // namespace msg
} // namespace events
} // namespace mtx