diff --git a/changelogs/appendices/newsfragments/2398.clarification b/changelogs/appendices/newsfragments/2398.clarification new file mode 100644 index 00000000..93fee967 --- /dev/null +++ b/changelogs/appendices/newsfragments/2398.clarification @@ -0,0 +1 @@ +Add specification of URL-safe unpadded Base64. diff --git a/changelogs/client_server/newsfragments/2398.clarification b/changelogs/client_server/newsfragments/2398.clarification new file mode 100644 index 00000000..17e14845 --- /dev/null +++ b/changelogs/client_server/newsfragments/2398.clarification @@ -0,0 +1 @@ +Clarify definitions of `EncryptedFile` structure. diff --git a/content/appendices.md b/content/appendices.md index 703dd051..0e87fe8b 100644 --- a/content/appendices.md +++ b/content/appendices.md @@ -12,7 +12,7 @@ Specifically, where RFC 4648 requires that encoded data be padded to a multiple of four characters using `=` characters, unpadded Base64 omits this padding. -For reference, RFC 4648 uses the following alphabet for Base 64: +For reference, RFC 4648 uses the following alphabet for Base64: Value Encoding Value Encoding Value Encoding Value Encoding 0 A 17 R 34 i 51 z @@ -47,6 +47,12 @@ When decoding Base64, implementations SHOULD accept input with or without padding characters wherever possible, to ensure maximum interoperability. +### URL-safe unpadded Base64 + +URL-safe unpadded Base64 is identical to standard unpadded Base64, except that +it uses `-` (minus) as the 62nd character in the alphabet, and `_` (underscore) +as the 63rd. + ## Binary data In some cases it is necessary to encapsulate binary data, for example, 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 ec86203d..88a97bdd 100644 --- a/content/client-server-api/modules/end_to_end_encryption.md +++ b/content/client-server-api/modules/end_to_end_encryption.md @@ -355,7 +355,7 @@ key, and encrypts the file using AES-CTR. The counter is 64 bits long, starting at 0 and prefixed by a random 64-bit Initialization Vector (IV), which together form a 128-bit unique counter block. -Clients MUST generate both the AES key and IV using a cryptographically +Clients MUST generate both the AES key and IV using a cryptographically secure random source and MUST NOT use the same key or IV multiple times. The latter 64 bits of the 128-bit counter block MUST start at zero. @@ -385,31 +385,11 @@ Key](https://tools.ietf.org/html/rfc7517#appendix-A.3) format, with a ###### Extensions to `m.room.message` msgtypes This module adds `file` and `thumbnail_file` properties, of type -`EncryptedFile`, to `m.room.message` msgtypes that reference files, such -as [m.file](#mfile) and [m.image](#mimage), replacing the `url` and `thumbnail_url` -properties. +[`EncryptedFile`](#definition-encryptedfile), to `m.room.message` msgtypes that +reference files, such as [m.file](#mfile) and [m.image](#mimage), replacing the +`url` and `thumbnail_url` properties. -`EncryptedFile` - -| Parameter | Type | Description | -|-----------|------------------|------------------------------------------------------------------------------------------------| -| url | string | **Required.** The URL to the file. | -| key | JWK | **Required.** A [JSON Web Key](https://tools.ietf.org/html/rfc7517#appendix-A.3) object. | -| iv | string | **Required.** The 128-bit unique counter block used by AES-CTR, encoded as unpadded base64. | -| hashes | {string: string} | **Required.** A map from an algorithm name to a hash of the ciphertext, encoded as unpadded base64. Clients MUST support the SHA-256 hash, which uses the key `sha256`. | -| v | string | **Required.** Version of the encrypted attachment's protocol. Must be `v2`. | - -`JWK` - -| Parameter | Type | Description | -| --------- |----------|--------------------------------------------------------------------------------------------------------------------------| -| kty | string | **Required.** Key type. Must be `oct`. | -| key_ops | [string] | **Required.** Key operations. Must at least contain `encrypt` and `decrypt`. | -| alg | string | **Required.** Algorithm. Must be `A256CTR`. | -| k | string | **Required.** The key, encoded as urlsafe unpadded base64. | -| ext | boolean | **Required.** Extractable. Must be `true`. This is a [W3C extension](https://w3c.github.io/webcrypto/#iana-section-jwk). | - -Example: +Example `m.room.message` event containing an encrypted image: ```json { @@ -470,6 +450,8 @@ Example: } ``` +{{% definition path="api/client-server/definitions/encrypted_file" %}} + #### Device verification Before Alice sends Bob encrypted data, or trusts data received from him, @@ -764,7 +746,7 @@ The process between Alice and Bob verifying each other would be: 15. Assuming they match, Alice and Bob's devices each calculate Message Authentication Codes (MACs) for: * {{% changed-in v="1.18" %}} Each of the keys that they wish the other user - to verify (usually their device ed25519 key and their master signing key, + to verify (usually their device ed25519 key and their master signing key, see below). The master signing key SHOULD be included when two different users are verifying each other. Verifying individual devices of other users is deprecated. diff --git a/data/api/client-server/definitions/encrypted_file.yaml b/data/api/client-server/definitions/encrypted_file.yaml new file mode 100644 index 00000000..5bb7af4c --- /dev/null +++ b/data/api/client-server/definitions/encrypted_file.yaml @@ -0,0 +1,84 @@ +# Copyright 2018-2026 The Matrix.org Foundation C.I.C. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +type: object +title: EncryptedFile +description: | + Information on an encrypted media blob, including its location in the + [content repository](/client-server-api/#content-repository), and the keys + necessary to decrypt it. +properties: + url: + type: string + format: mx-mxc-uri + description: The URL to the file. + example: "mxc://example.org/FHyPlCeYUSFFxlgbQYZmoEoe" + key: + type: object + title: JWK + description: A [JSON Web Key](https://tools.ietf.org/html/rfc7517#appendix-A.3) object. + properties: + kty: + type: string + description: Key type. Must be `oct`. + example: "oct" + key_ops: + type: array + items: + type: string + description: Key operations. Must at least contain `encrypt` and `decrypt`. + example: ["encrypt", "decrypt"] + alg: + type: string + description: Algorithm. Must be `A256CTR`. + example: A256CTR + k: + type: string + description: The key, encoded as [URL-safe unpadded Base64](/appendices/#url-safe-unpadded-base64). + example: "aWF6-32KGYaC3A_FEUCk1Bt0JA37zP0wrStgmdCaW-0" + ext: + type: boolean + description: "Extractable. Must be `true`. This is a [W3C extension](https://w3c.github.io/webcrypto/#iana-section-jwk)." + example: true + required: + - kty + - key_ops + - alg + - k + - ext + iv: + type: string + description: The 128-bit unique counter block used by AES-CTR, encoded as [unpadded Base64](/appendices/#unpadded-base64). + example: "w+sE15fzSc0AAAAAAAAAAA" + hashes: + type: object + title: EncryptedFileHashes + description: + A map from an algorithm name to a hash of the ciphertext. Clients MUST support the SHA-256 hash, which uses the key `sha256`. + properties: + sha256: + type: string + description: The hash of the ciphertext. encoded as [unpadded Base64](/appendices/#unpadded-base64). + example: "fdSLu/YkRx3Wyh3KQabP3rd6+SFiKg5lsJZQHtkSAYA" + required: ['sha256'] + v: + type: string + description: Version of the encrypted attachment’s protocol. Must be `v2`. + example: v2 +required: + - url + - key + - iv + - hashes + - v diff --git a/data/event-schemas/schema/core-event-schema/msgtype_infos/image_info.yaml b/data/event-schemas/schema/core-event-schema/msgtype_infos/image_info.yaml index 42e4540d..c19eca15 100644 --- a/data/event-schemas/schema/core-event-schema/msgtype_infos/image_info.yaml +++ b/data/event-schemas/schema/core-event-schema/msgtype_infos/image_info.yaml @@ -27,8 +27,7 @@ properties: pattern: "^mxc:\\/\\/" thumbnail_file: description: |- - Information on the encrypted thumbnail file, as specified in - [End-to-end encryption](/client-server-api/#sending-encrypted-attachments). + An [EncryptedFile](/client-server-api/#definition-encryptedfile) structure. Only present if the thumbnail is encrypted. title: EncryptedFile type: object diff --git a/data/event-schemas/schema/m.room.message$m.audio.yaml b/data/event-schemas/schema/m.room.message$m.audio.yaml index d138de38..462933c9 100644 --- a/data/event-schemas/schema/m.room.message$m.audio.yaml +++ b/data/event-schemas/schema/m.room.message$m.audio.yaml @@ -58,9 +58,7 @@ properties: pattern: "^mxc:\\/\\/" file: description: |- - Required if the file is encrypted. Information on the encrypted - file, as specified in - [End-to-end encryption](/client-server-api/#sending-encrypted-attachments). + Required if the file is encrypted. An [EncryptedFile](/client-server-api/#definition-encryptedfile) structure. title: EncryptedFile type: object required: diff --git a/data/event-schemas/schema/m.room.message$m.file.yaml b/data/event-schemas/schema/m.room.message$m.file.yaml index 296118e0..ca9a6ceb 100644 --- a/data/event-schemas/schema/m.room.message$m.file.yaml +++ b/data/event-schemas/schema/m.room.message$m.file.yaml @@ -48,8 +48,7 @@ properties: pattern: "^mxc:\\/\\/" thumbnail_file: description: |- - Information on the encrypted thumbnail file, as specified in - [End-to-end encryption](/client-server-api/#sending-encrypted-attachments). + An [EncryptedFile](/client-server-api/#definition-encryptedfile) structure. Only present if the thumbnail is encrypted. title: EncryptedFile type: object @@ -72,9 +71,7 @@ properties: pattern: "^mxc:\\/\\/" file: description: |- - Required if the file is encrypted. Information on the encrypted - file, as specified in - [End-to-end encryption](/client-server-api/#sending-encrypted-attachments). + Required if the file is encrypted. An [EncryptedFile](/client-server-api/#definition-encryptedfile) structure. title: EncryptedFile type: object required: diff --git a/data/event-schemas/schema/m.room.message$m.image.yaml b/data/event-schemas/schema/m.room.message$m.image.yaml index 2cb7371d..f36d5f7d 100644 --- a/data/event-schemas/schema/m.room.message$m.image.yaml +++ b/data/event-schemas/schema/m.room.message$m.image.yaml @@ -48,9 +48,7 @@ properties: pattern: "^mxc:\\/\\/" file: description: |- - Required if the file is encrypted. Information on the encrypted - file, as specified in - [End-to-end encryption](/client-server-api/#sending-encrypted-attachments). + Required if the file is encrypted. An [EncryptedFile](/client-server-api/#definition-encryptedfile) structure. title: EncryptedFile type: object required: diff --git a/data/event-schemas/schema/m.room.message$m.location.yaml b/data/event-schemas/schema/m.room.message$m.location.yaml index 3f1b9c1c..507f6a7f 100644 --- a/data/event-schemas/schema/m.room.message$m.location.yaml +++ b/data/event-schemas/schema/m.room.message$m.location.yaml @@ -31,8 +31,7 @@ properties: pattern: "^mxc:\\/\\/" thumbnail_file: description: |- - Information on the encrypted thumbnail file, as specified in - [End-to-end encryption](/client-server-api/#sending-encrypted-attachments). + An [EncryptedFile](/client-server-api/#definition-encryptedfile) structure. Only present if the thumbnail is encrypted. title: EncryptedFile type: object diff --git a/data/event-schemas/schema/m.room.message$m.video.yaml b/data/event-schemas/schema/m.room.message$m.video.yaml index 5ff9c250..0f3c5159 100644 --- a/data/event-schemas/schema/m.room.message$m.video.yaml +++ b/data/event-schemas/schema/m.room.message$m.video.yaml @@ -58,8 +58,7 @@ properties: pattern: "^mxc:\\/\\/" thumbnail_file: description: |- - Information on the encrypted thumbnail file, as specified in - [End-to-end encryption](/client-server-api/#sending-encrypted-attachments). + An [EncryptedFile](/client-server-api/#definition-encryptedfile) structure. Only present if the thumbnail is encrypted. title: EncryptedFile type: object @@ -82,9 +81,7 @@ properties: pattern: "^mxc:\\/\\/" file: description: |- - Required if the file is encrypted. Information on the encrypted - file, as specified in - [End-to-end encryption](/client-server-api/#sending-encrypted-attachments). + Required if the file is encrypted. An [EncryptedFile](/client-server-api/#definition-encryptedfile) structure. title: EncryptedFile type: object required: