From 0872ec788a1b9f15362e676db36e6638f205eeab Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Mon, 27 May 2024 18:03:05 -0600 Subject: [PATCH 01/16] e2ee/device verification: move general error handling under framework Most of the "Error and exception handling" section is generally applicable to other verification methods besides SAS, so I moved those bullet points under "Key verification framework". Signed-off-by: Sumner Evans --- .../modules/end_to_end_encryption.md | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 1b3bd7b32..1affb1f7a 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -597,6 +597,30 @@ package naming convention. {{% event event="m.key.verification.cancel" %}} +###### General key verification error handling + +At any point the interactive verification can go wrong. The following describes +what to do when an error happens: + +- Alice or Bob can cancel the verification at any time. An + `m.key.verification.cancel` message must be sent to signify the + cancellation. +- The verification can time out. Clients should time out a verification that + does not complete within 10 minutes. Additionally, clients should expire a + `transaction_id` which goes unused for 10 minutes after having last + sent/received it. The client should inform the user that the verification + timed out, and send an appropriate `m.key.verification.cancel` message to + the other device. +- When the same device attempts to initiate multiple verification attempts, + the recipient should cancel all attempts with that device. +- When a device receives an unknown `transaction_id`, it should send an + appropriate `m.key.verification.cancel` message to the other device + indicating as such. This does not apply for inbound + `m.key.verification.start` or `m.key.verification.cancel` messages. +- If the device receives a message out of sequence or that it was not + expecting, it should notify the other device with an appropriate + `m.key.verification.cancel` message. + ##### Short Authentication String (SAS) verification SAS verification is a user-friendly key verification process built off @@ -720,35 +744,17 @@ devices: | | ``` -###### Error and exception handling +###### SAS error handling At any point the interactive verification can go wrong. The following describes what to do when an error happens: -- Alice or Bob can cancel the verification at any time. An - `m.key.verification.cancel` message must be sent to signify the - cancellation. -- The verification can time out. Clients should time out a - verification that does not complete within 10 minutes. Additionally, - clients should expire a `transaction_id` which goes unused for 10 - minutes after having last sent/received it. The client should inform - the user that the verification timed out, and send an appropriate - `m.key.verification.cancel` message to the other device. -- When the same device attempts to initiate multiple verification - attempts, the recipient should cancel all attempts with that device. -- When a device receives an unknown `transaction_id`, it should send - an appropriate `m.key.verification.cancel` message to the other - device indicating as such. This does not apply for inbound - `m.key.verification.start` or `m.key.verification.cancel` messages. - 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 appropriate `m.key.verification.cancel` message. - If the user claims the Short Authentication Strings do not match, the device should send an appropriate `m.key.verification.cancel` message to the other device. -- If the device receives a message out of sequence or that it was not - expecting, it should notify the other device with an appropriate - `m.key.verification.cancel` message. ###### Verification messages specific to SAS From 01a816d0daf9a180f6f08c6c5a2fa26a1499930b Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Mon, 27 May 2024 18:04:52 -0600 Subject: [PATCH 02/16] e2ee/device verification/error handling: fix typo start -> request It used to be possible to create a start request without a request, but this was deprecated. Signed-off-by: Sumner Evans --- content/client-server-api/modules/end_to_end_encryption.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 1affb1f7a..f941f8b0d 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -616,7 +616,7 @@ what to do when an error happens: - When a device receives an unknown `transaction_id`, it should send an appropriate `m.key.verification.cancel` message to the other device indicating as such. This does not apply for inbound - `m.key.verification.start` or `m.key.verification.cancel` messages. + `m.key.verification.request` or `m.key.verification.cancel` messages. - If the device receives a message out of sequence or that it was not expecting, it should notify the other device with an appropriate `m.key.verification.cancel` message. From 8905029dec153a025b48fd4a3ccd4e403432de04 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Mon, 27 May 2024 18:05:40 -0600 Subject: [PATCH 03/16] m.key.verification.start: remove wording that it is typically to-device It can be either a to-device event or an in-room event. Signed-off-by: Sumner Evans --- data/event-schemas/schema/m.key.verification.start.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/event-schemas/schema/m.key.verification.start.yaml b/data/event-schemas/schema/m.key.verification.start.yaml index cc16d275d..ef862ffcf 100644 --- a/data/event-schemas/schema/m.key.verification.start.yaml +++ b/data/event-schemas/schema/m.key.verification.start.yaml @@ -3,9 +3,9 @@ allOf: - $ref: core-event-schema/event.yaml description: |- - Begins a key verification process. Typically sent as a [to-device](/client-server-api/#send-to-device-messaging) event. The `method` - field determines the type of verification. The fields in the event will differ depending - on the `method`. This definition includes fields that are in common among all variants. + Begins a key verification process. The `method` field determines the type of + verification. The fields in the event will differ depending on the `method`. + This definition includes fields that are in common among all variants. properties: content: properties: From b8808caa1eac4970b8ee004835cfdc0e5120d3aa Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Wed, 29 May 2024 22:05:34 -0600 Subject: [PATCH 04/16] Add changelog Signed-off-by: Sumner Evans --- changelogs/client_server/newsfragments/1830.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1830.clarification diff --git a/changelogs/client_server/newsfragments/1830.clarification b/changelogs/client_server/newsfragments/1830.clarification new file mode 100644 index 000000000..0283194a4 --- /dev/null +++ b/changelogs/client_server/newsfragments/1830.clarification @@ -0,0 +1 @@ +Clarify a few things in the Device Verification section. From ea9dc84424e90ad75b92c2bd34e598767bd6a511 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Fri, 7 Jun 2024 10:28:37 -0600 Subject: [PATCH 05/16] fixup! e2ee/device verification: move general error handling under framework Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- content/client-server-api/modules/end_to_end_encryption.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index f941f8b0d..e93e54d31 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -597,7 +597,7 @@ package naming convention. {{% event event="m.key.verification.cancel" %}} -###### General key verification error handling +###### Error handling during key verification At any point the interactive verification can go wrong. The following describes what to do when an error happens: From edc4f38c84fd3ff1fd33ab4ceef685e06743080c Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Fri, 7 Jun 2024 10:29:27 -0600 Subject: [PATCH 06/16] fixup! e2ee/device verification: move general error handling under framework Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- content/client-server-api/modules/end_to_end_encryption.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index e93e54d31..4faa7efa7 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -603,7 +603,7 @@ At any point the interactive verification can go wrong. The following describes what to do when an error happens: - Alice or Bob can cancel the verification at any time. An - `m.key.verification.cancel` message must be sent to signify the + [`m.key.verification.cancel`](#mkeyverificationcancel) message must be sent to signify the cancellation. - The verification can time out. Clients should time out a verification that does not complete within 10 minutes. Additionally, clients should expire a From 3fbb048689469a7734a7b637085e83cd42628d45 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Fri, 7 Jun 2024 10:29:44 -0600 Subject: [PATCH 07/16] fixup! e2ee/device verification: move general error handling under framework Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- content/client-server-api/modules/end_to_end_encryption.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 4faa7efa7..2c9863e48 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -744,7 +744,7 @@ devices: | | ``` -###### SAS error handling +###### Error handling during SAS verification At any point the interactive verification can go wrong. The following describes what to do when an error happens: From d6c6a0361fd5adb647e3b7eca6e844fee087f8c3 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Fri, 7 Jun 2024 10:32:49 -0600 Subject: [PATCH 08/16] fixup! e2ee/device verification: move general error handling under framework Signed-off-by: Sumner Evans --- .../modules/end_to_end_encryption.md | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 2c9863e48..ce8e63446 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -602,24 +602,27 @@ package naming convention. At any point the interactive verification can go wrong. The following describes what to do when an error happens: -- Alice or Bob can cancel the verification at any time. An - [`m.key.verification.cancel`](#mkeyverificationcancel) message must be sent to signify the - cancellation. -- The verification can time out. Clients should time out a verification that - does not complete within 10 minutes. Additionally, clients should expire a - `transaction_id` which goes unused for 10 minutes after having last - sent/received it. The client should inform the user that the verification - timed out, and send an appropriate `m.key.verification.cancel` message to - the other device. -- When the same device attempts to initiate multiple verification attempts, - the recipient should cancel all attempts with that device. -- When a device receives an unknown `transaction_id`, it should send an - appropriate `m.key.verification.cancel` message to the other device - indicating as such. This does not apply for inbound - `m.key.verification.request` or `m.key.verification.cancel` messages. -- If the device receives a message out of sequence or that it was not - expecting, it should notify the other device with an appropriate - `m.key.verification.cancel` message. +- Alice or Bob can cancel the verification at any time. An + [`m.key.verification.cancel`](#mkeyverificationcancel) message must be sent to + signify the cancellation. +- The verification can time out. Clients should time out a verification that + does not complete within 10 minutes. Additionally, clients should expire a + `transaction_id` which goes unused for 10 minutes after having last + sent/received it. The client should inform the user that the verification + timed out, and send an appropriate + [`m.key.verification.cancel`](#mkeyverificationcancel) message to the other + device. +- When the same device attempts to initiate multiple verification attempts, + the recipient should cancel all attempts with that device. +- When a device receives an unknown `transaction_id`, it should send an + appropriate [`m.key.verification.cancel`](#mkeyverificationcancel) message to + the other device indicating as such. This does not apply for inbound + [`m.key.verification.request`](#mkeyverificationrequest), + [`m.key.verification.start`](#mkeyverificationstart), or + [`m.key.verification.cancel`](#mkeyverificationcancel) messages. +- If the device receives a message out of sequence or that it was not expecting, + it should notify the other device with an appropriate + [`m.key.verification.cancel`](#mkeyverificationcancel) message. ##### Short Authentication String (SAS) verification From 2ea4e13239e78fde5692cb57187332d49bd1edc9 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Fri, 7 Jun 2024 10:35:31 -0600 Subject: [PATCH 09/16] fixup! e2ee/device verification: move general error handling under framework Signed-off-by: Sumner Evans --- .../modules/end_to_end_encryption.md | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index ce8e63446..0e06f410f 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -602,27 +602,27 @@ package naming convention. At any point the interactive verification can go wrong. The following describes what to do when an error happens: -- Alice or Bob can cancel the verification at any time. An - [`m.key.verification.cancel`](#mkeyverificationcancel) message must be sent to - signify the cancellation. -- The verification can time out. Clients should time out a verification that - does not complete within 10 minutes. Additionally, clients should expire a - `transaction_id` which goes unused for 10 minutes after having last - sent/received it. The client should inform the user that the verification - timed out, and send an appropriate - [`m.key.verification.cancel`](#mkeyverificationcancel) message to the other - device. -- When the same device attempts to initiate multiple verification attempts, - the recipient should cancel all attempts with that device. -- When a device receives an unknown `transaction_id`, it should send an - appropriate [`m.key.verification.cancel`](#mkeyverificationcancel) message to - the other device indicating as such. This does not apply for inbound - [`m.key.verification.request`](#mkeyverificationrequest), - [`m.key.verification.start`](#mkeyverificationstart), or - [`m.key.verification.cancel`](#mkeyverificationcancel) messages. -- If the device receives a message out of sequence or that it was not expecting, - it should notify the other device with an appropriate - [`m.key.verification.cancel`](#mkeyverificationcancel) message. +- Alice or Bob can cancel the verification at any time. An + [`m.key.verification.cancel`](#mkeyverificationcancel) message must be sent + to signify the cancellation. +- The verification can time out. Clients should time out a verification that + does not complete within 10 minutes. Additionally, clients should expire a + `transaction_id` which goes unused for 10 minutes after having last + sent/received it. The client should inform the user that the verification + timed out, and send an appropriate + [`m.key.verification.cancel`](#mkeyverificationcancel) message to the other + device. +- When the same device attempts to initiate multiple verification attempts, + the recipient should cancel all attempts with that device. +- When a device receives an unknown `transaction_id`, it should send an + appropriate [`m.key.verification.cancel`](#mkeyverificationcancel) message + to the other device indicating as such. This does not apply for inbound + [`m.key.verification.request`](#mkeyverificationrequest), + [`m.key.verification.start`](#mkeyverificationstart), or + [`m.key.verification.cancel`](#mkeyverificationcancel) messages. +- If the device receives a message out of sequence or that it was not + expecting, it should notify the other device with an appropriate + [`m.key.verification.cancel`](#mkeyverificationcancel) message. ##### Short Authentication String (SAS) verification @@ -749,8 +749,9 @@ devices: ###### Error handling during SAS verification -At any point the interactive verification can go wrong. The following -describes what to do when an error happens: +At any point the interactive verification can go wrong. In addition to the +[Error handling during key verification](#error-handling-during-key-verification) The following describes +what to do when an error happens: - 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 From d66a8057af86e76bea2b2d6ad9640ec9a6057d55 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Fri, 7 Jun 2024 10:37:17 -0600 Subject: [PATCH 10/16] fixup! e2ee/device verification: move general error handling under framework Signed-off-by: Sumner Evans --- content/client-server-api/modules/end_to_end_encryption.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 0e06f410f..df9f47853 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -750,8 +750,10 @@ devices: ###### Error handling during SAS verification At any point the interactive verification can go wrong. In addition to the -[Error handling during key verification](#error-handling-during-key-verification) The following describes -what to do when an error happens: +general +[error handling during key verification](#error-handling-during-key-verification) +that is applicable to all verification methods, the following describes what to +do when SAS-specific errors happen: - 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 From 55375f4452238c717ff48135ce6a3ec1ce59ec06 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Fri, 7 Jun 2024 10:39:47 -0600 Subject: [PATCH 11/16] fixup! e2ee/device verification: move general error handling under framework Signed-off-by: Sumner Evans --- content/client-server-api/modules/end_to_end_encryption.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index df9f47853..64b97bb99 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -471,8 +471,10 @@ In general, verification operates as follows: that the verification was successful. Verifications can be cancelled by either device at any time by sending an -[`m.key.verification.cancel`](#mkeyverificationcancel) event with a `code` field that indicates the reason -it was cancelled. +[`m.key.verification.cancel`](#mkeyverificationcancel) event with a `code` field +that indicates the reason it was cancelled. The +[Error handling during key verification](#error-handling-during-key-verification) +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 verify, or may not want to choose a specific device. In this case, Alice will From d10deb028aacdc509a73c261cdfcef7bdee680cb Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Fri, 7 Jun 2024 10:44:36 -0600 Subject: [PATCH 12/16] fixup! e2ee/device verification: move general error handling under framework Signed-off-by: Sumner Evans --- content/client-server-api/modules/end_to_end_encryption.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 64b97bb99..b83b3780f 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -471,7 +471,7 @@ In general, verification operates as follows: that the verification was successful. 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 [Error handling during key verification](#error-handling-during-key-verification) section explains specific situations where cancellation messages should be sent. From b87ffa6cceb1ed9f60b7d25217f68dea0b7477b2 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Fri, 7 Jun 2024 11:09:02 -0600 Subject: [PATCH 13/16] e2ee/device verification: normalize all links This commit changes the format of all links in the Device Verification section to be: [`m.key.verification.whatever`](#mkeyverificationwhatever) This involved adding links in a bunch of places, but also changing many links that did not have code within them to have the backticks. Signed-off-by: Sumner Evans --- .../modules/end_to_end_encryption.md | 249 ++++++++++-------- 1 file changed, 136 insertions(+), 113 deletions(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index b83b3780f..2c772ae5c 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -471,27 +471,29 @@ In general, verification operates as follows: that the verification was successful. 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 [Error handling during key verification](#error-handling-during-key-verification) 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 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 -events will use the same transaction ID. When Bob 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 -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. +send [`m.key.verification.request`](#mkeyverificationrequest) events to all of +Bob's devices. All of these events will use the same transaction ID. When Bob +accepts or declines the verification on one of his devices (sending either an +[`m.key.verification.ready`](#mkeyverificationready) or +[`m.key.verification.cancel`](#mkeyverificationcancel) event), Alice will send +an [`m.key.verification.cancel`](#mkeyverificationcancel) 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`](#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 messages, Alice only sends one request event (an event with type -`m.room.message` with `msgtype: m.key.verification.request`, rather than an -event with type `m.key.verification.request`), to the room. In addition, Alice -does not send an `m.key.verification.cancel` event to tell Bob's other devices -that the request as already been accepted; instead, when Bob's other devices -see his `m.key.verification.ready` event, they will know that the request has -already been accepted, and that they should ignore the request. +[`m.room.message` with `msgtype: m.key.verification.request`](#mroommessagemkeyverificationrequest), +rather than an event with type +[`m.key.verification.request`](#mkeyverificationrequest)), to the room. In +addition, Alice does not send an +[`m.key.verification.cancel`](#mkeyverificationcancel) event to tell Bob's other +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 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, 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. +Upon receipt of Alice's [`m.key.verification.request`](#mkeyverificationrequest) +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. +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`](#mkeyverificationcancel) 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), +[`m.key.verification.cancel`](#mkeyverificationcancel) 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`](#mkeyverificationcancel) 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`](#mkeyverificationstart) message, and both specify +the same verification method, then the +[`m.key.verification.start`](#mkeyverificationstart) 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`](#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 -`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`. +[`m.key.verification.start`](#mkeyverificationstart) messages do not specify the +same verification method, then the verification should be cancelled with a +`code` of `m.unexpected_message`. -When verifying using to-device messages, an `m.key.verification.start` -message can also be sent independently of any -request, specifying the verification method to use. This behaviour is -deprecated, and new clients should not begin verifications in this way. -However, clients should handle such verifications started by other clients. +When verifying using to-device messages, an +[`m.key.verification.start`](#mkeyverificationstart) message can also be sent +independently of any request, specifying the verification method to use. This +behaviour is deprecated, and new clients should not begin verifications in this +way. However, clients should handle such verifications started by other clients. Individual verification methods may add additional steps, events, and 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. 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. +`methods` fields of the [`m.key.verification.request`](#mkeyverificationrequest) +and [`m.key.verification.ready`](#mkeyverificationready), events. 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. 2. Alice and Bob begin a key verification using the key verification framework as described above. -3. Alice's device sends Bob's device an `m.key.verification.start` - message. Alice's device ensures it has a copy of Bob's device key. +3. Alice's device sends Bob's device an + [`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 protocol, hash algorithm, message authentication code, and SAS 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 key *KBpublic*. 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 for later use. 9. Alice's device creates an ephemeral Curve25519 key pair (*KAprivate*, *KApublic*) - and replies to Bob's device with an `m.key.verification.key`, - sending only the public key - *KApublic*. + and replies to Bob's device with an + [`m.key.verification.key`](#mkeyverificationkey), sending only the public + key *KApublic*. 10. Bob's device receives Alice's message and replies with its own - `m.key.verification.key` message containing its public key - *KBpublic*. + [`m.key.verification.key`](#mkeyverificationkey) message containing its + public key *KBpublic*. 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 - 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 their private ephemeral key, and the other device's ephemeral public key (*ECDH(KAprivate*, *KBpublic*) @@ -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 MAC calculation is defined [below](#mac-calculation). -16. Alice's device sends Bob's device an `m.key.verification.mac` - message containing the MAC of Alice's device keys and the MAC of her - key IDs to be verified. Bob's device does the same for Bob's device - keys and key IDs concurrently with Alice. -17. When the other device receives the `m.key.verification.mac` message, - the device calculates the MACs of its copies of the other device's - keys given in the message, as well as the MAC of the - comma-separated, sorted, list of key IDs in the message. The device - compares these with the MAC values given in the message, and if - everything matches then the device keys are verified. -18. Alice and Bob's devices send `m.key.verification.done` messages to complete - the verification. +16. Alice's device sends Bob's device an + [`m.key.verification.mac`](#mkeyverificationmac) message containing the MAC + of Alice's device keys and the MAC of her key IDs to be verified. Bob's + device does the same for Bob's device keys and key IDs concurrently with + Alice. +17. When the other device receives the + [`m.key.verification.mac`](#mkeyverificationmac) message, the device + calculates the MACs of its copies of the other device's keys given in the + message, as well as the MAC of the comma-separated, sorted, list of key IDs + in the message. The device compares these with the MAC values given in the + message, and if everything matches then the device keys are verified. +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 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 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, - the device should send an appropriate `m.key.verification.cancel` - message to the other device. + the device should send an appropriate + [`m.key.verification.cancel`](#mkeyverificationcancel) message to the other + device. ###### Verification messages specific to SAS Building off the common framework, the following events are involved in SAS verification. -The `m.key.verification.cancel` event is unchanged, however the -following error codes are used in addition to those already specified: +The [`m.key.verification.cancel`](#mkeyverificationcancel) event is unchanged, +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 agreement, hash, MAC, or SAS method. @@ -822,7 +835,8 @@ defined as follows: form `{algorithm}:{keyId}`. For example, the key list could look like: `ed25519:Cross+Signing+Key,ed25519:DEVICEID`. In this way, the recipient can 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 [`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: - The string `MATRIX_KEY_VERIFICATION_SAS|`. -- The Matrix ID of the user who sent the `m.key.verification.start` - message, followed by `|`. +- The Matrix ID of the user who sent the + [`m.key.verification.start`](#mkeyverificationstart) message, followed by + `|`. - The Device ID of the device which sent the - `m.key.verification.start` 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 + [`m.key.verification.start`](#mkeyverificationstart) message, followed by + `|`. +- 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 `|`. -- The Matrix ID of the user who sent the `m.key.verification.accept` - message, followed by `|`. +- The Matrix ID of the user who sent the + [`m.key.verification.accept`](#mkeyverificationaccept) message, followed by + `|`. - The Device ID of the device which sent the - `m.key.verification.accept` 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 + [`m.key.verification.accept`](#mkeyverificationaccept) message, followed by + `|`. +- 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 `|`. - 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 string `MATRIX_KEY_VERIFICATION_SAS`. -- The Matrix ID of the user who sent the `m.key.verification.start` - message. +- The Matrix ID of the user who sent the + [`m.key.verification.start`](#mkeyverificationstart) message. - The Device ID of the device which sent the - `m.key.verification.start` message. -- The Matrix ID of the user who sent the `m.key.verification.accept` - message. + [`m.key.verification.start`](#mkeyverificationstart) message. +- The Matrix ID of the user who sent the + [`m.key.verification.accept`](#mkeyverificationaccept) message. - 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. 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 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 -`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 `mac` property. Servers therefore must ensure that device IDs will not 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 `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 -advertise the ability to scan a QR code, clients use the names -`m.qr_code.scan.v1` and `m.reciprocate.v1` in the `methods` fields of the -`m.key.verification.request` and `m.key.verification.ready` events. -Clients that 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. +[`m.key.verification.request`](#mkeyverificationrequest) and +[`m.key.verification.ready`](#mkeyverificationready) events. To advertise the +ability to scan a QR code, clients use the names `m.qr_code.scan.v1` and +`m.reciprocate.v1` in the `methods` fields of the +[`m.key.verification.request`](#mkeyverificationrequest) and +[`m.key.verification.ready`](#mkeyverificationready) events. Clients that +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: @@ -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 expected values for the keys. If not, Alice's device displays an error 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: - 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 he has the right key for Alice because Alice's device will have shown this message, as otherwise the verification would be cancelled. -8. Alice's device sends an `m.key.verification.start` message with `method` set - to `m.reciprocate.v1` to Bob (see below). The message includes the shared - secret from the QR code. This signals to Bob's device that Alice has - scanned Bob's QR code. +8. Alice's device sends an [`m.key.verification.start`](#mkeyverificationstart) + message with `method` set to `m.reciprocate.v1` to Bob (see below). The + message includes the shared secret from the QR code. This signals to Bob's + device that Alice has scanned Bob's QR code. This message is merely a signal for Bob's device to proceed to the next step, and is not used for verification purposes. -9. Upon receipt of the `m.key.verification.start` message, Bob's device ensures - that the shared secret matches. +9. Upon receipt of the [`m.key.verification.start`](#mkeyverificationstart) + message, Bob's device ensures that the shared secret matches. 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 @@ -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 trust Alice's key, under the assumption that this communication is done 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 From a79d5a66ed51d418bdb32de92976d2f8698fa943 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Fri, 7 Jun 2024 11:18:57 -0600 Subject: [PATCH 14/16] fixup! Add changelog Signed-off-by: Sumner Evans --- changelogs/client_server/newsfragments/1830.clarification | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/client_server/newsfragments/1830.clarification b/changelogs/client_server/newsfragments/1830.clarification index 0283194a4..a5c066269 100644 --- a/changelogs/client_server/newsfragments/1830.clarification +++ b/changelogs/client_server/newsfragments/1830.clarification @@ -1 +1 @@ -Clarify a few things in the Device Verification section. +Clarify a few things in the Device Verification section and improve links throughout the section. From 4282a1a319362cf8dca6948ef77b1a6b3a464a27 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Fri, 7 Jun 2024 11:19:35 -0600 Subject: [PATCH 15/16] e2ee/device verification start: clarify required nature of transaction_id or m.relates_to Add notes about the fact that the start event *may* be the first event sent during a verification process and that clients should handle other clients doing so, but not themselves send the start event first. Signed-off-by: Sumner Evans --- .../schema/m.key.verification.start.yaml | 50 ++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/data/event-schemas/schema/m.key.verification.start.yaml b/data/event-schemas/schema/m.key.verification.start.yaml index ef862ffcf..70cb86c3d 100644 --- a/data/event-schemas/schema/m.key.verification.start.yaml +++ b/data/event-schemas/schema/m.key.verification.start.yaml @@ -16,11 +16,20 @@ properties: transaction_id: type: string description: |- - Required when sent as a to-device message. An opaque identifier for - the verification process. Must be unique with respect to the devices - involved. Must be the same as the `transaction_id` given in the - `m.key.verification.request` if this process is originating from a - request. + Required when sent as a to-device message unless the start event is + sent without a corresponding + [`m.key.verification.request`](#mkeyverificationrequest). + + An opaque identifier for the verification process. Must be unique + with respect to the devices involved. + + Must be the same as the `transaction_id` given in the + [`m.key.verification.request`](#mkeyverificationrequest) if this + process is originating from a request. + + Note that sending a start event without a request is deprecated, and + clients should not send a start event without first sending a request + event, but clients should handle other clients doing so. method: type: string description: |- @@ -32,7 +41,36 @@ properties: when the `method` chosen only verifies one user's key. This field will never be present if the `method` verifies keys both ways. m.relates_to: - $ref: m.key.verification.m.relates_to.yaml + description: |- + Required when sent as an in-room message unless the start event is + sent without a corresponding + [`m.key.verification.request`](#mkeyverificationrequest). + + Indicates the + [`m.key.verification.request`](#mkeyverificationrequest) that this + message is related to. Note that for encrypted messages, this + property should be in the unencrypted portion of the event. + + Note that sending a start event without a request is deprecated, and + clients should not send a start event without first sending a request + event, but clients should handle other clients doing so. + properties: + rel_type: + type: string + enum: + - m.reference + description: |- + The relationship type. Currently, this can only be an + [`m.reference`](/client-server-api/#reference-relations) + relationship type. + event_id: + type: string + description: |- + The event ID of the + [`m.key.verification.request`](#mkeyverificationrequest) that + this message is related to. + type: object + title: VerificationRelatesTo required: - from_device - method From a9350fcc41133f6d96a71ebcce750754098c7e53 Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Fri, 7 Jun 2024 11:31:58 -0600 Subject: [PATCH 16/16] fixup! e2ee/device verification: normalize all links Signed-off-by: Sumner Evans --- .../schema/m.key.verification.cancel.yaml | 22 +++++++++++-------- .../m.key.verification.m.relates_to.yaml | 11 +++++----- .../schema/m.key.verification.ready.yaml | 8 +++---- .../schema/m.key.verification.request.yaml | 5 +++-- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/data/event-schemas/schema/m.key.verification.cancel.yaml b/data/event-schemas/schema/m.key.verification.cancel.yaml index 237f0d065..53973a394 100644 --- a/data/event-schemas/schema/m.key.verification.cancel.yaml +++ b/data/event-schemas/schema/m.key.verification.cancel.yaml @@ -31,17 +31,19 @@ properties: * `m.user`: The user cancelled the verification. * `m.timeout`: The verification process timed out. Verification processes - can define their own timeout parameters. + can define their own timeout parameters. * `m.unknown_transaction`: The device does not know about the given transaction - ID. + ID. - * `m.unknown_method`: The device does not know how to handle the requested - method. This should be sent for `m.key.verification.start` messages and - messages defined by individual verification processes. + * `m.unknown_method`: The device does not know how to handle the + requested method. This should be sent for + [`m.key.verification.start`](#mkeyverificationstart) messages and + messages defined by individual verification processes. - * `m.unexpected_message`: The device received an unexpected message. Typically - raised when one of the parties is handling the verification out of order. + * `m.unexpected_message`: The device received an unexpected message. + Typically raised when one of the parties is handling the + verification out of order. * `m.key_mismatch`: The key was not verified. @@ -49,8 +51,10 @@ properties: * `m.invalid_message`: The message received was invalid. - * `m.accepted`: A `m.key.verification.request` was accepted by a different - device. The device receiving this error can ignore the verification request. + * `m.accepted`: A + [`m.key.verification.request`](#mkeyverificationrequest) was + accepted by a different device. The device receiving this error can + ignore the verification request. Clients should be careful to avoid error loops. For example, if a device sends an incorrect message and the client returns `m.invalid_message` to which it diff --git a/data/event-schemas/schema/m.key.verification.m.relates_to.yaml b/data/event-schemas/schema/m.key.verification.m.relates_to.yaml index 038344b9c..9604602a3 100644 --- a/data/event-schemas/schema/m.key.verification.m.relates_to.yaml +++ b/data/event-schemas/schema/m.key.verification.m.relates_to.yaml @@ -1,9 +1,9 @@ --- 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. + [`m.key.verification.request`](#mkeyverificationrequest) 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 @@ -15,7 +15,8 @@ properties: event_id: type: string description: |- - The event ID of the `m.key.verification.request` that this message is - related to. + The event ID of the + [`m.key.verification.request`](#mkeyverificationrequest) that this + message is related to. type: object title: VerificationRelatesTo diff --git a/data/event-schemas/schema/m.key.verification.ready.yaml b/data/event-schemas/schema/m.key.verification.ready.yaml index 1c5ed7bdf..cdaac01aa 100644 --- a/data/event-schemas/schema/m.key.verification.ready.yaml +++ b/data/event-schemas/schema/m.key.verification.ready.yaml @@ -4,7 +4,7 @@ allOf: description: |- Accepts a key verification request. Sent in response to an - `m.key.verification.request` event. + [`m.key.verification.request`](#mkeyverificationrequest) event. properties: content: properties: @@ -16,14 +16,14 @@ properties: 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. + verification request, as given in the + [`m.key.verification.request`](#mkeyverificationrequest) 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. + [`m.key.verification.request`](#mkeyverificationrequest) message. items: type: string m.relates_to: diff --git a/data/event-schemas/schema/m.key.verification.request.yaml b/data/event-schemas/schema/m.key.verification.request.yaml index 76ba618d4..9a2fd098e 100644 --- a/data/event-schemas/schema/m.key.verification.request.yaml +++ b/data/event-schemas/schema/m.key.verification.request.yaml @@ -4,8 +4,9 @@ allOf: description: |- Requests a key verification using to-device messaging. When requesting a key - verification in a room, a `m.room.message` should be used, with - [`m.key.verification.request`](#mroommessagemkeyverificationrequest) as msgtype. + verification in a room, a [`m.room.message`](#mroommessage should be used, + with [`m.key.verification.request`](#mroommessagemkeyverificationrequest) as + msgtype. properties: content: properties: