123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- import argparse
- import json
- import logging
- import sys
- import urllib2
- import dns.resolver
- from signedjson.key import decode_verify_key_bytes, write_signing_keys
- from signedjson.sign import verify_signed_json
- from unpaddedbase64 import decode_base64
- def get_targets(server_name):
- if ":" in server_name:
- target, port = server_name.split(":")
- yield (target, int(port))
- return
- try:
- answers = dns.resolver.query("_matrix._tcp." + server_name, "SRV")
- for srv in answers:
- yield (srv.target, srv.port)
- except dns.resolver.NXDOMAIN:
- yield (server_name, 8448)
- 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 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 Exception:
- 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 Exception:
- logging.exception("Check for key %s failed" % (key_id,))
- print("FAIL %s" % (key_id,))
- if __name__ == "__main__":
- main()
|