3.7 KiB
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, 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
{
"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:
{
// 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.
.