From 3aba9b153b1d96bbff1538db85fcc3eca6c3178a Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 20 Aug 2018 15:24:44 -0400 Subject: [PATCH 01/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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/50] 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 1f734cd4a90682d56b0c48f31b29b04c12baaa8a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 3 Sep 2020 08:53:10 -0600 Subject: [PATCH 24/50] Proposal to support widget avatars --- proposals/0000-widget-avatars.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 proposals/0000-widget-avatars.md diff --git a/proposals/0000-widget-avatars.md b/proposals/0000-widget-avatars.md new file mode 100644 index 00000000..45433c6e --- /dev/null +++ b/proposals/0000-widget-avatars.md @@ -0,0 +1,32 @@ +# MSC0000: Widget avatars + +Currently widgets have a name and title associated with them, though no opportunity for avatars +for a favicon-like experience. This proposal introduces such a concept. + +## Proposal + +In the widget's `data`, a new optional paramater named `avatar_url` is added. This parameter is +an MXC URI to an image clients can use to associate with the widget, likely alongside the `name` +and/or `title`. + +Widget avatars SHOULD be legible at small sizes, such as 20x20. The MXC URI in the `avatar_url` +should be the source material to allow clients to use the `/thumbnail` API to get a size for their +use case. + +Rendering avatars is optional for clients, much like how clients are not required to use the `name` +or `title` of a widget. + +## Alternatives + +We could define a whole structured system for different thumbnail sizes, though we have a thumbnail +API which can be used to request whatever size is needed by the client. + +## Security considerations + +Widget avatars could be non-images. Clients should use the thumbnail API to encourage error responses +from the server when a widget avatar is a non-image. + +## Unstable prefix + +Not applicable - this is backwards compatible with specification and an allowed property of `data` +without this MSC. From d8bc158a3ba7b7a78369b843a05896520c78844e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 3 Sep 2020 08:55:27 -0600 Subject: [PATCH 25/50] Renumber --- proposals/{0000-widget-avatars.md => 2765-widget-avatars.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename proposals/{0000-widget-avatars.md => 2765-widget-avatars.md} (97%) diff --git a/proposals/0000-widget-avatars.md b/proposals/2765-widget-avatars.md similarity index 97% rename from proposals/0000-widget-avatars.md rename to proposals/2765-widget-avatars.md index 45433c6e..1849fae4 100644 --- a/proposals/0000-widget-avatars.md +++ b/proposals/2765-widget-avatars.md @@ -1,4 +1,4 @@ -# MSC0000: Widget avatars +# MSC2765: Widget avatars Currently widgets have a name and title associated with them, though no opportunity for avatars for a favicon-like experience. This proposal introduces such a concept. From 70e69a110a5471417e0ce961f0afb8ef9b9d9e9b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 3 Sep 2020 09:00:36 -0600 Subject: [PATCH 26/50] Move the avatar up a level --- proposals/2765-widget-avatars.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/proposals/2765-widget-avatars.md b/proposals/2765-widget-avatars.md index 1849fae4..14facbb2 100644 --- a/proposals/2765-widget-avatars.md +++ b/proposals/2765-widget-avatars.md @@ -5,7 +5,7 @@ for a favicon-like experience. This proposal introduces such a concept. ## Proposal -In the widget's `data`, a new optional paramater named `avatar_url` is added. This parameter is +A new optional paramater named `avatar_url` is added to the widget definition. This parameter is an MXC URI to an image clients can use to associate with the widget, likely alongside the `name` and/or `title`. @@ -16,6 +16,24 @@ use case. Rendering avatars is optional for clients, much like how clients are not required to use the `name` or `title` of a widget. +An example widget would be: + +```json +{ + "creatorUserId": "@alice:example.org", + "data": { + "custom-key": "This is a custom key", + "title": "This is a witty description for the widget" + }, + "id": "20200827_WidgetExample", + "name": "My Cool Widget", + "type": "m.custom", + "url": "https://example.org/my/widget.html?roomId=$matrix_room_id", + "waitForIframeLoad": true, + "avatar_url": "mxc://example.org/abc123" +} +``` + ## Alternatives We could define a whole structured system for different thumbnail sizes, though we have a thumbnail @@ -28,5 +46,6 @@ from the server when a widget avatar is a non-image. ## Unstable prefix -Not applicable - this is backwards compatible with specification and an allowed property of `data` -without this MSC. +While this MSC is not in a released version of the specification, clients should use an alternative +event type for widgets or use `org.matrix.msc2765.avatar_url` when using `m.widget` or `m.widgets` +as an event type. From b3116e4a3c9ef590ec949f7bd4a94e84291905ff Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 11 Sep 2020 13:36:46 -0600 Subject: [PATCH 27/50] Proposal to have widgets aware of their widget ID --- proposals/2774-widget-id.md | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 proposals/2774-widget-id.md diff --git a/proposals/2774-widget-id.md b/proposals/2774-widget-id.md new file mode 100644 index 00000000..98166708 --- /dev/null +++ b/proposals/2774-widget-id.md @@ -0,0 +1,54 @@ +# MSC2774: Giving widgets their ID so they can communicate + +Under the [current specification](https://github.com/matrix-org/matrix-doc/pull/2764), widgets are +able to communicate with their client host, however doing so is a bit difficult if they don't already +know their widget ID. Some widgets will be able to get their ID from another source like an +integration managaer, however this is not the case for all widgets. + +[MSC2762](https://github.com/matrix-org/matrix-doc/pull/2762) has a fair amount of background +information on widgets, as does the current specification linked above. + +## Proposal + +Currently widgets can expect a `?widgetId` query parameter sent to them in clients like Element, +however this has some issues and as such is not proposed to exist any further. One of the issues +is that the widget must retain the query string, which isn't entirely possible for some frontends +(they would instead prefer to use the fragment). It's also a privacy risk in that by being sent +through the query string, the server can be made aware of the widget ID. The widget ID doesn't +normally contain any useful information (it's an opaque string), however it's not required for +the server to function under typical usage. + +The proposal is to introduce a `$matrix_widget_id` template variable for the URL, similar to the +existing `$matrix_room_id` variable. Widgets can then have their widget ID wherever they want in +the widget URL, making it easier on them to find and use. + +This carries the same risks as a room ID being passed to the widget: the client can easily lie about +it, however there's no real risk involved in doing so because it's used for communication only. So +long as the client is able to identify which widget is talking to it, it doesn't really matter. It's +more of a problem if the client uses a widget ID from another widget as that could confuse the +client, however this is believed to be a bug. Clients should also be performing origin checks to +ensure the widget is talking from a sane origin and not somewhere else, like another tab or browser. + +## Potential issues + +This is not backwards compatible with the history of widgets so far, so clients and widgets will +need to be modified to support it. Clients which currently use the `?widgetId` parameter are +encouraged to continue supporting the parameter until sufficient adoption is reached. + +## Alternatives + +As mentioned, a query parameter could be used, though this has the issues previously covered. Another +solution might be to allow a single widget API action which has no widget ID solely for the purpose +of finding the widget ID, however clients are unlikely to be able to differentiate between two widgets +if this were the case. + +Another solution would be to let the widget discover its widget ID by harvesting it out of the first +widget API request it sees. This can't always be relied upon (some flows require the widget to +speak first), and as the widget API becomes more capable it could become a security risk. A malicious +browser extension could spam the widget with fake requests to try and convince it to talk to it +instead of the client, thus redirecting some information to the wrong place. + +## Unstable prefix + +Implementations should use `$org.matrix.msc2774_widget_id` as a variable until this lands in a +released version of the specification. From 411202f2bf6e78ff1ae413932acb9d39334076f3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 9 Oct 2020 10:16:01 -0600 Subject: [PATCH 28/50] spelling Co-authored-by: David Baker --- proposals/2774-widget-id.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2774-widget-id.md b/proposals/2774-widget-id.md index 98166708..41c67f8f 100644 --- a/proposals/2774-widget-id.md +++ b/proposals/2774-widget-id.md @@ -3,7 +3,7 @@ Under the [current specification](https://github.com/matrix-org/matrix-doc/pull/2764), widgets are able to communicate with their client host, however doing so is a bit difficult if they don't already know their widget ID. Some widgets will be able to get their ID from another source like an -integration managaer, however this is not the case for all widgets. +integration manager, however this is not the case for all widgets. [MSC2762](https://github.com/matrix-org/matrix-doc/pull/2762) has a fair amount of background information on widgets, as does the current specification linked above. From 7b3c98cd9878be28ccf8cd43dcedebe3913e18be Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 16 Oct 2020 22:43:04 -0400 Subject: [PATCH 29/50] 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 38350002a62f6896ae8e0485280956be619104ce Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 19 Oct 2020 18:57:39 -0400 Subject: [PATCH 30/50] add spec for reporting that keys are withheld --- event-schemas/examples/m.room_key.withheld | 12 +++ event-schemas/schema/m.forwarded_room_key | 9 +++ event-schemas/schema/m.room_key.withheld | 77 +++++++++++++++++++ .../modules/end_to_end_encryption.rst | 46 +++++++++-- 4 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 event-schemas/examples/m.room_key.withheld create mode 100644 event-schemas/schema/m.room_key.withheld diff --git a/event-schemas/examples/m.room_key.withheld b/event-schemas/examples/m.room_key.withheld new file mode 100644 index 00000000..fa8f135f --- /dev/null +++ b/event-schemas/examples/m.room_key.withheld @@ -0,0 +1,12 @@ +{ + "$ref": "core/event.json", + "type": "m.room_key.withheld", + "content": { + "algorithm": "m.megolm.v1.aes-sha2", + "room_id": "!Cuyf34gef24t:localhost", + "session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ", + "sender_key": "RF3s+E7RkTQTGF2d8Deol0FkQvgII2aJDf3/Jp5mxVU", + "code": "m.unverified", + "reason": "Device not verified" + } +} diff --git a/event-schemas/schema/m.forwarded_room_key b/event-schemas/schema/m.forwarded_room_key index f0beed2b..7350a25b 100644 --- a/event-schemas/schema/m.forwarded_room_key +++ b/event-schemas/schema/m.forwarded_room_key @@ -43,6 +43,15 @@ properties: to the end of the list. For example, if the key is forwarded from A to B to C, this field is empty between A and B, and contains A's Curve25519 key between B and C. + withheld: + type: object + description: |- + Indicates that the key cannot be used to decrypt all the messages + from the session because a portion of the session was withheld as + described in `Reporting that decryption keys are withheld`_. This + object must include the ``code`` and ``reason`` properties from the + ``m.room_key.withheld`` message that was received by the sender of + this message. required: - algorithm - room_id diff --git a/event-schemas/schema/m.room_key.withheld b/event-schemas/schema/m.room_key.withheld new file mode 100644 index 00000000..f37b24ee --- /dev/null +++ b/event-schemas/schema/m.room_key.withheld @@ -0,0 +1,77 @@ +--- +allOf: + - $ref: core-event-schema/event.yaml + +description: |- + This event type is used to indicate that the sender is not sharing room keys + with the recipient. It is sent as a to-device event. + + Possible values for ``code`` include: + + * ``m.blacklisted``: the user/device was blacklisted. + * ``m.unverified``: the user/device was not verified, and the sender is only + sharing keys with verified users/devices. + * ``m.unauthorised``: the user/device is not allowed to have the key. For + example, this could be sent in response to a key request if the user/device + was not in the room when the original message was sent. + * ``m.unavailable``: sent in reply to a key request if the device that the + key is requested from does not have the requested key. + * ``m.no_olm``: an olm session could not be established. + + In most cases, this event refers to a specific room key. The one exception to + this is when the sender is unable to establish an olm session with the + recipient. When this happens, multiple sessions will be affected. In order + to avoid filling the recipient\'s device mailbox, the sender should only send + one ``m.room_key.withheld`` message with no ``room_id`` nor ``session_id`` + set. If the sender retries and fails to create an olm session again in the + future, it should not send another ``m.room_key.withheld`` message with a + ``code`` of ``m.no_olm``, unless another olm session was previously + established successfully. In response to receiving an + ``m.room_key.withheld`` message with a ``code`` of ``m.no_olm``, the + recipient may start an olm session with the sender and send an ``m.dummy`` + message to notify the sender of the new olm session. The recipient may + assume that this ``m.room_key.withheld`` message applies to all encrypted + room messages sent before it receives the message. +properties: + content: + properties: + algorithm: + type: string + enum: ["m.megolm.v1.aes-sha2"] + description: |- + The encryption algorithm for the key that this event is about. + room_id: + type: string + description: |- + Required if ``code`` is not ``m.no_olm``. The room for the key that + this event is about. + session_id: + type: string + description: |- + Required of ``code`` is not ``m.no_olm``. The session ID of the key + that this event is aboutis for. + sender_key: + type: string + description: |- + The unpadded base64-encoded device curve25519 key of the event\'s + sender. + code: + type: string + description: |- + A machine-readable code for why the key was not sent. + reason: + type: string + description: |- + A human-readable reason for why the key was not sent. The receiving + client should only use this string if it does not understand the + ``code``. + required: + - algorithm + - sender_key + - code + type: object + type: + enum: + - m.room_key.withheld + type: string +type: object diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 63c1e0d1..4f60c848 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -792,14 +792,19 @@ Key requests When a device is missing keys to decrypt messages, it can request the keys by sending `m.room_key_request`_ to-device messages to other devices with -``action`` set to ``request``. If a device wishes to share the keys with that -device, it can forward the keys to the first device by sending an encrypted -`m.forwarded_room_key`_ to-device message. The first device should then send an -`m.room_key_request`_ to-device message with ``action`` set to -``request_cancellation`` to the other devices that it had originally sent the key -request to; a device that receives a ``request_cancellation`` should disregard any -previously-received ``request`` message with the same ``request_id`` and -``requesting_device_id``. +``action`` set to ``request``. + +If a device wishes to share the keys with that device, it can forward the keys +to the first device by sending an encrypted `m.forwarded_room_key`_ to-device +message. The first device should then send an `m.room_key_request`_ to-device +message with ``action`` set to ``request_cancellation`` to the other devices +that it had originally sent the key request to; a device that receives a +``request_cancellation`` should disregard any previously-received ``request`` +message with the same ``request_id`` and ``requesting_device_id``. + +If a device does not wish to share keys with that device, it can indicate this +by sending an `m.room_key.withheld`_ to-device message, as described in +`Reporting that decryption keys are withheld`_. .. NOTE:: @@ -1333,6 +1338,31 @@ Example response: } } +Reporting that decryption keys are withheld +------------------------------------------- + +When sending an encrypted event to a room, a client can signal to other devices +in that room that it is not sending them the keys needed to decrypt the event. +In this way, the receiving client can indicate to the user why it cannot +decrypt the event, rather than just showing a generic error message. + +In the same way, when one device requests keys from another using `Key +requests`_, the device from which the key is being requested may want to tell +the requester that it is purposely not sharing the key. + +If Alice withholds a megolm session from Bob for some messages in a room, and +then later on decides to allow Bob to decrypt later messages, she can send Bob +the megolm session, ratcheted up to the point at which she allows Bob to +decrypt the messages. If Bob logs into a new device and uses key sharing to +obtain the decryption keys, the new device will be sent the megolm sessions +that have been ratcheted up. Bob's old device can include the reason that the +session was initially not shared by including a ``withheld`` property in the +``m.forwarded_room_key`` message that is an object with the ``code`` and +``reason`` properties from the ``m.room_key.withheld`` message. + +{{m_room_key_withheld_event}} + + .. References .. _ed25519: http://ed25519.cr.yp.to/ From 7b4ea94f226066f40214d06615e3c6ef57203ae2 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 19 Oct 2020 19:12:01 -0400 Subject: [PATCH 31/50] add changelog --- changelogs/client_server/newsfragments/2399.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2399.feature diff --git a/changelogs/client_server/newsfragments/2399.feature b/changelogs/client_server/newsfragments/2399.feature new file mode 100644 index 00000000..e9819639 --- /dev/null +++ b/changelogs/client_server/newsfragments/2399.feature @@ -0,0 +1 @@ +Document how clients can advise recipients that it is withholding decryption keys as per `MSC2399 `_. \ No newline at end of file From ee55d9d35bbb107a6ea8b2edea3e2f8574e94c8e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 22 Oct 2020 11:23:32 -0600 Subject: [PATCH 32/50] Update proposals/2765-widget-avatars.md Co-authored-by: Hubert Chathi --- proposals/2765-widget-avatars.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/2765-widget-avatars.md b/proposals/2765-widget-avatars.md index 14facbb2..a9030d29 100644 --- a/proposals/2765-widget-avatars.md +++ b/proposals/2765-widget-avatars.md @@ -22,7 +22,7 @@ An example widget would be: { "creatorUserId": "@alice:example.org", "data": { - "custom-key": "This is a custom key", + "custom_key": "This is a custom key", "title": "This is a witty description for the widget" }, "id": "20200827_WidgetExample", From 3fed0dd17f3d9044ba2099d789142321f3ce3aa6 Mon Sep 17 00:00:00 2001 From: Nikolai Zahariev Date: Thu, 29 Oct 2020 21:50:03 +0000 Subject: [PATCH 33/50] Added translation using Weblate (Bulgarian) --- data-definitions/sas-emoji-v1-i18n/bg.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/bg.json diff --git a/data-definitions/sas-emoji-v1-i18n/bg.json b/data-definitions/sas-emoji-v1-i18n/bg.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/bg.json @@ -0,0 +1 @@ +{} From a5e3652d26ccf97ca321370fd2c020ed36855617 Mon Sep 17 00:00:00 2001 From: Nikolai Zahariev Date: Thu, 29 Oct 2020 21:58:44 +0000 Subject: [PATCH 34/50] Translated using Weblate (Bulgarian) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.element.io/projects/matrix-doc/sas-emoji-v1/bg/ --- data-definitions/sas-emoji-v1-i18n/bg.json | 67 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/bg.json b/data-definitions/sas-emoji-v1-i18n/bg.json index 0967ef42..6727ee6f 100644 --- a/data-definitions/sas-emoji-v1-i18n/bg.json +++ b/data-definitions/sas-emoji-v1-i18n/bg.json @@ -1 +1,66 @@ -{} +{ + "Pin": "Кабърче", + "Folder": "Папка", + "Headphones": "Слушалки", + "Anchor": "Котва", + "Bell": "Звънец", + "Trumpet": "Тромпет", + "Guitar": "Китара", + "Ball": "Топка", + "Trophy": "Трофей", + "Rocket": "Ракета", + "Aeroplane": "Самолет", + "Bicycle": "Колело", + "Train": "Влак", + "Flag": "Флаг", + "Telephone": "Телефон", + "Hammer": "Чук", + "Key": "Ключ", + "Lock": "Катинар", + "Scissors": "Ножици", + "Paperclip": "Кламер", + "Pencil": "Молив", + "Book": "Книга", + "Light Bulb": "Лампа", + "Gift": "Подарък", + "Clock": "Часовник", + "Hourglass": "Пясъчен часовник", + "Umbrella": "Чадър", + "Thumbs Up": "Палец нагоре", + "Santa": "Дядо Коледа", + "Spanner": "Гаечен ключ", + "Glasses": "Очила", + "Hat": "Шапка", + "Robot": "Робот", + "Smiley": "Усмивка", + "Heart": "Сърце", + "Cake": "Торта", + "Pizza": "Пица", + "Corn": "Царевица", + "Strawberry": "Ягода", + "Apple": "Ябълка", + "Banana": "Банан", + "Fire": "Огън", + "Cloud": "Облак", + "Moon": "Луна", + "Globe": "Глобус", + "Mushroom": "Гъба", + "Cactus": "Кактус", + "Tree": "Дърво", + "Flower": "Цвете", + "Butterfly": "Пеперуда", + "Octopus": "Октопод", + "Fish": "Риба", + "Turtle": "Костенурка", + "Penguin": "Пингвин", + "Rooster": "Петел", + "Panda": "Панда", + "Rabbit": "Заек", + "Elephant": "Слон", + "Pig": "Прасе", + "Unicorn": "Еднорог", + "Horse": "Кон", + "Lion": "Лъв", + "Cat": "Котка", + "Dog": "Куче" +} From 267eead50f4abecffa2c02ce42db1513bbfbddf4 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 2 Nov 2020 12:30:57 -0500 Subject: [PATCH 35/50] apply changes from review --- event-schemas/schema/m.room_key.withheld | 11 ++++++++++- specification/modules/end_to_end_encryption.rst | 9 +++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/event-schemas/schema/m.room_key.withheld b/event-schemas/schema/m.room_key.withheld index f37b24ee..a2cddbfa 100644 --- a/event-schemas/schema/m.room_key.withheld +++ b/event-schemas/schema/m.room_key.withheld @@ -57,8 +57,17 @@ properties: sender. code: type: string + enum: + - m.blacklisted + - m.unverified + - m.unauthorised + - m.unavailable + - m.no_olm description: |- - A machine-readable code for why the key was not sent. + A machine-readable code for why the key was not sent. Codes beginning + with `m.` are reserved for codes defined in the Matrix + specification. Custom codes must use the Java package naming + convention. reason: type: string description: |- diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index 4f60c848..be66897b 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -1341,10 +1341,11 @@ Example response: Reporting that decryption keys are withheld ------------------------------------------- -When sending an encrypted event to a room, a client can signal to other devices -in that room that it is not sending them the keys needed to decrypt the event. -In this way, the receiving client can indicate to the user why it cannot -decrypt the event, rather than just showing a generic error message. +When sending an encrypted event to a room, a client can optionally signal to +other devices in that room that it is not sending them the keys needed to +decrypt the event. In this way, the receiving client can indicate to the user +why it cannot decrypt the event, rather than just showing a generic error +message. In the same way, when one device requests keys from another using `Key requests`_, the device from which the key is being requested may want to tell From 30448b988c775cb1a62c065c06a6cfa99c51eab6 Mon Sep 17 00:00:00 2001 From: Auri Botines Puertas Date: Thu, 5 Nov 2020 01:34:04 +0000 Subject: [PATCH 36/50] Added translation using Weblate (Catalan) --- data-definitions/sas-emoji-v1-i18n/ca.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 data-definitions/sas-emoji-v1-i18n/ca.json diff --git a/data-definitions/sas-emoji-v1-i18n/ca.json b/data-definitions/sas-emoji-v1-i18n/ca.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/data-definitions/sas-emoji-v1-i18n/ca.json @@ -0,0 +1 @@ +{} From 4a1d49ae4afc3a48fbedbc5517d6996d366aab2b Mon Sep 17 00:00:00 2001 From: "Auri B. P" Date: Thu, 5 Nov 2020 01:45:20 +0000 Subject: [PATCH 37/50] Translated using Weblate (Catalan) Currently translated at 100.0% (64 of 64 strings) Translation: matrix-doc/SAS Emoji v1 Translate-URL: https://translate.element.io/projects/matrix-doc/sas-emoji-v1/ca/ --- data-definitions/sas-emoji-v1-i18n/ca.json | 67 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data-definitions/sas-emoji-v1-i18n/ca.json b/data-definitions/sas-emoji-v1-i18n/ca.json index 0967ef42..adca06b3 100644 --- a/data-definitions/sas-emoji-v1-i18n/ca.json +++ b/data-definitions/sas-emoji-v1-i18n/ca.json @@ -1 +1,66 @@ -{} +{ + "Cactus": "Cactus", + "Globe": "Globus terraqüi", + "Rooster": "Gall", + "Pin": "Xinxeta", + "Folder": "Carpeta", + "Headphones": "Auriculars", + "Anchor": "Àncora", + "Bell": "Campana", + "Trumpet": "Trompeta", + "Guitar": "Guitarra", + "Ball": "Pilota", + "Trophy": "Trofeu", + "Rocket": "Coet", + "Aeroplane": "Avió", + "Bicycle": "Bicicleta", + "Train": "Tren", + "Flag": "Bandera", + "Telephone": "Telèfon", + "Hammer": "Martell", + "Lock": "Cadenat", + "Key": "Clau", + "Scissors": "Tisores", + "Paperclip": "Clip", + "Pencil": "Llapis", + "Book": "Llibre", + "Light Bulb": "Bombeta", + "Gift": "Regal", + "Clock": "Rellotge", + "Hourglass": "Rellotge de sorra", + "Umbrella": "Paraigües", + "Thumbs Up": "Polzes amunt", + "Santa": "Pare Noél", + "Spanner": "Clau anglesa", + "Glasses": "Ulleres", + "Hat": "Barret", + "Robot": "Robot", + "Smiley": "Somrient", + "Heart": "Cor", + "Cake": "Pastís", + "Pizza": "Pizza", + "Corn": "Blat de moro", + "Strawberry": "Maduixa", + "Apple": "Poma", + "Banana": "Plàtan", + "Fire": "Foc", + "Cloud": "Núvol", + "Moon": "Lluna", + "Mushroom": "Bolet", + "Tree": "Arbre", + "Flower": "Flor", + "Butterfly": "Papallona", + "Octopus": "Pop", + "Fish": "Peix", + "Turtle": "Tortuga", + "Penguin": "Pingüí", + "Panda": "Panda", + "Rabbit": "Conill", + "Elephant": "Elefant", + "Unicorn": "Unicorn", + "Pig": "Porc", + "Horse": "Cavall", + "Lion": "Lleó", + "Cat": "Gat", + "Dog": "Gos" +} From 42bb5127be7f3cfc5fa01bfed567fd69879c0c80 Mon Sep 17 00:00:00 2001 From: Will Date: Sun, 8 Nov 2020 09:44:11 -0800 Subject: [PATCH 38/50] Fix typo in API title --- api/client-server/capabilities.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/capabilities.yaml b/api/client-server/capabilities.yaml index a50908f7..ece0d9ad 100644 --- a/api/client-server/capabilities.yaml +++ b/api/client-server/capabilities.yaml @@ -13,7 +13,7 @@ # limitations under the License. swagger: '2.0' info: - title: "Matrix Client-Server Capabiltiies API" + title: "Matrix Client-Server Capabilities API" version: "1.0.0" host: localhost:8008 schemes: From c6441176b81ff6ece1fbf97b99186ad705ca34a6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 9 Nov 2020 15:12:49 -0700 Subject: [PATCH 39/50] Update i18n --- data-definitions/sas-emoji.json | 128 ++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/data-definitions/sas-emoji.json b/data-definitions/sas-emoji.json index a4d0c8e0..898c2132 100644 --- a/data-definitions/sas-emoji.json +++ b/data-definitions/sas-emoji.json @@ -5,6 +5,8 @@ "description": "Dog", "unicode": "U+1F436", "translated_descriptions": { + "bg": "Куче", + "ca": "Gos", "de": "Hund", "eo": "Hundo", "es": "Perro", @@ -29,6 +31,8 @@ "description": "Cat", "unicode": "U+1F431", "translated_descriptions": { + "bg": "Котка", + "ca": "Gat", "de": "Katze", "eo": "Kato", "es": "Gato", @@ -53,6 +57,8 @@ "description": "Lion", "unicode": "U+1F981", "translated_descriptions": { + "bg": "Лъв", + "ca": "Lleó", "de": "Löwe", "eo": "Leono", "es": "León", @@ -77,6 +83,8 @@ "description": "Horse", "unicode": "U+1F40E", "translated_descriptions": { + "bg": "Кон", + "ca": "Cavall", "de": "Pferd", "eo": "Ĉevalo", "es": "Caballo", @@ -101,6 +109,8 @@ "description": "Unicorn", "unicode": "U+1F984", "translated_descriptions": { + "bg": "Еднорог", + "ca": "Unicorn", "de": "Einhorn", "eo": "Unukorno", "es": "Unicornio", @@ -125,6 +135,8 @@ "description": "Pig", "unicode": "U+1F437", "translated_descriptions": { + "bg": "Прасе", + "ca": "Porc", "de": "Schwein", "eo": "Porko", "es": "Cerdo", @@ -149,6 +161,8 @@ "description": "Elephant", "unicode": "U+1F418", "translated_descriptions": { + "bg": "Слон", + "ca": "Elefant", "de": "Elefant", "eo": "Elefanto", "es": "Elefante", @@ -173,6 +187,8 @@ "description": "Rabbit", "unicode": "U+1F430", "translated_descriptions": { + "bg": "Заек", + "ca": "Conill", "de": "Hase", "eo": "Kuniklo", "es": "Conejo", @@ -197,6 +213,8 @@ "description": "Panda", "unicode": "U+1F43C", "translated_descriptions": { + "bg": "Панда", + "ca": "Panda", "de": "Panda", "eo": "Pando", "es": "Panda", @@ -221,6 +239,8 @@ "description": "Rooster", "unicode": "U+1F413", "translated_descriptions": { + "bg": "Петел", + "ca": "Gall", "de": "Hahn", "eo": "Virkoko", "es": "Gallo", @@ -245,6 +265,8 @@ "description": "Penguin", "unicode": "U+1F427", "translated_descriptions": { + "bg": "Пингвин", + "ca": "Pingüí", "de": "Pinguin", "eo": "Pingveno", "es": "Pingüino", @@ -269,6 +291,8 @@ "description": "Turtle", "unicode": "U+1F422", "translated_descriptions": { + "bg": "Костенурка", + "ca": "Tortuga", "de": "Schildkröte", "eo": "Testudo", "es": "Tortuga", @@ -293,6 +317,8 @@ "description": "Fish", "unicode": "U+1F41F", "translated_descriptions": { + "bg": "Риба", + "ca": "Peix", "de": "Fisch", "eo": "Fiŝo", "es": "Pez", @@ -317,6 +343,8 @@ "description": "Octopus", "unicode": "U+1F419", "translated_descriptions": { + "bg": "Октопод", + "ca": "Pop", "de": "Oktopus", "eo": "Polpo", "es": "Pulpo", @@ -341,6 +369,8 @@ "description": "Butterfly", "unicode": "U+1F98B", "translated_descriptions": { + "bg": "Пеперуда", + "ca": "Papallona", "de": "Schmetterling", "eo": "Papilio", "es": "Mariposa", @@ -365,6 +395,8 @@ "description": "Flower", "unicode": "U+1F337", "translated_descriptions": { + "bg": "Цвете", + "ca": "Flor", "de": "Blume", "eo": "Floro", "es": "Flor", @@ -389,6 +421,8 @@ "description": "Tree", "unicode": "U+1F333", "translated_descriptions": { + "bg": "Дърво", + "ca": "Arbre", "de": "Baum", "eo": "Arbo", "es": "Árbol", @@ -413,6 +447,8 @@ "description": "Cactus", "unicode": "U+1F335", "translated_descriptions": { + "bg": "Кактус", + "ca": "Cactus", "de": "Kaktus", "eo": "Kakto", "es": "Cactus", @@ -437,6 +473,8 @@ "description": "Mushroom", "unicode": "U+1F344", "translated_descriptions": { + "bg": "Гъба", + "ca": "Bolet", "de": "Pilz", "eo": "Fungo", "es": "Seta", @@ -461,6 +499,8 @@ "description": "Globe", "unicode": "U+1F30F", "translated_descriptions": { + "bg": "Глобус", + "ca": "Globus terraqüi", "de": "Globus", "eo": "Globo", "es": "Globo", @@ -485,6 +525,8 @@ "description": "Moon", "unicode": "U+1F319", "translated_descriptions": { + "bg": "Луна", + "ca": "Lluna", "de": "Mond", "eo": "Luno", "es": "Luna", @@ -509,6 +551,8 @@ "description": "Cloud", "unicode": "U+2601U+FE0F", "translated_descriptions": { + "bg": "Облак", + "ca": "Núvol", "de": "Wolke", "eo": "Nubo", "es": "Nube", @@ -533,6 +577,8 @@ "description": "Fire", "unicode": "U+1F525", "translated_descriptions": { + "bg": "Огън", + "ca": "Foc", "de": "Feuer", "eo": "Fajro", "es": "Fuego", @@ -557,6 +603,8 @@ "description": "Banana", "unicode": "U+1F34C", "translated_descriptions": { + "bg": "Банан", + "ca": "Plàtan", "de": "Banane", "eo": "Banano", "es": "Plátano", @@ -581,6 +629,8 @@ "description": "Apple", "unicode": "U+1F34E", "translated_descriptions": { + "bg": "Ябълка", + "ca": "Poma", "de": "Apfel", "eo": "Pomo", "es": "Manzana", @@ -605,6 +655,8 @@ "description": "Strawberry", "unicode": "U+1F353", "translated_descriptions": { + "bg": "Ягода", + "ca": "Maduixa", "de": "Erdbeere", "eo": "Frago", "es": "Fresa", @@ -629,6 +681,8 @@ "description": "Corn", "unicode": "U+1F33D", "translated_descriptions": { + "bg": "Царевица", + "ca": "Blat de moro", "de": "Korn", "eo": "Maizo", "es": "Maíz", @@ -653,6 +707,8 @@ "description": "Pizza", "unicode": "U+1F355", "translated_descriptions": { + "bg": "Пица", + "ca": "Pizza", "de": "Pizza", "eo": "Pico", "es": "Pizza", @@ -677,6 +733,8 @@ "description": "Cake", "unicode": "U+1F382", "translated_descriptions": { + "bg": "Торта", + "ca": "Pastís", "de": "Kuchen", "eo": "Torto", "es": "Tarta", @@ -701,6 +759,8 @@ "description": "Heart", "unicode": "U+2764U+FE0F", "translated_descriptions": { + "bg": "Сърце", + "ca": "Cor", "de": "Herz", "eo": "Koro", "es": "Corazón", @@ -725,6 +785,8 @@ "description": "Smiley", "unicode": "U+1F600", "translated_descriptions": { + "bg": "Усмивка", + "ca": "Somrient", "de": "Smiley", "eo": "Rideto", "es": "Emoticono", @@ -749,6 +811,8 @@ "description": "Robot", "unicode": "U+1F916", "translated_descriptions": { + "bg": "Робот", + "ca": "Robot", "de": "Roboter", "eo": "Roboto", "es": "Robot", @@ -773,6 +837,8 @@ "description": "Hat", "unicode": "U+1F3A9", "translated_descriptions": { + "bg": "Шапка", + "ca": "Barret", "de": "Hut", "eo": "Ĉapelo", "es": "Sombrero", @@ -797,6 +863,8 @@ "description": "Glasses", "unicode": "U+1F453", "translated_descriptions": { + "bg": "Очила", + "ca": "Ulleres", "de": "Brille", "eo": "Okulvitroj", "es": "Gafas", @@ -821,6 +889,8 @@ "description": "Spanner", "unicode": "U+1F527", "translated_descriptions": { + "bg": "Гаечен ключ", + "ca": "Clau anglesa", "de": "Schraubenschlüssel", "eo": "Ŝraŭbŝlosilo", "es": "Llave inglesa", @@ -845,6 +915,8 @@ "description": "Santa", "unicode": "U+1F385", "translated_descriptions": { + "bg": "Дядо Коледа", + "ca": "Pare Noél", "de": "Nikolaus", "eo": "Kristnaska viro", "es": null, @@ -869,6 +941,8 @@ "description": "Thumbs Up", "unicode": "U+1F44D", "translated_descriptions": { + "bg": "Палец нагоре", + "ca": "Polzes amunt", "de": "Daumen Hoch", "eo": "Dikfingro supren", "es": null, @@ -893,6 +967,8 @@ "description": "Umbrella", "unicode": "U+2602U+FE0F", "translated_descriptions": { + "bg": "Чадър", + "ca": "Paraigües", "de": "Regenschirm", "eo": "Ombrelo", "es": null, @@ -917,6 +993,8 @@ "description": "Hourglass", "unicode": "U+231B", "translated_descriptions": { + "bg": "Пясъчен часовник", + "ca": "Rellotge de sorra", "de": "Sanduhr", "eo": "Sablohorloĝo", "es": null, @@ -941,6 +1019,8 @@ "description": "Clock", "unicode": "U+23F0", "translated_descriptions": { + "bg": "Часовник", + "ca": "Rellotge", "de": "Wecker", "eo": "Horloĝo", "es": "Reloj", @@ -965,6 +1045,8 @@ "description": "Gift", "unicode": "U+1F381", "translated_descriptions": { + "bg": "Подарък", + "ca": "Regal", "de": "Geschenk", "eo": "Donaco", "es": "Regalo", @@ -989,6 +1071,8 @@ "description": "Light Bulb", "unicode": "U+1F4A1", "translated_descriptions": { + "bg": "Лампа", + "ca": "Bombeta", "de": "Glühbirne", "eo": "Lampo", "es": null, @@ -1013,6 +1097,8 @@ "description": "Book", "unicode": "U+1F4D5", "translated_descriptions": { + "bg": "Книга", + "ca": "Llibre", "de": "Buch", "eo": "Libro", "es": "Libro", @@ -1037,6 +1123,8 @@ "description": "Pencil", "unicode": "U+270FU+FE0F", "translated_descriptions": { + "bg": "Молив", + "ca": "Llapis", "de": "Bleistift", "eo": "Krajono", "es": "Lápiz", @@ -1061,6 +1149,8 @@ "description": "Paperclip", "unicode": "U+1F4CE", "translated_descriptions": { + "bg": "Кламер", + "ca": "Clip", "de": "Büroklammer", "eo": "Paperkuntenilo", "es": null, @@ -1085,6 +1175,8 @@ "description": "Scissors", "unicode": "U+2702U+FE0F", "translated_descriptions": { + "bg": "Ножици", + "ca": "Tisores", "de": "Schere", "eo": "Tondilo", "es": null, @@ -1109,6 +1201,8 @@ "description": "Lock", "unicode": "U+1F512", "translated_descriptions": { + "bg": "Катинар", + "ca": "Cadenat", "de": "Schloss", "eo": "Seruro", "es": null, @@ -1133,6 +1227,8 @@ "description": "Key", "unicode": "U+1F511", "translated_descriptions": { + "bg": "Ключ", + "ca": "Clau", "de": "Schlüssel", "eo": "Ŝlosilo", "es": "Llave", @@ -1157,6 +1253,8 @@ "description": "Hammer", "unicode": "U+1F528", "translated_descriptions": { + "bg": "Чук", + "ca": "Martell", "de": "Hammer", "eo": "Martelo", "es": "Martillo", @@ -1181,6 +1279,8 @@ "description": "Telephone", "unicode": "U+260EU+FE0F", "translated_descriptions": { + "bg": "Телефон", + "ca": "Telèfon", "de": "Telefon", "eo": "Telefono", "es": "Telefono", @@ -1205,6 +1305,8 @@ "description": "Flag", "unicode": "U+1F3C1", "translated_descriptions": { + "bg": "Флаг", + "ca": "Bandera", "de": "Flagge", "eo": "Flago", "es": null, @@ -1229,6 +1331,8 @@ "description": "Train", "unicode": "U+1F682", "translated_descriptions": { + "bg": "Влак", + "ca": "Tren", "de": "Zug", "eo": "Vagonaro", "es": "Tren", @@ -1253,6 +1357,8 @@ "description": "Bicycle", "unicode": "U+1F6B2", "translated_descriptions": { + "bg": "Колело", + "ca": "Bicicleta", "de": "Fahrrad", "eo": "Biciklo", "es": "Bicicleta", @@ -1277,6 +1383,8 @@ "description": "Aeroplane", "unicode": "U+2708U+FE0F", "translated_descriptions": { + "bg": "Самолет", + "ca": "Avió", "de": "Flugzeug", "eo": "Aviadilo", "es": null, @@ -1301,6 +1409,8 @@ "description": "Rocket", "unicode": "U+1F680", "translated_descriptions": { + "bg": "Ракета", + "ca": "Coet", "de": "Rakete", "eo": "Raketo", "es": null, @@ -1325,6 +1435,8 @@ "description": "Trophy", "unicode": "U+1F3C6", "translated_descriptions": { + "bg": "Трофей", + "ca": "Trofeu", "de": "Trophäe", "eo": "Trofeo", "es": null, @@ -1349,6 +1461,8 @@ "description": "Ball", "unicode": "U+26BD", "translated_descriptions": { + "bg": "Топка", + "ca": "Pilota", "de": "Ball", "eo": "Pilko", "es": "Bola", @@ -1373,6 +1487,8 @@ "description": "Guitar", "unicode": "U+1F3B8", "translated_descriptions": { + "bg": "Китара", + "ca": "Guitarra", "de": "Gitarre", "eo": "Gitaro", "es": "Guitarra", @@ -1397,6 +1513,8 @@ "description": "Trumpet", "unicode": "U+1F3BA", "translated_descriptions": { + "bg": "Тромпет", + "ca": "Trompeta", "de": "Trompete", "eo": "Trumpeto", "es": "Trompeta", @@ -1421,6 +1539,8 @@ "description": "Bell", "unicode": "U+1F514", "translated_descriptions": { + "bg": "Звънец", + "ca": "Campana", "de": "Glocke", "eo": "Sonorilo", "es": "Campana", @@ -1445,6 +1565,8 @@ "description": "Anchor", "unicode": "U+2693", "translated_descriptions": { + "bg": "Котва", + "ca": "Àncora", "de": "Anker", "eo": "Ankro", "es": null, @@ -1469,6 +1591,8 @@ "description": "Headphones", "unicode": "U+1F3A7", "translated_descriptions": { + "bg": "Слушалки", + "ca": "Auriculars", "de": "Kopfhörer", "eo": "Kapaŭdilo", "es": null, @@ -1493,6 +1617,8 @@ "description": "Folder", "unicode": "U+1F4C1", "translated_descriptions": { + "bg": "Папка", + "ca": "Carpeta", "de": "Ordner", "eo": "Dosierujo", "es": null, @@ -1517,6 +1643,8 @@ "description": "Pin", "unicode": "U+1F4CC", "translated_descriptions": { + "bg": "Кабърче", + "ca": "Xinxeta", "de": "Stecknadel", "eo": "Pinglo", "es": "Alfiler", From 0b97ac59bfd7e0c9119c93bec49ea0369b1245ca Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 18 Nov 2020 22:52:06 -0500 Subject: [PATCH 40/50] 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 41/50] 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. From 0fd1654879001c7f0329af58acee26ed39ee87cc Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 25 Nov 2020 21:48:34 +0100 Subject: [PATCH 42/50] Update link to extensible events MSC Signed-off-by: Nicolas Werner --- specification/modules/instant_messaging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/modules/instant_messaging.rst b/specification/modules/instant_messaging.rst index 705fd2d9..704277a1 100644 --- a/specification/modules/instant_messaging.rst +++ b/specification/modules/instant_messaging.rst @@ -121,7 +121,7 @@ the tag and its contents and therefore may wish to exclude the tag entirely. .. Note:: A future iteration of the specification will support more powerful and extensible - message formatting options, such as the proposal `MSC1225 `_. + message formatting options, such as the proposal `MSC1767 `_. {{msgtype_events}} From a0f4ae6b38849134f75c5ee374c6f3ff8f1ba236 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 25 Nov 2020 22:28:31 +0100 Subject: [PATCH 43/50] Add newsfragment Signed-off-by: Nicolas Werner --- changelogs/client_server/newsfragments/2878.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2878.clarification diff --git a/changelogs/client_server/newsfragments/2878.clarification b/changelogs/client_server/newsfragments/2878.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/client_server/newsfragments/2878.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. From b1d403083cac68e146e300b0de3df733751c5242 Mon Sep 17 00:00:00 2001 From: Emelie Date: Sun, 29 Nov 2020 21:50:33 +0100 Subject: [PATCH 44/50] Fix typo in moderation_policies.rst deliberatly -> deliberately --- specification/modules/moderation_policies.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/modules/moderation_policies.rst b/specification/modules/moderation_policies.rst index 2e85fb07..5092c895 100644 --- a/specification/modules/moderation_policies.rst +++ b/specification/modules/moderation_policies.rst @@ -77,7 +77,7 @@ is as follows: Subscribing to policy lists --------------------------- -This is deliberatly left as an implementation detail. For implementations using the +This is deliberately left as an implementation detail. For implementations using the Client-Server API, this could be as easy as joining or peeking the room. Joining or peeking is not required, however: an implementation could poll for updates or use a different technique for receiving updates to the policy's rules. @@ -108,7 +108,7 @@ or room alias - the subscriber is responsible for resolving the alias to a room Client behaviour ---------------- -As described above, the client behaviour is deliberatly left undefined. +As described above, the client behaviour is deliberately left undefined. Server behaviour ---------------- From 8d4d6a12e82e2da4aa98460daae0643f6e362887 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 30 Nov 2020 13:40:46 -0700 Subject: [PATCH 45/50] Add missing changelog --- changelogs/client_server/newsfragments/2885.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2885.clarification diff --git a/changelogs/client_server/newsfragments/2885.clarification b/changelogs/client_server/newsfragments/2885.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/client_server/newsfragments/2885.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. From aab2d587f31bc74f6f29827604036696bf61e275 Mon Sep 17 00:00:00 2001 From: Philipp Emanuel Weidmann Date: Fri, 4 Dec 2020 11:05:21 +0530 Subject: [PATCH 46/50] Fix spelling and grammar issues Signed-off-by: Philipp Emanuel Weidmann --- .../appendices/identifier_grammar.rst | 12 ++--- specification/appendices/signing_json.rst | 4 +- specification/appendices/threat_model.rst | 2 +- specification/application_service_api.rst | 6 +-- specification/client_server_api.rst | 38 ++++++++-------- specification/identity_service_api.rst | 4 +- specification/index.rst | 2 +- .../modules/end_to_end_encryption.rst | 44 +++++++++---------- specification/proposals_intro.rst | 30 ++++++------- specification/server_server_api.rst | 14 +++--- 10 files changed, 78 insertions(+), 78 deletions(-) diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index 95c22fb1..d9e56714 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -152,7 +152,7 @@ The complete grammar for a legal user ID is:: set. User IDs are primarily intended for use as an identifier at the protocol level, and their use as a human-readable handle is of secondary benefit. Furthermore, they are useful as a last-resort differentiator between - users with similar display names. Allowing the full unicode character set + users with similar display names. Allowing the full Unicode character set would make very difficult for a human to distinguish two similar user IDs. The limited character set used has the advantage that even a user unfamiliar with the Latin alphabet should be able to distinguish similar user IDs manually, if @@ -190,7 +190,7 @@ history includes events with a ``sender`` which does not conform. In order to handle these rooms successfully, clients and servers MUST accept user IDs with localparts from the expanded character set:: - extended_user_id_char = %x21-39 / %x3B-7E ; all ascii printing chars except : + extended_user_id_char = %x21-39 / %x3B-7E ; all ASCII printing chars except : Mapping from other character sets <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -251,8 +251,8 @@ risk of clashes of identifiers between different homeservers. There is no implication that the room or event in question is still available at the corresponding homeserver. -Event IDs and Room IDs are case-sensitive. They are not meant to be human -readable. They are intended to be treated as fully opaque strings by clients. +Event IDs and Room IDs are case-sensitive. They are not meant to be human-readable. +They are intended to be treated as fully opaque strings by clients. .. TODO-spec What is the grammar for the opaque part? https://matrix.org/jira/browse/SPEC-389 @@ -326,7 +326,7 @@ parameter is only used in the case of permalinks where an event ID is referenced The matrix.to URI, when referenced, must always start with ``https://matrix.to/#/`` followed by the identifier. -The ```` and the preceeding question mark are optional and +The ```` and the preceding question mark are optional and only apply in certain circumstances, documented below. Clients should not rely on matrix.to URIs falling back to a web server if accessed @@ -379,7 +379,7 @@ are picked is left as an implementation detail, however the current recommendati to pick 3 unique servers based on the following criteria: * The first server should be the server of the highest power level user in the room, - provided they are at least power level 50. If no user meets this criteria, pick the + provided they are at least power level 50. If no user meets these criteria, pick the most popular server in the room (most joined users). The rationale for not picking users with power levels under 50 is that they are unlikely to be around into the distant future while higher ranking users (and therefore servers) are less likely diff --git a/specification/appendices/signing_json.rst b/specification/appendices/signing_json.rst index fbeb0010..1bc99180 100644 --- a/specification/appendices/signing_json.rst +++ b/specification/appendices/signing_json.rst @@ -29,7 +29,7 @@ Canonical JSON ~~~~~~~~~~~~~~ We define the canonical JSON encoding for a value to be the shortest UTF-8 JSON -encoding with dictionary keys lexicographically sorted by unicode codepoint. +encoding with dictionary keys lexicographically sorted by Unicode codepoint. Numbers in the JSON must be integers in the range ``[-(2**53)+1, (2**53)-1]``. We pick UTF-8 as the encoding as it should be available to all platforms and @@ -63,7 +63,7 @@ using this representation. separators=(',',':'), # Sort the keys of dictionaries. sort_keys=True, - # Encode the resulting unicode as UTF-8 bytes. + # Encode the resulting Unicode as UTF-8 bytes. ).encode("UTF-8") Grammar diff --git a/specification/appendices/threat_model.rst b/specification/appendices/threat_model.rst index 9ad5fef8..354e9240 100644 --- a/specification/appendices/threat_model.rst +++ b/specification/appendices/threat_model.rst @@ -28,7 +28,7 @@ victim in order to: Threat: Resource Exhaustion +++++++++++++++++++++++++++ -An attacker could cause the victims server to exhaust a particular resource +An attacker could cause the victim's server to exhaust a particular resource (e.g. open TCP connections, CPU, memory, disk storage) Threat: Unrecoverable Consistency Violations diff --git a/specification/application_service_api.rst b/specification/application_service_api.rst index 302f0980..4f386171 100644 --- a/specification/application_service_api.rst +++ b/specification/application_service_api.rst @@ -194,7 +194,7 @@ Authorization Homeservers MUST include a query parameter named ``access_token`` containing the ``hs_token`` from the application service's registration when making requests to the application service. Application services MUST verify the provided ``access_token`` -matches their known ``hs_token``, failing the request with a ``M_FORBIDDEN`` error +matches their known ``hs_token``, failing the request with an ``M_FORBIDDEN`` error if it does not match. Legacy routes @@ -206,8 +206,8 @@ service specification now defines a version on all endpoints to be more compatib with the rest of the Matrix specification and the future. Homeservers should attempt to use the specified endpoints first when communicating -with application services. However, if the application service receives an http status -code that does not indicate success (ie: 404, 500, 501, etc) then the homeserver +with application services. However, if the application service receives an HTTP status +code that does not indicate success (i.e.: 404, 500, 501, etc) then the homeserver should fall back to the older endpoints for the application service. The older endpoints have the exact same request body and response format, they diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index a1f48910..8afd6d31 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -186,7 +186,7 @@ Other error codes the client might encounter are: permits, for example, email addresses from a particular domain. :``M_SERVER_NOT_TRUSTED``: - The client's request used a third party server, eg. identity server, that this server does not trust. + The client's request used a third party server, e.g. identity server, that this server does not trust. :``M_UNSUPPORTED_ROOM_VERSION``: The client's request to create a room used a room version that the server does not support. @@ -228,8 +228,8 @@ Other error codes the client might encounter are: may reach a resource limit if it starts using too much memory or disk space. The error MUST have an ``admin_contact`` field to provide the user receiving the error a place to reach out to. Typically, this error will appear on routes which attempt - to modify state (eg: sending messages, account data, etc) and not routes which only - read state (eg: ``/sync``, get account data, etc). + to modify state (e.g.: sending messages, account data, etc) and not routes which only + read state (e.g.: ``/sync``, get account data, etc). :``M_CANNOT_LEAVE_SERVER_NOTICE_ROOM``: The user is unable to reject an invite to join the server notices room. See the @@ -266,8 +266,8 @@ to pre-flight requests and supply Cross-Origin Resource Sharing (CORS) headers o all requests. Servers MUST expect that clients will approach them with ``OPTIONS`` requests, -allowing clients to discover the CORS headers. All endpoints in this specification s -upport the ``OPTIONS`` method, however the server MUST NOT perform any logic defined +allowing clients to discover the CORS headers. All endpoints in this specification +support the ``OPTIONS`` method, however the server MUST NOT perform any logic defined for the endpoints when approached with an ``OPTIONS`` request. When a client approaches the server with a request, the server should respond with @@ -438,7 +438,7 @@ homeserver may provide many different ways of authenticating, such as user/password auth, login via a single-sign-on server (SSO), etc. This specification does not define how homeservers should authorise their users but instead defines the standard interface which implementations should follow so -that ANY client can login to ANY homeserver. +that ANY client can log in to ANY homeserver. The process takes the form of one or more 'stages'. At each stage the client submits a set of data for a given authentication type and awaits a response @@ -707,7 +707,7 @@ For example, to authenticate using the user's Matrix ID, clients would submit: } Alternatively reply using a 3PID bound to the user's account on the homeserver -using the |/account/3pid|_ API rather then giving the ``user`` explicitly as +using the |/account/3pid|_ API rather than giving the ``user`` explicitly as follows: .. code:: json @@ -827,7 +827,7 @@ Dummy Auth Dummy authentication always succeeds and requires no extra parameters. Its purpose is to allow servers to not require any form of User-Interactive Authentication to perform a request. It can also be used to differentiate - flows where otherwise one flow would be a subset of another flow. eg. if + flows where otherwise one flow would be a subset of another flow. e.g. if a server offers flows ``m.login.recaptcha`` and ``m.login.recaptcha, m.login.email.identity`` and the client completes the recaptcha stage first, the auth would succeed with the former flow, even if the client was intending @@ -878,7 +878,7 @@ to be defined in an embedded browser, or to use the HTML5 `cross-document messaging `_ API, to receive a notification that the authentication stage has been completed. -Once a client receives the notificaton that the authentication stage has been +Once a client receives the notification that the authentication stage has been completed, it should resubmit the request with an auth dict with just the session ID: @@ -891,19 +891,19 @@ session ID: Example <<<<<<< -A client webapp might use the following javascript to open a popup window which will +A client webapp might use the following JavaScript to open a popup window which will handle unknown login types: .. code:: javascript /** * Arguments: - * homeserverUrl: the base url of the homeserver (eg "https://matrix.org") + * homeserverUrl: the base url of the homeserver (e.g. "https://matrix.org") * - * apiEndpoint: the API endpoint being used (eg + * apiEndpoint: the API endpoint being used (e.g. * "/_matrix/client/%CLIENT_MAJOR_VERSION%/account/password") * - * loginType: the loginType being attempted (eg "m.login.recaptcha") + * loginType: the loginType being attempted (e.g. "m.login.recaptcha") * * sessionID: the session ID given by the homeserver in earlier requests * @@ -930,7 +930,7 @@ handle unknown login types: }; request({ - method:'POST', url:apiEndpint, json:requestBody, + method:'POST', url:apiEndpoint, json:requestBody, }, onComplete); }; @@ -1044,7 +1044,7 @@ request as follows: } Alternatively, a client can use a 3PID bound to the user's account on the -homeserver using the |/account/3pid|_ API rather then giving the ``user`` +homeserver using the |/account/3pid|_ API rather than giving the ``user`` explicitly, as follows: .. code:: json @@ -1130,7 +1130,7 @@ can be proxied (bound) to the identity server in many cases. This section deals with two terms: "add" and "bind". Where "add" (or "remove") is used, it is speaking about an identifier that was not bound to an identity server. As a result, "bind" (or "unbind") references an identifier that is found - in an identity server. Note that an identifer can be added and bound at the same + in an identity server. Note that an identifier can be added and bound at the same time, depending on context. {{administrative_contact_cs_http_api}} @@ -1745,7 +1745,7 @@ same way a server does. except those protected by the redaction algorithm. For example, a redacted ``join`` event will still result in the user being considered joined. Similarly, a redacted topic does not necessarily cause the topic to revert to - what is was prior to the event - it causes the topic to be removed from the room. + what it was prior to the event - it causes the topic to be removed from the room. Events @@ -1977,9 +1977,9 @@ many places of a client's display, changes to these fields cause an automatic propagation event to occur, informing likely-interested parties of the new values. This change is conveyed using two separate mechanisms: -- a ``m.room.member`` event (with a ``join`` membership) is sent to every room +- an ``m.room.member`` event (with a ``join`` membership) is sent to every room the user is a member of, to update the ``displayname`` and ``avatar_url``. -- a ``m.presence`` presence status update is sent, again containing the new +- an ``m.presence`` presence status update is sent, again containing the new values of the ``displayname`` and ``avatar_url`` keys, in addition to the required ``presence`` key containing the current presence state of the user. diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index 704f763e..b2446381 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -225,7 +225,7 @@ Terms of service Identity Servers are encouraged to have terms of service (or similar policies) to ensure that users have agreed to their data being processed by the server. To facilitate -this, an identity server can respond to almost any authenticated API endpoint with a +this, an identity server can respond to almost any authenticated API endpoint with an HTTP 403 and the error code ``M_TERMS_NOT_SIGNED``. The error code is used to indicate that the user must accept new terms of service before being able to continue. @@ -421,7 +421,7 @@ i.e. I can claim that any email address I own is associated with Sessions are time-limited; a session is considered to have been modified when it was created, and then when a validation is performed within it. A session can only be checked for validation, and validation can only be performed within a -session, within a 24 hour period since its most recent modification. Any +session, within a 24-hour period since its most recent modification. Any attempts to perform these actions after the expiry will be rejected, and a new session should be created and used instead. diff --git a/specification/index.rst b/specification/index.rst index 4c256fc3..276ee8b2 100644 --- a/specification/index.rst +++ b/specification/index.rst @@ -431,7 +431,7 @@ Profiles ~~~~~~~~ Users may publish arbitrary key/value data associated with their account - such -as a human readable display name, a profile photo URL, contact information +as a human-readable display name, a profile photo URL, contact information (email address, phone numbers, website URLs etc). .. TODO diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index be66897b..6aa5eb1b 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -83,7 +83,7 @@ Base64`_. Example: "JGLn/yafz74HB2AbPLYJWIVGnKAtqECOBf11yyXac2Y" The name ``signed_curve25519`` also corresponds to the Curve25519 algorithm, -but a key using this algorithm is represented by an object with a the following +but a key using this algorithm is represented by an object with the following properties: ``KeyObject`` @@ -431,7 +431,7 @@ Device verification may reach one of several conclusions. For example: Key verification framework ~~~~~~~~~~~~~~~~~~~~~~~~~~ -Verifying keys manually by reading out the Ed25519 key is not very user friendly, +Verifying keys manually by reading out the Ed25519 key is not very user-friendly, and can lead to errors. In order to help mitigate errors, and to make the process easier for users, some verification methods are supported by the specification. The methods all use a common framework for negotiating the key verification. @@ -443,7 +443,7 @@ allows Bob to reject the request on one device, and have it apply to all of his devices. Similarly, it allows Bob to process the verification on one device without having to involve all of his devices. -When Bob's device receives a ``m.key.verification.request``, it should prompt Bob +When Bob's device receives an ``m.key.verification.request``, it should prompt Bob to verify keys with Alice using one of the supported methods in the request. If Bob's device does not understand any of the methods, it should not cancel the request as one of his other devices may support the request. Instead, Bob's device should @@ -454,17 +454,17 @@ minutes after Bob's client receives the message, whichever comes first, if Bob does not interact with the prompt. The prompt should additionally be hidden if an appropriate ``m.key.verification.cancel`` message is received. -If Bob rejects the request, Bob's client must send a ``m.key.verification.cancel`` +If Bob rejects the request, Bob's client must send an ``m.key.verification.cancel`` message to Alice's device. Upon receipt, Alice's device should tell her that Bob does not want to verify her device and send ``m.key.verification.cancel`` messages to all of Bob's devices to notify them that the request was rejected. If Bob accepts the request, Bob's device starts the key verification process by -sending a ``m.key.verification.start`` message to Alice's device. Upon receipt -of this message, Alice's device should send a ``m.key.verification.cancel`` message +sending an ``m.key.verification.start`` message to Alice's device. Upon receipt +of this message, Alice's device should send an ``m.key.verification.cancel`` message to all of Bob's other devices to indicate the process has been started. The start message must use the same ``transaction_id`` from the original key verification -request if it is in response to the request. The start message can be sent indepdently +request if it is in response to the request. The start message can be sent independently of any request. Individual verification methods may add additional steps, events, and properties to @@ -473,7 +473,7 @@ be under the ``m.key.verification`` namespace and any other event types must be according to the Java package naming convention. Any of Alice's or Bob's devices can cancel the key verification request or process -at any time with a ``m.key.verification.cancel`` message to all applicable devices. +at any time with an ``m.key.verification.cancel`` message to all applicable devices. This framework yields the following handshake, assuming both Alice and Bob each have 2 devices, Bob's first device accepts the key verification request, and Alice's second @@ -516,7 +516,7 @@ Short Authentication String (SAS) verification SAS verification is a user-friendly key verification process built off the common framework outlined above. SAS verification is intended to be a highly interactive -process for users, and as such exposes verfiication methods which are easier for +process for users, and as such exposes verification methods which are easier for users to use. The verification process is heavily inspired by Phil Zimmermann's ZRTP key agreement @@ -553,17 +553,17 @@ The process between Alice and Bob verifying each other would be: #. Alice and Bob communicate which devices they'd like to verify with each other. #. Alice selects Bob's device from the device list and begins verification. #. Alice's client ensures it has a copy of Bob's device key. -#. Alice's device sends Bob's device a ``m.key.verification.start`` message. +#. Alice's device sends Bob's device an ``m.key.verification.start`` message. #. Bob's device receives the message and selects a key agreement protocol, hash algorithm, message authentication code, and SAS method supported by Alice's device. #. Bob's device ensures it has a copy of Alice's device key. #. Bob's device creates an ephemeral Curve25519 key pair (|BobCurve25519|), and calculates the hash (using the chosen algorithm) of the public key |BobPublicKey|. -#. Bob's device replies to Alice's device with a ``m.key.verification.accept`` message. +#. Bob's device replies to Alice's device with an ``m.key.verification.accept`` message. #. Alice's device receives Bob's message and stores the commitment hash for later use. #. Alice's device creates an ephemeral Curve25519 key pair (|AliceCurve25519|) and - replies to Bob's device with a ``m.key.verification.key``, sending only the public + replies to Bob's device with an ``m.key.verification.key``, sending only the public key |AlicePublicKey|. #. Bob's device receives Alice's message and replies with its own ``m.key.verification.key`` message containing its public key |BobPublicKey|. @@ -578,11 +578,11 @@ The process between Alice and Bob verifying each other would be: #. Alice and Bob compare the strings shown by their devices, and tell their devices if they match or not. #. Assuming they match, Alice and Bob's devices calculate the HMAC of their own device keys - and a comma-separated sorted list of of the key IDs that they wish the other user + and a comma-separated sorted list of the key IDs that they wish the other user to verify, using SHA-256 as the hash function. HMAC is defined in `RFC 2104 `_. The key for the HMAC is different for each item and is calculated by generating 32 bytes (256 bits) using `the key verification HKDF <#sas-hkdf>`_. -#. Alice's device sends Bob's device a ``m.key.verification.mac`` message containing the +#. Alice's device sends Bob's device an ``m.key.verification.mac`` message containing the MAC of Alice's device keys and the MAC of her key IDs to be verified. Bob's device does the same for Bob's device keys and key IDs concurrently with Alice. #. When the other device receives the ``m.key.verification.mac`` message, the device @@ -619,20 +619,20 @@ The wire protocol looks like the following between Alice and Bob's devices:: Error and exception handling <<<<<<<<<<<<<<<<<<<<<<<<<<<< -At any point the interactive verfication can go wrong. The following describes what +At any point the interactive verification can go wrong. The following describes what to do when an error happens: -* Alice or Bob can cancel the verification at any time. A ``m.key.verification.cancel`` +* Alice or Bob can cancel the verification at any time. An ``m.key.verification.cancel`` message must be sent to signify the cancellation. * The verification can time out. Clients should time out a verification that does not complete within 10 minutes. Additionally, clients should expire a ``transaction_id`` which goes unused for 10 minutes after having last sent/received it. The client should inform the user that the verification timed out, and send an appropriate ``m.key.verification.cancel`` message to the other device. -* When the same device attempts to intiate multiple verification attempts, the receipient +* When the same device attempts to initiate multiple verification attempts, the recipient should cancel all attempts with that device. * When a device receives an unknown ``transaction_id``, it should send an appropriate - ``m.key.verfication.cancel`` message to the other device indicating as such. This + ``m.key.verification.cancel`` message to the other device indicating as such. This does not apply for inbound ``m.key.verification.start`` or ``m.key.verification.cancel`` messages. * If the two devices do not share a common key share, hash, HMAC, or SAS method then @@ -1169,7 +1169,7 @@ session has become corrupted and create a new one to replace it. to decrypt it successfully. Olm does not have a way to recover from the failure, making this session replacement process required. -To establish a new session, the client sends a `m.dummy <#m-dummy>`_ to-device event +To establish a new session, the client sends an `m.dummy <#m-dummy>`_ to-device event to the other party to notify them of the new session details. Clients should rate-limit the number of sessions it creates per device that it receives @@ -1232,13 +1232,13 @@ who sent the message. The same reasoning applies, but the sender ed25519 key has inferred from the ``keys.ed25519`` property of the event which established the Megolm session. -In order to enable end-to-end encryption in a room, clients can send a +In order to enable end-to-end encryption in a room, clients can send an ``m.room.encryption`` state event specifying ``m.megolm.v1.aes-sha2`` as its ``algorithm`` property. When creating a Megolm session in a room, clients must share the corresponding session key using Olm with the intended recipients, so that they can decrypt future messages -encrypted using this session. A ``m.room_key`` event is used to do this. Clients +encrypted using this session. An ``m.room_key`` event is used to do this. Clients must also handle ``m.room_key`` events sent by other devices in order to decrypt their messages. @@ -1275,7 +1275,7 @@ Extensions to /sync This module adds an optional ``device_lists`` property to the |/sync|_ response, as specified below. The server need only populate this property for -an incremental ``/sync`` (ie, one where the ``since`` parameter was +an incremental ``/sync`` (i.e., one where the ``since`` parameter was specified). The client is expected to use |/keys/query|_ or |/keys/changes|_ for the equivalent functionality after an initial sync, as documented in `Tracking the device list for a user`_. diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index 6d8dc8a9..a54f7bca 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -132,7 +132,7 @@ As a worked example: 1. Video conferencing is clearly a feature which would benefit the whole ecosystem, and so the spec should find a way to make it happen. 2. Video conferencing can be achieved by widgets without requiring any - compulsory changes to changes to clients nor servers to work, and so could be + compulsory changes to clients nor servers to work, and so could be omitted from the spec. 3. A better experience could be achieved by embedding Jitsi natively into clients rather than using a widget... @@ -145,10 +145,10 @@ for doing so), or to keep it as a widget-based approach (optionally with widget extensions specific for more deeply integrating video conferencing use cases). As an alternative example: it's very unlikely that "how to visualise Magnetic -Resonsance Imaging data over Matrix" would ever be added to the Matrix spec +Resonance Imaging data over Matrix" would ever be added to the Matrix spec (other than perhaps a custom event type in a wider standardised Matrix event registry) given that the spec's existing primitives of file transfer and -extensible events (MSC1767) give excellent tools for transfering and +extensible events (MSC1767) give excellent tools for transferring and visualising arbitrary rich data. Supporting public search engines are likely to not require custom spec features @@ -168,7 +168,7 @@ Process The process for submitting a Matrix Spec Change (MSC) Proposal in detail is as follows: -- Create a first draft of your proposal using `GitHub-flavored markdown +- Create a first draft of your proposal using `GitHub-flavored Markdown `_ - In the document, clearly state the problem being solved, and the possible @@ -190,7 +190,7 @@ follows: - The proposal must live in the ``proposals/`` directory with a filename that follows the format ``1234-my-new-proposal.md`` where ``1234`` is the MSC ID. - - Your PR description must include a link to the rendered markdown document + - Your PR description must include a link to the rendered Markdown document and a summary of the proposal. - It is often very helpful to link any related MSCs or `matrix-doc issues `_ to give context @@ -209,10 +209,10 @@ follows: If preferred, an alternative room can be created and advertised in #matrix-spec:matrix.org. Please also link to the room in your PR description. - - For additional discussion areas, know that that #matrix-dev:matrix.org is + - For additional discussion areas, know that #matrix-dev:matrix.org is for developers using existing Matrix APIs, #matrix:matrix.org is for users trying to run Matrix apps (clients & servers) and - #matrix-architecture:matrix.org is for cross-cutting discussion of matrix's + #matrix-architecture:matrix.org is for cross-cutting discussion of Matrix's architectural design. - The point of the spec proposal process is to be collaborative rather than competitive, and to try to solve the problem in question with the optimal @@ -239,7 +239,7 @@ follows: the current state of the discussion, along with reasoning for its occurrence. - A concern can be raised by a Spec Core Team member at any time, which will block an FCP from beginning. An FCP will only begin when 75% of the members of the - Spec Core Team team agree on its outcome, and all existing concerns have been + Spec Core Team agree on its outcome, and all existing concerns have been resolved. - The FCP will then begin and last for 5 days, giving anyone else some time to speak up before it concludes. On its conclusion, the disposition of the FCP @@ -332,7 +332,7 @@ Proposal Drafting and Feedback N/A A proposal docum Proposal In Review proposal-in-review A proposal document which is now ready and waiting for review by the Spec Core Team and community Proposed Final Comment Period proposed-final-comment-period Currently awaiting signoff of a 75% majority of team members in order to enter the final comment period Final Comment Period final-comment-period A proposal document which has reached final comment period either for merge, closure or postponement -Final Commment Period Complete finished-final-comment-period The final comment period has been completed. Waiting for a demonstration implementation +Final Comment Period Complete finished-final-comment-period The final comment period has been completed. Waiting for a demonstration implementation Spec PR Missing spec-pr-missing The proposal has been agreed, and proven with a demonstration implementation. Waiting for a PR against the Spec Spec PR In Review spec-pr-in-review The spec PR has been written, and is currently under review Spec PR Merged merged A proposal with a sufficient working implementation and whose Spec PR has been merged! @@ -352,7 +352,7 @@ an effort to pull MSCs out of that category when possible. The current categories are: ============ ================= ====================================== -Name Github Label Description +Name GitHub Label Description ============ ================= ====================================== Core kind:core Important for the protocol's success. Feature kind:feature Nice to have additions to the spec. @@ -379,10 +379,10 @@ As part of the proposal process the spec core team will require evidence of the working in order for it to move into FCP. This can usually be a branch/pull request to whichever implementation of choice that proves the MSC works in practice, though in some cases the MSC itself will be small enough to be considered proven. Where it's -unclear if a MSC will require an implementation proof, ask in `#matrix-spec:matrix.org +unclear if an MSC will require an implementation proof, ask in `#matrix-spec:matrix.org `_. -Early release of a MSC/idea +Early release of an MSC/idea ~~~~~~~~~~~~~~~~~~~~~~~~~~~ To help facilitate early releases of software dependent on a spec release, implementations @@ -447,7 +447,7 @@ is not cluttered with development or testing data. .. Note:: MSCs MUST still describe what the stable endpoints/feature looks like with a note towards the bottom for what the unstable feature flag/prefixes are. For example, - a MSC would propose `/_matrix/client/r0/new/endpoint`, not `/_matrix/client/unstable/ + an MSC would propose `/_matrix/client/r0/new/endpoint`, not `/_matrix/client/unstable/ com.example/new/endpoint`. In summary: @@ -488,7 +488,7 @@ resolve to the desired MSC, whether it started as an issue or a PR. Other metadata: - The MSC number is taken from the GitHub Pull Request ID. This is carried for - the lifetime of the proposal. These IDs do not necessary represent a + the lifetime of the proposal. These IDs do not necessarily represent a chronological order. - The GitHub PR title will act as the MSC's title. - Please link to the spec PR (if any) by adding a "PRs: #1234" line in the @@ -496,7 +496,7 @@ Other metadata: - The creation date is taken from the GitHub PR, but can be overridden by adding a "Date: yyyy-mm-dd" line in the PR description. - Updated Date is taken from GitHub. -- Author is the creator of the MSC PR, but can be overridden by adding a +- Author is the creator of the MSC PR, but can be overridden by adding an "Author: @username" line in the body of the issue description. Please make sure @username is a GitHub user (include the @!) - A shepherd can be assigned by adding a "Shepherd: @username" line in the diff --git a/specification/server_server_api.rst b/specification/server_server_api.rst index 9deb267c..5b143dbd 100644 --- a/specification/server_server_api.rst +++ b/specification/server_server_api.rst @@ -731,7 +731,7 @@ In summary, the remote join handshake consists of the joining server querying the directory server for information about the room alias; receiving a room ID and a list of join candidates. The joining server then requests information about the room from one of the residents. It uses this information to construct -a ``m.room.member`` event which it finally sends to a resident server. +an ``m.room.member`` event which it finally sends to a resident server. Conceptually these are three different roles of homeserver. In practice the directory server is likely to be resident in the room, and so may be selected @@ -822,7 +822,7 @@ Similar to the `Joining Rooms`_ handshake, the server which wishes to leave the room starts with sending a ``/make_leave`` request to a resident server. In the case of rejecting invites, the resident server may be the server which sent the invite. After receiving a template event from ``/make_leave``, the leaving server -signs the event and replaces the ``event_id`` with it's own. This is then sent to +signs the event and replaces the ``event_id`` with its own. This is then sent to the resident server via ``/send_leave``. The resident server will then send the event to other servers in the room. @@ -837,7 +837,7 @@ Third-party invites More information about third party invites is available in the `Client-Server API`_ under the Third Party Invites module. -When an user wants to invite another user in a room but doesn't know the Matrix +When a user wants to invite another user in a room but doesn't know the Matrix ID to invite, they can do so using a third-party identifier (e.g. an e-mail or a phone number). @@ -856,7 +856,7 @@ Cases where an association doesn't exist for a third-party identifier If the third-party identifier isn't bound to any Matrix ID, the inviting homeserver will request the identity server to store an invite for this identifier -and to deliver it to whoever binds it to its Matrix ID. It will also send a +and to deliver it to whoever binds it to its Matrix ID. It will also send an ``m.room.third_party_invite`` event in the room to specify a display name, a token and public keys the identity server provided as a response to the invite storage request. @@ -867,7 +867,7 @@ in the `Invitation Storage`_ section of the Identity Service API. The following process applies for each invite sent by the identity server: -The invited homeserver will create a ``m.room.member`` invite event containing +The invited homeserver will create an ``m.room.member`` invite event containing a special ``third_party_invite`` section containing the token and a signed object, both provided by the identity server. @@ -882,7 +882,7 @@ will need to request the room's homeserver to auth the event. Verifying the invite ++++++++++++++++++++ -When a homeserver receives a ``m.room.member`` invite event for a room it's in +When a homeserver receives an ``m.room.member`` invite event for a room it's in with a ``third_party_invite`` object, it must verify that the association between the third-party identifier initially invited to the room and the Matrix ID that claims to be bound to it has been verified without having to rely on a third-party @@ -949,7 +949,7 @@ Receipts are EDUs used to communicate a marker for a given event. Currently the only kind of receipt supported is a "read receipt", or where in the event graph the user has read up to. -Read receipts for events events that a user sent do not need to be sent. It is +Read receipts for events that a user sent do not need to be sent. It is implied that by sending the event the user has read up to the event. {{definition_ss_event_schemas_m_receipt}} From 942e8b36e4eafa550c6f699cbffcc37dce380a63 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 4 Dec 2020 10:38:14 -0700 Subject: [PATCH 47/50] Convert to markdown verbatim --- proposals/1337-improve-membership.md | 155 +++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 proposals/1337-improve-membership.md diff --git a/proposals/1337-improve-membership.md b/proposals/1337-improve-membership.md new file mode 100644 index 00000000..52047feb --- /dev/null +++ b/proposals/1337-improve-membership.md @@ -0,0 +1,155 @@ +# Improving the way membership lists are queried + +## Problem scope + +A common operation for bots, bridges, scripts, and clients is to determine what rooms the user is a +member of and who the members of those rooms are. Although possible with the current specification, +the API can be improved to provide more granular and simplified access to this information. + +The affected routes are: + +* `GET /_matrix/client/r0/rooms/{roomId}/members` +* `GET /_matrix/client/r0/rooms/{roomId}/joined_members` +* `GET /_matrix/client/r0/joined_rooms` + +This proposal aims to resolve [matrix-doc#1123](https://github.com/matrix-org/matrix-doc/issues/1123). + +## Background + +The `/joined_members` and `/joined_rooms` endpoints were originally added in [synapse#1680](https://github.com/matrix-org/synapse/pull/1680) +during a time when the IRC bridge on matrix.org was under extreme load. The endpoints were fully +intended to alleviate load by having the bridge do less work and have the server doing more. + +## Proposal + +This proposal calls for both `/joined_members` and `/joined_rooms` to be deprecated. The +deprecation is to be coupled with improving how `/members` works and introducing a new `/rooms` +endpoint, which will work in a very similar way to the updated `/members` endpoint. Both endpoints +are proposed to get some way to filter based upon membership, as outlined in the options below. + +### Option 1: Query string + +A new query parameter, `membership`, should be added to the `/members` endpoint. The parameter +filters the membership list of the room such that only members with a matching `membership` are +returned. The parameter can be supplied multiple times to filter on multiple membership states. For +example, the request could be `/members?membership=join&membership=invite` to get all invited and +joined members for the room. If no `membership` parameter is specified, the default is to return +all members of the room regardless of membership state. + +To compliment the `/members` endpoint, a new endpoint should be added to query the rooms for the +user. This uses the same style of using a membership query parameter to filter the rooms. + +Some examples of using this endpoint are below. The `rooms` field is an object where the key is a +room ID and the value is information about that room, currently storing a single `membership` +field. The value is an object to support future expansion of this API. + +```json5 +// GET /_matrix/client/r0/rooms?membership=join&membership=invite +{ + "rooms": { + "!somewhere:domain.com": { + "membership": "join" + }, + "!elsewhere:matrix.org": { + "membership": "invite" + } + } +} +``` + +```json5 +// GET /_matrix/client/r0/rooms?membership=ban +{ + "rooms": { + "!plzno:domain.com": { + "membership": "ban" + } + } +} +``` + +```json5 +// GET /_matrix/client/r0/rooms +{ + "rooms": { + "!somewhere:domain.com": { + "membership": "join" + }, + "!elsewhere:matrix.org": { + "membership": "invite" + }, + "!plzno:domain.com": { + "membership": "ban" + }, + "!curbaf:domain.com": { + "membership": "leave" + } + } +} +``` + +### Option 2: Filter + +As with Option 1, a new endpoint would be added to handle getting the list of rooms. However, instead of both `/members` and `/rooms` taking a query parameter for membership they would instead take a filter (re-using existing matrix concepts). Similar to how `/messages` works, this filter would be a `RoomEventFilter` instead of having all the available options. Additionally, the filter would support a `membership` field to filter based upon membership. + +An example filter for getting members/rooms of membership `invite` or `join` would be: + +```json5 +{ + "limit": 5, // The maximum number of items to return. Defaults to no limit. + + // These only apply when fetching members in a room + "senders": ["*"], + "not_senders": [], + + // These only apply when fetching rooms + "rooms": ["*"], + "not_rooms": [], + + // NEW! Filter based upon the given membership values. + "membership": ["join", "invite"], + + // These are copied from the RoomEventFilter schema, but are ignored + "types": [], + "not_types": [], + "contains_url": true, +} +``` + +### Option 3: Even more filters + +Expanding on Option 2, we give `/state` the option of a filter (also from Option 2). This would +require the `types` to be useful, and we could potentially deprecate the `/members` endpoint +entirely with this approach. + +Likewise, `/context` should take a similar filter so clients can get members at a given point in +history. + +## Alternative solutions + +### Using ?membership=join,invite or ?membership=join+invite instead + +The arguments in favour of this approach are: + +* It doesn’t rely on undefined behaviour in RFC3986 +* Using multiple keys in the query string hasn’t been done before in the matrix spec + +The arguments against this approach are: + +* It’s not as pretty and may require hex encoding +* It adds unnecessary complexity given most query string parsers are capable of handling multiple + keys in the query string. It is additional complexity because implementations would now need to + do string splitting instead of relying on their already-in-use parsing libraries + +### Encoding ?membership as a JSON value + +The arguments in favour of this approach are: + +* The filtering API already does this +* It doesn’t rely on undefined behaviour in RFC3986 + +The arguments against this approach are: + +* It’s not as pretty and requires hex encoding +* Implementations would be forced to perform decoding, adding additional complexity (see the con + for comma-separated values) From 734be5165bd9ddddf1d5d86e6fdf55a93800e561 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 4 Dec 2020 14:46:11 -0700 Subject: [PATCH 48/50] Apply suggestions from code review Co-authored-by: Kitsune Ral --- specification/appendices/identifier_grammar.rst | 2 +- specification/proposals_intro.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/appendices/identifier_grammar.rst b/specification/appendices/identifier_grammar.rst index d9e56714..f8b2aef5 100644 --- a/specification/appendices/identifier_grammar.rst +++ b/specification/appendices/identifier_grammar.rst @@ -379,7 +379,7 @@ are picked is left as an implementation detail, however the current recommendati to pick 3 unique servers based on the following criteria: * The first server should be the server of the highest power level user in the room, - provided they are at least power level 50. If no user meets these criteria, pick the + provided they are at least power level 50. If no user meets this criterion, pick the most popular server in the room (most joined users). The rationale for not picking users with power levels under 50 is that they are unlikely to be around into the distant future while higher ranking users (and therefore servers) are less likely diff --git a/specification/proposals_intro.rst b/specification/proposals_intro.rst index a54f7bca..4749457b 100644 --- a/specification/proposals_intro.rst +++ b/specification/proposals_intro.rst @@ -383,7 +383,7 @@ unclear if an MSC will require an implementation proof, ask in `#matrix-spec:mat `_. Early release of an MSC/idea -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To help facilitate early releases of software dependent on a spec release, implementations are required to use the following process to ensure that the official Matrix namespace From e659572183075f193d113725f494b66263348c61 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 7 Dec 2020 14:32:58 -0700 Subject: [PATCH 49/50] Add changelogs for 2888 --- changelogs/application_service/newsfragments/2888.clarification | 1 + changelogs/client_server/newsfragments/2888.clarification | 1 + changelogs/identity_service/newsfragments/2888.clarification | 1 + changelogs/server_server/newsfragments/2888.clarification | 1 + 4 files changed, 4 insertions(+) create mode 100644 changelogs/application_service/newsfragments/2888.clarification create mode 100644 changelogs/client_server/newsfragments/2888.clarification create mode 100644 changelogs/identity_service/newsfragments/2888.clarification create mode 100644 changelogs/server_server/newsfragments/2888.clarification diff --git a/changelogs/application_service/newsfragments/2888.clarification b/changelogs/application_service/newsfragments/2888.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/application_service/newsfragments/2888.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. diff --git a/changelogs/client_server/newsfragments/2888.clarification b/changelogs/client_server/newsfragments/2888.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/client_server/newsfragments/2888.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. diff --git a/changelogs/identity_service/newsfragments/2888.clarification b/changelogs/identity_service/newsfragments/2888.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/identity_service/newsfragments/2888.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. diff --git a/changelogs/server_server/newsfragments/2888.clarification b/changelogs/server_server/newsfragments/2888.clarification new file mode 100644 index 00000000..3ccb2333 --- /dev/null +++ b/changelogs/server_server/newsfragments/2888.clarification @@ -0,0 +1 @@ +Fix various typos throughout the specification. From 6ccc5489126c9e19ed471a0a209f1885e0edd1d4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 7 Dec 2020 14:31:26 -0700 Subject: [PATCH 50/50] Revert "Merge branch 'travis/msc/1337-joined-rooms'" This reverts commit 0961c7b0f76de64977e6fcf02f536a64dbc0e8c1. --- proposals/1337-improve-membership.md | 155 --------------------------- 1 file changed, 155 deletions(-) delete mode 100644 proposals/1337-improve-membership.md diff --git a/proposals/1337-improve-membership.md b/proposals/1337-improve-membership.md deleted file mode 100644 index 52047feb..00000000 --- a/proposals/1337-improve-membership.md +++ /dev/null @@ -1,155 +0,0 @@ -# Improving the way membership lists are queried - -## Problem scope - -A common operation for bots, bridges, scripts, and clients is to determine what rooms the user is a -member of and who the members of those rooms are. Although possible with the current specification, -the API can be improved to provide more granular and simplified access to this information. - -The affected routes are: - -* `GET /_matrix/client/r0/rooms/{roomId}/members` -* `GET /_matrix/client/r0/rooms/{roomId}/joined_members` -* `GET /_matrix/client/r0/joined_rooms` - -This proposal aims to resolve [matrix-doc#1123](https://github.com/matrix-org/matrix-doc/issues/1123). - -## Background - -The `/joined_members` and `/joined_rooms` endpoints were originally added in [synapse#1680](https://github.com/matrix-org/synapse/pull/1680) -during a time when the IRC bridge on matrix.org was under extreme load. The endpoints were fully -intended to alleviate load by having the bridge do less work and have the server doing more. - -## Proposal - -This proposal calls for both `/joined_members` and `/joined_rooms` to be deprecated. The -deprecation is to be coupled with improving how `/members` works and introducing a new `/rooms` -endpoint, which will work in a very similar way to the updated `/members` endpoint. Both endpoints -are proposed to get some way to filter based upon membership, as outlined in the options below. - -### Option 1: Query string - -A new query parameter, `membership`, should be added to the `/members` endpoint. The parameter -filters the membership list of the room such that only members with a matching `membership` are -returned. The parameter can be supplied multiple times to filter on multiple membership states. For -example, the request could be `/members?membership=join&membership=invite` to get all invited and -joined members for the room. If no `membership` parameter is specified, the default is to return -all members of the room regardless of membership state. - -To compliment the `/members` endpoint, a new endpoint should be added to query the rooms for the -user. This uses the same style of using a membership query parameter to filter the rooms. - -Some examples of using this endpoint are below. The `rooms` field is an object where the key is a -room ID and the value is information about that room, currently storing a single `membership` -field. The value is an object to support future expansion of this API. - -```json5 -// GET /_matrix/client/r0/rooms?membership=join&membership=invite -{ - "rooms": { - "!somewhere:domain.com": { - "membership": "join" - }, - "!elsewhere:matrix.org": { - "membership": "invite" - } - } -} -``` - -```json5 -// GET /_matrix/client/r0/rooms?membership=ban -{ - "rooms": { - "!plzno:domain.com": { - "membership": "ban" - } - } -} -``` - -```json5 -// GET /_matrix/client/r0/rooms -{ - "rooms": { - "!somewhere:domain.com": { - "membership": "join" - }, - "!elsewhere:matrix.org": { - "membership": "invite" - }, - "!plzno:domain.com": { - "membership": "ban" - }, - "!curbaf:domain.com": { - "membership": "leave" - } - } -} -``` - -### Option 2: Filter - -As with Option 1, a new endpoint would be added to handle getting the list of rooms. However, instead of both `/members` and `/rooms` taking a query parameter for membership they would instead take a filter (re-using existing matrix concepts). Similar to how `/messages` works, this filter would be a `RoomEventFilter` instead of having all the available options. Additionally, the filter would support a `membership` field to filter based upon membership. - -An example filter for getting members/rooms of membership `invite` or `join` would be: - -```json5 -{ - "limit": 5, // The maximum number of items to return. Defaults to no limit. - - // These only apply when fetching members in a room - "senders": ["*"], - "not_senders": [], - - // These only apply when fetching rooms - "rooms": ["*"], - "not_rooms": [], - - // NEW! Filter based upon the given membership values. - "membership": ["join", "invite"], - - // These are copied from the RoomEventFilter schema, but are ignored - "types": [], - "not_types": [], - "contains_url": true, -} -``` - -### Option 3: Even more filters - -Expanding on Option 2, we give `/state` the option of a filter (also from Option 2). This would -require the `types` to be useful, and we could potentially deprecate the `/members` endpoint -entirely with this approach. - -Likewise, `/context` should take a similar filter so clients can get members at a given point in -history. - -## Alternative solutions - -### Using ?membership=join,invite or ?membership=join+invite instead - -The arguments in favour of this approach are: - -* It doesn’t rely on undefined behaviour in RFC3986 -* Using multiple keys in the query string hasn’t been done before in the matrix spec - -The arguments against this approach are: - -* It’s not as pretty and may require hex encoding -* It adds unnecessary complexity given most query string parsers are capable of handling multiple - keys in the query string. It is additional complexity because implementations would now need to - do string splitting instead of relying on their already-in-use parsing libraries - -### Encoding ?membership as a JSON value - -The arguments in favour of this approach are: - -* The filtering API already does this -* It doesn’t rely on undefined behaviour in RFC3986 - -The arguments against this approach are: - -* It’s not as pretty and requires hex encoding -* Implementations would be forced to perform decoding, adding additional complexity (see the con - for comma-separated values)