Merge remote-tracking branch 'matrix-org/master' into travis/as/user-alias-query
This commit is contained in:
commit
7e5160c7c2
19 changed files with 532 additions and 24 deletions
|
@ -32,6 +32,10 @@ paths:
|
||||||
description: |-
|
description: |-
|
||||||
This API is called by the homeserver when it wants to push an event
|
This API is called by the homeserver when it wants to push an event
|
||||||
(or batch of events) to the application service.
|
(or batch of events) to the application service.
|
||||||
|
|
||||||
|
Note that the application service should distinguish state events
|
||||||
|
from message events via the presence of a ``state_key``, rather than
|
||||||
|
via the event type.
|
||||||
operationId: sendTransaction
|
operationId: sendTransaction
|
||||||
parameters:
|
parameters:
|
||||||
- in: path
|
- in: path
|
||||||
|
@ -44,7 +48,7 @@ paths:
|
||||||
x-example: "35"
|
x-example: "35"
|
||||||
- in: body
|
- in: body
|
||||||
name: body
|
name: body
|
||||||
description: A list of events
|
description: A list of events.
|
||||||
schema:
|
schema:
|
||||||
type: object
|
type: object
|
||||||
example: {
|
example: {
|
||||||
|
|
|
@ -194,7 +194,7 @@ paths:
|
||||||
"user_id": "@alice:example.com",
|
"user_id": "@alice:example.com",
|
||||||
"device_id": "JLAFKJWSCS",
|
"device_id": "JLAFKJWSCS",
|
||||||
"algorithms": [
|
"algorithms": [
|
||||||
"m.olm.curve25519-aes-sha256",
|
"m.olm.v1.curve25519-aes-sha256",
|
||||||
"m.megolm.v1.aes-sha"
|
"m.megolm.v1.aes-sha"
|
||||||
],
|
],
|
||||||
"keys": {
|
"keys": {
|
||||||
|
@ -247,7 +247,7 @@ paths:
|
||||||
description: algorithm
|
description: algorithm
|
||||||
example: "signed_curve25519"
|
example: "signed_curve25519"
|
||||||
example:
|
example:
|
||||||
"@alice:example.com": { "JLAFKJWSCS": "curve25519" }
|
"@alice:example.com": { "JLAFKJWSCS": "signed_curve25519" }
|
||||||
required:
|
required:
|
||||||
- one_time_keys
|
- one_time_keys
|
||||||
responses:
|
responses:
|
||||||
|
|
|
@ -253,6 +253,14 @@ paths:
|
||||||
description: |-
|
description: |-
|
||||||
Information on end-to-end device updates, as specified in
|
Information on end-to-end device updates, as specified in
|
||||||
|device_lists_sync|_.
|
|device_lists_sync|_.
|
||||||
|
device_one_time_keys_count:
|
||||||
|
title: One-time keys count
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: integer
|
||||||
|
description: |-
|
||||||
|
Information on end-to-end encryption keys, as specified
|
||||||
|
in |device_lists_sync|_.
|
||||||
examples:
|
examples:
|
||||||
application/json: {
|
application/json: {
|
||||||
"next_batch": "s72595_4483_1934",
|
"next_batch": "s72595_4483_1934",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Clarify ``changed`` field behaviour in device tracking process
|
7
changelogs/client_server/newsfragments/1284.feature
Normal file
7
changelogs/client_server/newsfragments/1284.feature
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
End-to-end encryption for group chats:
|
||||||
|
|
||||||
|
- Olm and Megolm messaging algorithms.
|
||||||
|
- ``m.room.encrypted``, ``m.room.encryption``, ``m.room_key`` events.
|
||||||
|
- Device verification process.
|
||||||
|
- ``device_one_time_keys_count`` sync parameter.
|
||||||
|
- ``device_lists:left`` sync parameter.
|
|
@ -0,0 +1 @@
|
||||||
|
Clarify how access tokens are meant to be supplied to the homeserver.
|
1
changelogs/client_server/newsfragments/1542.feature
Normal file
1
changelogs/client_server/newsfragments/1542.feature
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Guests can now call /context and /event to fetch events
|
14
event-schemas/examples/m.room.encrypted#megolm
Normal file
14
event-schemas/examples/m.room.encrypted#megolm
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"algorithm": "m.megolm.v1.aes-sha2",
|
||||||
|
"ciphertext": "AwgAEnACgAkLmt6qF84IK++J7UDH2Za1YVchHyprqTqsg...",
|
||||||
|
"device_id": "RJYKSTBOIE",
|
||||||
|
"sender_key": "IlRMeOPX2e0MurIyfWEucYBRVOEEUMrOHqn/8mLqMjA",
|
||||||
|
"session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ"
|
||||||
|
},
|
||||||
|
"event_id": "$WLGTSEFSEF:localhost",
|
||||||
|
"room_id": "!Cuyf34gef24t:localhost",
|
||||||
|
"origin_server_ts": 1476648761524,
|
||||||
|
"sender": "@example:localhost",
|
||||||
|
"type": "m.room.encrypted"
|
||||||
|
}
|
14
event-schemas/examples/m.room.encrypted#olm
Normal file
14
event-schemas/examples/m.room.encrypted#olm
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"type": "m.room.encrypted",
|
||||||
|
"sender": "@example:localhost",
|
||||||
|
"content": {
|
||||||
|
"algorithm": "m.olm.v1.curve25519-aes-sha2",
|
||||||
|
"sender_key": "Szl29ksW/L8yZGWAX+8dY1XyFi+i5wm+DRhTGkbMiwU",
|
||||||
|
"ciphertext": {
|
||||||
|
"7qZcfnBmbEGzxxaWfBjElJuvn7BZx+lSz/SvFrDF/z8": {
|
||||||
|
"type": 0,
|
||||||
|
"body": "AwogGJJzMhf/S3GQFXAOrCZ3iKyGU5ZScVtjI0KypTYrW..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
event-schemas/examples/m.room.encryption
Normal file
13
event-schemas/examples/m.room.encryption
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"algorithm": "m.megolm.v1.aes-sha2",
|
||||||
|
"rotation_period_ms": 604800000,
|
||||||
|
"rotation_period_msgs": 100
|
||||||
|
},
|
||||||
|
"event_id": "$WLGTSEFJJKJ:localhost",
|
||||||
|
"origin_server_ts": 1476648761524,
|
||||||
|
"sender": "@example:localhost",
|
||||||
|
"room_id": "!Cuyf34gef24t:localhost",
|
||||||
|
"state_key": "",
|
||||||
|
"type": "m.room.encryption"
|
||||||
|
}
|
9
event-schemas/examples/m.room_key
Normal file
9
event-schemas/examples/m.room_key
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"content": {
|
||||||
|
"algorithm": "m.megolm.v1.aes-sha2",
|
||||||
|
"room_id": "!Cuyf34gef24t:localhost",
|
||||||
|
"session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ",
|
||||||
|
"session_key": "AgAAAADxKHa9uFxcXzwYoNueL5Xqi69IkD4sni8LlfJL7qNBEY..."
|
||||||
|
},
|
||||||
|
"type": "m.room_key"
|
||||||
|
}
|
61
event-schemas/schema/m.room.encrypted
Normal file
61
event-schemas/schema/m.room.encrypted
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
allOf:
|
||||||
|
- $ref: core-event-schema/event.yaml
|
||||||
|
|
||||||
|
description: |-
|
||||||
|
This event type is used when sending encrypted events. It can be used either
|
||||||
|
within a room (in which case it will have all of the `Room Event fields`_), or
|
||||||
|
as a `to-device`_ event.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
content:
|
||||||
|
properties:
|
||||||
|
algorithm:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- m.olm.curve25519-aes-sha256
|
||||||
|
- m.megolm.v1.aes-sha
|
||||||
|
description: |-
|
||||||
|
The encryption algorithm used to encrypt this event. The
|
||||||
|
value of this field determines which other properties will be
|
||||||
|
present.
|
||||||
|
ciphertext:
|
||||||
|
oneOf:
|
||||||
|
- type: string
|
||||||
|
- type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: object
|
||||||
|
title: CiphertextInfo
|
||||||
|
properties:
|
||||||
|
body:
|
||||||
|
type: string
|
||||||
|
description: The encrypted payload.
|
||||||
|
type:
|
||||||
|
type: integer
|
||||||
|
description: The Olm message type.
|
||||||
|
description: |-
|
||||||
|
The encrypted content of the event. Either the encrypted payload
|
||||||
|
itself, in the case of a Megolm event, or a map from the recipient
|
||||||
|
Curve25519 identity key to ciphertext information, in the case of an
|
||||||
|
Olm event. For more details, see `Messaging Algorithms`_.
|
||||||
|
sender_key:
|
||||||
|
type: string
|
||||||
|
description: The Curve25519 key of the sender.
|
||||||
|
device_id:
|
||||||
|
type: string
|
||||||
|
description: The ID of the sending device. Required with Megolm.
|
||||||
|
session_id:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The ID of the session used to encrypt the message. Required with
|
||||||
|
Megolm.
|
||||||
|
required:
|
||||||
|
- algorithm
|
||||||
|
- sender_key
|
||||||
|
- ciphertext
|
||||||
|
type: object
|
||||||
|
type:
|
||||||
|
enum:
|
||||||
|
- m.room.encrypted
|
||||||
|
type: string
|
||||||
|
type: object
|
36
event-schemas/schema/m.room.encryption
Normal file
36
event-schemas/schema/m.room.encryption
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
---
|
||||||
|
allOf:
|
||||||
|
- $ref: core-event-schema/state_event.yaml
|
||||||
|
description: Defines how messages sent in this room should be encrypted.
|
||||||
|
properties:
|
||||||
|
content:
|
||||||
|
properties:
|
||||||
|
algorithm:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- "m.megolm.v1.aes-sha2"
|
||||||
|
description: |-
|
||||||
|
The encryption algorithm to be used to encrypt messages sent in this
|
||||||
|
room.
|
||||||
|
rotation_period_ms:
|
||||||
|
type: integer
|
||||||
|
description: |-
|
||||||
|
How long the session should be used before changing it. ``604800000``
|
||||||
|
(a week) is the recommended default.
|
||||||
|
rotation_period_msgs:
|
||||||
|
type: integer
|
||||||
|
description: |-
|
||||||
|
How many messages should be sent before changing the session. ``100`` is the
|
||||||
|
recommended default.
|
||||||
|
required:
|
||||||
|
- algorithm
|
||||||
|
type: object
|
||||||
|
state_key:
|
||||||
|
description: A zero-length string.
|
||||||
|
pattern: '^$'
|
||||||
|
type: string
|
||||||
|
type:
|
||||||
|
enum:
|
||||||
|
- m.room.encryption
|
||||||
|
type: string
|
||||||
|
type: object
|
35
event-schemas/schema/m.room_key
Normal file
35
event-schemas/schema/m.room_key
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
allOf:
|
||||||
|
- $ref: core-event-schema/event.yaml
|
||||||
|
|
||||||
|
description: |-
|
||||||
|
This event type is used to exchange keys for end-to-end encryption. Typically
|
||||||
|
it is encrypted as an ``m.room.encrypted`` event, then sent as a `to-device`_ event.
|
||||||
|
properties:
|
||||||
|
content:
|
||||||
|
properties:
|
||||||
|
algorithm:
|
||||||
|
type: string
|
||||||
|
enum: ["m.megolm.v1.aes-sha2"]
|
||||||
|
description: |-
|
||||||
|
The encryption algorithm the key in this event is to be used with.
|
||||||
|
room_id:
|
||||||
|
type: string
|
||||||
|
description: The room where the key is used.
|
||||||
|
session_id:
|
||||||
|
type: string
|
||||||
|
description: The ID of the session that the key is for.
|
||||||
|
session_key:
|
||||||
|
type: string
|
||||||
|
description: The key to be exchanged.
|
||||||
|
required:
|
||||||
|
- algorithm
|
||||||
|
- room_id
|
||||||
|
- session_id
|
||||||
|
- session_key
|
||||||
|
type: object
|
||||||
|
type:
|
||||||
|
enum:
|
||||||
|
- m.room_key
|
||||||
|
type: string
|
||||||
|
type: object
|
|
@ -32,6 +32,12 @@ complete specification to be merged correctly. These characters are:
|
||||||
If you find yourself using ``^`` or beyond, you should rethink your document
|
If you find yourself using ``^`` or beyond, you should rethink your document
|
||||||
layout if possible.
|
layout if possible.
|
||||||
|
|
||||||
|
Correct capitalisation for long section names
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Headings should start with a capital letter, and use lower-case otherwise.
|
||||||
|
|
||||||
|
|
||||||
TODOs
|
TODOs
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
.. Copyright 2016 OpenMarket Ltd
|
.. Copyright 2016 OpenMarket Ltd
|
||||||
|
.. Copyright 2018 New Vector Ltd
|
||||||
..
|
..
|
||||||
.. Licensed under the Apache License, Version 2.0 (the "License");
|
.. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
.. you may not use this file except in compliance with the License.
|
.. you may not use this file except in compliance with the License.
|
||||||
|
@ -39,7 +40,7 @@ This version of the specification is generated from
|
||||||
Application Services
|
Application Services
|
||||||
--------------------
|
--------------------
|
||||||
Application services are passive and can only observe events from a given
|
Application services are passive and can only observe events from a given
|
||||||
homeserver. They can inject events into rooms they are participating in.
|
homeserver (HS). They can inject events into rooms they are participating in.
|
||||||
They cannot prevent events from being sent, nor can they modify the content of
|
They cannot prevent events from being sent, nor can they modify the content of
|
||||||
the event being sent. In order to observe events from a homeserver, the
|
the event being sent. In order to observe events from a homeserver, the
|
||||||
homeserver needs to be configured to pass certain types of traffic to the
|
homeserver needs to be configured to pass certain types of traffic to the
|
||||||
|
@ -68,7 +69,13 @@ Registration
|
||||||
Application services register "namespaces" of user IDs, room aliases and room IDs.
|
Application services register "namespaces" of user IDs, room aliases and room IDs.
|
||||||
These namespaces are represented as regular expressions. An application service
|
These namespaces are represented as regular expressions. An application service
|
||||||
is said to be "interested" in a given event if one of the IDs in the event match
|
is said to be "interested" in a given event if one of the IDs in the event match
|
||||||
the regular expression provided by the application service. An application
|
the regular expression provided by the application service, such as the room having
|
||||||
|
an alias or ID in the relevant namespaces. Similarly, the application service is
|
||||||
|
said to be interested in a given event if one of the application service's namespaced
|
||||||
|
users is the target of the event, or is a joined member of the room where the event
|
||||||
|
occurred.
|
||||||
|
|
||||||
|
An application
|
||||||
service can also state whether they should be the only ones who
|
service can also state whether they should be the only ones who
|
||||||
can manage a specified namespace. This is referred to as an "exclusive"
|
can manage a specified namespace. This is referred to as an "exclusive"
|
||||||
namespace. An exclusive namespace prevents humans and other application
|
namespace. An exclusive namespace prevents humans and other application
|
||||||
|
@ -83,7 +90,7 @@ regular expressions and look like:
|
||||||
|
|
||||||
users:
|
users:
|
||||||
- exclusive: true
|
- exclusive: true
|
||||||
regex: @irc.freenode.net_.*
|
regex: @_irc.freenode.net_.*
|
||||||
|
|
||||||
|
|
||||||
The registration is represented by a series of key-value pairs, which this
|
The registration is represented by a series of key-value pairs, which this
|
||||||
|
@ -105,12 +112,17 @@ traffic to the AS is:
|
||||||
aliases: [] # Namespaces of room aliases which should be delegated to the AS
|
aliases: [] # Namespaces of room aliases which should be delegated to the AS
|
||||||
rooms: [] # Namespaces of room ids which should be delegated to the AS
|
rooms: [] # Namespaces of room ids which should be delegated to the AS
|
||||||
|
|
||||||
|
Exclusive user and alias namespaces should begin with an underscore after the
|
||||||
|
sigil to avoid collisions with other users on the homeserver. Application
|
||||||
|
services should additionally attempt to identify the service they represent
|
||||||
|
in the reserved namespace. For example, ``@_irc_.*`` would be a good namespace
|
||||||
|
to register for an application service which deals with IRC.
|
||||||
|
|
||||||
.. WARNING::
|
.. WARNING::
|
||||||
If the homeserver in question has multiple application services, each
|
If the homeserver in question has multiple application services, each
|
||||||
``as_token`` and ``id`` MUST be unique per application service as these are
|
``as_token`` and ``id`` MUST be unique per application service as these are
|
||||||
used to identify the application service. The homeserver MUST enforce this.
|
used to identify the application service. The homeserver MUST enforce this.
|
||||||
|
|
||||||
|
|
||||||
Homeserver -> Application Service API
|
Homeserver -> Application Service API
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -221,7 +233,8 @@ need to be able to adjust the ``origin_server_ts`` value to do this.
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
- Application service token (``as_token``)
|
- Application service token (``as_token``)
|
||||||
- Desired timestamp
|
- Desired timestamp (in milliseconds since the unix epoch)
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- This will only apply when sending events.
|
- This will only apply when sending events.
|
||||||
|
|
||||||
|
@ -268,6 +281,14 @@ normal users who attempt to create users or aliases *inside* an application
|
||||||
service-defined namespace will receive the same ``M_EXCLUSIVE`` error code,
|
service-defined namespace will receive the same ``M_EXCLUSIVE`` error code,
|
||||||
but only if the application service has defined the namespace as ``exclusive``.
|
but only if the application service has defined the namespace as ``exclusive``.
|
||||||
|
|
||||||
|
Using ``/sync`` and ``/events``
|
||||||
|
+++++++++++++++++++++++++++++++
|
||||||
|
|
||||||
|
Application services wishing to use ``/sync`` or ``/events`` from the Client-Server
|
||||||
|
API MUST do so with a virtual user (provide a ``user_id`` via the query string). It
|
||||||
|
is expectected that the application service use the transactions pushed to it to
|
||||||
|
handle events rather than syncing with the user implied by ``sender_localpart``.
|
||||||
|
|
||||||
Event fields
|
Event fields
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -191,10 +191,6 @@ previously obtained credentials in the form of an ``access_token`` query
|
||||||
parameter or through an Authorization Header of ``Bearer $access_token``.
|
parameter or through an Authorization Header of ``Bearer $access_token``.
|
||||||
An access token is typically obtained via the `Login`_ or `Registration`_ processes.
|
An access token is typically obtained via the `Login`_ or `Registration`_ processes.
|
||||||
|
|
||||||
When credentials are required but missing or invalid, the HTTP call will
|
|
||||||
return with a status of 401 and the error code, ``M_MISSING_TOKEN`` or
|
|
||||||
``M_UNKNOWN_TOKEN`` respectively.
|
|
||||||
|
|
||||||
.. NOTE::
|
.. NOTE::
|
||||||
|
|
||||||
This specification does not mandate a particular format for the access
|
This specification does not mandate a particular format for the access
|
||||||
|
@ -202,6 +198,24 @@ return with a status of 401 and the error code, ``M_MISSING_TOKEN`` or
|
||||||
to choose an appropriate format. Server implementors may like to investigate
|
to choose an appropriate format. Server implementors may like to investigate
|
||||||
`macaroons <macaroon_>`_.
|
`macaroons <macaroon_>`_.
|
||||||
|
|
||||||
|
Using access tokens
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Access tokens may be provided in two ways, both of which the homeserver MUST
|
||||||
|
support:
|
||||||
|
|
||||||
|
1. Via a query string parameter, ``access_token=TheTokenHere``.
|
||||||
|
#. Via a request header, ``Authorization: Bearer TheTokenHere``.
|
||||||
|
|
||||||
|
Clients are encouraged to use the ``Authorization`` header where possible
|
||||||
|
to prevent the access token being leaked in access/HTTP logs. The query
|
||||||
|
string should only be used in cases where the ``Authorization`` header is
|
||||||
|
inaccessible for the client.
|
||||||
|
|
||||||
|
When credentials are required but missing or invalid, the HTTP call will
|
||||||
|
return with a status of 401 and the error code, ``M_MISSING_TOKEN`` or
|
||||||
|
``M_UNKNOWN_TOKEN`` respectively.
|
||||||
|
|
||||||
Relationship between access tokens and devices
|
Relationship between access tokens and devices
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,6 @@ Matrix optionally supports end-to-end encryption, allowing rooms to be created
|
||||||
whose conversation contents is not decryptable or interceptable on any of the
|
whose conversation contents is not decryptable or interceptable on any of the
|
||||||
participating homeservers.
|
participating homeservers.
|
||||||
|
|
||||||
.. WARNING::
|
|
||||||
|
|
||||||
End to end encryption is being worked on and will be coming soon. This
|
|
||||||
section is incomplete. You can read more about what's underway at
|
|
||||||
http://matrix.org/speculator/spec/drafts%2Fe2e/client_server/unstable.html#end-to-end-encryption.
|
|
||||||
|
|
||||||
Key Distribution
|
Key Distribution
|
||||||
----------------
|
----------------
|
||||||
Encryption and Authentication in Matrix is based around public-key
|
Encryption and Authentication in Matrix is based around public-key
|
||||||
|
@ -159,7 +153,7 @@ It is therefore expected that each client will maintain a list of devices for a
|
||||||
number of users (in practice, typically each user with whom we share an
|
number of users (in practice, typically each user with whom we share an
|
||||||
encrypted room). Furthermore, it is likely that this list will need to be
|
encrypted room). Furthermore, it is likely that this list will need to be
|
||||||
persisted between invocations of the client application (to preserve device
|
persisted between invocations of the client application (to preserve device
|
||||||
verification data and to alert Alice if Bob suddently gets a new
|
verification data and to alert Alice if Bob suddenly gets a new
|
||||||
device).
|
device).
|
||||||
|
|
||||||
Alice's client can maintain a list of Bob's devices via the following
|
Alice's client can maintain a list of Bob's devices via the following
|
||||||
|
@ -176,9 +170,10 @@ process:
|
||||||
flag.
|
flag.
|
||||||
|
|
||||||
#. During its normal processing of responses to |/sync|_, Alice's client
|
#. During its normal processing of responses to |/sync|_, Alice's client
|
||||||
inspects the |device_lists|_ field. If it is tracking the device lists of
|
inspects the ``changed`` property of the |device_lists|_ field. If it is
|
||||||
any of the listed users, then it marks the device lists for those users
|
tracking the device lists of any of the listed users, then it marks the
|
||||||
outdated, and initiates another request to |/keys/query|_ for them.
|
device lists for those users outdated, and initiates another request to
|
||||||
|
|/keys/query|_ for them.
|
||||||
|
|
||||||
#. Periodically, Alice's client stores the ``next_batch`` field of the result
|
#. Periodically, Alice's client stores the ``next_batch`` field of the result
|
||||||
from |/sync|_ in persistent storage. If Alice later restarts her client, it
|
from |/sync|_ in persistent storage. If Alice later restarts her client, it
|
||||||
|
@ -214,6 +209,18 @@ process:
|
||||||
that the first request's results are ignored (possibly by cancelling the
|
that the first request's results are ignored (possibly by cancelling the
|
||||||
request).
|
request).
|
||||||
|
|
||||||
|
.. Note::
|
||||||
|
|
||||||
|
When Bob and Alice share a room, with Bob tracking Alice's devices, she may leave
|
||||||
|
the room and then add a new device. Bob will not be notified of this change,
|
||||||
|
as he doesn't share a room anymore with Alice. When they start sharing a
|
||||||
|
room again, Bob has an out-of-date list of Alice's devices. In order to address
|
||||||
|
this issue, Bob's homeserver will add Alice's user ID to the ``changed`` property of
|
||||||
|
the ``device_lists`` field, thus Bob will update his list of Alice's devices as part
|
||||||
|
of his normal processing. Note that Bob can also be notified when he stops sharing
|
||||||
|
any room with Alice by inspecting the ``left`` property of the ``device_lists``
|
||||||
|
field, and as a result should remove her from its list of tracked users.
|
||||||
|
|
||||||
.. |device_lists| replace:: ``device_lists``
|
.. |device_lists| replace:: ``device_lists``
|
||||||
.. _`device_lists`: `device_lists_sync`_
|
.. _`device_lists`: `device_lists_sync`_
|
||||||
|
|
||||||
|
@ -228,10 +235,238 @@ 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
|
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.
|
time key once it has given that key to another user.
|
||||||
|
|
||||||
|
Device verification
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Before Alice sends Bob encrypted data, or trusts data received from him, she
|
||||||
|
may want to verify that she is actually communicating with him, rather than a
|
||||||
|
man-in-the-middle. This verification process requires an out-of-band channel:
|
||||||
|
there is no way to do it within Matrix without trusting the administrators of
|
||||||
|
the homeservers.
|
||||||
|
|
||||||
|
In Matrix, the basic process for device verification is for Alice to verify
|
||||||
|
that the public Ed25519 signing key she received via ``/keys/query`` for Bob's
|
||||||
|
device corresponds to the private key in use by Bob's device. For now, it is
|
||||||
|
recommended that clients provide mechanisms by which the user can see:
|
||||||
|
|
||||||
|
1. The public part of their device's Ed25519 signing key, encoded using
|
||||||
|
`unpadded Base64`_.
|
||||||
|
|
||||||
|
2. The list of devices in use for each user in a room, along with the public
|
||||||
|
Ed25519 signing key for each device, again encoded using unpadded Base64.
|
||||||
|
|
||||||
|
Alice can then meet Bob in person, or contact him via some other trusted
|
||||||
|
medium, and ask him to read out the Ed25519 key shown on his device. She
|
||||||
|
compares this with the value shown for his device on her client.
|
||||||
|
|
||||||
|
Device verification may reach one of several conclusions. For example:
|
||||||
|
|
||||||
|
* Alice may "accept" the device. This means that she is satisfied that the
|
||||||
|
device belongs to Bob. She can then encrypt sensitive material for that
|
||||||
|
device, and knows that messages received were sent from that device.
|
||||||
|
|
||||||
|
* Alice may "reject" the device. She will do this if she knows or suspects
|
||||||
|
that Bob does not control that device (or equivalently, does not trust
|
||||||
|
Bob). She will not send sensitive material to that device, and cannot trust
|
||||||
|
messages apparently received from it.
|
||||||
|
|
||||||
|
* Alice may choose to skip the device verification process. She is not able
|
||||||
|
to verify that the device actually belongs to Bob, but has no reason to
|
||||||
|
suspect otherwise. The encryption protocol continues to protect against
|
||||||
|
passive eavesdroppers.
|
||||||
|
|
||||||
|
.. NOTE::
|
||||||
|
|
||||||
|
Once the signing key has been verified, it is then up to the encryption
|
||||||
|
protocol to verify that a given message was sent from a device holding that
|
||||||
|
Ed25519 private key, or to encrypt a message so that it may only be
|
||||||
|
decrypted by such a device. For the Olm protocol, this is documented at
|
||||||
|
https://matrix.org/git/olm/about/docs/signing.rst.
|
||||||
|
|
||||||
|
Messaging Algorithms
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Messaging Algorithm Names
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Messaging algorithm names use the extensible naming scheme used throughout this
|
||||||
|
specification. Algorithm names that start with ``m.`` are reserved for
|
||||||
|
algorithms defined by this specification. Implementations wanting to experiment
|
||||||
|
with new algorithms must be uniquely globally namespaced following Java's package
|
||||||
|
naming conventions.
|
||||||
|
|
||||||
|
Algorithm names should be short and meaningful, and should list the primitives
|
||||||
|
used by the algorithm so that it is easier to see if the algorithm is using a
|
||||||
|
broken primitive.
|
||||||
|
|
||||||
|
A name of ``m.olm.v1`` is too short: it gives no information about the primitives
|
||||||
|
in use, and is difficult to extend for different primitives. However a name of
|
||||||
|
``m.olm.v1.ecdh-curve25519-hdkfsha256.hmacsha256.hkdfsha256-aes256-cbc-hmac64sha256``
|
||||||
|
is too long despite giving a more precise description of the algorithm: it adds
|
||||||
|
to the data transfer overhead and sacrifices clarity for human readers without
|
||||||
|
adding any useful extra information.
|
||||||
|
|
||||||
|
``m.olm.v1.curve25519-aes-sha2``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The name ``m.olm.v1.curve25519-aes-sha2`` corresponds to version 1 of the Olm
|
||||||
|
ratchet, as defined by the `Olm specification`_. This uses:
|
||||||
|
|
||||||
|
* Curve25519 for the initial key agreement.
|
||||||
|
* HKDF-SHA-256 for ratchet key derivation.
|
||||||
|
* Curve25519 for the root key ratchet.
|
||||||
|
* HMAC-SHA-256 for the chain key ratchet.
|
||||||
|
* HKDF-SHA-256, AES-256 in CBC mode, and 8 byte truncated HMAC-SHA-256 for authenticated encryption.
|
||||||
|
|
||||||
|
Devices that support Olm must include "m.olm.v1.curve25519-aes-sha2" in their
|
||||||
|
list of supported messaging algorithms, must list a Curve25519 device key, and
|
||||||
|
must publish Curve25519 one-time keys.
|
||||||
|
|
||||||
|
An event encrypted using Olm has the following format:
|
||||||
|
|
||||||
|
.. code:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "m.room.encrypted",
|
||||||
|
"content": {
|
||||||
|
"algorithm": "m.olm.v1.curve25519-aes-sha2",
|
||||||
|
"sender_key": "<sender_curve25519_key>",
|
||||||
|
"ciphertext": {
|
||||||
|
"<device_curve25519_key>": {
|
||||||
|
"type": 0,
|
||||||
|
"body": "<encrypted_payload_base_64>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
``ciphertext`` is a mapping from device Curve25519 key to an encrypted payload
|
||||||
|
for that device. ``body`` is a Base64-encoded Olm message body. ``type`` is an
|
||||||
|
integer indicating the type of the message body: 0 for the initial pre-key
|
||||||
|
message, 1 for ordinary messages.
|
||||||
|
|
||||||
|
Olm sessions will generate messages with a type of 0 until they receive a
|
||||||
|
message. Once a session has decrypted a message it will produce messages with
|
||||||
|
a type of 1.
|
||||||
|
|
||||||
|
When a client receives a message with a type of 0 it must first check if it
|
||||||
|
already has a matching session. If it does then it will use that session to
|
||||||
|
try to decrypt the message. If there is no existing session then the client
|
||||||
|
must create a new session and use the new session to decrypt the message. A
|
||||||
|
client must not persist a session or remove one-time keys used by a session
|
||||||
|
until it has successfully decrypted a message using that session.
|
||||||
|
|
||||||
|
Messages with type 1 can only be decrypted with an existing session. If there
|
||||||
|
is no matching session, the client must treat this as an invalid message.
|
||||||
|
|
||||||
|
The plaintext payload is of the form:
|
||||||
|
|
||||||
|
.. code:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "<type of the plaintext event>",
|
||||||
|
"content": "<content for the plaintext event>",
|
||||||
|
"sender": "<sender_user_id>",
|
||||||
|
"recipient": "<recipient_user_id>",
|
||||||
|
"recipient_keys": {
|
||||||
|
"ed25519": "<our_ed25519_key>"
|
||||||
|
},
|
||||||
|
"keys": {
|
||||||
|
"ed25519": "<sender_ed25519_key>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
The type and content of the plaintext message event are given in the payload.
|
||||||
|
|
||||||
|
Other properties are included in order to prevent an attacker from publishing
|
||||||
|
someone else's curve25519 keys as their own and subsequently claiming to have
|
||||||
|
sent messages which they didn't.
|
||||||
|
``sender`` must correspond to the user who sent the event, ``recipient`` to
|
||||||
|
the local user, and ``recipient_keys`` to the local ed25519 key.
|
||||||
|
|
||||||
|
Clients must confirm that the ``sender_key`` and the ``ed25519`` field value
|
||||||
|
under the ``keys`` property match the keys returned by |/keys/query|_ for
|
||||||
|
the given user, and must also verify the signature of the payload. Without
|
||||||
|
this check, a client cannot be sure that the sender device owns the private
|
||||||
|
part of the ed25519 key it claims to have in the Olm payload.
|
||||||
|
This is crucial when the ed25519 key corresponds to a verified device.
|
||||||
|
|
||||||
|
``m.megolm.v1.aes-sha2``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The name ``m.megolm.v1.aes-sha2`` corresponds to version 1 of the Megolm
|
||||||
|
ratchet, as defined by the `Megolm specification`_. This uses:
|
||||||
|
|
||||||
|
* HMAC-SHA-256 for the hash ratchet.
|
||||||
|
* HKDF-SHA-256, AES-256 in CBC mode, and 8 byte truncated HMAC-SHA-256 for authenticated encryption.
|
||||||
|
* Ed25519 for message authenticity.
|
||||||
|
|
||||||
|
Devices that support Megolm must support Olm, and include "m.megolm.v1.aes-sha2" in
|
||||||
|
their list of supported messaging algorithms.
|
||||||
|
|
||||||
|
An event encrypted using Megolm has the following format:
|
||||||
|
|
||||||
|
.. code:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "m.room.encrypted",
|
||||||
|
"content": {
|
||||||
|
"algorithm": "m.megolm.v1.aes-sha2",
|
||||||
|
"sender_key": "<sender_curve25519_key>",
|
||||||
|
"device_id": "<sender_device_id>",
|
||||||
|
"session_id": "<outbound_group_session_id>",
|
||||||
|
"ciphertext": "<encypted_payload_base_64>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
The encrypted payload can contain any message event. The plaintext is of the form:
|
||||||
|
|
||||||
|
.. code:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "<event_type>",
|
||||||
|
"content": "<event_content>",
|
||||||
|
"room_id": "<the room_id>"
|
||||||
|
}
|
||||||
|
|
||||||
|
We include the room ID in the payload, because otherwise the homeserver would
|
||||||
|
be able to change the room a message was sent in.
|
||||||
|
|
||||||
|
Clients must guard against replay attacks by keeping track of the ratchet indices
|
||||||
|
of Megolm sessions. They should reject messages with a ratchet index that they
|
||||||
|
have already decrypted. Care should be taken in order to avoid false positives, as a
|
||||||
|
client may decrypt the same event twice as part of its normal processing.
|
||||||
|
|
||||||
|
As with Olm events, clients must confirm that the ``sender_key`` belongs to the user
|
||||||
|
who sent the message. The same reasoning applies, but the sender ed25519 key has to be
|
||||||
|
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
|
||||||
|
``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
|
||||||
|
must also handle ``m.room_key`` events sent by other devices in order to decrypt their
|
||||||
|
messages.
|
||||||
|
|
||||||
Protocol definitions
|
Protocol definitions
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
Events
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
{{m_room_encryption_event}}
|
||||||
|
|
||||||
|
{{m_room_encrypted_event}}
|
||||||
|
|
||||||
|
{{m_room_key_event}}
|
||||||
|
|
||||||
|
Key management API
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
{{keys_cs_http_api}}
|
{{keys_cs_http_api}}
|
||||||
|
|
||||||
|
|
||||||
|
@ -249,6 +484,9 @@ specified). The client is expected to use |/keys/query|_ or |/keys/changes|_
|
||||||
for the equivalent functionality after an initial sync, as documented in
|
for the equivalent functionality after an initial sync, as documented in
|
||||||
`Tracking the device list for a user`_.
|
`Tracking the device list for a user`_.
|
||||||
|
|
||||||
|
It also adds a ``one_time_keys_count`` property. Note the spelling difference
|
||||||
|
with the ``one_time_key_counts`` property in the |/keys/upload|_ response.
|
||||||
|
|
||||||
.. todo: generate this from a swagger definition?
|
.. todo: generate this from a swagger definition?
|
||||||
|
|
||||||
.. device_lists: { changed: ["@user:server", ... ]},
|
.. device_lists: { changed: ["@user:server", ... ]},
|
||||||
|
@ -258,6 +496,9 @@ Parameter Type Description
|
||||||
============ =========== =====================================================
|
============ =========== =====================================================
|
||||||
device_lists DeviceLists Optional. Information on e2e device updates. Note:
|
device_lists DeviceLists Optional. Information on e2e device updates. Note:
|
||||||
only present on an incremental sync.
|
only present on an incremental sync.
|
||||||
|
|device_otk| {string: Optional. For each key algorithm, the number of
|
||||||
|
integer} unclaimed one-time keys currently held on the server
|
||||||
|
for this device.
|
||||||
============ =========== =====================================================
|
============ =========== =====================================================
|
||||||
|
|
||||||
``DeviceLists``
|
``DeviceLists``
|
||||||
|
@ -265,10 +506,20 @@ device_lists DeviceLists Optional. Information on e2e device updates. Note:
|
||||||
========= ========= =============================================
|
========= ========= =============================================
|
||||||
Parameter Type Description
|
Parameter Type Description
|
||||||
========= ========= =============================================
|
========= ========= =============================================
|
||||||
changed [string] List of users who have updated their device identity keys
|
changed [string] List of users who have updated their device identity keys,
|
||||||
since the previous sync response.
|
or who now share an encrypted room with the client since
|
||||||
|
the previous sync response.
|
||||||
|
left [string] List of users with whom we do not share any encrypted rooms
|
||||||
|
anymore since the previous sync response.
|
||||||
========= ========= =============================================
|
========= ========= =============================================
|
||||||
|
|
||||||
|
.. NOTE::
|
||||||
|
|
||||||
|
For optimal performance, Alice should be added to ``changed`` in Bob's sync only
|
||||||
|
when she adds a new device, or when Alice and Bob now share a room but didn't
|
||||||
|
share any room previously. However, for the sake of simpler logic, a server
|
||||||
|
may add Alice to ``changed`` when Alice and Bob share a new room, even if they
|
||||||
|
previously already shared a room.
|
||||||
|
|
||||||
Example response:
|
Example response:
|
||||||
|
|
||||||
|
@ -281,17 +532,27 @@ Example response:
|
||||||
"changed": [
|
"changed": [
|
||||||
"@alice:example.com",
|
"@alice:example.com",
|
||||||
],
|
],
|
||||||
|
"left": [
|
||||||
|
"@bob:example.com",
|
||||||
|
],
|
||||||
},
|
},
|
||||||
|
"device_one_time_keys_count": {
|
||||||
|
"curve25519": 10,
|
||||||
|
"signed_curve25519": 20
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.. References
|
.. References
|
||||||
|
|
||||||
.. _ed25519: http://ed25519.cr.yp.to/
|
.. _ed25519: http://ed25519.cr.yp.to/
|
||||||
.. _curve25519: https://cr.yp.to/ecdh.html
|
.. _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
|
||||||
|
|
||||||
.. _`Signing JSON`: ../appendices.html#signing-json
|
.. _`Signing JSON`: ../appendices.html#signing-json
|
||||||
|
|
||||||
.. |m.olm.v1.curve25519-aes-sha2| replace:: ``m.olm.v1.curve25519-aes-sha2``
|
.. |m.olm.v1.curve25519-aes-sha2| replace:: ``m.olm.v1.curve25519-aes-sha2``
|
||||||
|
.. |device_otk| replace:: device_one_time_keys_count
|
||||||
|
|
||||||
.. |/keys/upload| replace:: ``/keys/upload``
|
.. |/keys/upload| replace:: ``/keys/upload``
|
||||||
.. _/keys/upload: #post-matrix-client-%CLIENT_MAJOR_VERSION%-keys-upload
|
.. _/keys/upload: #post-matrix-client-%CLIENT_MAJOR_VERSION%-keys-upload
|
||||||
|
|
|
@ -50,6 +50,8 @@ The following API endpoints are allowed to be accessed by guest accounts for
|
||||||
retrieving events:
|
retrieving events:
|
||||||
|
|
||||||
* `GET /rooms/:room_id/state <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state>`_
|
* `GET /rooms/:room_id/state <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state>`_
|
||||||
|
* `GET /rooms/:room_id/context/:event_id <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-context-eventid>`_
|
||||||
|
* `GET /rooms/:room_id/event/:event_id <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-event-eventid>`_
|
||||||
* `GET /rooms/:room_id/state/:event_type/:state_key <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state-eventtype-statekey>`_
|
* `GET /rooms/:room_id/state/:event_type/:state_key <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state-eventtype-statekey>`_
|
||||||
* `GET /rooms/:room_id/messages <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-messages>`_
|
* `GET /rooms/:room_id/messages <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-messages>`_
|
||||||
* `GET /rooms/:room_id/initialSync <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-initialsync>`_
|
* `GET /rooms/:room_id/initialSync <#get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-initialsync>`_
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue