summary refs log tree commit diff
path: root/synapse/crypto
diff options
context:
space:
mode:
authorMark Haines <mark.haines@matrix.org>2014-10-13 16:39:15 +0100
committerMark Haines <mark.haines@matrix.org>2014-10-13 16:39:15 +0100
commit07639c79d9536cf293c550e5849ce6b5dd82189e (patch)
treed55672383c1cbcf17b2e19d1ce469991a8a507af /synapse/crypto
parentRaise a SynapseError if the authorisation header is missing or malformed (diff)
downloadsynapse-07639c79d9536cf293c550e5849ce6b5dd82189e.tar.xz
Respond with more helpful error messages for unsigned requests
Diffstat (limited to 'synapse/crypto')
-rw-r--r--synapse/crypto/keyclient.py4
-rw-r--r--synapse/crypto/keyring.py33
2 files changed, 33 insertions, 4 deletions
diff --git a/synapse/crypto/keyclient.py b/synapse/crypto/keyclient.py
index c26f16a038..5949ea0573 100644
--- a/synapse/crypto/keyclient.py
+++ b/synapse/crypto/keyclient.py
@@ -43,7 +43,7 @@ def fetch_server_key(server_name, ssl_context_factory):
             return
         except Exception as e:
             logger.exception(e)
-    raise IOError("Cannot get key for " % server_name)
+    raise IOError("Cannot get key for %s" % server_name)
 
 
 class SynapseKeyClientError(Exception):
@@ -93,7 +93,7 @@ class SynapseKeyClientProtocol(HTTPClient):
     def on_timeout(self):
         logger.debug("Timeout waiting for response from %s",
                      self.transport.getHost())
-        self.on_remote_key.errback(IOError("Timeout waiting for response"))
+        self.remote_key.errback(IOError("Timeout waiting for response"))
         self.transport.abortConnection()
 
 
diff --git a/synapse/crypto/keyring.py b/synapse/crypto/keyring.py
index ce19c69bd5..3c85295274 100644
--- a/synapse/crypto/keyring.py
+++ b/synapse/crypto/keyring.py
@@ -20,6 +20,7 @@ from syutil.crypto.signing_key import (
     is_signing_algorithm_supported, decode_verify_key_bytes
 )
 from syutil.base64util import decode_base64, encode_base64
+from synapse.api.errors import SynapseError, Codes
 
 from OpenSSL import crypto
 
@@ -38,8 +39,36 @@ class Keyring(object):
     @defer.inlineCallbacks
     def verify_json_for_server(self, server_name, json_object):
         key_ids = signature_ids(json_object, server_name)
-        verify_key = yield self.get_server_verify_key(server_name, key_ids)
-        verify_signed_json(json_object, server_name, verify_key)
+        if not key_ids:
+            raise SynapseError(
+                400,
+                "No supported algorithms in signing keys",
+                 Codes.UNAUTHORIZED,
+            )
+        try:
+            verify_key = yield self.get_server_verify_key(server_name, key_ids)
+        except IOError:
+            raise SynapseError(
+                502,
+                "Error downloading keys for %s" % (server_name,),
+                Codes.UNAUTHORIZED,
+            )
+        except:
+            raise SynapseError(
+                401,
+                "No key for %s with id %s" % (server_name, key_ids),
+                Codes.UNAUTHORIZED,
+            )
+        try:
+            verify_signed_json(json_object, server_name, verify_key)
+        except:
+            raise SynapseError(
+                401,
+                "Invalid signature for server %s with key %s:%s" % (
+                    server_name, verify_key.alg, verify_key.version
+                ),
+                Codes.UNAUTHORIZED,
+            )
 
     @defer.inlineCallbacks
     def get_server_verify_key(self, server_name, key_ids):