Merge pull request #3139 from uhoreg/verification_in_dms_spec

spec verification in DMs and m.key.verification.ready/done
pull/977/head
Hubert Chathi 4 years ago committed by Richard van der Hoff
commit 8019699dc5

@ -0,0 +1 @@
Add `m.key.verification.ready` and `m.key.verification.done` to key verification framework as per [MSC2366](https://github.com/matrix-org/matrix-doc/pull/2366).

@ -0,0 +1 @@
Add key verification using in-room messages as per [MSC2241](https://github.com/matrix-org/matrix-doc/pull/2241).

@ -357,7 +357,7 @@ out-of-band channel: there is no way to do it within Matrix without
trusting the administrators of the homeservers. trusting the administrators of the homeservers.
In Matrix, verification works by Alice meeting Bob in person, or In Matrix, verification works by Alice meeting Bob in person, or
contacting him via some other trusted medium, and use [SAS contacting him via some other trusted medium, and using [SAS
Verification](#SAS Verification) to interactively verify Bob's devices. Verification](#SAS Verification) to interactively verify Bob's devices.
Alice and Bob may also read aloud their unpadded base64 encoded Ed25519 Alice and Bob may also read aloud their unpadded base64 encoded Ed25519
public key, as returned by `/keys/query`. public key, as returned by `/keys/query`.
@ -390,60 +390,70 @@ decrypted by such a device. For the Olm protocol, this is documented at
Verifying keys manually by reading out the Ed25519 key is not very Verifying keys manually by reading out the Ed25519 key is not very
user-friendly, and can lead to errors. In order to help mitigate errors, user-friendly, and can lead to errors. In order to help mitigate errors,
and to make the process easier for users, some verification methods are and to make the process easier for users, some verification methods are
supported by the specification. The methods all use a common framework supported by the specification and use messages exchanged by the user's devices
to assist in the verification. The methods all use a common framework
for negotiating the key verification. for negotiating the key verification.
To use this framework, Alice's client would send Verification messages can be sent either in a room shared by the two parties,
`m.key.verification.request` events to Bob's devices. All of the which should be a [direct messaging](#direct-messaging) room between the two
`to_device` messages sent to Bob MUST have the same `transaction_id` to parties, or by using [to-device](#send-to-device-messaging) messages sent
indicate they are part of the same request. This allows Bob to reject directly between the two devices involved. In both cases, the messages
the request on one device, and have it apply to all of his devices. exchanged are similar, with minor differences as detailed below. Verifying
Similarly, it allows Bob to process the verification on one device between two different users should be performed using in-room messages, whereas
without having to involve all of his devices. verifying two devices belonging to the same user should be performed using
to-device messages.
When Bob's device receives an `m.key.verification.request`, it should
prompt Bob to verify keys with Alice using one of the supported methods A key verification session is identified by an ID that is established by the
in the request. If Bob's device does not understand any of the methods, first message sent in that session. For verifications using in-room messages,
it should not cancel the request as one of his other devices may support the ID is the event ID of the initial message, and for verifications using
the request. Instead, Bob's device should tell Bob that an unsupported to-device messages, the first message contains a `transaction_id` field that is
method was used for starting key verification. The prompt for Bob to shared by the other messages of that session.
accept/reject Alice's request (or the unsupported method prompt) should
be automatically dismissed 10 minutes after the `timestamp` field or 2 In general, verification operates as follows:
minutes after Bob's client receives the message, whichever comes first,
if Bob does not interact with the prompt. The prompt should additionally - Alice requests a key verification with Bob by sending an
be hidden if an appropriate `m.key.verification.cancel` message is `m.key.verification.request` event. This event indicates the verification
received. methods that Alice's client supports. (Note that "Alice" and "Bob" may in
fact be the same user, in the case where a user is verifying their own
If Bob rejects the request, Bob's client must send an devices.)
`m.key.verification.cancel` message to Alice's device. Upon receipt, - Bob's client prompts Bob to accept the key verification. When Bob accepts
Alice's device should tell her that Bob does not want to verify her the verification, Bob's client sends an `m.key.verification.ready` event.
device and send `m.key.verification.cancel` messages to all of Bob's This event indicates the verification methods, corresponding to the
devices to notify them that the request was rejected. verification methods supported by Alice's client, that Bob's client supports.
- Alice's or Bob's devices allow their users to select one of the verification
If Bob accepts the request, Bob's device starts the key verification methods supported by both devices to use for verification. When Alice or Bob
process by sending an `m.key.verification.start` message to Alice's selects a verification method, their device begins the verification by
device. Upon receipt of this message, Alice's device should send an sending an `m.key.verification.start` event, indicating the selected
`m.key.verification.cancel` message to all of Bob's other devices to verification method. Note that if there is only one verification method in
indicate the process has been started. The start message must use the common between the devices then the receiver's device (Bob) can auto-select
same `transaction_id` from the original key verification request if it it.
is in response to the request. The start message can be sent - Alice and Bob complete the verification as defined by the selected
independently of any request. verification method. This could involve their clients exchanging messages,
Alice and Bob exchanging information out-of-band, and/or Alice and Bob
Individual verification methods may add additional steps, events, and interacting with their devices.
properties to the verification messages. Event types for methods defined - Alice's and Bob's clients send `m.key.verification.done` events to indicate
in this specification must be under the `m.key.verification` namespace that the verification was successful.
and any other event types must be namespaced according to the Java
package naming convention. Verifications can be cancelled by either device at any time by sending an
`m.key.verification.cancel` event with a `code` field that indicates the reason
Any of Alice's or Bob's devices can cancel the key verification request it was cancelled.
or process at any time with an `m.key.verification.cancel` message to
all applicable devices. When using to-device messages, Alice may not know which of Bob's devices to
verify, or may not want to choose a specific device. In this case, Alice will
This framework yields the following handshake, assuming both Alice and send `m.key.verification.request` events to all of Bob's devices. All of these
Bob each have 2 devices, Bob's first device accepts the key verification events will use the same transaction ID. When Bob accepts or declines the
request, and Alice's second device initiates the request. Note how verification on one of his devices (sending either an
Alice's first device is not involved in the request or verification `m.key.verification.ready` or `m.key.verification.cancel` event), Alice will
process. send an `m.key.verification.cancel` event to Bob's other devices with a `code`
of `m.accepted` in the case where Bob accepted the verification, or `m.user` in
the case where Bob rejected the verification. This yields the following
handshake when using to-device messages, assuming both Alice and Bob each have
2 devices, Bob's first device accepts the key verification request, and Alice's
second device initiates the request. Note how Alice's first device is not
involved in the request or verification process. Also note that, although in
this example, Bob's device sends the `m.key.verification.start`, Alice's device
could also send that message. As well, the order of the
`m.key.verification.done` messages could be reversed.
``` ```
+---------------+ +---------------+ +-------------+ +-------------+ +---------------+ +---------------+ +-------------+ +-------------+
@ -456,20 +466,85 @@ process.
| | m.key.verification.request | | | | m.key.verification.request | |
| |-------------------------------------------------->| | |-------------------------------------------------->|
| | | | | | | |
| | m.key.verification.start | | | | m.key.verification.ready | |
| |<----------------------------------| | | |<----------------------------------| |
| | | | | | | |
| | m.key.verification.cancel | | | | m.key.verification.cancel | |
| |-------------------------------------------------->| | |-------------------------------------------------->|
| | | | | | | |
| | m.key.verification.start | |
| |<----------------------------------| |
| | | |
.
. (verification messages)
.
| | | |
| | m.key.verification.done | |
| |<----------------------------------| |
| | | |
| | m.key.verification.done | |
| |---------------------------------->| |
| | | |
``` ```
After the handshake, the verification process begins. When using in-room messages and the room has encryption enabled, clients should
ensure that encryption does not hinder the verification. For example, if the
verification messages are encrypted, clients must ensure that all the
recipient's unverified devices receive the keys necessary to decrypt the
messages, even if they would normally not be given the keys to decrypt messages
in the room. Alternatively, verification messages may be sent unencrypted,
though this is not encouraged.
Upon receipt of Alice's `m.key.verification.request` message, if Bob's device
does not understand any of the methods, it should not cancel the request as one
of his other devices may support the request. Instead, Bob's device should tell
Bob that no supported method was found, and allow him to manually reject the
request.
The prompt for Bob to accept/reject Alice's request (or the unsupported method
prompt) should be automatically dismissed 10 minutes after the `timestamp` (in
the case of to-device messages) or `origin_ts` (in the case of in-room
messages) field or 2 minutes after Bob's client receives the message, whichever
comes first, if Bob does not interact with the prompt. The prompt should
additionally be hidden if an appropriate `m.key.verification.cancel` message is
received.
If Bob rejects the request, Bob's client must send an
`m.key.verification.cancel` event with `code` set to `m.user`. Upon receipt,
Alice's device should tell her that Bob does not want to verify her device and,
if the request was sent as a to-device message, send
`m.key.verification.cancel` messages to all of Bob's devices to notify them
that the request was rejected.
If Alice's and Bob's clients both send an `m.key.verification.start` message,
and both specify the same verification method, then the
`m.key.verification.start` message sent by the user whose ID is the
lexicographically largest user ID should be ignored, and the situation should
be treated the same as if only the user with the lexicographically smallest
user ID had sent the `m.key.verification.start` message. In the case where the
user IDs are the same (that is, when a user is verifying their own device),
then the device IDs should be compared instead. If the two
`m.key.verification.start` messages do not specify the same verification
method, then the verification should be cancelled with a `code` of
`m.unexpected_message`.
An `m.key.verification.start` message can also be sent independently of any
request, specifying the verification method to use.
Individual verification methods may add additional steps, events, and
properties to the verification messages. Event types for methods defined
in this specification must be under the `m.key.verification` namespace
and any other event types must be namespaced according to the Java
package naming convention.
{{% event event="m.key.verification.request" %}} {{% event event="m.key.verification.request" %}}
{{% event event="m.key.verification.ready" %}}
{{% event event="m.key.verification.start" %}} {{% event event="m.key.verification.start" %}}
{{% event event="m.key.verification.done" %}}
{{% event event="m.key.verification.cancel" %}} {{% event event="m.key.verification.cancel" %}}
##### Short Authentication String (SAS) verification ##### Short Authentication String (SAS) verification
@ -493,6 +568,10 @@ example, if we verify 40 bits, then an attacker has a 1 in
success. A failed attack would result in a mismatched Short success. A failed attack would result in a mismatched Short
Authentication String, alerting users to the attack. Authentication String, alerting users to the attack.
To advertise support for this method, clients use the name `m.sas.v1` in the
`methods` fields of the `m.key.verification.request` and
`m.key.verification.ready` events.
The verification process takes place over [to-device](#send-to-device-messaging) messages in two The verification process takes place over [to-device](#send-to-device-messaging) messages in two
phases: phases:

@ -0,0 +1,6 @@
{
"type": "m.key.verification.done",
"content": {
"transaction_id": "S0meUniqueAndOpaqueString"
}
}

@ -0,0 +1,10 @@
{
"type": "m.key.verification.ready",
"content": {
"from_device": "BobDevice1",
"transaction_id": "S0meUniqueAndOpaqueString",
"methods": [
"m.sas.v1"
]
}
}

@ -3,16 +3,16 @@ allOf:
- $ref: core-event-schema/event.yaml - $ref: core-event-schema/event.yaml
description: |- description: |-
Accepts a previously sent `m.key.verification.start` message. Typically sent as a Accepts a previously sent `m.key.verification.start` message.
[to-device](/client-server-api/#send-to-device-messaging) event.
properties: properties:
content: content:
properties: properties:
transaction_id: transaction_id:
type: string type: string
description: |- description: |-
An opaque identifier for the verification process. Must be the same as Required when sent as a to-device message. An opaque identifier for
the one used for the `m.key.verification.start` message. the verification process. Must be the same as the one used for the
`m.key.verification.start` message.
key_agreement_protocol: key_agreement_protocol:
type: string type: string
description: |- description: |-
@ -43,8 +43,10 @@ properties:
The hash (encoded as unpadded base64) of the concatenation of the device's The hash (encoded as unpadded base64) of the concatenation of the device's
ephemeral public key (encoded as unpadded base64) and the canonical JSON ephemeral public key (encoded as unpadded base64) and the canonical JSON
representation of the `m.key.verification.start` message. representation of the `m.key.verification.start` message.
m.relates_to:
allOf:
- $ref: m.key.verification.m.relates_to.yaml
required: required:
- transaction_id
- method - method
- key_agreement_protocol - key_agreement_protocol
- hash - hash

@ -3,14 +3,15 @@ allOf:
- $ref: core-event-schema/event.yaml - $ref: core-event-schema/event.yaml
description: |- description: |-
Cancels a key verification process/request. Typically sent as a [to-device](/client-server-api/#send-to-device-messaging) event. Cancels a key verification process/request.
properties: properties:
content: content:
properties: properties:
transaction_id: transaction_id:
type: string type: string
description: |- description: |-
The opaque identifier for the verification process/request. Required when sent as a to-device message. The opaque identifier for
the verification process/request.
reason: reason:
type: string type: string
description: |- description: |-
@ -56,8 +57,10 @@ properties:
gets an unexpected response with `m.unexpected_message`, the client should not gets an unexpected response with `m.unexpected_message`, the client should not
respond again with `m.unexpected_message` to avoid the other device potentially respond again with `m.unexpected_message` to avoid the other device potentially
sending another error response. sending another error response.
m.relates_to:
allOf:
- $ref: m.key.verification.m.relates_to.yaml
required: required:
- transaction_id
- code - code
- reason - reason
type: object type: object

@ -0,0 +1,23 @@
---
allOf:
- $ref: core-event-schema/event.yaml
description: |-
Indicates that a verification process/request has completed successfully.
properties:
content:
properties:
transaction_id:
type: string
description: |-
Required when sent as a to-device message. The opaque identifier for
the verification process/request.
m.relates_to:
allOf:
- $ref: m.key.verification.m.relates_to.yaml
type: object
type:
enum:
- m.key.verification.done
type: string
type: object

@ -3,22 +3,24 @@ allOf:
- $ref: core-event-schema/event.yaml - $ref: core-event-schema/event.yaml
description: |- description: |-
Sends the ephemeral public key for a device to the partner device. Typically sent as a Sends the ephemeral public key for a device to the partner device.
[to-device](/client-server-api/#send-to-device-messaging) event.
properties: properties:
content: content:
properties: properties:
transaction_id: transaction_id:
type: string type: string
description: |- description: |-
An opaque identifier for the verification process. Must be the same as Required when sent as a to-device message. An opaque identifier for
the one used for the `m.key.verification.start` message. the verification process. Must be the same as the one used for the
`m.key.verification.start` message.
key: key:
type: string type: string
description: |- description: |-
The device's ephemeral public key, encoded as unpadded base64. The device's ephemeral public key, encoded as unpadded base64.
m.relates_to:
allOf:
- $ref: m.key.verification.m.relates_to.yaml
required: required:
- transaction_id
- key - key
type: object type: object
type: type:

@ -0,0 +1,21 @@
---
description: |-
Required when sent as an in-room message. Indicates the
`m.key.verification.request` that this message is related to. Note that for
encrypted messages, this property should be in the unencrypted portion of the
event.
properties:
rel_type:
type: string
enum:
- m.reference
description: |-
The relationship type.
event_id:
type: string
description: |-
The event ID of the `m.key.verification.request` that this message is
related to.
type: object
type: object
title: VerificationRelatesTo

@ -3,16 +3,16 @@ allOf:
- $ref: core-event-schema/event.yaml - $ref: core-event-schema/event.yaml
description: |- description: |-
Sends the MAC of a device's key to the partner device. Typically sent as a Sends the MAC of a device's key to the partner device.
[to-device](/client-server-api/#send-to-device-messaging) event.
properties: properties:
content: content:
properties: properties:
transaction_id: transaction_id:
type: string type: string
description: |- description: |-
An opaque identifier for the verification process. Must be the same as Required when sent as a to-device message. An opaque identifier for
the one used for the `m.key.verification.start` message. the verification process. Must be the same as the one used for the
`m.key.verification.start` message.
mac: mac:
type: object type: object
description: |- description: |-
@ -26,8 +26,10 @@ properties:
description: |- description: |-
The MAC of the comma-separated, sorted, list of key IDs given in the `mac` The MAC of the comma-separated, sorted, list of key IDs given in the `mac`
property, encoded as unpadded base64. property, encoded as unpadded base64.
m.relates_to:
allOf:
- $ref: m.key.verification.m.relates_to.yaml
required: required:
- transaction_id
- mac - mac
- keys - keys
type: object type: object

@ -0,0 +1,40 @@
---
allOf:
- $ref: core-event-schema/event.yaml
description: |-
Accepts a key verification request. Sent in response to an
`m.key.verification.request` event.
properties:
content:
properties:
from_device:
type: string
description: |-
The device ID which is accepting the request.
transaction_id:
type: string
description: |-
Required when sent as a to-device message. The transaction ID of the
verification request, as given in the `m.key.verification.request`
message.
methods:
type: array
description: |-
The verification methods supported by the sender, corresponding to
the verification methods indicated in the
`m.key.verification.request` message.
items:
type: string
m.relates_to:
allOf:
- $ref: m.key.verification.m.relates_to.yaml
required:
- from_device
- methods
type: object
type:
enum:
- m.key.verification.ready
type: string
type: object

@ -3,8 +3,7 @@ allOf:
- $ref: core-event-schema/event.yaml - $ref: core-event-schema/event.yaml
description: |- description: |-
Requests a key verification with another user's devices. Typically sent as a Requests a key verification with another user's devices.
[to-device](/client-server-api/#send-to-device-messaging) event.
properties: properties:
content: content:
properties: properties:
@ -15,8 +14,9 @@ properties:
transaction_id: transaction_id:
type: string type: string
description: |- description: |-
An opaque identifier for the verification request. Must be unique Required when sent as a to-device message. An opaque identifier for
with respect to the devices involved. the verification request. Must be unique with respect to the devices
involved.
methods: methods:
type: array type: array
description: |- description: |-
@ -27,14 +27,13 @@ properties:
type: integer type: integer
format: int64 format: int64
description: |- description: |-
The POSIX timestamp in milliseconds for when the request was made. If Required when sent as a to-device message. The POSIX timestamp in
the request is in the future by more than 5 minutes or more than 10 milliseconds for when the request was made. If the request is in the
minutes in the past, the message should be ignored by the receiver. future by more than 5 minutes or more than 10 minutes in the past,
the message should be ignored by the receiver.
required: required:
- from_device - from_device
- transaction_id
- methods - methods
- timestamp
type: object type: object
type: type:
enum: enum:

@ -3,7 +3,7 @@ allOf:
- $ref: core-event-schema/event.yaml - $ref: core-event-schema/event.yaml
description: |- description: |-
Begins a SAS key verification process using the `m.sas.v1` method. Typically sent as a [to-device](/client-server-api/#send-to-device-messaging) event. Begins a SAS key verification process using the `m.sas.v1` method.
properties: properties:
content: content:
properties: properties:
@ -14,10 +14,11 @@ properties:
transaction_id: transaction_id:
type: string type: string
description: |- description: |-
An opaque identifier for the verification process. Must be unique Required when sent as a to-device message. An opaque identifier for
with respect to the devices involved. Must be the same as the the verification process. Must be unique with respect to the devices
`transaction_id` given in the `m.key.verification.request` involved. Must be the same as the `transaction_id` given in the
if this process is originating from a request. `m.key.verification.request` if this process is originating from a
request.
method: method:
type: string type: string
enum: ["m.sas.v1"] enum: ["m.sas.v1"]
@ -53,9 +54,11 @@ properties:
items: items:
type: string type: string
enum: ["decimal", "emoji"] enum: ["decimal", "emoji"]
m.relates_to:
allOf:
- $ref: m.key.verification.m.relates_to.yaml
required: required:
- from_device - from_device
- transaction_id
- method - method
- key_agreement_protocols - key_agreement_protocols
- hashes - hashes

@ -16,10 +16,11 @@ properties:
transaction_id: transaction_id:
type: string type: string
description: |- description: |-
An opaque identifier for the verification process. Must be unique Required when sent as a to-device message. An opaque identifier for
with respect to the devices involved. Must be the same as the the verification process. Must be unique with respect to the devices
`transaction_id` given in the `m.key.verification.request` involved. Must be the same as the `transaction_id` given in the
if this process is originating from a request. `m.key.verification.request` if this process is originating from a
request.
method: method:
type: string type: string
description: |- description: |-
@ -30,9 +31,11 @@ properties:
Optional method to use to verify the other user's key with. Applicable Optional method to use to verify the other user's key with. Applicable
when the `method` chosen only verifies one user's key. This field will when the `method` chosen only verifies one user's key. This field will
never be present if the `method` verifies keys both ways. never be present if the `method` verifies keys both ways.
m.relates_to:
allOf:
- $ref: m.key.verification.m.relates_to.yaml
required: required:
- from_device - from_device
- transaction_id
- method - method
type: object type: object
type: type:

Loading…
Cancel
Save