Compare commits

...

8 commits

Author SHA1 Message Date
Johannes Marbach ae25ddf38c
Merge d05a26b24e into 643a6dca2d 2025-05-28 19:51:20 +02:00
Johannes Marbach 643a6dca2d
Spec PR - MSC4147: Including device keys with Olm-encrypted events (#2122)
Some checks failed
Spec / 🔎 Validate OpenAPI specifications (push) Has been cancelled
Spec / 🔎 Check Event schema examples (push) Has been cancelled
Spec / 🔎 Check OpenAPI definitions examples (push) Has been cancelled
Spec / 🔎 Check JSON Schemas inline examples (push) Has been cancelled
Spec / ⚙️ Calculate baseURL for later jobs (push) Has been cancelled
Spec / 📢 Run towncrier for changelog (push) Has been cancelled
Spell Check / Spell Check with Typos (push) Has been cancelled
Spec / 🐍 Build OpenAPI definitions (push) Has been cancelled
Spec / 📖 Build the spec (push) Has been cancelled
Spec / 🔎 Validate generated HTML (push) Has been cancelled
Spec / 📖 Build the historical backup spec (push) Has been cancelled
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
Co-authored-by: Richard van der Hoff <richard@matrix.org>
2025-05-28 18:50:27 +01:00
Johannes Marbach d05a26b24e
Update content/client-server-api/modules/spaces.md 2025-05-21 23:00:48 +02:00
Johannes Marbach 20828ee354
Update content/client-server-api/modules/spaces.md 2025-05-21 22:58:24 +02:00
Johannes Marbach dd8aaa0d66
Update content/client-server-api/modules/spaces.md 2025-05-21 22:57:43 +02:00
Richard van der Hoff 3946435d7f
Merge branch 'main' into johannes/public-rooms-spaces 2025-05-21 17:42:26 +01:00
Johannes Marbach 339ea6be12 Add changelog 2025-03-20 16:32:19 +01:00
Johannes Marbach ba4252afe5 Clarify the meaning of "public spaces"
Relates to: #633
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
2025-03-20 16:20:58 +01:00
5 changed files with 163 additions and 41 deletions

View file

@ -0,0 +1 @@
Spaces are subject to the same access mechanisms as rooms.

View file

@ -0,0 +1 @@
Include device keys with Olm-encrypted events as per [MSC4147](https://github.com/matrix-org/matrix-spec-proposals/pull/4147).

View file

@ -1512,40 +1512,11 @@ message.
The plaintext payload is of the form:
```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>"
}
}
```
{{% definition path="api/client-server/definitions/olm_payload" %}}
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` property in the cleartext
`m.room.encrypted` event body, and the `keys.ed25519` property in the
decrypted plaintext, match the keys returned by
[`/keys/query`](#post_matrixclientv3keysquery) for
the given user. Clients must also verify the signature of the keys from the
`/keys/query` response. 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.
If a client has multiple sessions established with another device, it
should use the session from which it last received and successfully
decrypted a message. For these purposes, a session that has not received
@ -1555,6 +1526,68 @@ maximum number of olm sessions that it will maintain for each device,
and expiring sessions on a Least Recently Used basis. The maximum number
of olm sessions maintained per device should be at least 4.
###### Validation of incoming decrypted events
{{% changed-in v="1.15" %}} Existing checks made more explicit, and checks for `sender_device_keys` added.
After decrypting an incoming encrypted event, clients MUST apply the
following checks:
1. The `sender` property in the decrypted content must match the
`sender` of the event.
2. The `keys.ed25519` property in the decrypted content must match
the `sender_key` property in the cleartext `m.room.encrypted`
event body.
3. The `recipient` property in the decrypted content must match
the user ID of the local user.
4. The `recipient_keys.ed25519` property in the decrypted content
must match the client device's [Ed25519 signing key](#device-keys).
5. Where `sender_device_keys` is present in the decrypted content:
1. `sender_device_keys.user_id` must also match the `sender`
of the event.
2. `sender_device_keys.keys.ed25519:<device_id>` must also match
the `sender_key` property in the cleartext `m.room.encrypted`
event body.
3. `sender_device_keys.keys.curve25519:<device_id>` must match
the Curve25519 key used to establish the Olm session.
4. The `sender_device_keys` structure must have a valid signature
from the key with ID `ed25519:<device_id>` (i.e., the sending
device's Ed25519 key).
Any event that does not comply with these checks MUST be discarded.
###### Verification of the sending user for incoming events
{{% added-in v="1.15" %}}
In addition, for each Olm session, clients MUST verify that the
Curve25519 key used to establish the Olm session does indeed belong
to the claimed `sender`. This requires a signed "device keys" structure
for that Curve25519 key, which can be obtained in one of two ways:
1. An Olm message may be received with a `sender_device_keys` property
in the decrypted content.
2. The keys are returned via a [`/keys/query`](#post_matrixclientv3keysquery)
request. Note that both the Curve25519 key **and** the Ed25519 key in
the returned device keys structure must match those used in an
Olm-encrypted event as above. (In particular, the Ed25519 key must
be present in the **encrypted** content of an Olm-encrypted event
to prevent an attacker from claiming another user's Curve25519 key
as their own.)
Ownership of the Curve25519 key is then established in one of two ways:
1. Via [cross-signing](#cross-signing). For this to be sufficient, the
device keys structure must be signed by the sender's self-signing key,
and that self-signing key must itself have been validated (either via
[explicit verification](#device-verification) or a "trust on first use" (TOFU) mechanism).
2. Via explicit verification of the device's Ed25519 signing key, as
contained in the device keys structure. This is no longer recommended.
A failure to complete these verifications does not necessarily mean that
the session is bogus; however it is the case that there is no proof that
the claimed sender is accurate, and the user should be warned accordingly.
###### Recovering from undecryptable messages
Occasionally messages may be undecryptable by clients due to a variety

View file

@ -2,8 +2,8 @@
{{% added-in v="1.2" %}}
Often used to group rooms of similar subject matter (such as a public "Official
matrix.org rooms" space or personal "Work stuff" space), spaces are a way to
Often used to group rooms of similar subject matter (such as an "Official
matrix.org rooms" space or a "Work stuff" space), spaces are a way to
organise rooms while being represented as rooms themselves.
A space is defined by the [`m.space` room type](#types), making it known as a
@ -18,11 +18,11 @@ In the default power level structure, this would be `100`. Clients might wish to
go a step further and explicitly ignore notification counts on space-rooms.
Membership of a space is defined and controlled by the existing mechanisms which
govern a room: [`m.room.member`](#mroommember), [`m.room.history_visibility`](#mroomhistory_visibility),
and [`m.room.join_rules`](#mroomjoin_rules). Public spaces are encouraged to have
a similar setup to public rooms: `world_readable` history visibility, published
canonical alias, and suitably public `join_rule`. Invites, including third-party
invites, still work just as they do in normal rooms as well.
govern a room: [`m.room.member`](/client-server-api#mroommember), [`m.room.history_visibility`](/client-server-api#mroomhistory_visibility),
and [`m.room.join_rules`](/client-server-api#mroomjoin_rules). Canonical aliases and invites, including
third-party invites, still work just as they do in normal rooms as well. Furthermore,
spaces can also be published in the [room directory](/client-server-api#published-room-directory) to make them
discoverable.
All other aspects of regular rooms are additionally carried over, such as the
ability to set arbitrary state events, hold room account data, etc. Spaces are
@ -87,10 +87,9 @@ the state of `#space:example.org` would consist of:
}
```
No state events in the child rooms themselves would be required (though they
can also be present). This allows for users
to define personal/private spaces to organise their own rooms without needing explicit
permission from the room moderators/admins.
No state events in the child rooms themselves would be required (though they can also
be present). This allows for users to define spaces without needing explicit permission
from the room moderators/admins.
Child rooms can be removed from a space by omitting the `via` key of `content` on the
relevant state event, such as through redaction or otherwise clearing the `content`.

View file

@ -0,0 +1,88 @@
# Copyright 2025 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: OlmPayload
description: |-
The plaintext payload of Olm message events.
properties:
type:
type: string
description: The type of the event.
content:
type: object
description: The event content.
sender:
type: string
description: The user ID of the event sender.
recipient:
type: string
description: The user ID of the intended event recipient.
recipient_keys:
description: The recipient's signing keys of the encrypted event.
$ref: "#/components/schemas/SigningKeys"
keys:
$ref: "#/components/schemas/SigningKeys"
description: The sender's signing keys of the encrypted event.
sender_device_keys:
$ref: device_keys.yaml
description: The sender's device keys.
x-addedInMatrixVersion: "1.15"
required:
- type
- content
- sender
- recipient
- recipient_keys
- keys
components:
schemas:
SigningKeys:
type: object
title: SigningKeys
description: Public keys used for an `m.olm.v1.curve25519-aes-sha2` event.
properties:
ed25519:
type: string
description: The Ed25519 public key encoded using unpadded base64.
required:
- ed25519
example: {
"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>"
},
"sender_device_keys": {
"algorithms": ["<supported>", "<algorithms>"],
"user_id": "<user_id>",
"device_id": "<device_id>",
"keys": {
"ed25519:<device_id>": "<sender_ed25519_key>",
"curve25519:<device_id>": "<sender_curve25519_key>"
},
"signatures": {
"<user_id>": {
"ed25519:<device_id>": "<device_signature>",
"ed25519:<ssk_id>": "<ssk_signature>",
}
}
}
}