switch to the 3-key system, and some wording improvements

This commit is contained in:
Hubert Chathi 2019-05-20 21:03:48 -04:00
parent 2ae122903f
commit 7bad359b0d
3 changed files with 150 additions and 79 deletions

View file

@ -19,49 +19,51 @@ MSC1680 is presented below.
## Proposal ## Proposal
Each user has a self-signing key pair that is used to sign their own devices, Each user has three sets of key pairs:
and a user-signing key pair that is used to sign other users' signing keys. A
user's user-signing key is also signed by their own self-signing key. When one - a master cross-signing key pair that is used to identify themselves and to
user (e.g. Alice) verifies another user's (Bob's) identity, Alice will sign sign their other cross-signing keys,
Bob's self-signing key with her user-signing key. (This will mean that - a self-signing key pair that is used to sign their own devices, and
- a user-signing key pair that is used to sign other users' master keys.
When one user (e.g. Alice) verifies another user's (Bob's) identity, Alice will
sign Bob's self-signing key with her user-signing key. (This will mean that
verification methods will need to be modified to pass along the self-signing verification methods will need to be modified to pass along the self-signing
identity key.) Alice's device will trust Bob's device if: identity key.) Alice's device will trust Bob's device if:
- Alice's device is using a self-signing key that has signed her user-signing key, - Alice's device is using a master key that has signed her user-signing key,
- Alice's user-signing key has signed Bob's self-signing key, and - 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. - Bob's self-signing key has signed Bob's device key.
### Key security ### Key security
A user's private half of their user-signing key pair may be kept unlocked on a A user's master key could allow an attacker to impersonate that user to other
device, but their self-signing key should not; the private half of the users, or other users to that user. Thus clients must ensure that the private
self-signing key pair should only be stored encrypted, requiring a passphrase part of the master key is treated securely. If clients do not have a secure
to access. By keeping the user-signing key unlocked, Alice can verify Bob's means of storing the master key (such as an secret storage system provided by
identity and distribute signatures to all her devices without needing to enter the operating system), then clients must not store the private part. If a user
a passphrase to decrypt the key. changes their master key, clients of users that they communicate with must
notify their users about the change.
If a user's device is compromised, they can issue a new user-signing key, A user's user-signing and self-signing keys are intended to be easily
signed by their self-signing key, rendering the old user-signing key useless. replaceable if they are compromised by re-issuing a new key signed by the
If they are certain that the old user-signing key has not yet been used by an user's master key and possibly by re-verifying devices or users. However,
attacker, then they may also reissue signatures made by the old user-signing doing so relies on the user being able to notice when their keys have been
key by using the new user-signing key. Otherwise, they will need to re-verify compromised, and it involves extra work for the user, and so although clients
the other users. 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.
If a user's self-signing key is compromised, then the user will need to issue The private halves of a user's cross-signing keys be stored encrypted on the
both a new self-signing key and a new user-signing key. The user may sign server so that they may be retrieved by new devices. FIXME: explain how to do
their new self-signing key with their old self-signing key, allowing other this via MSC 1946
users who have verified the old self-signing key to automatically trust the new
self-signing key if they wish to. Otherwise, the users will need to re-verify
each other.
The private halves of the user-signing key pair and self-signing key pair may
be stored encrypted on the server (possibly along with the megolm key backup)
so that they may be retrieved by new devices. FIXME: explain how to do this
### Signature distribution ### Signature distribution
Currently, users will only be allowed to see signatures made by their own Currently, users will only be allowed to see signatures made by her own master,
self-signing or user-signing keys, or signatures made by other users' self-signing or user-signing keys, or signatures made by other users' master or
self-signing keys about their own devices. This is done in order to preserve self-signing keys about their own devices. This is done in order to preserve
the privacy of social connections. Future proposals may define mechanisms for the privacy of social connections. Future proposals may define mechanisms for
distributing signatures to other users in order to allow for other web-of-trust distributing signatures to other users in order to allow for other web-of-trust
@ -71,19 +73,31 @@ use cases.
#### Uploading signing keys #### Uploading signing keys
Public keys for the self-signing and user-signing keys are uploaded to the Public keys for the cross-signing keys are uploaded to the servers using
servers using `/keys/device_signing/upload`. This endpoint requires [UI `/keys/device_signing/upload`. This endpoint requires [UI
Auth](https://matrix.org/docs/spec/client_server/r0.4.0.html#user-interactive-authentication-api). Auth](https://matrix.org/docs/spec/client_server/r0.4.0.html#user-interactive-authentication-api).
`POST /keys/device_signing/upload` `POST /keys/device_signing/upload`
``` json ``` json
{ {
"master_key": {
"user_id": "@alice:example.com",
"usage": ["master"],
"keys": {
"ed25519:base64+master+public+key": "base64+self+master+key",
}
},
"self_signing_key": { "self_signing_key": {
"user_id": "@alice:example.com", "user_id": "@alice:example.com",
"usage": ["self_signing"], "usage": ["self_signing"],
"keys": { "keys": {
"ed25519:base64+self+signing+public+key": "base64+self+signing+public+key", "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key",
},
"signatures": {
"@alice:example.com": {
"ed25519:base64+master+public+key": "base64+signature"
}
} }
}, },
"user_signing_key": { "user_signing_key": {
@ -94,24 +108,25 @@ Auth](https://matrix.org/docs/spec/client_server/r0.4.0.html#user-interactive-au
"usage": ["user_signing"], "usage": ["user_signing"],
"signatures": { "signatures": {
"@alice:example.com": { "@alice:example.com": {
"ed25519:base64+self+signing+public+key": "base64+signature" "ed25519:base64+master+public+key": "base64+signature"
} }
} }
} }
} }
``` ```
Self-signing and user-signing keys are JSON objects with the following Cross-signing keys are JSON objects with the following
properties: properties:
* `user_id` (string): The user who owns the key * `user_id` (string): The user who owns the key
* `usage` ([string]): Allowed uses for the key. Must be `["self_signing"]` for * `usage` ([string]): Allowed uses for the key. Must contain `"master"` for
self-signing keys, and `["user_signing"]` for user-signing keys. master keys, `"self_signing"` for self-signing keys, and `"user_signing"`
for user-signing keys.
* `keys` ({string: string}): an object that must have one entry, whose name is * `keys` ({string: string}): an object that must have one entry, whose name is
"`ed25519:`" followed by the unpadded base64 encoding of the public key, and "`ed25519:`" followed by the unpadded base64 encoding of the public key, and
whose value is the unpadded base64 encoding of the public key. whose value is the unpadded base64 encoding of the public key.
* `signatures` ({string: {stringg: string}}): signatures of the key. A * `signatures` ({string: {string: string}}): signatures of the key. A
user-signing key must be signed by the self-signing key. self-signing or user-signing key must be signed by the master key.
In order to ensure that there will be no collisions in the `signatures` In order to ensure that there will be no collisions in the `signatures`
property, the server must respond with an error (FIXME: what error?) if any of property, the server must respond with an error (FIXME: what error?) if any of
@ -119,18 +134,14 @@ the uploaded public keys match an existing device ID for the user. Similarly,
if a user attempts to log in specifying a device ID matching one of the signing if a user attempts to log in specifying a device ID matching one of the signing
keys, the server must respond with an error (FIXME: what error?). keys, the server must respond with an error (FIXME: what error?).
If a user-signing key is uploaded, it must be signed by the current If a self-signing or user-signing key is uploaded, it must be signed by the
self-signing key (or the self-signing key that is included in the request) master key that is included in the request, or the current master key if no
master key is included.
If a previous self-signing key exists, then the new self-signing key must have After uploading cross-signing keys, they will be included under the
a `replaces` property whose value is the previous public self-signing key. `/keys/query` endpoint under the `master_keys`, `self_signing_keys` and
Otherwise the server must respond with an error (FIXME: what error?). The new `user_signing_keys` properties. The `user_signing_keys` property will only be
self-signing key may also be signed with the old self-signing key. included when a user requests their own keys.
After uploading self-signing and user-signing keys, they will be included under
the `/keys/query` endpoint under the `self_signing_key` and `user_signing_key`
properties, respectively. The `user_signing_key` will only be included when a
user requests their own keys.
`POST /keys/query` `POST /keys/query`
@ -153,12 +164,26 @@ response:
// ... // ...
} }
}, },
"master_keys": {
"@alice:example.com": {
"user_id": "@alice:example.com",
"usage": ["master"],
"keys": {
"ed25519:base64+master+public+key": "base64+master+public+key"
}
}
},
"self_signing_keys": { "self_signing_keys": {
"@alice:example.com": { "@alice:example.com": {
"user_id": "@alice:example.com", "user_id": "@alice:example.com",
"usage": ["self_signing"], "usage": ["self_signing"],
"keys": { "keys": {
"ed25519:base64+self+signing+public+key": "base64+self+signing+public+key" "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key"
},
"signatures": {
"@alice:example.com": {
"ed25519:base64+master+public+key": "base64+signature"
}
} }
} }
} }
@ -166,7 +191,9 @@ response:
``` ```
Similarly, the federation endpoints `GET /user/keys/query` and Similarly, the federation endpoints `GET /user/keys/query` and
`POST /user/devices/{userId}` will include the self-signing key. `POST /user/devices/{userId}` will include the master and self-signing keys.
(It will not include the user-signing key because it is not intended to be
visible to other users.)
`POST /keys/query` `POST /keys/query`
@ -187,12 +214,26 @@ response:
// ... // ...
} }
}, },
"master_keys": {
"@alice:example.com": {
"user_id": "@alice:example.com",
"usage": ["master"],
"keys": {
"ed25519:base64+master+public+key": "base64+master+public+key"
}
}
},
"self_signing_keys": { "self_signing_keys": {
"@alice:example.com": { "@alice:example.com": {
"user_id": "@alice:example.com", "user_id": "@alice:example.com",
"usage": ["self_signing"], "usage": ["self_signing"],
"keys": { "keys": {
"ed25519:base64+self+signing+public+key": "base64+self+signing+public+key" "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key"
},
"signatures": {
"@alice:example.com": {
"ed25519:base64+master+public+key": "base64+signature"
}
} }
} }
} }
@ -210,11 +251,23 @@ response:
"devices": [ "devices": [
// ... // ...
], ],
"self_signing_keys": { "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", "user_id": "@alice:example.com",
"usage": ["self_signing"], "usage": ["self_signing"],
"keys": { "keys": {
"ed25519:base64+self+signing+public+key": "base64+self+signing+public+key" "ed25519:base64+self+signing+public+key": "base64+self+signing+public+key"
},
"signatures": {
"@alice:example.com": {
"ed25519:base64+master+public+key": "base64+signature"
}
} }
} }
} }
@ -225,7 +278,8 @@ servers that have users who share encrypted rooms with Alice. The `content` of
that EDU has the following properties: that EDU has the following properties:
* `user_id` (string): Required. The user ID who owns the signing key * `user_id` (string): Required. The user ID who owns the signing key
* `self_signing_key` (object): Required. The self-signing key, as above. * `master_key` (object): The master key, as above.
* `self_signing_key` (object): The self-signing key, as above.
After uploading self-signing and user-signing keys, the user will show up in After uploading self-signing and user-signing keys, the user will show up in
the `changed` property of the `device_lists` field of the sync result of any the `changed` property of the `device_lists` field of the sync result of any
@ -235,7 +289,8 @@ others users who share an encrypted room with that user.
Signatures of keys can be uploaded using `/keys/signatures/upload`. Signatures of keys can be uploaded using `/keys/signatures/upload`.
For example, Alice signs one of her devices (HIJKLMN), and Bob's self-signing key. For example, Alice signs one of her devices (HIJKLMN) (using her self-signing
key), and signs Bob's master key (using her user-signing key).
`POST /keys/signatures/upload` `POST /keys/signatures/upload`
@ -255,7 +310,7 @@ For example, Alice signs one of her devices (HIJKLMN), and Bob's self-signing ke
}, },
"signatures": { "signatures": {
"@alice:example.com": { "@alice:example.com": {
"ed25519:base64+user+signing+public+key": "base64+signature+of+HIJKLMN" "ed25519:base64+self+signing+public+key": "base64+signature+of+HIJKLMN"
} }
} }
} }
@ -264,12 +319,12 @@ For example, Alice signs one of her devices (HIJKLMN), and Bob's self-signing ke
"bobs+base64+self+signing+public+key": { "bobs+base64+self+signing+public+key": {
"user_id": "@bob:example.com", "user_id": "@bob:example.com",
"keys": { "keys": {
"ed25519:bobs+base64+self+signing+public+key": "bobs+base64+self+signing+public+key" "ed25519:bobs+base64+master+public+key": "bobs+base64+master+public+key"
}, },
"usage": ["self_signing"], "usage": ["master"],
"signatures": { "signatures": {
"@alice:example.com": { "@alice:example.com": {
"ed25519:base64+user+signing+public+key": "base64+signature+of+bobs+self+signing+key" "ed25519:base64+user+signing+public+key": "base64+signature+of+bobs+master+key"
} }
} }
} }
@ -313,7 +368,7 @@ response:
"signatures": { "signatures": {
"@alice:example.com": { "@alice:example.com": {
"ed25519:HIJKLMN": "base64+self+signature", "ed25519:HIJKLMN": "base64+self+signature",
"ed25519:base64+user+signing+public+key": "base64+signature+of+HIJKLMN" "ed25519:base64+self+signing+public+key": "base64+signature+of+HIJKLMN"
} }
}, },
"unsigned": { "unsigned": {
@ -322,12 +377,22 @@ response:
} }
} }
}, },
"self_signing_keys": { "master_key": {
"@alice:example.com": { "user_id": "@alice:example.com",
"user_id": "@alice:example.com", "usage": ["master"],
"usage": ["self_signing"], "keys": {
"keys": { "ed25519:base64+master+public+key": "base64+master+public+key"
"ed25519:base64+self+signing+public+key": "base64+self+signing+public+key", }
},
"self_signing_key": {
"user_id": "@alice:example.com",
"usage": ["self_signing"],
"keys": {
"ed25519:base64+self+signing+public+key": "base64+self+signing+public+key"
},
"signatures": {
"@alice:example.com": {
"ed25519:base64+master+public+key": "base64+signature"
} }
} }
} }
@ -343,7 +408,7 @@ include her new signature.
After Alice uploads a signature for Bob's user-signing key, her signature will After Alice uploads a signature for Bob's user-signing key, her signature will
be included in the results of the `/keys/query` request when Alice requests be included in the results of the `/keys/query` request when Alice requests
Bob's key: Bob's key, but will not be included when anyone else requests Bob's key:
`GET /keys/query` `GET /keys/query`
@ -355,16 +420,16 @@ Bob's key:
// ... // ...
} }
}, },
"self_signing_keys": { "master_keys": {
"@bob:example.com": { "@bob:example.com": {
"user_id": "@bob:example.com", "user_id": "@bob:example.com",
"keys": { "keys": {
"ed25519:bobs+base64+self+signing+public+key": "bobs+base64+self+signing+public+key" "ed25519:bobs+base64+master+public+key": "bobs+base64+master+public+key"
}, },
"usage": ["self_signing"], "usage": ["master"],
"signatures": { "signatures": {
"@alice:example.com": { "@alice:example.com": {
"ed25519:base64+user+signing+public+key": "base64+signature+of+bobs+self+signing+key" "ed25519:base64+user+signing+public+key": "base64+signature+of+bobs+master+key"
} }
} }
} }
@ -414,11 +479,13 @@ user-signing key must be re-issued.
## Security considerations ## Security considerations
This proposal relies on servers to communicate when self-signing or This proposal relies on servers to communicate when cross-signing keys are
user-signing keys are deleted and replaced. An attacker who is able to both deleted and replaced. An attacker who is able to both steal a user's device
steal a user's device and control their homeserver could prevent that device and control their homeserver could prevent that device from being marked as
from being marked as untrusted. untrusted.
## Conclusion ## Conclusion
This proposal presents an alternative cross-signing mechanism to MSC1680. This proposal presents an alternative cross-signing mechanism to MSC1680,
allowing users to trust another user's devices without needing to verify each
one individually.

View file

@ -1,18 +1,22 @@
digraph { digraph {
A1 [label="A's PDP-11"] A1 [label="A's PDP-11"]
A2 [label="A's Osborne 2"] A2 [label="A's Osborne 2"]
AM [label="A's master key"]
AS [label="A's self-signing key"] AS [label="A's self-signing key"]
AU [label="A's user-signing key"] AU [label="A's user-signing key"]
BM [label="B's master key"]
BU [label="B's user-signing key"] BU [label="B's user-signing key"]
BS [label="B's self-signing key"] BS [label="B's self-signing key"]
B1 [label="B's Dynabook"] B1 [label="B's Dynabook"]
B2 [label="B's VAX"] B2 [label="B's VAX"]
AS -> A1 AS -> A1
AS -> A2 AS -> A2
AS -> AU AM -> AS
AU -> BS AM -> AU
BS -> BU AU -> BM
BU -> AS BM -> BS
BM -> BU
BU -> AM
BS -> B1 BS -> B1
BS -> B2 BS -> B2
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Before After
Before After