mirror of
https://github.com/matrix-org/matrix-spec
synced 2025-12-23 17:48:37 +01:00
clarifications, change "hash" to "etag"
This commit is contained in:
parent
7ed5367516
commit
cf953c47fd
|
|
@ -38,20 +38,26 @@ Proposal
|
||||||
--------
|
--------
|
||||||
|
|
||||||
This proposal creates new APIs to allow clients to back up room decryption keys
|
This proposal creates new APIs to allow clients to back up room decryption keys
|
||||||
on the server. Decryption keys are encrypted (using public key crypto) before
|
on the server. Room decryption keys are encrypted (using public key crypto)
|
||||||
being sent to the server along with some unencrypted metadata to allow the
|
before being sent to the server along with some unencrypted metadata to allow
|
||||||
server to manage the backups, overwriting backups with "better" versions of the
|
the server to manage the backups. If a key for a new megolm session is
|
||||||
keys. The user is given a private recovery key to save for recovering the keys
|
uploaded, it is added to the current backup. If a key is uploaded for a megolm
|
||||||
from the backup.
|
session is that is already present in the backup, the server will use the
|
||||||
|
metadata to determine which version of the key is "better". The way in which
|
||||||
|
the server determines which key is "better" is described in the [Storing
|
||||||
|
Keys](#storing-keys) section. The user is given a private recovery key in
|
||||||
|
order to recover the keys from the backup in the future.
|
||||||
|
|
||||||
Clients can create new versions of backups. Aside from the initial backup
|
Clients can create new key backups (sometimes also referred to in the API as
|
||||||
creation, a client might start a new version of a backup when, for example, a
|
backup versions) to replace the current backup. Aside from the initial backup
|
||||||
user loses a device, and wants to ensure that that device does not get any new
|
creation, a client might start a new a backup when, for example, a user loses a
|
||||||
decryption keys.
|
device and wants to ensure that that device does not get any new decryption
|
||||||
|
keys. In this case, the client will then create a new backup using a new key
|
||||||
|
that the device does not have access to.
|
||||||
|
|
||||||
Once one client has created a backup version, other clients can fetch the
|
Once one client has created a backup, other clients can fetch the public part
|
||||||
public key for the backup from the server and add keys to the backup, if they
|
of the recovery key from the server and add keys to the backup, if they trust
|
||||||
trust that the backup was not created by a malicious device.
|
that the backup was not created by a malicious device.
|
||||||
|
|
||||||
### Possible UX for interactive clients
|
### Possible UX for interactive clients
|
||||||
|
|
||||||
|
|
@ -63,31 +69,30 @@ On receipt of encryption keys (1st time):
|
||||||
1. client checks if there is an existing backup: `GET /room_keys/version`
|
1. client checks if there is an existing backup: `GET /room_keys/version`
|
||||||
1. if not, ask if the user wants to back up keys
|
1. if not, ask if the user wants to back up keys
|
||||||
1. if yes:
|
1. if yes:
|
||||||
1. generate new curve25519 key pair
|
1. generate new curve25519 key pair, which will be the recovery key
|
||||||
2. create new backup version: `POST /room_keys/version`
|
2. create new backup: `POST /room_keys/version`
|
||||||
3. display private key for user to save (see below for the format)
|
3. display private key for user to save (see below for the
|
||||||
|
[format of the recovery key](#recovery-key))
|
||||||
2. if no, exit and remember decision (user can change their mind later)
|
2. if no, exit and remember decision (user can change their mind later)
|
||||||
3. while prompting, continue to poll `GET /room_keys/versions`, as
|
3. while prompting, continue to poll `GET /room_keys/versions`, as
|
||||||
another device may have created a backup. If so, go to 1.2.
|
another device may have created a backup. If so, go to 1.2.
|
||||||
2. if yes, get public key, prompt user to verify a device that signed the
|
2. if yes, either get the public part of the recovery key and check that it
|
||||||
key¹, or enter recovery key (which can derive the backup key).
|
is signed by the master cross-signing key, or prompt user to enter the
|
||||||
|
private part of the recovery key (which can derive the public part).
|
||||||
1. User can also decide to create a new backup, in which case, go to 1.1.
|
1. User can also decide to create a new backup, in which case, go to 1.1.
|
||||||
2. send key to backup: `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v`
|
2. send key to backup: `PUT /room_keys/keys/${roomId}/${sessionId}?version=$v`
|
||||||
3. continue backing up keys as we receive them (may receive a
|
3. continue backing up keys as we receive them (may receive a
|
||||||
`M_WRONG_ROOM_KEYS_VERSION` error if a new backup version has been created:
|
`M_WRONG_ROOM_KEYS_VERSION` error if a new backup has been created:
|
||||||
see below)
|
see below)
|
||||||
|
|
||||||
On `M_WRONG_ROOM_KEYS_VERSION` error when trying to `PUT` keys:
|
On `M_WRONG_ROOM_KEYS_VERSION` error when trying to `PUT` keys:
|
||||||
|
|
||||||
1. get the current version
|
1. get the current version
|
||||||
2. notify the user that there is a new backup version, and display relevant
|
2. notify the user that there is a new backup, and display relevant information
|
||||||
information
|
|
||||||
3. confirm with user that they want to use the backup (user may want use the
|
3. confirm with user that they want to use the backup (user may want use the
|
||||||
backup, to stop backing up keys, or to create a new backup)
|
backup, to stop backing up keys, or to create a new backup)
|
||||||
4. verify the device that signed the backup key¹, or enter recovery key
|
4. ensure the backup key is signed by the user's master key, or prompt the user
|
||||||
|
to enter the recovery key
|
||||||
¹: cross-signing (when that is completed) can be used to verify the device
|
|
||||||
that signed the key.
|
|
||||||
|
|
||||||
On receipt of undecryptable message:
|
On receipt of undecryptable message:
|
||||||
|
|
||||||
|
|
@ -125,7 +130,7 @@ is 35 bytes. Clients must then remove the first two bytes and the last byte,
|
||||||
and use the resulting string as the private key to decrypt backups.
|
and use the resulting string as the private key to decrypt backups.
|
||||||
|
|
||||||
If MSC1946 is used to store the key on the server, it must be stored using the
|
If MSC1946 is used to store the key on the server, it must be stored using the
|
||||||
`account_data` `type` `m.megolm_backup.v1`.
|
`account_data` type `m.megolm_backup.v1`.
|
||||||
|
|
||||||
As a special case, if the recovery key is the same as the curve25519 key used
|
As a special case, if the recovery key is the same as the curve25519 key used
|
||||||
for storing the key, then the contents of the `m.megolm_backup.v1`
|
for storing the key, then the contents of the `m.megolm_backup.v1`
|
||||||
|
|
@ -160,8 +165,8 @@ Body parameters:
|
||||||
- `algorithm` (string): Required. The algorithm used for storing backups.
|
- `algorithm` (string): Required. The algorithm used for storing backups.
|
||||||
Currently, only `m.megolm_backup.v1.curve25519-aes-sha2` is defined.
|
Currently, only `m.megolm_backup.v1.curve25519-aes-sha2` is defined.
|
||||||
- `auth_data` (object): Required. algorithm-dependent data. For
|
- `auth_data` (object): Required. algorithm-dependent data. For
|
||||||
`m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of
|
`m.megolm_backup.v1.curve25519-aes-sha2`, see below for the [definition of
|
||||||
this property.
|
this property](#auth_data-backup-versions).
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
|
@ -195,10 +200,10 @@ On success, returns a JSON object with keys:
|
||||||
- `auth_data` (object): Required. Same as in the body parameters for
|
- `auth_data` (object): Required. Same as in the body parameters for
|
||||||
`POST /room_keys/version`.
|
`POST /room_keys/version`.
|
||||||
- `version` (string): Required. The backup version.
|
- `version` (string): Required. The backup version.
|
||||||
- `hash` (string): Required. The hash value which is an opaque string
|
- `etag` (string): Required. The etag value which is an opaque string
|
||||||
representing stored keys in the backup. Client can compare it with the `hash`
|
representing stored keys in the backup. Clients can compare it with the
|
||||||
value they received in the response of their last key storage request.
|
`etag` value they received in the response of their last key storage request.
|
||||||
If not equal, another matrix client pushed new keys to the backup.
|
If not equal, another client has pushed new keys to the backup.
|
||||||
- `count` (number): Required. The number of keys stored in the backup.
|
- `count` (number): Required. The number of keys stored in the backup.
|
||||||
|
|
||||||
Error codes:
|
Error codes:
|
||||||
|
|
@ -214,8 +219,8 @@ Body parameters:
|
||||||
- `algorithm` (string): Required. Must be the same as in the body parameters for `GET
|
- `algorithm` (string): Required. Must be the same as in the body parameters for `GET
|
||||||
/room_keys/version`.
|
/room_keys/version`.
|
||||||
- `auth_data` (object): Required. algorithm-dependent data. For
|
- `auth_data` (object): Required. algorithm-dependent data. For
|
||||||
`m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of
|
`m.megolm_backup.v1.curve25519-aes-sha2`, see below for the [definition of
|
||||||
this property.
|
this property](#auth_data-backup-versions).
|
||||||
- `version` (string): Required. The backup version. Must be the same as the query parameter or must be the current version.
|
- `version` (string): Required. The backup version. Must be the same as the query parameter or must be the current version.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
@ -251,9 +256,15 @@ version.
|
||||||
|
|
||||||
If the server already has a backup in the backup version for the given session
|
If the server already has a backup in the backup version for the given session
|
||||||
and room, then it will keep the "better" one. To determine which one is
|
and room, then it will keep the "better" one. To determine which one is
|
||||||
"better", key backups are compared first by the `is_verified` flag (`true` is
|
"better", keys are compared:
|
||||||
better than `false`), then by the `first_message_index` (a lower number is better),
|
|
||||||
and finally by `forwarded_count` (a lower number is better).
|
- first by the `is_verified` flag (`true` is better than `false`),
|
||||||
|
- then, if `is_verified` is equal, by the `first_message_index` (a lower number is better),
|
||||||
|
- and finally, is `is_verified` and `first_message_index` are equal, by
|
||||||
|
`forwarded_count` (a lower number is better).
|
||||||
|
|
||||||
|
If neither key is better than the other (that is, if all three fields are
|
||||||
|
equal), then the server should keep the existing key.
|
||||||
|
|
||||||
Body parameters:
|
Body parameters:
|
||||||
|
|
||||||
|
|
@ -264,12 +275,12 @@ Body parameters:
|
||||||
- `is_verified` (boolean): Required. Whether the device backing up the key has
|
- `is_verified` (boolean): Required. Whether the device backing up the key has
|
||||||
verified the device that the key is from.
|
verified the device that the key is from.
|
||||||
- `session_data` (object): Required. Algorithm-dependent data. For
|
- `session_data` (object): Required. Algorithm-dependent data. For
|
||||||
`m.megolm_backup.v1.curve25519-aes-sha2`, see below for the definition of
|
`m.megolm_backup.v1.curve25519-aes-sha2`, see below for the [definition of
|
||||||
this property.
|
this property](#auth_data-backup-versions).
|
||||||
|
|
||||||
On success, returns a JSON object with keys:
|
On success, returns a JSON object with keys:
|
||||||
|
|
||||||
- `hash` (string): Required. The new hash value representing stored keys. See
|
- `etag` (string): Required. The new etag value representing stored keys. See
|
||||||
`GET /room_keys/version/{version}` for more details.
|
`GET /room_keys/version/{version}` for more details.
|
||||||
- `count` (number): Required. The new count of keys stored in the backup.
|
- `count` (number): Required. The new count of keys stored in the backup.
|
||||||
|
|
||||||
|
|
@ -299,7 +310,7 @@ Result:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
{
|
{
|
||||||
"hash": "abcdefghi",
|
"etag": "abcdefghi",
|
||||||
"count": 10
|
"count": 10
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -344,7 +355,7 @@ Result:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
{
|
{
|
||||||
"hash": "abcdefghi",
|
"etag": "abcdefghi",
|
||||||
"count": 10
|
"count": 10
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -393,7 +404,7 @@ Result:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
{
|
{
|
||||||
"hash": "abcdefghi",
|
"etag": "abcdefghi",
|
||||||
"count": 10
|
"count": 10
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -401,7 +412,7 @@ Result:
|
||||||
#### Retrieving keys
|
#### Retrieving keys
|
||||||
|
|
||||||
When retrieving keys, the `version` parameter is optional, and defaults to
|
When retrieving keys, the `version` parameter is optional, and defaults to
|
||||||
retrieving the latest backup version.
|
retrieving keys from the latest backup version.
|
||||||
|
|
||||||
##### `GET /room_keys/keys/${roomId}/${sessionId}?version=$v`
|
##### `GET /room_keys/keys/${roomId}/${sessionId}?version=$v`
|
||||||
|
|
||||||
|
|
@ -463,7 +474,8 @@ Error codes:
|
||||||
|
|
||||||
Deletes keys from the backup.
|
Deletes keys from the backup.
|
||||||
|
|
||||||
On success, returns the empty JSON object.
|
Returns the same as `PUT
|
||||||
|
/room_keys/keys/${roomId}/${sessionId}?version=$v`.
|
||||||
|
|
||||||
#### `m.megolm_backup.v1.curve25519-aes-sha2` definitions
|
#### `m.megolm_backup.v1.curve25519-aes-sha2` definitions
|
||||||
|
|
||||||
|
|
@ -479,9 +491,9 @@ following keys:
|
||||||
|
|
||||||
The `auth_data` should be signed by the user's [master cross-signing
|
The `auth_data` should be signed by the user's [master cross-signing
|
||||||
key](https://github.com/matrix-org/matrix-doc/pull/1756), and may also be
|
key](https://github.com/matrix-org/matrix-doc/pull/1756), and may also be
|
||||||
signed by the user's device key. The allows clients to ensure that the public
|
signed by the user's device key. This allows clients to ensure that the public
|
||||||
key is valid, and prevents an attacker from being able to change the backup to
|
key is valid, and prevents an attacker from being able to change the backup to
|
||||||
use a public key that have the private key for.
|
use a public key that they have the private key for.
|
||||||
|
|
||||||
##### `session_data` for key backups
|
##### `session_data` for key backups
|
||||||
|
|
||||||
|
|
@ -489,7 +501,9 @@ The `session_data` field in the backups is constructed as follows:
|
||||||
|
|
||||||
1. Encode the session key to be backed up as a JSON object with the properties:
|
1. Encode the session key to be backed up as a JSON object with the properties:
|
||||||
- `algorithm` (string): `m.megolm.v1.aes-sha2`
|
- `algorithm` (string): `m.megolm.v1.aes-sha2`
|
||||||
- `sender_key` (string): base64-encoded device curve25519 key
|
- `sender_key` (string): base64-encoded device curve25519 key in
|
||||||
|
[session-sharing
|
||||||
|
format](https://gitlab.matrix.org/matrix-org/olm/blob/master/docs/megolm.md#session-sharing-format)
|
||||||
- `sender_claimed_keys` (object): object containing the identity keys for the
|
- `sender_claimed_keys` (object): object containing the identity keys for the
|
||||||
sending device
|
sending device
|
||||||
- `forwarding_curve25519_key_chain` (array): zero or more curve25519 keys
|
- `forwarding_curve25519_key_chain` (array): zero or more curve25519 keys
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue