From ec05d1af7e9423e65ccfabb760350d62ef708c77 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 31 Dec 2021 17:02:33 -0700 Subject: [PATCH 1/7] Specify fallback keys MSC: https://github.com/matrix-org/matrix-doc/pull/2732 --- .../modules/end_to_end_encryption.md | 50 +++++++++++++++++-- data/api/client-server/keys.yaml | 37 ++++++++++++++ 2 files changed, 82 insertions(+), 5 deletions(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 7056a1b9f4e..fa7b6f190de 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -118,9 +118,13 @@ must include the public part of the device's Ed25519 key, and must be signed by that key, as described in [Signing JSON](/appendices/#signing-json). -One-time keys are also uploaded to the homeserver using the +One-time and fallback keys are also uploaded to the homeserver using the [`/keys/upload`](/client-server-api/#post_matrixclientv3keysupload) API. +{{% added-in v="1.2" %}} Fallback keys are simply one-time keys which get +used when the device has run out of one-time keys. They are not consumed +once used, but should be replaced when additional one-time keys are uploaded. + Devices must store the private part of each key they upload. They can discard the private part of a one-time key when they receive a message using that key. However it's possible that a one-time key given out by a @@ -129,6 +133,24 @@ never know that it can discard the key. Therefore a device could end up trying to store too many private keys. A device that is trying to store too many private keys may discard keys starting with the oldest. +{{% boxes/warning %}} +Fallback keys are used to prevent one-time key exhaustion when devices +are offline/unable to upload additional keys, though can also be used +to initiate replay attacks. +{{% /boxes/warning %}} + +{{% boxes/warning %}} +Clients should not store the private half of fallback keys indefinitely +to avoid situations where attackers can decrypt past messages sent using +that fallback key. + +Instead, clients should keep the private keys for at most 2 fallback keys: +the current, unused, fallback key and the key immediately preceding it. +Once the client is reasonably certain it has received all messages that +used the old fallback key, such as after an hour since the last message, +it should remove that fallback key. +{{% /boxes/warning %}} + ##### Tracking the device list for a user Before Alice can send an encrypted message to Bob, she needs a list of @@ -345,6 +367,11 @@ A homeserver should rate-limit the number of one-time keys that a given user or remote server can claim. A homeserver should discard the public part of a one time key once it has given that key to another user. +{{% added-in v="1.2" %}} If the device has run out of one-time keys which +can be claimed, the homeserver will return the fallback key (if one was +uploaded). Fallback keys are not deleted once used and should be replaced +by the device when they are able to upload more one-time keys. + #### Device verification Before Alice sends Bob encrypted data, or trusts data received from him, @@ -1604,10 +1631,23 @@ It also adds a `one_time_keys_count` property. Note the spelling difference with the `one_time_key_counts` property in the [`/keys/upload`](/client-server-api/#post_matrixclientv3keysupload) response. -| Parameter | Type | Description | -|----------------------------|--------------------|------------------------------------------------------------------------------------------------------------------------| -| device_lists | DeviceLists | Optional. Information on e2e device updates. Note: only present on an incremental sync. | -| device_one_time_keys_count | {string: integer} | Optional. For each key algorithm, the number of unclaimed one-time keys currently held on the server for this device. | + +{{% added-in v="1.2" %}} Finally, a `device_unused_fallback_key_types` property +is added to list the key algorithms which *have not* been used in a +[`/keys/claim`](/client-server-api/#post_matrixclientv3keysclaim) response. +When a previously uploaded fallback key's algorithm is missing from this +list, the device should upload a replacement key alongside any necessary +one-time keys to avoid the fallback key's further usage. This property +is required for inclusion, though previous versions of the specification +did not have it. In addition to `/versions`, this can be a way to identify +the server's support for fallback keys. + + +| Parameter | Type | Description | +|----------------------------------|--------------------|------------------------------------------------------------------------------------------------------------------------| +| device_lists | DeviceLists | Optional. Information on e2e device updates. Note: only present on an incremental sync. | +| device_one_time_keys_count | {string: integer} | Optional. For each key algorithm, the number of unclaimed one-time keys currently held on the server for this device. | +| device_unused_fallback_key_types | [string] | **Required.** The unused fallback key algorithms. | `DeviceLists` diff --git a/data/api/client-server/keys.yaml b/data/api/client-server/keys.yaml index 65782362fff..06d6f0162f9 100644 --- a/data/api/client-server/keys.yaml +++ b/data/api/client-server/keys.yaml @@ -100,6 +100,40 @@ paths: } } } + fallback_keys: + type: object + x-addedInMatrixVersion: "1.2" + description: |- + The public key which should be used if the device's one-time keys + are exhausted. The fallback key is not deleted once used, but should + be replaced when additional one-time keys are being uploaded. The + server will notify the client of the fallback key being used through + `/sync`. + + There can only be at most one key per algorithm uploaded, and the server + will only persist one key per algorithm. + + When uploading a signed key, an additional `fallback: true` key should + be included to denote that the key is a fallback key. + + May be absent if a new fallback key is not required. + additionalProperties: + type: + - string + - object + # XXX: We can't define an actual object here - see OTKs. + example: { + "curve25519:AAAAAG": "/qyvZvwjiTxGdGU0RCguDCLeR+nmsb3FfNG3/Ve4vU8", + "signed_curve25519:AAAAGj": { + "key": "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs", + "fallback": true, + "signatures": { + "@alice:example.com": { + "ed25519:JLAFKJWSCS": "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw" + } + } + } + } responses: 200: description: @@ -378,6 +412,9 @@ paths: See the [key algorithms](/client-server-api/#key-algorithms) section for information on the Key Object format. + + If necessary, the claimed key might be a fallback key. Fallback + keys are re-used by the server until replaced by the device. additionalProperties: type: object additionalProperties: From 8c1ee2432e134e55278a51892be0e9ec4ff5825d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 31 Dec 2021 17:03:36 -0700 Subject: [PATCH 2/7] changelog --- changelogs/client_server/newsfragments/3615.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/3615.feature diff --git a/changelogs/client_server/newsfragments/3615.feature b/changelogs/client_server/newsfragments/3615.feature new file mode 100644 index 00000000000..19a07e26306 --- /dev/null +++ b/changelogs/client_server/newsfragments/3615.feature @@ -0,0 +1 @@ +Add support for fallback keys (optional keys used once one-time keys run out), as per [MSC2732](https://github.com/matrix-org/matrix-doc/pull/2732). \ No newline at end of file From f7f009be66453993c65494a5a6a26497974dbf15 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 31 Dec 2021 17:04:36 -0700 Subject: [PATCH 3/7] Appease spell check --- .github/_typos.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/_typos.toml b/.github/_typos.toml index 3807820731c..613ccfc1bf3 100644 --- a/.github/_typos.toml +++ b/.github/_typos.toml @@ -9,4 +9,5 @@ au1ba7o = "au1ba7o" [default.extend-words] Appy = "Appy" -fo = "fo" \ No newline at end of file +fo = "fo" +OTKs = "OTKs" From f2e9f588947af9f8b7f4be8934d14c1e984c73aa Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 31 Dec 2021 17:07:31 -0700 Subject: [PATCH 4/7] Fine, let's appease the spellcheck this way --- .github/_typos.toml | 1 - data/api/client-server/keys.yaml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/_typos.toml b/.github/_typos.toml index 613ccfc1bf3..4aff005f486 100644 --- a/.github/_typos.toml +++ b/.github/_typos.toml @@ -10,4 +10,3 @@ au1ba7o = "au1ba7o" [default.extend-words] Appy = "Appy" fo = "fo" -OTKs = "OTKs" diff --git a/data/api/client-server/keys.yaml b/data/api/client-server/keys.yaml index 06d6f0162f9..357df233cb2 100644 --- a/data/api/client-server/keys.yaml +++ b/data/api/client-server/keys.yaml @@ -121,7 +121,7 @@ paths: type: - string - object - # XXX: We can't define an actual object here - see OTKs. + # XXX: We can't define an actual object here - see one_time_keys. example: { "curve25519:AAAAAG": "/qyvZvwjiTxGdGU0RCguDCLeR+nmsb3FfNG3/Ve4vU8", "signed_curve25519:AAAAGj": { From 902d479e0f449ccbefb082775a92328dbc257f86 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 4 Jan 2022 20:32:01 -0700 Subject: [PATCH 5/7] Apply suggestions from code review Co-authored-by: Hubert Chathi --- .../client-server-api/modules/end_to_end_encryption.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index fa7b6f190de..7941b65783b 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -135,8 +135,8 @@ too many private keys may discard keys starting with the oldest. {{% boxes/warning %}} Fallback keys are used to prevent one-time key exhaustion when devices -are offline/unable to upload additional keys, though can also be used -to initiate replay attacks. +are offline/unable to upload additional keys, though sessions started using +fallback keys could be vulnerable to replay attacks. {{% /boxes/warning %}} {{% boxes/warning %}} @@ -147,7 +147,7 @@ that fallback key. Instead, clients should keep the private keys for at most 2 fallback keys: the current, unused, fallback key and the key immediately preceding it. Once the client is reasonably certain it has received all messages that -used the old fallback key, such as after an hour since the last message, +used the old fallback key, such as after an hour since the first message, it should remove that fallback key. {{% /boxes/warning %}} @@ -1633,7 +1633,7 @@ difference with the `one_time_key_counts` property in the {{% added-in v="1.2" %}} Finally, a `device_unused_fallback_key_types` property -is added to list the key algorithms which *have not* been used in a +is added to list the key algorithms where the device has a fallback key that *has not* been used in a [`/keys/claim`](/client-server-api/#post_matrixclientv3keysclaim) response. When a previously uploaded fallback key's algorithm is missing from this list, the device should upload a replacement key alongside any necessary From 7fa4c65aa5b63c45b38a8b0bddf719ba5e53ee5e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 4 Jan 2022 20:34:19 -0700 Subject: [PATCH 6/7] Fix intro --- content/client-server-api/modules/end_to_end_encryption.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 7941b65783b..641a724519f 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -121,9 +121,9 @@ JSON](/appendices/#signing-json). One-time and fallback keys are also uploaded to the homeserver using the [`/keys/upload`](/client-server-api/#post_matrixclientv3keysupload) API. -{{% added-in v="1.2" %}} Fallback keys are simply one-time keys which get -used when the device has run out of one-time keys. They are not consumed -once used, but should be replaced when additional one-time keys are uploaded. +{{% added-in v="1.2" %}} Fallback keys are similar to one-time keys, but +are not consumed once used. They are only used when the device has run out +of one-time keys, and can be replaced by a new fallback key. Devices must store the private part of each key they upload. They can discard the private part of a one-time key when they receive a message From 44340adc163d87f4753d66a578575d997f5c1d6a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 4 Jan 2022 20:35:10 -0700 Subject: [PATCH 7/7] word wrap --- .../modules/end_to_end_encryption.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/content/client-server-api/modules/end_to_end_encryption.md b/content/client-server-api/modules/end_to_end_encryption.md index 641a724519f..96093b276fb 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -1633,14 +1633,14 @@ difference with the `one_time_key_counts` property in the {{% added-in v="1.2" %}} Finally, a `device_unused_fallback_key_types` property -is added to list the key algorithms where the device has a fallback key that *has not* been used in a -[`/keys/claim`](/client-server-api/#post_matrixclientv3keysclaim) response. -When a previously uploaded fallback key's algorithm is missing from this -list, the device should upload a replacement key alongside any necessary -one-time keys to avoid the fallback key's further usage. This property -is required for inclusion, though previous versions of the specification -did not have it. In addition to `/versions`, this can be a way to identify -the server's support for fallback keys. +is added to list the key algorithms where the device has a fallback key that +*has not* been used in a [`/keys/claim`](/client-server-api/#post_matrixclientv3keysclaim) +response. When a previously uploaded fallback key's algorithm is missing +from this list, the device should upload a replacement key alongside any +necessary one-time keys to avoid the fallback key's further usage. This +property is required for inclusion, though previous versions of the +specification did not have it. In addition to `/versions`, this can be +a way to identify the server's support for fallback keys. | Parameter | Type | Description |