Use query_user_devices instead, assume only master, self_signing key types
parent
39ed9f6938
commit
fd8d154e6d
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue