|
|
|
@ -1232,20 +1232,22 @@ access to the previously exchanged messages. To address this issue,
|
|
|
|
|
several methods are provided to allow users to transfer keys from one
|
|
|
|
|
device to another.
|
|
|
|
|
|
|
|
|
|
##### Key requests
|
|
|
|
|
|
|
|
|
|
When a device is missing keys to decrypt messages, it can request the
|
|
|
|
|
keys by sending [m.room\_key\_request](#mroom_key_request) to-device messages to other
|
|
|
|
|
devices with `action` set to `request`.
|
|
|
|
|
|
|
|
|
|
If a device wishes to share the keys with that device, it can forward
|
|
|
|
|
the keys to the first device by sending an encrypted
|
|
|
|
|
[m.forwarded\_room\_key](#mforwarded_room_key) to-device message. The first device should
|
|
|
|
|
then send an [m.room\_key\_request](#mroom_key_request) to-device message with `action`
|
|
|
|
|
set to `request_cancellation` to the other devices that it had
|
|
|
|
|
originally sent the key request to; a device that receives a
|
|
|
|
|
`request_cancellation` should disregard any previously-received
|
|
|
|
|
`request` message with the same `request_id` and `requesting_device_id`.
|
|
|
|
|
##### Key requests and forwarding
|
|
|
|
|
|
|
|
|
|
When a device is missing keys to decrypt messages, the keys can be forwarded to
|
|
|
|
|
it from a device that has the keys to allow it to decrypt the messages.
|
|
|
|
|
|
|
|
|
|
The device that is missing the keys can request the keys from other devices by
|
|
|
|
|
sending [m.room\_key\_request](#mroom_key_request) to-device messages with
|
|
|
|
|
`action` set to `request`. If a device that receives the request wishes to
|
|
|
|
|
share the keys with that device, it can forward the keys to the first device by
|
|
|
|
|
sending an encrypted [m.forwarded\_room\_key](#mforwarded_room_key) to-device
|
|
|
|
|
message. The first device should then send an
|
|
|
|
|
[m.room\_key\_request](#mroom_key_request) to-device message with `action` set
|
|
|
|
|
to `request_cancellation` to the other devices that it had originally sent the
|
|
|
|
|
key request to; a device that receives a `request_cancellation` should
|
|
|
|
|
disregard any previously-received `request` message with the same `request_id`
|
|
|
|
|
and `requesting_device_id`.
|
|
|
|
|
|
|
|
|
|
If a device does not wish to share keys with that device, it can
|
|
|
|
|
indicate this by sending an [m.room\_key.withheld](#mroom_keywithheld) to-device message,
|
|
|
|
@ -1259,6 +1261,42 @@ of the same user, and should only request and accept forwarded keys from
|
|
|
|
|
verified devices of the same user.
|
|
|
|
|
{{% /boxes/note %}}
|
|
|
|
|
|
|
|
|
|
Devices can also forward keys without waiting for a request. For example, when
|
|
|
|
|
a user is invited to an encrypted room, the inviter may wish to allow the
|
|
|
|
|
invitee to decrypt old messages, as the invitee would otherwise be unable to
|
|
|
|
|
read the messages even if the [room history visibility
|
|
|
|
|
setting](#room-history-visibility) allows them to fetch the message events.
|
|
|
|
|
|
|
|
|
|
To ensure that keys are only shared for messages sent while the history
|
|
|
|
|
visibility setting allowed for non-members to view the events, the `m.room_key`
|
|
|
|
|
event used to share the initial room key should have the `shared_history`
|
|
|
|
|
property set to `true` if the history visibility for the room is set to
|
|
|
|
|
`"world_readable"` or `"shared"`. If the history visibility for the room is any
|
|
|
|
|
other value, including being unset or an unrecognized value, the
|
|
|
|
|
`shared_history` property should be set to `false` or be unset. If the key is
|
|
|
|
|
subsequently backed up or forwarded, the `shared_history` property (if present)
|
|
|
|
|
should be preserved in the backup or `m.forwarded_room_key` event,
|
|
|
|
|
respectively.
|
|
|
|
|
|
|
|
|
|
A consequence of this is that when a room's history visibility settings change
|
|
|
|
|
such that the value of the `shared_history` property would change, event
|
|
|
|
|
senders should rotate their room keys.
|
|
|
|
|
|
|
|
|
|
This property may be used by clients to determine which keys to share with
|
|
|
|
|
other devices. For example, when inviting a user to an encrypted room, the
|
|
|
|
|
inviter may choose to share only the keys with `shared_history` set to `true`.
|
|
|
|
|
|
|
|
|
|
{{% boxes/note %}}
|
|
|
|
|
When sharing keys for old messages, clients must not blindly trust the current
|
|
|
|
|
state as reported by the homeserver: clients should not assume that users who
|
|
|
|
|
have `m.room.member` events with `membership: "join"` are legitimately in the
|
|
|
|
|
room, as such events could be spoofed by the homeserver. Clients should use
|
|
|
|
|
other means of ensuring that a user is actually in the room before sharing keys
|
|
|
|
|
for old messages with them. For example, clients can share keys for old
|
|
|
|
|
messages only to users that they invite to the room, as then they know that the
|
|
|
|
|
user is supposed to be in the room.
|
|
|
|
|
{{% /boxes/note %}}
|
|
|
|
|
|
|
|
|
|
##### Server-side key backups
|
|
|
|
|
|
|
|
|
|
Devices may upload encrypted copies of keys to the server. When a device
|
|
|
|
|