Use query_user_devices instead, assume only master, self_signing key types

pull/7289/head
Andrew Morgan 2020-04-16 17:13:32 +01:00
parent 39ed9f6938
commit fd8d154e6d
2 changed files with 40 additions and 39 deletions

View File

@ -406,13 +406,19 @@ class TransportLayerClient(object):
"device_keys": { "device_keys": {
"<user_id>": { "<user_id>": {
"<device_id>": {...} "<device_id>": {...}
} }
"master_keys": {
"<user_id>": {...}
} }
"self_signing_keys": {
"<user_id>": {...}
} } } } } }
Args: Args:
destination(str): The server to query. destination(str): The server to query.
query_content(dict): The user ids to query. query_content(dict): The user ids to query.
Returns: Returns:
A dict containing the device keys. A dict containing device and cross-signing keys.
""" """
path = _create_v1_path("/user/keys/query") path = _create_v1_path("/user/keys/query")
@ -429,14 +435,16 @@ class TransportLayerClient(object):
Response: Response:
{ {
"stream_id": "...", "stream_id": "...",
"devices": [ { ... } ] "devices": [ { ... } ],
"master_key": { ... },
"self_signing_key: { ... }
} }
Args: Args:
destination(str): The server to query. destination(str): The server to query.
query_content(dict): The user ids to query. query_content(dict): The user ids to query.
Returns: Returns:
A dict containg the device keys. A dict containing device and cross-signing keys.
""" """
path = _create_v1_path("/user/devices/%s", user_id) path = _create_v1_path("/user/devices/%s", user_id)

View File

@ -969,12 +969,14 @@ class E2eKeysHandler(object):
return signature_list, failures return signature_list, failures
@defer.inlineCallbacks @defer.inlineCallbacks
def _get_e2e_cross_signing_verify_key(self, user_id, key_type, from_user_id=None): def _get_e2e_cross_signing_verify_key(
self, user_id, desired_key_type, from_user_id=None
):
"""Fetch the cross-signing public key from storage and interpret it. """Fetch the cross-signing public key from storage and interpret it.
Args: Args:
user_id (str): the user whose key should be fetched user_id (str): the user whose key should be fetched
key_type (str): the type of key to fetch desired_key_type (str): the type of key to fetch
from_user_id (str): the user that we are fetching the keys for. from_user_id (str): the user that we are fetching the keys for.
This affects what signatures are fetched. This affects what signatures are fetched.
@ -987,47 +989,38 @@ class E2eKeysHandler(object):
""" """
user = UserID.from_string(user_id) user = UserID.from_string(user_id)
key = yield self.store.get_e2e_cross_signing_key( key = yield self.store.get_e2e_cross_signing_key(
user_id, key_type, from_user_id user_id, desired_key_type, from_user_id
) )
if key is None and self.is_mine(user): # If we still can't find the key, and we're looking for keys of another user,
# Attempt to fetch the missing key from the remote user's server # then attempt to fetch the missing key from the remote user's server.
#
# We don't get "user_signing" keys from remote servers, so disallow that here
if (
key is None
and not self.is_mine(user)
and desired_key_type != "user_signing"
):
try: try:
remote_result = yield self.federation.query_client_keys( remote_result = yield self.federation.query_user_devices(
user.domain, {"device_keys": {user_id: []}}, timeout=10 * 1000 user.domain, user_id
) )
# Process the result # Process each of the retrieved cross-signing keys
for remote_key_type, remote_user_dict in remote_result.items(): for key_type in ["master", "self_signing"]:
# The key_type variable passed to this function is in the form key_content = remote_result.get(key_type + "_key")
# "self_signing","master" etc. whereas the results returned from if not key_content:
# the remote server use "self_signing_keys", "master_keys" etc. continue
# Remove the "_keys" from the key type
if remote_key_type.endswith("_keys"):
remote_key_type = remote_key_type[:-5]
# remote_user_dict is a dictionary in the form of # If this is the desired key type, return it
# { if key_type == desired_key_type:
# "user_id": { key = key_content
# "master_keys": ...
# },
# ...
# }
# Only extract the keys that pertain to the requested user # At the same time, store this key in the db for
key_content_list = remote_user_dict.get(user_id, {}).values() # subsequent queries
yield self.store.set_e2e_cross_signing_key(
for key_content in key_content_list: user_id, key_type, key_content
# If the key_type here matches the key we're requesting, )
# then this is the key we want to return
if remote_key_type == key_type:
key = key_content
# At the same time, save the key to the database for subsequent
# queries
yield self.store.set_e2e_cross_signing_key(
user_id, remote_key_type, key_content
)
except ( except (
HttpResponseException, HttpResponseException,
NotRetryingDestination, NotRetryingDestination,