From 3aba9b153b1d96bbff1538db85fcc3eca6c3178a Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 20 Aug 2018 15:24:44 -0400 Subject: [PATCH 01/26] initial dump of proposal --- proposals/1543-qr_code_key_verification.md | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 proposals/1543-qr_code_key_verification.md diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md new file mode 100644 index 00000000..3f1ee6b1 --- /dev/null +++ b/proposals/1543-qr_code_key_verification.md @@ -0,0 +1,85 @@ +Key verification using QR codes +=============================== + +Problem/Background +------------------ + +Key verification is essential in ensuring that end-to-end encrypted messages +cannot be read by unauthorized parties. Traditionally, key verification is +done by comparing long strings. To save users from the tedium of reading out +long strings, some systems allow one party to verify the other party by +scanning a QR code; by doing this twice, both parties can verify each other. +In this proposal, we present a method for both parties to verify each other by +only scanning one QR code. + +Other methods exist for making it easier to verify keys. In Matrix, +[MSC1267](https://github.com/matrix-org/matrix-doc/issues/1267) proposes +another method, which is useful when neither party is able to scan a QR code. + +Proposal +-------- + +Example flow: + +1. Alice and Bob meet in person, and want to verify each other's keys. +2. Bob tells his device to display a QR code. Bob's device displays a + byte-encoded QR code using UTF-8 of the string `/verify + `. (This format matches the + `/verify` command in Riot.) +3. Alice scans the QR code. +4. Alice's device ensures that the user ID in the QR code is the same as the + expected user ID. This can be done by prompting Alice with the user ID, or + can be done automatically if the device already knows what user ID to + expect. At this point, Alice's device has now verified Bob's key. +5. Alice's device sends a `m.key.verification.reciprocate` message (see below) + as a to-device message to Bob's device (using the user ID and device ID from + the QR code.) +6. Bob's device fetches Alice's public key, signs it, and sends it to Alice's + device in a `m.key.verification.check_own_key` to-device message (see + below). Bob's device displays a message saying that Alice wants him to + verify her key, and presents a button for him to press /after/ Alice's + device says that things match. +7. Alice's device receives the `m.key.verification.check_own_key` message, + checks Bob's signature, and checks that the key is the same as her device + key. Alice's device displays the result of the checks. +8. 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. + +### Message types + +#### `m.key.verification.reciprocate` + +Tells Bob's device that Alice has verified his key, and requests that he verify +Alice's key in turn. + +message contents: + +- `device_id`: the ID of the device that Alice is using +- `transaction_id`: a unique identifier for the transaction (is this needed?) + +#### `m.key.verification.check_own_key` + +Tells Alice's device what Bob's device thinks her key is. + +message contents: + +- `key`: The key that Bob's device has for Alice's device +- `transaction_id`: the transaction ID from the + `m.key.verification.reciprocate` message +- `signatures`: signature of the key and transaction ID, signed using Bob's key + +Tradeoffs +--------- + +Security Considerations +----------------------- + +Step 4 is to ensure that Bob does not present a QR code claiming to be Carol's +key. Without this check, Bob will be able to trick Alice into verifying a key +under his control, and evesdropping on Alice's communications with Carol. + +Other Issues +------------ + +Conclusion +---------- From 37344710284ba777ae0ee30ff8aaf91aebd9753f Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 20 Aug 2018 15:52:01 -0400 Subject: [PATCH 02/26] mention option of having the QR code be a URL --- proposals/1543-qr_code_key_verification.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 3f1ee6b1..0256cafb 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -68,8 +68,13 @@ message contents: `m.key.verification.reciprocate` message - `signatures`: signature of the key and transaction ID, signed using Bob's key -Tradeoffs ---------- +Tradeoffs/Alternatives +---------------------- + +The exact format for the QR code is not nailed down. Another possibility is +that it could be a URL, so that a user can scan the code in any QR code +scanner, and have it automatically open the user's Matrix client to begin the +verification. Security Considerations ----------------------- From acd9a5d32f22afc10a807ffdc4da5ccb6ce87fcf Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 20 Aug 2018 19:35:27 -0400 Subject: [PATCH 03/26] add note about Bob mashing the "Verify" button prematurely --- proposals/1543-qr_code_key_verification.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 0256cafb..8388d27f 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -83,6 +83,21 @@ Step 4 is to ensure that Bob does not present a QR code claiming to be Carol's key. Without this check, Bob will be able to trick Alice into verifying a key under his control, and evesdropping on Alice's communications with Carol. +The security of verifying Alice's key depends on Bob not hitting the "Verified" +button until after Alice's device indicates success. However, users have a +tendency to click on buttons without reading what the screen says. This might +be addressed by: + +- allowing Bob to easily undo the verification if Alice's device subsequently + gives an error +- posing Bob a dummy question that he cannot answer until after Alice's device + displays the check results. For example: "Does Alice's device show a cat or + a dog?" Alice's device will show one or the other after it has checked the + key received from Bob, forcing Bob to wait for the check to complete. + (Whether a cat or a dog is displayed could be keyed to, for example, a bit in + the transaction ID.) +- (possibly other ways) + Other Issues ------------ From 95280d8b09d5ee9487f10f45a47bf4c645659a4a Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 5 Sep 2018 16:37:42 -0400 Subject: [PATCH 04/26] switch QR code to URL, add introductory text, add clarifications, reorganize --- proposals/1543-qr_code_key_verification.md | 35 ++++++++++++++-------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 8388d27f..148728b9 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -12,20 +12,24 @@ scanning a QR code; by doing this twice, both parties can verify each other. In this proposal, we present a method for both parties to verify each other by only scanning one QR code. -Other methods exist for making it easier to verify keys. In Matrix, -[MSC1267](https://github.com/matrix-org/matrix-doc/issues/1267) proposes -another method, which is useful when neither party is able to scan a QR code. - Proposal -------- +When Alice and Bob meet in person to verify keys, Alice will scan a QR code +generated by Bob's device. This easily allows Alice to verify Bob's key, but +does not give Bob any information about Alice's key in order to verify it. +However, Bob's device can now send to Alice's device what it thinks is her key +(signed by his key, so that Alice can verify that the message actually came +from his device), and Alice's device can do the verification on behalf of Bob +and display the result. + Example flow: 1. Alice and Bob meet in person, and want to verify each other's keys. 2. Bob tells his device to display a QR code. Bob's device displays a - byte-encoded QR code using UTF-8 of the string `/verify - `. (This format matches the - `/verify` command in Riot.) + QR code that encodes the URL + `https://matrix.to/#/?device=&action=verify&pubkey=` + (when `mx:` URLs are specced, this will be used instead). 3. Alice scans the QR code. 4. Alice's device ensures that the user ID in the QR code is the same as the expected user ID. This can be done by prompting Alice with the user ID, or @@ -41,7 +45,9 @@ Example flow: device says that things match. 7. Alice's device receives the `m.key.verification.check_own_key` message, checks Bob's signature, and checks that the key is the same as her device - key. Alice's device displays the result of the checks. + key, as well as checking that the rest of the contents match the expected + values. Alice's device displays whether the verification was successful or + not. 8. 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. @@ -55,7 +61,10 @@ Alice's key in turn. message contents: - `device_id`: the ID of the device that Alice is using -- `transaction_id`: a unique identifier for the transaction (is this needed?) +- `transaction_id`: an identifier for the transaction. Must be unique on + Alice's device. + +FIXME: Alice's device should be allowed to expire verification requests. #### `m.key.verification.check_own_key` @@ -71,10 +80,10 @@ message contents: Tradeoffs/Alternatives ---------------------- -The exact format for the QR code is not nailed down. Another possibility is -that it could be a URL, so that a user can scan the code in any QR code -scanner, and have it automatically open the user's Matrix client to begin the -verification. +Other methods of verifying keys, which do not require scanning QR codes, are +needed for devices that are unable to scan QR codes. One such method is +[MSC1267](https://github.com/matrix-org/matrix-doc/issues/1267). These methods +are not exclusive to each other. Security Considerations ----------------------- From 517754badaeb5da61e79ca20c14d7063fb6bcec3 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 8 Jan 2019 16:05:55 -0500 Subject: [PATCH 05/26] use common key verification message types as per MSC1717 --- proposals/1543-qr_code_key_verification.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 148728b9..c97861c7 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -35,7 +35,7 @@ Example flow: expected user ID. This can be done by prompting Alice with the user ID, or can be done automatically if the device already knows what user ID to expect. At this point, Alice's device has now verified Bob's key. -5. Alice's device sends a `m.key.verification.reciprocate` message (see below) +5. Alice's device sends a `m.key.verification.start` message (see below) as a to-device message to Bob's device (using the user ID and device ID from the QR code.) 6. Bob's device fetches Alice's public key, signs it, and sends it to Alice's @@ -53,19 +53,18 @@ Example flow: ### Message types -#### `m.key.verification.reciprocate` +#### `m.key.verification.start` Tells Bob's device that Alice has verified his key, and requests that he verify Alice's key in turn. message contents: -- `device_id`: the ID of the device that Alice is using +- `method`: the verification method to use. Must be `m.reciprocate.v1`. +- `from_device`: the ID of the device that Alice is using - `transaction_id`: an identifier for the transaction. Must be unique on Alice's device. -FIXME: Alice's device should be allowed to expire verification requests. - #### `m.key.verification.check_own_key` Tells Alice's device what Bob's device thinks her key is. From ba397793756fa462728e596c8a6aacaea2795c96 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 8 Jan 2019 16:06:53 -0500 Subject: [PATCH 06/26] add a conclusion --- proposals/1543-qr_code_key_verification.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index c97861c7..153db9df 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -111,3 +111,6 @@ Other Issues Conclusion ---------- + +This proposal presents a method for bi-directional key verification by scanning +a QR code and a very simplified out-of-band verification. From 3b0073a9d1d041cf49cf6234e3532fa5a8cf01bf Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 8 Jan 2019 16:07:22 -0500 Subject: [PATCH 07/26] allow for multiple keys to be verified, for cross-signing --- proposals/1543-qr_code_key_verification.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 153db9df..0c1fed14 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -28,8 +28,8 @@ Example flow: 1. Alice and Bob meet in person, and want to verify each other's keys. 2. Bob tells his device to display a QR code. Bob's device displays a QR code that encodes the URL - `https://matrix.to/#/?device=&action=verify&pubkey=` - (when `mx:` URLs are specced, this will be used instead). + `https://matrix.to/#/?device=action=verify&key_=...` + (when `matrix:` URLs are specced, this will be used instead). 3. Alice scans the QR code. 4. Alice's device ensures that the user ID in the QR code is the same as the expected user ID. This can be done by prompting Alice with the user ID, or @@ -64,6 +64,7 @@ message contents: - `from_device`: the ID of the device that Alice is using - `transaction_id`: an identifier for the transaction. Must be unique on Alice's device. +- `keys_ids`: array of key IDs to verify. #### `m.key.verification.check_own_key` @@ -71,10 +72,10 @@ Tells Alice's device what Bob's device thinks her key is. message contents: -- `key`: The key that Bob's device has for Alice's device -- `transaction_id`: the transaction ID from the - `m.key.verification.reciprocate` message -- `signatures`: signature of the key and transaction ID, signed using Bob's key +- `keys`: A map of key IDs to the key that Bob's device has +- `transaction_id`: the transaction ID from the `m.key.verification.start` + message +- `signatures`: signature of the keys and transaction ID, signed using Bob's key Tradeoffs/Alternatives ---------------------- From 38689a8215d173b9a77e03739ceb93d461c2f87f Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 8 Jan 2019 17:44:01 -0500 Subject: [PATCH 08/26] add information about interacting with key requests and define cancellation codes --- proposals/1543-qr_code_key_verification.md | 73 ++++++++++++++++++---- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 0c1fed14..278b23e8 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -23,21 +23,19 @@ However, Bob's device can now send to Alice's device what it thinks is her key from his device), and Alice's device can do the verification on behalf of Bob and display the result. -Example flow: +Example flow 1: 1. Alice and Bob meet in person, and want to verify each other's keys. 2. Bob tells his device to display a QR code. Bob's device displays a - QR code that encodes the URL - `https://matrix.to/#/?device=action=verify&key_=...` - (when `matrix:` URLs are specced, this will be used instead). + QR code as specified below. 3. Alice scans the QR code. 4. Alice's device ensures that the user ID in the QR code is the same as the expected user ID. This can be done by prompting Alice with the user ID, or can be done automatically if the device already knows what user ID to expect. At this point, Alice's device has now verified Bob's key. -5. Alice's device sends a `m.key.verification.start` message (see below) - as a to-device message to Bob's device (using the user ID and device ID from - the QR code.) +5. Alice's device sends a `m.key.verification.start` message with `method` set + to `m.reciprocate.v1` as a to-device message to Bob's device (using the user + ID and device ID from the QR code.) 6. Bob's device fetches Alice's public key, signs it, and sends it to Alice's device in a `m.key.verification.check_own_key` to-device message (see below). Bob's device displays a message saying that Alice wants him to @@ -51,20 +49,60 @@ Example flow: 8. 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. +Example flow 2: + +1. Alice and Bob meet in person, and want to verify each other's keys. +2. Alice requests a key verification through her device by sending an + `m.key.verification.request` message (see MSC1717). +3. Bob responds by sending an `m.key.verification.start` message with `method` + set to `m.qr_code.scan.v1` and `next_method` set to `m.reciprocate.v1`. +4. Bob's device displays a QR code as specified below. +5. Alice scans the QR code. +6. Alice's device ensures that the user ID in the QR code is the same as the + expected user ID (which it knows because it is the recipient of her + `m.key.verification.request` message). At this point, Alice's device has + now verified Bob's key. +7. Alice's device sends a `m.key.verification.start` message with `method` set + to `m.reciprocate.v1` to Bob's device. +8. Bob's device fetches Alice's public key, signs it, and sends it to Alice's + device in a `m.key.verification.check_own_key` to-device message (see + below). Bob's device displays a message saying that Alice wants him to + verify her key, and presents a button for him to press /after/ Alice's + device says that things match. +9. Alice's device receives the `m.key.verification.check_own_key` message, + checks Bob's signature, and checks that the key is the same as her device + key, as well as checking that the rest of the contents match the expected + values. Alice's device displays whether the verification was successful or + not. +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. + +### QR code format + +The QR codes to be displayed and scanned using this format will encode URLs of +the form: +`https://matrix.to/#/?device=&action=verify&key_=...` +(when `matrix:` URLs are specced, this will be used instead). + ### Message types #### `m.key.verification.start` -Tells Bob's device that Alice has verified his key, and requests that he verify -Alice's key in turn. +Begins a key verification process. message contents: -- `method`: the verification method to use. Must be `m.reciprocate.v1`. +- `method`: the verification method to use. For this method, this must be one of: + - `m.qr_code.show.v1` to request that the other device show a QR code that + can be scanned + - `m.qr_code.scan.v1` to request that the other device scan a QR code + - `m.reciprocate.v1` to tell the other device that its key has been verified, + and to request that it verify this device's key in turn - `from_device`: the ID of the device that Alice is using - `transaction_id`: an identifier for the transaction. Must be unique on Alice's device. -- `keys_ids`: array of key IDs to verify. +- `next_method` (only if `method` is `m.qr_code.show.v1` or `m.qr_code.scan.v1`) +- `keys_ids`: (only if `method` is `m.reciprocate.v1`) array of key IDs to verify. #### `m.key.verification.check_own_key` @@ -75,7 +113,18 @@ message contents: - `keys`: A map of key IDs to the key that Bob's device has - `transaction_id`: the transaction ID from the `m.key.verification.start` message -- `signatures`: signature of the keys and transaction ID, signed using Bob's key +- `signatures`: signature of the keys and transaction ID, signed using Bob's + key + +### Cancellation + +In addition to the cancellation codes specified in MSC1717, the following +cancellation codes may be used: + +- `m.qr_code.invalid`: The QR code is invalid (e.g. it is not a URL of the + required form) +- `m.invalid_signature`: The signature of the + `m.key.verification.check_own_key` message was incorrect. Tradeoffs/Alternatives ---------------------- From 10b6fd6c8e5ea80b3bebc06324ef7ed1414890e0 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 18 Sep 2019 19:05:05 -0400 Subject: [PATCH 09/26] add more crypto magic, clarify things, add examples --- proposals/1543-qr_code_key_verification.md | 235 +++++++++++++-------- 1 file changed, 145 insertions(+), 90 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 278b23e8..c9b1d8d6 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -17,58 +17,41 @@ Proposal When Alice and Bob meet in person to verify keys, Alice will scan a QR code generated by Bob's device. This easily allows Alice to verify Bob's key, but -does not give Bob any information about Alice's key in order to verify it. -However, Bob's device can now send to Alice's device what it thinks is her key -(signed by his key, so that Alice can verify that the message actually came -from his device), and Alice's device can do the verification on behalf of Bob -and display the result. +does not give Bob any information about Alice's key in order to verify it. We +can add a secret key to the QR code, which Alice's device can use to MAC her +key to send to Bob. In order to ensure that an attacker, who manages to also +scan the QR code, is unable to send a false device key to Bob, Bob's device now +sends to Alice's device what it thinks is her key, signed by his key. Since +Alice has verified Bob's key via the QR code, Alice's device verifies that the +key send by Bob matches her key, and that his signature is valid. -Example flow 1: - -1. Alice and Bob meet in person, and want to verify each other's keys. -2. Bob tells his device to display a QR code. Bob's device displays a - QR code as specified below. -3. Alice scans the QR code. -4. Alice's device ensures that the user ID in the QR code is the same as the - expected user ID. This can be done by prompting Alice with the user ID, or - can be done automatically if the device already knows what user ID to - expect. At this point, Alice's device has now verified Bob's key. -5. Alice's device sends a `m.key.verification.start` message with `method` set - to `m.reciprocate.v1` as a to-device message to Bob's device (using the user - ID and device ID from the QR code.) -6. Bob's device fetches Alice's public key, signs it, and sends it to Alice's - device in a `m.key.verification.check_own_key` to-device message (see - below). Bob's device displays a message saying that Alice wants him to - verify her key, and presents a button for him to press /after/ Alice's - device says that things match. -7. Alice's device receives the `m.key.verification.check_own_key` message, - checks Bob's signature, and checks that the key is the same as her device - key, as well as checking that the rest of the contents match the expected - values. Alice's device displays whether the verification was successful or - not. -8. 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. - -Example flow 2: +Example flow: 1. Alice and Bob meet in person, and want to verify each other's keys. 2. Alice requests a key verification through her device by sending an - `m.key.verification.request` message (see MSC1717). -3. Bob responds by sending an `m.key.verification.start` message with `method` - set to `m.qr_code.scan.v1` and `next_method` set to `m.reciprocate.v1`. -4. Bob's device displays a QR code as specified below. -5. Alice scans the QR code. + `m.key.verification.request` message (see + [MSC2241](https://github.com/matrix-org/matrix-doc/pull/2241)), with + `m.qr_code.show.v1`, `m.qr_code.scan.v1`, and `m.reciprocate.v1` listed in + `methods`. +3. Alice's client displays a QR code that Bob is able to scan, and an option to + scan Bob's QR code. +4. Bob's client prompts Bob to verify Alice's key. The prompt includes a QR + code that Alice can scan (if the `m.key.verification.request` message listed + `m.qr_code.scan.v1`), and an option to scan Alice's QR code (if the + `m.key.verification.request` message listed `m.qr_code.show.v1`). +5. Alice scans Bob's QR code. 6. Alice's device ensures that the user ID in the QR code is the same as the expected user ID (which it knows because it is the recipient of her `m.key.verification.request` message). At this point, Alice's device has now verified Bob's key. 7. Alice's device sends a `m.key.verification.start` message with `method` set - to `m.reciprocate.v1` to Bob's device. -8. Bob's device fetches Alice's public key, signs it, and sends it to Alice's - device in a `m.key.verification.check_own_key` to-device message (see - below). Bob's device displays a message saying that Alice wants him to - verify her key, and presents a button for him to press /after/ Alice's - device says that things match. + to `m.reciprocate.v1` to Bob (see below). +8. Bob's device fetches Alice's public key, checks it against what was received + in the `m.key.verification.start` message, signs it, and sends it to Alice + in a `m.key.verification.check_own_key` message (see below). Bob's device + displays a message saying that Alice wants him to verify her key, and + presents a button for him to press /after/ Alice's device says that things + match. 9. Alice's device receives the `m.key.verification.check_own_key` message, checks Bob's signature, and checks that the key is the same as her device key, as well as checking that the rest of the contents match the expected @@ -77,32 +60,88 @@ Example flow 2: 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. +### Verification methods + +This proposal defines three verification methods that can be used in +`m.key.verification.request` messages (see +[MSC2241](https://github.com/matrix-org/matrix-doc/pull/2241)). + +- `m.qr_code.show.v1`: means that the sender of the + `m.key.verification.request` message can show a QR code that the recipient + can scan. If the recipient can scan the QR code, it should allow the user to + do so. This method is never sent as part of a `m.key.verification.start` + message. +- `m.qr_code.scan.v1`: means that the sender of the + `m.key.verification.request` message can scan a QR code displayed by the + recipient. If the recipient can display a QR code, it should allow the user + to display it so that the sender can scan it. This method is never sent as + part of a `m.key.verification.start` message. +- `m.reciprocate.v1`: means that the sender can participate in a reciprocal + verification, either as initiator or responder, as described in the [Message + types](#message-types) section below. + ### QR code format The QR codes to be displayed and scanned using this format will encode URLs of the form: -`https://matrix.to/#/?device=&action=verify&key_=...` +`https://matrix.to/#/?request=&action=verify&key_=...&verification_algorithms=&verification_key=` (when `matrix:` URLs are specced, this will be used instead). +The `request`, `verification_algorithm`, and `verification_key` parameters are +only present if this QR code is related to a key verification request event. +`verification_algorithms` is a comma-separated list of hashing algorithms that +can be used for verifying the keys of the user who scanned the QR code; +currently, only `hmac-sha256` is defined, which is HMAC using SHA-256 as the +hash. `verification_key` is a random single-use shared secret, with a length +depending on the `verification_algorithm`; for `hmac-sha256`, it must be at +least 256-bits long (43 characters when base64-encoded). + ### Message types #### `m.key.verification.start` -Begins a key verification process. +Alice's device tells Bob's device that his key is verified, and asks it to +verify her keys. The request is MAC'ed using the verification algorithm and +verification key from the QR code. message contents: -- `method`: the verification method to use. For this method, this must be one of: - - `m.qr_code.show.v1` to request that the other device show a QR code that - can be scanned - - `m.qr_code.scan.v1` to request that the other device scan a QR code - - `m.reciprocate.v1` to tell the other device that its key has been verified, - and to request that it verify this device's key in turn -- `from_device`: the ID of the device that Alice is using -- `transaction_id`: an identifier for the transaction. Must be unique on - Alice's device. -- `next_method` (only if `method` is `m.qr_code.show.v1` or `m.qr_code.scan.v1`) -- `keys_ids`: (only if `method` is `m.reciprocate.v1`) array of key IDs to verify. +- `method`: `m.reciprocate.v1` +- `m.relates_to`: as per [key verification framework](https://github.com/matrix-org/matrix-doc/pull/2241) +- `keys`: a map of key ID to key in unpadded base64 +- `signatures`: MAC of the message contents, formed as in [Signing + JSON](https://matrix.org/docs/spec/appendices#signing-json), with the chosen + verification algorithm as the signing algorithm. The key ID depends on the + verification algorithm; for `hmac-sha256`, it is the SHA-256 hash of the + verification key. The MAC is calculated similarly to Signed JSON: + 1. The `unsigned` and `signatures` keys are removed, and the contents are + encoded as canonical JSON. + 2. The encoded object is then MAC'ed using the verification key according to the + selected algorithm, and the MAC is encoded in unpadded base64. + +Example: + +```json +{ + "method": "m.reciprocate.v1", + "m.relates_to": { + "rel_type": "m.reference", + "event_id": "!event_id_of_verification_request" + }, + "keys": { + "ed25519:ODRMFSSXPK": "5YaK7EA3HvtPWr+B0jXFXJ9UidyJ4I9PWpT03xCCJrY", + }, + "signatures": { + "@alice:example.com": { + "hmac-sha256:key+id": "mac+of+message+in+unpadded+base64" + } + } +} +``` + +Note that this message could be sent by either Alice or Bob. That is, it can +be sent by either the sender or the recipient of the +`m.key.verification.request` message. #### `m.key.verification.check_own_key` @@ -110,16 +149,35 @@ Tells Alice's device what Bob's device thinks her key is. message contents: -- `keys`: A map of key IDs to the key that Bob's device has -- `transaction_id`: the transaction ID from the `m.key.verification.start` - message -- `signatures`: signature of the keys and transaction ID, signed using Bob's - key +- `m.relates_to`: as per [key verification framework](https://github.com/matrix-org/matrix-doc/pull/2241) +- `keys`: A map of key IDs to the key that Bob's device has. Must be the same + as the `keys` property from the `m.key.verification.start` event. +- `signatures`: signature of the mesage contents, signed using Bob's key + +Example: + +```json +{ + "m.relates_to": { + "rel_type": "m.reference", + "event_id": "!event_id_of_verification_request" + }, + "keys": { + "ed25519:ODRMFSSXPK": "5YaK7EA3HvtPWr+B0jXFXJ9UidyJ4I9PWpT03xCCJrY", + }, + "signatures": { + "@bob:example.com": { + "ed25519:bobs+key+id": "signature+of+message" + } + } +} +``` ### Cancellation -In addition to the cancellation codes specified in MSC1717, the following -cancellation codes may be used: +In addition to the cancellation codes specified in [the spec for +`m.key.verification.cancel`](https://matrix.org/docs/spec/client_server/r0.5.0#m-key-verification-cancel), +the following cancellation codes may be used: - `m.qr_code.invalid`: The QR code is invalid (e.g. it is not a URL of the required form) @@ -131,36 +189,33 @@ Tradeoffs/Alternatives Other methods of verifying keys, which do not require scanning QR codes, are needed for devices that are unable to scan QR codes. One such method is -[MSC1267](https://github.com/matrix-org/matrix-doc/issues/1267). These methods -are not exclusive to each other. +[MSC1267](https://github.com/matrix-org/matrix-doc/issues/1267). Security Considerations ----------------------- -Step 4 is to ensure that Bob does not present a QR code claiming to be Carol's -key. Without this check, Bob will be able to trick Alice into verifying a key -under his control, and evesdropping on Alice's communications with Carol. +Step 6 in the example flow is to ensure that Bob does not present a QR code +claiming to be Carol's key. Without this check, Bob will be able to trick +Alice into verifying a key under his control, and evesdropping on Alice's +communications with Carol. The security of verifying Alice's key depends on Bob not hitting the "Verified" -button until after Alice's device indicates success. However, users have a -tendency to click on buttons without reading what the screen says. This might -be addressed by: - -- allowing Bob to easily undo the verification if Alice's device subsequently - gives an error -- posing Bob a dummy question that he cannot answer until after Alice's device - displays the check results. For example: "Does Alice's device show a cat or - a dog?" Alice's device will show one or the other after it has checked the - key received from Bob, forcing Bob to wait for the check to complete. - (Whether a cat or a dog is displayed could be keyed to, for example, a bit in - the transaction ID.) -- (possibly other ways) - -Other Issues ------------- - -Conclusion ----------- - -This proposal presents a method for bi-directional key verification by scanning -a QR code and a very simplified out-of-band verification. +button (step 10 in the example flow) until after Alice's device indicates +success. However, users have a tendency to click on buttons without reading +what the screen says. This is partially mitigated by having Alice's device +send her keys MAC'ed with a shared secret. But this relies on the shared +secret actually being secret, which may not be the case if an attacker is able +to view the QR code, which limits the possible attackers to people who are +physically present when Alice and Bob verify. This can also be addressed by +allowing Bob to easily undo the verification if Alice's device subsequently +gives an error. + +One potential attack involves an attacker preventing the +`m.key.verification.check_own_key` message from reaching Alice, and hoping that +Bob blindly clicks on the "Verify" button without waiting for Alice's device to +check that the key is correct. In this case, Alice's device will not display +an error message saying that the key is incorrect, the users may assume that the +absence of an error message means that everything is OK. To prevent this, +Alice's device should display an error message if it does not receive a +`m.key.verification.check_own_key` message as a response to its +`m.key.verification.start` message after a reasonable amount of time. From 332b5605c1eec0e22277dce252119b3f3d0e920b Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 19 Sep 2019 16:18:46 -0400 Subject: [PATCH 10/26] simplify protocol by embedding Alice's key in Bob's QR code --- proposals/1543-qr_code_key_verification.md | 177 ++++++++------------- 1 file changed, 65 insertions(+), 112 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index c9b1d8d6..b8458961 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -16,14 +16,10 @@ Proposal -------- When Alice and Bob meet in person to verify keys, Alice will scan a QR code -generated by Bob's device. This easily allows Alice to verify Bob's key, but -does not give Bob any information about Alice's key in order to verify it. We -can add a secret key to the QR code, which Alice's device can use to MAC her -key to send to Bob. In order to ensure that an attacker, who manages to also -scan the QR code, is unable to send a false device key to Bob, Bob's device now -sends to Alice's device what it thinks is her key, signed by his key. Since -Alice has verified Bob's key via the QR code, Alice's device verifies that the -key send by Bob matches her key, and that his signature is valid. +generated by Bob's device. The QR code will encode both Bob's key as well as what Bob +thinks Alice's key is. When Alice scans the QR code, she will ensure that the +keys match what is expected, in which case, she relays this information to Bob, +who can then tell his device that the keys match. Example flow: @@ -40,25 +36,26 @@ Example flow: `m.qr_code.scan.v1`), and an option to scan Alice's QR code (if the `m.key.verification.request` message listed `m.qr_code.show.v1`). 5. Alice scans Bob's QR code. -6. Alice's device ensures that the user ID in the QR code is the same as the - expected user ID (which it knows because it is the recipient of her - `m.key.verification.request` message). At this point, Alice's device has - now verified Bob's key. +6. Alice's device ensures that: + - the user ID in the QR code is the same as the expected user ID (which it + knows because it is the recipient of her `m.key.verification.request` + message), + - Bob's keys encoded in the QR code match the keys that she already has for + Bob, and + - Alice's cross-signing key matches the cross-signing key encoded in the QR + code. + + If any of these checks fail, Alice's device displays an error message. + Otherwise, at this point, Alice's device has now verified Bob's key, and her + device will display a message saying that all is well. 7. Alice's device sends a `m.key.verification.start` message with `method` set to `m.reciprocate.v1` to Bob (see below). -8. Bob's device fetches Alice's public key, checks it against what was received - in the `m.key.verification.start` message, signs it, and sends it to Alice - in a `m.key.verification.check_own_key` message (see below). Bob's device - displays a message saying that Alice wants him to verify her key, and - presents a button for him to press /after/ Alice's device says that things - match. -9. Alice's device receives the `m.key.verification.check_own_key` message, - checks Bob's signature, and checks that the key is the same as her device - key, as well as checking that the rest of the contents match the expected - values. Alice's device displays whether the verification was successful or - not. -10. Bob sees Alice's device confirm that the key matches, and presses the button +8. Upon receipt of the `m.key.verification.start` message, Bob's device + presents a button for him to press /after/ he has checked that Alice's + device says that things match. +9. 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. +10. Both devices send an `m.key.verification.done` message. ### Verification methods @@ -84,40 +81,38 @@ This proposal defines three verification methods that can be used in The QR codes to be displayed and scanned using this format will encode URLs of the form: -`https://matrix.to/#/?request=&action=verify&key_=...&verification_algorithms=&verification_key=` +`https://matrix.to/#/?request=&action=verify&key_=...&verification_algorithms=&verification_key=&other_user_key=` (when `matrix:` URLs are specced, this will be used instead). -The `request`, `verification_algorithm`, and `verification_key` parameters are -only present if this QR code is related to a key verification request event. -`verification_algorithms` is a comma-separated list of hashing algorithms that -can be used for verifying the keys of the user who scanned the QR code; -currently, only `hmac-sha256` is defined, which is HMAC using SHA-256 as the -hash. `verification_key` is a random single-use shared secret, with a length -depending on the `verification_algorithm`; for `hmac-sha256`, it must be at -least 256-bits long (43 characters when base64-encoded). +- `request`: is the event ID of the associated verification request event. +- `key_`: each key that the user wants verified will have an entry of + this form, where the value is the key in unpadded base64. The QR code should + contain at least the user's master cross-signing key. +- `secret`: is a random single-use shared secret in unpadded base64. It must be + at least 256-bits long (43 characters when base64-encoded). +- `other_user_key`: the other user's master cross-signing key, in unpadded + base64. In other words, if Alice is displaying the QR code, this would be + the copy of Bob's master cross-signing key that Alice has. + +The QR codes to be displayed and scanned, which are not a part of an in-person +verification (for example, for printing on business cards), will encode URLs of +the form: +`https://matrix.to/#/?&action=verify&key_=...` +In this case, only the user scanning the QR code will verify the key of the +user whose QR code was scanned; bi-directional verification is not possible. ### Message types #### `m.key.verification.start` -Alice's device tells Bob's device that his key is verified, and asks it to -verify her keys. The request is MAC'ed using the verification algorithm and -verification key from the QR code. +Alice's device tells Bob's device that the keys are verified. The request is +MAC'ed using the verification algorithm and verification key from the QR code. message contents: - `method`: `m.reciprocate.v1` - `m.relates_to`: as per [key verification framework](https://github.com/matrix-org/matrix-doc/pull/2241) -- `keys`: a map of key ID to key in unpadded base64 -- `signatures`: MAC of the message contents, formed as in [Signing - JSON](https://matrix.org/docs/spec/appendices#signing-json), with the chosen - verification algorithm as the signing algorithm. The key ID depends on the - verification algorithm; for `hmac-sha256`, it is the SHA-256 hash of the - verification key. The MAC is calculated similarly to Signed JSON: - 1. The `unsigned` and `signatures` keys are removed, and the contents are - encoded as canonical JSON. - 2. The encoded object is then MAC'ed using the verification key according to the - selected algorithm, and the MAC is encoded in unpadded base64. +- `secret`: the shared secret from the QR code Example: @@ -128,50 +123,13 @@ Example: "rel_type": "m.reference", "event_id": "!event_id_of_verification_request" }, - "keys": { - "ed25519:ODRMFSSXPK": "5YaK7EA3HvtPWr+B0jXFXJ9UidyJ4I9PWpT03xCCJrY", - }, - "signatures": { - "@alice:example.com": { - "hmac-sha256:key+id": "mac+of+message+in+unpadded+base64" - } - } + "secret": "shared+secret" } ``` -Note that this message could be sent by either Alice or Bob. That is, it can -be sent by either the sender or the recipient of the -`m.key.verification.request` message. - -#### `m.key.verification.check_own_key` - -Tells Alice's device what Bob's device thinks her key is. - -message contents: - -- `m.relates_to`: as per [key verification framework](https://github.com/matrix-org/matrix-doc/pull/2241) -- `keys`: A map of key IDs to the key that Bob's device has. Must be the same - as the `keys` property from the `m.key.verification.start` event. -- `signatures`: signature of the mesage contents, signed using Bob's key - -Example: - -```json -{ - "m.relates_to": { - "rel_type": "m.reference", - "event_id": "!event_id_of_verification_request" - }, - "keys": { - "ed25519:ODRMFSSXPK": "5YaK7EA3HvtPWr+B0jXFXJ9UidyJ4I9PWpT03xCCJrY", - }, - "signatures": { - "@bob:example.com": { - "ed25519:bobs+key+id": "signature+of+message" - } - } -} -``` +Note that this message could be sent by either the sender or the recipient of +the `m.key.verification.request` message, depending on which user scanned the +QR code. ### Cancellation @@ -181,8 +139,12 @@ the following cancellation codes may be used: - `m.qr_code.invalid`: The QR code is invalid (e.g. it is not a URL of the required form) -- `m.invalid_signature`: The signature of the - `m.key.verification.check_own_key` message was incorrect. + +The verification can also be cancelled with the error codes: + +- `m.key_mismatch`: if the QR code has keys that do not match the expected + value +- `m.user_mismatch`: if the QR code is for a different user from what was expected Tradeoffs/Alternatives ---------------------- @@ -194,28 +156,19 @@ needed for devices that are unable to scan QR codes. One such method is Security Considerations ----------------------- -Step 6 in the example flow is to ensure that Bob does not present a QR code -claiming to be Carol's key. Without this check, Bob will be able to trick -Alice into verifying a key under his control, and evesdropping on Alice's -communications with Carol. +The first check in Step 6 in the example flow is to ensure that Bob does not +present a QR code claiming to be Carol's key. Without this check, Bob will be +able to trick Alice into verifying a key under his control, and evesdropping on +Alice's communications with Carol. The security of verifying Alice's key depends on Bob not hitting the "Verified" -button (step 10 in the example flow) until after Alice's device indicates -success. However, users have a tendency to click on buttons without reading -what the screen says. This is partially mitigated by having Alice's device -send her keys MAC'ed with a shared secret. But this relies on the shared -secret actually being secret, which may not be the case if an attacker is able -to view the QR code, which limits the possible attackers to people who are -physically present when Alice and Bob verify. This can also be addressed by -allowing Bob to easily undo the verification if Alice's device subsequently -gives an error. - -One potential attack involves an attacker preventing the -`m.key.verification.check_own_key` message from reaching Alice, and hoping that -Bob blindly clicks on the "Verify" button without waiting for Alice's device to -check that the key is correct. In this case, Alice's device will not display -an error message saying that the key is incorrect, the users may assume that the -absence of an error message means that everything is OK. To prevent this, -Alice's device should display an error message if it does not receive a -`m.key.verification.check_own_key` message as a response to its -`m.key.verification.start` message after a reasonable amount of time. +button (step 9 in the example flow) until after Alice's device indicates +success or failure. Users have a tendency to click on buttons without reading +what the screen says, but this is partially mitigated by the fact that it is +unlikely that Bob will be interacting with the device while Alice is scanning +and Alice's device will display the verification results immediately upon +scanning. Also, Bob's device will not display the button until it receives the +`m.key.verification.start` message that contains the shared secret from the QR +code, which means that an attacker would need to be physically present while +Alice and Bob verify. This issue can also be addressed by allowing Bob to +easily undo the verification if Alice's device displays an error. From 4f83bd3e36d2452a4d23fdaa581bab1da7b9617e Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 22 Jan 2020 11:55:22 -0500 Subject: [PATCH 11/26] Update proposals/1543-qr_code_key_verification.md Co-Authored-By: Travis Ralston --- proposals/1543-qr_code_key_verification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index b8458961..cd2b19f9 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -97,7 +97,7 @@ the form: The QR codes to be displayed and scanned, which are not a part of an in-person verification (for example, for printing on business cards), will encode URLs of the form: -`https://matrix.to/#/?&action=verify&key_=...` +`https://matrix.to/#/?action=verify&key_=...` In this case, only the user scanning the QR code will verify the key of the user whose QR code was scanned; bi-directional verification is not possible. From 379bb79b00946a6ac378fafc65cf1b8ccf8d4a5a Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 22 Jan 2020 11:59:35 -0500 Subject: [PATCH 12/26] Update proposals/1543-qr_code_key_verification.md --- proposals/1543-qr_code_key_verification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index cd2b19f9..142e793e 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -81,7 +81,7 @@ This proposal defines three verification methods that can be used in The QR codes to be displayed and scanned using this format will encode URLs of the form: -`https://matrix.to/#/?request=&action=verify&key_=...&verification_algorithms=&verification_key=&other_user_key=` +`https://matrix.to/#/?request=&action=verify&key_=...&secret=&other_user_key=` (when `matrix:` URLs are specced, this will be used instead). - `request`: is the event ID of the associated verification request event. From a8c7fda1872c54a3d9ef2c56de8b152fee53d2ba Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 24 Jan 2020 12:50:51 -0500 Subject: [PATCH 13/26] add some clarifications --- proposals/1543-qr_code_key_verification.md | 26 +++++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 142e793e..cfce549d 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -34,7 +34,13 @@ Example flow: 4. Bob's client prompts Bob to verify Alice's key. The prompt includes a QR code that Alice can scan (if the `m.key.verification.request` message listed `m.qr_code.scan.v1`), and an option to scan Alice's QR code (if the - `m.key.verification.request` message listed `m.qr_code.show.v1`). + `m.key.verification.request` message listed `m.qr_code.show.v1`). The QR + code encodes: + - Bob's Matrix user ID, + - Bob's keys that he wants Alice to verify (should contain at least his + master cross-signing key), + - what Bob thinks Alice's master cross-signing key is, + - a random shared secret. 5. Alice scans Bob's QR code. 6. Alice's device ensures that: - the user ID in the QR code is the same as the expected user ID (which it @@ -45,14 +51,22 @@ Example flow: - Alice's cross-signing key matches the cross-signing key encoded in the QR code. - If any of these checks fail, Alice's device displays an error message. + If any of these checks fail, 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 her device will display a message saying that all is well. 7. Alice's device sends a `m.key.verification.start` message with `method` set - to `m.reciprocate.v1` to Bob (see below). -8. Upon receipt of the `m.key.verification.start` message, Bob's device - presents a button for him to press /after/ he has checked that Alice's - device says that things match. + to `m.reciprocate.v1` to Bob (see below). The message includes the shared + secret from the QR code. +8. Upon receipt of the `m.key.verification.start` message, Bob's device ensures + that the shared secret matches, and if so, presents a button for him to press + /after/ he has checked that Alice's device says that things match, and a + button for him to press if Alice's device indicates that the QR code is + invalid or if Alice has not yet scanned. 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.) 9. 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. 10. Both devices send an `m.key.verification.done` message. From be9c37e95986b8a986a72b041973b0e9f4de5730 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 27 Jan 2020 18:27:06 -0500 Subject: [PATCH 14/26] more clarifications, add comparison with SAS --- proposals/1543-qr_code_key_verification.md | 52 +++++++++++++++------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index cfce549d..d7775221 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -55,21 +55,32 @@ Example flow: 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 her - device will display a message saying that all is well. -7. Alice's device sends a `m.key.verification.start` message with `method` set + 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 all is well. 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 a `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. -8. Upon receipt of the `m.key.verification.start` message, Bob's device ensures - that the shared secret matches, and if so, presents a button for him to press - /after/ he has checked that Alice's device says that things match, and a - button for him to press if Alice's device indicates that the QR code is - invalid or if Alice has not yet scanned. 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.) -9. 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. -10. Both devices send an `m.key.verification.done` message. + 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 in the actual verification.) +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. +11. Both devices send an `m.key.verification.done` message. ### Verification methods @@ -119,8 +130,7 @@ user whose QR code was scanned; bi-directional verification is not possible. #### `m.key.verification.start` -Alice's device tells Bob's device that the keys are verified. The request is -MAC'ed using the verification algorithm and verification key from the QR code. +Alice's device tells Bob's device that the QR code has been scanned. message contents: @@ -167,6 +177,14 @@ Other methods of verifying keys, which do not require scanning QR codes, are needed for devices that are unable to scan QR codes. One such method is [MSC1267](https://github.com/matrix-org/matrix-doc/issues/1267). +Rather than embedding the keys in the QR codes directly, the two clients could +perform an exchange similar to +[MSC1267](https://github.com/matrix-org/matrix-doc/issues/1267), and encoding +the Short Authentication String code in the QR code. However, this means that +the clients must exchange several messages before they can verify each other, +which would delay showing the QR codes. This proposal is also simpler to +implement. + Security Considerations ----------------------- @@ -176,7 +194,7 @@ able to trick Alice into verifying a key under his control, and evesdropping on Alice's communications with Carol. The security of verifying Alice's key depends on Bob not hitting the "Verified" -button (step 9 in the example flow) until after Alice's device indicates +button (step 10 in the example flow) until after Alice's device indicates success or failure. Users have a tendency to click on buttons without reading what the screen says, but this is partially mitigated by the fact that it is unlikely that Bob will be interacting with the device while Alice is scanning From 0b4411eadbf07c773facdd3d6778a981b79240d2 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 28 Jan 2020 15:28:49 -0500 Subject: [PATCH 15/26] more words --- proposals/1543-qr_code_key_verification.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index d7775221..25eeced9 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -67,8 +67,10 @@ Example flow: 8. Alice's device sends a `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 in the actual verification.) + 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. @@ -80,8 +82,23 @@ Example flow: 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. +This flow allows Alice to verify Bob's key, and Bob to verify Alice's key. +Alice verifies Bob's key because she can trust the QR code that Bob displays +for her, as this is done over a trusted medium. Bob verifies Alice's key +because Alice can trust the QR code that Bob displays, and Bob can trust Alice +to tell him the result of the verification. + ### Verification methods This proposal defines three verification methods that can be used in From fcfd5d99a187b2bebdfe4ef9697338933118d4c6 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 29 Jan 2020 16:39:32 -0500 Subject: [PATCH 16/26] add examples for self-verification --- proposals/1543-qr_code_key_verification.md | 68 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 25eeced9..392ef028 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -21,7 +21,7 @@ thinks Alice's key is. When Alice scans the QR code, she will ensure that the keys match what is expected, in which case, she relays this information to Bob, who can then tell his device that the keys match. -Example flow: +### Example flow 1. Alice and Bob meet in person, and want to verify each other's keys. 2. Alice requests a key verification through her device by sending an @@ -99,6 +99,64 @@ for her, as this is done over a trusted medium. Bob verifies Alice's key because Alice can trust the QR code that Bob displays, and Bob can trust Alice to tell him the result of the verification. +#### Self-verification + +QR codes can also be used by a user to verify their own devices. These examples +shows Alice verifying two devices, one of them (Osborne2) having cross-signing +already set up, and the other one (Dynabook) having just logged in. + +In the first example, Osborne2 scans Dynabook: + +1. Alice logs into her new Dynabook and wants other users to be able to trust + it via cross-signing, and to trust other devices via cross-signing. +2. Dynabook retrieves Alice's public cross-signing key from the server, and + displays a QR code that encodes: + - Alice's user ID, + - Dynabook's device key, + - what it thinks Alice's master key is, as the `other_user_key` parameter, and + - a random shared secret. + + Note that in this case, the QR code does not include Alice's master key in a + `key_` parameter, since Dynabook does not know whether it is trusted + or not. +3. Osborne2 scans the QR code displayed by Dynabook. At this point, Osborne2 + knows Dynabook's device key and can sign it with the self-signing key and + upload the signature, and can trust Dynabook for sending secrets via SSSS. + It also knows that Dynabook has the correct cross-signing key. +4. Osborne2 tells Alice that the scan was successful, and sends the + `reciprocate` message containing the shared secret. +5. Upon receipt of the `reciprocate` message, Dynabook (after checking the + shared secret) confirms with Alice that she successfully scanned the QR + code. +6. Alice confirms. +7. Dynabook now knows that it can trust Alice's cross-signing keys that it + fetched from the server. + +In the second example, Dynabook scans Osborne2: + +1. Alice logs into her new Dynabook and wants other users to be able to trust + it via cross-signing, and to trust other devices via cross-signing. +2. Osborne2 notices that Dynabook is a new device. Osborne2 fetches Dynabook's + identity key and displays a QR code that encodes: + - Alice's user ID, + - Osborne2's device key (optional), + - what it thinks Dynabook's key is, as `other_device_key`, + - Alice's master key, both as `key_` and `other_user_key` + parameters, and + - a random shared secret. +3. Dynabook scans the QR code shown by Osborne2. At this point, Dynabook knows + Alice's cross-signing key, and so it can trust it to sign other devices. It + also knows that Osborne2 as the correct key for it. +4. Dynabook tells Alice that the scan is successful, and sends the + `reciprocate` message containing the shared secret. +5. Upon receipt of the `reciprocate` message, Osborne2 (after checking the + shared secret) confirms with Alice that she successfully scanned the QR + code. +6. Alice confirms. +7. Osborne2 now knows that it has the correct device key for Dynabook, and can + sign it with the self-signing key and upload the signature. Osborne2 can + also trust Dynabook for sending secrets via SSSS. + ### Verification methods This proposal defines three verification methods that can be used in @@ -129,12 +187,18 @@ the form: - `request`: is the event ID of the associated verification request event. - `key_`: each key that the user wants verified will have an entry of this form, where the value is the key in unpadded base64. The QR code should - contain at least the user's master cross-signing key. + contain at least the user's master cross-signing key. In the case where a + device does not have a cross-signing key (as in the case where a user logs in + to a new device, and is verifying against another device), thin the QR code + should contain at least the device's key. - `secret`: is a random single-use shared secret in unpadded base64. It must be at least 256-bits long (43 characters when base64-encoded). - `other_user_key`: the other user's master cross-signing key, in unpadded base64. In other words, if Alice is displaying the QR code, this would be the copy of Bob's master cross-signing key that Alice has. +- `other_device_key`: the other device's key, in unpadded base64. This is only + needed when a user is verifying their own devices, where the other device has + not yet been signed with the cross-signing key. The QR codes to be displayed and scanned, which are not a part of an in-person verification (for example, for printing on business cards), will encode URLs of From 21ddf8507aae22dbf61311de2d20c95cec1dcfbd Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 29 Jan 2020 17:52:18 -0500 Subject: [PATCH 17/26] make other_user_key optional for one flow of self-verification --- proposals/1543-qr_code_key_verification.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 392ef028..c2e2d9d4 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -141,8 +141,8 @@ In the second example, Dynabook scans Osborne2: - Alice's user ID, - Osborne2's device key (optional), - what it thinks Dynabook's key is, as `other_device_key`, - - Alice's master key, both as `key_` and `other_user_key` - parameters, and + - Alice's master key as a `key_` parameter and (optionally) a `other_user_key` + parameter, and - a random shared secret. 3. Dynabook scans the QR code shown by Osborne2. At this point, Dynabook knows Alice's cross-signing key, and so it can trust it to sign other devices. It From 7f93084242fe4f6e1667c6189e7081297c0eaad4 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 30 Jan 2020 10:34:10 -0500 Subject: [PATCH 18/26] request can be transaction_id --- proposals/1543-qr_code_key_verification.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index c2e2d9d4..84058a62 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -184,7 +184,8 @@ the form: `https://matrix.to/#/?request=&action=verify&key_=...&secret=&other_user_key=` (when `matrix:` URLs are specced, this will be used instead). -- `request`: is the event ID of the associated verification request event. +- `request`: is the event ID or `transaction_id` of the associated verification + request event. - `key_`: each key that the user wants verified will have an entry of this form, where the value is the key in unpadded base64. The QR code should contain at least the user's master cross-signing key. In the case where a From 78b8133142d943c30efeea234f184ba7936fa7fa Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 6 Feb 2020 13:53:33 -0500 Subject: [PATCH 19/26] use binary encoding of keys to reduce size of QR code --- proposals/1543-qr_code_key_verification.md | 119 +++++++++++---------- 1 file changed, 64 insertions(+), 55 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 84058a62..e9362811 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -1,5 +1,5 @@ -Key verification using QR codes -=============================== +Bi-directional Key verification using QR codes +============================================== Problem/Background ------------------ @@ -28,7 +28,7 @@ who can then tell his device that the keys match. `m.key.verification.request` message (see [MSC2241](https://github.com/matrix-org/matrix-doc/pull/2241)), with `m.qr_code.show.v1`, `m.qr_code.scan.v1`, and `m.reciprocate.v1` listed in - `methods`. + `methods`, and Bob responds with a `m.key.verification.ready` message. 3. Alice's client displays a QR code that Bob is able to scan, and an option to scan Bob's QR code. 4. Bob's client prompts Bob to verify Alice's key. The prompt includes a QR @@ -36,17 +36,12 @@ who can then tell his device that the keys match. `m.qr_code.scan.v1`), and an option to scan Alice's QR code (if the `m.key.verification.request` message listed `m.qr_code.show.v1`). The QR code encodes: - - Bob's Matrix user ID, - - Bob's keys that he wants Alice to verify (should contain at least his - master cross-signing key), - - what Bob thinks Alice's master cross-signing key is, + - Bob's master cross-signing public key, + - what Bob thinks Alice's master cross-signing public key is, - a random shared secret. 5. Alice scans Bob's QR code. 6. Alice's device ensures that: - - the user ID in the QR code is the same as the expected user ID (which it - knows because it is the recipient of her `m.key.verification.request` - message), - - Bob's keys encoded in the QR code match the keys that she already has for + - Bob's key encoded in the QR code match the key that she already has for Bob, and - Alice's cross-signing key matches the cross-signing key encoded in the QR code. @@ -111,9 +106,8 @@ In the first example, Osborne2 scans Dynabook: it via cross-signing, and to trust other devices via cross-signing. 2. Dynabook retrieves Alice's public cross-signing key from the server, and displays a QR code that encodes: - - Alice's user ID, - Dynabook's device key, - - what it thinks Alice's master key is, as the `other_user_key` parameter, and + - what it thinks Alice's master key is, and - a random shared secret. Note that in this case, the QR code does not include Alice's master key in a @@ -138,11 +132,8 @@ In the second example, Dynabook scans Osborne2: it via cross-signing, and to trust other devices via cross-signing. 2. Osborne2 notices that Dynabook is a new device. Osborne2 fetches Dynabook's identity key and displays a QR code that encodes: - - Alice's user ID, - - Osborne2's device key (optional), - - what it thinks Dynabook's key is, as `other_device_key`, - - Alice's master key as a `key_` parameter and (optionally) a `other_user_key` - parameter, and + - what it thinks Dynabook's key is, + - Alice's master key, and - a random shared secret. 3. Dynabook scans the QR code shown by Osborne2. At this point, Dynabook knows Alice's cross-signing key, and so it can trust it to sign other devices. It @@ -163,12 +154,12 @@ This proposal defines three verification methods that can be used in `m.key.verification.request` messages (see [MSC2241](https://github.com/matrix-org/matrix-doc/pull/2241)). -- `m.qr_code.show.v1`: means that the sender of the +- `m.qr_code.show.v2`: means that the sender of the `m.key.verification.request` message can show a QR code that the recipient can scan. If the recipient can scan the QR code, it should allow the user to do so. This method is never sent as part of a `m.key.verification.start` message. -- `m.qr_code.scan.v1`: means that the sender of the +- `m.qr_code.scan.v2`: means that the sender of the `m.key.verification.request` message can scan a QR code displayed by the recipient. If the recipient can display a QR code, it should allow the user to display it so that the sender can scan it. This method is never sent as @@ -179,34 +170,51 @@ This proposal defines three verification methods that can be used in ### QR code format -The QR codes to be displayed and scanned using this format will encode URLs of -the form: -`https://matrix.to/#/?request=&action=verify&key_=...&secret=&other_user_key=` -(when `matrix:` URLs are specced, this will be used instead). - -- `request`: is the event ID or `transaction_id` of the associated verification - request event. -- `key_`: each key that the user wants verified will have an entry of - this form, where the value is the key in unpadded base64. The QR code should - contain at least the user's master cross-signing key. In the case where a - device does not have a cross-signing key (as in the case where a user logs in - to a new device, and is verifying against another device), thin the QR code - should contain at least the device's key. -- `secret`: is a random single-use shared secret in unpadded base64. It must be - at least 256-bits long (43 characters when base64-encoded). -- `other_user_key`: the other user's master cross-signing key, in unpadded - base64. In other words, if Alice is displaying the QR code, this would be - the copy of Bob's master cross-signing key that Alice has. -- `other_device_key`: the other device's key, in unpadded base64. This is only - needed when a user is verifying their own devices, where the other device has - not yet been signed with the cross-signing key. - -The QR codes to be displayed and scanned, which are not a part of an in-person -verification (for example, for printing on business cards), will encode URLs of -the form: -`https://matrix.to/#/?action=verify&key_=...` -In this case, only the user scanning the QR code will verify the key of the -user whose QR code was scanned; bi-directional verification is not possible. +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 of the + ID + - the ID as an ASCII string +- the first key, as 32 bytes. The key to use depends on the mode field: + - if `0x00` or `0x01`, then the 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). ### Message types @@ -218,7 +226,7 @@ message contents: - `method`: `m.reciprocate.v1` - `m.relates_to`: as per [key verification framework](https://github.com/matrix-org/matrix-doc/pull/2241) -- `secret`: the shared secret from the QR code +- `secret`: the shared secret from the QR code, encoded using unpadded base64 Example: @@ -257,7 +265,9 @@ Tradeoffs/Alternatives Other methods of verifying keys, which do not require scanning QR codes, are needed for devices that are unable to scan QR codes. One such method is -[MSC1267](https://github.com/matrix-org/matrix-doc/issues/1267). +[MSC1267](https://github.com/matrix-org/matrix-doc/issues/1267). Since the key +verification framework allows for multiple methods to be supported, clients can +allow users to use different methods depending on their capability. Rather than embedding the keys in the QR codes directly, the two clients could perform an exchange similar to @@ -267,14 +277,13 @@ the clients must exchange several messages before they can verify each other, which would delay showing the QR codes. This proposal is also simpler to implement. +This proposal does not support the case of asynchronous verification, such as +printing a QR code on a business card for others to scan. That may be address +in a separate MSC. + Security Considerations ----------------------- -The first check in Step 6 in the example flow is to ensure that Bob does not -present a QR code claiming to be Carol's key. Without this check, Bob will be -able to trick Alice into verifying a key under his control, and evesdropping on -Alice's communications with Carol. - The security of verifying Alice's key depends on Bob not hitting the "Verified" button (step 10 in the example flow) until after Alice's device indicates success or failure. Users have a tendency to click on buttons without reading From 405ac1e2b548aa8aae77ab353a61d30077eea034 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 18 Feb 2020 22:35:21 -0500 Subject: [PATCH 20/26] add base32 option --- proposals/1543-qr_code_key_verification.md | 49 ++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index e9362811..084e80e1 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -170,6 +170,11 @@ This proposal defines three verification methods that can be used in ### QR code format +Note: only one of the following will be supported. They are both being +documented here while we determine how well different formats are supported. + +#### Binary format + The QR codes to be displayed and scanned using this format will encode binary strings in the general form: @@ -183,9 +188,9 @@ strings in the general form: 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 of the - ID - - the ID as an ASCII string + - 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 user's own master cross-signing public key - if `0x02`, then the current device's device key @@ -216,6 +221,44 @@ Bob's cross-signing key is `1011121314151617...` (which is "EBESExQVFh..." in base64), and the shared secret is `2021222324252627` (which is "ICEiIyQlJic" in base64). +#### Base32 format + +The QR codes to be displayed and scanned using this format will encode alphanumeric +strings generated as follows: + +1. generate a binary string by concatenating: + - 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 as + described in step 3: + - if "0" or "1", then the user's own master cross-signing public key + - if "2", then the current device's device key + - the second key, as 32 bytes. The key to use depends on the mode field: + - if "0", then what the device thinks the other user's master + cross-signing key is + - if "1", then what the device thinks the other device's device key is + - if "2", 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. +2. encode the above string using unpadded base32 as defined in RFC4648 +3. prepend the resulting string with + - the string "MATRIX" + - one character indicating the version (must by "2") + - one character indicating the QR code verification mode. May be one of the + following values: + - "0" verifying another user with cross-signing + - "1" self-verifying in which the current device does trust the master key + - "2" self-verifying in which the current device does not yet trust the + master key + +The QR code is then generated using alphanumeric encoding mode. + ### Message types #### `m.key.verification.start` From c77d04c70937e44fb24948f10d2cb4d285f6fd32 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 18 Feb 2020 22:58:41 -0500 Subject: [PATCH 21/26] add base64 option --- proposals/1543-qr_code_key_verification.md | 70 +++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 084e80e1..50aa4ebc 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -170,7 +170,7 @@ This proposal defines three verification methods that can be used in ### QR code format -Note: only one of the following will be supported. They are both being +Note: only one of the following will be supported. They are all being documented here while we determine how well different formats are supported. #### Binary format @@ -259,6 +259,74 @@ strings generated as follows: The QR code is then generated using alphanumeric encoding mode. +#### Base64 format + +The QR codes to be displayed and scanned using this format will be a string of +the following form: + +- the string "MATRIX" +- one character indicating the version (must by "2") +- one character indicating the QR code verification mode. May be one of the + following values: + - "0" verifying another user with cross-signing + - "1" self-verifying in which the current device does trust the master key + - "2" 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), encoded in unpadded base64 (3 + characters), indicating the length in bytes of the ID as a UTF-8 string + - the ID as a UTF-8 string +- the first key as unpadded base64 (43 characters). The key to use depends on + the mode field: + - if "0" or "1", then the user's own master cross-signing public key + - if "2", then the current device's device key +- the second key as unpadded base64 (43 characters). The key to use depends on + the mode field: + - if "0", then what the device thinks the other user's master + cross-signing key is + - if "1", then what the device thinks the other device's device key is + - if "2", then what the device thinks the user's master cross-signing key + is +- a random shared secret, as an ASCII string. It is suggested to use a secret + that is about 11 bytes long. (This is approximately the length of 8 bytes as + a base64 string.) 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. + +1. generate a binary string by concatenating: + - 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 as + described in step 3: + - if "0" or "1", then the user's own master cross-signing public key + - if "2", then the current device's device key + - the second key, as 32 bytes. The key to use depends on the mode field: + - if "0", then what the device thinks the other user's master + cross-signing key is + - if "1", then what the device thinks the other device's device key is + - if "2", 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. +2. encode the above string using unpadded base64 +3. prepend the resulting string with + - the string "MATRIX" + - one character indicating the version (must by "2") + - one character indicating the QR code verification mode. May be one of the + following values: + - "0" verifying another user with cross-signing + - "1" self-verifying in which the current device does trust the master key + - "2" self-verifying in which the current device does not yet trust the + master key + +The QR code is then generated using byte encoding mode. + ### Message types #### `m.key.verification.start` From ea0abe9de936045ea5d0e0d1e8085aef73886284 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 18 Feb 2020 23:03:54 -0500 Subject: [PATCH 22/26] remove incorrect stuff --- proposals/1543-qr_code_key_verification.md | 33 ---------------------- 1 file changed, 33 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 50aa4ebc..160249d0 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -294,39 +294,6 @@ the following form: is not a fixed size, clients will just use the remainder of binary string as the shared secret. -1. generate a binary string by concatenating: - - 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 as - described in step 3: - - if "0" or "1", then the user's own master cross-signing public key - - if "2", then the current device's device key - - the second key, as 32 bytes. The key to use depends on the mode field: - - if "0", then what the device thinks the other user's master - cross-signing key is - - if "1", then what the device thinks the other device's device key is - - if "2", 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. -2. encode the above string using unpadded base64 -3. prepend the resulting string with - - the string "MATRIX" - - one character indicating the version (must by "2") - - one character indicating the QR code verification mode. May be one of the - following values: - - "0" verifying another user with cross-signing - - "1" self-verifying in which the current device does trust the master key - - "2" self-verifying in which the current device does not yet trust the - master key - -The QR code is then generated using byte encoding mode. - ### Message types #### `m.key.verification.start` From a7279d99f06a2f343574a7a7ce86827942ba77ff Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 27 Feb 2020 11:42:22 -0500 Subject: [PATCH 23/26] Update proposals/1543-qr_code_key_verification.md Co-Authored-By: Travis Ralston --- proposals/1543-qr_code_key_verification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 160249d0..bce5c0a4 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -192,7 +192,7 @@ strings in the general form: 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 user's own master cross-signing public key + - 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 From 7b3c98cd9878be28ccf8cd43dcedebe3913e18be Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 16 Oct 2020 22:43:04 -0400 Subject: [PATCH 24/26] we're using the binary format --- proposals/1543-qr_code_key_verification.md | 78 ---------------------- 1 file changed, 78 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index bce5c0a4..690323f6 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -170,11 +170,6 @@ This proposal defines three verification methods that can be used in ### QR code format -Note: only one of the following will be supported. They are all being -documented here while we determine how well different formats are supported. - -#### Binary format - The QR codes to be displayed and scanned using this format will encode binary strings in the general form: @@ -221,79 +216,6 @@ Bob's cross-signing key is `1011121314151617...` (which is "EBESExQVFh..." in base64), and the shared secret is `2021222324252627` (which is "ICEiIyQlJic" in base64). -#### Base32 format - -The QR codes to be displayed and scanned using this format will encode alphanumeric -strings generated as follows: - -1. generate a binary string by concatenating: - - 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 as - described in step 3: - - if "0" or "1", then the user's own master cross-signing public key - - if "2", then the current device's device key - - the second key, as 32 bytes. The key to use depends on the mode field: - - if "0", then what the device thinks the other user's master - cross-signing key is - - if "1", then what the device thinks the other device's device key is - - if "2", 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. -2. encode the above string using unpadded base32 as defined in RFC4648 -3. prepend the resulting string with - - the string "MATRIX" - - one character indicating the version (must by "2") - - one character indicating the QR code verification mode. May be one of the - following values: - - "0" verifying another user with cross-signing - - "1" self-verifying in which the current device does trust the master key - - "2" self-verifying in which the current device does not yet trust the - master key - -The QR code is then generated using alphanumeric encoding mode. - -#### Base64 format - -The QR codes to be displayed and scanned using this format will be a string of -the following form: - -- the string "MATRIX" -- one character indicating the version (must by "2") -- one character indicating the QR code verification mode. May be one of the - following values: - - "0" verifying another user with cross-signing - - "1" self-verifying in which the current device does trust the master key - - "2" 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), encoded in unpadded base64 (3 - characters), indicating the length in bytes of the ID as a UTF-8 string - - the ID as a UTF-8 string -- the first key as unpadded base64 (43 characters). The key to use depends on - the mode field: - - if "0" or "1", then the user's own master cross-signing public key - - if "2", then the current device's device key -- the second key as unpadded base64 (43 characters). The key to use depends on - the mode field: - - if "0", then what the device thinks the other user's master - cross-signing key is - - if "1", then what the device thinks the other device's device key is - - if "2", then what the device thinks the user's master cross-signing key - is -- a random shared secret, as an ASCII string. It is suggested to use a secret - that is about 11 bytes long. (This is approximately the length of 8 bytes as - a base64 string.) 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. - ### Message types #### `m.key.verification.start` From 0b97ac59bfd7e0c9119c93bec49ea0369b1245ca Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 18 Nov 2020 22:52:06 -0500 Subject: [PATCH 25/26] event IDs use $ --- proposals/1543-qr_code_key_verification.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index 690323f6..fe4e9926 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -210,7 +210,7 @@ For example, if Alice displays a QR code encoding the following binary string: ``` this indicates that Alice is verifying another user (say Bob), in response to -the request from event "!ABCD...", her cross-signing key is +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 @@ -235,7 +235,7 @@ Example: "method": "m.reciprocate.v1", "m.relates_to": { "rel_type": "m.reference", - "event_id": "!event_id_of_verification_request" + "event_id": "$event_id_of_verification_request" }, "secret": "shared+secret" } From 9db8cc98d95fdf724088c1592979b60776456b44 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 20 Nov 2020 22:52:41 -0500 Subject: [PATCH 26/26] Update proposals/1543-qr_code_key_verification.md Co-authored-by: David Baker --- proposals/1543-qr_code_key_verification.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/1543-qr_code_key_verification.md b/proposals/1543-qr_code_key_verification.md index fe4e9926..ce620d92 100644 --- a/proposals/1543-qr_code_key_verification.md +++ b/proposals/1543-qr_code_key_verification.md @@ -41,7 +41,7 @@ who can then tell his device that the keys match. - a random shared secret. 5. Alice scans Bob's QR code. 6. Alice's device ensures that: - - Bob's key encoded in the QR code match the key that she already has for + - Bob's key encoded in the QR code matches the key that she already has for Bob, and - Alice's cross-signing key matches the cross-signing key encoded in the QR code.