1#pragma once
2
3/// @file
4/// @brief E2EE related endpoints.
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/common.hpp"
13#include "mtx/lightweight_error.hpp"
14
15#include <map>
16#include <string>
17
18namespace mtx {
19namespace responses {
20//! Response from the `POST /_matrix/client/r0/keys/upload` endpoint.
21struct UploadKeys
22{
23 //! For each key algorithm, the number of unclaimed one-time keys
24 //! of that type currently held on the server for this device.
25 std::map<std::string, uint32_t> one_time_key_counts;
26
27 friend void from_json(const nlohmann::json &obj, UploadKeys &response);
28};
29
30using DeviceToKeysMap = std::map<std::string, mtx::crypto::DeviceKeys>;
31
32//! Response from the `POST /_matrix/client/r0/keys/query` endpoint.
33struct QueryKeys
34{
35 //! If any remote homeservers could not be reached, they are
36 //! recorded here. The names of the properties are the names
37 //! of the unreachable servers.
38 std::map<std::string, nlohmann::json> failures;
39 //! Information on the queried devices.
40 //! A map from user ID, to a map from device ID to device information.
41 //! For each device, the information returned will be the same
42 //! as uploaded via /keys/upload, with the addition of an unsigned property
43 std::map<std::string, DeviceToKeysMap> device_keys;
44 //! A map from user ID, to information about master_keys.
45 std::map<std::string, mtx::crypto::CrossSigningKeys> master_keys;
46 //! A map from user ID, to information about user_signing_keys.
47 std::map<std::string, mtx::crypto::CrossSigningKeys> user_signing_keys;
48 //! A map from user ID, to information about self_signing_keys.
49 std::map<std::string, mtx::crypto::CrossSigningKeys> self_signing_keys;
50
51 friend void to_json(nlohmann::json &obj, const QueryKeys &response);
52 friend void from_json(const nlohmann::json &obj, QueryKeys &response);
53};
54
55//! Request for `POST /_matrix/client/r0/keys/upload`.
56struct KeySignaturesUpload
57{
58 //! Errors returned during upload.
59 std::map<std::string, std::map<std::string, mtx::errors::LightweightError>> errors;
60
61 friend void from_json(const nlohmann::json &obj, KeySignaturesUpload &response);
62};
63
64//! Response from the `POST /_matrix/client/r0/keys/claim` endpoint.
65struct ClaimKeys
66{
67 //! If any remote homeservers could not be reached, they are
68 //! recorded here. The names of the properties are the names
69 //! of the unreachable servers.
70 std::map<std::string, nlohmann::json> failures;
71 //! One-time keys for the queried devices. A map from user ID,
72 //! to a map from <algorithm>:<key_id> to the key object.
73 std::map<std::string, std::map<std::string, nlohmann::json>> one_time_keys;
74
75 friend void from_json(const nlohmann::json &obj, ClaimKeys &response);
76};
77
78//! Response from the `GET /_matrix/client/r0/keys/changes` endpoint.
79struct KeyChanges
80{
81 //! The Matrix User IDs of all users who updated their device identity keys.
82 std::vector<std::string> changed;
83 //! The Matrix User IDs of all users who may have left all the end-to-end
84 //! encrypted rooms they previously shared with the user.
85 std::vector<std::string> left;
86
87 friend void from_json(const nlohmann::json &obj, KeyChanges &response);
88};
89
90//! KeysBackup related responses.
91namespace backup {
92//! Encrypted session data using the m.megolm_backup.v1.curve25519-aes-sha2 algorithm
93struct EncryptedSessionData
94{
95 //! Generate an ephemeral curve25519 key, and perform an ECDH with the ephemeral key and the
96 //! backup's public key to generate a shared secret. The public half of the ephemeral key,
97 //! encoded using unpadded base64, becomes the ephemeral property
98 std::string ephemeral;
99 //! Stringify the JSON object, and encrypt it using AES-CBC-256 with PKCS#7 padding. This
100 //! encrypted data, encoded using unpadded base64, becomes the ciphertext property of the
101 //! session_data.
102 std::string ciphertext;
103 //! Pass the raw encrypted data (prior to base64 encoding) through HMAC-SHA-256 using the
104 //! MAC key generated above. The first 8 bytes of the resulting MAC are base64-encoded, and
105 //! become the mac property of the session_data.
106 std::string mac;
107
108 friend void from_json(const nlohmann::json &obj, EncryptedSessionData &response);
109 friend void to_json(nlohmann::json &obj, const EncryptedSessionData &response);
110};
111
112//! Responses from the `GET /_matrix/client/r0/room_keys/keys/{room_id}/{session_id}` endpoint
113struct SessionBackup
114{
115 //! Required. The index of the first message in the session that the key can decrypt.
116 int64_t first_message_index;
117 //! Required. The number of times this key has been forwarded via key-sharing between
118 //! devices.
119 int64_t forwarded_count;
120 //! Required. Whether the device backing up the key verified the device that the key is
121 //! from.
122 bool is_verified;
123 //! Required. Algorithm-dependent data. See the documentation for the backup algorithms in
124 //! Server-side key backups for more information on the expected format of the data.
125 EncryptedSessionData session_data;
126
127 friend void from_json(const nlohmann::json &obj, SessionBackup &response);
128 friend void to_json(nlohmann::json &obj, const SessionBackup &response);
129};
130
131//! Responses from the `GET /_matrix/client/r0/room_keys/keys/{room_id}` endpoint
132struct RoomKeysBackup
133{
134 //! map of session id to the individual sessions
135 std::map<std::string, SessionBackup> sessions;
136
137 friend void from_json(const nlohmann::json &obj, RoomKeysBackup &response);
138 friend void to_json(nlohmann::json &obj, const RoomKeysBackup &response);
139};
140
141//! Responses from the `GET /_matrix/client/r0/room_keys/keys` endpoint
142struct KeysBackup
143{
144 //! map of room id to map of session ids to backups of individual sessions
145 std::map<std::string, RoomKeysBackup> rooms;
146
147 friend void from_json(const nlohmann::json &obj, KeysBackup &response);
148 friend void to_json(nlohmann::json &obj, const KeysBackup &response);
149};
150
151inline constexpr const char *megolm_backup_v1 = "m.megolm_backup.v1.curve25519-aes-sha2";
152
153//! Responses from the `GET /_matrix/client/r0/room_keys/version` endpoint
154struct BackupVersion
155{
156 //! Required. The algorithm used for storing backups. Must be
157 //! 'm.megolm_backup.v1.curve25519-aes-sha2'.
158 std::string algorithm;
159 //! Required. Algorithm-dependent data. See the documentation for the backup algorithms in
160 //! Server-side key backups for more information on the expected format of the data.
161 std::string auth_data;
162 //! Required. The number of keys stored in the backup.
163 int64_t count;
164 //! Required. An opaque string representing stored keys in the backup. Clients can
165 //! compare it with the etag value they received in the request of their last key storage
166 //! request. If not equal, another client has modified the backup
167 std::string etag;
168 //! Required. The backup version
169 std::string version;
170
171 friend void from_json(const nlohmann::json &obj, BackupVersion &response);
172 friend void to_json(nlohmann::json &obj, const BackupVersion &response);
173};
174
175//! The SessionData stored in the KeysBackup.
176struct SessionData
177{
178 //! Required. The end-to-end message encryption algorithm that the key is
179 // for. Must be m.megolm.v1.aes-sha2.
180 std::string algorithm;
181 // Required. Chain of Curve25519 keys through which this
182 // session was forwarded, via m.forwarded_room_key events.
183 std::vector<std::string> forwarding_curve25519_key_chain;
184 // Required. Unpadded base64-encoded device curve25519 key.
185 std::string sender_key;
186 // Required. A map from algorithm name (ed25519) to the identity
187 // key for the sending device.
188 std::map<std::string, std::string> sender_claimed_keys;
189 // Required. Unpadded base64-encoded session key in session-sharing format.
190 std::string session_key;
191
192 friend void to_json(nlohmann::json &obj, const SessionData &desc);
193 friend void from_json(const nlohmann::json &obj, SessionData &desc);
194};
195}
196} // namespace responses
197} // namespace mtx
198