Merge pull request #2536 from uhoreg/cross-signing-spec
initial spec for cross-signing
This commit is contained in:
commit
f352de90c3
13 changed files with 665 additions and 8 deletions
224
api/client-server/cross_signing.yaml
Normal file
224
api/client-server/cross_signing.yaml
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
# Copyright 2020 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.
|
||||||
|
swagger: '2.0'
|
||||||
|
info:
|
||||||
|
title: "Matrix Client-Server Cross Signing API"
|
||||||
|
version: "1.0.0"
|
||||||
|
host: localhost:8008
|
||||||
|
schemes:
|
||||||
|
- https
|
||||||
|
- http
|
||||||
|
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
securityDefinitions:
|
||||||
|
$ref: definitions/security.yaml
|
||||||
|
paths:
|
||||||
|
"/keys/device_signing/upload":
|
||||||
|
post:
|
||||||
|
summary: Upload cross-signing keys.
|
||||||
|
description: |-
|
||||||
|
Publishes cross-signing keys for the user.
|
||||||
|
|
||||||
|
This API endpoint uses the `User-Interactive Authentication API`_.
|
||||||
|
operationId: uploadCrossSigningKeys
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: keys
|
||||||
|
description: |-
|
||||||
|
The keys to be published.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
master_key:
|
||||||
|
description: |-
|
||||||
|
Optional. The user\'s master key.
|
||||||
|
allOf:
|
||||||
|
- $ref: definitions/cross_signing_key.yaml
|
||||||
|
self_signing_key:
|
||||||
|
description: |-
|
||||||
|
Optional. The user\'s self-signing key. Must be signed by
|
||||||
|
the accompanying master key, or by the user\'s most recently
|
||||||
|
uploaded master key if no master key is included in the
|
||||||
|
request.
|
||||||
|
allOf:
|
||||||
|
- $ref: definitions/cross_signing_key.yaml
|
||||||
|
user_signing_key:
|
||||||
|
description: |-
|
||||||
|
Optional. The user\'s user-signing key. Must be signed by
|
||||||
|
the accompanying master key, or by the user\'s most recently
|
||||||
|
uploaded master key if no master key is included in the
|
||||||
|
request.
|
||||||
|
allOf:
|
||||||
|
- $ref: definitions/cross_signing_key.yaml
|
||||||
|
example: {
|
||||||
|
"master_key": {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"usage": ["master"],
|
||||||
|
"keys": {
|
||||||
|
"ed25519:base64+master+public+key": "base64+master+public+key",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"self_signing_key": {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"usage": ["self_signing"],
|
||||||
|
"keys": {
|
||||||
|
"ed25519:base64+self+signing+public+key": "base64+self+signing+master+public+key",
|
||||||
|
},
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"ed25519:base64+master+public+key": "signature+of+self+signing+key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user_signing_key": {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"usage": ["user_signing"],
|
||||||
|
"keys": {
|
||||||
|
"ed25519:base64+user+signing+public+key": "base64+user+signing+master+public+key",
|
||||||
|
},
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"ed25519:base64+master+public+key": "signature+of+user+signing+key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The provided keys were successfully uploaded.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
example: {}
|
||||||
|
400:
|
||||||
|
description: |-
|
||||||
|
The input was invalid in some way. This can include one of the
|
||||||
|
following error codes:
|
||||||
|
|
||||||
|
* ``M_INVALID_SIGNATURE``: For example, the self-signing or
|
||||||
|
user-signing key had an incorrect signature.
|
||||||
|
* ``M_MISSING_PARAM``: No master key is available.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
example: {
|
||||||
|
"errcode": "M_INVALID_SIGNATURE",
|
||||||
|
"error": "Invalid signature"
|
||||||
|
}
|
||||||
|
403:
|
||||||
|
description: |-
|
||||||
|
The public key of one of the keys is the same as one of the user\'s
|
||||||
|
device IDs, or the request is not authorized for any other reason.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
example: {
|
||||||
|
"errcode": "M_FORBIDDEN",
|
||||||
|
"error": "Key ID in use"
|
||||||
|
}
|
||||||
|
"/keys/signatures/upload":
|
||||||
|
post:
|
||||||
|
summary: Upload cross-signing signatures.
|
||||||
|
description: |-
|
||||||
|
Publishes cross-signing signatures for the user. The request body is a
|
||||||
|
map from user ID to key ID to signed JSON object.
|
||||||
|
operationId: uploadCrossSigningSignatures
|
||||||
|
security:
|
||||||
|
- accessToken: []
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: signatures
|
||||||
|
description: |-
|
||||||
|
The signatures to be published.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
title: Signatures
|
||||||
|
additionalProperties:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: object
|
||||||
|
example: {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"HIJKLMN": {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"device_id": "HIJKLMN",
|
||||||
|
"algorithms": [
|
||||||
|
"m.olm.curve25519-aes-sha256",
|
||||||
|
"m.megolm.v1.aes-sha"
|
||||||
|
],
|
||||||
|
"keys": {
|
||||||
|
"curve25519:HIJKLMN": "base64+curve25519+key",
|
||||||
|
"ed25519:HIJKLMN": "base64+ed25519+key"
|
||||||
|
},
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"ed25519:base64+self+signing+public+key": "base64+signature+of+HIJKLMN"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"base64+master+public+key": {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"usage": ["master"],
|
||||||
|
"keys": {
|
||||||
|
"ed25519:base64+master+public+key": "base64+master+public+key"
|
||||||
|
},
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"ed25519:HIJKLMN": "base64+signature+of+master+key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@bob:example.com": {
|
||||||
|
"bobs+base64+master+public+key": {
|
||||||
|
"user_id": "@bob:example.com",
|
||||||
|
"keys": {
|
||||||
|
"ed25519:bobs+base64+master+public+key": "bobs+base64+master+public+key"
|
||||||
|
},
|
||||||
|
"usage": ["master"],
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"ed25519:base64+user+signing+public+key": "base64+signature+of+bobs+master+key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: The provided signatures were processed.
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
failures:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
A map from user ID to key ID to an error for any signatures
|
||||||
|
that failed. If a signature was invalid, the ``errcode`` will
|
||||||
|
be set to ``M_INVALID_SIGNATURE``.
|
||||||
|
additionalProperties:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: object
|
||||||
|
title: Error
|
||||||
|
example: {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"HIJKLMN": {
|
||||||
|
"errcode": "M_INVALID_SIGNATURE",
|
||||||
|
"error": "Invalid signature"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
55
api/client-server/definitions/cross_signing_key.yaml
Normal file
55
api/client-server/definitions/cross_signing_key.yaml
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
# Copyright 2020 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: CrossSigningKey
|
||||||
|
description: Cross signing key
|
||||||
|
properties:
|
||||||
|
user_id:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The ID of the user the key belongs to.
|
||||||
|
example: "@alice:example.com"
|
||||||
|
usage:
|
||||||
|
type: array
|
||||||
|
description: |-
|
||||||
|
What the key is used for.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
enum: ["master", "self_signing", "user_signing"]
|
||||||
|
keys:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The public key. The object must have exactly one property, whose name is
|
||||||
|
in the form ``<algorithm>:<unpadded_base64_public_key>``, and whose value
|
||||||
|
is the unpadded base64 public key.
|
||||||
|
example:
|
||||||
|
"ed25519:alice+base64+public+key": "alice+base64+public+key"
|
||||||
|
signatures:
|
||||||
|
type: object
|
||||||
|
title: Signatures
|
||||||
|
description: |-
|
||||||
|
Signatures of the key, calculated using the process described at `Signing
|
||||||
|
JSON`_. Optional for the master key. Other keys must be signed by the
|
||||||
|
user\'s master key.
|
||||||
|
example: {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"ed25519:alice+base64+master+key": "signature+of+key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
required:
|
||||||
|
- user_id
|
||||||
|
- usage
|
||||||
|
- keys
|
|
@ -1,5 +1,6 @@
|
||||||
# Copyright 2016 OpenMarket Ltd
|
# Copyright 2016 OpenMarket Ltd
|
||||||
# Copyright 2018 New Vector Ltd
|
# Copyright 2018 New Vector Ltd
|
||||||
|
# Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
#
|
#
|
||||||
# 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.
|
||||||
|
@ -236,7 +237,76 @@ paths:
|
||||||
"device_display_name": "Alice's mobile phone"
|
"device_display_name": "Alice's mobile phone"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
master_keys:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
Information on the master cross-signing keys of the queried users.
|
||||||
|
A map from user ID, to master key information. For each key, the
|
||||||
|
information returned will be the same as uploaded via
|
||||||
|
``/keys/device_signing/upload``, along with the signatures
|
||||||
|
uploaded via ``/keys/signatures/upload`` that the requesting user
|
||||||
|
is allowed to see.
|
||||||
|
additionalProperties:
|
||||||
|
allOf:
|
||||||
|
- $ref: definitions/cross_signing_key.yaml
|
||||||
|
example: {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"usage": ["master"],
|
||||||
|
"keys": {
|
||||||
|
"ed25519:base64+master+public+key": "base64+master+public+key",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self_signing_keys:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
Information on the self-signing keys of the queried users. A map
|
||||||
|
from user ID, to self-signing key information. For each key, the
|
||||||
|
information returned will be the same as uploaded via
|
||||||
|
``/keys/device_signing/upload``.
|
||||||
|
additionalProperties:
|
||||||
|
allOf:
|
||||||
|
- $ref: definitions/cross_signing_key.yaml
|
||||||
|
example: {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"usage": ["self_signing"],
|
||||||
|
"keys": {
|
||||||
|
"ed25519:base64+self+signing+public+key": "base64+self+signing+master+public+key",
|
||||||
|
},
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"ed25519:base64+master+public+key": "signature+of+self+signing+key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
user_signing_keys:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
Information on the user-signing key of the user making the
|
||||||
|
request, if they queried their own device information. A map
|
||||||
|
from user ID, to user-signing key information. The
|
||||||
|
information returned will be the same as uploaded via
|
||||||
|
``/keys/device_signing/upload``.
|
||||||
|
additionalProperties:
|
||||||
|
allOf:
|
||||||
|
- $ref: definitions/cross_signing_key.yaml
|
||||||
|
example: {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"usage": ["user_signing"],
|
||||||
|
"keys": {
|
||||||
|
"ed25519:base64+user+signing+public+key": "base64+user+signing+master+public+key",
|
||||||
|
},
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"ed25519:base64+master+public+key": "signature+of+user+signing+key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
tags:
|
tags:
|
||||||
- End-to-end encryption
|
- End-to-end encryption
|
||||||
"/keys/claim":
|
"/keys/claim":
|
||||||
|
|
|
@ -123,8 +123,10 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
description: |-
|
description: |-
|
||||||
ID of the client device. If this does not correspond to a
|
ID of the client device. If this does not correspond to a
|
||||||
known client device, a new device will be created. The server
|
known client device, a new device will be created. The given
|
||||||
will auto-generate a device_id if this is not specified.
|
device ID must not be the same as a `cross-signing key ID
|
||||||
|
<#cross-signing>`_. The server will auto-generate a device_id
|
||||||
|
if this is not specified.
|
||||||
initial_device_display_name:
|
initial_device_display_name:
|
||||||
type: string
|
type: string
|
||||||
description: |-
|
description: |-
|
||||||
|
@ -195,7 +197,9 @@ paths:
|
||||||
403:
|
403:
|
||||||
description: |-
|
description: |-
|
||||||
The login attempt failed. This can include one of the following error codes:
|
The login attempt failed. This can include one of the following error codes:
|
||||||
* ``M_FORBIDDEN``: The provided authentication data was incorrect.
|
* ``M_FORBIDDEN``: The provided authentication data was incorrect
|
||||||
|
or the requested device ID is the same as a cross-signing key
|
||||||
|
ID.
|
||||||
* ``M_USER_DEACTIVATED``: The user has been deactivated.
|
* ``M_USER_DEACTIVATED``: The user has been deactivated.
|
||||||
examples:
|
examples:
|
||||||
application/json: {
|
application/json: {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# Copyright 2018 New Vector Ltd
|
# Copyright 2018 New Vector Ltd
|
||||||
|
# Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
#
|
#
|
||||||
# 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.
|
||||||
|
@ -17,7 +18,8 @@ title: m.device_list_update
|
||||||
description: |-
|
description: |-
|
||||||
An EDU that lets servers push details to each other when one of their users
|
An EDU that lets servers push details to each other when one of their users
|
||||||
adds a new device to their account, required for E2E encryption to correctly
|
adds a new device to their account, required for E2E encryption to correctly
|
||||||
target the current set of devices for a given user.
|
target the current set of devices for a given user. This event will also be
|
||||||
|
sent when an existing device gets a new cross-signing signature.
|
||||||
|
|
||||||
# FIXME: It's very unclear why we have this API surface for synchronising
|
# FIXME: It's very unclear why we have this API surface for synchronising
|
||||||
# device lists, rather than just using a room (which could also be used for
|
# device lists, rather than just using a room (which could also be used for
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
# Copyright 2020 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: m.signing_key_update
|
||||||
|
description: |-
|
||||||
|
An EDU that lets servers push details to each other when one of their users
|
||||||
|
updates their cross-signing keys.
|
||||||
|
allOf:
|
||||||
|
- $ref: ../edu.yaml
|
||||||
|
- type: object
|
||||||
|
properties:
|
||||||
|
edu_type:
|
||||||
|
type: enum
|
||||||
|
enum: ['m.signing_key_update']
|
||||||
|
description: The string ``m.signing_update``.
|
||||||
|
example: "m.signing_key_update"
|
||||||
|
content:
|
||||||
|
type: object
|
||||||
|
description: The updated signing keys.
|
||||||
|
title: Signing Key Update
|
||||||
|
properties:
|
||||||
|
user_id:
|
||||||
|
type: string
|
||||||
|
description: The user ID whose cross-signing keys have changed.
|
||||||
|
example: "@alice:example.com"
|
||||||
|
master_key:
|
||||||
|
type: object
|
||||||
|
$ref: ../../../client-server/definitions/cross_signing_key.yaml
|
||||||
|
example: {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"usage": ["master"],
|
||||||
|
"keys": {
|
||||||
|
"ed25519:base64+master+public+key": "base64+master+public+key",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self_signing_key:
|
||||||
|
type: object
|
||||||
|
$ref: ../../../client-server/definitions/cross_signing_key.yaml
|
||||||
|
example: {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"usage": ["self_signing"],
|
||||||
|
"keys": {
|
||||||
|
"ed25519:base64+self+signing+public+key": "base64+self+signing+master+public+key",
|
||||||
|
},
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"ed25519:base64+master+public+key": "signature+of+self+signing+key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
required:
|
||||||
|
- user_id
|
|
@ -1,4 +1,5 @@
|
||||||
# Copyright 2018 New Vector Ltd
|
# Copyright 2018 New Vector Ltd
|
||||||
|
# Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
#
|
#
|
||||||
# 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.
|
||||||
|
@ -81,4 +82,37 @@ paths:
|
||||||
description: Optional display name for the device.
|
description: Optional display name for the device.
|
||||||
example: "Alice's Mobile Phone"
|
example: "Alice's Mobile Phone"
|
||||||
required: ['device_id', 'keys']
|
required: ['device_id', 'keys']
|
||||||
|
master_key:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
The user\'s master cross-signing key.
|
||||||
|
allOf:
|
||||||
|
- $ref: ../client-server/definitions/cross_signing_key.yaml
|
||||||
|
# FIXME: why isn't the doc generator picking up this example?
|
||||||
|
- example: {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"usage": ["master"],
|
||||||
|
"keys": {
|
||||||
|
"ed25519:base64+master+public+key": "base64+master+public+key",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self_signing_keys:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
The user\'s self-signing key.
|
||||||
|
allOf:
|
||||||
|
- $ref: ../client-server/definitions/cross_signing_key.yaml
|
||||||
|
# FIXME: why isn't the doc generator picking up this example?
|
||||||
|
- example: {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"usage": ["self_signing"],
|
||||||
|
"keys": {
|
||||||
|
"ed25519:base64+self+signing+public+key": "base64+self+signing+master+public+key",
|
||||||
|
},
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"ed25519:base64+master+public+key": "signature+of+self+signing+key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
required: ['user_id', 'stream_id', 'devices']
|
required: ['user_id', 'stream_id', 'devices']
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# Copyright 2018 New Vector Ltd
|
# Copyright 2018 New Vector Ltd
|
||||||
|
# Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||||
#
|
#
|
||||||
# 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.
|
||||||
|
@ -177,6 +178,51 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
description:
|
description:
|
||||||
The display name which the user set on the device.
|
The display name which the user set on the device.
|
||||||
|
master_keys:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
Information on the master cross-signing keys of the queried users.
|
||||||
|
A map from user ID, to master key information. For each key, the
|
||||||
|
information returned will be the same as uploaded via
|
||||||
|
``/keys/device_signing/upload``, along with the signatures
|
||||||
|
uploaded via ``/keys/signatures/upload`` that the user is
|
||||||
|
allowed to see.
|
||||||
|
additionalProperties:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../client-server/definitions/cross_signing_key.yaml
|
||||||
|
example: {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"usage": ["master"],
|
||||||
|
"keys": {
|
||||||
|
"ed25519:base64+master+public+key": "base64+master+public+key",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self_signing_keys:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
Information on the self-signing keys of the queried users. A map
|
||||||
|
from user ID, to self-signing key information. For each key, the
|
||||||
|
information returned will be the same as uploaded via
|
||||||
|
``/keys/device_signing/upload``.
|
||||||
|
additionalProperties:
|
||||||
|
allOf:
|
||||||
|
- $ref: ../client-server/definitions/cross_signing_key.yaml
|
||||||
|
example: {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"user_id": "@alice:example.com",
|
||||||
|
"usage": ["self_signing"],
|
||||||
|
"keys": {
|
||||||
|
"ed25519:base64+self+signing+public+key": "base64+self+signing+master+public+key",
|
||||||
|
},
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"ed25519:base64+master+public+key": "signature+of+self+signing+key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
required: ['device_keys']
|
required: ['device_keys']
|
||||||
examples:
|
examples:
|
||||||
application/json: {
|
application/json: {
|
||||||
|
|
1
changelogs/client_server/newsfragments/2536.feature
Normal file
1
changelogs/client_server/newsfragments/2536.feature
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Add cross-signing properties to the response of ``POST /keys/query`` per [MSC1756](https://github.com/matrix-org/matrix-doc/pull/1756).
|
1
changelogs/client_server/newsfragments/2536.new
Normal file
1
changelogs/client_server/newsfragments/2536.new
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Add ``POST /keys/device_signing/upload`` and ``POST /keys/signatures/upload`` per [MSC1756](https://github.com/matrix-org/matrix-doc/pull/1756).
|
9
changelogs/server_server/newsfragments/2536.feature
Normal file
9
changelogs/server_server/newsfragments/2536.feature
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
Add cross-signing:
|
||||||
|
|
||||||
|
- Add properties to the response of ``GET /user/keys`` and ``GET
|
||||||
|
/user/devices/{userId}``.
|
||||||
|
- The ``m.device_list_update`` EDU is sent when a device gets a new signature.
|
||||||
|
- A new ``m.signing_key_update`` EDU is sent when a user's cross-signing keys
|
||||||
|
are changed.
|
||||||
|
|
||||||
|
per [MSC1756](https://github.com/matrix-org/matrix-doc/pull/1756).
|
|
@ -1,5 +1,5 @@
|
||||||
.. Copyright 2016 OpenMarket Ltd
|
.. Copyright 2016 OpenMarket Ltd
|
||||||
.. Copyright 2019 The Matrix.org Foundation C.I.C.
|
.. Copyright 2019-2020 The Matrix.org Foundation C.I.C.
|
||||||
..
|
..
|
||||||
.. 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.
|
||||||
|
@ -776,6 +776,149 @@ common set of translations for all languages.
|
||||||
translated online: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1
|
translated online: https://translate.riot.im/projects/matrix-doc/sas-emoji-v1
|
||||||
|
|
||||||
|
|
||||||
|
Cross-signing
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Rather than requiring Alice to verify each of Bob's devices with each of her
|
||||||
|
own devices and vice versa, the cross-signing feature allows users to sign their
|
||||||
|
device keys such that Alice and Bob only need to verify once. With
|
||||||
|
cross-signing, each user has a set of cross-signing keys that are used to sign
|
||||||
|
their own device keys and other users' keys, and can be used to trust device
|
||||||
|
keys that were not verified directly.
|
||||||
|
|
||||||
|
Each user has three ed25519 key pairs for cross-signing:
|
||||||
|
|
||||||
|
* a master key (MSK) that serves as the user's identity in cross-signing and signs
|
||||||
|
their other cross-signing keys;
|
||||||
|
* a user-signing key (USK) -- only visible to the user that it belongs to --
|
||||||
|
that signs other users' master keys; and
|
||||||
|
* a self-signing key (SSK) that signs the user's own device keys.
|
||||||
|
|
||||||
|
The master key may also be used to sign other items such as the backup key. The
|
||||||
|
master key may also be signed by the user's own device keys to aid in migrating
|
||||||
|
from device verifications: if Alice's device had previously verified Bob's
|
||||||
|
device and Bob's device has signed his master key, then Alice's device can
|
||||||
|
trust Bob's master key, and she can sign it with her user-signing key.
|
||||||
|
|
||||||
|
Users upload their cross-signing keys to the server using `POST
|
||||||
|
/_matrix/client/r0/keys/device_signing/upload`_. When Alice uploads new
|
||||||
|
cross-signing keys, her user ID will appear in the ``changed`` property of the
|
||||||
|
``device_lists`` field of the ``/sync`` of response of all users who share an
|
||||||
|
encrypted room with her. When Bob sees Alice's user ID in his ``/sync``, he
|
||||||
|
will call `POST /_matrix/client/r0/keys/query`_ to retrieve Alice's device and
|
||||||
|
cross-signing keys.
|
||||||
|
|
||||||
|
If Alice has a device and wishes to send an encrypted message to Bob, she can
|
||||||
|
trust Bob's device if:
|
||||||
|
|
||||||
|
- Alice's device is using a master key that has signed her user-signing key,
|
||||||
|
- Alice's user-signing key has signed Bob's master key,
|
||||||
|
- Bob's master key has signed Bob's self-signing key, and
|
||||||
|
- Bob's self-signing key has signed Bob's device key.
|
||||||
|
|
||||||
|
The following diagram illustrates how keys are signed:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
+------------------+ .................. +----------------+
|
||||||
|
| +--------------+ | .................. : | +------------+ |
|
||||||
|
| | v v v : : v v v | |
|
||||||
|
| | +-----------+ : : +-----------+ | |
|
||||||
|
| | | Alice MSK | : : | Bob MSK | | |
|
||||||
|
| | +-----------+ : : +-----------+ | |
|
||||||
|
| | | : : : : | | |
|
||||||
|
| | +--+ :... : : ...: +--+ | |
|
||||||
|
| | v v : : v v | |
|
||||||
|
| | +-----------+ ............. : : ............. +-----------+ | |
|
||||||
|
| | | Alice SSK | : Alice USK : : : : Bob USK : | Bob SSK | | |
|
||||||
|
| | +-----------+ :...........: : : :...........: +-----------+ | |
|
||||||
|
| | | ... | : : : : | ... | | |
|
||||||
|
| | V V :........: :........: V V | |
|
||||||
|
| | +---------+ -+ +---------+ -+ | |
|
||||||
|
| | | Devices | ...| | Devices | ...| | |
|
||||||
|
| | +---------+ -+ +---------+ -+ | |
|
||||||
|
| | | ... | | ... | | |
|
||||||
|
| +------+ | | +----+ |
|
||||||
|
+----------------+ +--------------+
|
||||||
|
|
||||||
|
.. based on https://jcg.re/blog/quick-overview-matrix-cross-signing/
|
||||||
|
|
||||||
|
In the diagram, boxes represent keys and lines represent signatures with the
|
||||||
|
arrows pointing from the signing key to the key being signed. Dotted boxes and
|
||||||
|
lines represent keys and signatures that are only visible to the user who
|
||||||
|
created them.
|
||||||
|
|
||||||
|
The following diagram illustrates Alice's view, hiding the keys and signatures
|
||||||
|
that she cannot see:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
+------------------+ +----------------+ +----------------+
|
||||||
|
| +--------------+ | | | | +------------+ |
|
||||||
|
| | v v | v v v | |
|
||||||
|
| | +-----------+ | +-----------+ | |
|
||||||
|
| | | Alice MSK | | | Bob MSK | | |
|
||||||
|
| | +-----------+ | +-----------+ | |
|
||||||
|
| | | | | | | |
|
||||||
|
| | +--+ +--+ | +--+ | |
|
||||||
|
| | v v | v | |
|
||||||
|
| | +-----------+ +-----------+ | +-----------+ | |
|
||||||
|
| | | Alice SSK | | Alice USK | | | Bob SSK | | |
|
||||||
|
| | +-----------+ +-----------+ | +-----------+ | |
|
||||||
|
| | | ... | | | | ... | | |
|
||||||
|
| | V V +--------+ V V | |
|
||||||
|
| | +---------+ -+ +---------+ -+ | |
|
||||||
|
| | | Devices | ...| | Devices | ...| | |
|
||||||
|
| | +---------+ -+ +---------+ -+ | |
|
||||||
|
| | | ... | | ... | | |
|
||||||
|
| +------+ | | +----+ |
|
||||||
|
+----------------+ +--------------+
|
||||||
|
|
||||||
|
`Verification methods <#device-verification>`_ can be used to verify a user's
|
||||||
|
master key by using the master public key, encoded using unpadded base64, as
|
||||||
|
the device ID, and treating it as a normal device. For example, if Alice and
|
||||||
|
Bob verify each other using SAS, Alice's ``m.key.verification.mac`` message to
|
||||||
|
Bob may include ``"ed25519:alices+master+public+key":
|
||||||
|
"alices+master+public+key"`` in the ``mac`` property. Servers therefore must
|
||||||
|
ensure that device IDs will not collide with cross-signing public keys.
|
||||||
|
|
||||||
|
Key and signature security
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
|
||||||
|
A user's master key could allow an attacker to impersonate that user to other
|
||||||
|
users, or other users to that user. Thus clients must ensure that the private
|
||||||
|
part of the master key is treated securely. If clients do not have a secure
|
||||||
|
means of storing the master key (such as a secret storage system provided by
|
||||||
|
the operating system), then clients must not store the private part.
|
||||||
|
|
||||||
|
If a user's client sees that any other user has changed their master key, that
|
||||||
|
client must notify the user about the change before allowing communication
|
||||||
|
between the users to continue.
|
||||||
|
|
||||||
|
A user's user-signing and self-signing keys are intended to be easily
|
||||||
|
replaceable if they are compromised by re-issuing a new key signed by the
|
||||||
|
user's master key and possibly by re-verifying devices or users. However,
|
||||||
|
doing so relies on the user being able to notice when their keys have been
|
||||||
|
compromised, and it involves extra work for the user, and so although clients
|
||||||
|
do not have to treat the private parts as sensitively as the master key,
|
||||||
|
clients should still make efforts to store the private part securely, or not
|
||||||
|
store it at all. Clients will need to balance the security of the keys with
|
||||||
|
the usability of signing users and devices when performing key verification.
|
||||||
|
|
||||||
|
To avoid leaking of social graphs, servers will only allow users to see:
|
||||||
|
|
||||||
|
* signatures made by the user's own master, self-signing or user-signing keys,
|
||||||
|
* signatures made by the user's own devices about their own master key,
|
||||||
|
* signatures made by other users' self-signing keys about their respective
|
||||||
|
devices,
|
||||||
|
* signatures made by other users' master keys about their respective
|
||||||
|
self-signing key, or
|
||||||
|
* signatures made by other users' devices about their respective master keys.
|
||||||
|
|
||||||
|
Users will not be able to see signatures made by other users' user-signing keys.
|
||||||
|
|
||||||
|
{{cross_signing_cs_http_api}}
|
||||||
|
|
||||||
.. section name changed, so make sure that old links keep working
|
.. section name changed, so make sure that old links keep working
|
||||||
.. _key-sharing:
|
.. _key-sharing:
|
||||||
|
|
||||||
|
@ -1302,7 +1445,8 @@ 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 or
|
||||||
|
cross-signing keys,
|
||||||
or who now share an encrypted room with the client since
|
or who now share an encrypted room with the client since
|
||||||
the previous sync response.
|
the previous sync response.
|
||||||
left [string] List of users with whom we do not share any encrypted rooms
|
left [string] List of users with whom we do not share any encrypted rooms
|
||||||
|
@ -1312,7 +1456,8 @@ left [string] List of users with whom we do not share any encrypted rooms
|
||||||
.. NOTE::
|
.. NOTE::
|
||||||
|
|
||||||
For optimal performance, Alice should be added to ``changed`` in Bob's sync only
|
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
|
when she updates her devices or cross-signing keys, 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
|
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
|
may add Alice to ``changed`` when Alice and Bob share a new room, even if they
|
||||||
previously already shared a room.
|
previously already shared a room.
|
||||||
|
|
|
@ -1037,6 +1037,8 @@ through to federation, and have the response also be proxied through to the clie
|
||||||
|
|
||||||
{{user_keys_ss_http_api}}
|
{{user_keys_ss_http_api}}
|
||||||
|
|
||||||
|
{{definition_ss_event_schemas_m_signing_key_update}}
|
||||||
|
|
||||||
|
|
||||||
Send-to-device messaging
|
Send-to-device messaging
|
||||||
------------------------
|
------------------------
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue