1 #pragma once 2 3 /// @file 4 /// @brief Various event types used in E2EE. 5 6 #if __has_include(<nlohmann/json_fwd.hpp>) 7 #include <nlohmann/json_fwd.hpp> 8 #else 9 #include <nlohmann/json.hpp> 10 #endif 11 12 #include "mtx/events.hpp" 13 #include "mtx/events/common.hpp" 14 #include "variant" 15 16 namespace mtx { 17 namespace events { 18 namespace msg { 19 20 //! Display methods for Short Authentication Strings 21 enum class SASMethods 22 { 23 Decimal, //!< Display 3 times 4 digits 24 Emoji, //! Display 7 emoji 25 Unsupported 26 }; 27 28 void 29 from_json(const nlohmann::json &obj, SASMethods &method); 30 31 void 32 to_json(nlohmann::json &obj, const SASMethods &method); 33 34 //! The different verification methods 35 enum class VerificationMethods 36 { 37 SASv1, //!< Short Authentication Strings 38 Unsupported //!< Unsupported method 39 }; 40 41 void 42 from_json(const nlohmann::json &obj, VerificationMethods &method); 43 44 void 45 to_json(nlohmann::json &obj, const VerificationMethods &method); 46 47 //! Content of an individual message encrypted for a certain key. 48 struct OlmCipherContent 49 { 50 //! Ciphertext of the message. 51 std::string body; 52 /// @brief Olm message type. 53 /// 54 /// `0` for initial pre-key messages. 55 /// `1` for normal messages after the initial exchange. 56 uint8_t type; 57 }; 58 59 void 60 from_json(const nlohmann::json &obj, OlmCipherContent &event); 61 62 void 63 to_json(nlohmann::json &obj, const OlmCipherContent &event); 64 65 //! Content of the `m.room.encrypted` Olm event. 66 struct OlmEncrypted 67 { 68 //! Algorithm used for encrypting this event. 69 std::string algorithm; 70 //! curve25519 key of the sender. 71 std::string sender_key; 72 73 using RecipientKey = std::string; 74 //! Map of recipient curve25519 key to the encrypted message. 75 std::map<RecipientKey, OlmCipherContent> ciphertext; 76 }; 77 78 void 79 from_json(const nlohmann::json &obj, OlmEncrypted &event); 80 81 void 82 to_json(nlohmann::json &obj, const OlmEncrypted &event); 83 84 //! Content of the `m.room.encrypted` event. 85 struct Encrypted 86 { 87 //! Used for one-on-one exchanges. 88 std::string algorithm; 89 //! The actual encrypted payload. 90 std::string ciphertext; 91 //! Sender's device id. 92 std::string device_id; 93 //! The curve25519 device key. 94 std::string sender_key; 95 //! Outbound group session id. 96 std::string session_id; 97 //! Relations like rich replies 98 common::Relations relations; 99 }; 100 101 void 102 from_json(const nlohmann::json &obj, Encrypted &event); 103 104 void 105 to_json(nlohmann::json &obj, const Encrypted &event); 106 107 //! Content of the `m.dummy` event. 108 struct Dummy 109 {}; 110 111 void 112 from_json(const nlohmann::json &obj, Dummy &event); 113 114 void 115 to_json(nlohmann::json &obj, const Dummy &event); 116 117 //! Content of the `m.room_key` event. 118 struct RoomKey 119 { 120 /// @brief *Required.* The encryption algorithm the key in this event is to be used with. 121 /// 122 /// Must be 'm.megolm.v1.aes-sha2'. 123 std::string algorithm; 124 std::string room_id; //!< *Required.* The room where the key is used. 125 std::string session_id; //!< *Required.* The ID of the session that the key is for. 126 std::string session_key; //!< *Required.* The key to be exchanged. 127 }; 128 129 void 130 from_json(const nlohmann::json &obj, RoomKey &event); 131 132 void 133 to_json(nlohmann::json &obj, const RoomKey &event); 134 135 //! Content of the `m.forwarded_room_key` event. 136 struct ForwardedRoomKey 137 { 138 /// @brief *Required.* The encryption algorithm the key in this event is to be used with. 139 std::string algorithm; 140 std::string room_id; //!< *Required.* The room where the key is used. 141 std::string session_id; //!< *Required.* The ID of the session that the key is for. 142 std::string session_key; //!< *Required.* The key to be exchanged. 143 144 //! *Required.* The Curve25519 key of the device which initiated the session originally. 145 std::string sender_key; 146 /// @brief *Required.* The Ed25519 key of the device which initiated the session originally. 147 /// 148 /// It is 'claimed' because the receiving device has no way to tell that the original 149 /// room_key actually came from a device which owns the private part of this key unless they 150 /// have done device verification. 151 std::string sender_claimed_ed25519_key; 152 /// @brief *Required.* Chain of Curve25519 keys. 153 /// 154 /// It starts out empty, but each time the key is forwarded to another device, the previous 155 /// sender in the chain is added to the end of the list. For example, if the key is 156 /// forwarded from A to B to C, this field is empty between A and B, and contains A's 157 /// Curve25519 key between B and C. 158 std::vector<std::string> forwarding_curve25519_key_chain; 159 }; 160 161 void 162 from_json(const nlohmann::json &obj, ForwardedRoomKey &event); 163 164 void 165 to_json(nlohmann::json &obj, const ForwardedRoomKey &event); 166 167 //! The type of key request. 168 enum class RequestAction 169 { 170 Request, //!< request 171 Cancellation, //!< request_cancellation 172 Unknown, //!< Unknown request action 173 }; 174 175 void 176 from_json(const nlohmann::json &obj, RequestAction &action); 177 178 void 179 to_json(nlohmann::json &obj, const RequestAction &action); 180 181 //! A request to share a session key. 182 struct KeyRequest 183 { 184 //! The type of request. 185 RequestAction action; 186 187 /// @brief The encryption algorithm of the session we want keys for. 188 /// 189 /// Always m.megolm.v1.aes-sha2. 190 std::string algorithm; 191 //! The room in which the session was created. 192 std::string room_id; 193 //! The curve25519 key of the session creator. 194 std::string sender_key; 195 //! The session_id of the outbound megolm session. 196 std::string session_id; 197 198 //! A unique identifier for this request. 199 std::string request_id; 200 //! The device requesting the keys. 201 std::string requesting_device_id; 202 }; 203 204 void 205 from_json(const nlohmann::json &obj, KeyRequest &event); 206 207 void 208 to_json(nlohmann::json &obj, const KeyRequest &event); 209 210 //! Content of the `m.key.verification.request` event 211 struct KeyVerificationRequest 212 { 213 std::optional<std::string> body; 214 //! The device ID which is initiating the request. 215 std::string from_device; 216 //! The device ID to which the key verification request is meant,used only for to-device 217 //! verification 218 std::optional<std::string> to; 219 //! An opaque identifier for the verification request. Must be unique with respect to the 220 //! devices involved. 221 std::optional<std::string> transaction_id; 222 //! must be `key.verification.request`, this field will be needed only in room verification 223 std::optional<std::string> msgtype; 224 //! The verification methods supported by the sender. 225 std::vector<VerificationMethods> methods; 226 //! The POSIX timestamp in milliseconds for when the request was made. If the request is in 227 //! the future by more than 5 minutes or more than 10 minutes in the past, the message 228 //! should be ignored by the receiver. 229 std::optional<uint64_t> timestamp; 230 }; 231 232 void 233 from_json(const nlohmann::json &obj, KeyVerificationRequest &event); 234 235 void 236 to_json(nlohmann::json &obj, const KeyVerificationRequest &event); 237 238 //! Content of the `m.key.verification.start` event 239 struct KeyVerificationStart 240 { 241 //! The device ID which is initiating the process. 242 std::string from_device; 243 /// @brief An opaque identifier for the verification process. 244 /// 245 /// Must be unique with respect to the devices involved. Must be the same as the 246 /// transaction_id given in the `m.key.verification.request` if this process is originating 247 /// from a request. 248 /// @note Used in verification via to_device messaging 249 std::optional<std::string> transaction_id; 250 //! The verification method to use. Must be 'm.sas.v1' 251 VerificationMethods method = VerificationMethods::SASv1; 252 /// @brief Optional method to use to verify the other user's key with. 253 // 254 // Applicable when the method chosen only verifies one user's key. This field will never be 255 // present if the method verifies keys both ways. 256 /// @note This appears to be unused in SAS verification 257 std::optional<std::string> next_method; 258 /// @brief The key agreement protocols the sending device understands. 259 /// 260 /// Must include at least curve25519. 261 std::vector<std::string> key_agreement_protocols; 262 //! The hash methods the sending device understands. Must include at least sha256. 263 std::vector<std::string> hashes; 264 /// @brief The message authentication codes that the sending device understands. 265 /// 266 /// Must include at least hkdf-hmac-sha256. 267 std::vector<std::string> message_authentication_codes; 268 /// @brief The SAS methods the sending device (and the sending device's user) understands. 269 /// 270 /// Must include at least decimal. Optionally can include emoji. 271 /// 272 /// One of: 273 /// - `decimal` 274 /// - `emoji` 275 std::vector<SASMethods> short_authentication_string; 276 /// @brief This is used for relating this message with previously sent 277 /// `key.verification.request` 278 /// 279 /// @note Will be used only for room-verification msgs where this is used in place of 280 /// transaction_id. 281 common::Relations relations; 282 }; 283 284 void 285 from_json(const nlohmann::json &obj, KeyVerificationStart &event); 286 287 void 288 to_json(nlohmann::json &obj, const KeyVerificationStart &event); 289 290 //! Implements the `m.key.verification.ready` event 291 struct KeyVerificationReady 292 { 293 //! the deviceId of the device which send the `m.key.verification.request` 294 std::string from_device; 295 //! transactionId of the current flow 296 std::optional<std::string> transaction_id; 297 //! Sends the user the supported methods 298 std::vector<VerificationMethods> methods; 299 //! this is used for relating this message with previously sent 300 //! key.verification.request will be used only for room-verification msgs where this 301 //! is used in place of txnid 302 common::Relations relations; 303 }; 304 305 void 306 from_json(const nlohmann::json &obj, KeyVerificationReady &event); 307 308 void 309 to_json(nlohmann::json &obj, const KeyVerificationReady &event); 310 311 // ! Implements the `m.key.verification.done` event 312 struct KeyVerificationDone 313 { 314 //! transactionId of the current flow 315 std::optional<std::string> transaction_id; 316 //! this is used for relating this message with previously sent key.verification.request 317 //! will be used only for room-verification msgs where this is used in place of txnid 318 common::Relations relations; 319 }; 320 321 void 322 from_json(const nlohmann::json &obj, KeyVerificationDone &event); 323 324 void 325 to_json(nlohmann::json &obj, const KeyVerificationDone &event); 326 327 //! Implements the `m.key.verification.accept` event 328 struct KeyVerificationAccept 329 { 330 //! when the method chosen only verifies one user's key. This field will never be present 331 //! if the method verifies keys both ways. 332 std::optional<std::string> transaction_id; 333 //! The verification method to use. Must be 'm.sas.v1' 334 VerificationMethods method = VerificationMethods::SASv1; 335 //! The key agreement protocol the device is choosing to use, out of the options in the 336 //! m.key.verification.start message. 337 std::string key_agreement_protocol; 338 //! The hash method the device is choosing to use, out of the options in the 339 //! m.key.verification.start message. 340 std::string hash; 341 //! The message authentication code the device is choosing to use, out of the options in 342 //! the m.key.verification.start message. 343 std::string message_authentication_code; 344 //! The SAS methods both devices involed in the verification process understand. Must be 345 //! a subset of the options in the m.key.verification.start message. 346 //! One of: ["decimal", "emoji"] 347 std::vector<SASMethods> short_authentication_string; 348 //! The hash (encoded as unpadded base64) of the concatenation of the device's ephemeral 349 //! public key (encoded as unpadded base64) and the canonical JSON representation of the 350 //! m.key.verification.start message. 351 std::string commitment; 352 //! this is used for relating this message with previously sent key.verification.request 353 //! will be used only for room-verification msgs where this is used in place of txnid 354 common::Relations relations; 355 }; 356 357 void 358 from_json(const nlohmann::json &obj, KeyVerificationAccept &event); 359 360 void 361 to_json(nlohmann::json &obj, const KeyVerificationAccept &event); 362 363 //! implementation of the `m.key.verification.cancel` event 364 struct KeyVerificationCancel 365 { 366 //! The opaque identifier for the verification process/request. 367 std::optional<std::string> transaction_id; 368 //! A human readable description of the code. The client should only rely on this string 369 //! if it does not understand the code. 370 std::string reason; 371 //! The error code for why the process/request was cancelled by the user. Error codes 372 //! should use the Java package naming convention if not in the following list: 373 //! m.user: The user cancelled the verification. 374 //! m.timeout: The verification process timed out. Verification processes can define 375 //! their own timeout parameters. 376 //! m.unknown_transaction: The device does not know about the given transaction ID. 377 //! m.unknown_method: The device does not know how to handle the requested method. 378 //! This should be sent for m.key.verification.start messages and messages 379 //! defined by individual verification processes. 380 //! m.unexpected_message: The device received an unexpected message. Typically raised 381 //! when one of the parties is handling the verification out of order. 382 //! m.key_mismatch: The key was not verified. 383 //! m.user_mismatch: The expected user did not match the user verified. 384 //! m.invalid_message: The message received was invalid. 385 //! m.accepted: A m.key.verification.request was accepted by a different device. 386 //! The device receiving this error can ignore the verification request. 387 //! m.unknown_method: The devices are unable to agree on the key agreement, 388 //! hash, MAC, or SAS method. 389 //! m.mismatched_commitment: The hash commitment did not match. 390 //! m.mismatched_sas: The SAS did not match. 391 //! Clients should be careful to avoid error loops. For example, if a device sends an 392 //! incorrect message and the client returns m.invalid_message to which it gets an 393 //! unexpected response with m.unexpected_message, the client should not respond 394 //! again with m.unexpected_message to avoid the other device potentially sending 395 //! another error response. 396 std::string code; 397 //! this is used for relating this message with previously sent key.verification.request 398 //! will be used only for room-verification msgs where this is used in place of txnid 399 common::Relations relations; 400 }; 401 402 void 403 from_json(const nlohmann::json &obj, KeyVerificationCancel &event); 404 405 void 406 to_json(nlohmann::json &obj, const KeyVerificationCancel &event); 407 408 struct KeyVerificationKey 409 { 410 //! An opaque identifier for the verification process. Must be the same as the one 411 //! used for the m.key.verification.start message. 412 std::optional<std::string> transaction_id; 413 //! The device's ephemeral public key, encoded as unpadded base64. 414 std::string key; 415 //! this is used for relating this message with previously sent key.verification.request 416 //! will be used only for room-verification msgs where this is used in place of txnid 417 common::Relations relations; 418 }; 419 420 void 421 from_json(const nlohmann::json &obj, KeyVerificationKey &event); 422 423 void 424 to_json(nlohmann::json &obj, const KeyVerificationKey &event); 425 426 struct KeyVerificationMac 427 { 428 //! An opaque identifier for the verification process. Must be the same as the one 429 //! used for the m.key.verification.start message. 430 std::optional<std::string> transaction_id; 431 //! A map of the key ID to the MAC of the key, using the algorithm in the 432 //! verification process. The MAC is encoded as unpadded base64. 433 std::map<std::string, std::string> mac; 434 //! The MAC of the comma-separated, sorted, list of key IDs given in the mac 435 //! property, encoded as unpadded base64. 436 std::string keys; 437 //! this is used for relating this message with previously sent key.verification.request 438 //! will be used only for room-verification msgs where this is used in place of txnid 439 common::Relations relations; 440 }; 441 442 void 443 from_json(const nlohmann::json &obj, KeyVerificationMac &event); 444 445 void 446 to_json(nlohmann::json &obj, const KeyVerificationMac &event); 447 448 struct SecretRequest 449 { 450 //! The type of request. 451 RequestAction action; 452 453 //! Required if action is request. The name of the secret that is being requested. 454 std::string name; 455 456 //! A unique identifier for this request. 457 std::string request_id; 458 //! The device requesting the keys. 459 std::string requesting_device_id; 460 }; 461 462 void 463 from_json(const nlohmann::json &obj, SecretRequest &event); 464 465 void 466 to_json(nlohmann::json &obj, const SecretRequest &event); 467 468 struct SecretSend 469 { 470 //! Required. The contents of the secret. 471 std::string secret; 472 473 //! A unique identifier for this request. 474 std::string request_id; 475 }; 476 477 void 478 from_json(const nlohmann::json &obj, SecretSend &event); 479 480 void 481 to_json(nlohmann::json &obj, const SecretSend &event); 482 483 } // namespace msg 484 } // namespace events 485 } // namespace mtx 486