From af5ac7c5faa5366683dfddf76f4122c8974ca1fa Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Fri, 27 Feb 2015 13:53:32 +0100 Subject: Require authentication for merge calls --- test/config/frontend-1.config | 10 +++++----- test/config/storage-1.config | 2 +- tools/merge.py | 42 ++++++++++++++++++++++++++++++++---------- tools/testcase1.py | 2 +- 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/test/config/frontend-1.config b/test/config/frontend-1.config index 35631d1..9d7e37c 100644 --- a/test/config/frontend-1.config +++ b/test/config/frontend-1.config @@ -34,11 +34,11 @@ {storage_nodes_quorum, 1}, {publickey_path, "publickeys"}, {own_key, {"frontend-1", "privatekeys/frontend-1-private.pem"}}, - {allowed_clients, [{"/ct/frontend/sendentry", noauth}, - {"/ct/frontend/sendlog", noauth}, - {"/ct/frontend/sendsth", noauth}, - {"/ct/frontend/currentposition", noauth}, - {"/ct/frontend/missingentries", noauth}, + {allowed_clients, [{"/ct/frontend/sendentry", ["merge-1"]}, + {"/ct/frontend/sendlog", ["merge-1"]}, + {"/ct/frontend/sendsth", ["merge-1"]}, + {"/ct/frontend/currentposition", ["merge-1"]}, + {"/ct/frontend/missingentries", ["merge-1"]}, {"/ct/v1/add-chain", noauth}, {"/ct/v1/add-pre-chain", noauth}, {"/ct/v1/get-sth", noauth}, diff --git a/test/config/storage-1.config b/test/config/storage-1.config index 8770f88..005a8ad 100644 --- a/test/config/storage-1.config +++ b/test/config/storage-1.config @@ -33,7 +33,7 @@ {own_key, {"storage-1", "privatekeys/storage-1-private.pem"}}, {allowed_clients, [{"/ct/storage/sendentry", ["frontend-1"]}, {"/ct/storage/entrycommitted", ["frontend-1"]}, - {"/ct/storage/fetchnewentries", noauth}, + {"/ct/storage/fetchnewentries", ["merge-1"]}, {"/ct/storage/getentry", noauth} ]} ]}]. diff --git a/tools/merge.py b/tools/merge.py index f4a007d..6becf7e 100755 --- a/tools/merge.py +++ b/tools/merge.py @@ -11,6 +11,9 @@ import urllib import urllib2 import sys import time +import ecdsa +import hashlib +import urlparse from certtools import build_merkle_tree, create_sth_signature, check_sth_signature, get_eckey_from_file, timing_point parser = argparse.ArgumentParser(description="") @@ -19,6 +22,8 @@ parser.add_argument("--frontend", action="append", metavar="url", help="Base URL parser.add_argument("--storage", action="append", metavar="url", help="Base URL for storage server", required=True) parser.add_argument("--mergedb", metavar="dir", help="Merge database directory", required=True) parser.add_argument("--keyfile", metavar="keyfile", help="File containing log key", required=True) +parser.add_argument("--own-keyname", metavar="keyname", help="The key name of the merge node", required=True) +parser.add_argument("--own-keyfile", metavar="keyfile", help="The file containing the private key of the merge node", required=True) parser.add_argument("--nomerge", action='store_true', help="Don't actually do merge") args = parser.parse_args() @@ -52,9 +57,26 @@ def add_to_logorder(key): f.write(base64.b16encode(key) + "\n") f.close() +def http_request(url, data=None): + req = urllib2.Request(url, data) + keyname = args.own_keyname + privatekey = get_eckey_from_file(args.own_keyfile) + sk = ecdsa.SigningKey.from_der(privatekey) + parsed_url = urlparse.urlparse(url) + if data == None: + data = parsed_url.query + method = "GET" + else: + method = "POST" + signature = sk.sign("%s\0%s\0%s" % (method, parsed_url.path, data), hashfunc=hashlib.sha256, + sigencode=ecdsa.util.sigencode_der) + req.add_header('X-Catlfish-Auth', base64.b64encode(signature) + ";key=" + keyname) + result = urllib2.urlopen(req).read() + return result + def get_new_entries(baseurl): try: - result = urllib2.urlopen(baseurl + "ct/storage/fetchnewentries").read() + result = http_request(baseurl + "ct/storage/fetchnewentries") parsed_result = json.loads(result) if parsed_result.get(u"result") == u"ok": return [base64.b64decode(entry) for entry in parsed_result[u"entries"]] @@ -67,7 +89,7 @@ def get_new_entries(baseurl): def get_entries(baseurl, hashes): try: params = urllib.urlencode({"hash":[base64.b64encode(hash) for hash in hashes]}, doseq=True) - result = urllib2.urlopen(baseurl + "ct/storage/getentry?" + params).read() + result = http_request(baseurl + "ct/storage/getentry?" + params) parsed_result = json.loads(result) if parsed_result.get(u"result") == u"ok": entries = dict([(base64.b64decode(entry["hash"]), base64.b64decode(entry["entry"])) for entry in parsed_result[u"entries"]]) @@ -82,7 +104,7 @@ def get_entries(baseurl, hashes): def get_curpos(baseurl): try: - result = urllib2.urlopen(baseurl + "ct/frontend/currentposition").read() + result = http_request(baseurl + "ct/frontend/currentposition") parsed_result = json.loads(result) if parsed_result.get(u"result") == u"ok": return parsed_result[u"position"] @@ -94,8 +116,8 @@ def get_curpos(baseurl): def sendlog(baseurl, submission): try: - result = urllib2.urlopen(baseurl + "ct/frontend/sendlog", - json.dumps(submission)).read() + result = http_request(baseurl + "ct/frontend/sendlog", + json.dumps(submission)) return json.loads(result) except urllib2.HTTPError, e: print "ERROR: sendlog", e.read() @@ -110,8 +132,8 @@ def sendlog(baseurl, submission): def sendentry(baseurl, entry, hash): try: - result = urllib2.urlopen(baseurl + "ct/frontend/sendentry", - json.dumps({"entry":base64.b64encode(entry), "treeleafhash":base64.b64encode(hash)})).read() + result = http_request(baseurl + "ct/frontend/sendentry", + json.dumps({"entry":base64.b64encode(entry), "treeleafhash":base64.b64encode(hash)})) return json.loads(result) except urllib2.HTTPError, e: print "ERROR: sendentry", e.read() @@ -126,8 +148,8 @@ def sendentry(baseurl, entry, hash): def sendsth(baseurl, submission): try: - result = urllib2.urlopen(baseurl + "ct/frontend/sendsth", - json.dumps(submission)).read() + result = http_request(baseurl + "ct/frontend/sendsth", + json.dumps(submission)) return json.loads(result) except urllib2.HTTPError, e: print "ERROR: sendsth", e.read() @@ -142,7 +164,7 @@ def sendsth(baseurl, submission): def get_missingentries(baseurl): try: - result = urllib2.urlopen(baseurl + "ct/frontend/missingentries").read() + result = http_request(baseurl + "ct/frontend/missingentries") parsed_result = json.loads(result) if parsed_result.get(u"result") == u"ok": return parsed_result[u"entries"] diff --git a/tools/testcase1.py b/tools/testcase1.py index a41a783..c87e8eb 100755 --- a/tools/testcase1.py +++ b/tools/testcase1.py @@ -136,7 +136,7 @@ def get_and_check_entry(timestamp, chain, leaf_index): len(submittedcertchain)) def merge(): - return subprocess.call(["./merge.py", "--baseurl", "https://127.0.0.1:8080/", "--frontend", "https://127.0.0.1:8082/", "--storage", "https://127.0.0.1:8081/", "--mergedb", "../rel/mergedb", "--keyfile", "../rel/test/eckey.pem"]) + return subprocess.call(["./merge.py", "--baseurl", "https://127.0.0.1:8080/", "--frontend", "https://127.0.0.1:8082/", "--storage", "https://127.0.0.1:8081/", "--mergedb", "../rel/mergedb", "--keyfile", "../rel/test/eckey.pem", "--own-keyname", "merge-1", "--own-keyfile", "../rel/privatekeys/merge-1-private.pem"]) print_and_check_tree_size(0) -- cgit v1.1