Skip to content

Commit 1b81970

Browse files
committed
initial commit of e2e backup proposal
1 parent f5dc0ea commit 1b81970

File tree

1 file changed

+197
-0
lines changed

1 file changed

+197
-0
lines changed
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
Storing megolm keys serverside
2+
==============================
3+
4+
Background
5+
----------
6+
7+
We *optionally* let clients store a copy of their megolm inbound session keys
8+
on the HS so that they can recover history if all devices are lost without an
9+
explicit key export; transparently share history between a user's devices;
10+
transparently share missing keys between a user's devices to fix UISIs; support
11+
clients with limited local storage for keys.
12+
13+
See also:
14+
15+
* https://github.com/matrix-org/matrix-doc/issues/1219
16+
* https://github.com/vector-im/riot-web/issues/3661
17+
* https://github.com/vector-im/riot-web/issues/5675
18+
* https://docs.google.com/document/d/1MOoIA9qEKIhUQ3UmKZG-loqA8e0BzgWKKlKRUGMynVc/edit#
19+
(old version of proposal)
20+
21+
Proposal
22+
--------
23+
24+
This proposal creates new APIs to allow clients to back up room decryption keys
25+
on the server. Decryption keys are encrypted (using public key crypto) before
26+
being sent to the server along with some unencrypted metadata to allow the
27+
server to manage the backups, overwriting backups with "better" versions of the
28+
keys. The user is given a private recovery key to save for recovering the keys
29+
from the backup.
30+
31+
Clients can create new versions of backups. A client would start a new version
32+
of a backup when, for example, a user loses a device, and wants to ensure that
33+
that device does not get any new decryption keys.
34+
35+
### Possible UX for interactive clients
36+
37+
On receipt of encryption keys (1st time):
38+
39+
1. client checks if there is an existing backup: `GET /room_keys/version`
40+
1. if not, ask if the user wants to back up keys
41+
1. if yes:
42+
1. generate new key pair
43+
2. create new backup version: `POST /room_keys/version`
44+
3. display private key to user to save
45+
2. if no, exit and remember decision (user can change their mind later)
46+
3. while prompting, continue to poll `GET /room_keys/versions`, as
47+
another device may have created a backup. If so, go to 1.2.
48+
2. if yes, get public key, prompt user to verify a device that signed the
49+
key¹, or enter recovery key (which can derive the backup key).
50+
1. User can also decide to create a new backup, in which case, go to 1.1.
51+
2. send key to backup: `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v`
52+
3. continue backing up keys as we receive them (may receive a 403 error if a
53+
new backup version has been created: see below)
54+
55+
On 403 error when trying to `PUT` keys:
56+
57+
1. get the current version
58+
2. notify the user that there is a new backup version, and display relevant
59+
information
60+
3. confirm with user that they want to use the backup (user may want use the
61+
backup, to stop backing up keys, or to create a new backup)
62+
4. verify the device that signed the backup key¹, or enter recovery key
63+
64+
¹: cross-signing (when that is completed) can be used to verify the device
65+
that signed the key.
66+
67+
On receipt of undecryptable message:
68+
69+
1. ask user if they want to restore backup (ask whether to get individual key,
70+
room keys, or all keys). (This can be done in the same place as asking if
71+
the user wants to request keys from other devices.)
72+
2. if yes, prompt for private key, and get keys: `GET /room_keys/keys`
73+
74+
### API
75+
76+
#### Backup versions
77+
78+
##### `POST /room_keys/version`
79+
80+
Create a new backup version.
81+
82+
Body parameters:
83+
84+
- `algorithm` (string): Required. The algorithm used for storing backups.
85+
Currently, only `m.megolm_backup.v1` is defined. (FIXME: change the algorithm
86+
name to include the encryption method)
87+
- `auth_data` (string or object): Required. algorithm-dependent data. For
88+
`m.megolm_backup.v1`, this is a signedjson object with the following keys:
89+
- `public_key` (string): ...
90+
- `signatures` (object): signatures of the public key
91+
92+
Example:
93+
94+
```javascript
95+
{
96+
"algorithm": "m.megolm_backup.v1",
97+
"auth_data": {
98+
"public_key": {
99+
"public_key": "abcdefg",
100+
"signatures": {
101+
"something": {
102+
"ed25519:something": "hijklmnop"
103+
}
104+
}
105+
}
106+
}
107+
}
108+
```
109+
110+
On success, returns a JSON object with keys:
111+
112+
- `version` (integer): the backup version
113+
114+
##### `GET /room_keys/version`
115+
116+
Get information about the current version.
117+
118+
On success, returns a JSON object with keys:
119+
120+
- `algorithm` (string): Required. Same as in the body parameters for `POST
121+
/room_keys/version`.
122+
- `auth_data` (string or object): Required. Same as in the body parameters for
123+
`POST /room_keys/version`.
124+
- `version` (integer): the backup version
125+
126+
127+
#### Storing keys
128+
129+
##### `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v`
130+
131+
Store the key for the given session in the given room, using the given backup
132+
version.
133+
134+
If the server already has a backup in the backup version for the given session
135+
and room, then it will keep the "better" one ...
136+
137+
Body parameters:
138+
139+
- `first_message_index` (integer): Required. The index of the first message
140+
in the session that the key can decrypt.
141+
- `forwarded_count` (integer): Required. The number of times this key has been
142+
forwarded.
143+
- `is_verified` (boolean): Whether the device backing up the key has verified
144+
the device that the key is from.
145+
- `session_data` (string): The backup of the key, encrypted according to the
146+
backup algorithm.
147+
148+
On success, returns ... ?
149+
150+
##### `PUT /room_keys/keys/${roomId}?version=$v`
151+
152+
Store several keys for the given room, using the given backup version.
153+
154+
Behaves the same way as if the keys were added individually using `PUT
155+
/room_keys/keys/${roomId}/${sessionId}?version=$v`.
156+
157+
Body paremeters:
158+
- `sessions` (object): an object where the keys are the session IDs, and the
159+
values are objects of the same form as the body in `PUT
160+
/room_keys/keys/${roomId}/${sessionId}?version=$v`.
161+
162+
On success, returns same as `PUT
163+
/room_keys/keys/${roomId}/${sessionId}?version=$v`
164+
165+
##### `PUT /room_keys/keys/?version=$v`
166+
167+
...
168+
169+
#### Retrieving keys
170+
171+
##### `GET /room_keys/keys/${roomId}/${sessionId}?version=$v`
172+
##### `GET /room_keys/keys/${roomId}?version=$v`
173+
##### `GET /room_keys/keys/?version=$v`
174+
175+
#### Deleting keys
176+
177+
##### `DELETE /room_keys/keys/${roomId}/${sessionId}?version=$v`
178+
##### `DELETE /room_keys/keys/${roomId}?version=$v`
179+
##### `DELETE /room_keys/keys/?version=$v`
180+
181+
Tradeoffs
182+
---------
183+
184+
Security Considerations
185+
-----------------------
186+
187+
An attacker who gains access to a user's account can delete or corrupt their
188+
key backup. This proposal does not attempt to protect against that.
189+
190+
Other Issues
191+
------------
192+
193+
Since many clients will receive encryption keys at around the same time,
194+
clients should randomly offset their requests ...
195+
196+
Conclusion
197+
----------

0 commit comments

Comments
 (0)