def _handle_key_deferred(verify_request): """Waits for the key to become available, and then performs a verification Args: verify_request (VerifyKeyRequest): Returns: Deferred[None] Raises: SynapseError if there was a problem performing the verification """ server_name = verify_request.server_name try: with PreserveLoggingContext(): _, key_id, verify_key = yield verify_request.deferred except KeyLookupError as e: logger.warn( "Failed to download keys for %s: %s %s", server_name, type(e).__name__, str(e), ) raise SynapseError( 502, "Error downloading keys for %s" % (server_name,), Codes.UNAUTHORIZED, ) except Exception as e: logger.exception( "Got Exception when downloading keys for %s: %s %s", server_name, type(e).__name__, str(e), ) raise SynapseError( 401, "No key for %s with id %s" % (server_name, verify_request.key_ids), Codes.UNAUTHORIZED, ) json_object = verify_request.json_object logger.debug("Got key %s %s:%s for server %s, verifying" % ( key_id, verify_key.alg, verify_key.version, server_name, )) try: verify_signed_json(json_object, server_name, verify_key) except SignatureVerifyException as e: logger.debug( "Error verifying signature for %s:%s:%s with key %s: %s", server_name, verify_key.alg, verify_key.version, encode_verify_key_base64(verify_key), str(e), ) raise SynapseError( 401, "Invalid signature for server %s with key %s:%s: %s" % ( server_name, verify_key.alg, verify_key.version, str(e), ), Codes.UNAUTHORIZED, )
def encode_pubkey(sk: SigningKey) -> str: """Encode the public key corresponding to the given signing key as base64""" return key.encode_verify_key_base64(key.get_verify_key(sk))
def get_verify_keys(self): vk = signedjson.key.get_verify_key(self.key) return {"%s:%s" % (vk.alg, vk.version): encode_verify_key_base64(vk)}
def setUp(self): self.version = "my_version" self.key = generate_signing_key(self.version) self.key_base64 = encode_signing_key_base64(self.key) self.verify_key = get_verify_key(self.key) self.verify_key_base64 = encode_verify_key_base64(self.verify_key)
def _handle_key_deferred(verify_request): """Waits for the key to become available, and then performs a verification Args: verify_request (VerifyKeyRequest): Returns: Deferred[None] Raises: SynapseError if there was a problem performing the verification """ server_name = verify_request.server_name try: with PreserveLoggingContext(): _, key_id, verify_key = yield verify_request.deferred except KeyLookupError as e: logger.warn( "Failed to download keys for %s: %s %s", server_name, type(e).__name__, str(e), ) raise SynapseError( 502, "Error downloading keys for %s" % (server_name, ), Codes.UNAUTHORIZED, ) except Exception as e: logger.exception( "Got Exception when downloading keys for %s: %s %s", server_name, type(e).__name__, str(e), ) raise SynapseError( 401, "No key for %s with id %s" % (server_name, verify_request.key_ids), Codes.UNAUTHORIZED, ) json_object = verify_request.json_object logger.debug("Got key %s %s:%s for server %s, verifying" % ( key_id, verify_key.alg, verify_key.version, server_name, )) try: verify_signed_json(json_object, server_name, verify_key) except SignatureVerifyException as e: logger.debug( "Error verifying signature for %s:%s:%s with key %s: %s", server_name, verify_key.alg, verify_key.version, encode_verify_key_base64(verify_key), str(e), ) raise SynapseError( 401, "Invalid signature for server %s with key %s:%s: %s" % ( server_name, verify_key.alg, verify_key.version, str(e), ), Codes.UNAUTHORIZED, )
async def process_request(self, verify_request: VerifyJsonRequest) -> None: """Processes the `VerifyJsonRequest`. Raises if the object is not signed by the server, the signatures don't match or we failed to fetch the necessary keys. """ if not verify_request.key_ids: raise SynapseError( 400, f"Not signed by {verify_request.server_name}", Codes.UNAUTHORIZED, ) # Add the keys we need to verify to the queue for retrieval. We queue # up requests for the same server so we don't end up with many in flight # requests for the same keys. key_request = verify_request.to_fetch_key_request() found_keys_by_server = await self._server_queue.add_to_queue( key_request, key=verify_request.server_name ) # Since we batch up requests the returned set of keys may contain keys # from other servers, so we pull out only the ones we care about.s found_keys = found_keys_by_server.get(verify_request.server_name, {}) # Verify each signature we got valid keys for, raising if we can't # verify any of them. verified = False for key_id in verify_request.key_ids: key_result = found_keys.get(key_id) if not key_result: continue if key_result.valid_until_ts < verify_request.minimum_valid_until_ts: continue verify_key = key_result.verify_key json_object = verify_request.get_json_object() try: verify_signed_json( json_object, verify_request.server_name, verify_key, ) verified = True except SignatureVerifyException as e: logger.debug( "Error verifying signature for %s:%s:%s with key %s: %s", verify_request.server_name, verify_key.alg, verify_key.version, encode_verify_key_base64(verify_key), str(e), ) raise SynapseError( 401, "Invalid signature for server %s with key %s:%s: %s" % ( verify_request.server_name, verify_key.alg, verify_key.version, str(e), ), Codes.UNAUTHORIZED, ) if not verified: raise SynapseError( 401, f"Failed to find any key to satisfy: {key_request}", Codes.UNAUTHORIZED, )
def format_plain(public_key: VerifyKey) -> None: print("%s:%s %s" % ( public_key.alg, public_key.version, encode_verify_key_base64(public_key), ))