Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Revert recent merges of #7289 into matrix-org-hotfixes
Browse files Browse the repository at this point in the history
This was incorrectly merged before it was ready.

This reverts commit aead826, reversing
changes made to 4cd2a4a.

It also reverts commits 9b8212d, fb3f1fb and 2fdfa96.
  • Loading branch information
richvdh committed Apr 21, 2020
1 parent 2fdfa96 commit da5e6ee
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 141 deletions.
1 change: 0 additions & 1 deletion changelog.d/7289.bugfix

This file was deleted.

14 changes: 3 additions & 11 deletions synapse/federation/transport/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,19 +406,13 @@ def query_client_keys(self, destination, query_content, timeout):
"device_keys": {
"<user_id>": {
"<device_id>": {...}
} }
"master_keys": {
"<user_id>": {...}
} }
"self_signing_keys": {
"<user_id>": {...}
} } }
Args:
destination(str): The server to query.
query_content(dict): The user ids to query.
Returns:
A dict containing device and cross-signing keys.
A dict containg the device keys.
"""
path = _create_v1_path("/user/keys/query")

Expand All @@ -435,16 +429,14 @@ def query_user_devices(self, destination, user_id, timeout):
Response:
{
"stream_id": "...",
"devices": [ { ... } ],
"master_key": { ... },
"self_signing_key: { ... }
"devices": [ { ... } ]
}
Args:
destination(str): The server to query.
query_content(dict): The user ids to query.
Returns:
A dict containing device and cross-signing keys.
A dict containg the device keys.
"""
path = _create_v1_path("/user/devices/%s", user_id)

Expand Down
138 changes: 9 additions & 129 deletions synapse/handlers/e2e_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ def do_remote_query(destination):
"""This is called when we are querying the device list of a user on
a remote homeserver and their device list is not in the device list
cache. If we share a room with this user and we're not querying for
specific user we will update the cache with their device list.
"""
specific user we will update the cache
with their device list."""

destination_query = remote_queries_not_in_cache[destination]

Expand Down Expand Up @@ -961,19 +961,13 @@ def _process_other_signatures(self, user_id, signatures):
return signature_list, failures

@defer.inlineCallbacks
def _get_e2e_cross_signing_verify_key(
self, user_id: str, key_type: str, from_user_id: str = None
):
"""Fetch locally or remotely query for a cross-signing public key.
First, attempt to fetch the cross-signing public key from storage.
If that fails, query the keys from the homeserver they belong to
and update our local copy.
def _get_e2e_cross_signing_verify_key(self, user_id, key_type, from_user_id=None):
"""Fetch the cross-signing public key from storage and interpret it.
Args:
user_id: the user whose key should be fetched
key_type: the type of key to fetch
from_user_id: the user that we are fetching the keys for.
user_id (str): the user whose key should be fetched
key_type (str): the type of key to fetch
from_user_id (str): the user that we are fetching the keys for.
This affects what signatures are fetched.
Returns:
Expand All @@ -982,130 +976,16 @@ def _get_e2e_cross_signing_verify_key(
Raises:
NotFoundError: if the key is not found
SynapseError: if `user_id` is invalid
"""
user = UserID.from_string(user_id)

key_id = None
verify_key = None
key = yield self.store.get_e2e_cross_signing_key(
user_id, key_type, from_user_id
)
if key is not None:
try:
key_id, verify_key = get_verify_key_from_cross_signing_key(key)
except ValueError as e:
logger.warning(
"Invalid %s key retrieved: %s - %s %s", key_type, key, type(e), e,
)
raise SynapseError(
502, "Invalid %s key retrieved from database" % (key_type,)
)

# If we couldn't find the key locally, and we're looking for keys of
# another user then attempt to fetch the missing key from the remote
# user's server.
#
# We may run into this in possible edge cases where a user tries to
# cross-sign a remote user, but does not share any rooms with them yet.
# Thus, we would not have their key list yet. We fetch the key here,
# store it and notify clients of new, associated device IDs.
if (
key is None
and not self.is_mine(user)
# We only get "master" and "self_signing" keys from remote servers
and key_type in ["master", "self_signing"]
):
(
key,
key_id,
verify_key,
) = yield self._retrieve_cross_signing_keys_for_remote_user(user, key_type)

if key is None:
logger.debug("No %s key found for %s", key_type, user_id)
logger.debug("no %s key found for %s", key_type, user_id)
raise NotFoundError("No %s key found for %s" % (key_type, user_id))

key_id, verify_key = get_verify_key_from_cross_signing_key(key)
return key, key_id, verify_key

@defer.inlineCallbacks
def _retrieve_cross_signing_keys_for_remote_user(
self, user: UserID, desired_key_type: str,
):
"""Queries cross-signing keys for a remote user and saves them to the database
Only the key specified by `key_type` will be returned, while all retrieved keys
will be saved regardless
Args:
user: The user to query remote keys for
desired_key_type: The type of key to receive. One of "master", "self_signing"
Returns:
Deferred[Tuple[Optional[Dict], Optional[str], Optional[VerifyKey]]]: A tuple
of the retrieved key content, the key's ID and the matching VerifyKey.
If the key cannot be retrieved, all values in the tuple will instead be None.
"""
try:
remote_result = yield self.federation.query_user_devices(
user.domain, user.to_string()
)
except Exception as e:
logger.warning(
"Unable to query %s for cross-signing keys of user %s: %s %s",
user.domain,
user.to_string(),
type(e),
e,
)
return None, None, None

# Process each of the retrieved cross-signing keys
final_key = None
final_key_id = None
final_verify_key = None
device_ids = []
for key_type in ["master", "self_signing"]:
key_content = remote_result.get(key_type + "_key")
if not key_content:
continue

# At the same time, store this key in the db for
# subsequent queries
yield self.store.set_e2e_cross_signing_key(
user.to_string(), key_type, key_content
)

# Note down the device ID attached to this key
try:
# verify_key is a VerifyKey from signedjson, which uses
# .version to denote the portion of the key ID after the
# algorithm and colon, which is the device ID
key_id, verify_key = get_verify_key_from_cross_signing_key(key_content)
except ValueError as e:
logger.warning(
"Invalid %s key retrieved from remote %s: %s - %s %s",
user.domain,
key_type,
key_content,
type(e),
e,
)
continue
device_ids.append(verify_key.version)

# If this is the desired key type, save it and its ID/VerifyKey
if key_type == desired_key_type:
final_key = key_content
final_verify_key = verify_key
final_key_id = key_id

# Notify clients that new devices for this user have been discovered
if device_ids:
yield self.device_handler.notify_device_update(user.to_string(), device_ids)

return final_key, final_key_id, final_verify_key


def _check_cross_signing_key(key, user_id, key_type, signing_key=None):
"""Check a cross-signing key uploaded by a user. Performs some basic sanity
Expand Down

0 comments on commit da5e6ee

Please sign in to comment.