diff options
Diffstat (limited to 'tools/mergetools.py')
| -rw-r--r-- | tools/mergetools.py | 250 | 
1 files changed, 247 insertions, 3 deletions
| diff --git a/tools/mergetools.py b/tools/mergetools.py index 947d7f4..820087c 100644 --- a/tools/mergetools.py +++ b/tools/mergetools.py @@ -1,10 +1,17 @@  # Copyright (c) 2015, NORDUnet A/S.  # See LICENSE for licensing information. + +import os  import base64  import hashlib  import sys  import struct -from certtools import get_leaf_hash +import urllib +import urllib2 +import json +from certtools import get_leaf_hash, create_sth_signature, \ +    check_sth_signature, get_eckey_from_file, http_request, \ +    get_leaf_hash, decode_certificate_chain  def parselogrow(row):      return base64.b16decode(row, casefold=True) @@ -22,7 +29,7 @@ def read_chain(chainsdir, key):      filename = base64.b16encode(key).upper()      try:          f = read_chain_open(chainsdir, filename) -    except IOError, e: +    except IOError:          f = read_chain_open(chainsdir, filename.lower())      value = f.read()      f.close() @@ -67,7 +74,7 @@ def unwrap_entry(entry):  def wrap_entry(entry):      return tlv_encodelist([("PLOP", entry), -                        ("S256", hashlib.sha256(entry).digest())]) +                           ("S256", hashlib.sha256(entry).digest())])  def verify_entry(verifycert, entry, hash):      packed = unwrap_entry(entry) @@ -94,3 +101,240 @@ def verify_entry(verifycert, entry, hash):      if error_code != 0:          print >>sys.stderr, result[1:]          sys.exit(1) + +def hexencode(key): +    return base64.b16encode(key).lower() + +def write_chain(key, value, chainsdir, hashed_dir=True): +    filename = hexencode(key) +    if hashed_dir: +        path = chainsdir + "/" \ +          + filename[0:2] + "/" + filename[2:4] + "/" + filename[4:6] +        try: +            os.makedirs(path) +        except Exception, e: +            pass +    else: +        path = chainsdir +    f = open(path + "/" + filename, "w") +    f.write(value) +    f.close() + +def add_to_logorder(logorderfile, key): +    f = open(logorderfile, "a") +    f.write(hexencode(key) + "\n") +    f.close() + +def fsync_logorder(logorderfile): +    f = open(logorderfile, "a") +    os.fsync(f.fileno()) +    f.close() + +def get_new_entries(node, baseurl, own_key, paths): +    try: +        result = http_request(baseurl + "plop/v1/storage/fetchnewentries", +                              key=own_key, verifynode=node, +                              publickeydir=paths["publickeys"]) +        parsed_result = json.loads(result) +        if parsed_result.get(u"result") == u"ok": +            return [base64.b64decode(entry) for \ +                    entry in parsed_result[u"entries"]] +        print >>sys.stderr, "ERROR: fetchnewentries", parsed_result +        sys.exit(1) +    except urllib2.HTTPError, e: +        print >>sys.stderr, "ERROR: fetchnewentries", e.read() +        sys.exit(1) + +def get_entries(node, baseurl, own_key, paths, hashes): +    try: +        params = urllib.urlencode({"hash":[base64.b64encode(hash) for \ +                                           hash in hashes]}, doseq=True) +        result = http_request(baseurl + "plop/v1/storage/getentry?" + params, +                              key=own_key, verifynode=node, +                              publickeydir=paths["publickeys"]) +        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"]]) +            assert len(entries) == len(hashes) +            assert set(entries.keys()) == set(hashes) +            return entries +        print >>sys.stderr, "ERROR: getentry", parsed_result +        sys.exit(1) +    except urllib2.HTTPError, e: +        print >>sys.stderr, "ERROR: getentry", e.read() +        sys.exit(1) + +def get_curpos(node, baseurl, own_key, paths): +    try: +        result = http_request(baseurl + "plop/v1/frontend/currentposition", key=own_key, verifynode=node, publickeydir=paths["publickeys"]) +        parsed_result = json.loads(result) +        if parsed_result.get(u"result") == u"ok": +            return parsed_result[u"position"] +        print >>sys.stderr, "ERROR: currentposition", parsed_result +        sys.exit(1) +    except urllib2.HTTPError, e: +        print >>sys.stderr, "ERROR: currentposition", e.read() +        sys.exit(1) + +def get_verifiedsize(node, baseurl, own_key, paths): +    try: +        result = http_request(baseurl + "plop/v1/merge/verifiedsize", key=own_key, verifynode=node, publickeydir=paths["publickeys"]) +        parsed_result = json.loads(result) +        if parsed_result.get(u"result") == u"ok": +            return parsed_result[u"size"] +        print >>sys.stderr, "ERROR: verifiedsize", parsed_result +        sys.exit(1) +    except urllib2.HTTPError, e: +        print >>sys.stderr, "ERROR: verifiedsize", e.read() +        sys.exit(1) + + +def sendlog(node, baseurl, own_key, paths, submission): +    try: +        result = http_request(baseurl + "plop/v1/frontend/sendlog", +            json.dumps(submission), key=own_key, verifynode=node, publickeydir=paths["publickeys"]) +        return json.loads(result) +    except urllib2.HTTPError, e: +        print >>sys.stderr, "ERROR: sendlog", e.read() +        sys.stderr.flush() +        return None +    except ValueError, e: +        print >>sys.stderr, "==== FAILED REQUEST ====" +        print >>sys.stderr, submission +        print >>sys.stderr, "======= RESPONSE =======" +        print >>sys.stderr, result +        print >>sys.stderr, "========================" +        sys.stderr.flush() +        raise e + +def backup_sendlog(node, baseurl, own_key, paths, submission): +    try: +        result = http_request(baseurl + "plop/v1/merge/sendlog", +            json.dumps(submission), key=own_key, verifynode=node, publickeydir=paths["publickeys"]) +        return json.loads(result) +    except urllib2.HTTPError, e: +        print >>sys.stderr, "ERROR: sendlog", e.read() +        sys.stderr.flush() +        return None +    except ValueError, e: +        print >>sys.stderr, "==== FAILED REQUEST ====" +        print >>sys.stderr, submission +        print >>sys.stderr, "======= RESPONSE =======" +        print >>sys.stderr, result +        print >>sys.stderr, "========================" +        sys.stderr.flush() +        raise e + +def sendentry(node, baseurl, own_key, paths, entry, hash): +    try: +        result = http_request(baseurl + "plop/v1/frontend/sendentry", +            json.dumps({"entry":base64.b64encode(entry), "treeleafhash":base64.b64encode(hash)}), key=own_key, +            verifynode=node, publickeydir=paths["publickeys"]) +        return json.loads(result) +    except urllib2.HTTPError, e: +        print >>sys.stderr, "ERROR: sendentry", e.read() +        sys.exit(1) +    except ValueError, e: +        print >>sys.stderr, "==== FAILED REQUEST ====" +        print >>sys.stderr, hash +        print >>sys.stderr, "======= RESPONSE =======" +        print >>sys.stderr, result +        print >>sys.stderr, "========================" +        sys.stderr.flush() +        raise e + +def sendentry_merge(node, baseurl, own_key, paths, entry, hash): +    try: +        result = http_request(baseurl + "plop/v1/merge/sendentry", +            json.dumps({"entry":base64.b64encode(entry), "treeleafhash":base64.b64encode(hash)}), key=own_key, +            verifynode=node, publickeydir=paths["publickeys"]) +        return json.loads(result) +    except urllib2.HTTPError, e: +        print >>sys.stderr, "ERROR: sendentry", e.read() +        sys.exit(1) +    except ValueError, e: +        print >>sys.stderr, "==== FAILED REQUEST ====" +        print >>sys.stderr, hash +        print >>sys.stderr, "======= RESPONSE =======" +        print >>sys.stderr, result +        print >>sys.stderr, "========================" +        sys.stderr.flush() +        raise e + +def sendsth(node, baseurl, own_key, paths, submission): +    try: +        result = http_request(baseurl + "plop/v1/frontend/sendsth", +            json.dumps(submission), key=own_key, verifynode=node, publickeydir=paths["publickeys"]) +        return json.loads(result) +    except urllib2.HTTPError, e: +        print >>sys.stderr, "ERROR: sendsth", e.read() +        sys.exit(1) +    except ValueError, e: +        print >>sys.stderr, "==== FAILED REQUEST ====" +        print >>sys.stderr, submission +        print >>sys.stderr, "======= RESPONSE =======" +        print >>sys.stderr, result +        print >>sys.stderr, "========================" +        sys.stderr.flush() +        raise e + +def verifyroot(node, baseurl, own_key, paths, treesize): +    try: +        result = http_request(baseurl + "plop/v1/merge/verifyroot", +            json.dumps({"tree_size":treesize}), key=own_key, verifynode=node, publickeydir=paths["publickeys"]) +        return json.loads(result) +    except urllib2.HTTPError, e: +        print >>sys.stderr, "ERROR: verifyroot", e.read() +        sys.exit(1) +    except ValueError, e: +        print >>sys.stderr, "==== FAILED REQUEST ====" +        print >>sys.stderr, submission +        print >>sys.stderr, "======= RESPONSE =======" +        print >>sys.stderr, result +        print >>sys.stderr, "========================" +        sys.stderr.flush() +        raise e + +def setverifiedsize(node, baseurl, own_key, paths, treesize): +    try: +        result = http_request(baseurl + "plop/v1/merge/setverifiedsize", +            json.dumps({"size":treesize}), key=own_key, verifynode=node, publickeydir=paths["publickeys"]) +        return json.loads(result) +    except urllib2.HTTPError, e: +        print >>sys.stderr, "ERROR: setverifiedsize", e.read() +        sys.exit(1) +    except ValueError, e: +        print >>sys.stderr, "==== FAILED REQUEST ====" +        print >>sys.stderr, submission +        print >>sys.stderr, "======= RESPONSE =======" +        print >>sys.stderr, result +        print >>sys.stderr, "========================" +        sys.stderr.flush() +        raise e + +def get_missingentries(node, baseurl, own_key, paths): +    try: +        result = http_request(baseurl + "plop/v1/frontend/missingentries", key=own_key, verifynode=node, publickeydir=paths["publickeys"]) +        parsed_result = json.loads(result) +        if parsed_result.get(u"result") == u"ok": +            return parsed_result[u"entries"] +        print >>sys.stderr, "ERROR: missingentries", parsed_result +        sys.exit(1) +    except urllib2.HTTPError, e: +        print >>sys.stderr, "ERROR: missingentries", e.read() +        sys.exit(1) + +def get_missingentriesforbackup(node, baseurl, own_key, paths): +    try: +        result = http_request(baseurl + "plop/v1/merge/missingentries", key=own_key, verifynode=node, publickeydir=paths["publickeys"]) +        parsed_result = json.loads(result) +        if parsed_result.get(u"result") == u"ok": +            return parsed_result[u"entries"] +        print >>sys.stderr, "ERROR: missingentriesforbackup", parsed_result +        sys.exit(1) +    except urllib2.HTTPError, e: +        print >>sys.stderr, "ERROR: missingentriesforbackup", e.read() +        sys.exit(1) + +def chunks(l, n): +    return [l[i:i+n] for i in range(0, len(l), n)] | 
