From 332b5605c1eec0e22277dce252119b3f3d0e920b Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 19 Sep 2019 16:18:46 -0400 Subject: [PATCH] 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 c9b1d8d67..b8458961f 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.