-
Notifications
You must be signed in to change notification settings - Fork 385
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2732 from uhoreg/fallback_keys
MSC2732: Olm fallback keys
- Loading branch information
Showing
1 changed file
with
97 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# MSC2732: Olm fallback keys | ||
|
||
Olm uses a set of one-time keys when initializing a session between two | ||
devices: Alice uploads one-time keys to her homeserver, and Bob claims one of | ||
them to perform a Diffie-Hellman to generate a shared key. As implied by the | ||
name, a one-time key is only to be used once. However, if all of Alice's | ||
one-time keys are claimed, Bob will not be able to create a session with Alice. | ||
|
||
This can be addressed by Alice uploading a fallback key that is used in place | ||
of a one-time key when no one-time keys are available. | ||
|
||
## Proposal | ||
|
||
A new request parameter, `fallback_keys`, is added to the body of the | ||
[`/keys/upload` client-server API](https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-keys-upload), which is in the same format as the | ||
`one_time_keys` parameter with the exception that there must be at most one key | ||
per key algorithm. If the user had previously uploaded a fallback key for a | ||
given algorithm, it is replaced -- the server will only keep one fallback key | ||
per algorithm for each user. | ||
|
||
When uploading fallback keys for algorithms whose key format is a signed JSON | ||
object, client should include a property named `fallback` with a value of | ||
`true`. | ||
|
||
Example: | ||
|
||
`POST /keys/upload` | ||
|
||
```json | ||
{ | ||
"fallback_keys": { | ||
"signed_curve25519:AAAAAA": { | ||
"key": "base64+public+key", | ||
"fallback": true, | ||
"signatures": { | ||
"@alice:example.org": { | ||
"ed25519:DEVICEID": "base64+signature" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
When Bob calls `/keys/claim` to claim one of Alice's one-time keys, but Alice | ||
has no one-time keys left, the homeserver will return the fallback key instead, | ||
if Alice had previously uploaded one. Unlike with one-time keys, fallback keys | ||
are not deleted when they are returned by `/keys/claim`. However, the server | ||
marks that they have been used. | ||
|
||
A new response parameter, `device_unused_fallback_key_types`, is added to | ||
`/sync`. This is an array listing the key algorithms for which the server has | ||
an unused fallback key for the device. If the client wants the server to have a | ||
fallback key for a given key algorithm, but that algorithm is not listed in | ||
`device_unused_fallback_key_types`, the client will upload a new key as above. | ||
|
||
The `device_unused_fallback_key_types` parameter must be present if the server | ||
supports fallback keys. Clients can thus treat this field as an indication | ||
that the server supports fallback keys, and so only upload fallback keys to | ||
servers that support them. | ||
|
||
Example: | ||
|
||
`GET /sync` | ||
|
||
Response: | ||
|
||
```jsonc | ||
{ | ||
// other fields... | ||
"device_unused_fallback_key_types": ["signed_curve25519"] | ||
} | ||
``` | ||
|
||
## Security considerations | ||
|
||
Using a fallback key rather than a one-time key has security implications. An | ||
attacker can replay a message that was originally sent with a fallback key, and | ||
the receiving client will accept it as a new message if the fallback key is | ||
still active. Also, an attacker that compromises a client may be able to | ||
retrieve the private part of the fallback key to decrypt past messages if the | ||
client has still retained the private part of the fallback key. | ||
|
||
For this reason, clients should not store the private part of the fallback key | ||
indefinitely. For example, client should only store at most two fallback keys: | ||
the current fallback key (that it has not yet received any messages for) and | ||
the previous fallback key, and should remove the previous fallback key once it | ||
is reasonably certain that it has received all the messages that use it (for | ||
example, one hour after receiving the first message that used it). | ||
|
||
For addressing replay attacks, clients can also keep track of inbound sessions | ||
to detect replays. | ||
|
||
## Unstable prefix | ||
|
||
The `fallback_keys` request parameter and the `device_unused_fallback_key_types` | ||
response parameter will be prefixed by `org.matrix.msc2732.`. |