|
| 1 | +# Key verification in DMs |
| 2 | + |
| 3 | +Currently, key verification is done using `to_device` messages. However, since |
| 4 | +`to_device` messages are not part of a timeline, there is no user-visible |
| 5 | +record of the key verification. |
| 6 | + |
| 7 | +As well, the current key verification framework does not provide any feedback |
| 8 | +when interacting with clients that do not support it; if a client does not |
| 9 | +support the key verification framework, there is no way for users to discover |
| 10 | +this other than waiting for a while and noticing that nothing is happening. |
| 11 | + |
| 12 | +This proposal will solve both problems. |
| 13 | + |
| 14 | +## Proposal |
| 15 | + |
| 16 | +The current [key verification |
| 17 | +framework](https://matrix.org/docs/spec/client_server/r0.5.0#key-verification-framework) |
| 18 | +will be replaced by a new framework that uses room messages rather than |
| 19 | +`to_device` messages. Key verification messages will be sent in a [Direct |
| 20 | +Messaging](https://matrix.org/docs/spec/client_server/r0.5.0#id185) room. If |
| 21 | +there is no Direct Messaging room between the two users involved, the client |
| 22 | +that initiates the key verification will create one. |
| 23 | + |
| 24 | +In this proposal, we use "Alice" to denote the user who initiates the key |
| 25 | +verification, and "Bob" to denote the other user involved in the key |
| 26 | +verification. |
| 27 | + |
| 28 | +### General framework |
| 29 | + |
| 30 | +#### Requesting a key verification |
| 31 | + |
| 32 | +To request a key verification, Alice will send an `m.room.message` event with the |
| 33 | +following properties in its contents: |
| 34 | + |
| 35 | +- `body`: a fallback message to alert users that their client does not support |
| 36 | + the key verification framework, and that they should use a different method |
| 37 | + to verify keys. For example, "Alice is requesting to verify keys with you. |
| 38 | + However, your client does not support this method, so you will need to use |
| 39 | + the legacy method of key verification." |
| 40 | + |
| 41 | + Clients that do support the key verification framework should hide the body |
| 42 | + and instead present the user with an interface to accept or reject the key |
| 43 | + verification. |
| 44 | + |
| 45 | + The event may also contain `format` and `formatted_body` properties as |
| 46 | + described in the [m.room.message |
| 47 | + msgtypes](https://matrix.org/docs/spec/client_server/r0.5.0#m-room-message-msgtypes) |
| 48 | + section of the spec. Clients that support the key verification should |
| 49 | + similarly hide these from the user. |
| 50 | +- `msgtype`: `m.key.verification.request` |
| 51 | +- `methods`: the verification methods supported by Alice's client |
| 52 | +- `to`: Bob's Matrix ID. Users should only respond to verification requests if |
| 53 | + they are named in this field. Users who are not named in this field and who |
| 54 | + did not send this event should ignore all other events that have a |
| 55 | + `m.reference` relationship with this event. |
| 56 | +- `from_device`: Alice's device ID. This is required since some verification |
| 57 | + methods may use the device IDs as part of the verification process. |
| 58 | + |
| 59 | +Key verifications will be identified by the event ID of the key verification |
| 60 | +request event. |
| 61 | + |
| 62 | +Clients should ignore verification requests that have been accepted or |
| 63 | +cancelled, or if they do not belong to the sending or target users. |
| 64 | + |
| 65 | +The way that clients display this event can depend on which user and device the |
| 66 | +client belongs to, and what state the verification is in. For example: |
| 67 | + |
| 68 | +- If the verification has been completed (there is an `m.key.verification.done` |
| 69 | + or `m.key.verification.cancel` event), the client can indicate that the |
| 70 | + verification was successful or had an error. |
| 71 | +- If the verification has been accepted (there is an `m.key.verification.start` |
| 72 | + event) but has not been completed, the two devices involved can indicate that |
| 73 | + the verification is in progress and can use this event as a place in the |
| 74 | + room's timeline to display progress of the key verification and to interact |
| 75 | + with the user as necessary. Other devices can indicate that the verification |
| 76 | + is in progress on other devices. |
| 77 | +- If the verification has not been accepted, clients for the target user can |
| 78 | + indicate that a verification has been requested and allow the user to accept |
| 79 | + the verification on that device. The sending client can indicate that it is |
| 80 | + waiting for the request to be accepted, and the sending user's other clients |
| 81 | + can indicate the that a request was initiated on a different device. |
| 82 | + |
| 83 | +Clients may choose to display or not to display events of any other type that |
| 84 | +reference the original request event; but it must not have any effect on the |
| 85 | +verification itself. |
| 86 | + |
| 87 | +#### Accepting a key verification |
| 88 | + |
| 89 | +To accept a key verification, Bob will send an `m.key.verification.ready` event |
| 90 | +with the following properties in its contents: |
| 91 | + |
| 92 | +- `m.relates_to`: an object with the properties: |
| 93 | + - `rel_type`: `m.reference` |
| 94 | + - `event_id`: the event ID of the key verification request that is being |
| 95 | + accepted |
| 96 | +- `methods`: an array of verification methods that the device supports |
| 97 | +- `from_device`: Bob's device ID. This is required since some verification |
| 98 | + methods may use the device IDs as part of the verification process. |
| 99 | + |
| 100 | +(Note: the form of the `m.relates_to` property is based on the current state of |
| 101 | +[MSC2674](https://github.com/matrix-org/matrix-doc/pull/2674), but is |
| 102 | +independent from it since this MSC does not rely on any aggregations features.) |
| 103 | + |
| 104 | +Clients should ignore `m.key.verification.ready` events that correspond to |
| 105 | +verification requests that they did not send. |
| 106 | + |
| 107 | +After this, either Alice or Bob may start the verification by sending an |
| 108 | +`m.key.verification.start` event with the following properties in its contents: |
| 109 | + |
| 110 | +- `m.relates_to`: an object with the properties: |
| 111 | + - `rel_type`: `m.reference` |
| 112 | + - `event_id`: the event ID of the key verification request that is being |
| 113 | + started |
| 114 | +- `method`: the key verification method that is being used. This should be a |
| 115 | + method that both Alice's and Bob's devices support. |
| 116 | +- `from_device`: The user's device ID. |
| 117 | + |
| 118 | +If both Alice and Bob send an `m.key.verification.start` message, and they both |
| 119 | +specify the same verification method, then the event sent by the user whose |
| 120 | +user ID is the smallest is used, and the other event is ignored. If they both |
| 121 | +send an `m.key.verification.start` message and the method is different, then |
| 122 | +the verification should be cancelled with a `code` of `m.unexpected_message`. |
| 123 | + |
| 124 | +After the `m.key.verification.start` event is sent, the devices may exchange |
| 125 | +messages (if any) according to the verification method in use. |
| 126 | + |
| 127 | +#### Rejecting a key verification |
| 128 | + |
| 129 | +To reject a key verification, Alice or Bob will send an |
| 130 | +`m.key.verification.cancel` event with the following properties in its |
| 131 | +contents: |
| 132 | + |
| 133 | +- `m.relates_to`: an object with the properties: |
| 134 | + - `rel_type`: `m.reference` |
| 135 | + - `event_id`: the event ID of the key verification that is being cancelled |
| 136 | +- `reason`: A human readable description of the `code`. The client should only |
| 137 | + rely on this string if it does not understand the `code`. |
| 138 | +- `code`: The error code for why the process/request was cancelled by the |
| 139 | + user. The contents are the same as the `code` property of the currently |
| 140 | + defined [`m.key.verification.cancel` to-device |
| 141 | + event](https://matrix.org/docs/spec/client_server/r0.5.0#m-key-verification-cancel), |
| 142 | + or as defined for specific key verification methods. |
| 143 | + |
| 144 | +This message may be sent at any point in the key verification process. Any |
| 145 | +subsequent key verification messages relating to the same request are ignored. |
| 146 | +However, this does not undo any verifications that have already been done. |
| 147 | + |
| 148 | +#### Concluding a key verification |
| 149 | + |
| 150 | +When the other user's key is verified and no more messages are expected, each |
| 151 | +party will send an `m.key.verification.done` event with the following |
| 152 | +properties in its contents: |
| 153 | + |
| 154 | +- `m.relates_to`: an object with the properties: |
| 155 | + - `rel_type`: `m.reference` |
| 156 | + - `event_id`: the event ID of the key verification that is being concluded |
| 157 | + |
| 158 | +This provides a record within the room of the result of the verification. |
| 159 | + |
| 160 | +Any subsequent key verification messages relating to the same request are |
| 161 | +ignored. |
| 162 | + |
| 163 | +Although a client may have successfully completed its side of the verification, |
| 164 | +it may wait until receiving an `m.key.verification.done` (or |
| 165 | +`m.key.verification.cancel`) event from the other device before informing the |
| 166 | +user that the verification was successful or unsuccessful. |
| 167 | + |
| 168 | +#### Other events |
| 169 | + |
| 170 | +Key verification methods may define their own event types, or extensions to the |
| 171 | +above event types. All events sent as part of a key verification process |
| 172 | +should have an `m.relates_to` property as defined for |
| 173 | +`m.key.verification.accept` or `m.key.verification.cancel` events. |
| 174 | + |
| 175 | +Clients should ignore events with an `m.relates_to` that have a `rel_type` of |
| 176 | +`m.reference` that refer to a verification where it is neither the requester |
| 177 | +nor the accepter. |
| 178 | + |
| 179 | +Clients should not redact or edit verification messages. A client may ignore |
| 180 | +redactions or edits of key verification messages, or may cancel the |
| 181 | +verification with a `code` of `m.unexpected_message` when it receives a |
| 182 | +redaction or edit. |
| 183 | + |
| 184 | +### SAS verification |
| 185 | + |
| 186 | +The messages used in SAS verification are the same as those currently defined, |
| 187 | +except that instead of the `transaction_id` property, an `m.relates_to` |
| 188 | +property, as defined above, is used instead. |
| 189 | + |
| 190 | +If the key verification messages are encrypted, the hash commitment sent in the |
| 191 | +`m.key.verification.accept` message MUST be based on the decrypted |
| 192 | +`m.key.verification.start` message contents, and include the `m.relates_to` |
| 193 | +field, even if the decrypted message contents do not include that field. For |
| 194 | +example, if Alice sends a message to start the SAS verification: |
| 195 | + |
| 196 | +```json |
| 197 | +{ |
| 198 | + "content": { |
| 199 | + "algorithm": "m.megolm.v1.aes-sha2", |
| 200 | + "ciphertext": "ABCDEFG...", |
| 201 | + "device_id": "Dynabook", |
| 202 | + "sender_key": "alice+sender+key", |
| 203 | + "session_id": "session+id", |
| 204 | + "m.relates_to": { |
| 205 | + "rel_type": "m.reference", |
| 206 | + "event_id": "$verification_request_event" |
| 207 | + } |
| 208 | + }, |
| 209 | + "event_id": "$event_id", |
| 210 | + "origin_server_ts": 1234567890, |
| 211 | + "sender": "@alice:example.org", |
| 212 | + "type": "m.room.encrypted", |
| 213 | + "room_id": "!room_id:example.org" |
| 214 | +} |
| 215 | +``` |
| 216 | + |
| 217 | +which, when decrypted, yields: |
| 218 | + |
| 219 | +```json |
| 220 | +{ |
| 221 | + "room_id": "!room_id:example.org", |
| 222 | + "type": "m.key.verification.start", |
| 223 | + "content": { |
| 224 | + "from_device": "Dynabook", |
| 225 | + "hashes": [ |
| 226 | + "sha256" |
| 227 | + ], |
| 228 | + "key_agreement_protocols": [ |
| 229 | + "curve25519" |
| 230 | + ], |
| 231 | + "message_authentication_codes": [ |
| 232 | + "hkdf-hmac-sha256" |
| 233 | + ], |
| 234 | + "method": "m.sas.v1", |
| 235 | + "short_authentication_string": [ |
| 236 | + "decimal", |
| 237 | + "emoji" |
| 238 | + ] |
| 239 | + } |
| 240 | +} |
| 241 | +``` |
| 242 | + |
| 243 | +then the hash commitment will be based on the message contents: |
| 244 | + |
| 245 | +```json |
| 246 | +{ |
| 247 | + "from_device": "Dynabook", |
| 248 | + "hashes": [ |
| 249 | + "sha256" |
| 250 | + ], |
| 251 | + "key_agreement_protocols": [ |
| 252 | + "curve25519" |
| 253 | + ], |
| 254 | + "message_authentication_codes": [ |
| 255 | + "hkdf-hmac-sha256" |
| 256 | + ], |
| 257 | + "method": "m.sas.v1", |
| 258 | + "short_authentication_string": [ |
| 259 | + "decimal", |
| 260 | + "emoji" |
| 261 | + ], |
| 262 | + "m.relates_to": { |
| 263 | + "rel_type": "m.reference", |
| 264 | + "event_id": "$verification_request_event" |
| 265 | + } |
| 266 | +} |
| 267 | +``` |
| 268 | + |
| 269 | +## Alternatives |
| 270 | + |
| 271 | +Messages sent by the verification methods, after the initial key verification |
| 272 | +request message, could be sent as to-device messages. The |
| 273 | +`m.key.verification.ready`, `m.key.verification.cancel`, and |
| 274 | +`m.key.verification.done` messages must be still be sent in the room, as the |
| 275 | +`m.key.verification.ready` notifies the sender's other devices that the request |
| 276 | +has been acknowledged, and the `m.key.verification.cancel` and |
| 277 | +`m.key.verification.done` provide a record of the status of the key |
| 278 | +verification. |
| 279 | + |
| 280 | +However, it seems more natural to have all messages sent via the same |
| 281 | +mechanism. |
| 282 | + |
| 283 | +## Potential issues |
| 284 | + |
| 285 | +If a user wants to verify their own device, this will require the creation of a |
| 286 | +Direct Messaging room with themselves. Instead, clients may use the current |
| 287 | +`to_device` messages for verifying the user's other devices. |
| 288 | + |
| 289 | +Direct Messaging rooms could have end-to-end encryption enabled, and some |
| 290 | +clients can be configured to only send decryption keys to verified devices. |
| 291 | +Key verification messages should be granted an exception to this (so that |
| 292 | +decryption keys are sent to all of the target user's devices), or should be |
| 293 | +sent unencrypted, so that unverified devices will be able to be verified. |
| 294 | + |
| 295 | +Users might have multiple Direct Messaging rooms with other users. In this |
| 296 | +case, clients could need to prompt the user to select the room in which they |
| 297 | +want to perform the verification, or could select a room. |
| 298 | + |
| 299 | +## Security considerations |
| 300 | + |
| 301 | +Key verification is subject to the room's visibility settings, and may be |
| 302 | +visible to other users in the room. However, key verification does not rely on |
| 303 | +secrecy, so this will no affect the security of the key verification. This may |
| 304 | +reveal to others in the room that Alice and Bob know each other, but this is |
| 305 | +already revealed by the fact that they share a Direct Messaging room. |
| 306 | + |
| 307 | +This framework allows users to see what key verifications they have performed |
| 308 | +in the past. However, since key verification messages are not secured, this |
| 309 | +should not be considered as authoritative. |
| 310 | + |
| 311 | +## Conclusion |
| 312 | + |
| 313 | +By using room messages to perform key verification rather than `to_device` |
| 314 | +messages, the user experience of key verification can be improved. |
0 commit comments