diff options
-rw-r--r-- | tools/certtools.py | 19 | ||||
-rwxr-xr-x | tools/initlog.py | 79 | ||||
-rwxr-xr-x | tools/merge_sth.py | 17 |
3 files changed, 102 insertions, 13 deletions
diff --git a/tools/certtools.py b/tools/certtools.py index e9ee99b..a054bbb 100644 --- a/tools/certtools.py +++ b/tools/certtools.py @@ -16,6 +16,7 @@ import zipfile import shutil import requests import warnings +import logging from datetime import datetime from certkeys import publickeys @@ -753,3 +754,21 @@ def write_file(fn, jsondata): tempname = fn + ".new" open(tempname, 'w').write(json.dumps(jsondata)) mv_file(tempname, fn) + +def generate_tree_head_signature(signingnodes, own_key, + tree_size, timestamp, root_hash): + tree_head_signature = None + for signingnode in signingnodes: + try: + tree_head_signature = \ + create_sth_signature(tree_size, timestamp, + root_hash, + "https://%s/" % signingnode["address"], + key=own_key) + break + except requests.exceptions.HTTPError, e: + logging.warning("create_sth_signature error: %s", e.response) + if tree_head_signature == None: + logging.error("Could not contact any signing nodes") + + return tree_head_signature diff --git a/tools/initlog.py b/tools/initlog.py new file mode 100755 index 0000000..270ebc5 --- /dev/null +++ b/tools/initlog.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (c) 2016, NORDUnet A/S. +# See LICENSE for licensing information. +# +# Initialise a new CT log. +# + +import sys +import os +import argparse +import yaml +import errno +from time import time +from base64 import b64encode +from certtools import build_merkle_tree, generate_tree_head_signature, \ + write_file +from mergetools import get_sth + +def parse_args(): + parser = argparse.ArgumentParser(description="") + parser.add_argument('--config', help="System configuration", + required=True) + parser.add_argument('--localconfig', help="Local configuration", + required=True) + + args = parser.parse_args() + config = yaml.load(open(args.config)) + localconfig = yaml.load(open(args.localconfig)) + + return (args, config, localconfig) + +def main(): + """ + """ + args, config, localconfig = parse_args() + signingnodes = config["signingnodes"] + paths = localconfig["paths"] + own_key = (localconfig["nodename"], + "%s/%s-private.pem" % (paths["privatekeys"], + localconfig["nodename"])) + mergedb = paths["mergedb"] + sthfile = mergedb + "/sth" + + sth = get_sth(sthfile) + if sth['tree_size'] >= 0: + print >>sys.stderr, \ + "This log has an STH file with tree size %s." % sth['tree_size'] + print >>sys.stderr, "I refuse to destroy this log." + return 1 + + try: + os.stat(own_key[1]) + except OSError, e: + if e.errno == errno.ENOENT: + print >>sys.stderr, "Unable to open keyfile: %s" % own_key[1] + return 1 + raise + + tree_size = 0 + timestamp = int(time() * 1000) + root_hash = build_merkle_tree('')[-1][0] + tree_head_signature = \ + generate_tree_head_signature(signingnodes, own_key, + tree_size, timestamp, root_hash) + if tree_head_signature == None: + return 1 + + sth = {"tree_size": 0, + "timestamp": timestamp, + "sha256_root_hash": b64encode(root_hash), + "tree_head_signature": b64encode(tree_head_signature)} + + write_file(sthfile, sth) + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/tools/merge_sth.py b/tools/merge_sth.py index 2184af1..89fcf18 100755 --- a/tools/merge_sth.py +++ b/tools/merge_sth.py @@ -18,7 +18,7 @@ from mergetools import parse_args, get_nfetched, hexencode, hexdecode, \ get_logorder, get_sth, flock_ex_or_fail, loginit from certtools import create_ssl_context, get_public_key_from_file, \ timing_point, create_sth_signature, write_file, check_sth_signature, \ - build_merkle_tree + build_merkle_tree, generate_tree_head_signature def merge_sth(args, config, localconfig): paths = localconfig["paths"] @@ -85,19 +85,10 @@ def merge_sth(args, config, localconfig): root_hash = root_hash_calc timestamp = int(time.time() * 1000) - tree_head_signature = None - for signingnode in signingnodes: - try: - tree_head_signature = \ - create_sth_signature(tree_size, timestamp, - root_hash, - "https://%s/" % signingnode["address"], - key=own_key) - break - except requests.exceptions.HTTPError, e: - logging.warning("create_sth_signature error: %s", e.response) + tree_head_signature = \ + generate_tree_head_signature(signingnodes, own_key, + tree_size, timestamp, root_hash) if tree_head_signature == None: - logging.error("Could not contact any signing nodes") return 0 sth = {"tree_size": tree_size, "timestamp": timestamp, |