simplify protocol by embedding Alice's key in Bob's QR code

pull/1544/head
Hubert Chathi 5 years ago
parent 10b6fd6c8e
commit 332b5605c1

@ -16,14 +16,10 @@ Proposal
-------- --------
When Alice and Bob meet in person to verify keys, Alice will scan a QR code 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 generated by Bob's device. The QR code will encode both Bob's key as well as what Bob
does not give Bob any information about Alice's key in order to verify it. We thinks Alice's key is. When Alice scans the QR code, she will ensure that the
can add a secret key to the QR code, which Alice's device can use to MAC her keys match what is expected, in which case, she relays this information to Bob,
key to send to Bob. In order to ensure that an attacker, who manages to also who can then tell his device that the keys match.
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: 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.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`).
5. Alice scans Bob's QR code. 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 6. Alice's device ensures that:
expected user ID (which it knows because it is the recipient of her - the user ID in the QR code is the same as the expected user ID (which it
`m.key.verification.request` message). At this point, Alice's device has knows because it is the recipient of her `m.key.verification.request`
now verified Bob's key. 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 7. Alice's device sends a `m.key.verification.start` message with `method` set
to `m.reciprocate.v1` to Bob (see below). to `m.reciprocate.v1` to Bob (see below).
8. Bob's device fetches Alice's public key, checks it against what was received 8. Upon receipt of the `m.key.verification.start` message, Bob's device
in the `m.key.verification.start` message, signs it, and sends it to Alice presents a button for him to press /after/ he has checked that Alice's
in a `m.key.verification.check_own_key` message (see below). Bob's device device says that things match.
displays a message saying that Alice wants him to verify her key, and 9. Bob sees Alice's device confirm that the key matches, and presses the button
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. on his device to indicate that Alice's key is verified.
10. Both devices send an `m.key.verification.done` message.
### Verification methods ### 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 QR codes to be displayed and scanned using this format will encode URLs of
the form: the form:
`https://matrix.to/#/<user-id>?request=<event-id>&action=verify&key_<keyid>=<key-in-base64>...&verification_algorithms=<algorithm>&verification_key=<random-key-in-base64>` `https://matrix.to/#/<user-id>?request=<event-id>&action=verify&key_<keyid>=<key-in-base64>...&verification_algorithms=<algorithm>&verification_key=<random-key-in-base64>&other_user_key=<master-key-in-base64>`
(when `matrix:` URLs are specced, this will be used instead). (when `matrix:` URLs are specced, this will be used instead).
The `request`, `verification_algorithm`, and `verification_key` parameters are - `request`: is the event ID of the associated verification request event.
only present if this QR code is related to a key verification request event. - `key_<key_id>`: each key that the user wants verified will have an entry of
`verification_algorithms` is a comma-separated list of hashing algorithms that this form, where the value is the key in unpadded base64. The QR code should
can be used for verifying the keys of the user who scanned the QR code; contain at least the user's master cross-signing key.
currently, only `hmac-sha256` is defined, which is HMAC using SHA-256 as the - `secret`: is a random single-use shared secret in unpadded base64. It must be
hash. `verification_key` is a random single-use shared secret, with a length at least 256-bits long (43 characters when base64-encoded).
depending on the `verification_algorithm`; for `hmac-sha256`, it must be at - `other_user_key`: the other user's master cross-signing key, in unpadded
least 256-bits long (43 characters when base64-encoded). 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/#/<user-id>?&action=verify&key_<keyid>=<key-in-base64>...`
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 ### Message types
#### `m.key.verification.start` #### `m.key.verification.start`
Alice's device tells Bob's device that his key is verified, and asks it to Alice's device tells Bob's device that the keys are verified. The request is
verify her keys. The request is MAC'ed using the verification algorithm and MAC'ed using the verification algorithm and verification key from the QR code.
verification key from the QR code.
message contents: message contents:
- `method`: `m.reciprocate.v1` - `method`: `m.reciprocate.v1`
- `m.relates_to`: as per [key verification framework](https://github.com/matrix-org/matrix-doc/pull/2241) - `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 - `secret`: the shared secret from the QR code
- `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: Example:
@ -128,50 +123,13 @@ Example:
"rel_type": "m.reference", "rel_type": "m.reference",
"event_id": "!event_id_of_verification_request" "event_id": "!event_id_of_verification_request"
}, },
"keys": { "secret": "shared+secret"
"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 Note that this message could be sent by either the sender or the recipient of
be sent by either the sender or the recipient of the the `m.key.verification.request` message, depending on which user scanned the
`m.key.verification.request` message. QR code.
#### `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"
}
}
}
```
### Cancellation ### 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 - `m.qr_code.invalid`: The QR code is invalid (e.g. it is not a URL of the
required form) 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 Tradeoffs/Alternatives
---------------------- ----------------------
@ -194,28 +156,19 @@ needed for devices that are unable to scan QR codes. One such method is
Security Considerations Security Considerations
----------------------- -----------------------
Step 6 in the example flow is to ensure that Bob does not present a QR code The first check in Step 6 in the example flow is to ensure that Bob does not
claiming to be Carol's key. Without this check, Bob will be able to trick present a QR code claiming to be Carol's key. Without this check, Bob will be
Alice into verifying a key under his control, and evesdropping on Alice's able to trick Alice into verifying a key under his control, and evesdropping on
communications with Carol. Alice's communications with Carol.
The security of verifying Alice's key depends on Bob not hitting the "Verified" 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 button (step 9 in the example flow) until after Alice's device indicates
success. However, users have a tendency to click on buttons without reading success or failure. Users have a tendency to click on buttons without reading
what the screen says. This is partially mitigated by having Alice's device what the screen says, but this is partially mitigated by the fact that it is
send her keys MAC'ed with a shared secret. But this relies on the shared unlikely that Bob will be interacting with the device while Alice is scanning
secret actually being secret, which may not be the case if an attacker is able and Alice's device will display the verification results immediately upon
to view the QR code, which limits the possible attackers to people who are scanning. Also, Bob's device will not display the button until it receives the
physically present when Alice and Bob verify. This can also be addressed by `m.key.verification.start` message that contains the shared secret from the QR
allowing Bob to easily undo the verification if Alice's device subsequently code, which means that an attacker would need to be physically present while
gives an error. 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.
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.

Loading…
Cancel
Save