From 1d98a7441b06fac3cdad7a0a29779e860d9e4bda Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Apr 2021 18:54:22 -0400 Subject: [PATCH 1/3] Add spec for verification by QR codes. --- .../modules/end_to_end_encryption.md | 125 +++++++++++++++++- ...y.verification.start$m.reciprocate.v1.yaml | 44 ++++++ 2 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 data/event-schemas/schema/m.key.verification.start$m.reciprocate.v1.yaml 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 16cd3178..b5388003 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -357,8 +357,8 @@ out-of-band channel: there is no way to do it within Matrix without trusting the administrators of the homeservers. In Matrix, verification works by Alice meeting Bob in person, or -contacting him via some other trusted medium, and using [SAS -Verification](#SAS Verification) to interactively verify Bob's devices. +contacting him via some other trusted medium, and using one of the +verification methods defined below to interactively verify Bob's devices. Alice and Bob may also read aloud their unpadded base64 encoded Ed25519 public key, as returned by `/keys/query`. @@ -986,6 +986,127 @@ user-signing keys. {{% http-api spec="client-server" api="cross_signing" %}} +##### QR codes + +Verifying by QR codes provides a quick way to verify when one of the parties +has a device capable of scanning a QR code. The QR code encodes both parties' +master signing keys as well as a random shared secret that is used to allow +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. + +The process between Alice and Bob verifying each other would be: + +1. Alice and Bob meet in person, and want to verify each other's keys. +2. Alice and Bob begin a key verification using the key verification + framework as described above. +3. Alice's client displays a QR code that Bob is able to scan if Bob's client + indicated the ability to scan, an option to scan Bob's QR code if her client + is able to scan. Bob's client prompts displays a QR code that Alice can + scan if Alice's client indicated the ability to scan, and an option to scan + Alice's QR code if his client is able to scan. The format for the QR code + is described below. +5. Alice scans Bob's QR code. +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. + + Otherwise, at this point: + - Alice's device has now verified Bob's key, and + - Alice's device knows that Bob has the correct key for her. + + Thus for Bob to verify Alice's key, Alice needs to tell Bob that he has the + right key. +7. Alice's device displays a message saying that the verification was + successful. This message tells Alice that she has the right key for Bob, + and tells Bob that he has the right key for Alice. +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. + + 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. + + 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 + verification of Bob's keys.) + + If the shared secret does match, it asks Bob to confirm that Alice + has scanned the QR code. +10. Bob sees Alice's device confirm that the key matches, and presses the button + on his device to indicate that Alice's key is verified. + + Bob's verification of Alice's key hinges on Alice telling Bob the result of + her scan. Since the QR code includes what Bob thinks Alice's key is, + Alice's device can check whether Bob has the right key for her. Alice has + no motivation to lie about the result, as getting Bob to trust an incorrect + key would only affect communications between herself and Bob. Thus Alice + 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. + +###### QR code format + +The QR codes to be displayed and scanned using this format will encode binary +strings in the general form: + +- the ASCII string "MATRIX" +- one byte indicating the QR code version (must be `0x02`) +- one byte indicating the QR code verification mode. May be one of the + following values: + - `0x00` verifying another user with cross-signing + - `0x01` self-verifying in which the current device does trust the master key + - `0x02` self-verifying in which the current device does not yet trust the + master key +- the event ID or `transaction_id` of the associated verification + request event, encoded as: + - two bytes in network byte order (big-endian) indicating the length in + bytes of the ID as a UTF-8 string + - the ID as a UTF-8 string +- the first key, as 32 bytes. The key to use depends on the mode field: + - if `0x00` or `0x01`, then the current user's own master cross-signing public key + - if `0x02`, then the current device's device key +- the second key, as 32 bytes. The key to use depends on the mode field: + - if `0x00`, then what the device thinks the other user's master + cross-signing key is + - if `0x01`, then what the device thinks the other device's device key is + - if `0x02`, then what the device thinks the user's master cross-signing key + is +- a random shared secret, as a byte string. It is suggested to use a secret + that is about 8 bytes long. Note: as we do not share the length of the + secret, and it is not a fixed size, clients will just use the remainder of + binary string as the shared secret. + +For example, if Alice displays a QR code encoding the following binary string: + +``` + "MATRIX" |ver|mode| len | event ID + 4D 41 54 52 49 58 02 00 00 2D 21 41 42 43 44 ... +| user's cross-signing key | other user's cross-signing key | shared secret + 00 01 02 03 04 05 06 07 ... 10 11 12 13 14 15 16 17 ... 20 21 22 23 24 25 26 27 +``` + +this indicates that Alice is verifying another user (say Bob), in response to +the request from event "$ABCD...", her cross-signing key is +`0001020304050607...` (which is "AAECAwQFBg..." in base64), she thinks that +Bob's cross-signing key is `1011121314151617...` (which is "EBESExQVFh..." in +base64), and the shared secret is `2021222324252627` (which is "ICEiIyQlJic" in +base64). + +###### Verification messages specific to QR codes + +{{% event event="m.key.verification.start$m.reciprocate.v1" %}} + #### Sharing keys between devices If Bob has an encrypted conversation with Alice on his computer, and diff --git a/data/event-schemas/schema/m.key.verification.start$m.reciprocate.v1.yaml b/data/event-schemas/schema/m.key.verification.start$m.reciprocate.v1.yaml new file mode 100644 index 00000000..a60711b3 --- /dev/null +++ b/data/event-schemas/schema/m.key.verification.start$m.reciprocate.v1.yaml @@ -0,0 +1,44 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + Begins a key verification process using the `m.reciprocate.v1` method, after + scanning a QR code. +properties: + content: + properties: + from_device: + type: string + description: |- + The device ID which is initiating the process. + 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. + method: + type: string + enum: ["m.reciprocate.v1"] + description: |- + The verification method to use. + secret: + type: string + description: |- + The shared secret from the QR code, encoded using unpadded base64. + m.relates_to: + allOf: + - $ref: m.key.verification.m.relates_to.yaml + required: + - from_device + - method + - secret + type: object + type: + enum: + - m.key.verification.start + type: string +type: object From 6338edc6a1c8a06acfc349153c59ba5616f4bd87 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 27 Apr 2021 20:56:18 -0400 Subject: [PATCH 2/3] add changelog --- changelogs/client_server/newsfragments/3149.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/3149.feature diff --git a/changelogs/client_server/newsfragments/3149.feature b/changelogs/client_server/newsfragments/3149.feature new file mode 100644 index 00000000..2a85b47f --- /dev/null +++ b/changelogs/client_server/newsfragments/3149.feature @@ -0,0 +1 @@ +Add key verification method using QR codes ([MSC1544](https://github.com/matrix-org/matrix-doc/pull/1544)). From dc8dd05c630c4db640e1577dd3288f02120c2d6b Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 28 Apr 2021 15:59:55 -0400 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Travis Ralston --- .../modules/end_to_end_encryption.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 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 b5388003..db689ad0 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -999,6 +999,9 @@ To advertise the ability to show a QR code, clients use the names 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. The process between Alice and Bob verifying each other would be: @@ -1010,7 +1013,9 @@ The process between Alice and Bob verifying each other would be: is able to scan. Bob's client prompts displays a QR code that Alice can scan if Alice's client indicated the ability to scan, and an option to scan Alice's QR code if his client is able to scan. The format for the QR code - is described below. + is described below. Other options, like starting SAS Emoji verification, + can be presented alongside the QR code if the devices have appropriate + support. 5. Alice scans Bob's QR code. 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 @@ -1024,8 +1029,11 @@ The process between Alice and Bob verifying each other would be: Thus for Bob to verify Alice's key, Alice needs to tell Bob that he has the right key. 7. Alice's device displays a message saying that the verification was - successful. This message tells Alice that she has the right key for Bob, - and tells Bob that he has the right key for Alice. + successful because the QR code's keys will have matched the keys + expected for Bob. Bob's device hasn't had a chance to verify Alice's + 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 @@ -1060,9 +1068,9 @@ The process between Alice and Bob verifying each other would be: The QR codes to be displayed and scanned using this format will encode binary strings in the general form: -- the ASCII string "MATRIX" +- the ASCII string `MATRIX` - one byte indicating the QR code version (must be `0x02`) -- one byte indicating the QR code verification mode. May be one of the +- one byte indicating the QR code verification mode. Should be one of the following values: - `0x00` verifying another user with cross-signing - `0x01` self-verifying in which the current device does trust the master key