@ -471,27 +471,29 @@ In general, verification operates as follows:
that the verification was successful.
that the verification was successful.
Verifications can be cancelled by either device at any time by sending an
Verifications can be cancelled by either device at any time by sending an
[ m.key.verification.cancel](#mkeyverificationcancel ) event with a `code` field
[` m.key.verification.cancel` ](#mkeyverificationcancel ) event with a `code` field
that indicates the reason it was cancelled. The
that indicates the reason it was cancelled. The
[Error handling during key verification ](#error-handling-during-key-verification )
[Error handling during key verification ](#error-handling-during-key-verification )
section explains specific situations where cancellation messages should be sent.
section explains specific situations where cancellation messages should be sent.
When using to-device messages, Alice may not know which of Bob's devices to
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
verify, or may not want to choose a specific device. In this case, Alice will
send `m.key.verification.request` events to all of Bob's devices. All of these
send [`m.key.verification.request` ](#mkeyverificationrequest ) events to all of
events will use the same transaction ID. When Bob accepts or declines the
Bob's devices. All of these events will use the same transaction ID. When Bob
verification on one of his devices (sending either an
accepts or declines the verification on one of his devices (sending either an
`m.key.verification.ready` or `m.key.verification.cancel` event), Alice will
[`m.key.verification.ready` ](#mkeyverificationready ) or
send an `m.key.verification.cancel` event to Bob's other devices with a `code`
[`m.key.verification.cancel` ](#mkeyverificationcancel ) event), Alice will send
of `m.accepted` in the case where Bob accepted the verification, or `m.user` in
an [`m.key.verification.cancel` ](#mkeyverificationcancel ) event to Bob's other
the case where Bob rejected the verification. This yields the following
devices with a `code` of `m.accepted` in the case where Bob accepted the
handshake when using to-device messages, assuming both Alice and Bob each have
verification, or `m.user` in the case where Bob rejected the verification. This
2 devices, Bob's first device accepts the key verification request, and Alice's
yields the following handshake when using to-device messages, assuming both
second device initiates the request. Note how Alice's first device is not
Alice and Bob each have 2 devices, Bob's first device accepts the key
involved in the request or verification process. Also note that, although in
verification request, and Alice's second device initiates the request. Note how
this example, Bob's device sends the `m.key.verification.start` , Alice's device
Alice's first device is not involved in the request or verification process.
could also send that message. As well, the order of the
Also note that, although in this example, Bob's device sends the
`m.key.verification.done` messages could be reversed.
[`m.key.verification.start` ](#mkeyverificationstart ), Alice's device could also
send that message. As well, the order of the
[`m.key.verification.done` ](#mkeyverificationdone ) messages could be reversed.
```
```
+---------------+ +---------------+ +-------------+ +-------------+
+---------------+ +---------------+ +-------------+ +-------------+
@ -527,12 +529,15 @@ could also send that message. As well, the order of the
In contrast with the case of using to-devices messages, when using in-room
In contrast with the case of using to-devices messages, when using in-room
messages, Alice only sends one request event (an event with type
messages, Alice only sends one request event (an event with type
`m.room.message` with `msgtype: m.key.verification.request` , rather than an
[`m.room.message` with `msgtype: m.key.verification.request` ](#mroommessagemkeyverificationrequest ),
event with type `m.key.verification.request` ), to the room. In addition, Alice
rather than an event with type
does not send an `m.key.verification.cancel` event to tell Bob's other devices
[`m.key.verification.request` ](#mkeyverificationrequest )), to the room. In
that the request as already been accepted; instead, when Bob's other devices
addition, Alice does not send an
see his `m.key.verification.ready` event, they will know that the request has
[`m.key.verification.cancel` ](#mkeyverificationcancel ) event to tell Bob's other
already been accepted, and that they should ignore the request.
devices that the request as already been accepted; instead, when Bob's other
devices see his [`m.key.verification.ready` ](#mkeyverificationready ) event, they
will know that the request has already been accepted, and that they should
ignore the request.
When using in-room messages and the room has encryption enabled, clients should
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
ensure that encryption does not hinder the verification. For example, if the
@ -542,44 +547,46 @@ messages, even if they would normally not be given the keys to decrypt messages
in the room. Alternatively, verification messages may be sent unencrypted,
in the room. Alternatively, verification messages may be sent unencrypted,
though this is not encouraged.
though this is not encouraged.
Upon receipt of Alice's `m.key.verification.request` message, if Bob's device
Upon receipt of Alice's [`m.key.verification.request` ](#mkeyverificationrequest )
does not understand any of the methods, it should not cancel the request as one
message, if Bob's device does not understand any of the methods, it should not
of his other devices may support the request. Instead, Bob's device should tell
cancel the request as one of his other devices may support the request. Instead,
Bob that no supported method was found, and allow him to manually reject the
Bob's device should tell Bob that no supported method was found, and allow him
request.
to manually reject the request.
The prompt for Bob to accept/reject Alice's request (or the unsupported method
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
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
the case of to-device messages) or `origin_ts` (in the case of in-room messages)
messages) field or 2 minutes after Bob's client receives the message, whichever
field or 2 minutes after Bob's client receives the message, whichever comes
comes first, if Bob does not interact with the prompt. The prompt should
first, if Bob does not interact with the prompt. The prompt should additionally
additionally be hidden if an appropriate `m.key.verification.cancel` message is
be hidden if an appropriate
received.
[`m.key.verification.cancel` ](#mkeyverificationcancel ) message is received.
If Bob rejects the request, Bob's client must send an
If Bob rejects the request, Bob's client must send an
`m.key.verification.cancel` event with `code` set to `m.user` . Upon receipt,
[`m.key.verification.cancel` ](#mkeyverificationcancel ) event with `code` set to
Alice's device should tell her that Bob does not want to verify her device and,
`m.user` . Upon receipt, Alice's device should tell her that Bob does not want to
if the request was sent as a to-device message, send
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
[`m.key.verification.cancel` ](#mkeyverificationcancel ) messages to all of Bob's
that the request was rejected.
devices to notify them that the request was rejected.
If Alice's and Bob's clients both send an `m.key.verification.start` message,
If Alice's and Bob's clients both send an
and both specify the same verification method, then the
[`m.key.verification.start` ](#mkeyverificationstart ) message, and both specify
`m.key.verification.start` message sent by the user whose ID is the
the same verification method, then the
lexicographically largest user ID should be ignored, and the situation should
[`m.key.verification.start` ](#mkeyverificationstart ) message sent by the user
be treated the same as if only the user with the lexicographically smallest
whose ID is the lexicographically largest user ID should be ignored, and the
user ID had sent the `m.key.verification.start` message. In the case where the
situation should be treated the same as if only the user with the
user IDs are the same (that is, when a user is verifying their own device),
lexicographically smallest user ID had sent the
[`m.key.verification.start` ](#mkeyverificationstart ) 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
then the device IDs should be compared instead. If the two
`m.key.verification.start` messages do not specify the same verification
[`m.key.verification.start` ](#mkeyverificationstart ) messages do not specify the
method, then the verification should be cancelled with a `code` of
same verification method, then the verification should be cancelled with a
`m.unexpected_message` .
`code` of `m.unexpected_message` .
When verifying using to-device messages, an `m.key.verification.start`
When verifying using to-device messages, an
message can also be sent independently of any
[`m.key.verification.start` ](#mkeyverificationstart ) message can also be sent
request, specifying the verification method to use. This behaviour is
independently of any request, specifying the verification method to use. This
deprecated, and new clients should not begin verifications in this way.
behaviour is deprecated, and new clients should not begin verifications in this
However, clients should handle such verifications started by other clients.
way. However, clients should handle such verifications started by other clients.
Individual verification methods may add additional steps, events, and
Individual verification methods may add additional steps, events, and
properties to the verification messages. Event types for methods defined
properties to the verification messages. Event types for methods defined
@ -648,8 +655,8 @@ 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
To advertise support for this method, clients use the name `m.sas.v1` in the
`methods` fields of the `m.key.verification.request` and
`methods` fields of the [`m.key.verification.request` ](#mkeyverificationrequest )
`m.key.verification.ready` events.
and [`m.key.verification.ready` ](#mkeyverificationready ), events.
The verification process takes place in two phases:
The verification process takes place in two phases:
@ -664,8 +671,9 @@ The process between Alice and Bob verifying each other would be:
party cannot be impersonated, not explicit secrecy.
party cannot be impersonated, not explicit secrecy.
2. Alice and Bob begin a key verification using the key verification
2. Alice and Bob begin a key verification using the key verification
framework as described above.
framework as described above.
3. Alice's device sends Bob's device an `m.key.verification.start`
3. Alice's device sends Bob's device an
message. Alice's device ensures it has a copy of Bob's device key.
[`m.key.verification.start` ](#mkeyverificationstart ) message. Alice's device
ensures it has a copy of Bob's device key.
4. Bob's device receives the message and selects a key agreement
4. Bob's device receives the message and selects a key agreement
protocol, hash algorithm, message authentication code, and SAS
protocol, hash algorithm, message authentication code, and SAS
method supported by Alice's device.
method supported by Alice's device.
@ -675,20 +683,21 @@ The process between Alice and Bob verifying each other would be:
and calculates the hash (using the chosen algorithm) of the public
and calculates the hash (using the chosen algorithm) of the public
key *K<sub>B</sub><sup>public</sup>* .
key *K<sub>B</sub><sup>public</sup>* .
7. Bob's device replies to Alice's device with an
7. Bob's device replies to Alice's device with an
`m.key.verification.accept` message.
[`m.key.verification.accept` ](#mkeyverificationaccept ) message.
8. Alice's device receives Bob's message and stores the commitment hash
8. Alice's device receives Bob's message and stores the commitment hash
for later use.
for later use.
9. Alice's device creates an ephemeral Curve25519 key pair
9. Alice's device creates an ephemeral Curve25519 key pair
(*K< sub > A< / sub > < sup > private< / sup > *, *K< sub > A< / sub > < sup > public< / sup > *)
(*K< sub > A< / sub > < sup > private< / sup > *, *K< sub > A< / sub > < sup > public< / sup > *)
and replies to Bob's device with an `m.key.verification.key` ,
and replies to Bob's device with an
sending only the public key
[`m.key.verification.key` ](#mkeyverificationkey ), sending only the public
*K<sub>A</sub><sup>public</sup>* .
key *K<sub>A</sub><sup>public</sup>* .
10. Bob's device receives Alice's message and replies with its own
10. Bob's device receives Alice's message and replies with its own
`m.key.verification.key` message containing its public key
[`m.key.verification.key` ](#mkeyverificationkey ) message containing its
*K<sub>B</sub><sup>public</sup>* .
public key *K<sub>B</sub><sup>public</sup>* .
11. Alice's device receives Bob's message and verifies the commitment
11. Alice's device receives Bob's message and verifies the commitment
hash from earlier matches the hash of the key Bob's device just sent
hash from earlier matches the hash of the key Bob's device just sent
and the content of Alice's `m.key.verification.start` message.
and the content of Alice's
[`m.key.verification.start` ](#mkeyverificationstart ) message.
12. Both Alice's and Bob's devices perform an Elliptic-curve Diffie-Hellman using
12. Both Alice's and Bob's devices perform an Elliptic-curve Diffie-Hellman using
their private ephemeral key, and the other device's ephemeral public key
their private ephemeral key, and the other device's ephemeral public key
(*ECDH(K< sub > A< / sub > < sup > private< / sup > *, *K< sub > B< / sub > < sup > public< / sup > *)
(*ECDH(K< sub > A< / sub > < sup > private< / sup > *, *K< sub > B< / sub > < sup > public< / sup > *)
@ -708,18 +717,20 @@ The process between Alice and Bob verifying each other would be:
* The complete list of key IDs that they wish the other user to verify.
* The complete list of key IDs that they wish the other user to verify.
The MAC calculation is defined [below ](#mac-calculation ).
The MAC calculation is defined [below ](#mac-calculation ).
16. Alice's device sends Bob's device an `m.key.verification.mac`
16. Alice's device sends Bob's device an
message containing the MAC of Alice's device keys and the MAC of her
[`m.key.verification.mac` ](#mkeyverificationmac ) message containing the MAC
key IDs to be verified. Bob's device does the same for Bob's device
of Alice's device keys and the MAC of her key IDs to be verified. Bob's
keys and key IDs concurrently with Alice.
device does the same for Bob's device keys and key IDs concurrently with
17. When the other device receives the `m.key.verification.mac` message,
Alice.
the device calculates the MACs of its copies of the other device's
17. When the other device receives the
keys given in the message, as well as the MAC of the
[`m.key.verification.mac` ](#mkeyverificationmac ) message, the device
comma-separated, sorted, list of key IDs in the message. The device
calculates the MACs of its copies of the other device's keys given in the
compares these with the MAC values given in the message, and if
message, as well as the MAC of the comma-separated, sorted, list of key IDs
everything matches then the device keys are verified.
in the message. The device compares these with the MAC values given in the
18. Alice and Bob's devices send `m.key.verification.done` messages to complete
message, and if everything matches then the device keys are verified.
the verification.
18. Alice and Bob's devices send
[`m.key.verification.done` ](#mkeyverificationdone ) messages to complete the
verification.
The wire protocol looks like the following between Alice and Bob's
The wire protocol looks like the following between Alice and Bob's
devices:
devices:
@ -759,18 +770,20 @@ do when SAS-specific errors happen:
- If the two devices do not share a common key share, hash, HMAC, or
- If the two devices do not share a common key share, hash, HMAC, or
SAS method then the device should notify the other device with an
SAS method then the device should notify the other device with an
appropriate `m.key.verification.cancel` message.
appropriate [`m.key.verification.cancel` ](#mkeyverificationcancel ) message.
- If the user claims the Short Authentication Strings do not match,
- If the user claims the Short Authentication Strings do not match,
the device should send an appropriate `m.key.verification.cancel`
the device should send an appropriate
message to the other device.
[`m.key.verification.cancel` ](#mkeyverificationcancel ) message to the other
device.
###### Verification messages specific to SAS
###### Verification messages specific to SAS
Building off the common framework, the following events are involved in
Building off the common framework, the following events are involved in
SAS verification.
SAS verification.
The `m.key.verification.cancel` event is unchanged, however the
The [`m.key.verification.cancel` ](#mkeyverificationcancel ) event is unchanged,
following error codes are used in addition to those already specified:
however the following error codes are used in addition to those already
specified:
- `m.unknown_method` : The devices are unable to agree on the key
- `m.unknown_method` : The devices are unable to agree on the key
agreement, hash, MAC, or SAS method.
agreement, hash, MAC, or SAS method.
@ -822,7 +835,8 @@ defined as follows:
form `{algorithm}:{keyId}` . For example, the key list could look like:
form `{algorithm}:{keyId}` . For example, the key list could look like:
`ed25519:Cross+Signing+Key,ed25519:DEVICEID` . In this way, the recipient can
`ed25519:Cross+Signing+Key,ed25519:DEVICEID` . In this way, the recipient can
reconstruct the list from the names in the `mac` property of the
reconstruct the list from the names in the `mac` property of the
`m.key.verification.mac` message and ensure that no keys were added or removed.
[`m.key.verification.mac` ](#mkeyverificationmac ) message and ensure that no
keys were added or removed.
3. The MAC values are base64-encoded and sent in a
3. The MAC values are base64-encoded and sent in a
[`m.key.verification.mac` ](#mkeyverificationmac ) message.
[`m.key.verification.mac` ](#mkeyverificationmac ) message.
@ -847,19 +861,25 @@ supplied as the input keying material. No salt is used. When the
is the concatenation of:
is the concatenation of:
- The string `MATRIX_KEY_VERIFICATION_SAS|` .
- The string `MATRIX_KEY_VERIFICATION_SAS|` .
- The Matrix ID of the user who sent the `m.key.verification.start`
- The Matrix ID of the user who sent the
message, followed by `|` .
[`m.key.verification.start` ](#mkeyverificationstart ) message, followed by
`|` .
- The Device ID of the device which sent the
- The Device ID of the device which sent the
`m.key.verification.start` message, followed by `|` .
[`m.key.verification.start` ](#mkeyverificationstart ) message, followed by
- The public key from the `m.key.verification.key` message sent by
`|` .
the device which sent the `m.key.verification.start` message, encoded as
- The public key from the [`m.key.verification.key` ](#mkeyverificationkey )
message sent by the device which sent the
[`m.key.verification.start` ](#mkeyverificationstart ) message, encoded as
unpadded base64, followed by `|` .
unpadded base64, followed by `|` .
- The Matrix ID of the user who sent the `m.key.verification.accept`
- The Matrix ID of the user who sent the
message, followed by `|` .
[`m.key.verification.accept` ](#mkeyverificationaccept ) message, followed by
`|` .
- The Device ID of the device which sent the
- The Device ID of the device which sent the
`m.key.verification.accept` message, followed by `|` .
[`m.key.verification.accept` ](#mkeyverificationaccept ) message, followed by
- The public key from the `m.key.verification.key` message sent by
`|` .
the device which sent the `m.key.verification.accept` message, encoded as
- The public key from the [`m.key.verification.key` ](#mkeyverificationkey )
message sent by the device which sent the
[`m.key.verification.accept` ](#mkeyverificationaccept ) message, encoded as
unpadded base64, followed by `|` .
unpadded base64, followed by `|` .
- The `transaction_id` being used.
- The `transaction_id` being used.
@ -867,14 +887,14 @@ When the `key_agreement_protocol` is the deprecated method `curve25519`,
the info parameter is the concatenation of:
the info parameter is the concatenation of:
- The string `MATRIX_KEY_VERIFICATION_SAS` .
- The string `MATRIX_KEY_VERIFICATION_SAS` .
- The Matrix ID of the user who sent the `m.key.verification.start`
- The Matrix ID of the user who sent the
message.
[`m.key.verification.start` ](#mkeyverificationstart ) message.
- The Device ID of the device which sent the
- The Device ID of the device which sent the
`m.key.verification.start` message.
[`m.key.verification.start` ](#mkeyverificationstart ) message.
- The Matrix ID of the user who sent the `m.key.verification.accept`
- The Matrix ID of the user who sent the
message.
[`m.key.verification.accept` ](#mkeyverificationaccept ) message.
- The Device ID of the device which sent the
- The Device ID of the device which sent the
`m.key.verification.accept` message.
[`m.key.verification.accept` ](#mkeyverificationaccept ) message.
- The `transaction_id` being used.
- The `transaction_id` being used.
New implementations are discouraged from implementing the `curve25519`
New implementations are discouraged from implementing the `curve25519`
@ -1041,7 +1061,7 @@ signatures that she cannot see:
user's master key by using the master public key, encoded using unpadded
user's master key by using the master public key, encoded using unpadded
base64, as the device ID, and treating it as a normal device. For
base64, as the device ID, and treating it as a normal device. For
example, if Alice and Bob verify each other using SAS, Alice's
example, if Alice and Bob verify each other using SAS, Alice's
`m.key.verification.mac` message to Bob may include
[`m.key.verification.mac` ](#mkeyverificationmac ) message to Bob may include
`"ed25519:alices+master+public+key": "alices+master+public+key"` in the
`"ed25519:alices+master+public+key": "alices+master+public+key"` in the
`mac` property. Servers therefore must ensure that device IDs will not
`mac` property. Servers therefore must ensure that device IDs will not
collide with cross-signing public keys.
collide with cross-signing public keys.
@ -1123,13 +1143,14 @@ bi-directional verification from a single scan.
To advertise the ability to show a QR code, clients use the names
To advertise the ability to show a QR code, clients use the names
`m.qr_code.show.v1` and `m.reciprocate.v1` in the `methods` fields of the
`m.qr_code.show.v1` and `m.reciprocate.v1` in the `methods` fields of the
`m.key.verification.request` and `m.key.verification.ready` events. To
[`m.key.verification.request` ](#mkeyverificationrequest ) and
advertise the ability to scan a QR code, clients use the names
[`m.key.verification.ready` ](#mkeyverificationready ) events. To advertise the
`m.qr_code.scan.v1` and `m.reciprocate.v1` in the `methods` fields of the
ability to scan a QR code, clients use the names `m.qr_code.scan.v1` and
`m.key.verification.request` and `m.key.verification.ready` events.
`m.reciprocate.v1` in the `methods` fields of the
Clients that support both showing and scanning QR codes would advertise
[`m.key.verification.request` ](#mkeyverificationrequest ) and
`m.qr_code.show.v1` , `m.qr_code.scan.v1` , and `m.reciprocate.v1` as
[`m.key.verification.ready` ](#mkeyverificationready ) events. Clients that
methods.
support both showing and scanning QR codes would advertise `m.qr_code.show.v1` ,
`m.qr_code.scan.v1` , and `m.reciprocate.v1` as methods.
The process between Alice and Bob verifying each other would be:
The process between Alice and Bob verifying each other would be:
@ -1148,7 +1169,8 @@ The process between Alice and Bob verifying each other would be:
6. Alice's device ensures that the keys encoded in the QR code match the
6. Alice's device ensures that the keys encoded in the QR code match the
expected values for the keys. If not, Alice's device displays an error
expected values for the keys. If not, Alice's device displays an error
message indicating that the code is incorrect, and sends a
message indicating that the code is incorrect, and sends a
`m.key.verification.cancel` message to Bob's device.
[`m.key.verification.cancel` ](#mkeyverificationcancel ) message to Bob's
device.
Otherwise, at this point:
Otherwise, at this point:
- Alice's device has now verified Bob's key, and
- Alice's device has now verified Bob's key, and
@ -1162,15 +1184,15 @@ The process between Alice and Bob verifying each other would be:
keys yet so wouldn't show the same message. Bob will know that
keys yet so wouldn't show the same message. Bob will know that
he has the right key for Alice because Alice's device will have shown
he has the right key for Alice because Alice's device will have shown
this message, as otherwise the verification would be cancelled.
this message, as otherwise the verification would be cancelled.
8. Alice's device sends an `m.key.verification.start` message with `method` set
8. Alice's device sends an [`m.key.verification.start` ](#mkeyverificationstart )
to `m.reciprocate.v1` to Bob (see below). The message includes the shared
message with `method` set to `m.reciprocate.v1` to Bob (see below). The
secret from the QR code. This signals to Bob's device that Alice has
message includes the shared secret from the QR code. This signals to Bob's
scanned Bob's QR code.
device that Alice has scanned Bob's QR code.
This message is merely a signal for Bob's device to proceed to the next
This message is merely a signal for Bob's device to proceed to the next
step, and is not used for verification purposes.
step, and is not used for verification purposes.
9. Upon receipt of the `m.key.verification.start` message, Bob's device ensures
9. Upon receipt of the [`m.key.verification.start` ](#mkeyverificationstart )
that the shared secret matches.
message, Bob's device ensures that the shared secret matches.
If the shared secret does not match, it should display an error message
If the shared secret does not match, it should display an error message
indicating that an attack was attempted. (This does not affect Alice's
indicating that an attack was attempted. (This does not affect Alice's
@ -1189,7 +1211,8 @@ The process between Alice and Bob verifying each other would be:
telling Bob that the code was scanned successfully is sufficient for Bob to
telling Bob that the code was scanned successfully is sufficient for Bob to
trust Alice's key, under the assumption that this communication is done
trust Alice's key, under the assumption that this communication is done
over a trusted medium (such as in-person).
over a trusted medium (such as in-person).
11. Both devices send an `m.key.verification.done` message.
11. Both devices send an [`m.key.verification.done` ](#mkeyverificationdone )
message.
###### QR code format
###### QR code format