diff --git a/event-schemas/examples/m.room.message.encrypted_file b/event-schemas/examples/m.room.message.encrypted_file new file mode 100644 index 00000000..1b157922 --- /dev/null +++ b/event-schemas/examples/m.room.message.encrypted_file @@ -0,0 +1,55 @@ +{ + "age": 146, + "content": { + "body": "something-important.doc", + "filename": "something-important.doc", + "file": { + "url": "mxc://localhost/FHyPlCeYUSFFxlgbQYZmoEoe", + "mimetype": "application/msword", + "v": "v2", + "key": { + "alg": "A256CTR", + "ext": true, + "k": "aWF6-32KGYaC3A_FEUCk1Bt0JA37zP0wrStgmdCaW-0", + "key_ops": ["encrypt","decrypt"], + "kty": "oct" + }, + "iv": "w+sE15fzSc0AAAAAAAAAAA", + "hashes": { + "sha256": "fdSLu/YkRx3Wyh3KQabP3rd6+SFiKg5lsJZQHtkSAYA" + } + }, + "info": { + "mimetype": "application/msword", + "size": 46144, + "thumbnail_file": { + "hashes": { + "sha256": "/NogKqW5bz/m8xHgFiH5haFGjCNVmUIPLzfvOhHdrxY" + }, + "iv": "U+k7PfwLr6UAAAAAAAAAAA", + "key": { + "alg": "A256CTR", + "ext": true, + "k": "RMyd6zhlbifsACM1DXkCbioZ2u0SywGljTH8JmGcylg", + "key_ops": ["encrypt", "decrypt"], + "kty": "oct" + }, + "mimetype": "image/jpeg", + "url": "mxc://localhost/pmVJxyxGlmxHposwVSlOaEOv", + "v": "v2" + }, + "thumbnail_info": { + "h": 768, + "mimetype": "image/jpeg", + "size": 211009, + "w": 432 + } + }, + "msgtype": "m.file" + }, + "event_id": "$143273582443PhrSn:localhost", + "origin_server_ts": 1432735824653, + "room_id": "!jEsUZKDJdhlrceRyVU:localhost", + "type": "m.room.message", + "sender": "@example:localhost" +} diff --git a/event-schemas/schema/m.room.message.encrypted_file b/event-schemas/schema/m.room.message.encrypted_file new file mode 100644 index 00000000..b1f5d1f4 --- /dev/null +++ b/event-schemas/schema/m.room.message.encrypted_file @@ -0,0 +1,95 @@ +--- +allOf: + - $ref: core-event-schema/room_event.yaml +description: |- + This message represents an encrypted generic file, corresponding to a + plaintext ``m.file`` message. ``m.image``, ``m.video`` and ``m.audio`` can be + sent encrypted using the same structure. +properties: + content: + properties: + body: + description: |- + A human-readable description of the file. This is recommended to be + the filename of the original upload. + type: string + filename: + description: The original filename of the uploaded file. + type: string + info: + description: Information about the file referred to in ``url``. + properties: + mimetype: + description: The mimetype of the file e.g. ``application/msword``. + type: string + size: + description: The size of the file in bytes. + type: integer + thumbnail_file: + description: The URL to the thumbnail of the file. + title: EncryptedFile + type: object + thumbnail_info: + allOf: + - $ref: core-event-schema/msgtype_infos/thumbnail_info.yaml + description: Metadata about the image referred to in ``thumbnail_url``. + title: FileInfo + type: object + msgtype: + enum: + - m.file + type: string + file: + description: Information needed to decrypt the file. + properties: + url: + description: The URL to the file. + type: string + key: + description: A JSON web key object (as defined in RFC7517 LINK). + type: object + title: JWK + properties: + kty: + description: Key type. Must be ``oct``. + type: string + key_ops: + description: |- + Key operations. Must at least contain ``encrypt`` and ``decrypt``. + type: array + items: + type: string + alg: + description: Algorithm. Must be ``A256CTR``. + type: string + k: + description: The key, encoded as urlsafe unpadded base64. + type: string + ext: + description: Extractable. Must be ``true``.(W3C link) + type: boolean + iv: + description: The Initialisation Vector used by AES-CTR. + type: string + hashes: + description: A map from an algorithm name to a hash of the ciphertext. + type: object + additionalProperties: + type: string + v: + description: Version of the encrypted attachments protocol. + type: string + title: EncryptedFile + type: object + required: + - msgtype + - body + - file + - filename + type: object + type: + enum: + - m.room.message + type: string +title: EncryptedFileMessage +type: object diff --git a/specification/modules/end_to_end_encryption.rst b/specification/modules/end_to_end_encryption.rst index fa461cc2..c6a8f28f 100644 --- a/specification/modules/end_to_end_encryption.rst +++ b/specification/modules/end_to_end_encryption.rst @@ -224,6 +224,39 @@ process: .. |device_lists| replace:: ``device_lists`` .. _`device_lists`: `device_lists_sync`_ + +Sending encrypted attachments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When encryption is enabled in a room, files should be uploaded encrypted on +the homeserver. + +In order to achieve this, a client should generate a single-use 256 bits AES key. +Then, it should encrypt the file using AES-CTR. The counter should be 64 bits long, +starting at 0 and prefixed by a random 64 bits Initialization Vector (IV), which +together form a 128 bits unique counter block. + +.. Warning:: + An IV must never be used multiple times with the same key. This implies that if there + are multiple files to encrypt in the same message, typically an image and its thumbnail, + the key may be reused, but not the IV. + +Then, the encrypted file can be uploaded to the homeserver. +The key and the IV must be shared along with the resulting ``mxc://`` in order to allow +recipients to decrypt the file. As the event containing those will be Megolm encrypted, +the server will never have access to the decrypted file. + +A hash of the ciphertext must also be included, in order to prevent the homeserver from +changing the file content. + +A client should send those data as a ``m.room.message``. The structure is similar to +a ``m.file`` message or equivalent. The two differing keys are ``url`` and +``thumbnail_url``, which are replaced respectively by ``file`` and ``thumbnail_file``, +containing an ``EncryptedFile`` object as specified below. The key is sent using +the `JSON Web Key`_ format, with a `W3C extension`_. + +{{m_room_message_encrypted_file_event}} + Claiming one-time keys ~~~~~~~~~~~~~~~~~~~~~~ @@ -548,6 +581,8 @@ Example response: .. _curve25519: https://cr.yp.to/ecdh.html .. _`Olm specification`: http://matrix.org/docs/spec/olm.html .. _`Megolm specification`: http://matrix.org/docs/spec/megolm.html +.. _`JSON Web Key`: https://tools.ietf.org/html/rfc7517#appendix-A.3 +.. _`W3C extension`: https://w3c.github.io/webcrypto/#iana-section-jwk .. _`Signing JSON`: ../appendices.html#signing-json