def verify_json_for_server(self, server_name, json_object): logger.debug("Verifying for %s", server_name) key_ids = signature_ids(json_object, server_name) if not key_ids: raise SynapseError( 400, "Not signed with a supported algorithm", 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, )
def test_sign_and_verify(self): self.assertIn('signatures', self.signed) self.assertIn('Alice', self.signed['signatures']) self.assertIn('mock:test', self.signed['signatures']['Alice']) self.assertEqual(self.signed['signatures']['Alice']['mock:test'], encode_base64('x_______')) verify_signed_json(self.signed, 'Alice', self.verkey)
def main(): parser = argparse.ArgumentParser() parser.add_argument("signature_name") parser.add_argument("input_json", nargs="?", type=argparse.FileType('r'), default=sys.stdin) args = parser.parse_args() logging.basicConfig() server_name = args.signature_name keys = {} for target, port in get_targets(server_name): try: keys = get_server_keys(server_name, target, port) print "Using keys from https://%s:%s/_matrix/key/v1" % (target, port) write_signing_keys(sys.stdout, keys.values()) break except: logging.exception("Error talking to %s:%s", target, port) json_to_check = json.load(args.input_json) print "Checking JSON:" for key_id in json_to_check["signatures"][args.signature_name]: try: key = keys[key_id] verify_signed_json(json_to_check, args.signature_name, key) print "PASS %s" % (key_id, ) except: logging.exception("Check for key %s failed" % (key_id, )) print "FAIL %s" % (key_id, )
def main(): parser = argparse.ArgumentParser() parser.add_argument("signature_name") parser.add_argument("input_json", nargs="?", type=argparse.FileType('r'), default=sys.stdin) args = parser.parse_args() logging.basicConfig() server_name = args.signature_name keys = {} for target, port in get_targets(server_name): try: keys = get_server_keys(server_name, target, port) print "Using keys from https://%s:%s/_matrix/key/v1" % (target, port) write_signing_keys(sys.stdout, keys.values()) break except: logging.exception("Error talking to %s:%s", target, port) json_to_check = json.load(args.input_json) print "Checking JSON:" for key_id in json_to_check["signatures"][args.signature_name]: try: key = keys[key_id] verify_signed_json(json_to_check, args.signature_name, key) print "PASS %s" % (key_id,) except: logging.exception("Check for key %s failed" % (key_id,)) print "FAIL %s" % (key_id,)
def verify_json_for_server(self, server_name, json_object): logger.debug("Verifying for %s", server_name) key_ids = signature_ids(json_object, server_name) if not key_ids: raise SynapseError( 400, "Not signed with a supported algorithm", 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, )
def test_verify_fail(self): self.signed['signatures']['Alice']['mock:test'] = encode_base64( 'not a signature') print self.signed verkey = MockVerifyKey() with self.assertRaises(SignatureVerifyException): verify_signed_json(self.signed, 'Alice', self.verkey)
def _do_invite(self, roomid, userstring): if (not userstring.startswith('@') and self._is_on("complete_usernames")): url = self._identityServerUrl() + "/_matrix/identity/api/v1/lookup" json_res = yield self.http_client.do_request("GET", url, qparams={ 'medium': 'email', 'address': userstring }) mxid = None if 'mxid' in json_res and 'signatures' in json_res: url = self._identityServerUrl( ) + "/_matrix/identity/api/v1/pubkey/ed25519" pubKey = None pubKeyObj = yield self.http_client.do_request("GET", url) if 'public_key' in pubKeyObj: pubKey = nacl.signing.VerifyKey( pubKeyObj['public_key'], encoder=nacl.encoding.HexEncoder) else: print "No public key found in pubkey response!" sigValid = False if pubKey: for signame in json_res['signatures']: if signame not in TRUSTED_ID_SERVERS: print "Ignoring signature from untrusted server %s" % ( signame) else: try: verify_signed_json(json_res, signame, pubKey) sigValid = True print "Mapping %s -> %s correctly signed by %s" % ( userstring, json_res['mxid'], signame) break except SignatureVerifyException as e: print "Invalid signature from %s" % (signame) print e if sigValid: print "Resolved 3pid %s to %s" % (userstring, json_res['mxid']) mxid = json_res['mxid'] else: print "Got association for %s but couldn't verify signature" % ( userstring) if not mxid: mxid = "@" + userstring + ":" + self._domain() self._do_membership_change(roomid, "invite", mxid)
def test_verify_fail(self): self.signed['signatures']['Alice']['mock:test'] = encode_base64( 'not a signature' ) print self.signed verkey = MockVerifyKey() with self.assertRaises(SignatureVerifyException): verify_signed_json(self.signed, 'Alice', self.verkey)
def test_sign_and_verify(self): self.assertIn('signatures', self.signed) self.assertIn('Alice', self.signed['signatures']) self.assertIn('mock:test', self.signed['signatures']['Alice']) self.assertEqual( self.signed['signatures']['Alice']['mock:test'], encode_base64('x_______') ) verify_signed_json(self.signed, 'Alice', self.verkey)
def get_server_keys(server_name, target, port): url = "https://%s:%i/_matrix/key/v1" % (target, port) keys = json.load(urllib2.urlopen(url)) verify_keys = {} for key_id, key_base64 in keys["verify_keys"].items(): verify_key = decode_verify_key_bytes(key_id, decode_base64(key_base64)) verify_signed_json(keys, server_name, verify_key) verify_keys[key_id] = verify_key return verify_keys
def _do_invite(self, roomid, userstring): if (not userstring.startswith('@') and self._is_on("complete_usernames")): url = self._identityServerUrl()+"/_matrix/identity/api/v1/lookup" json_res = yield self.http_client.do_request("GET", url, qparams={'medium':'email','address':userstring}) mxid = None if 'mxid' in json_res and 'signatures' in json_res: url = self._identityServerUrl()+"/_matrix/identity/api/v1/pubkey/ed25519" pubKey = None pubKeyObj = yield self.http_client.do_request("GET", url) if 'public_key' in pubKeyObj: pubKey = nacl.signing.VerifyKey(pubKeyObj['public_key'], encoder=nacl.encoding.HexEncoder) else: print "No public key found in pubkey response!" sigValid = False if pubKey: for signame in json_res['signatures']: if signame not in TRUSTED_ID_SERVERS: print "Ignoring signature from untrusted server %s" % (signame) else: try: verify_signed_json(json_res, signame, pubKey) sigValid = True print "Mapping %s -> %s correctly signed by %s" % (userstring, json_res['mxid'], signame) break except SignatureVerifyException as e: print "Invalid signature from %s" % (signame) print e if sigValid: print "Resolved 3pid %s to %s" % (userstring, json_res['mxid']) mxid = json_res['mxid'] else: print "Got association for %s but couldn't verify signature" % (userstring) if not mxid: mxid = "@" + userstring + ":" + self._domain() self._do_membership_change(roomid, "invite", mxid)
def handle_key_deferred(group, deferred): server_name = group.server_name try: _, _, key_id, verify_key = yield deferred except IOError as e: logger.warn( "Got IOError when downloading keys for %s: %s %s", server_name, type(e).__name__, str(e.message), ) 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.message), ) raise SynapseError( 401, "No key for %s with id %s" % (server_name, key_ids), Codes.UNAUTHORIZED, ) json_object = group_id_to_json[group.group_id] 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, )
def _async_render_GET(self, request): try: server_keys, certificate = yield fetch_server_key( self.server_name, self.key_server.ssl_context_factory ) resp_server_name = server_keys[u"server_name"] verify_key_b64 = server_keys[u"signature_verify_key"] tls_certificate_b64 = server_keys[u"tls_certificate"] verify_key = VerifyKey(decode_base64(verify_key_b64)) if resp_server_name != self.server_name: raise ValueError("Wrong server name '%s' != '%s'" % (resp_server_name, self.server_name)) x509_certificate_bytes = crypto.dump_certificate( crypto.FILETYPE_ASN1, certificate ) if encode_base64(x509_certificate_bytes) != tls_certificate_b64: raise ValueError("TLS certificate doesn't match") verify_signed_json(server_keys, self.server_name, verify_key) signed_json = sign_json( server_keys, self.key_server.server_name, self.key_server.signing_key ) json_bytes = encode_canonical_json(signed_json) respond_with_json_bytes(request, 200, json_bytes) except Exception as e: json_bytes = encode_canonical_json({ u"error": {u"code": 502, u"message": e.message} }) respond_with_json_bytes(request, 502, json_bytes)
def handle_key_deferred(group, deferred): server_name = group.server_name try: _, _, key_id, verify_key = yield deferred except IOError as e: logger.warn( "Got IOError when downloading keys for %s: %s %s", server_name, type(e).__name__, str(e.message), ) 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.message), ) raise SynapseError( 401, "No key for %s with id %s" % (server_name, key_ids), Codes.UNAUTHORIZED, ) json_object = group_id_to_json[group.group_id] 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, )
def reinsert_events(cursor, server_name, signing_key): print "Running delta: v10" cursor.executescript(delta_sql) cursor.execute( "SELECT * FROM events ORDER BY rowid ASC" ) print "Getting events..." rows = store.cursor_to_dict(cursor) events = store._generate_event_json(cursor, rows) print "Got events from DB." algorithms = { "sha256": hashlib.sha256, } key_id = "%s:%s" % (signing_key.alg, signing_key.version) verify_key = signing_key.verify_key verify_key.alg = signing_key.alg verify_key.version = signing_key.version server_keys = { server_name: { key_id: verify_key } } i = 0 N = len(events) for event in events: if i % 100 == 0: print "Processed: %d/%d events" % (i,N,) i += 1 # for alg_name in event.hashes: # if check_event_content_hash(event, algorithms[alg_name]): # pass # else: # pass # print "FAIL content hash %s %s" % (alg_name, event.event_id, ) have_own_correctly_signed = False for host, sigs in event.signatures.items(): pruned = prune_event(event) for key_id in sigs: if host not in server_keys: server_keys[host] = {} # get_key(host) if key_id in server_keys[host]: try: verify_signed_json( pruned.get_pdu_json(), host, server_keys[host][key_id] ) if host == server_name: have_own_correctly_signed = True except SignatureVerifyException: print "FAIL signature check %s %s" % ( key_id, event.event_id ) # TODO: Re sign with our own server key if not have_own_correctly_signed: sigs = compute_event_signature(event, server_name, signing_key) event.signatures.update(sigs) pruned = prune_event(event) for key_id in event.signatures[server_name]: verify_signed_json( pruned.get_pdu_json(), server_name, server_keys[server_name][key_id] ) event_json = encode_canonical_json( event.get_dict() ).decode("UTF-8") metadata_json = encode_canonical_json( event.internal_metadata.get_dict() ).decode("UTF-8") store._simple_insert_txn( cursor, table="event_json", values={ "event_id": event.event_id, "room_id": event.room_id, "internal_metadata": metadata_json, "json": event_json, }, or_replace=True, )
def get_server_verify_key_v1_direct(self, server_name, key_ids): """Finds a verification key for the server with one of the key ids. Args: server_name (str): The name of the server to fetch a key for. keys_ids (list of str): The key_ids to check for. """ # Try to fetch the key from the remote server. (response, tls_certificate) = yield fetch_server_key(server_name, self.hs.tls_context_factory) # Check the response. x509_certificate_bytes = crypto.dump_certificate( crypto.FILETYPE_ASN1, tls_certificate) if ("signatures" not in response or server_name not in response["signatures"]): raise ValueError("Key response not signed by remote server") if "tls_certificate" not in response: raise ValueError("Key response missing TLS certificate") tls_certificate_b64 = response["tls_certificate"] if encode_base64(x509_certificate_bytes) != tls_certificate_b64: raise ValueError("TLS certificate doesn't match") # Cache the result in the datastore. time_now_ms = self.clock.time_msec() verify_keys = {} for key_id, key_base64 in response["verify_keys"].items(): if is_signing_algorithm_supported(key_id): key_bytes = decode_base64(key_base64) verify_key = decode_verify_key_bytes(key_id, key_bytes) verify_key.time_added = time_now_ms verify_keys[key_id] = verify_key for key_id in response["signatures"][server_name]: if key_id not in response["verify_keys"]: raise ValueError( "Key response must include verification keys for all" " signatures") if key_id in verify_keys: verify_signed_json(response, server_name, verify_keys[key_id]) yield self.store.store_server_certificate( server_name, server_name, time_now_ms, tls_certificate, ) yield self.store_keys( server_name=server_name, from_server=server_name, verify_keys=verify_keys, ) defer.returnValue(verify_keys)
def get_server_verify_key(self, server_name, key_ids): """Finds a verification key for the server with one of the key ids. Args: server_name (str): The name of the server to fetch a key for. keys_ids (list of str): The key_ids to check for. """ # Check the datastore to see if we have one cached. cached = yield self.store.get_server_verify_keys(server_name, key_ids) if cached: defer.returnValue(cached[0]) return # Try to fetch the key from the remote server. limiter = yield get_retry_limiter( server_name, self.clock, self.store, ) with limiter: (response, tls_certificate) = yield fetch_server_key( server_name, self.hs.tls_context_factory ) # Check the response. x509_certificate_bytes = crypto.dump_certificate( crypto.FILETYPE_ASN1, tls_certificate ) if ("signatures" not in response or server_name not in response["signatures"]): raise ValueError("Key response not signed by remote server") if "tls_certificate" not in response: raise ValueError("Key response missing TLS certificate") tls_certificate_b64 = response["tls_certificate"] if encode_base64(x509_certificate_bytes) != tls_certificate_b64: raise ValueError("TLS certificate doesn't match") verify_keys = {} for key_id, key_base64 in response["verify_keys"].items(): if is_signing_algorithm_supported(key_id): key_bytes = decode_base64(key_base64) verify_key = decode_verify_key_bytes(key_id, key_bytes) verify_keys[key_id] = verify_key for key_id in response["signatures"][server_name]: if key_id not in response["verify_keys"]: raise ValueError( "Key response must include verification keys for all" " signatures" ) if key_id in verify_keys: verify_signed_json( response, server_name, verify_keys[key_id] ) # Cache the result in the datastore. time_now_ms = self.clock.time_msec() yield self.store.store_server_certificate( server_name, server_name, time_now_ms, tls_certificate, ) for key_id, key in verify_keys.items(): yield self.store.store_server_verify_key( server_name, server_name, time_now_ms, key ) for key_id in key_ids: if key_id in verify_keys: defer.returnValue(verify_keys[key_id]) return raise ValueError("No verification key found for given key ids")
def get_server_verify_key_v2_indirect(self, server_name, key_ids, perspective_name, perspective_keys): limiter = yield get_retry_limiter(perspective_name, self.clock, self.store) with limiter: # TODO(mark): Set the minimum_valid_until_ts to that needed by # the events being validated or the current time if validating # an incoming request. responses = yield self.client.post_json( destination=perspective_name, path=b"/_matrix/key/v2/query", data={ u"server_keys": { server_name: { key_id: { u"minimum_valid_until_ts": 0 } for key_id in key_ids } } }, ) keys = {} for response in responses: if (u"signatures" not in response or perspective_name not in response[u"signatures"]): raise ValueError( "Key response not signed by perspective server" " %r" % (perspective_name, )) verified = False for key_id in response[u"signatures"][perspective_name]: if key_id in perspective_keys: verify_signed_json(response, perspective_name, perspective_keys[key_id]) verified = True if not verified: logging.info( "Response from perspective server %r not signed with a" " known key, signed with: %r, known keys: %r", perspective_name, list(response[u"signatures"][perspective_name]), list(perspective_keys)) raise ValueError( "Response not signed with a known key for perspective" " server %r" % (perspective_name, )) response_keys = yield self.process_v2_response( server_name, perspective_name, response) keys.update(response_keys) yield self.store_keys( server_name=server_name, from_server=perspective_name, verify_keys=keys, ) defer.returnValue(keys)
def process_v2_response(self, server_name, from_server, response_json, requested_id=None): time_now_ms = self.clock.time_msec() response_keys = {} verify_keys = {} for key_id, key_data in response_json["verify_keys"].items(): if is_signing_algorithm_supported(key_id): key_base64 = key_data["key"] key_bytes = decode_base64(key_base64) verify_key = decode_verify_key_bytes(key_id, key_bytes) verify_key.time_added = time_now_ms verify_keys[key_id] = verify_key old_verify_keys = {} for key_id, key_data in response_json["old_verify_keys"].items(): if is_signing_algorithm_supported(key_id): key_base64 = key_data["key"] key_bytes = decode_base64(key_base64) verify_key = decode_verify_key_bytes(key_id, key_bytes) verify_key.expired = key_data["expired_ts"] verify_key.time_added = time_now_ms old_verify_keys[key_id] = verify_key for key_id in response_json["signatures"][server_name]: if key_id not in response_json["verify_keys"]: raise ValueError( "Key response must include verification keys for all" " signatures") if key_id in verify_keys: verify_signed_json(response_json, server_name, verify_keys[key_id]) signed_key_json = sign_json( response_json, self.config.server_name, self.config.signing_key[0], ) signed_key_json_bytes = encode_canonical_json(signed_key_json) ts_valid_until_ms = signed_key_json[u"valid_until_ts"] updated_key_ids = set() if requested_id is not None: updated_key_ids.add(requested_id) updated_key_ids.update(verify_keys) updated_key_ids.update(old_verify_keys) response_keys.update(verify_keys) response_keys.update(old_verify_keys) for key_id in updated_key_ids: yield self.store.store_server_keys_json( server_name=server_name, key_id=key_id, from_server=server_name, ts_now_ms=time_now_ms, ts_expires_ms=ts_valid_until_ms, key_json_bytes=signed_key_json_bytes, ) defer.returnValue(response_keys) raise ValueError("No verification key found for given key ids")
def reinsert_events(cursor, server_name, signing_key): print "Running delta: v10" cursor.executescript(delta_sql) cursor.execute("SELECT * FROM events ORDER BY rowid ASC") print "Getting events..." rows = store.cursor_to_dict(cursor) events = store._generate_event_json(cursor, rows) print "Got events from DB." algorithms = { "sha256": hashlib.sha256, } key_id = "%s:%s" % (signing_key.alg, signing_key.version) verify_key = signing_key.verify_key verify_key.alg = signing_key.alg verify_key.version = signing_key.version server_keys = {server_name: {key_id: verify_key}} i = 0 N = len(events) for event in events: if i % 100 == 0: print "Processed: %d/%d events" % ( i, N, ) i += 1 # for alg_name in event.hashes: # if check_event_content_hash(event, algorithms[alg_name]): # pass # else: # pass # print "FAIL content hash %s %s" % (alg_name, event.event_id, ) have_own_correctly_signed = False for host, sigs in event.signatures.items(): pruned = prune_event(event) for key_id in sigs: if host not in server_keys: server_keys[host] = {} # get_key(host) if key_id in server_keys[host]: try: verify_signed_json(pruned.get_pdu_json(), host, server_keys[host][key_id]) if host == server_name: have_own_correctly_signed = True except SignatureVerifyException: print "FAIL signature check %s %s" % (key_id, event.event_id) # TODO: Re sign with our own server key if not have_own_correctly_signed: sigs = compute_event_signature(event, server_name, signing_key) event.signatures.update(sigs) pruned = prune_event(event) for key_id in event.signatures[server_name]: verify_signed_json(pruned.get_pdu_json(), server_name, server_keys[server_name][key_id]) event_json = encode_canonical_json(event.get_dict()).decode("UTF-8") metadata_json = encode_canonical_json( event.internal_metadata.get_dict()).decode("UTF-8") store._simple_insert_txn( cursor, table="event_json", values={ "event_id": event.event_id, "room_id": event.room_id, "internal_metadata": metadata_json, "json": event_json, }, or_replace=True, )
def process_v2_response(self, server_name, from_server, response_json, requested_id=None): time_now_ms = self.clock.time_msec() response_keys = {} verify_keys = {} for key_id, key_data in response_json["verify_keys"].items(): if is_signing_algorithm_supported(key_id): key_base64 = key_data["key"] key_bytes = decode_base64(key_base64) verify_key = decode_verify_key_bytes(key_id, key_bytes) verify_key.time_added = time_now_ms verify_keys[key_id] = verify_key old_verify_keys = {} for key_id, key_data in response_json["old_verify_keys"].items(): if is_signing_algorithm_supported(key_id): key_base64 = key_data["key"] key_bytes = decode_base64(key_base64) verify_key = decode_verify_key_bytes(key_id, key_bytes) verify_key.expired = key_data["expired_ts"] verify_key.time_added = time_now_ms old_verify_keys[key_id] = verify_key for key_id in response_json["signatures"].get(server_name, {}): if key_id not in response_json["verify_keys"]: raise ValueError( "Key response must include verification keys for all" " signatures" ) if key_id in verify_keys: verify_signed_json( response_json, server_name, verify_keys[key_id] ) signed_key_json = sign_json( response_json, self.config.server_name, self.config.signing_key[0], ) signed_key_json_bytes = encode_canonical_json(signed_key_json) ts_valid_until_ms = signed_key_json[u"valid_until_ts"] updated_key_ids = set() if requested_id is not None: updated_key_ids.add(requested_id) updated_key_ids.update(verify_keys) updated_key_ids.update(old_verify_keys) response_keys.update(verify_keys) response_keys.update(old_verify_keys) for key_id in updated_key_ids: yield self.store.store_server_keys_json( server_name=server_name, key_id=key_id, from_server=server_name, ts_now_ms=time_now_ms, ts_expires_ms=ts_valid_until_ms, key_json_bytes=signed_key_json_bytes, ) defer.returnValue(response_keys) raise ValueError("No verification key found for given key ids")
def get_server_verify_key_v2_indirect(self, server_name, key_ids, perspective_name, perspective_keys): limiter = yield get_retry_limiter( perspective_name, self.clock, self.store ) with limiter: # TODO(mark): Set the minimum_valid_until_ts to that needed by # the events being validated or the current time if validating # an incoming request. query_response = yield self.client.post_json( destination=perspective_name, path=b"/_matrix/key/v2/query", data={ u"server_keys": { server_name: { key_id: { u"minimum_valid_until_ts": 0 } for key_id in key_ids } } }, ) keys = {} responses = query_response["server_keys"] for response in responses: if (u"signatures" not in response or perspective_name not in response[u"signatures"]): raise ValueError( "Key response not signed by perspective server" " %r" % (perspective_name,) ) verified = False for key_id in response[u"signatures"][perspective_name]: if key_id in perspective_keys: verify_signed_json( response, perspective_name, perspective_keys[key_id] ) verified = True if not verified: logging.info( "Response from perspective server %r not signed with a" " known key, signed with: %r, known keys: %r", perspective_name, list(response[u"signatures"][perspective_name]), list(perspective_keys) ) raise ValueError( "Response not signed with a known key for perspective" " server %r" % (perspective_name,) ) response_keys = yield self.process_v2_response( server_name, perspective_name, response ) keys.update(response_keys) yield self.store_keys( server_name=server_name, from_server=perspective_name, verify_keys=keys, ) defer.returnValue(keys)
def process_v2_response(self, from_server, response_json, requested_ids=[]): time_now_ms = self.clock.time_msec() response_keys = {} verify_keys = {} for key_id, key_data in response_json["verify_keys"].items(): if is_signing_algorithm_supported(key_id): key_base64 = key_data["key"] key_bytes = decode_base64(key_base64) verify_key = decode_verify_key_bytes(key_id, key_bytes) verify_key.time_added = time_now_ms verify_keys[key_id] = verify_key old_verify_keys = {} for key_id, key_data in response_json["old_verify_keys"].items(): if is_signing_algorithm_supported(key_id): key_base64 = key_data["key"] key_bytes = decode_base64(key_base64) verify_key = decode_verify_key_bytes(key_id, key_bytes) verify_key.expired = key_data["expired_ts"] verify_key.time_added = time_now_ms old_verify_keys[key_id] = verify_key results = {} server_name = response_json["server_name"] for key_id in response_json["signatures"].get(server_name, {}): if key_id not in response_json["verify_keys"]: raise ValueError( "Key response must include verification keys for all" " signatures" ) if key_id in verify_keys: verify_signed_json( response_json, server_name, verify_keys[key_id] ) signed_key_json = sign_json( response_json, self.config.server_name, self.config.signing_key[0], ) signed_key_json_bytes = encode_canonical_json(signed_key_json) ts_valid_until_ms = signed_key_json[u"valid_until_ts"] updated_key_ids = set(requested_ids) updated_key_ids.update(verify_keys) updated_key_ids.update(old_verify_keys) response_keys.update(verify_keys) response_keys.update(old_verify_keys) yield defer.gatherResults( [ self.store.store_server_keys_json( server_name=server_name, key_id=key_id, from_server=server_name, ts_now_ms=time_now_ms, ts_expires_ms=ts_valid_until_ms, key_json_bytes=signed_key_json_bytes, ) for key_id in updated_key_ids ], consumeErrors=True, ).addErrback(unwrapFirstError) results[server_name] = response_keys defer.returnValue(results)
def process_v2_response(self, from_server, response_json, requested_ids=[]): time_now_ms = self.clock.time_msec() response_keys = {} verify_keys = {} for key_id, key_data in response_json["verify_keys"].items(): if is_signing_algorithm_supported(key_id): key_base64 = key_data["key"] key_bytes = decode_base64(key_base64) verify_key = decode_verify_key_bytes(key_id, key_bytes) verify_key.time_added = time_now_ms verify_keys[key_id] = verify_key old_verify_keys = {} for key_id, key_data in response_json["old_verify_keys"].items(): if is_signing_algorithm_supported(key_id): key_base64 = key_data["key"] key_bytes = decode_base64(key_base64) verify_key = decode_verify_key_bytes(key_id, key_bytes) verify_key.expired = key_data["expired_ts"] verify_key.time_added = time_now_ms old_verify_keys[key_id] = verify_key results = {} server_name = response_json["server_name"] for key_id in response_json["signatures"].get(server_name, {}): if key_id not in response_json["verify_keys"]: raise ValueError( "Key response must include verification keys for all" " signatures") if key_id in verify_keys: verify_signed_json(response_json, server_name, verify_keys[key_id]) signed_key_json = sign_json( response_json, self.config.server_name, self.config.signing_key[0], ) signed_key_json_bytes = encode_canonical_json(signed_key_json) ts_valid_until_ms = signed_key_json[u"valid_until_ts"] updated_key_ids = set(requested_ids) updated_key_ids.update(verify_keys) updated_key_ids.update(old_verify_keys) response_keys.update(verify_keys) response_keys.update(old_verify_keys) yield defer.gatherResults( [ self.store.store_server_keys_json( server_name=server_name, key_id=key_id, from_server=server_name, ts_now_ms=time_now_ms, ts_expires_ms=ts_valid_until_ms, key_json_bytes=signed_key_json_bytes, ) for key_id in updated_key_ids ], consumeErrors=True, ).addErrback(unwrapFirstError) results[server_name] = response_keys defer.returnValue(results)