diff options
author | Josef Gustafsson <josef.gson@gmail.com> | 2015-09-04 12:18:19 +0200 |
---|---|---|
committer | Josef Gustafsson <josef.gson@gmail.com> | 2015-09-04 12:18:19 +0200 |
commit | d1a2f978fb626c904fb1278c792d992ec4563acf (patch) | |
tree | e0ae1a38f9d4fc4c14b433222bff70e64bb1ac83 /tools | |
parent | 4596485adffb636c014362bc982ee0b952c77f26 (diff) |
stripping away everything except what is necessary for nagiosnagios
Diffstat (limited to 'tools')
36 files changed, 0 insertions, 5391 deletions
diff --git a/tools/check-sth.py b/tools/check-sth.py deleted file mode 100755 index dacd8e6..0000000 --- a/tools/check-sth.py +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (c) 2015, NORDUnet A/S. -# See LICENSE for licensing information. - -import sys -import argparse -import json -import errno -import shutil -import base64 -from datetime import datetime, timedelta, tzinfo -import time -from certtools import get_sth, create_ssl_context, check_sth_signature, get_public_key_from_file, get_consistency_proof, verify_consistency_proof - -NAGIOS_OK = 0 -NAGIOS_WARN = 1 -NAGIOS_CRIT = 2 -NAGIOS_UNKNOWN = 3 - -DEFAULT_CUR_FILE = 'cur-sth.json' - -parser = argparse.ArgumentParser(description="") -parser.add_argument('--cur-sth', - metavar='file', - default=DEFAULT_CUR_FILE, - help="File containing current STH (default=%s)" % DEFAULT_CUR_FILE) -parser.add_argument('baseurl', help="Base URL for CT log") -parser.add_argument('--publickey', default=None, metavar='file', help='Public key for the CT log') -parser.add_argument('--cafile', default=None, metavar='file', help='File containing the CA cert') -parser.add_argument('--allow-lag', action='store_true', help='Allow node to lag behind previous STH') -parser.add_argument('--quiet-ok', action='store_true', help="Don't print status if OK") - -def print_sth(sth): - if sth is None: - print "NONE" - else: - print sth['timestamp'] - print sth['sha256_root_hash'] - print sth['tree_size'] - print sth['tree_head_signature'] - -def get_new_sth(baseurl): - try: - sth = get_sth(baseurl) - except Exception, e: - print e - sys.exit(NAGIOS_UNKNOWN) - return sth - -def read_sth(fn): - try: - f = open(fn) - except IOError, e: - if e.errno == errno.ENOENT: - return None - raise e - return json.loads(f.read()) - -def mv_file(fromfn, tofn): - shutil.move(fromfn, tofn) - -def write_file(fn, sth): - tempname = fn + ".new" - open(tempname, 'w').write(json.dumps(sth)) - mv_file(tempname, fn) - -class UTC(tzinfo): - def utcoffset(self, dt): - return timedelta(hours=0) - def dst(self, dt): - return timedelta(0) - -def check_age(sth): - age = time.time() - sth["timestamp"]/1000 - sth_time = datetime.fromtimestamp(sth['timestamp'] / 1000, UTC()).strftime("%Y-%m-%d %H:%M:%S") - roothash = b64_to_b16(sth['sha256_root_hash']) - if age > 6 * 3600: - print "CRITICAL: %s is older than 6h: %s UTC" % (roothash, sth_time) - sys.exit(NAGIOS_CRIT) - if age > 2 * 3600: - print "WARNING: %s is older than 2h: %s UTC" % (roothash, sth_time) - sys.exit(NAGIOS_WARN) - return "%s UTC, %d minutes ago" % (sth_time, age/60) - -def check_consistency(newsth, oldsth, baseurl): - consistency_proof = [base64.decodestring(entry) for entry in get_consistency_proof(baseurl, oldsth["tree_size"], newsth["tree_size"])] - (old_treehead, new_treehead) = verify_consistency_proof(consistency_proof, oldsth["tree_size"], newsth["tree_size"], base64.b64decode(oldsth["sha256_root_hash"])) - assert old_treehead == base64.b64decode(oldsth["sha256_root_hash"]) - assert new_treehead == base64.b64decode(newsth["sha256_root_hash"]) - -def b64_to_b16(s): - return base64.b16encode(base64.decodestring(s)) - -def main(args): - if args.cur_sth is None: - args.cur_sth = "cur-sth.json" - - create_ssl_context(cafile=args.cafile) - - logpublickey = get_public_key_from_file(args.publickey) if args.publickey else None - - newsth = get_new_sth(args.baseurl) - check_sth_signature(args.baseurl, newsth, publickey=logpublickey) - - oldsth = read_sth(args.cur_sth) - - #print_sth(newsth) - #print_sth(oldsth) - - if oldsth: - if newsth["tree_size"] == oldsth["tree_size"]: - if oldsth["sha256_root_hash"] != newsth["sha256_root_hash"]: - print "CRITICAL: root hash is different even though tree size is the same.", - print "tree size:", newsth["tree_size"], - print "old hash:", b64_to_b16(oldsth["sha256_root_hash"]) - print "new hash:", b64_to_b16(newsth["sha256_root_hash"]) - sys.exit(NAGIOS_CRIT) - elif newsth["tree_size"] < oldsth["tree_size"]: - if not args.allow_lag: - print "CRITICAL: new tree smaller than previous tree (%d < %d)" % \ - (newsth["tree_size"], oldsth["tree_size"]) - sys.exit(NAGIOS_CRIT) - - if oldsth and oldsth["tree_size"] > 0 and oldsth["tree_size"] != newsth["tree_size"]: - check_consistency(newsth, oldsth, args.baseurl) - - age = check_age(newsth) - - write_file(args.cur_sth, newsth) - - if not args.quiet_ok: - print "OK: size: %d hash: %s, %s" % (newsth["tree_size"], b64_to_b16(newsth["sha256_root_hash"])[:8], age) - sys.exit(NAGIOS_OK) - -if __name__ == '__main__': - main(parser.parse_args()) diff --git a/tools/comparecert.py b/tools/comparecert.py deleted file mode 100755 index 81893f7..0000000 --- a/tools/comparecert.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2014, NORDUnet A/S. -# See LICENSE for licensing information. - -import argparse -import urllib2 -import urllib -import json -import base64 -import sys -import struct -import hashlib -import itertools -from certtools import * -from certtools import * -from precerttools import * -import os -import signal -import select -import zipfile - -def readfile(filename): - contents = open(filename).read() - certchain = get_certs_from_string(contents) - precerts = get_precerts_from_string(contents) - return (certchain, precerts) - -def testcerts(template, test): - (certchain1, precerts1) = template - (certchain2, precerts2) = test - - if precerts1 != precerts2: - return (False, "precerts are different") - - if certchain1 == certchain2: - return (True, "") - - if len(certchain2) == len(certchain1) + 1: - if certchain2[:-1] != certchain1: - return (False, "certchains are different") - last_issuer = get_cert_info(certchain1[-1])["issuer"] - root_subject = get_cert_info(certchain2[-1])["subject"] - if last_issuer == root_subject: - return (True, "fetched chain has an appended root cert") - else: - return (False, "fetched chain has an extra entry") - - return (False, "certchains are different") - -parser = argparse.ArgumentParser(description='') -parser.add_argument('templates', help="Test templates, separated with colon") -parser.add_argument('test', help="Files to test, separated with colon") -args = parser.parse_args() - -templates = [readfile(filename) for filename in args.templates.split(":")] - -tests = [readfile(filename) for filename in args.test.split(":")] - - -for test in tests: - found = False - errors = [] - for template in templates: - (result, message) = testcerts(template, test) - if result: - print message - found = True - templates.remove(template) - break - else: - errors.append(message) - if not found: - print "Matching template not found for test" - for error in errors: - print error - sys.exit(1) -sys.exit(0) diff --git a/tools/compileconfig.py b/tools/compileconfig.py deleted file mode 100755 index eb0ddc6..0000000 --- a/tools/compileconfig.py +++ /dev/null @@ -1,372 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2014, NORDUnet A/S. -# See LICENSE for licensing information. - -import argparse -import sys -import yaml -import re - -class Symbol(str): - pass - -clean_string = re.compile(r'^[-.:_/A-Za-z0-9 ]*$') -clean_symbol = re.compile(r'^[_A-Za-z0-9]*$') - -def quote_erlang_string(s): - if clean_string.match(s): - return '"' + s + '"' - else: - return "[" + ",".join([str(ord(c)) for c in s]) + "]" - -def quote_erlang_symbol(s): - if clean_symbol.match(s): - return s - elif clean_string.match(s): - return "'" + s + "'" - else: - print >>sys.stderr, "Cannot generate symbol", s - sys.exit(1) - -def gen_erlang(term, level=1): - indent = " " * level - separator = ",\n" + indent - if isinstance(term, Symbol): - return quote_erlang_symbol(term) - elif isinstance(term, basestring): - return quote_erlang_string(term) - elif isinstance(term, int): - return str(term) - elif isinstance(term, tuple): - tuplecontents = [gen_erlang(e, level=level+1) for e in term] - if "\n" not in "".join(tuplecontents): - separator = ", " - return "{" + separator.join(tuplecontents) + "}" - elif isinstance(term, list): - listcontents = [gen_erlang(e, level=level+1) for e in term] - return "[" + separator.join(listcontents) + "]" - else: - print "unknown type", type(term) - sys.exit(1) - -saslconfig = [(Symbol("sasl_error_logger"), Symbol("false")), - (Symbol("errlog_type"), Symbol("error")), - (Symbol("error_logger_mf_dir"), "sasl_log"), - (Symbol("error_logger_mf_maxbytes"), 10485760), - (Symbol("error_logger_mf_maxfiles"), 10), - ] - -def parse_address(address): - parsed_address = address.split(":") - if len(parsed_address) != 2: - print >>sys.stderr, "Invalid address format", address - sys.exit(1) - return (parsed_address[0], int(parsed_address[1])) - -def get_node_config(nodename, config): - nodetype = None - nodeconfig = None - for t in ["frontendnodes", "storagenodes", "signingnodes", "mergenodes"]: - for node in config[t]: - if node["name"] == nodename: - nodetype = t - nodeconfig = node - if nodeconfig == None: - print >>sys.stderr, "Cannot find config for node", nodename - sys.exit(1) - return (nodetype, nodeconfig) - -def gen_http_servers(nodetype, nodeconfig, bind_address, bind_publicaddress, bind_publichttpaddress): - if bind_address: - (host, port) = parse_address(bind_address) - else: - (_, port) = parse_address(nodeconfig["address"]) - host = "0.0.0.0" - if nodetype == "frontendnodes": - if bind_publicaddress: - (publichost, publicport) = parse_address(bind_publicaddress) - else: - (_, publicport) = parse_address(nodeconfig["publicaddress"]) - publichost = "0.0.0.0" - - http_servers = [] - https_servers = [] - if bind_publichttpaddress: - (publichttphost, publichttpport) = parse_address(bind_publichttpaddress) - http_servers.append((Symbol("external_http_api"), publichttphost, publichttpport, Symbol("v1"))) - https_servers.append((Symbol("external_https_api"), publichost, publicport, Symbol("v1"))) - https_servers.append((Symbol("frontend_https_api"), host, port, Symbol("frontend"))) - return (http_servers, - https_servers) - - elif nodetype == "storagenodes": - return ([], - [(Symbol("storage_https_api"), host, port, Symbol("storage"))]) - elif nodetype == "signingnodes": - return ([], - [(Symbol("signing_https_api"), host, port, Symbol("signing"))]) - elif nodetype == "mergenodes": - return ([], - [(Symbol("frontend_https_api"), host, port, Symbol("frontend"))]) - else: - print >>sys.stderr, "unknown nodetype", nodetype - sys.exit(1) - -def allowed_clients_frontend(mergenodenames, primarymergenode): - return [ - ("/plop/v1/frontend/sendentry", mergenodenames), - ("/plop/v1/frontend/sendlog", mergenodenames), - ("/plop/v1/frontend/sendsth", [primarymergenode]), - ("/plop/v1/frontend/currentposition", mergenodenames), - ("/plop/v1/frontend/missingentries", mergenodenames), - ] - -def allowed_clients_mergesecondary(primarymergenode): - return [ - ("/plop/v1/merge/sendentry", [primarymergenode]), - ("/plop/v1/merge/sendlog", [primarymergenode]), - ("/plop/v1/merge/verifyroot", [primarymergenode]), - ("/plop/v1/merge/verifiedsize", [primarymergenode]), - ("/plop/v1/merge/setverifiedsize", [primarymergenode]), - ("/plop/v1/merge/missingentries", [primarymergenode]), - ] - -def allowed_clients_public(): - noauth = Symbol("noauth") - return [ - ("/ct/v1/add-chain", noauth), - ("/ct/v1/add-pre-chain", noauth), - ("/ct/v1/get-sth", noauth), - ("/ct/v1/get-sth-consistency", noauth), - ("/ct/v1/get-proof-by-hash", noauth), - ("/ct/v1/get-entries", noauth), - ("/ct/v1/get-entry-and-proof", noauth), - ("/ct/v1/get-roots", noauth), - ] - -def allowed_clients_signing(frontendnodenames, primarymergenode): - return [ - ("/plop/v1/signing/sct", frontendnodenames), - ("/plop/v1/signing/sth", [primarymergenode]), - ] - -def allowed_clients_storage(frontendnodenames, mergenodenames): - return [ - ("/plop/v1/storage/sendentry", frontendnodenames), - ("/plop/v1/storage/entrycommitted", frontendnodenames), - ("/plop/v1/storage/fetchnewentries", mergenodenames), - ("/plop/v1/storage/getentry", mergenodenames), - ] - -def allowed_servers_frontend(signingnodenames, storagenodenames): - return [ - ("/plop/v1/storage/sendentry", storagenodenames), - ("/plop/v1/storage/entrycommitted", storagenodenames), - ("/plop/v1/signing/sct", signingnodenames), - ] - -def parse_ratelimit_expression(expression): - if expression == "none": - return Symbol("none") - parts = expression.split(" ") - if not (len(parts) == 3 and parts[1] == 'per' and parts[2] in ["second", "minute", "hour"]): - print >>sys.stderr, "Ratelimit expressions must have the format \"<frequency> per second|minute|hour\" or \"none\"" - sys.exit(1) - return (int(parts[0]), Symbol(parts[2])) - -def parse_ratelimit((type, description)): - descriptions = [parse_ratelimit_expression(s.strip()) for s in description.split(",")] - if len(descriptions) != 1: - print >>sys.stderr, "%s: Only one ratelimit expression supported right now" % (type,) - return (Symbol(type), descriptions) - -def gen_config(nodename, config, localconfig): - print "generating config for", nodename - paths = localconfig["paths"] - bind_address = localconfig.get("addresses", {}).get(nodename) - bind_publicaddress = localconfig.get("publicaddresses", {}).get(nodename) - bind_publichttpaddress = localconfig.get("publichttpaddresses", {}).get(nodename) - options = localconfig.get("options", []) - - configfile = open(paths["configdir"] + "/" + nodename + ".config", "w") - print >>configfile, "%% catlfish configuration file (-*- erlang -*-)" - - (nodetype, nodeconfig) = get_node_config(nodename, config) - (http_servers, https_servers) = gen_http_servers(nodetype, nodeconfig, bind_address, bind_publicaddress, bind_publichttpaddress=bind_publichttpaddress) - - catlfishconfig = [] - plopconfig = [] - - if nodetype in ("frontendnodes", "mergenodes"): - catlfishconfig.append((Symbol("known_roots_path"), localconfig["paths"]["knownroots"])) - if nodetype == "frontendnodes": - if "sctcaching" in options: - catlfishconfig.append((Symbol("sctcache_root_path"), paths["db"] + "sctcache/")) - if "ratelimits" in localconfig: - ratelimits = map(parse_ratelimit, localconfig["ratelimits"].items()) - catlfishconfig.append((Symbol("ratelimits"), ratelimits)) - - catlfishconfig += [ - (Symbol("https_servers"), https_servers), - (Symbol("http_servers"), http_servers), - (Symbol("https_certfile"), paths["https_certfile"]), - (Symbol("https_keyfile"), paths["https_keyfile"]), - (Symbol("https_cacertfile"), paths["https_cacertfile"]), - ] - - catlfishconfig.append((Symbol("mmd"), config["mmd"])) - - lagerconfig = [ - (Symbol("handlers"), [ - (Symbol("lager_console_backend"), Symbol("info")), - (Symbol("lager_file_backend"), [(Symbol("file"), nodename + "-error.log"), (Symbol("level"), Symbol("error"))]), - (Symbol("lager_file_backend"), [(Symbol("file"), nodename + "-debug.log"), (Symbol("level"), Symbol("debug"))]), - (Symbol("lager_file_backend"), [(Symbol("file"), nodename + "-console.log"), (Symbol("level"), Symbol("info"))]), - ]) - ] - - if nodetype in ("frontendnodes", "storagenodes"): - plopconfig += [ - (Symbol("entry_root_path"), paths["db"] + "certentries/"), - ] - if nodetype == "frontendnodes": - plopconfig += [ - (Symbol("index_path"), paths["db"] + "index"), - ] - elif nodetype == "storagenodes": - plopconfig += [ - (Symbol("newentries_path"), paths["db"] + "newentries"), - (Symbol("lastverifiednewentry_path"), paths["db"] + "lastverifiednewentry"), - ] - if nodetype in ("frontendnodes", "storagenodes"): - plopconfig += [ - (Symbol("entryhash_root_path"), paths["db"] + "entryhash/"), - (Symbol("indexforhash_root_path"), paths["db"] + "certindex/"), - ] - if nodetype == "frontendnodes": - plopconfig += [ - (Symbol("sth_path"), paths["db"] + "sth"), - (Symbol("entryhash_from_entry"), - (Symbol("catlfish"), Symbol("entryhash_from_entry"))), - ] - if nodetype in ("frontendnodes", "mergenodes"): - plopconfig += [ - (Symbol("verify_entry"), - (Symbol("catlfish"), Symbol("verify_entry"))), - ] - if nodetype == "mergenodes": - plopconfig += [ - (Symbol("verifiedsize_path"), paths["mergedb"] + "/verifiedsize"), - (Symbol("index_path"), paths["mergedb"] + "/logorder"), - (Symbol("entry_root_path"), paths["mergedb"] + "/chains/"), - ] - - signingnodes = config["signingnodes"] - signingnodeaddresses = ["https://%s/plop/v1/signing/" % node["address"] for node in config["signingnodes"]] - mergenodenames = [node["name"] for node in config["mergenodes"]] - primarymergenode = config["primarymergenode"] - storagenodeaddresses = ["https://%s/plop/v1/storage/" % node["address"] for node in config["storagenodes"]] - frontendnodenames = [node["name"] for node in config["frontendnodes"]] - - allowed_clients = [] - allowed_servers = [] - - if nodetype == "frontendnodes": - storagenodenames = [node["name"] for node in config["storagenodes"]] - plopconfig.append((Symbol("storage_nodes"), storagenodeaddresses)) - plopconfig.append((Symbol("storage_nodes_quorum"), config["storage-quorum-size"])) - services = [Symbol("ht")] - allowed_clients += allowed_clients_frontend(mergenodenames, primarymergenode) - allowed_clients += allowed_clients_public() - allowed_servers += allowed_servers_frontend([node["name"] for node in signingnodes], storagenodenames) - elif nodetype == "storagenodes": - allowed_clients += allowed_clients_storage(frontendnodenames, mergenodenames) - services = [] - elif nodetype == "signingnodes": - allowed_clients += allowed_clients_signing(frontendnodenames, primarymergenode) - services = [Symbol("sign")] - elif nodetype == "mergenodes": - storagenodenames = [node["name"] for node in config["storagenodes"]] - plopconfig.append((Symbol("storage_nodes"), storagenodeaddresses)) - plopconfig.append((Symbol("storage_nodes_quorum"), config["storage-quorum-size"])) - services = [Symbol("ht")] - allowed_clients += allowed_clients_mergesecondary(primarymergenode) - - plopconfig += [ - (Symbol("publickey_path"), paths["publickeys"]), - (Symbol("services"), services), - ] - if nodetype == "signingnodes": - hsm = localconfig.get("hsm") - if "logprivatekey" in paths: - plopconfig.append((Symbol("log_private_key"), paths["logprivatekey"])) - if hsm: - plopconfig.append((Symbol("hsm"), [hsm.get("library"), str(hsm.get("slot")), "ecdsa", hsm.get("label"), hsm.get("pin")])) - if not ("logprivatekey" in paths or hsm): - print >>sys.stderr, "Neither logprivatekey nor hsm configured for signing node", nodename - sys.exit(1) - plopconfig += [ - (Symbol("log_public_key"), paths["logpublickey"]), - (Symbol("own_key"), (nodename, "%s/%s-private.pem" % (paths["privatekeys"], nodename))), - ] - if nodetype == "frontendnodes": - plopconfig.append((Symbol("signing_nodes"), signingnodeaddresses)) - plopconfig += [ - (Symbol("allowed_clients"), allowed_clients), - (Symbol("allowed_servers"), allowed_servers), - ] - - erlangconfig = [ - (Symbol("sasl"), saslconfig), - (Symbol("catlfish"), catlfishconfig), - (Symbol("lager"), lagerconfig), - (Symbol("plop"), plopconfig), - ] - - print >>configfile, gen_erlang(erlangconfig) + ".\n" - - configfile.close() - - -def gen_testmakefile(config, testmakefile, machines): - configfile = open(testmakefile, "w") - frontendnodenames = [node["name"] for node in config["frontendnodes"]] - storagenodenames = [node["name"] for node in config["storagenodes"]] - signingnodenames = [node["name"] for node in config["signingnodes"]] - mergenodenames = [node["name"] for node in config["mergenodes"]] - - frontendnodeaddresses = [node["publicaddress"] for node in config["frontendnodes"]] - storagenodeaddresses = [node["address"] for node in config["storagenodes"]] - signingnodeaddresses = [node["address"] for node in config["signingnodes"]] - mergenodeaddresses = [node["address"] for node in config["mergenodes"] if node["name"] != config["primarymergenode"]] - - print >>configfile, "NODES=" + " ".join(frontendnodenames+storagenodenames+signingnodenames+mergenodenames) - print >>configfile, "MACHINES=" + " ".join([str(e) for e in range(1, machines+1)]) - print >>configfile, "TESTURLS=" + " ".join(frontendnodeaddresses+storagenodeaddresses+signingnodeaddresses+mergenodeaddresses) - print >>configfile, "BASEURL=" + config["baseurl"] - - configfile.close() - - -def main(): - parser = argparse.ArgumentParser(description="") - parser.add_argument('--config', help="System configuration", required=True) - parser.add_argument('--localconfig', help="Local configuration") - parser.add_argument("--testmakefile", metavar="file", help="Generate makefile variables for test") - parser.add_argument("--machines", type=int, metavar="n", help="Number of machines") - args = parser.parse_args() - - config = yaml.load(open(args.config)) - if args.testmakefile and args.machines: - gen_testmakefile(config, args.testmakefile, args.machines) - elif args.localconfig: - localconfig = yaml.load(open(args.localconfig)) - localnodes = localconfig["localnodes"] - for localnode in localnodes: - gen_config(localnode, config, localconfig) - else: - print >>sys.stderr, "Nothing to do" - sys.exit(1) - -main() diff --git a/tools/convertdb.py b/tools/convertdb.py deleted file mode 100644 index c036843..0000000 --- a/tools/convertdb.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright (c) 2014, NORDUnet A/S. -# See LICENSE for licensing information. - -import argparse -import urllib2 -import urllib -import json -import base64 -import sys -import struct -import hashlib -import itertools -from certtools import * -from mergetools import * -import zipfile -import os -import time -import shutil - -def write_file(fn, contents): - tempname = fn + ".new" - open(tempname, 'w').write(contents) - shutil.move(tempname, fn) - -def unpack_entry(entry): - pieces = [] - while len(entry): - (length,) = struct.unpack(">I", entry[0:4]) - data = entry[4:4+length] - entry = entry[4+length:] - pieces.append(data) - return pieces - -def read_old_entry(entry, hash): - unpacked = unpack_entry(entry) - mtl = unpacked[0] - assert hash == get_leaf_hash(mtl) - (leafcert, timestamp, issuer_key_hash) = unpack_mtl(mtl) - certchain = decode_certificate_chain(unpacked[1]) - if issuer_key_hash: - leafcert = certchain[0] - certchain = certchain[1:] - certtype = "PRC1" - else: - certtype = "EEC1" - return (mtl, leafcert, certtype, certchain) - -def convertentry(entry, hash): - (mtl, leafcert, certtype, chain) = read_old_entry(entry, hash) - entry = tlv_encodelist([("MTL1", mtl), - (certtype, leafcert), - ("CHN1", tlv_encodelist([("X509", cert) for cert in chain]))]) - return wrap_entry(entry) - -parser = argparse.ArgumentParser(description='') -parser.add_argument('path', help="Path to database to convert") -args = parser.parse_args() - -for (dirpath, dirnames, filenames) in os.walk(args.path): - for filename in filenames: - fullpath = dirpath + "/" + filename - entry = open(fullpath).read() - entry = convertentry(entry, base64.b16decode(filename.upper())) - if entry != None: - print "writing new entry for", filename - write_file(fullpath, entry) - else: - print "not writing new entry for", filename diff --git a/tools/create-key.sh b/tools/create-key.sh deleted file mode 100755 index 9d29c86..0000000 --- a/tools/create-key.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -openssl ecparam -name prime256v1 -genkey -noout -out $1-private.pem -openssl ec -in $1-private.pem -pubout -out $1.pem diff --git a/tools/fetchacert.py b/tools/fetchacert.py deleted file mode 100755 index 82ea7c1..0000000 --- a/tools/fetchacert.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import argparse -import base64 -from certtools import * - -parser = argparse.ArgumentParser(description='') -parser.add_argument('baseurl', help="Base URL for CT server") -parser.add_argument('index', type=int, help="Index for entry to fetch") -args = parser.parse_args() - -rawentries = get_entries(args.baseurl, args.index, args.index)["entries"] -entry = extract_original_entry(rawentries[0]) -(chain, _timestamp, _issuer_key_hash) = entry -s = "" -for cert in chain: - s += "-----BEGIN CERTIFICATE-----\n" - s += base64.encodestring(cert).rstrip() + "\n" - s += "-----END CERTIFICATE-----\n" - s += "\n" -print s diff --git a/tools/fetchallcerts.py b/tools/fetchallcerts.py deleted file mode 100755 index 66fde74..0000000 --- a/tools/fetchallcerts.py +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright (c) 2014, NORDUnet A/S. -# See LICENSE for licensing information. - -import argparse -import urllib2 -import urllib -import json -import base64 -import sys -import struct -import hashlib -import itertools -from certtools import * -import zipfile -import os -import time - -parser = argparse.ArgumentParser(description='') -parser.add_argument('baseurl', help="Base URL for CT server") -parser.add_argument('--store', default=None, metavar="dir", help='Store certificates in directory dir') -parser.add_argument('--write-sth', action='store_true', help='Write STH') -parser.add_argument('--no-check-signature', action='store_true', help='Don\'t check signature') -parser.add_argument('--publickey', default=None, metavar="file", help='Public key for the CT log') -parser.add_argument('--cafile', default=None, metavar="file", help='File containing the CA cert') -args = parser.parse_args() - -create_ssl_context(cafile=args.cafile) - -def get_entries_wrapper(baseurl, start, end): - fetched_entries = 0 - while start + fetched_entries < (end + 1): - print "fetching from", start + fetched_entries - entries = get_entries(baseurl, start + fetched_entries, end)["entries"] - if len(entries) == 0: - break - for entry in entries: - fetched_entries += 1 - yield entry - -def print_layer(layer): - for entry in layer: - print base64.b16encode(entry) - -logpublickey = get_public_key_from_file(args.publickey) if args.publickey else None - -sth = get_sth(args.baseurl) -if not args.no_check_signature: - check_sth_signature(args.baseurl, sth, publickey=logpublickey) -tree_size = sth["tree_size"] -root_hash = base64.decodestring(sth["sha256_root_hash"]) - -try: - if args.store: - oldsth = json.load(open(args.store + "/currentsth")) - else: - oldsth = None -except IOError: - oldsth = None - -sth_timestamp = datetime.datetime.fromtimestamp(sth["timestamp"]/1000) -since_timestamp = time.time() - sth["timestamp"]/1000 - -print "Log last updated %s, %d seconds ago" % (sth_timestamp.ctime(), since_timestamp) - -print "tree size", tree_size -print "root hash", base64.b16encode(root_hash) - -if oldsth: - if oldsth["tree_size"] == tree_size: - print "Tree size has not changed" - if oldsth["sha256_root_hash"] != sth["sha256_root_hash"]: - print "Root hash is different even though tree size is the same." - print "Log has violated the append-only property." - print "Old hash:", oldsth["sha256_root_hash"] - print "New hash:", sth["sha256_root_hash"] - sys.exit(1) - if oldsth["timestamp"] == sth["timestamp"]: - print "Timestamp has not changed" - else: - print "Tree size changed, old tree size was", oldsth["tree_size"] - -merkle_64klayer = [] - -if args.store: - ncerts = None - for blocknumber in range(0, (tree_size / 65536) + 1): - (resulttype, result) = get_merkle_hash_64k(args.store, blocknumber, write_to_cache=True) - if resulttype == "incomplete": - (incompletelength, hash) = result - ncerts = blocknumber * 65536 + incompletelength - break - assert resulttype == "hash" - hash = result - merkle_64klayer.append(hash) - print blocknumber * 65536, - sys.stdout.flush() - print - print "ncerts", ncerts -else: - ncerts = 0 - -entries = get_entries_wrapper(args.baseurl, ncerts, tree_size - 1) - -if not args.store: - layer0 = [get_leaf_hash(base64.decodestring(entry["leaf_input"])) for entry in entries] - - tree = build_merkle_tree(layer0) - - calculated_root_hash = tree[-1][0] - -else: - currentfilename = None - zf = None - for entry, i in itertools.izip(entries, itertools.count(ncerts)): - try: - (chain, timestamp, issuer_key_hash) = extract_original_entry(entry) - zipfilename = args.store + "/" + ("%04d.zip" % (i / 10000)) - if zipfilename != currentfilename: - if zf: - zf.close() - zf = zipfile.ZipFile(zipfilename, "a", - compression=zipfile.ZIP_DEFLATED) - currentfilename = zipfilename - s = "" - s += "Timestamp: %s\n" % timestamp - leaf_input = base64.decodestring(entry["leaf_input"]) - leaf_hash = get_leaf_hash(leaf_input) - s += "Leafhash: %s\n" % base64.b16encode(leaf_hash) - if issuer_key_hash: - s += "-----BEGIN PRECERTIFICATE-----\n" - s += base64.encodestring(chain[0]).rstrip() + "\n" - s += "-----END PRECERTIFICATE-----\n" - s += "\n" - chain = chain[1:] - for cert in chain: - s += "-----BEGIN CERTIFICATE-----\n" - s += base64.encodestring(cert).rstrip() + "\n" - s += "-----END CERTIFICATE-----\n" - s += "\n" - zf.writestr("%08d" % i, s) - except AssertionError, e: - print "error for cert", i, e - if zf: - zf.close() - - for blocknumber in range(ncerts / 65536, (tree_size / 65536) + 1): - (resulttype, result) = get_merkle_hash_64k(args.store, blocknumber, write_to_cache=True) - if resulttype == "incomplete": - (incompletelength, hash) = result - ncerts = blocknumber * 65536 + incompletelength - merkle_64klayer.append(hash) - break - assert resulttype == "hash" - hash = result - merkle_64klayer.append(hash) - print blocknumber * 65536, base64.b16encode(hash) - - tree = build_merkle_tree(merkle_64klayer) - - calculated_root_hash = tree[-1][0] - - assert ncerts == tree_size - -print "calculated root hash", base64.b16encode(calculated_root_hash) - -if oldsth and oldsth["tree_size"] > 0 and oldsth["tree_size"] != tree_size: - consistency_proof = [base64.decodestring(entry) for entry in get_consistency_proof(args.baseurl, oldsth["tree_size"], tree_size)] - (old_treehead, new_treehead) = verify_consistency_proof(consistency_proof, oldsth["tree_size"], tree_size, base64.b64decode(oldsth["sha256_root_hash"])) - assert old_treehead == base64.b64decode(oldsth["sha256_root_hash"]) - assert new_treehead == base64.b64decode(sth["sha256_root_hash"]) - -if calculated_root_hash != root_hash: - print "fetched root hash and calculated root hash different" - sys.exit(1) - -if args.store and args.write_sth: - f = open(args.store + "/currentsth", "w") - f.write(json.dumps(sth)) - f.close() diff --git a/tools/josef_auditor.py b/tools/josef_auditor.py deleted file mode 100755 index 710e3da..0000000 --- a/tools/josef_auditor.py +++ /dev/null @@ -1,398 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -import time -import datetime -import base64 -import argparse -import errno -from certtools import * - -NAGIOS_OK = 0 -NAGIOS_WARN = 1 -NAGIOS_CRIT = 2 -NAGIOS_UNKNOWN = 3 - -DEFAULT_CUR_FILE = 'all-sth.json' - -base_urls = ["https://plausible.ct.nordu.net/", - "https://ct1.digicert-ct.com/log/", - "https://ct.izenpe.com/", - "https://log.certly.io/", - "https://ct.googleapis.com/aviator/", - "https://ct.googleapis.com/pilot/", - "https://ct.googleapis.com/rocketeer/", - "https://ct.ws.symantec.com/", - "https://ctlog.api.venafi.com/", - ] - -logkeys = {} -logkeys["https://plausible.ct.nordu.net/"] = get_public_key_from_file("../../plausible-logkey.pem") -logkeys["https://ct.googleapis.com/rocketeer/"] = get_public_key_from_file("../../rocketeer-logkey.pem") -logkeys["https://ct.googleapis.com/aviator/"] = get_public_key_from_file("../../aviator-logkey.pem") -logkeys["https://ct.googleapis.com/pilot/"] = get_public_key_from_file("../../pilot-logkey.pem") -logkeys["https://log.certly.io/"] = get_public_key_from_file("../../certly-logkey.pem") -logkeys["https://ct.izenpe.com/"] = get_public_key_from_file("../../izenpe-logkey.pem") -logkeys["https://ct.ws.symantec.com/"] = get_public_key_from_file("../../symantec-logkey.pem") -logkeys["https://ctlog.api.venafi.com/"] = get_public_key_from_file("../../venafi-logkey.pem") -logkeys["https://ct1.digicert-ct.com/log/"] = get_public_key_from_file("../../digicert-logkey.pem") - -parser = argparse.ArgumentParser(description="") -parser.add_argument('--audit', action='store_true', help="run lightweight auditor verifying consistency in STH") -parser.add_argument('--audit2', action='store_true', help="run medium-weight auditor verifying consistency in STH and inclusion proofs of new entries") -parser.add_argument('--audit3', action='store_true', help="continously run medium-weight auditor verifying consistency in STH and inclusion proofs of new entries") -parser.add_argument('--build-sth', action='store_true', help="get all entries and construct STH") -parser.add_argument('--verify-index', default=None, help="Verify a specific index in all logs" ) -# parser.add_argument('--verify-hash', action='store_true', help="Verify an entry hash in all logs" ) -parser.add_argument('--roots', action='store_true', help="Check accepted root certificates for all logs" ) -parser.add_argument('--cur-sth', - metavar='file', - default=DEFAULT_CUR_FILE, - help="File containing current STH (default=%s)" % DEFAULT_CUR_FILE) - -timings = {} -errors = [] - -class UTC(datetime.tzinfo): - def utcoffset(self, dt): - return datetime.timedelta(hours=0) - def dst(self, dt): - return datetime.timedelta(0) - -def reduce_layer(layer): - new_layer = [] - while len(layer) > 1: - e1 = layer.pop(0) - e2 = layer.pop(0) - new_layer.append(internal_hash((e1,e2))) - return new_layer - -def reduce_tree(entries, layers): - if len(entries) == 0 and layers is []: - return [[hashlib.sha256().digest()]] - - layer_idx = 0 - layers[layer_idx] += entries - - while len(layers[layer_idx]) > 1: - if len(layers) == layer_idx + 1: - layers.append([]) - - layers[layer_idx + 1] += reduce_layer(layers[layer_idx]) - layer_idx += 1 - return layers - -def reduce_subtree_to_root(layers): - while len(layers) > 1: - if len(layers[1]) == 0: - layers[1] = layers[0] - else: - layers[1] += next_merkle_layer(layers[0]) - del layers[0] - - if len(layers[0]) > 1: - return next_merkle_layer(layers[0]) - return layers[0] - -def fetch_all_sth(): - sths = {} - for base_url in base_urls: - # Fetch STH - try: - sths[base_url] = get_sth(base_url) - except: - sths[base_url] = None - error_str = time.strftime('%H:%M:%S') + " ERROR: Failed to retrieve STH from " + base_url - print error_str - errors.append(error_str) - continue - - # Check signature on the STH - try: - check_sth_signature(base_url, sths[base_url], logkeys[base_url]) - except: - error_str = time.strftime('%H:%M:%S') + " ERROR: Could not verify signature from " + base_url - print error_str - errors.append(error_str) - continue - - return sths - -def verify_progress(old, new): - print "Verifying progress" - for url in new: - if new and old and new[url] and old[url]: - if new[url]["tree_size"] == old[url]["tree_size"]: - if old[url]["sha256_root_hash"] != new[url]["sha256_root_hash"]: - errors.append(time.strftime('%H:%M:%S') + " CRITICAL: root hash is different for same tree size in " + url) - # print "tree size:", newsth["tree_size"], - # print "old hash:", b64_to_b16(oldsth["sha256_root_hash"]) - # print "new hash:", b64_to_b16(newsth["sha256_root_hash"]) - # sys.exit(NAGIOS_CRIT) - # TODO - elif new[url]["tree_size"] < old[url]["tree_size"]: - # if not args.allow_lag: - errors.append(time.strftime('%H:%M:%S') + " CRITICAL: new tree smaller than previous tree (%d < %d)" % \ - (new[url]["tree_size"], old[url]["tree_size"])) - # sys.exit(NAGIOS_CRIT) - if new[url]: - age = time.time() - new[url]["timestamp"]/1000 - sth_time = datetime.datetime.fromtimestamp(new[url]['timestamp'] / 1000, UTC()).strftime("%Y-%m-%d %H:%M:%S") - # roothash = b64_to_b16(sth['sha256_root_hash']) - roothash = new[url]['sha256_root_hash'] - if age > 24 * 3600: - errors.append(time.strftime('%H:%M:%S') + " CRITICAL: %s is older than 24h: %s UTC" % (url, sth_time)) - elif age > 12 * 3600: - errors.append(time.strftime('%H:%M:%S') + " WARNING: %s is older than 12h: %s UTC" % (url, sth_time)) - elif age > 6 * 3600: - errors.append(time.strftime('%H:%M:%S') + " WARNING: %s is older than 6h: %s UTC" % (url, sth_time)) - # elif age > 2 * 3600: - # errors.append(time.strftime('%H:%M:%S') + " WARNING: %s is older than 2h: %s UTC" % (url, sth_time)) - -def verify_consistency(old, new): - for url in old: - # try: - if old[url] and new[url] and old[url]["tree_size"]!= new[url]["tree_size"]: - consistency_proof = get_consistency_proof(url, old[url]["tree_size"], new[url]["tree_size"]) - decoded_consistency_proof = [] - for item in consistency_proof: - decoded_consistency_proof.append(base64.b64decode(item)) - res = verify_consistency_proof(decoded_consistency_proof, old[url]["tree_size"], new[url]["tree_size"], old[url]["sha256_root_hash"]) - - if old[url]["sha256_root_hash"] != str(base64.b64encode(res[0])): - print time.strftime('%H:%M:%S') + " Verification of old hash failed! " + old[url]["sha256_root_hash"], str(base64.b64encode(res[0])) - errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to verify consistency for " + url + ", tree size " + old[url]["tree_size"]) - elif new[url]["sha256_root_hash"] != str(base64.b64encode(res[1])): - print time.strftime('%H:%M:%S') + " Verification of new hash failed! " + new[url]["sha256_root_hash"], str(base64.b64encode(res[1])) - errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to verify consistency for " + url + ", tree size " + new[url]["tree_size"]) - else: - print time.strftime("%H:%M:%S") + " New STH from " + url + ", timestamp: " + \ - str(new[url]["timestamp"]) + ", size: " + str(new[url]["tree_size"]) + "...OK." - - # except: - # print "ERROR: Could not verify consistency for " + url - -def verify_inclusion_all(old, new): - for url in old: - try: - if old[url] and new[url]: - if old[url]["tree_size"]!= new[url]["tree_size"]: - entries = get_entries(url, old[url]["tree_size"], new[url]["tree_size"] -1)["entries"] - success = True - for i in entries: - h = get_leaf_hash(base64.b64decode(i["leaf_input"])) - if not verify_inclusion_by_hash(url, h): - success = False - - if success: - print time.strftime("%H:%M:%S") + " Verifying inclusion for " + str(len(entries)) + " new entries in " + url + " ...OK" - else: - print time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url - errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url) - except: - print time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url - errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url) - -def fetch_and_build_tree(old_sth, base_url): - sth = old_sth[base_url] - subtree = [[]] - idx = 0 - - res_strings = [""] - - print time.strftime('%H:%M:%S') + " Getting all entries from " + base_url - while idx < sth["tree_size"]: - pre_size = idx - entries = get_entries(base_url, idx, sth["tree_size"]-1)["entries"] - - new_leafs = [] - for item in entries: - new_leafs.append(get_leaf_hash(base64.b64decode(item["leaf_input"]))) - idx += len(new_leafs) - print time.strftime('%H:%M:%S') + " Got entries " + str(pre_size) + " to " + str(idx) + " from " + base_url - subtree = reduce_tree(new_leafs, subtree) - - root = base64.b64encode(reduce_subtree_to_root(subtree)[0]) - - if root == sth["sha256_root_hash"]: - print time.strftime('%H:%M:%S') + " Verifying root hashes for " + base_url + "...OK." - res_strings.append("STH for " + base_url + " built successfully.") - else: - print time.strftime('%H:%M:%S') + " ERROR: Failed to verify root hashes! STH root: " + sth["sha256_root_hash"] + ", Tree root: " + root - res_strings.append(time.strftime('%H:%M:%S') + " " + base_url + " Failed! STH root: " + sth["sha256_root_hash"] + " Calculated root: " + root) - errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to verify root hash for " + base_url + ", tre size " + sth["tree_size"]) - - for item in res_strings: - print item + "\n" - -def verify_inclusion_by_hash(base_url, leaf_hash): - try: - tmp_sth = get_sth(base_url) - proof = get_proof_by_hash(base_url, leaf_hash, tmp_sth["tree_size"]) - - decoded_inclusion_proof = [] - for item in proof["audit_path"]: - decoded_inclusion_proof.append(base64.b64decode(item)) - - root = base64.b64encode(verify_inclusion_proof(decoded_inclusion_proof, proof["leaf_index"], tmp_sth["tree_size"], leaf_hash)) - - if tmp_sth["sha256_root_hash"] == root: - # print "Verifying inclusion for entry " + str(proof["leaf_index"]) + " in " + base_url + "...OK." - return True - else: - print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(proof["leaf_index"]) + " in " + base_url - errors.append(time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(proof["leaf_index"]) + " in " + base_url) - return False - except: - print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for hashed entry in " + base_url - errors.append(time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for hashed entry in " + base_url) - return False - -def verify_inclusion_by_index(base_url, index): - try: - tmp_sth = get_sth(base_url) - proof = get_proof_by_index(base_url, index, tmp_sth["tree_size"]) - - decoded_inclusion_proof = [] - for item in proof["audit_path"]: - decoded_inclusion_proof.append(base64.b64decode(item)) - - root = base64.b64encode(verify_inclusion_proof(decoded_inclusion_proof, index, tmp_sth["tree_size"], get_leaf_hash(base64.b64decode(proof["leaf_input"])))) - - if tmp_sth["sha256_root_hash"] == root: - print time.strftime('%H:%M:%S') + " Verifying inclusion for entry " + str(index) + " in " + base_url + "...OK." - else: - print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url - errors.append(time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url) - except: - print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url - errors.append(time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url) - -def get_proof_by_index(baseurl, index, tree_size): - try: - params = urllib.urlencode({"leaf_index":index, - "tree_size":tree_size}) - result = \ - urlopen(baseurl + "ct/v1/get-entry-and-proof?" + params).read() - return json.loads(result) - except urllib2.HTTPError, e: - print "ERROR:", e.read() - sys.exit(0) - -def get_all_roots(base_url): - # print "Fetching roots from " + base_url - result = urlopen(base_url + "ct/v1/get-roots").read() - certs = json.loads(result)["certificates"] - print time.strftime('%H:%M:%S') + " Received " + str(len(certs)) + " certs from " + base_url - - for accepted_cert in certs: - subject = get_cert_info(base64.decodestring(accepted_cert))["subject"] - issuer = get_cert_info(base64.decodestring(accepted_cert))["issuer"] - if subject == issuer: - root_cert = base64.decodestring(accepted_cert) - print get_cert_info(root_cert)["subject"] - -def print_errors(errors): - print "Encountered " + str(len(errors)) + " errors:" - for item in errors: - print item - -def print_timings(timings): - for item in timings: - m,s = divmod(timings[item]["longest"], 60) - h,m = divmod(m, 60) - print item + " last seen " + datetime.datetime.fromtimestamp(int(timings[item]["last"])/1000).strftime('%Y-%m-%d %H:%M:%S') \ - + " longest between two STH: " + str(int(h)) + "h " + str(int(m)) + "m "# + str(int(s)) + "s." - - -def read_sth(fn): - try: - f = open(fn) - except IOError, e: - if e.errno == errno.ENOENT: - return None - raise e - return json.loads(f.read()) - - -def write_file(fn, sth): - tempname = fn + ".new" - open(tempname, 'w').write(json.dumps(sth)) - mv_file(tempname, fn) - - -def main(args): - - # print time.strftime("%H:%M:%S") + " Starting..." - if args.verify_index is None and not args.build_sth and not args.audit and not args.audit2 \ - and not args.audit3 and not args.verify_hash and not args.roots: - - print time.strftime('%H:%M:%S') + " Nothing to do." - return - else: - sth = fetch_all_sth() - - if args.verify_index is not None: - for url in base_urls: - verify_inclusion_by_index(url, int(args.verify_index)) - - - if args.roots: - print time.strftime('%H:%M:%S') + " Getting accepted Root Certs from all logs..." - for url in base_urls: - get_all_roots(url) - - - if args.build_sth: - print time.strftime('%H:%M:%S') + " Building trees from entries. This may take a while, go get coffee or something..." - for base_url in base_urls: - fetch_and_build_tree(sth, base_url) - # fetch_and_build_tree(sth, base_urls[2]) - - if args.audit: - print time.strftime('%H:%M:%S') + " Running auditor1 for " +str(len(base_urls)) + " logs..." - old_sth = read_sth(args.cur_sth) - if old_sth: - verify_consistency(old_sth, sth) - else: - print "No old sth found..." - write_file(args.cur_sth, sth) - - - if args.audit3: - print time.strftime('%H:%M:%S') + " Running auditor3 for " +str(len(base_urls)) + " logs..." - while True: - time.sleep(30) - new_sth = fetch_all_sth() - verify_consistency(sth, new_sth) - verify_inclusion_all(sth, new_sth) - sth = new_sth - - if args.audit2: - print time.strftime('%H:%M:%S') + " Running auditor2 for " +str(len(base_urls)) + " logs..." - old_sth = read_sth(args.cur_sth) - verify_progress(old_sth, sth) - if old_sth: - verify_consistency(old_sth, sth) - verify_inclusion_all(old_sth, sth) - write_file(args.cur_sth, sth) - - - -if __name__ == '__main__': - main(parser.parse_args()) - if len(errors) == 0: - print time.strftime('%H:%M:%S') + " Everything OK." - sys.exit(NAGIOS_OK) - else: - print_errors(errors) - sys.exit(NAGIOS_WARN) - - - - - - - - - diff --git a/tools/josef_experimental.py b/tools/josef_experimental.py deleted file mode 100755 index 4377b8b..0000000 --- a/tools/josef_experimental.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -import time -import base64 -import urllib -import urllib2 -import sys -# from pympler.asizeof import asizeof -from certtools import * -from Crypto.Signature import PKCS1_v1_5 - -def reduce_leafs_to_root(layer0): - if len(layer0) == 0: - return [[hashlib.sha256().digest()]] - current_layer = layer0 - while len(current_layer) > 1: - current_layer = next_merkle_layer(current_layer) - return current_layer - -def reduce_layer(layer): - new_layer = [] - while len(layer) > 1: - e1 = layer.pop(0) - e2 = layer.pop(0) - new_layer.append(internal_hash((e1,e2))) - return new_layer - -def reduce_tree(entries, layers): - if len(entries) == 0 and layers is []: - return [[hashlib.sha256().digest()]] - - layer_idx = 0 - layers[layer_idx] += entries - - while len(layers[layer_idx]) > 1: - if len(layers) == layer_idx + 1: - layers.append([]) - - layers[layer_idx + 1] += reduce_layer(layers[layer_idx]) - layer_idx += 1 - return layers - -def reduce_subtree_to_root(layers): - while len(layers) > 1: - layers[1] += next_merkle_layer(layers[0]) - del layers[0] - - if len(layers[0]) > 1: - return next_merkle_layer(layers[0]) - return layers[0] - -def get_proof_by_index(baseurl, index, tree_size): - try: - params = urllib.urlencode({"leaf_index":index, - "tree_size":tree_size}) - result = \ - urlopen(baseurl + "ct/v1/get-entry-and-proof?" + params).read() - return json.loads(result) - except urllib2.HTTPError, e: - print "ERROR:", e.read() - sys.exit(1) - - -base_urls = ["https://plausible.ct.nordu.net/", - "https://ct1.digicert-ct.com/log/", - "https://ct.izenpe.com/", - "https://log.certly.io/", - "https://ctlog.api.venafi.com/", - "https://ct.googleapis.com/aviator/", - "https://ct.googleapis.com/pilot/", - "https://ct.googleapis.com/rocketeer/", - ] - -logkeys = {} -logkeys["https://plausible.ct.nordu.net/"] = get_public_key_from_file("../../plausible-logkey.pem") -logkeys["https://ct.googleapis.com/rocketeer/"] = get_public_key_from_file("../../rocketeer-logkey.pem") -logkeys["https://ct.googleapis.com/aviator/"] = get_public_key_from_file("../../aviator-logkey.pem") -logkeys["https://ct.googleapis.com/pilot/"] = get_public_key_from_file("../../pilot-logkey.pem") -logkeys["https://log.certly.io/"] = get_public_key_from_file("../../certly-logkey.pem") -logkeys["https://ct.izenpe.com/"] = get_public_key_from_file("../../izenpe-logkey.pem") -logkeys["https://ct1.digicert-ct.com/log/"] = get_public_key_from_file("../../digicert-logkey.pem") -logkeys["https://ctlog.api.venafi.com/"] = get_public_key_from_file("../../venafi-logkey.pem") - - -import Crypto.PublicKey.RSA as RSA -from Crypto.Hash import SHA256 - -for url in base_urls: - sth = get_sth(url) - signature = base64.b64decode(sth["tree_head_signature"]) - key = logkeys[url] - root_hash = base64.b64decode(sth["sha256_root_hash"]) - - hash_alg, signature_alg, unpacked_signature = decode_signature(signature) - if signature_alg == 1: - - # rsa_key = RSA.importKey(key) - # verifier = PKCS1_v1_5.new(rsa_key) - - # version = struct.pack(">b", 0) - # signature_type = struct.pack(">b", 1) - # timestamp = struct.pack(">Q", sth["timestamp"]) - # tree_size = struct.pack(">Q", sth["tree_size"]) - # hash = base64.decodestring(sth["sha256_root_hash"]) - - # tree_head = version + signature_type + timestamp + tree_size + hash - # h = SHA256.new(tree_head) - - # print verifier - # print verifier.verify(h, unpacked_signature) - print "RSA Signature from " + url - check_sth_signature(url, sth, key) - - - - elif signature_alg == 3: - print "ECDSA signature from " + url - check_sth_signature(url, sth, key) - else: - print "Unknown signature algorithm from " + url - -# print sth -# print "\n\n" + signature -# print "\n\n" + key -# print rsa_key - -# print "\n\n" + rsa_key.verify(root_hash, signature)
\ No newline at end of file diff --git a/tools/josef_experimental_auditor.py b/tools/josef_experimental_auditor.py deleted file mode 100755 index 57ef9cb..0000000 --- a/tools/josef_experimental_auditor.py +++ /dev/null @@ -1,476 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -import time -import datetime -import base64 -import argparse -import errno -from certtools import * - -NAGIOS_OK = 0 -NAGIOS_WARN = 1 -NAGIOS_CRIT = 2 -NAGIOS_UNKNOWN = 3 - -DEFAULT_CUR_FILE = 'all-sth.json' - -base_urls = [ - "https://plausible.ct.nordu.net/", - "https://ct1.digicert-ct.com/log/", - "https://ct.izenpe.com/", - "https://log.certly.io/", - "https://ct.googleapis.com/aviator/", - "https://ct.googleapis.com/pilot/", - "https://ct.googleapis.com/rocketeer/", - "https://ct.ws.symantec.com/", - # "https://ctlog.api.venafi.com/", - ] - -# logkeys = {} -# logkeys["https://plausible.ct.nordu.net/"] = get_public_key_from_file("../../plausible-logkey.pem") -# logkeys["https://ct.googleapis.com/rocketeer/"] = get_public_key_from_file("../../rocketeer-logkey.pem") -# logkeys["https://ct.googleapis.com/aviator/"] = get_public_key_from_file("../../aviator-logkey.pem") -# logkeys["https://ct.googleapis.com/pilot/"] = get_public_key_from_file("../../pilot-logkey.pem") -# logkeys["https://log.certly.io/"] = get_public_key_from_file("../../certly-logkey.pem") -# logkeys["https://ct.izenpe.com/"] = get_public_key_from_file("../../izenpe-logkey.pem") -# logkeys["https://ct.ws.symantec.com/"] = get_public_key_from_file("../../symantec-logkey.pem") -# logkeys["https://ctlog.api.venafi.com/"] = get_public_key_from_file("../../venafi-logkey.pem") -# logkeys["https://ct1.digicert-ct.com/log/"] = get_public_key_from_file("../../digicert-logkey.pem") - -parser = argparse.ArgumentParser(description="") -parser.add_argument('--audit', action='store_true', help="run lightweight auditor verifying consistency in STH") -parser.add_argument('--audit2', action='store_true', help="run medium-weight auditor verifying consistency in STH and inclusion proofs of new entries") -parser.add_argument('--audit3', action='store_true', help="continously run medium-weight auditor verifying consistency in STH and inclusion proofs of new entries") -parser.add_argument('--audit4', action='store_true', help="run one check on one server") -parser.add_argument('--build-sth', action='store_true', help="get all entries and construct STH") -parser.add_argument('--verify-index', default=None, help="Verify a specific index in all logs" ) -# parser.add_argument('--verify-hash', action='store_true', help="Verify an entry hash in all logs" ) -parser.add_argument('--host', default=None, help="Base URL for CT log") -parser.add_argument('--roots', action='store_true', help="Check accepted root certificates for all logs" ) -parser.add_argument('--cur-sth', - metavar='file', - default=DEFAULT_CUR_FILE, - help="File containing current STH (default=%s)" % DEFAULT_CUR_FILE) - -timings = {} -errors = [] - -class UTC(datetime.tzinfo): - def utcoffset(self, dt): - return datetime.timedelta(hours=0) - def dst(self, dt): - return datetime.timedelta(0) - -def reduce_layer(layer): - new_layer = [] - while len(layer) > 1: - e1 = layer.pop(0) - e2 = layer.pop(0) - new_layer.append(internal_hash((e1,e2))) - return new_layer - -def reduce_tree(entries, layers): - if len(entries) == 0 and layers is []: - return [[hashlib.sha256().digest()]] - - layer_idx = 0 - layers[layer_idx] += entries - - while len(layers[layer_idx]) > 1: - if len(layers) == layer_idx + 1: - layers.append([]) - - layers[layer_idx + 1] += reduce_layer(layers[layer_idx]) - layer_idx += 1 - return layers - -def reduce_subtree_to_root(layers): - while len(layers) > 1: - if len(layers[1]) == 0: - layers[1] = layers[0] - else: - layers[1] += next_merkle_layer(layers[0]) - del layers[0] - - if len(layers[0]) > 1: - return next_merkle_layer(layers[0]) - return layers[0] - -def fetch_all_sth(): - sths = {} - for base_url in base_urls: - # Fetch STH - try: - sths[base_url] = get_sth(base_url) - except: - sths[base_url] = None - error_str = time.strftime('%H:%M:%S') + " ERROR: Failed to retrieve STH from " + base_url - print error_str - errors.append(error_str) - continue - - # Check signature on the STH - try: - # check_sth_signature(base_url, sths[base_url], logkeys[base_url]) - check_sth_signature(base_url, sths[base_url], None) - except: - error_str = time.strftime('%H:%M:%S') + " ERROR: Could not verify signature from " + base_url - print error_str - errors.append(error_str) - continue - - # Add timing info - # try: - # if base_url not in timings: - # timings[base_url] = {"last":sths[base_url]["timestamp"], "longest":0} - # else: - # then = datetime.datetime.fromtimestamp(int(timings[base_url]["last"])/1000) - # now = datetime.datetime.fromtimestamp(int(sths[base_url]["timestamp"])/1000) - # tdelta = now - then - - # timings[base_url]["last"] = sths[base_url]["timestamp"] - - # if tdelta.total_seconds() > timings[base_url]["longest"]: - # timings[base_url]["longest"] = tdelta.total_seconds() - - # except Exception, err: - # print Exception, err - # print time.strftime('%H:%M:%S') + "ERROR: Failed to set TIME info for STH" - - return sths - -def verify_progress(old, new): - print "Verifying progress" - try: - for url in new: - if new and old and new[url] and old[url]: - if new[url]["tree_size"] == old[url]["tree_size"]: - if old[url]["sha256_root_hash"] != new[url]["sha256_root_hash"]: - errors.append(time.strftime('%H:%M:%S') + " CRITICAL: root hash is different for same tree size in " + url) - # print "tree size:", newsth["tree_size"], - # print "old hash:", b64_to_b16(oldsth["sha256_root_hash"]) - # print "new hash:", b64_to_b16(newsth["sha256_root_hash"]) - # sys.exit(NAGIOS_CRIT) - # TODO - elif new[url]["tree_size"] < old[url]["tree_size"]: - # if not args.allow_lag: - errors.append(time.strftime('%H:%M:%S') + " CRITICAL: new tree smaller than previous tree (%d < %d)" % \ - (new[url]["tree_size"], old[url]["tree_size"])) - # sys.exit(NAGIOS_CRIT) - if new[url]: - age = time.time() - new[url]["timestamp"]/1000 - sth_time = datetime.datetime.fromtimestamp(new[url]['timestamp'] / 1000, UTC()).strftime("%Y-%m-%d %H:%M:%S") - # roothash = b64_to_b16(sth['sha256_root_hash']) - roothash = new[url]['sha256_root_hash'] - if age > 24 * 3600: - errors.append(time.strftime('%H:%M:%S') + " CRITICAL: %s is older than 24h: %s UTC" % (url, sth_time)) - elif age > 12 * 3600: - errors.append(time.strftime('%H:%M:%S') + " WARNING: %s is older than 12h: %s UTC" % (url, sth_time)) - elif age > 6 * 3600: - errors.append(time.strftime('%H:%M:%S') + " WARNING: %s is older than 6h: %s UTC" % (url, sth_time)) - # elif age > 2 * 3600: - # errors.append(time.strftime('%H:%M:%S') + " WARNING: %s is older than 2h: %s UTC" % (url, sth_time)) - except: - print time.strftime('%H:%M:%S') + " ERROR: Failed to verify progress for " + url - - -def verify_consistency(old, new): - for url in old: - try: - if old[url] and new[url] and old[url]["tree_size"]!= new[url]["tree_size"]: - consistency_proof = get_consistency_proof(url, old[url]["tree_size"], new[url]["tree_size"]) - decoded_consistency_proof = [] - for item in consistency_proof: - decoded_consistency_proof.append(base64.b64decode(item)) - res = verify_consistency_proof(decoded_consistency_proof, old[url]["tree_size"], new[url]["tree_size"], old[url]["sha256_root_hash"]) - - if old[url]["sha256_root_hash"] != str(base64.b64encode(res[0])): - print time.strftime('%H:%M:%S') + " Verification of old hash failed! " + old[url]["sha256_root_hash"], str(base64.b64encode(res[0])) - errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to verify consistency for " + url + ", tree size " + old[url]["tree_size"]) - elif new[url]["sha256_root_hash"] != str(base64.b64encode(res[1])): - print time.strftime('%H:%M:%S') + " Verification of new hash failed! " + new[url]["sha256_root_hash"], str(base64.b64encode(res[1])) - errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to verify consistency for " + url + ", tree size " + new[url]["tree_size"]) - else: - print time.strftime("%H:%M:%S") + " New STH from " + url + ", timestamp: " + \ - str(new[url]["timestamp"]) + ", size: " + str(new[url]["tree_size"]) + "...OK." - - except: - print "ERROR: Could not verify consistency for " + url - -def verify_inclusion_all(old, new): - for url in old: - try: - if old[url] and new[url]: - if old[url]["tree_size"]!= new[url]["tree_size"]: - entries = [] - - while len(entries) + old[url]["tree_size"]!= new[url]["tree_size"]: - entries += get_entries(url, str(int(old[url]["tree_size"]) + len(entries)), new[url]["tree_size"] -1)["entries"] - print "Got " + str(len(entries)) + " entries..." - - success = True - for i in entries: - h = get_leaf_hash(base64.b64decode(i["leaf_input"])) - if not verify_inclusion_by_hash(url, h): - success = False - - if success: - print time.strftime("%H:%M:%S") + " Verifying inclusion for " + str(len(entries)) + " new entries in " + url + " ...OK" - else: - print time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url - errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url) - except: - print time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url - errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url) - -def fetch_and_build_tree(old_sth, base_url): - try: - sth = old_sth[base_url] - subtree = [[]] - idx = 0 - - res_strings = [""] - - print time.strftime('%H:%M:%S') + " Getting all entries from " + base_url - while idx < sth["tree_size"]: - pre_size = idx - entries = get_entries(base_url, idx, sth["tree_size"]-1)["entries"] - - new_leafs = [] - for item in entries: - new_leafs.append(get_leaf_hash(base64.b64decode(item["leaf_input"]))) - idx += len(new_leafs) - print time.strftime('%H:%M:%S') + " Got entries " + str(pre_size) + " to " + str(idx) + " from " + base_url - subtree = reduce_tree(new_leafs, subtree) - - root = base64.b64encode(reduce_subtree_to_root(subtree)[0]) - - if root == sth["sha256_root_hash"]: - print time.strftime('%H:%M:%S') + " Verifying root hashes for " + base_url + "...OK." - res_strings.append("STH for " + base_url + " built successfully.") - else: - print time.strftime('%H:%M:%S') + " ERROR: Failed to verify root hashes! STH root: " + sth["sha256_root_hash"] + ", Tree root: " + root - res_strings.append(time.strftime('%H:%M:%S') + " " + base_url + " Failed! STH root: " + sth["sha256_root_hash"] + " Calculated root: " + root) - errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to verify root hash for " + base_url + ", tre size " + sth["tree_size"]) - - for item in res_strings: - print item + "\n" - - except: - print time.strftime('%H:%M:%S') + " ERROR: Failed to build STH for " + base_url - errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to build STH for " + base_url) - -def verify_inclusion_by_hash(base_url, leaf_hash): - try: - tmp_sth = get_sth(base_url) - proof = get_proof_by_hash(base_url, leaf_hash, tmp_sth["tree_size"]) - - decoded_inclusion_proof = [] - for item in proof["audit_path"]: - decoded_inclusion_proof.append(base64.b64decode(item)) - - root = base64.b64encode(verify_inclusion_proof(decoded_inclusion_proof, proof["leaf_index"], tmp_sth["tree_size"], leaf_hash)) - - if tmp_sth["sha256_root_hash"] == root: - # print "Verifying inclusion for entry " + str(proof["leaf_index"]) + " in " + base_url + "...OK." - return True - else: - print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(proof["leaf_index"]) + " in " + base_url - errors.append(time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(proof["leaf_index"]) + " in " + base_url) - return False - except: - print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for hashed entry in " + base_url - errors.append(time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for hashed entry in " + base_url) - return False - -def verify_inclusion_by_index(base_url, index): - try: - tmp_sth = get_sth(base_url) - proof = get_proof_by_index(base_url, index, tmp_sth["tree_size"]) - - decoded_inclusion_proof = [] - for item in proof["audit_path"]: - decoded_inclusion_proof.append(base64.b64decode(item)) - - root = base64.b64encode(verify_inclusion_proof(decoded_inclusion_proof, index, tmp_sth["tree_size"], get_leaf_hash(base64.b64decode(proof["leaf_input"])))) - - if tmp_sth["sha256_root_hash"] == root: - print time.strftime('%H:%M:%S') + " Verifying inclusion for entry " + str(index) + " in " + base_url + "...OK." - else: - print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url - errors.append(time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url) - except: - print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url - errors.append(time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url) - -def get_proof_by_index(baseurl, index, tree_size): - try: - params = urllib.urlencode({"leaf_index":index, - "tree_size":tree_size}) - result = \ - urlopen(baseurl + "ct/v1/get-entry-and-proof?" + params).read() - return json.loads(result) - except urllib2.HTTPError, e: - print "ERROR:", e.read() - sys.exit(0) - -def get_all_roots(base_url): - # print "Fetching roots from " + base_url - result = urlopen(base_url + "ct/v1/get-roots").read() - certs = json.loads(result)["certificates"] - print time.strftime('%H:%M:%S') + " Received " + str(len(certs)) + " certs from " + base_url - - for accepted_cert in certs: - subject = get_cert_info(base64.decodestring(accepted_cert))["subject"] - issuer = get_cert_info(base64.decodestring(accepted_cert))["issuer"] - if subject == issuer: - root_cert = base64.decodestring(accepted_cert) - print get_cert_info(root_cert)["subject"] - -def print_errors(errors): - print "Encountered " + str(len(errors)) + " errors:" - for item in errors: - print item - -def print_timings(timings): - for item in timings: - m,s = divmod(timings[item]["longest"], 60) - h,m = divmod(m, 60) - print item + " last seen " + datetime.datetime.fromtimestamp(int(timings[item]["last"])/1000).strftime('%Y-%m-%d %H:%M:%S') \ - + " longest between two STH: " + str(int(h)) + "h " + str(int(m)) + "m "# + str(int(s)) + "s." - - -def read_sth(fn): - try: - f = open(fn) - except IOError, e: - if e.errno == errno.ENOENT: - return None - raise e - return json.loads(f.read()) - - -def write_file(fn, sth): - tempname = fn + ".new" - open(tempname, 'w').write(json.dumps(sth)) - mv_file(tempname, fn) - - -def main(args): - - # print time.strftime("%H:%M:%S") + " Starting..." - if args.verify_index is None and not args.build_sth and not args.audit and not args.audit2 \ - and not args.audit3 and not args.audit4 and not args.roots: - - print time.strftime('%H:%M:%S') + " Nothing to do." - return - elif args.audit4: - pass - else: - sth = fetch_all_sth() - - if args.verify_index is not None: - for url in base_urls: - verify_inclusion_by_index(url, int(args.verify_index)) - - # if args.verify_hash: - # idx = 1337 - # url = base_urls[0] - # entries = get_entries(url, idx, idx)["entries"] - # h = get_leaf_hash(base64.b64decode(entries[0]["leaf_input"])) - # verify_inclusion_by_hash(url, h) - - if args.roots: - print time.strftime('%H:%M:%S') + " Getting accepted Root Certs from all logs..." - for url in base_urls: - get_all_roots(url) - - - if args.build_sth: - print time.strftime('%H:%M:%S') + " Building trees from entries. This may take a while, go get coffee or something..." - for base_url in base_urls: - fetch_and_build_tree(sth, base_url) - # fetch_and_build_tree(sth, base_urls[2]) - - if args.audit: - print time.strftime('%H:%M:%S') + " Running auditor1 for " +str(len(base_urls)) + " logs..." - old_sth = read_sth(args.cur_sth) - if old_sth: - verify_consistency(old_sth, sth) - else: - print "No old sth found..." - write_file(args.cur_sth, sth) - - - if args.audit3: - print time.strftime('%H:%M:%S') + " Running auditor3 for " +str(len(base_urls)) + " logs..." - while True: - time.sleep(30) - new_sth = fetch_all_sth() - verify_consistency(sth, new_sth) - verify_inclusion_all(sth, new_sth) - sth = new_sth - - if args.audit2: - print time.strftime('%H:%M:%S') + " Running auditor2 for " +str(len(base_urls)) + " logs..." - old_sth = read_sth(args.cur_sth) - # print "Verifying progress..." - verify_progress(old_sth, sth) - if old_sth: - print "Verifying consistency..." - verify_consistency(old_sth, sth) - print "Verifying inclusion..." - verify_inclusion_all(old_sth, sth) - write_file(args.cur_sth, sth) - - # Experimental for plausible + nagios - if args.audit4: - base_url = base_urls[0] - old_sth = read_sth("plausible-sth.json") - print "Running auditor4 for " + base_url - try: - tmp_sth = get_sth(base_url) - except: - # sths[base_url] = None - error_str = time.strftime('%H:%M:%S') + " ERROR: Failed to retrieve STH from " + base_url - print error_str - errors.append(error_str) - sys.exit(NAGIOS_WARN) - - # Check signature on the STH - try: - check_sth_signature(base_url, tmp_sth, None) - write_file("plausible-sth.json", tmp_sth) - except: - error_str = time.strftime('%H:%M:%S') + " ERROR: Could not verify signature from " + base_url - print error_str - errors.append(error_str) - sys.exit(NAGIOS_CRIT) - sys.exit(NAGIOS_OK) - - -if __name__ == '__main__': - # try: - main(parser.parse_args()) - if len(errors) == 0: - print time.strftime('%H:%M:%S') + " Everything OK." - sys.exit(NAGIOS_OK) - else: - # print "errors found!" - print_errors(errors) - sys.exit(NAGIOS_WARN) - # except: - # pass - # finally: - # # print_timings(timings) - # print_errors(errors) - - - - - - - - - diff --git a/tools/josef_nagios_auditor.py b/tools/josef_nagios_auditor.py index db68bbe..74d9256 100755 --- a/tools/josef_nagios_auditor.py +++ b/tools/josef_nagios_auditor.py @@ -22,10 +22,6 @@ parser.add_argument('--sthfile', required=True, metavar='file', help="File containing current STH") -# parser.add_argument('--keyfile', -# metavar='file', -# required=True, -# help="File containing current STH") class UTC(datetime.tzinfo): def utcoffset(self, dt): @@ -78,8 +74,6 @@ def get_and_verify_sth(url): # Check signature on the STH try: check_sth_signature(url, sth, None) - # check_sth_signature(url, sth, key) - # write_file("plausible-sth.json", tmp_sth) except: error_str = time.strftime('%H:%M:%S') + " ERROR: Could not verify signature from " + url print error_str @@ -302,11 +296,6 @@ def write_file(fn, sth): def main(args): - # try: - # log_key = get_public_key_from_file(args.keyfile) - # except: - # print time.strftime('%H:%M:%S') + " ERROR: Failed to load keyfile " + args.keyfile - # sys.exit(NAGIOS_WARN) old_sth = read_sth(args.sthfile) new_sth = get_and_verify_sth(args.baseurl) diff --git a/tools/merge.py b/tools/merge.py deleted file mode 100755 index 2065a2d..0000000 --- a/tools/merge.py +++ /dev/null @@ -1,518 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (c) 2014, NORDUnet A/S. -# See LICENSE for licensing information. - -import argparse -import json -import base64 -import urllib -import urllib2 -import sys -import time -import ecdsa -import hashlib -import urlparse -import os -import yaml -import select -import struct -from certtools import build_merkle_tree, create_sth_signature, \ - check_sth_signature, get_eckey_from_file, timing_point, http_request, \ - get_public_key_from_file, get_leaf_hash, decode_certificate_chain, \ - create_ssl_context -from mergetools import parselogrow, get_logorder, read_chain, \ - verify_entry - -parser = argparse.ArgumentParser(description="") -parser.add_argument('--config', help="System configuration", required=True) -parser.add_argument('--localconfig', help="Local configuration", required=True) -parser.add_argument("--nomerge", action='store_true', help="Don't actually do merge") -parser.add_argument("--timing", action='store_true', help="Print timing information") -args = parser.parse_args() - -config = yaml.load(open(args.config)) -localconfig = yaml.load(open(args.localconfig)) - -ctbaseurl = config["baseurl"] -frontendnodes = config["frontendnodes"] -storagenodes = config["storagenodes"] -secondaries = config.get("mergenodes", []) -paths = localconfig["paths"] -mergedb = paths["mergedb"] - -signingnodes = config["signingnodes"] -create_ssl_context(cafile=paths["https_cacertfile"]) - -chainsdir = mergedb + "/chains" -logorderfile = mergedb + "/logorder" - -own_key = (localconfig["nodename"], "%s/%s-private.pem" % (paths["privatekeys"], localconfig["nodename"])) - -logpublickey = get_public_key_from_file(paths["logpublickey"]) - -hashed_dir = True - -def hexencode(key): - return base64.b16encode(key).lower() - -def write_chain(key, value): - 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(key): - f = open(logorderfile, "a") - f.write(hexencode(key) + "\n") - f.close() - -def fsync_logorder(): - f = open(logorderfile, "a") - os.fsync(f.fileno()) - f.close() - -def get_new_entries(node, baseurl): - 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, 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): - 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): - 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, 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, 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, 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, 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, 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, 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, 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): - 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): - 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)] - -timing = timing_point() - -logorder = get_logorder(logorderfile) - -timing_point(timing, "get logorder") - -certsinlog = set(logorder) - -new_entries_per_node = {} -new_entries = set() -entries_to_fetch = {} - -for storagenode in storagenodes: - print >>sys.stderr, "getting new entries from", storagenode["name"] - sys.stderr.flush() - new_entries_per_node[storagenode["name"]] = set(get_new_entries(storagenode["name"], "https://%s/" % storagenode["address"])) - new_entries.update(new_entries_per_node[storagenode["name"]]) - entries_to_fetch[storagenode["name"]] = [] - -import subprocess - -timing_point(timing, "get new entries") - -new_entries -= certsinlog - -print >>sys.stderr, "adding", len(new_entries), "entries" -sys.stderr.flush() - -if args.nomerge: - sys.exit(0) - -for hash in new_entries: - for storagenode in storagenodes: - if hash in new_entries_per_node[storagenode["name"]]: - entries_to_fetch[storagenode["name"]].append(hash) - break - -verifycert = subprocess.Popen([paths["verifycert_bin"], paths["known_roots"]], - stdin=subprocess.PIPE, stdout=subprocess.PIPE) - -added_entries = 0 -for storagenode in storagenodes: - print >>sys.stderr, "getting %d entries from %s:" % (len(entries_to_fetch[storagenode["name"]]), storagenode["name"]), - sys.stderr.flush() - for chunk in chunks(entries_to_fetch[storagenode["name"]], 100): - entries = get_entries(storagenode["name"], "https://%s/" % storagenode["address"], chunk) - for hash in chunk: - entry = entries[hash] - verify_entry(verifycert, entry, hash) - write_chain(hash, entry) - add_to_logorder(hash) - logorder.append(hash) - certsinlog.add(hash) - added_entries += 1 - print >>sys.stderr, added_entries, - sys.stderr.flush() - print >>sys.stderr - sys.stderr.flush() -fsync_logorder() -timing_point(timing, "add entries") -print >>sys.stderr, "added", added_entries, "entries" -sys.stderr.flush() - -verifycert.communicate(struct.pack("I", 0)) - -tree = build_merkle_tree(logorder) -tree_size = len(logorder) -root_hash = tree[-1][0] -timestamp = int(time.time() * 1000) - -for secondary in secondaries: - if secondary["name"] == config["primarymergenode"]: - continue - nodeaddress = "https://%s/" % secondary["address"] - nodename = secondary["name"] - timing = timing_point() - print >>sys.stderr, "backing up to node", nodename - sys.stderr.flush() - verifiedsize = get_verifiedsize(nodename, nodeaddress) - timing_point(timing, "get verified size") - print >>sys.stderr, "verified size", verifiedsize - sys.stderr.flush() - entries = [base64.b64encode(entry) for entry in logorder[verifiedsize:]] - print >>sys.stderr, "sending log:", - sys.stderr.flush() - for chunk in chunks(entries, 1000): - for trynumber in range(5, 0, -1): - sendlogresult = backup_sendlog(nodename, nodeaddress, {"start": verifiedsize, "hashes": chunk}) - if sendlogresult == None: - if trynumber == 1: - sys.exit(1) - select.select([], [], [], 10.0) - print >>sys.stderr, "tries left:", trynumber - sys.stderr.flush() - continue - break - if sendlogresult["result"] != "ok": - print >>sys.stderr, "sendlog:", sendlogresult - sys.exit(1) - verifiedsize += len(chunk) - print >>sys.stderr, verifiedsize, - sys.stderr.flush() - print >>sys.stderr - timing_point(timing, "sendlog") - print >>sys.stderr, "log sent" - sys.stderr.flush() - missingentries = get_missingentriesforbackup(nodename, nodeaddress) - timing_point(timing, "get missing") - print >>sys.stderr, "missing entries:", len(missingentries) - sys.stderr.flush() - fetched_entries = 0 - print >>sys.stderr, "fetching missing entries", - sys.stderr.flush() - for missingentry in missingentries: - hash = base64.b64decode(missingentry) - sendentryresult = sendentry_merge(nodename, nodeaddress, read_chain(chainsdir, hash), hash) - if sendentryresult["result"] != "ok": - print >>sys.stderr, "send sth:", sendentryresult - sys.exit(1) - fetched_entries += 1 - if added_entries % 1000 == 0: - print >>sys.stderr, fetched_entries, - sys.stderr.flush() - print >>sys.stderr - sys.stderr.flush() - timing_point(timing, "send missing") - verifyrootresult = verifyroot(nodename, nodeaddress, tree_size) - if verifyrootresult["result"] != "ok": - print >>sys.stderr, "verifyroot:", verifyrootresult - sys.exit(1) - secondary_root_hash = base64.b64decode(verifyrootresult["root_hash"]) - if root_hash != secondary_root_hash: - print >>sys.stderr, "secondary root hash was", hexencode(secondary_root_hash) - print >>sys.stderr, " expected", hexencode(root_hash) - sys.exit(1) - timing_point(timing, "verifyroot") - setverifiedsize(nodename, nodeaddress, tree_size) - if args.timing: - print >>sys.stderr, timing["deltatimes"] - sys.stderr.flush() - -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 urllib2.URLError, e: - print >>sys.stderr, e - sys.stderr.flush() -if tree_head_signature == None: - print >>sys.stderr, "Could not contact any signing nodes" - sys.exit(1) - -sth = {"tree_size": tree_size, "timestamp": timestamp, - "sha256_root_hash": base64.b64encode(root_hash), - "tree_head_signature": base64.b64encode(tree_head_signature)} - -check_sth_signature(ctbaseurl, sth, publickey=logpublickey) - -timing_point(timing, "build sth") - -if args.timing: - print >>sys.stderr, timing["deltatimes"] - sys.stderr.flush() - -print hexencode(root_hash) -sys.stdout.flush() - -for frontendnode in frontendnodes: - nodeaddress = "https://%s/" % frontendnode["address"] - nodename = frontendnode["name"] - timing = timing_point() - print >>sys.stderr, "distributing for node", nodename - sys.stderr.flush() - curpos = get_curpos(nodename, nodeaddress) - timing_point(timing, "get curpos") - print >>sys.stderr, "current position", curpos - sys.stderr.flush() - entries = [base64.b64encode(entry) for entry in logorder[curpos:]] - print >>sys.stderr, "sending log:", - sys.stderr.flush() - for chunk in chunks(entries, 1000): - for trynumber in range(5, 0, -1): - sendlogresult = sendlog(nodename, nodeaddress, {"start": curpos, "hashes": chunk}) - if sendlogresult == None: - if trynumber == 1: - sys.exit(1) - select.select([], [], [], 10.0) - print >>sys.stderr, "tries left:", trynumber - sys.stderr.flush() - continue - break - if sendlogresult["result"] != "ok": - print >>sys.stderr, "sendlog:", sendlogresult - sys.exit(1) - curpos += len(chunk) - print >>sys.stderr, curpos, - sys.stderr.flush() - print >>sys.stderr - timing_point(timing, "sendlog") - print >>sys.stderr, "log sent" - sys.stderr.flush() - missingentries = get_missingentries(nodename, nodeaddress) - timing_point(timing, "get missing") - print >>sys.stderr, "missing entries:", len(missingentries) - sys.stderr.flush() - fetched_entries = 0 - print >>sys.stderr, "fetching missing entries", - sys.stderr.flush() - for missingentry in missingentries: - hash = base64.b64decode(missingentry) - sendentryresult = sendentry(nodename, nodeaddress, read_chain(chainsdir, hash), hash) - if sendentryresult["result"] != "ok": - print >>sys.stderr, "send sth:", sendentryresult - sys.exit(1) - fetched_entries += 1 - if added_entries % 1000 == 0: - print >>sys.stderr, fetched_entries, - sys.stderr.flush() - print >>sys.stderr - sys.stderr.flush() - timing_point(timing, "send missing") - sendsthresult = sendsth(nodename, nodeaddress, sth) - if sendsthresult["result"] != "ok": - print >>sys.stderr, "send sth:", sendsthresult - sys.exit(1) - timing_point(timing, "send sth") - if args.timing: - print >>sys.stderr, timing["deltatimes"] - sys.stderr.flush() diff --git a/tools/mergetools.py b/tools/mergetools.py deleted file mode 100644 index 947d7f4..0000000 --- a/tools/mergetools.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (c) 2015, NORDUnet A/S. -# See LICENSE for licensing information. -import base64 -import hashlib -import sys -import struct -from certtools import get_leaf_hash - -def parselogrow(row): - return base64.b16decode(row, casefold=True) - -def get_logorder(filename): - f = open(filename, "r") - return [parselogrow(row.rstrip()) for row in f] - -def read_chain_open(chainsdir, filename): - path = chainsdir + "/" + filename[0:2] + "/" + filename[2:4] + "/" + filename[4:6] - f = open(path + "/" + filename, "r") - return f - -def read_chain(chainsdir, key): - filename = base64.b16encode(key).upper() - try: - f = read_chain_open(chainsdir, filename) - except IOError, e: - f = read_chain_open(chainsdir, filename.lower()) - value = f.read() - f.close() - return value - -def tlv_decode(data): - (length,) = struct.unpack(">I", data[0:4]) - type = data[4:8] - value = data[8:length] - rest = data[length:] - return (type, value, rest) - -def tlv_encode(type, value): - assert(len(type) == 4) - data = struct.pack(">I", len(value) + 8) + type + value - return data - -def tlv_decodelist(data): - l = [] - while len(data): - (type, value, rest) = tlv_decode(data) - l.append((type, value)) - data = rest - return l - -def tlv_encodelist(l): - data = "" - for (type, value) in l: - data += tlv_encode(type, value) - return data - -def unwrap_entry(entry): - ploplevel = tlv_decodelist(entry) - assert(len(ploplevel) == 2) - (ploptype, plopdata) = ploplevel[0] - (plopchecksumtype, plopchecksum) = ploplevel[1] - assert(ploptype == "PLOP") - assert(plopchecksumtype == "S256") - computedchecksum = hashlib.sha256(plopdata).digest() - assert(computedchecksum == plopchecksum) - return plopdata - -def wrap_entry(entry): - return tlv_encodelist([("PLOP", entry), - ("S256", hashlib.sha256(entry).digest())]) - -def verify_entry(verifycert, entry, hash): - packed = unwrap_entry(entry) - unpacked = tlv_decodelist(packed) - (mtltype, mtl) = unpacked[0] - assert hash == get_leaf_hash(mtl) - assert mtltype == "MTL1" - s = struct.pack(">I", len(packed)) + packed - try: - verifycert.stdin.write(s) - except IOError, e: - sys.stderr.write("merge: unable to write to verifycert process: ") - while 1: - line = verifycert.stdout.readline() - if line: - sys.stderr.write(line) - else: - sys.exit(1) - result_length_packed = verifycert.stdout.read(4) - (result_length,) = struct.unpack(">I", result_length_packed) - result = verifycert.stdout.read(result_length) - assert len(result) == result_length - (error_code,) = struct.unpack("B", result[0:1]) - if error_code != 0: - print >>sys.stderr, result[1:] - sys.exit(1) diff --git a/tools/precerttools.py b/tools/precerttools.py deleted file mode 100644 index 13ac572..0000000 --- a/tools/precerttools.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright (c) 2014, NORDUnet A/S. -# See LICENSE for licensing information. - -import sys -import hashlib -import rfc2459 -from pyasn1.type import univ, tag -from pyasn1.codec.der import encoder, decoder - -def cleanextensions(extensions): - result = rfc2459.Extensions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)) - for idx in range(len(extensions)): - extension = extensions.getComponentByPosition(idx) - if extension.getComponentByName("extnID") == univ.ObjectIdentifier("1.3.6.1.4.1.11129.2.4.3"): - pass - else: - result.setComponentByPosition(len(result), extension) - return result - -def decode_any(anydata, asn1Spec=None): - (wrapper, _) = decoder.decode(anydata) - (data, _) = decoder.decode(wrapper, asn1Spec=asn1Spec) - return data - -def get_subject(cert): - (asn1,rest) = decoder.decode(cert, asn1Spec=rfc2459.Certificate()) - assert rest == '' - tbsCertificate = asn1.getComponentByName("tbsCertificate") - subject = tbsCertificate.getComponentByName("subject") - extensions = tbsCertificate.getComponentByName("extensions") - keyid_wrapper = get_extension(extensions, rfc2459.id_ce_subjectKeyIdentifier) - keyid = decode_any(keyid_wrapper, asn1Spec=rfc2459.KeyIdentifier()) - return (subject, keyid) - -def cleanprecert(precert, issuer=None): - (asn1,rest) = decoder.decode(precert, asn1Spec=rfc2459.Certificate()) - assert rest == '' - tbsCertificate = asn1.getComponentByName("tbsCertificate") - - extensions = tbsCertificate.getComponentByName("extensions") - tbsCertificate.setComponentByName("extensions", cleanextensions(extensions)) - - if issuer: - (issuer_subject, keyid) = get_subject(issuer) - tbsCertificate.setComponentByName("issuer", issuer_subject) - authkeyid = rfc2459.AuthorityKeyIdentifier() - authkeyid.setComponentByName("keyIdentifier", - rfc2459.KeyIdentifier(str(keyid)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) - authkeyid_wrapper = univ.OctetString(encoder.encode(authkeyid)) - authkeyid_wrapper2 = encoder.encode(authkeyid_wrapper) - set_extension(extensions, rfc2459.id_ce_authorityKeyIdentifier, authkeyid_wrapper2) - return encoder.encode(tbsCertificate) - -def get_extension(extensions, id): - for idx in range(len(extensions)): - extension = extensions.getComponentByPosition(idx) - if extension.getComponentByName("extnID") == id: - return extension.getComponentByName("extnValue") - return None - -def set_extension(extensions, id, value): - result = rfc2459.Extensions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3)) - for idx in range(len(extensions)): - extension = extensions.getComponentByPosition(idx) - if extension.getComponentByName("extnID") == id: - extension.setComponentByName("extnValue", value) - -def get_cert_key_hash(cert): - (asn1,rest) = decoder.decode(cert, asn1Spec=rfc2459.Certificate()) - assert rest == '' - tbsCertificate = asn1.getComponentByName("tbsCertificate") - key = encoder.encode(tbsCertificate.getComponentByName("subjectPublicKeyInfo")) - hash = hashlib.sha256() - hash.update(key) - return hash.digest() - -def printcert(cert, outfile=sys.stdout): - (asn1,rest) = decoder.decode(cert, asn1Spec=rfc2459.Certificate()) - assert rest == '' - print >>outfile, asn1.prettyPrint() - -def printtbscert(cert, outfile=sys.stdout): - (asn1,rest) = decoder.decode(cert, asn1Spec=rfc2459.TBSCertificate()) - assert rest == '' - print >>outfile, asn1.prettyPrint() - -ext_key_usage_precert_signing_cert = univ.ObjectIdentifier("1.3.6.1.4.1.11129.2.4.4") - -def get_ext_key_usage(cert): - (asn1,rest) = decoder.decode(cert, asn1Spec=rfc2459.Certificate()) - assert rest == '' - tbsCertificate = asn1.getComponentByName("tbsCertificate") - extensions = tbsCertificate.getComponentByName("extensions") - for idx in range(len(extensions)): - extension = extensions.getComponentByPosition(idx) - if extension.getComponentByName("extnID") == rfc2459.id_ce_extKeyUsage: - ext_key_usage_wrapper_binary = extension.getComponentByName("extnValue") - (ext_key_usage_wrapper, _) = decoder.decode(ext_key_usage_wrapper_binary) - (ext_key_usage, _) = decoder.decode(ext_key_usage_wrapper)#, asn1Spec=rfc2459.ExtKeyUsageSyntax()) - return list(ext_key_usage) - return [] - diff --git a/tools/rfc2459.py b/tools/rfc2459.py deleted file mode 100644 index 0ce9c6d..0000000 --- a/tools/rfc2459.py +++ /dev/null @@ -1,927 +0,0 @@ -# Copyright (c) 2005-2013, Ilya Etingof <ilya@glas.net> -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# X.509 message syntax -# -# ASN.1 source from: -# http://www.trl.ibm.com/projects/xml/xss4j/data/asn1/grammars/x509.asn -# http://www.ietf.org/rfc/rfc2459.txt -# -# Sample captures from: -# http://wiki.wireshark.org/SampleCaptures/ -# -from pyasn1.type import tag,namedtype,namedval,univ,constraint,char,useful - -MAX = 64 # XXX ? - -# -# PKIX1Explicit88 -# - -# Upper Bounds -ub_name = univ.Integer(32768) -ub_common_name = univ.Integer(64) -ub_locality_name = univ.Integer(128) -ub_state_name = univ.Integer(128) -ub_organization_name = univ.Integer(64) -ub_organizational_unit_name = univ.Integer(64) -ub_title = univ.Integer(64) -ub_match = univ.Integer(128) -ub_emailaddress_length = univ.Integer(128) -ub_common_name_length = univ.Integer(64) -ub_country_name_alpha_length = univ.Integer(2) -ub_country_name_numeric_length = univ.Integer(3) -ub_domain_defined_attributes = univ.Integer(4) -ub_domain_defined_attribute_type_length = univ.Integer(8) -ub_domain_defined_attribute_value_length = univ.Integer(128) -ub_domain_name_length = univ.Integer(16) -ub_extension_attributes = univ.Integer(256) -ub_e163_4_number_length = univ.Integer(15) -ub_e163_4_sub_address_length = univ.Integer(40) -ub_generation_qualifier_length = univ.Integer(3) -ub_given_name_length = univ.Integer(16) -ub_initials_length = univ.Integer(5) -ub_integer_options = univ.Integer(256) -ub_numeric_user_id_length = univ.Integer(32) -ub_organization_name_length = univ.Integer(64) -ub_organizational_unit_name_length = univ.Integer(32) -ub_organizational_units = univ.Integer(4) -ub_pds_name_length = univ.Integer(16) -ub_pds_parameter_length = univ.Integer(30) -ub_pds_physical_address_lines = univ.Integer(6) -ub_postal_code_length = univ.Integer(16) -ub_surname_length = univ.Integer(40) -ub_terminal_id_length = univ.Integer(24) -ub_unformatted_address_length = univ.Integer(180) -ub_x121_address_length = univ.Integer(16) - -class UniversalString(char.UniversalString): pass -class BMPString(char.BMPString): pass -class UTF8String(char.UTF8String): pass - -id_pkix = univ.ObjectIdentifier('1.3.6.1.5.5.7') -id_pe = univ.ObjectIdentifier('1.3.6.1.5.5.7.1') -id_qt = univ.ObjectIdentifier('1.3.6.1.5.5.7.2') -id_kp = univ.ObjectIdentifier('1.3.6.1.5.5.7.3') -id_ad = univ.ObjectIdentifier('1.3.6.1.5.5.7.48') - -id_qt_cps = univ.ObjectIdentifier('1.3.6.1.5.5.7.2.1') -id_qt_unotice = univ.ObjectIdentifier('1.3.6.1.5.5.7.2.2') - -id_ad_ocsp = univ.ObjectIdentifier('1.3.6.1.5.5.7.48.1') -id_ad_caIssuers = univ.ObjectIdentifier('1.3.6.1.5.5.7.48.2') - -class AttributeValue(univ.Any): pass - -class AttributeType(univ.ObjectIdentifier): pass - -class AttributeTypeAndValue(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('type', AttributeType()), - namedtype.NamedType('value', AttributeValue()) - ) - -class Attribute(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('type', AttributeType()), - namedtype.NamedType('vals', univ.SetOf(componentType=AttributeValue())) - ) - -id_at = univ.ObjectIdentifier('2.5.4') -id_at_name = univ.ObjectIdentifier('2.5.4.41') -id_at_sutname = univ.ObjectIdentifier('2.5.4.4') -id_at_givenName = univ.ObjectIdentifier('2.5.4.42') -id_at_initials = univ.ObjectIdentifier('2.5.4.43') -id_at_generationQualifier = univ.ObjectIdentifier('2.5.4.44') - -class X520name(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))) - ) - -id_at_commonName = univ.ObjectIdentifier('2.5.4.3') - -class X520CommonName(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))) - ) - -id_at_localityName = univ.ObjectIdentifier('2.5.4.7') - -class X520LocalityName(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))) - ) - -id_at_stateOrProvinceName = univ.ObjectIdentifier('2.5.4.8') - -class X520StateOrProvinceName(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))) - ) - -id_at_organizationName = univ.ObjectIdentifier('2.5.4.10') - -class X520OrganizationName(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))) - ) - -id_at_organizationalUnitName = univ.ObjectIdentifier('2.5.4.11') - -class X520OrganizationalUnitName(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))) - ) - -id_at_title = univ.ObjectIdentifier('2.5.4.12') - -class X520Title(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))) - ) - -id_at_dnQualifier = univ.ObjectIdentifier('2.5.4.46') - -class X520dnQualifier(char.PrintableString): pass - -id_at_countryName = univ.ObjectIdentifier('2.5.4.6') - -class X520countryName(char.PrintableString): - subtypeSpec = char.PrintableString.subtypeSpec + constraint.ValueSizeConstraint(2, 2) - -pkcs_9 = univ.ObjectIdentifier('1.2.840.113549.1.9') - -emailAddress = univ.ObjectIdentifier('1.2.840.113549.1.9.1') - -class Pkcs9email(char.IA5String): - subtypeSpec = char.IA5String.subtypeSpec + constraint.ValueSizeConstraint(1, ub_emailaddress_length) - -# ---- - -class DSAPrivateKey(univ.Sequence): - """PKIX compliant DSA private key structure""" - componentType = namedtype.NamedTypes( - namedtype.NamedType('version', univ.Integer(namedValues=namedval.NamedValues(('v1', 0)))), - namedtype.NamedType('p', univ.Integer()), - namedtype.NamedType('q', univ.Integer()), - namedtype.NamedType('g', univ.Integer()), - namedtype.NamedType('public', univ.Integer()), - namedtype.NamedType('private', univ.Integer()) - ) - -# ---- - -class RelativeDistinguishedName(univ.SetOf): - componentType = AttributeTypeAndValue() - -class RDNSequence(univ.SequenceOf): - componentType = RelativeDistinguishedName() - -class Name(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('', RDNSequence()) - ) - -class DirectoryString(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - namedtype.NamedType('ia5String', char.IA5String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))) # hm, this should not be here!? XXX - ) - -# certificate and CRL specific structures begin here - -class AlgorithmIdentifier(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('algorithm', univ.ObjectIdentifier()), - namedtype.OptionalNamedType('parameters', univ.Any()) - ) - -class Extension(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('extnID', univ.ObjectIdentifier()), - namedtype.DefaultedNamedType('critical', univ.Boolean('False')), - namedtype.NamedType('extnValue', univ.Any()) - ) - -class Extensions(univ.SequenceOf): - componentType = Extension() - sizeSpec = univ.SequenceOf.sizeSpec + constraint.ValueSizeConstraint(1, MAX) - -class SubjectPublicKeyInfo(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('algorithm', AlgorithmIdentifier()), - namedtype.NamedType('subjectPublicKey', univ.BitString()) - ) - -class UniqueIdentifier(univ.BitString): pass - -class Time(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('utcTime', useful.UTCTime()), - namedtype.NamedType('generalTime', useful.GeneralizedTime()) - ) - -class Validity(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('notBefore', Time()), - namedtype.NamedType('notAfter', Time()) - ) - -class CertificateSerialNumber(univ.Integer): pass - -class Version(univ.Integer): - namedValues = namedval.NamedValues( - ('v1', 0), ('v2', 1), ('v3', 2) - ) - -class TBSCertificate(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.DefaultedNamedType('version', Version('v1').subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('serialNumber', CertificateSerialNumber()), - namedtype.NamedType('signature', AlgorithmIdentifier()), - namedtype.NamedType('issuer', Name()), - namedtype.NamedType('validity', Validity()), - namedtype.NamedType('subject', Name()), - namedtype.NamedType('subjectPublicKeyInfo', SubjectPublicKeyInfo()), - namedtype.OptionalNamedType('issuerUniqueID', UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('subjectUniqueID', UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('extensions', Extensions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) - ) - -class Certificate(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('tbsCertificate', TBSCertificate()), - namedtype.NamedType('signatureAlgorithm', AlgorithmIdentifier()), - namedtype.NamedType('signatureValue', univ.BitString()) - ) - -# CRL structures - -class RevokedCertificate(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('userCertificate', CertificateSerialNumber()), - namedtype.NamedType('revocationDate', Time()), - namedtype.OptionalNamedType('crlEntryExtensions', Extensions()) - ) - -class TBSCertList(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('version', Version()), - namedtype.NamedType('signature', AlgorithmIdentifier()), - namedtype.NamedType('issuer', Name()), - namedtype.NamedType('thisUpdate', Time()), - namedtype.OptionalNamedType('nextUpdate', Time()), - namedtype.OptionalNamedType('revokedCertificates', univ.SequenceOf(componentType=RevokedCertificate())), - namedtype.OptionalNamedType('crlExtensions', Extensions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))) - ) - -class CertificateList(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('tbsCertList', TBSCertList()), - namedtype.NamedType('signatureAlgorithm', AlgorithmIdentifier()), - namedtype.NamedType('signature', univ.BitString()) - ) - -# Algorithm OIDs and parameter structures - -pkcs_1 = univ.ObjectIdentifier('1.2.840.113549.1.1') -rsaEncryption = univ.ObjectIdentifier('1.2.840.113549.1.1.1') -md2WithRSAEncryption = univ.ObjectIdentifier('1.2.840.113549.1.1.2') -md5WithRSAEncryption = univ.ObjectIdentifier('1.2.840.113549.1.1.4') -sha1WithRSAEncryption = univ.ObjectIdentifier('1.2.840.113549.1.1.5') -id_dsa_with_sha1 = univ.ObjectIdentifier('1.2.840.10040.4.3') - -class Dss_Sig_Value(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('r', univ.Integer()), - namedtype.NamedType('s', univ.Integer()) - ) - -dhpublicnumber = univ.ObjectIdentifier('1.2.840.10046.2.1') - -class ValidationParms(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('seed', univ.BitString()), - namedtype.NamedType('pgenCounter', univ.Integer()) - ) - -class DomainParameters(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('p', univ.Integer()), - namedtype.NamedType('g', univ.Integer()), - namedtype.NamedType('q', univ.Integer()), - namedtype.NamedType('j', univ.Integer()), - namedtype.OptionalNamedType('validationParms', ValidationParms()) - ) - -id_dsa = univ.ObjectIdentifier('1.2.840.10040.4.1') - -class Dss_Parms(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('p', univ.Integer()), - namedtype.NamedType('q', univ.Integer()), - namedtype.NamedType('g', univ.Integer()) - ) - -# x400 address syntax starts here - -teletex_domain_defined_attributes = univ.Integer(6) - -class TeletexDomainDefinedAttribute(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('type', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attribute_type_length))), - namedtype.NamedType('value', char.TeletexString()) - ) - -class TeletexDomainDefinedAttributes(univ.SequenceOf): - componentType = TeletexDomainDefinedAttribute() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) - -terminal_type = univ.Integer(23) - -class TerminalType(univ.Integer): - subtypeSpec = univ.Integer.subtypeSpec + constraint.ValueSizeConstraint(0, ub_integer_options) - namedValues = namedval.NamedValues( - ('telex', 3), - ('teletelex', 4), - ('g3-facsimile', 5), - ('g4-facsimile', 6), - ('ia5-terminal', 7), - ('videotex', 8) - ) - -class PresentationAddress(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('pSelector', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('sSelector', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('tSelector', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('nAddresses', univ.SetOf(componentType=univ.OctetString()).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3), subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - ) - -extended_network_address = univ.Integer(22) - -class E163_4_address(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('number', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_e163_4_number_length), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('sub-address', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_e163_4_sub_address_length), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) - ) - -class ExtendedNetworkAddress(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('e163-4-address', E163_4_address()), - namedtype.NamedType('psap-address', PresentationAddress().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) - ) - -class PDSParameter(univ.Set): - componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('printable-string', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pds_parameter_length))), - namedtype.OptionalNamedType('teletex-string', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pds_parameter_length))) - ) - -local_postal_attributes = univ.Integer(21) - -class LocalPostalAttributes(PDSParameter): pass - -class UniquePostalName(PDSParameter): pass - -unique_postal_name = univ.Integer(20) - -poste_restante_address = univ.Integer(19) - -class PosteRestanteAddress(PDSParameter): pass - -post_office_box_address = univ.Integer(18) - -class PostOfficeBoxAddress(PDSParameter): pass - -street_address = univ.Integer(17) - -class StreetAddress(PDSParameter): pass - -class UnformattedPostalAddress(univ.Set): - componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('printable-address', univ.SequenceOf(componentType=char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pds_parameter_length)).subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pds_physical_address_lines)))), - namedtype.OptionalNamedType('teletex-string', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_unformatted_address_length))) - ) - -physical_delivery_office_name = univ.Integer(10) - -class PhysicalDeliveryOfficeName(PDSParameter): pass - -physical_delivery_office_number = univ.Integer(11) - -class PhysicalDeliveryOfficeNumber(PDSParameter): pass - -extension_OR_address_components = univ.Integer(12) - -class ExtensionORAddressComponents(PDSParameter): pass - -physical_delivery_personal_name = univ.Integer(13) - -class PhysicalDeliveryPersonalName(PDSParameter): pass - -physical_delivery_organization_name = univ.Integer(14) - -class PhysicalDeliveryOrganizationName(PDSParameter): pass - -extension_physical_delivery_address_components = univ.Integer(15) - -class ExtensionPhysicalDeliveryAddressComponents(PDSParameter): pass - -unformatted_postal_address = univ.Integer(16) - -postal_code = univ.Integer(9) - -class PostalCode(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('numeric-code', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_postal_code_length))), - namedtype.NamedType('printable-code', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_postal_code_length))) - ) - -class PhysicalDeliveryCountryName(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('x121-dcc-code', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(ub_country_name_numeric_length, ub_country_name_numeric_length))), - namedtype.NamedType('iso-3166-alpha2-code', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(ub_country_name_alpha_length, ub_country_name_alpha_length))) - ) - -class PDSName(char.PrintableString): - subtypeSpec = char.PrintableString.subtypeSpec + constraint.ValueSizeConstraint(1, ub_pds_name_length) - -physical_delivery_country_name = univ.Integer(8) - -class TeletexOrganizationalUnitName(char.TeletexString): - subtypeSpec = char.TeletexString.subtypeSpec + constraint.ValueSizeConstraint(1, ub_organizational_unit_name_length) - -pds_name = univ.Integer(7) - -teletex_organizational_unit_names = univ.Integer(5) - -class TeletexOrganizationalUnitNames(univ.SequenceOf): - componentType = TeletexOrganizationalUnitName() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, ub_organizational_units) - -teletex_personal_name = univ.Integer(4) - -class TeletexPersonalName(univ.Set): - componentType = namedtype.NamedTypes( - namedtype.NamedType('surname', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_surname_length), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('given-name', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_given_name_length), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('initials', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_initials_length), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('generation-qualifier', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_generation_qualifier_length), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) - ) - -teletex_organization_name = univ.Integer(3) - -class TeletexOrganizationName(char.TeletexString): - subtypeSpec = char.TeletexString.subtypeSpec + constraint.ValueSizeConstraint(1, ub_organization_name_length) - -teletex_common_name = univ.Integer(2) - -class TeletexCommonName(char.TeletexString): - subtypeSpec = char.TeletexString.subtypeSpec + constraint.ValueSizeConstraint(1, ub_common_name_length) - -class CommonName(char.PrintableString): - subtypeSpec = char.PrintableString.subtypeSpec + constraint.ValueSizeConstraint(1, ub_common_name_length) - -common_name = univ.Integer(1) - -class ExtensionAttribute(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('extension-attribute-type', univ.Integer().subtype(subtypeSpec=constraint.ValueSizeConstraint(0, ub_extension_attributes), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('extension-attribute-value', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) - ) - -class ExtensionAttributes(univ.SetOf): - componentType = ExtensionAttribute() - subtypeSpec = univ.SetOf.subtypeSpec + constraint.ValueSizeConstraint(1, ub_extension_attributes) - -class BuiltInDomainDefinedAttribute(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('type', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attribute_type_length))), - namedtype.NamedType('value', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attribute_value_length))) - ) - -class BuiltInDomainDefinedAttributes(univ.SequenceOf): - componentType = BuiltInDomainDefinedAttribute() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) - -class OrganizationalUnitName(char.PrintableString): - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, ub_organizational_unit_name_length) - -class OrganizationalUnitNames(univ.SequenceOf): - componentType = OrganizationalUnitName() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, ub_organizational_units) - -class PersonalName(univ.Set): - componentType = namedtype.NamedTypes( - namedtype.NamedType('surname', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_surname_length), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('given-name', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_given_name_length), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('initials', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_initials_length), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('generation-qualifier', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_generation_qualifier_length), explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) - ) - -class NumericUserIdentifier(char.NumericString): - subtypeSpec = char.NumericString.subtypeSpec + constraint.ValueSizeConstraint(1, ub_numeric_user_id_length) - -class OrganizationName(char.PrintableString): - subtypeSpec = char.PrintableString.subtypeSpec + constraint.ValueSizeConstraint(1, ub_organization_name_length) - -class PrivateDomainName(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('numeric', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_name_length))), - namedtype.NamedType('printable', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_name_length))) - ) - -class TerminalIdentifier(char.PrintableString): - subtypeSpec = char.PrintableString.subtypeSpec + constraint.ValueSizeConstraint(1, ub_terminal_id_length) - -class X121Address(char.NumericString): - subtypeSpec = char.NumericString.subtypeSpec + constraint.ValueSizeConstraint(1, ub_x121_address_length) - -class NetworkAddress(X121Address): pass - -class AdministrationDomainName(univ.Choice): - tagSet = univ.Choice.tagSet.tagExplicitly( - tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 2) - ) - componentType = namedtype.NamedTypes( - namedtype.NamedType('numeric', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(0, ub_domain_name_length))), - namedtype.NamedType('printable', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(0, ub_domain_name_length))) - ) - -class CountryName(univ.Choice): - tagSet = univ.Choice.tagSet.tagExplicitly( - tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 1) - ) - componentType = namedtype.NamedTypes( - namedtype.NamedType('x121-dcc-code', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(ub_country_name_numeric_length, ub_country_name_numeric_length))), - namedtype.NamedType('iso-3166-alpha2-code', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(ub_country_name_alpha_length, ub_country_name_alpha_length))) - ) - -class BuiltInStandardAttributes(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('country-name', CountryName()), - namedtype.OptionalNamedType('administration-domain-name', AdministrationDomainName()), - namedtype.OptionalNamedType('network-address', NetworkAddress().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('terminal-identifier', TerminalIdentifier().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('private-domain-name', PrivateDomainName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('organization-name', OrganizationName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), - namedtype.OptionalNamedType('numeric-user-identifier', NumericUserIdentifier().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))), - namedtype.OptionalNamedType('personal-name', PersonalName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))), - namedtype.OptionalNamedType('organizational-unit-names', OrganizationalUnitNames().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))) - ) - -class ORAddress(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('built-in-standard-attributes', BuiltInStandardAttributes()), - namedtype.OptionalNamedType('built-in-domain-defined-attributes', BuiltInDomainDefinedAttributes()), - namedtype.OptionalNamedType('extension-attributes', ExtensionAttributes()) - ) - -# -# PKIX1Implicit88 -# - -id_ce_invalidityDate = univ.ObjectIdentifier('2.5.29.24') - -class InvalidityDate(useful.GeneralizedTime): pass - -id_holdinstruction_none = univ.ObjectIdentifier('2.2.840.10040.2.1') -id_holdinstruction_callissuer = univ.ObjectIdentifier('2.2.840.10040.2.2') -id_holdinstruction_reject = univ.ObjectIdentifier('2.2.840.10040.2.3') - -holdInstruction = univ.ObjectIdentifier('2.2.840.10040.2') - -id_ce_holdInstructionCode = univ.ObjectIdentifier('2.5.29.23') - -class HoldInstructionCode(univ.ObjectIdentifier): pass - -id_ce_cRLReasons = univ.ObjectIdentifier('2.5.29.21') - -class CRLReason(univ.Enumerated): - namedValues = namedval.NamedValues( - ('unspecified', 0), - ('keyCompromise', 1), - ('cACompromise', 2), - ('affiliationChanged', 3), - ('superseded', 4), - ('cessationOfOperation', 5), - ('certificateHold', 6), - ('removeFromCRL', 8) - ) - -id_ce_cRLNumber = univ.ObjectIdentifier('2.5.29.20') - -class CRLNumber(univ.Integer): - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(0, MAX) - -class BaseCRLNumber(CRLNumber): pass - -id_kp_serverAuth = univ.ObjectIdentifier('1.3.6.1.5.5.7.3.1.1') -id_kp_clientAuth = univ.ObjectIdentifier('1.3.6.1.5.5.7.3.2') -id_kp_codeSigning = univ.ObjectIdentifier('1.3.6.1.5.5.7.3.3') -id_kp_emailProtection = univ.ObjectIdentifier('1.3.6.1.5.5.7.3.4') -id_kp_ipsecEndSystem = univ.ObjectIdentifier('1.3.6.1.5.5.7.3.5') -id_kp_ipsecTunnel = univ.ObjectIdentifier('1.3.6.1.5.5.7.3.6') -id_kp_ipsecUser = univ.ObjectIdentifier('1.3.6.1.5.5.7.3.7') -id_kp_timeStamping = univ.ObjectIdentifier('1.3.6.1.5.5.7.3.8') -id_pe_authorityInfoAccess = univ.ObjectIdentifier('1.3.6.1.5.5.7.1.1') -id_ce_extKeyUsage = univ.ObjectIdentifier('2.5.29.37') - -class KeyPurposeId(univ.ObjectIdentifier): pass - -class ExtKeyUsageSyntax(univ.SequenceOf): - componentType = KeyPurposeId() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) - -class ReasonFlags(univ.BitString): - namedValues = namedval.NamedValues( - ('unused', 0), - ('keyCompromise', 1), - ('cACompromise', 2), - ('affiliationChanged', 3), - ('superseded', 4), - ('cessationOfOperation', 5), - ('certificateHold', 6) - ) - - -class SkipCerts(univ.Integer): - subtypeSpec = univ.Integer.subtypeSpec + constraint.ValueSizeConstraint(0, MAX) - -id_ce_policyConstraints = univ.ObjectIdentifier('2.5.29.36') - -class PolicyConstraints(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('requireExplicitPolicy', SkipCerts().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('inhibitPolicyMapping', SkipCerts().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) - ) - -id_ce_basicConstraints = univ.ObjectIdentifier('2.5.29.19') - -class BasicConstraints(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('cA', univ.Boolean(False)), - namedtype.OptionalNamedType('pathLenConstraint', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, MAX))) - ) - -id_ce_subjectDirectoryAttributes = univ.ObjectIdentifier('2.5.29.9') - -class SubjectDirectoryAttributes(univ.SequenceOf): - componentType = Attribute() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) - -class EDIPartyName(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('nameAssigner', DirectoryString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('partyName', DirectoryString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) - ) - -class AnotherName(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('type-id', univ.ObjectIdentifier()), - namedtype.NamedType('value', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) - ) - -class GeneralName(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('otherName', AnotherName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('rfc822Name', char.IA5String().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('dNSName', char.IA5String().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.NamedType('x400Address', ORAddress().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), - namedtype.NamedType('directoryName', Name().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))), - namedtype.NamedType('ediPartyName', EDIPartyName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5))), - namedtype.NamedType('uniformResourceIdentifier', char.IA5String().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))), - namedtype.NamedType('iPAddress', univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7))), - namedtype.NamedType('registeredID', univ.ObjectIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 8))) - ) - -class GeneralNames(univ.SequenceOf): - componentType = GeneralName() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) - -class AccessDescription(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('accessMethod', univ.ObjectIdentifier()), - namedtype.NamedType('accessLocation', GeneralName()) - ) - -class AuthorityInfoAccessSyntax(univ.SequenceOf): - componentType = AccessDescription() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) - -id_ce_deltaCRLIndicator = univ.ObjectIdentifier('2.5.29.27') - -class DistributionPointName(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('fullName', GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('nameRelativeToCRLIssuer', RelativeDistinguishedName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) - ) - -class DistributionPoint(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('distributionPoint', DistributionPointName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('reasons', ReasonFlags().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('cRLIssuer', GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))) - ) -class BaseDistance(univ.Integer): - subtypeSpec = univ.Integer.subtypeSpec + constraint.ValueRangeConstraint(0, MAX) - -id_ce_cRLDistributionPoints = univ.ObjectIdentifier('2.5.29.31') - -class CRLDistPointsSyntax(univ.SequenceOf): - componentType = DistributionPoint - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) -id_ce_issuingDistributionPoint = univ.ObjectIdentifier('2.5.29.28') - -class IssuingDistributionPoint(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('distributionPoint', DistributionPointName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('onlyContainsUserCerts', univ.Boolean(False).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('onlyContainsCACerts', univ.Boolean(False).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('onlySomeReasons', ReasonFlags().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), - namedtype.NamedType('indirectCRL', univ.Boolean(False).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))) - ) - -class GeneralSubtree(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('base', GeneralName()), - namedtype.NamedType('minimum', BaseDistance(0).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('maximum', BaseDistance().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) - ) - -class GeneralSubtrees(univ.SequenceOf): - componentType = GeneralSubtree() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) - -id_ce_nameConstraints = univ.ObjectIdentifier('2.5.29.30') - -class NameConstraints(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('permittedSubtrees', GeneralSubtrees().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('excludedSubtrees', GeneralSubtrees().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))) - ) - - -class DisplayText(univ.Choice): - componentType = namedtype.NamedTypes( - namedtype.NamedType('visibleString', char.VisibleString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, 200))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, 200))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, 200))) - ) - -class NoticeReference(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('organization', DisplayText()), - namedtype.NamedType('noticeNumbers', univ.SequenceOf(componentType=univ.Integer())) - ) - -class UserNotice(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('noticeRef', NoticeReference()), - namedtype.OptionalNamedType('explicitText', DisplayText()) - ) - -class CPSuri(char.IA5String): pass - -class PolicyQualifierId(univ.ObjectIdentifier): - subtypeSpec = univ.ObjectIdentifier.subtypeSpec + constraint.SingleValueConstraint(id_qt_cps, id_qt_unotice) - -class CertPolicyId(univ.ObjectIdentifier): pass - -class PolicyQualifierInfo(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('policyQualifierId', PolicyQualifierId()), - namedtype.NamedType('qualifier', univ.Any()) - ) - -id_ce_certificatePolicies = univ.ObjectIdentifier('2.5.29.32') - -class PolicyInformation(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('policyIdentifier', CertPolicyId()), - namedtype.OptionalNamedType('policyQualifiers', univ.SequenceOf(componentType=PolicyQualifierInfo()).subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))) - ) - -class CertificatePolicies(univ.SequenceOf): - componentType = PolicyInformation() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) - -id_ce_policyMappings = univ.ObjectIdentifier('2.5.29.33') - -class PolicyMapping(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('issuerDomainPolicy', CertPolicyId()), - namedtype.NamedType('subjectDomainPolicy', CertPolicyId()) - ) - -class PolicyMappings(univ.SequenceOf): - componentType = PolicyMapping() - subtypeSpec = univ.SequenceOf.subtypeSpec + constraint.ValueSizeConstraint(1, MAX) - -id_ce_privateKeyUsagePeriod = univ.ObjectIdentifier('2.5.29.16') - -class PrivateKeyUsagePeriod(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('notBefore', useful.GeneralizedTime().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('notAfter', useful.GeneralizedTime().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) - ) - -id_ce_keyUsage = univ.ObjectIdentifier('2.5.29.15') - -class KeyUsage(univ.BitString): - namedValues = namedval.NamedValues( - ('digitalSignature', 0), - ('nonRepudiation', 1), - ('keyEncipherment', 2), - ('dataEncipherment', 3), - ('keyAgreement', 4), - ('keyCertSign', 5), - ('cRLSign', 6), - ('encipherOnly', 7), - ('decipherOnly', 8) - ) - -id_ce = univ.ObjectIdentifier('2.5.29') - -id_ce_authorityKeyIdentifier = univ.ObjectIdentifier('2.5.29.35') - -class KeyIdentifier(univ.OctetString): pass - -id_ce_subjectKeyIdentifier = univ.ObjectIdentifier('2.5.29.14') - -class SubjectKeyIdentifier(KeyIdentifier): pass - -class AuthorityKeyIdentifier(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('keyIdentifier', KeyIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('authorityCertIssuer', GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('authorityCertSerialNumber', CertificateSerialNumber().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) - ) - -id_ce_certificateIssuer = univ.ObjectIdentifier('2.5.29.29') - -class CertificateIssuer(GeneralNames): pass - -id_ce_subjectAltName = univ.ObjectIdentifier('2.5.29.17') - -class SubjectAltName(GeneralNames): pass - -id_ce_issuerAltName = univ.ObjectIdentifier('2.5.29.18') - -class IssuerAltName(GeneralNames): pass diff --git a/tools/storagegc.py b/tools/storagegc.py deleted file mode 100755 index a4f15b7..0000000 --- a/tools/storagegc.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2015, NORDUnet A/S. -# See LICENSE for licensing information. - -import argparse -import urllib2 -import urllib -import json -import base64 -import sys -import yaml -from certtools import * - -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)) - -paths = localconfig["paths"] -db_path = paths["db"] -create_ssl_context(cafile=paths.get("public_cacertfile", None)) - -baseurl = config["baseurl"] - -sth = get_sth(baseurl) - -def verifyleafhash(leaf_hash): - try: - proof = get_proof_by_hash(baseurl, leaf_hash, sth["tree_size"]) - except SystemExit: - return False - - leaf_index = proof["leaf_index"] - inclusion_proof = [base64.b64decode(e) for e in proof["audit_path"]] - - calc_root_hash = verify_inclusion_proof(inclusion_proof, leaf_index, sth["tree_size"], leaf_hash) - - root_hash = base64.b64decode(sth["sha256_root_hash"]) - if root_hash != calc_root_hash: - print "sth calculation incorrect:" - print base64.b16encode(root_hash) - print base64.b16encode(calc_root_hash) - sys.exit(1) - - return True - -starttime = datetime.datetime.now() - - -try: - lastverifiedstring = open(db_path + "lastverifiednewentry").read() - lastverified = json.loads(lastverifiedstring) -except IOError: - lastverified = {"index": -1, "hash": None} -print "starting at", lastverified - -newentriesfile = open(db_path + "newentries") -if lastverified["index"] >= 0: - newentriesfile.seek(lastverified["index"]*65) - assert(newentriesfile.read(64).lower() == lastverified["hash"]) -newentriesfile.seek((lastverified["index"]+1)*65) - -try: - i = lastverified["index"] + 1 - sincewritten = 0 - for line in newentriesfile: - leaf_hash = base64.b16decode(line.strip(), casefold=True) - result = verifyleafhash(leaf_hash) - if not result: - break - lastverified = {"index": i, "hash": base64.b16encode(leaf_hash).lower()} - i += 1 - sincewritten += 1 - if sincewritten > 1000: - write_file(db_path + "lastverifiednewentry", lastverified) - sincewritten = 0 - if lastverified["index"] >= 0: - write_file(db_path + "lastverifiednewentry", lastverified) - print "lastverified", lastverified -except KeyboardInterrupt: - pass diff --git a/tools/submitcert.py b/tools/submitcert.py deleted file mode 100755 index 3b14912..0000000 --- a/tools/submitcert.py +++ /dev/null @@ -1,219 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2014, NORDUnet A/S. -# See LICENSE for licensing information. - -import argparse -import urllib2 -import urllib -import json -import base64 -import sys -import struct -import hashlib -import itertools -from certtools import * -from certtools import * -from precerttools import * -import os -import signal -import select -import zipfile - -parser = argparse.ArgumentParser(description='') -parser.add_argument('baseurl', help="Base URL for CT server") -parser.add_argument('--store', default=None, metavar="dir", help='Get certificates from directory dir') -parser.add_argument('--sct-file', default=None, metavar="file", help='Store SCT:s in file') -parser.add_argument('--parallel', type=int, default=16, metavar="n", help="Number of parallel submits") -parser.add_argument('--check-sct', action='store_true', help="Check SCT signature") -parser.add_argument('--pre-warm', action='store_true', help="Wait 3 seconds after first submit") -parser.add_argument('--publickey', default=None, metavar="file", help='Public key for the CT log') -parser.add_argument('--cafile', default=None, metavar="file", help='File containing the CA cert') -args = parser.parse_args() - -create_ssl_context(cafile=args.cafile) - -from multiprocessing import Pool - -baseurl = args.baseurl -certfilepath = args.store - -logpublickey = get_public_key_from_file(args.publickey) if args.publickey else None - -lookup_in_log = False - -if certfilepath[-1] == "/": - certfiles = [certfilepath + filename for filename in sorted(os.listdir(certfilepath)) if os.path.isfile(certfilepath + filename)] -else: - certfiles = [certfilepath] - -sth = get_sth(baseurl) - -def submitcert((certfile, cert)): - timing = timing_point() - certchain = get_certs_from_string(cert) - precerts = get_precerts_from_string(cert) - assert len(precerts) == 0 or len(precerts) == 1 - precert = precerts[0] if precerts else None - timing_point(timing, "readcerts") - - try: - if precert: - if ext_key_usage_precert_signing_cert in get_ext_key_usage(certchain[0]): - issuer_key_hash = get_cert_key_hash(certchain[1]) - issuer = certchain[1] - else: - issuer_key_hash = get_cert_key_hash(certchain[0]) - issuer = None - cleanedcert = cleanprecert(precert, issuer=issuer) - signed_entry = pack_precert(cleanedcert, issuer_key_hash) - leafcert = cleanedcert - result = add_prechain(baseurl, {"chain":map(base64.b64encode, [precert] + certchain)}) - else: - signed_entry = pack_cert(certchain[0]) - leafcert = certchain[0] - issuer_key_hash = None - result = add_chain(baseurl, {"chain":map(base64.b64encode, certchain)}) - except SystemExit: - print "EXIT:", certfile - select.select([], [], [], 1.0) - return (None, None) - - timing_point(timing, "addchain") - - if result == None: - print "ERROR for certfile", certfile - return (None, timing["deltatimes"]) - - try: - if args.check_sct: - check_sct_signature(baseurl, signed_entry, result, precert=precert, publickey=logpublickey) - timing_point(timing, "checksig") - except AssertionError, e: - print "ERROR:", certfile, e - return (None, None) - except urllib2.HTTPError, e: - print "ERROR:", certfile, e - return (None, None) - except ecdsa.keys.BadSignatureError, e: - print "ERROR: bad signature", certfile - return (None, None) - - if lookup_in_log: - - merkle_tree_leaf = pack_mtl(result["timestamp"], leafcert) - - leaf_hash = get_leaf_hash(merkle_tree_leaf) - - proof = get_proof_by_hash(baseurl, leaf_hash, sth["tree_size"]) - - leaf_index = proof["leaf_index"] - - entries = get_entries(baseurl, leaf_index, leaf_index) - - fetched_entry = entries["entries"][0] - - print "does the leaf_input of the fetched entry match what we calculated:", \ - base64.decodestring(fetched_entry["leaf_input"]) == merkle_tree_leaf - - extra_data = fetched_entry["extra_data"] - - certchain = decode_certificate_chain(base64.decodestring(extra_data)) - - submittedcertchain = certchain[1:] - - for (submittedcert, fetchedcert, i) in zip(submittedcertchain, - certchain, itertools.count(1)): - print "cert", i, "in chain is the same:", submittedcert == fetchedcert - - if len(certchain) == len(submittedcertchain) + 1: - last_issuer = get_cert_info(certchain[-1])["issuer"] - root_subject = get_cert_info(certchain[-1])["subject"] - print "issuer of last cert in submitted chain and " \ - "subject of last cert in fetched chain is the same:", \ - last_issuer == root_subject - elif len(certchain) == len(submittedcertchain): - print "cert chains are the same length" - else: - print "ERROR: fetched cert chain has length", len(certchain), - print "and submitted chain has length", len(submittedcertchain) - - timing_point(timing, "lookup") - return ((leafcert, issuer_key_hash, result), timing["deltatimes"]) - -def get_ncerts(certfiles): - n = 0 - for certfile in certfiles: - if certfile.endswith(".zip"): - zf = zipfile.ZipFile(certfile) - n += len(zf.namelist()) - zf.close() - else: - n += 1 - return n - -def get_all_certificates(certfiles): - for certfile in certfiles: - if certfile.endswith(".zip"): - zf = zipfile.ZipFile(certfile) - for name in zf.namelist(): - yield (name, zf.read(name)) - zf.close() - else: - yield (certfile, open(certfile).read()) - -def save_sct(sct, sth, leafcert, issuer_key_hash): - sctlog = open(args.sct_file, "a") - sctentry = {"leafcert": base64.b64encode(leafcert), "sct": sct, "sth": sth} - if issuer_key_hash: - sctentry["issuer_key_hash"] = base64.b64encode(issuer_key_hash) - json.dump(sctentry, sctlog) - sctlog.write("\n") - sctlog.close() - -p = Pool(args.parallel, lambda: signal.signal(signal.SIGINT, signal.SIG_IGN)) - -nsubmitted = 0 -lastprinted = 0 - -print "listing certs" -ncerts = get_ncerts(certfiles) - -print ncerts, "certs" - -certs = get_all_certificates(certfiles) - -(result, timing) = submitcert(certs.next()) -if result != None: - nsubmitted += 1 - (leafcert, issuer_key_hash, sct) = result - save_sct(sct, sth, leafcert, issuer_key_hash) - -if args.pre_warm: - select.select([], [], [], 3.0) - -starttime = datetime.datetime.now() - -try: - for result, timing in p.imap_unordered(submitcert, certs): - if timing == None: - print "error" - print "submitted", nsubmitted - p.terminate() - p.join() - sys.exit(1) - if result != None: - nsubmitted += 1 - (leafcert, issuer_key_hash, sct) = result - save_sct(sct, sth, leafcert, issuer_key_hash) - deltatime = datetime.datetime.now() - starttime - deltatime_f = deltatime.seconds + deltatime.microseconds / 1000000.0 - rate = nsubmitted / deltatime_f - if nsubmitted > lastprinted + ncerts / 10: - print nsubmitted, "rate %.1f" % rate - lastprinted = nsubmitted - #print timing, "rate %.1f" % rate - print "submitted", nsubmitted -except KeyboardInterrupt: - p.terminate() - p.join() diff --git a/tools/testcase1.py b/tools/testcase1.py deleted file mode 100755 index c66d976..0000000 --- a/tools/testcase1.py +++ /dev/null @@ -1,264 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright (c) 2014, NORDUnet A/S. -# See LICENSE for licensing information. - -import urllib2 -import urllib -import json -import base64 -import sys -import struct -import hashlib -import itertools -from certtools import * - -baseurls = [sys.argv[1]] -logpublickeyfile = sys.argv[2] -cacertfile = sys.argv[3] - -certfiles = ["../tools/testcerts/cert1.txt", "../tools/testcerts/cert2.txt", - "../tools/testcerts/cert3.txt", "../tools/testcerts/cert4.txt", - "../tools/testcerts/cert5.txt"] - -cc1 = get_certs_from_file(certfiles[0]) -cc2 = get_certs_from_file(certfiles[1]) -cc3 = get_certs_from_file(certfiles[2]) -cc4 = get_certs_from_file(certfiles[3]) -cc5 = get_certs_from_file(certfiles[4]) - -create_ssl_context(cafile=cacertfile) - -failures = 0 -indentation = "" - -logpublickey = get_public_key_from_file(logpublickeyfile) - -def testgroup(name): - global indentation - print name + ":" - indentation = " " - -def print_error(message, *args): - global failures, indentation - print indentation + "ERROR:", message % args - failures += 1 - -def print_success(message, *args): - print indentation + message % args - -def assert_equal(actual, expected, name, quiet=False, nodata=False, fatal=False): - global failures - if actual != expected: - if nodata: - print_error("%s differs", name) - else: - print_error("%s expected %s got %s", name, expected, actual) - if fatal: - sys.exit(1) - elif not quiet: - print_success("%s was correct", name) - -def print_and_check_tree_size(expected, baseurl): - global failures - sth = get_sth(baseurl) - try: - check_sth_signature(baseurl, sth, publickey=logpublickey) - except AssertionError, e: - print_error("%s", e) - except ecdsa.keys.BadSignatureError, e: - print_error("bad STH signature") - tree_size = sth["tree_size"] - assert_equal(tree_size, expected, "tree size", quiet=True) - -def do_add_chain(chain, baseurl): - global failures - try: - result = add_chain(baseurl, {"chain":map(base64.b64encode, chain)}) - except ValueError, e: - print_error("%s", e) - try: - signed_entry = pack_cert(chain[0]) - check_sct_signature(baseurl, signed_entry, result, publickey=logpublickey) - print_success("signature check succeeded") - except AssertionError, e: - print_error("%s", e) - except ecdsa.keys.BadSignatureError, e: - print e - print_error("bad SCT signature") - return result - -def get_and_validate_proof(timestamp, chain, leaf_index, nentries, baseurl): - cert = chain[0] - merkle_tree_leaf = pack_mtl(timestamp, cert) - leaf_hash = get_leaf_hash(merkle_tree_leaf) - sth = get_sth(baseurl) - proof = get_proof_by_hash(baseurl, leaf_hash, sth["tree_size"]) - leaf_index = proof["leaf_index"] - inclusion_proof = [base64.b64decode(e) for e in proof["audit_path"]] - assert_equal(leaf_index, leaf_index, "leaf_index", quiet=True) - assert_equal(len(inclusion_proof), nentries, "audit_path length", quiet=True) - - calc_root_hash = verify_inclusion_proof(inclusion_proof, leaf_index, sth["tree_size"], leaf_hash) - root_hash = base64.b64decode(sth["sha256_root_hash"]) - - assert_equal(root_hash, calc_root_hash, "verified root hash", nodata=True, quiet=True) - get_and_check_entry(timestamp, chain, leaf_index, baseurl) - -def get_and_validate_consistency_proof(sth1, sth2, size1, size2, baseurl): - consistency_proof = [base64.decodestring(entry) for entry in get_consistency_proof(baseurl, size1, size2)] - (old_treehead, new_treehead) = verify_consistency_proof(consistency_proof, size1, size2, sth1) - #print repr(sth1), repr(old_treehead) - #print repr(sth2), repr(new_treehead) - assert_equal(old_treehead, sth1, "sth1", nodata=True, quiet=True) - assert_equal(new_treehead, sth2, "sth2", nodata=True, quiet=True) - - -def get_and_check_entry(timestamp, chain, leaf_index, baseurl): - entries = get_entries(baseurl, leaf_index, leaf_index) - assert_equal(len(entries), 1, "get_entries", quiet=True) - fetched_entry = entries["entries"][0] - merkle_tree_leaf = pack_mtl(timestamp, chain[0]) - leaf_input = base64.decodestring(fetched_entry["leaf_input"]) - assert_equal(leaf_input, merkle_tree_leaf, "entry", nodata=True, quiet=True) - extra_data = base64.decodestring(fetched_entry["extra_data"]) - certchain = decode_certificate_chain(extra_data) - - submittedcertchain = chain[1:] - - for (submittedcert, fetchedcert, i) in zip(submittedcertchain, - certchain, itertools.count(1)): - assert_equal(fetchedcert, submittedcert, "cert %d in chain" % (i,), quiet=True) - - if len(certchain) == len(submittedcertchain) + 1: - last_issuer = get_cert_info(submittedcertchain[-1])["issuer"] - root_subject = get_cert_info(certchain[-1])["subject"] - if last_issuer == root_subject: - print_success("fetched chain has an appended root cert") - else: - print_error("fetched chain has an extra entry") - elif len(certchain) == len(submittedcertchain): - print_success("cert chains are the same length") - else: - print_error("cert chain length %d expected %d or %d", - len(certchain), - len(submittedcertchain), - len(submittedcertchain)) - -def merge(): - return subprocess.call(["../tools/merge.py", "--config", "../test/catlfish-test.cfg", - "--localconfig", "../test/catlfish-test-local-merge.cfg"]) - -mergeresult = merge() -assert_equal(mergeresult, 0, "merge", quiet=True, fatal=True) - -for baseurl in baseurls: - print_and_check_tree_size(0, baseurl) - -testgroup("cert1") - -result1 = do_add_chain(cc1, baseurls[0]) - -mergeresult = merge() -assert_equal(mergeresult, 0, "merge", quiet=True, fatal=True) - -size_sth = {} - -for baseurl in baseurls: - print_and_check_tree_size(1, baseurl) -size_sth[1] = base64.b64decode(get_sth(baseurls[0])["sha256_root_hash"]) - -result2 = do_add_chain(cc1, baseurls[0]) - -assert_equal(result2["timestamp"], result1["timestamp"], "timestamp") - -mergeresult = merge() -assert_equal(mergeresult, 0, "merge", quiet=True, fatal=True) - -for baseurl in baseurls: - print_and_check_tree_size(1, baseurl) -size1_v2_sth = base64.b64decode(get_sth(baseurls[0])["sha256_root_hash"]) - -assert_equal(size_sth[1], size1_v2_sth, "sth", nodata=True) - -# TODO: add invalid cert and check that it generates an error -# and that treesize still is 1 - -get_and_validate_proof(result1["timestamp"], cc1, 0, 0, baseurls[0]) - -testgroup("cert2") - -result3 = do_add_chain(cc2, baseurls[0]) - -mergeresult = merge() -assert_equal(mergeresult, 0, "merge", quiet=True, fatal=True) - -for baseurl in baseurls: - print_and_check_tree_size(2, baseurl) -size_sth[2] = base64.b64decode(get_sth(baseurls[0])["sha256_root_hash"]) - -get_and_validate_proof(result1["timestamp"], cc1, 0, 1, baseurls[0]) -get_and_validate_proof(result3["timestamp"], cc2, 1, 1, baseurls[0]) - -testgroup("cert3") - -result4 = do_add_chain(cc3, baseurls[0]) - -mergeresult = merge() -assert_equal(mergeresult, 0, "merge", quiet=True, fatal=True) - -for baseurl in baseurls: - print_and_check_tree_size(3, baseurl) -size_sth[3] = base64.b64decode(get_sth(baseurls[0])["sha256_root_hash"]) - -get_and_validate_proof(result1["timestamp"], cc1, 0, 2, baseurls[0]) -get_and_validate_proof(result3["timestamp"], cc2, 1, 2, baseurls[0]) -get_and_validate_proof(result4["timestamp"], cc3, 2, 1, baseurls[0]) - -testgroup("cert4") - -result5 = do_add_chain(cc4, baseurls[0]) - -mergeresult = merge() -assert_equal(mergeresult, 0, "merge", quiet=True, fatal=True) - -for baseurl in baseurls: - print_and_check_tree_size(4, baseurl) -size_sth[4] = base64.b64decode(get_sth(baseurls[0])["sha256_root_hash"]) - -get_and_validate_proof(result1["timestamp"], cc1, 0, 2, baseurls[0]) -get_and_validate_proof(result3["timestamp"], cc2, 1, 2, baseurls[0]) -get_and_validate_proof(result4["timestamp"], cc3, 2, 2, baseurls[0]) -get_and_validate_proof(result5["timestamp"], cc4, 3, 2, baseurls[0]) - -testgroup("cert5") - -result6 = do_add_chain(cc5, baseurls[0]) - -mergeresult = merge() -assert_equal(mergeresult, 0, "merge", quiet=True, fatal=True) - -for baseurl in baseurls: - print_and_check_tree_size(5, baseurl) -size_sth[5] = base64.b64decode(get_sth(baseurls[0])["sha256_root_hash"]) - -get_and_validate_proof(result1["timestamp"], cc1, 0, 3, baseurls[0]) -get_and_validate_proof(result3["timestamp"], cc2, 1, 3, baseurls[0]) -get_and_validate_proof(result4["timestamp"], cc3, 2, 3, baseurls[0]) -get_and_validate_proof(result5["timestamp"], cc4, 3, 3, baseurls[0]) -get_and_validate_proof(result6["timestamp"], cc5, 4, 1, baseurls[0]) - -mergeresult = merge() -assert_equal(mergeresult, 0, "merge", quiet=True, fatal=True) - -for first_size in range(1, 5): - for second_size in range(first_size + 1, 6): - get_and_validate_consistency_proof(size_sth[first_size], size_sth[second_size], first_size, second_size, baseurls[0]) - -print "-------" -if failures: - print failures, "failed tests" if failures != 1 else "failed test" - sys.exit(1) -else: - print "all tests succeeded" diff --git a/tools/testcerts/cert1.txt b/tools/testcerts/cert1.txt deleted file mode 100644 index 4871b22..0000000 --- a/tools/testcerts/cert1.txt +++ /dev/null @@ -1,86 +0,0 @@ -CONNECTED(00000003) ---- -Certificate chain - 0 s:/C=SE/2.5.4.17=114 27/ST=Stockholms l\xC3\xA4n/L=Stockholm/2.5.4.9=Valhallav\xC3\xA4gen 79/O=Kungliga Tekniska H\xC3\xB6gskolan/OU=ITA/CN=ns-vip-01.sys.kth.se - i:/C=NL/O=TERENA/CN=TERENA SSL CA ------BEGIN CERTIFICATE----- -MIIFBTCCA+2gAwIBAgIRAN/MrgvfgxMmWUPdGv/VYEgwDQYJKoZIhvcNAQEFBQAw -NjELMAkGA1UEBhMCTkwxDzANBgNVBAoTBlRFUkVOQTEWMBQGA1UEAxMNVEVSRU5B -IFNTTCBDQTAeFw0xNDA3MDMwMDAwMDBaFw0xNzA3MDIyMzU5NTlaMIG8MQswCQYD -VQQGEwJTRTEPMA0GA1UEERMGMTE0IDI3MRgwFgYDVQQIDA9TdG9ja2hvbG1zIGzD -pG4xEjAQBgNVBAcTCVN0b2NraG9sbTEaMBgGA1UECQwRVmFsaGFsbGF2w6RnZW4g -NzkxJTAjBgNVBAoMHEt1bmdsaWdhIFRla25pc2thIEjDtmdza29sYW4xDDAKBgNV -BAsTA0lUQTEdMBsGA1UEAxMUbnMtdmlwLTAxLnN5cy5rdGguc2UwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCmIUMi8T6Mf+ku/h7d0bYsi8/oKySKTpkS -rzeAbuUNhmnT+VTMvb2w538KcPKnOhFGFRF3Lzfa1j70vKuLWbfLqQHOXa0Yq0zb -mvVNFH9Uthtpmv7uj5o8uK7kTSNF2FzaWnm3gg6QckxYAAS1eG9wjRvfSSSwzbw0 -e/y3tvhN+vxerzZX8oiY4dFWmtmPRf9xE18LkQus41AJPLH+4SCXbpuJn4Vo3kTk -rZp2MZo4bZ6PB/y257FowNOokkQG/Qg6wOX+9WW/zHCj8RqofaEhmpgtVyOklgJk -DTLN8Z8869Zo+Nt2TeDyPWRr+IxFSVZCXAnEL0qCMYDrHAzZKJkDAgMBAAGjggGF -MIIBgTAfBgNVHSMEGDAWgBQMvZNoDPPeq6NJays3V0fqkOO57TAdBgNVHQ4EFgQU -3BVAdQu5ifzshxwoM7LxZfO3KnEwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQC -MAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMCIGA1UdIAQbMBkwDQYL -KwYBBAGyMQECAh0wCAYGZ4EMAQICMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9j -cmwudGNzLnRlcmVuYS5vcmcvVEVSRU5BU1NMQ0EuY3JsMG0GCCsGAQUFBwEBBGEw -XzA1BggrBgEFBQcwAoYpaHR0cDovL2NydC50Y3MudGVyZW5hLm9yZy9URVJFTkFT -U0xDQS5jcnQwJgYIKwYBBQUHMAGGGmh0dHA6Ly9vY3NwLnRjcy50ZXJlbmEub3Jn -MDMGA1UdEQQsMCqCFG5zLXZpcC0wMS5zeXMua3RoLnNlggZrdGguc2WCCnd3dy5r -dGguc2UwDQYJKoZIhvcNAQEFBQADggEBAK7O5ycJffAYElE0wXYDyRIakFWHbouO -0l9D+npPMz8pKzIeLEZ46/sCK9E+Nd3AkCIpL0hZftlSKsDg3mppAgMhMLn2/Tux -HelMlEqdwN7/7fiNPGzsBYu4fBqpGddbI69RWf/1JzR2Xeo76kQ6UCwg3EirYfw7 -zpeV81ct9fxYcFEyabiG18l7hmYEm/3SeKeRDcYWauk+hB/kg7lzCJ2qZFIk/sQM -EEmI7JvoNuAfrWYwfr9hG39CawNQ0beGnlAAKxJeU2IC1Sbl9ccBu1JFRcsMRTr+ -Y8IfG+gNlh5a/vDJ98MnSJZp8QZo1TXDinEk+2tSHVR5iin1oOH1D60= ------END CERTIFICATE----- - 1 s:/C=NL/O=TERENA/CN=TERENA SSL CA - i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware ------BEGIN CERTIFICATE----- -MIIEmDCCA4CgAwIBAgIQS8gUAy8H+mqk8Nop32F5ujANBgkqhkiG9w0BAQUFADCB -lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt -SGFyZHdhcmUwHhcNMDkwNTE4MDAwMDAwWhcNMjAwNTMwMTA0ODM4WjA2MQswCQYD -VQQGEwJOTDEPMA0GA1UEChMGVEVSRU5BMRYwFAYDVQQDEw1URVJFTkEgU1NMIENB -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+NIxC9cwcupmf0booNd -ij2tOtDipEMfTQ7+NSUwpWkbxOjlwY9UfuFqoppcXN49/ALOlrhfj4NbzGBAkPjk -tjolnF8UUeyx56+eUKExVccCvaxSin81joL6hK0V/qJ/gxA6VVOULAEWdJRUYyij -8lspPZSIgCDiFFkhGbSkmOFg5vLrooCDQ+CtaPN5GYtoQ1E/iptBhQw1jF218bbl -p8ODtWsjb9Sl61DllPFKX+4nSxQSFSRMDc9ijbcAIa06Mg9YC18em9HfnY6pGTVQ -L0GprTvG4EWyUzl/Ib8iGodcNK5Sbwd9ogtOnyt5pn0T3fV/g3wvWl13eHiRoBS/ -fQIDAQABo4IBPjCCATowHwYDVR0jBBgwFoAUoXJfJhsomEOVXQc31YWWnUvSw0Uw -HQYDVR0OBBYEFAy9k2gM896ro0lrKzdXR+qQ47ntMA4GA1UdDwEB/wQEAwIBBjAS -BgNVHRMBAf8ECDAGAQH/AgEAMBgGA1UdIAQRMA8wDQYLKwYBBAGyMQECAh0wRAYD -VR0fBD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VS -Rmlyc3QtSGFyZHdhcmUuY3JsMHQGCCsGAQUFBwEBBGgwZjA9BggrBgEFBQcwAoYx -aHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VUTkFkZFRydXN0U2VydmVyX0NBLmNy -dDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG -9w0BAQUFAAOCAQEATiPuSJz2hYtxxApuc5NywDqOgIrZs8qy1AGcKM/yXA4hRJML -thoh45gBlA5nSYEevj0NTmDa76AxTpXv8916WoIgQ7ahY0OzUGlDYktWYrA0irkT -Q1mT7BR5iPNIk+idyfqHcgxrVqDDFY1opYcfcS3mWm08aXFABFXcoEOUIEU4eNe9 -itg5xt8Jt1qaqQO4KBB4zb8BG1oRPjj02Bs0ec8z0gH9rJjNbUcRkEy7uVvYcOfV -r7bMxIbmdcCeKbYrDyqlaQIN4+mitF3A884saoU4dmHGSYKrUbOCprlBmCiY+2v+ -ihb/MX5UR6g83EMmqZsFt57ANEORMNQywxFa4Q== ------END CERTIFICATE----- ---- -Server certificate -subject=/C=SE/2.5.4.17=114 27/ST=Stockholms l\xC3\xA4n/L=Stockholm/2.5.4.9=Valhallav\xC3\xA4gen 79/O=Kungliga Tekniska H\xC3\xB6gskolan/OU=ITA/CN=ns-vip-01.sys.kth.se -issuer=/C=NL/O=TERENA/CN=TERENA SSL CA ---- -No client certificate CA names sent ---- -SSL handshake has read 2608 bytes and written 452 bytes ---- -New, TLSv1/SSLv3, Cipher is RC4-MD5 -Server public key is 2048 bit -SSL-Session: - Protocol : TLSv1 - Cipher : RC4-MD5 - Session-ID: 1CB6F52D821C229181597FA36C61A4DAB2AB0330A5157E1C8094AA73D475C123 - Session-ID-ctx: - Master-Key: E01E6B7F470205A7BAE7CCB5290A57E59DE52D822E5AFC5BFFC1DD28C5CA9D4D55CD2308CCB7E302641BF5B352E6AB11 - Key-Arg : None - Krb5 Principal: None - Start Time: 1406768584 - Timeout : 300 (sec) - Verify return code: 20 (unable to get local issuer certificate) ---- diff --git a/tools/testcerts/cert2.txt b/tools/testcerts/cert2.txt deleted file mode 100644 index 011caf5..0000000 --- a/tools/testcerts/cert2.txt +++ /dev/null @@ -1,138 +0,0 @@ -CONNECTED(00000003) ---- -Certificate chain - 0 s:/C=SE/O=Kungliga Tekniska H\xC3\xB6gskolan/OU=ITA/CN=www.lan.kth.se - i:/C=NL/O=TERENA/CN=TERENA SSL CA ------BEGIN CERTIFICATE----- -MIIEfzCCA2egAwIBAgIRALtnWx1jbyJqNiquRFaHsxwwDQYJKoZIhvcNAQEFBQAw -NjELMAkGA1UEBhMCTkwxDzANBgNVBAoTBlRFUkVOQTEWMBQGA1UEAxMNVEVSRU5B -IFNTTCBDQTAeFw0xMzAxMTYwMDAwMDBaFw0xNjAxMTYyMzU5NTlaMFsxCzAJBgNV -BAYTAlNFMSUwIwYDVQQKDBxLdW5nbGlnYSBUZWtuaXNrYSBIw7Znc2tvbGFuMQww -CgYDVQQLEwNJVEExFzAVBgNVBAMTDnd3dy5sYW4ua3RoLnNlMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2fC9NwlmMN9ja8S9sMRdPXTY9XMutGDbVStq -VQbflK1A4Ap3ODAEIsTFz1xn5OvrxSPFyphbDwNDlfvnB9lWQQvG6EZ003zExbiY -g2WrUk74IsGEgvjw3u+1DIRJCO/mKXlg1a/8wkzINXvnra+yTMDO8VLmiLmUrvn+ -yYi8gr7ekUgFr+3rm9J25tfHyan9p15RMcI//WQTfjq3X/EnyImOiZpMyh0OjSif -LnwHrE0M3grivYP6PZN3mJjKJNFGL9zh5S/Wt4Q65t9wXhO5oAkDA9XS6bk1yOv2 -V81qRANaBdP/ieHghko2UV/mGeHeJhHYB02XFg5mpxxIndBcxwIDAQABo4IBYTCC -AV0wHwYDVR0jBBgwFoAUDL2TaAzz3qujSWsrN1dH6pDjue0wHQYDVR0OBBYEFDAA -juxftrwLBCSto5PE6PBYMX1RMA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAA -MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAYBgNVHSAEETAPMA0GCysG -AQQBsjEBAgIdMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly9jcmwudGNzLnRlcmVu -YS5vcmcvVEVSRU5BU1NMQ0EuY3JsMG0GCCsGAQUFBwEBBGEwXzA1BggrBgEFBQcw -AoYpaHR0cDovL2NydC50Y3MudGVyZW5hLm9yZy9URVJFTkFTU0xDQS5jcnQwJgYI -KwYBBQUHMAGGGmh0dHA6Ly9vY3NwLnRjcy50ZXJlbmEub3JnMBkGA1UdEQQSMBCC -Dnd3dy5sYW4ua3RoLnNlMA0GCSqGSIb3DQEBBQUAA4IBAQCrfiHdIwVEVO1HwZXb -Hi5KsOFDcHS+MH5tvo2Cj6uXzDOMFWSoLm31MR4TK55Hzz7oMkpO+rxchqpvoUtl -m2ma9phntzvCppeOcob2dZt6lyqzg4uIxlgV6ucULQ27KlwGZPAp46ZdK1M3qVMR -gQ2kOXc0wMAKFXu4qvrj2JsWFnZKn233Cg2iS6ixDjqZvSxzC23buhN48dzCdYI/ -mWaisULtkd95O+WhtQPp5tP5QqGmwGoM6+Q1StOo4068CG1TRDoQWnjVHHt5yU2O -gG3YSEwpMe/FJS4UcojdAkWewbv4ArP72/LEBkqubicFib6ALkQ7WfuUf8XN4Ky3 -vVwW ------END CERTIFICATE----- - 1 s:/C=NL/O=TERENA/CN=TERENA SSL CA - i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware ------BEGIN CERTIFICATE----- -MIIEmDCCA4CgAwIBAgIQS8gUAy8H+mqk8Nop32F5ujANBgkqhkiG9w0BAQUFADCB -lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt -SGFyZHdhcmUwHhcNMDkwNTE4MDAwMDAwWhcNMjAwNTMwMTA0ODM4WjA2MQswCQYD -VQQGEwJOTDEPMA0GA1UEChMGVEVSRU5BMRYwFAYDVQQDEw1URVJFTkEgU1NMIENB -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+NIxC9cwcupmf0booNd -ij2tOtDipEMfTQ7+NSUwpWkbxOjlwY9UfuFqoppcXN49/ALOlrhfj4NbzGBAkPjk -tjolnF8UUeyx56+eUKExVccCvaxSin81joL6hK0V/qJ/gxA6VVOULAEWdJRUYyij -8lspPZSIgCDiFFkhGbSkmOFg5vLrooCDQ+CtaPN5GYtoQ1E/iptBhQw1jF218bbl -p8ODtWsjb9Sl61DllPFKX+4nSxQSFSRMDc9ijbcAIa06Mg9YC18em9HfnY6pGTVQ -L0GprTvG4EWyUzl/Ib8iGodcNK5Sbwd9ogtOnyt5pn0T3fV/g3wvWl13eHiRoBS/ -fQIDAQABo4IBPjCCATowHwYDVR0jBBgwFoAUoXJfJhsomEOVXQc31YWWnUvSw0Uw -HQYDVR0OBBYEFAy9k2gM896ro0lrKzdXR+qQ47ntMA4GA1UdDwEB/wQEAwIBBjAS -BgNVHRMBAf8ECDAGAQH/AgEAMBgGA1UdIAQRMA8wDQYLKwYBBAGyMQECAh0wRAYD -VR0fBD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VS -Rmlyc3QtSGFyZHdhcmUuY3JsMHQGCCsGAQUFBwEBBGgwZjA9BggrBgEFBQcwAoYx -aHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VUTkFkZFRydXN0U2VydmVyX0NBLmNy -dDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG -9w0BAQUFAAOCAQEATiPuSJz2hYtxxApuc5NywDqOgIrZs8qy1AGcKM/yXA4hRJML -thoh45gBlA5nSYEevj0NTmDa76AxTpXv8916WoIgQ7ahY0OzUGlDYktWYrA0irkT -Q1mT7BR5iPNIk+idyfqHcgxrVqDDFY1opYcfcS3mWm08aXFABFXcoEOUIEU4eNe9 -itg5xt8Jt1qaqQO4KBB4zb8BG1oRPjj02Bs0ec8z0gH9rJjNbUcRkEy7uVvYcOfV -r7bMxIbmdcCeKbYrDyqlaQIN4+mitF3A884saoU4dmHGSYKrUbOCprlBmCiY+2v+ -ihb/MX5UR6g83EMmqZsFt57ANEORMNQywxFa4Q== ------END CERTIFICATE----- - 2 s:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware - i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root ------BEGIN CERTIFICATE----- -MIIEPDCCAySgAwIBAgIQSEus8arH1xND0aJ0NUmXJTANBgkqhkiG9w0BAQUFADBv -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk -ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF -eHRlcm5hbCBDQSBSb290MB4XDTA1MDYwNzA4MDkxMFoXDTIwMDUzMDEwNDgzOFow -gZcxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtl -IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMY -aHR0cDovL3d3dy51c2VydHJ1c3QuY29tMR8wHQYDVQQDExZVVE4tVVNFUkZpcnN0 -LUhhcmR3YXJlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsffDOD+0 -qH/POYJRZ9Btn9L/WPPnnyvsDYlUmbk4mRb34CF5SMK7YXQSlh08anLVPBBnOjnt -KxPNZuuVCTOkbJex6MbswXV5nEZejavQav25KlUXEFSzGfCa9vGxXbanbfvgcRdr -ooj7AN/+GjF3DJoBerEy4ysBBzhuw6VeI7xFm3tQwckwj9vlK3rTW/szQB6g1ZgX -vIuHw4nTXaCOsqqq9o5piAbF+okh8widaS4JM5spDUYPjMxJNLBpUb35Bs1orWZM -vD6sYb0KiA7I3z3ufARMnQpea5HW7sftKI2rTYeJc9BupNAeFosU4XZEA39jrOTN -SZzFkvSrMqFIWwIDAQABo4GqMIGnMB8GA1UdIwQYMBaAFK29mHo0tCb3+sQmVO8D -veAky1QaMB0GA1UdDgQWBBShcl8mGyiYQ5VdBzfVhZadS9LDRTAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8v -Y3JsLnVzZXJ0cnVzdC5jb20vQWRkVHJ1c3RFeHRlcm5hbENBUm9vdC5jcmwwDQYJ -KoZIhvcNAQEFBQADggEBADzse+Cuow6WbTDXhcbSaFtFWoKmNA+wyZIjXhFtCBGy -dAkjOjUlc1heyrl8KPpH7PmgA1hQtlPvjNs55Gfp2MooRtSn4PU4dfjny1y/HRE8 -akCbLURW0/f/BSgyDBXIZEWT6CEkjy3aeoR7T8/NsiV8dxDTlNEEkaglHAkiD31E -NREU768A/l7qX46w2ZJZuvwTlqAYAVbO2vYoC7Gv3VxPXLLzj1pxz+0YrWOIHY6V -9+qV5x+tkLiECEeFfyIvGh1IMNZMCNg3GWcyK+tc0LL8blefBDVekAB+EcfeEyrN -pG1FJseIVqDwavfY5/wnfmcI0L36tsNhAgFlubgvz1o= ------END CERTIFICATE----- - 3 s:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root - i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root ------BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs -IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 -MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux -FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h -bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v -dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt -H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 -uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX -mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX -a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN -E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 -WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD -VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 -Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU -cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx -IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN -AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH -YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC -Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX -c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a -mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= ------END CERTIFICATE----- ---- -Server certificate -subject=/C=SE/O=Kungliga Tekniska H\xC3\xB6gskolan/OU=ITA/CN=www.lan.kth.se -issuer=/C=NL/O=TERENA/CN=TERENA SSL CA ---- -No client certificate CA names sent ---- -SSL handshake has read 5205 bytes and written 340 bytes ---- -New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA -Server public key is 2048 bit -SSL-Session: - Protocol : TLSv1 - Cipher : DHE-RSA-AES256-SHA - Session-ID: 6389C01938F30B55DE1970773DAF16F5F0577712DCC25140FC5B09E60712DF4C - Session-ID-ctx: - Master-Key: 0ABCD607E10E921BDF9D0D5439972F8789517C18318AF2FA5CEFF7F45A74F246C27D25ED9E6CE97500156803DA037BDA - Key-Arg : None - Krb5 Principal: None - Start Time: 1411388821 - Timeout : 300 (sec) - Verify return code: 19 (self signed certificate in certificate chain) ---- diff --git a/tools/testcerts/cert3.txt b/tools/testcerts/cert3.txt deleted file mode 100644 index a776b58..0000000 --- a/tools/testcerts/cert3.txt +++ /dev/null @@ -1,108 +0,0 @@ -CONNECTED(00000003) ---- -Certificate chain - 0 s:/OU=Domain Control Validated/CN=*.nordu.net - i:/C=NL/O=TERENA/CN=TERENA SSL CA - 1 s:/C=NL/O=TERENA/CN=TERENA SSL CA - i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware - 2 s:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware - i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root ---- -Server certificate ------BEGIN CERTIFICATE----- -MIIEZDCCA0ygAwIBAgIRALmfsKN7LvrBTlo9bsrluT0wDQYJKoZIhvcNAQEFBQAw -NjELMAkGA1UEBhMCTkwxDzANBgNVBAoTBlRFUkVOQTEWMBQGA1UEAxMNVEVSRU5B -IFNTTCBDQTAeFw0xMzAzMjEwMDAwMDBaFw0xNjA0MDIyMzU5NTlaMDkxITAfBgNV -BAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRlZDEUMBIGA1UEAxQLKi5ub3JkdS5u -ZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQClir/sHXJpaMQ8SpK1 -giyizJhK9GSuZkoTaIKiK2hXkHUbxJ09w6pspWXPbUwLK8ZFn32vHMabshKxe4fL -d0kR/AEr9okwfnABK7+u4CBEs10D2oVrRFS2GFAUtri8v+5+n/mWDoqGc2XybQNs -CoYyVdSYs6YO/+b8dEGfOrRD2XFoTtP32T35YIlejwpg72f9lUnvOi6Jh+s6jV8P -hIJV6w3exVQojDiEPSQ3fV/KF6FAaQK4XyEspHL4TH0mtaJhEjnAvHDmN1Bw4WhV -0Bm86alryZxYNTmpPXDD5AFNBIuL+5FfQgZm+s7QzZriguRGDv8L+YKePFvhiaPV -AagTAgMBAAGjggFoMIIBZDAfBgNVHSMEGDAWgBQMvZNoDPPeq6NJays3V0fqkOO5 -7TAdBgNVHQ4EFgQU6YkL0qj0tSK5bsZfjDUNLwXUlFgwDgYDVR0PAQH/BAQDAgWg -MAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMCIG -A1UdIAQbMBkwDQYLKwYBBAGyMQECAh0wCAYGZ4EMAQIBMDoGA1UdHwQzMDEwL6At -oCuGKWh0dHA6Ly9jcmwudGNzLnRlcmVuYS5vcmcvVEVSRU5BU1NMQ0EuY3JsMG0G -CCsGAQUFBwEBBGEwXzA1BggrBgEFBQcwAoYpaHR0cDovL2NydC50Y3MudGVyZW5h -Lm9yZy9URVJFTkFTU0xDQS5jcnQwJgYIKwYBBQUHMAGGGmh0dHA6Ly9vY3NwLnRj -cy50ZXJlbmEub3JnMBYGA1UdEQQPMA2CCyoubm9yZHUubmV0MA0GCSqGSIb3DQEB -BQUAA4IBAQAdj2R0qT47oLIMnYw69qU58VZB/rnejwhNVdzLtLZ+vQ1YwcXoabOi -9LmSOZ019ESWxZ415/FjvoLXYKpkq8w96bDw/jqPhUWwK2U6EpD/MlYUKWyAH9XP -ZLBaYewZEBjkwxYIlroUboPWXUYJIDwotvNgSE9N8Xy1XZ4oi0UVfxxyo3XRpS49 -Ch1az16jKS5rF5R1Q/t6UxYrnfx4XMZHFx56ks6kpucxch37JJ/2i1O84/T9lX17 -7qwk+SO93EmtgxE40wtvL1i2cTZaNHcybyClV6N3Bm8Hu2L4e35SF761CMc4rzlu -SbDmRK4Rxa5UmgfZnezD0snHVUCrzKzP ------END CERTIFICATE----- -subject=/OU=Domain Control Validated/CN=*.nordu.net -issuer=/C=NL/O=TERENA/CN=TERENA SSL CA ---- - -Manually added intermediate certificate: ------BEGIN CERTIFICATE----- -MIIEmDCCA4CgAwIBAgIQS8gUAy8H+mqk8Nop32F5ujANBgkqhkiG9w0BAQUFADCB -lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt -SGFyZHdhcmUwHhcNMDkwNTE4MDAwMDAwWhcNMjAwNTMwMTA0ODM4WjA2MQswCQYD -VQQGEwJOTDEPMA0GA1UEChMGVEVSRU5BMRYwFAYDVQQDEw1URVJFTkEgU1NMIENB -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+NIxC9cwcupmf0booNd -ij2tOtDipEMfTQ7+NSUwpWkbxOjlwY9UfuFqoppcXN49/ALOlrhfj4NbzGBAkPjk -tjolnF8UUeyx56+eUKExVccCvaxSin81joL6hK0V/qJ/gxA6VVOULAEWdJRUYyij -8lspPZSIgCDiFFkhGbSkmOFg5vLrooCDQ+CtaPN5GYtoQ1E/iptBhQw1jF218bbl -p8ODtWsjb9Sl61DllPFKX+4nSxQSFSRMDc9ijbcAIa06Mg9YC18em9HfnY6pGTVQ -L0GprTvG4EWyUzl/Ib8iGodcNK5Sbwd9ogtOnyt5pn0T3fV/g3wvWl13eHiRoBS/ -fQIDAQABo4IBPjCCATowHwYDVR0jBBgwFoAUoXJfJhsomEOVXQc31YWWnUvSw0Uw -HQYDVR0OBBYEFAy9k2gM896ro0lrKzdXR+qQ47ntMA4GA1UdDwEB/wQEAwIBBjAS -BgNVHRMBAf8ECDAGAQH/AgEAMBgGA1UdIAQRMA8wDQYLKwYBBAGyMQECAh0wRAYD -VR0fBD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VS -Rmlyc3QtSGFyZHdhcmUuY3JsMHQGCCsGAQUFBwEBBGgwZjA9BggrBgEFBQcwAoYx -aHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VUTkFkZFRydXN0U2VydmVyX0NBLmNy -dDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG -9w0BAQUFAAOCAQEATiPuSJz2hYtxxApuc5NywDqOgIrZs8qy1AGcKM/yXA4hRJML -thoh45gBlA5nSYEevj0NTmDa76AxTpXv8916WoIgQ7ahY0OzUGlDYktWYrA0irkT -Q1mT7BR5iPNIk+idyfqHcgxrVqDDFY1opYcfcS3mWm08aXFABFXcoEOUIEU4eNe9 -itg5xt8Jt1qaqQO4KBB4zb8BG1oRPjj02Bs0ec8z0gH9rJjNbUcRkEy7uVvYcOfV -r7bMxIbmdcCeKbYrDyqlaQIN4+mitF3A884saoU4dmHGSYKrUbOCprlBmCiY+2v+ -ihb/MX5UR6g83EMmqZsFt57ANEORMNQywxFa4Q== ------END CERTIFICATE----- - -No client certificate CA names sent ---- -SSL handshake has read 4093 bytes and written 434 bytes ---- -New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384 -Server public key is 2048 bit -Secure Renegotiation IS supported -Compression: NONE -Expansion: NONE -SSL-Session: - Protocol : TLSv1.2 - Cipher : ECDHE-RSA-AES256-GCM-SHA384 - Session-ID: 1A247C94557A7847AA13E2EFD64ECE3C2DD142B15ABB7BF78BFE43F28BB2C144 - Session-ID-ctx: - Master-Key: D714373C285767FD040C497DFA59C81AA43BCF62AB9199F5FAB2C34211F7FB767922047DD758441C5493B238E716B477 - Key-Arg : None - PSK identity: None - PSK identity hint: None - SRP username: None - TLS session ticket lifetime hint: 300 (seconds) - TLS session ticket: - 0000 - 7d 26 51 e1 11 16 18 15-b2 1c 21 51 10 10 f0 0d }&Q.......!Q.... - 0010 - 29 f5 24 13 c8 a5 dd 34-87 c1 36 6a 97 12 cc f3 ).$....4..6j.... - 0020 - e4 bb 50 db 39 94 3b b3-8e 52 df 73 89 a2 30 91 ..P.9.;..R.s..0. - 0030 - 4e a5 8c 80 97 49 79 0f-ce a9 1a eb a8 a0 2d fa N....Iy.......-. - 0040 - 53 90 fe f1 29 1b 43 5d-09 cc 6c 81 de f8 41 e7 S...).C]..l...A. - 0050 - dc c3 57 b5 66 e0 03 2b-fd e7 82 5b b6 c4 6a fe ..W.f..+...[..j. - 0060 - 15 55 55 cd ea af a6 b8-c5 80 2f c8 2d dd bf a0 .UU......./.-... - 0070 - 1b 23 4c 60 67 70 1c 39-2c 9a 39 1d e0 a4 f7 c0 .#L`gp.9,.9..... - 0080 - 6e c9 8b 59 c2 cc 2b 12-ee 5d 8f 8c 4a 8e ab 07 n..Y..+..]..J... - 0090 - 9e be d3 89 9d c1 1e 17-a5 65 19 41 14 63 32 62 .........e.A.c2b - 00a0 - ce 51 ce ee c0 0c 01 49-b0 0b da 41 29 67 21 e0 .Q.....I...A)g!. - 00b0 - 2f 77 e2 35 44 35 ba 78-47 fc 3c 11 24 57 8d e3 /w.5D5.xG.<.$W.. - - Start Time: 1411743389 - Timeout : 300 (sec) - Verify return code: 20 (unable to get local issuer certificate) ---- diff --git a/tools/testcerts/cert4.txt b/tools/testcerts/cert4.txt deleted file mode 100644 index 57559e9..0000000 --- a/tools/testcerts/cert4.txt +++ /dev/null @@ -1,120 +0,0 @@ -CONNECTED(00000003) ---- -Certificate chain - 0 s:/businessCategory=Private Organization/1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/serialNumber=3359300/street=16 Allen Rd/postalCode=03894-4801/C=US/ST=NH/L=Wolfeboro,/O=Python Software Foundation/CN=www.python.org - i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA - 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA - i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA ---- -Server certificate ------BEGIN CERTIFICATE----- -MIIG2jCCBcKgAwIBAgIQAbtvABIrF382yrSc6otrJjANBgkqhkiG9w0BAQsFADB1 -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMTQwMgYDVQQDEytEaWdpQ2VydCBTSEEyIEV4dGVuZGVk -IFZhbGlkYXRpb24gU2VydmVyIENBMB4XDTE0MDkwNTAwMDAwMFoXDTE2MDkwOTEy -MDAwMFowgfkxHTAbBgNVBA8TFFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYB -BAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQITCERlbGF3YXJlMRAwDgYDVQQF -EwczMzU5MzAwMRQwEgYDVQQJEwsxNiBBbGxlbiBSZDETMBEGA1UEERMKMDM4OTQt -NDgwMTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk5IMRMwEQYDVQQHEwpXb2xmZWJv -cm8sMSMwIQYDVQQKExpQeXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEXMBUGA1UE -AxMOd3d3LnB5dGhvbi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCtUnfHpOteoIqZxGsaR/2tIenj0+pBtNBiWT6PlYLLXC6MNRjFwtnhRzEVanAm -GEEOEQwUokYZHw8kCL2SIZ1DFI5IIFyhTFql1dqiKtoQse0LAZlUHscVxn9OZyWM -DA4JZ6A4c3/j5SA9hGO3+KyTc95GfiEXqkSkmjH3aBtY2flr+H1fvatQA8AIAD5k -weQLFbbqi33Uvf4sJ3OhY63Kf1ZWteXSeCT+FRMlFTaYbauo86AmU9X2/b85wold -naUO3VjcGjTSoSuaxtWuHFRxpOTBG7bqPbtWk+X5l+rjsIoGJ6ZrRFbAtHqG+S3v -luEG9FtgGAo+3hKm99U8UKKVAgMBAAGjggLfMIIC2zAfBgNVHSMEGDAWgBQ901Cl -1qCt7vNKYApl0yHU+PjWDzAdBgNVHQ4EFgQUTWfmKThuIBhkZX4B3yNf+DpBqokw -ggEUBgNVHREEggELMIIBB4IOd3d3LnB5dGhvbi5vcmeCCnB5dGhvbi5vcmeCD3B5 -cGkucHl0aG9uLm9yZ4IPZG9jcy5weXRob24ub3JnghN0ZXN0cHlwaS5weXRob24u -b3Jngg9idWdzLnB5dGhvbi5vcmeCD3dpa2kucHl0aG9uLm9yZ4INaGcucHl0aG9u -Lm9yZ4IPbWFpbC5weXRob24ub3JnghRwYWNrYWdpbmcucHl0aG9uLm9yZ4IQcHl0 -aG9uaG9zdGVkLm9yZ4IUd3d3LnB5dGhvbmhvc3RlZC5vcmeCFXRlc3QucHl0aG9u -aG9zdGVkLm9yZ4IMdXMucHljb24ub3Jngg1pZC5weXRob24ub3JnMA4GA1UdDwEB -/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYDVR0fBG4w -bDA0oDKgMIYuaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItZXYtc2VydmVy -LWcxLmNybDA0oDKgMIYuaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItZXYt -c2VydmVyLWcxLmNybDBCBgNVHSAEOzA5MDcGCWCGSAGG/WwCATAqMCgGCCsGAQUF -BwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMIGIBggrBgEFBQcBAQR8 -MHowJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBSBggrBgEF -BQcwAoZGaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkV4 -dGVuZGVkVmFsaWRhdGlvblNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqG -SIb3DQEBCwUAA4IBAQBsTgMOFUP8wHVpgCzm/fQTrKp4nxcb9m9gkTW1aRKuhlAY -g/CUQ8DC0Ii1XqOolTmGi6NIyX2Xf+RWqh7UzK+Q30Y2RGGb/47uZaif9WaIlKGn -40D1mzzyGjrfTMSSFlrtwyg/3yM8KN800Cz5HgXnHD2qIuYcYqXRRS6E7PEHB1Dm -h72iCAHYwUTgfcfqUWVEZ26EQhP4Lk4+hs2UJsAUnMWj7/bnk8LR/KZumLuuv3RK -lmR1Qg+9AChafiCCFra1UxfgznvF5ocJzr6nNmYc6k1ImaipRq7c/OuwUTTqNqR2 -FceHmpqlkA2AvjdvSvwnODux3QPbMucIaJXrUUwf ------END CERTIFICATE----- -subject=/businessCategory=Private Organization/1.3.6.1.4.1.311.60.2.1.3=US/1.3.6.1.4.1.311.60.2.1.2=Delaware/serialNumber=3359300/street=16 Allen Rd/postalCode=03894-4801/C=US/ST=NH/L=Wolfeboro,/O=Python Software Foundation/CN=www.python.org -issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA ---- - -Manually added intermediate certificate: ------BEGIN CERTIFICATE----- -MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBW -YWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUY -uD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/ -LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy -/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQh -cJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k -8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYB -Af8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF -BQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp -Z2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2Vy -dC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2 -MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j -b20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAW -gBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbh -hgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg -4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa -2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs -1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1 -oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn -8TUoE6smftX3eg== ------END CERTIFICATE----- - -No client certificate CA names sent ---- -SSL handshake has read 3662 bytes and written 434 bytes ---- -New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 -Server public key is 2048 bit -Secure Renegotiation IS supported -Compression: NONE -Expansion: NONE -SSL-Session: - Protocol : TLSv1.2 - Cipher : ECDHE-RSA-AES128-GCM-SHA256 - Session-ID: 1DE0E69544F8883ADCF023857A02135C5332AB1D514A30DAB522FCF6F23E1DB6 - Session-ID-ctx: - Master-Key: 5959095AB05ED21709F503091DFCEAFDBD8C3ED809DA5BC8886A6E25A7D66D78F8528A20C900F288E77852C311E881EF - Key-Arg : None - PSK identity: None - PSK identity hint: None - SRP username: None - TLS session ticket lifetime hint: 14400 (seconds) - TLS session ticket: - 0000 - 63 cc 77 4a 00 db 2c 42-2e 8f 76 23 dd a9 ae 53 c.wJ..,B..v#...S - 0010 - f0 ac 9f 96 82 bb 06 da-a2 8b 3a 44 cb 66 77 d2 ..........:D.fw. - 0020 - 01 7d 5a b4 0e bd 63 d0-38 f4 86 b4 05 76 68 9f .}Z...c.8....vh. - 0030 - 6f 76 1a 2e 06 93 3d d2-05 7e 0e 57 1a 0d a0 22 ov....=..~.W..." - 0040 - f5 17 e5 1b a7 9d b9 02-95 d8 08 cb 10 31 fb e9 .............1.. - 0050 - 63 26 8c 6e 52 76 cb 7f-64 cc bc c6 43 52 cf 0f c&.nRv..d...CR.. - 0060 - 8e ba 6a 6d b2 30 43 c5-0c 6b 5c 7d 86 90 ad 02 ..jm.0C..k\}.... - 0070 - 8a 71 3b 17 22 ae 4f a6-0e 1b d8 5a fa 86 f1 3c .q;.".O....Z...< - 0080 - c4 bd 56 7d 6d 40 ed 06-f5 12 56 ff 15 ab 39 69 ..V}m@....V...9i - 0090 - 20 21 84 e5 15 ac 52 58-8b 13 d0 f3 db 89 a7 c6 !....RX........ - 00a0 - fd 35 6b ec 94 19 99 e1-cb 28 89 3d aa bb ba 52 .5k......(.=...R - 00b0 - 13 1a 7b c8 39 04 7d cc-49 34 99 52 88 ce ac 8d ..{.9.}.I4.R.... - - Start Time: 1411736151 - Timeout : 300 (sec) - Verify return code: 20 (unable to get local issuer certificate) ---- diff --git a/tools/testcerts/cert5.txt b/tools/testcerts/cert5.txt deleted file mode 100644 index 14af5fd..0000000 --- a/tools/testcerts/cert5.txt +++ /dev/null @@ -1,145 +0,0 @@ -CONNECTED(00000003) ---- -Certificate chain - 0 s:/C=US/ST=California/L=San Francisco/O=Wikimedia Foundation, Inc./CN=*.wikipedia.org - i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3 - 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3 - i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA ---- -Server certificate ------BEGIN CERTIFICATE----- -MIIKMzCCCRugAwIBAgIQDfxZHyWomiN2WUOBQIituTANBgkqhkiG9w0BAQUFADBm -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSUwIwYDVQQDExxEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBDQS0zMB4XDTEyMTAyMjAwMDAwMFoXDTE2MDEyMDEyMDAwMFoweTELMAkGA1UE -BhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lz -Y28xIzAhBgNVBAoTGldpa2ltZWRpYSBGb3VuZGF0aW9uLCBJbmMuMRgwFgYDVQQD -DA8qLndpa2lwZWRpYS5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQDCuToIC6iqulFKeu4DD5l336SonDpCEiVPqSyopch4fm+Zz2Da0KsCROq1AX5K -9kb7WXbSSpnVbXaaDDF/dxD65kD+keNJONqEAVdylW/G16Sa89agTVdgLTjZK2dI -99Q7ws9ijH2psHOUHRJLaJdySLO97OkGwcttd8UGDlCS98A7mN9icvpF4XMl6Oqw -q1/mj624a1BmAzhQaBLPNKsZcJmadACRL7LJ6sNr/SZV1SENlRLHnkmW/c4T2lSp -ikvIyJaOFLlt9J0aqCB+Tb0LwO4gNtrMaJ+fjBBJrMVRtLojrukc/yOdGBlTCx7x -JK5ER9VTf/sb1RViqSKMtSojAgMBAAGjggbIMIIGxDAfBgNVHSMEGDAWgBRQ6nOJ -2yn7EI+e5QEg1N55mUiD9zAdBgNVHQ4EFgQUAouBfESp0dUaQhWaXSogknV7Q3cw -ggObBgNVHREEggOSMIIDjoIPKi53aWtpcGVkaWEub3Jngg13aWtpcGVkaWEub3Jn -gg9tLndpa2lwZWRpYS5vcmeCEnplcm8ud2lraXBlZGlhLm9yZ4IRKi5tLndpa2lw -ZWRpYS5vcmeCDXdpa2lib29rcy5vcmeCD20ud2lraWJvb2tzLm9yZ4IPKi53aWtp -Ym9va3Mub3JnghEqLm0ud2lraWJvb2tzLm9yZ4IMd2lraWRhdGEub3Jngg5tLndp -a2lkYXRhLm9yZ4IOKi53aWtpZGF0YS5vcmeCECoubS53aWtpZGF0YS5vcmeCDXdp -a2ltZWRpYS5vcmeCD20ud2lraW1lZGlhLm9yZ4IPKi53aWtpbWVkaWEub3JnghEq -Lm0ud2lraW1lZGlhLm9yZ4IXd2lraW1lZGlhZm91bmRhdGlvbi5vcmeCGW0ud2lr -aW1lZGlhZm91bmRhdGlvbi5vcmeCGSoud2lraW1lZGlhZm91bmRhdGlvbi5vcmeC -GyoubS53aWtpbWVkaWFmb3VuZGF0aW9uLm9yZ4IMd2lraW5ld3Mub3Jngg5tLndp -a2luZXdzLm9yZ4IOKi53aWtpbmV3cy5vcmeCECoubS53aWtpbmV3cy5vcmeCDXdp -a2lxdW90ZS5vcmeCD20ud2lraXF1b3RlLm9yZ4IPKi53aWtpcXVvdGUub3JnghEq -Lm0ud2lraXF1b3RlLm9yZ4IOd2lraXNvdXJjZS5vcmeCEG0ud2lraXNvdXJjZS5v -cmeCECoud2lraXNvdXJjZS5vcmeCEioubS53aWtpc291cmNlLm9yZ4IPd2lraXZl -cnNpdHkub3JnghFtLndpa2l2ZXJzaXR5Lm9yZ4IRKi53aWtpdmVyc2l0eS5vcmeC -EyoubS53aWtpdmVyc2l0eS5vcmeCDndpa2l2b3lhZ2Uub3JnghBtLndpa2l2b3lh -Z2Uub3JnghAqLndpa2l2b3lhZ2Uub3JnghIqLm0ud2lraXZveWFnZS5vcmeCDndp -a3Rpb25hcnkub3JnghBtLndpa3Rpb25hcnkub3JnghAqLndpa3Rpb25hcnkub3Jn -ghIqLm0ud2lrdGlvbmFyeS5vcmeCDW1lZGlhd2lraS5vcmeCDyoubWVkaWF3aWtp -Lm9yZ4IPbS5tZWRpYXdpa2kub3JnghEqLm0ubWVkaWF3aWtpLm9yZ4IUKi56ZXJv -Lndpa2lwZWRpYS5vcmcwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF -BwMBBggrBgEFBQcDAjBhBgNVHR8EWjBYMCqgKKAmhiRodHRwOi8vY3JsMy5kaWdp -Y2VydC5jb20vY2EzLWcyOC5jcmwwKqAooCaGJGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0 -LmNvbS9jYTMtZzI4LmNybDCCAcQGA1UdIASCAbswggG3MIIBswYJYIZIAYb9bAEB -MIIBpDA6BggrBgEFBQcCARYuaHR0cDovL3d3dy5kaWdpY2VydC5jb20vc3NsLWNw -cy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsGAQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1 -AHMAZQAgAG8AZgAgAHQAaABpAHMAIABDAGUAcgB0AGkAZgBpAGMAYQB0AGUAIABj -AG8AbgBzAHQAaQB0AHUAdABlAHMAIABhAGMAYwBlAHAAdABhAG4AYwBlACAAbwBm -ACAAdABoAGUAIABEAGkAZwBpAEMAZQByAHQAIABDAFAALwBDAFAAUwAgAGEAbgBk -ACAAdABoAGUAIABSAGUAbAB5AGkAbgBnACAAUABhAHIAdAB5ACAAQQBnAHIAZQBl -AG0AZQBuAHQAIAB3AGgAaQBjAGgAIABsAGkAbQBpAHQAIABsAGkAYQBiAGkAbABp -AHQAeQAgAGEAbgBkACAAYQByAGUAIABpAG4AYwBvAHIAcABvAHIAYQB0AGUAZAAg -AGgAZQByAGUAaQBuACAAYgB5ACAAcgBlAGYAZQByAGUAbgBjAGUALjB7BggrBgEF -BQcBAQRvMG0wJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBF -BggrBgEFBQcwAoY5aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 -SGlnaEFzc3VyYW5jZUNBLTMuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEF -BQADggEBAFBllO9JfipPjol+w1hrrwbJ2ZdT1l09ZkjdmvcIhyv54XxaW8NDsjjp -5IIMc28q3JvuERxBnbKiwcrco/JGqwsywTSkYam9pS5ALhP4EXB773cfpYXEeyOC -LyXQgp79CZXe1q5l3DDKtWXRWyuZ8WZw3dd4y8qPJ9JvkIw4ZFgZgo7NV+Fa0HtY -vTe7D68o+EbYdmOLRkxKTEldv7A8f6WAWf5KRFE9dIsQvDD96zTYzdfzOCnonDuz -wJwsJ4BJB8uIs3jFNg05e+6ZrENL/QBEDFe8H09auNHSBuwy4gxEVdfZwgxgrKlf -uMko54p5i2QMvXtvIr/a3Nzlx6CiavI= ------END CERTIFICATE----- -subject=/C=US/ST=California/L=San Francisco/O=Wikimedia Foundation, Inc./CN=*.wikipedia.org -issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3 ---- - -Manually added intermediate certificate: ------BEGIN CERTIFICATE----- -MIIGWDCCBUCgAwIBAgIQCl8RTQNbF5EX0u/UA4w/OzANBgkqhkiG9w0BAQUFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTA4MDQwMjEyMDAwMFoXDTIyMDQwMzAwMDAwMFowZjEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTElMCMGA1UEAxMcRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug -Q0EtMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9hCikQH17+NDdR -CPge+yLtYb4LDXBMUGMmdRW5QYiXtvCgFbsIYOBC6AUpEIc2iihlqO8xB3RtNpcv -KEZmBMcqeSZ6mdWOw21PoF6tvD2Rwll7XjZswFPPAAgyPhBkWBATaccM7pxCUQD5 -BUTuJM56H+2MEb0SqPMV9Bx6MWkBG6fmXcCabH4JnudSREoQOiPkm7YDr6ictFuf -1EutkozOtREqqjcYjbTCuNhcBoz4/yO9NV7UfD5+gw6RlgWYw7If48hl66l7XaAs -zPw82W3tzPpLQ4zJ1LilYRyyQLYoEt+5+F/+07LJ7z20Hkt8HEyZNp496+ynaF4d -32duXvsCAwEAAaOCAvowggL2MA4GA1UdDwEB/wQEAwIBhjCCAcYGA1UdIASCAb0w -ggG5MIIBtQYLYIZIAYb9bAEDAAIwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3 -LmRpZ2ljZXJ0LmNvbS9zc2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUH -AgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQBy -AHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBj -AGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAg -AEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQ -AGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBt -AGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBj -AG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBl -AHIAZQBuAGMAZQAuMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYIKwYBBQUHAQEEKDAm -MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wgY8GA1UdHwSB -hzCBhDBAoD6gPIY6aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0SGln -aEFzc3VyYW5jZUVWUm9vdENBLmNybDBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNl -cnQuY29tL0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDAfBgNVHSME -GDAWgBSxPsNpA/i/RwHUmCYaCALvY2QrwzAdBgNVHQ4EFgQUUOpzidsp+xCPnuUB -INTeeZlIg/cwDQYJKoZIhvcNAQEFBQADggEBAB7ipUiebNtTOA/vphoqrOIDQ+2a -vD6OdRvw/S4iWawTwGHi5/rpmc2HCXVUKL9GYNy+USyS8xuRfDEIcOI3ucFbqL2j -CwD7GhX9A61YasXHJJlIR0YxHpLvtF9ONMeQvzHB+LGEhtCcAarfilYGzjrpDq6X -dF3XcZpCdF/ejUN83ulV7WkAywXgemFhM9EZTfkI7qA5xSU1tyvED7Ld8aW3DiTE -JiiNeXf1L/BXunwH1OH8zVowV36GEEfdMR/X/KLCvzB8XSSq6PmuX2p0ws5rs0bY -Ib4p1I5eFdZCSucyb6Sxa1GDWL4/bcf72gMhy2oWGU4K8K2Eyl2Us1p292E= ------END CERTIFICATE----- - - -No client certificate CA names sent ---- -SSL handshake has read 4905 bytes and written 434 bytes ---- -New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256 -Server public key is 2048 bit -Secure Renegotiation IS supported -Compression: NONE -Expansion: NONE -SSL-Session: - Protocol : TLSv1.2 - Cipher : ECDHE-RSA-AES128-GCM-SHA256 - Session-ID: 2022CC0AC2A1FCAB925F6511FCC28ACB27DDA644586ED6502753A3AA9FD70109 - Session-ID-ctx: - Master-Key: 81B1182E9E133115CE67AD77ED3429F907601B7C5B30A9D5EE66F08652264B06F8576B6943369C92F6734DA8C146B4E8 - Key-Arg : None - PSK identity: None - PSK identity hint: None - SRP username: None - TLS session ticket lifetime hint: 300 (seconds) - TLS session ticket: - 0000 - 4f bd 82 9c 08 63 6f 2c-6f a1 09 b9 33 a3 66 b0 O....co,o...3.f. - 0010 - 5f 4f 74 38 3a fc 89 a5-e6 88 42 ab 58 7f d6 ba _Ot8:.....B.X... - 0020 - 30 1f 13 da 7e 7d 31 a3-0d 87 85 67 1b 86 5d 66 0...~}1....g..]f - 0030 - e0 8e 14 03 c9 89 73 60-38 60 87 a0 0d 48 dd dd ......s`8`...H.. - 0040 - 1d b9 c3 8f 91 ed 92 2d-48 02 fb f0 79 25 4f 56 .......-H...y%OV - 0050 - 5a ce 68 23 08 78 bc 86-1b ad 7a b7 58 41 04 19 Z.h#.x....z.XA.. - 0060 - 29 0c b6 66 72 f1 27 36-83 18 4b b4 9c 41 64 bb )..fr.'6..K..Ad. - 0070 - 6f 52 0b df 03 f6 cc c2-b2 37 c2 c9 0e f9 df 9f oR.......7...... - 0080 - 13 af d6 d0 35 e8 e9 ac-f3 a6 02 07 9b 2f a2 e6 ....5......../.. - 0090 - 48 c6 1c c0 12 b2 ec 55-36 ad a0 c0 3c f5 cc db H......U6...<... - - Start Time: 1411743946 - Timeout : 300 (sec) - Verify return code: 20 (unable to get local issuer certificate) ---- diff --git a/tools/testcerts/pre1.txt b/tools/testcerts/pre1.txt deleted file mode 100644 index 776c38e..0000000 --- a/tools/testcerts/pre1.txt +++ /dev/null @@ -1,79 +0,0 @@ -Timestamp: 1383337821156 -Leafhash: A4892155FE9929177BCA785A73C15351A3EE2AF6F163DE40C15802BDE0F41302 ------BEGIN PRECERTIFICATE----- -MIIGqDCCBZCgAwIBAgIQCxvJV1NZEuon0JIojHqH+DANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5EaWdpQ2VydCBTSEEyIFNlY3Vy -ZSBTZXJ2ZXIgQ0EwHhcNMTMxMTAxMDAwMDAwWhcNMTQxMTA2MTIwMDAwWjBkMQswCQYDVQQGEwJV -UzENMAsGA1UECBMEVXRhaDENMAsGA1UEBxMETGVoaTEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4x -HjAcBgNVBAMTFWVtYmVkLmN0LmRpZ2ljZXJ0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBANExEGl1kTCQJNWXQuTH3m4DWx7xh9Tq+EXHlhorVtgUmHLmBPn7FGC3MH51q0MXN6K7 -huQVXa9LRmCdPRNlNPSkWUqpCVTEqBZrTPuAGEs01+XgXsyhP3uwBxWZkkKJ0FJ4tu7RVHXXgmSC -+JQkSgI4MUNuMaIHvWEpEKsmov9kcQZGUTPnwEg90PyVLlbKypRoFM0dynpslh6FUH4OEAuCx4h1 -tsAN2KHk/ajYE0ND+FN0gBf5qXuY+njUEsDaGiAVKgAb16wOk//0xWy4cTWeHnyLObrsZ3F11GVl -8cK1x0dNGxgeVfH6yTB8BJu/2wqaQSAdzf14Cie5D8YUXf0CAwEAAaOCA2swggNnMB8GA1UdIwQY -MBaAFA+AYRyCMWHVLyjnjUY4tCzhxtniMB0GA1UdDgQWBBT8yxF+UXTw/RIW5igB3ZSRrSSkFzAg -BgNVHREEGTAXghVlbWJlZC5jdC5kaWdpY2VydC5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW -MBQGCCsGAQUFBwMBBggrBgEFBQcDAjBrBgNVHR8EZDBiMC+gLaArhilodHRwOi8vY3JsMy5kaWdp -Y2VydC5jb20vc3NjYS1zaGEyLWcxLmNybDAvoC2gK4YpaHR0cDovL2NybDQuZGlnaWNlcnQuY29t -L3NzY2Etc2hhMi1nMS5jcmwwggHEBgNVHSAEggG7MIIBtzCCAbMGCWCGSAGG/WwBATCCAaQwOgYI -KwYBBQUHAgEWLmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0w -ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgAaQBzACAAQwBl -AHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQAZQBzACAAYQBjAGMAZQBwAHQA -YQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcAaQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABh -AG4AZAAgAHQAaABlACAAUgBlAGwAeQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUA -bgB0ACAAdwBoAGkAYwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAg -AGEAcgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIAeQAgAHIA -ZQBmAGUAcgBlAG4AYwBlAC4wfAYIKwYBBQUHAQEEcDBuMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz -cC5kaWdpY2VydC5jb20wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E -aWdpQ2VydFNIQTJTZWN1cmVTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH/BAIwADATBgorBgEEAdZ5AgQD -AQH/BAIFADANBgkqhkiG9w0BAQsFAAOCAQEAbHgFxzrmkXjRdQdlHj4Ey2U8rTOetMqjddrXR1DZ -9E12vp8yWB+LkSVASutpgzxNawj/rv1w1ODdJWMTra12R1MnxqoVytSEmbE0gjgxahdWWiV8yTFB -4tMFRHvCCwmIJqhRwjufnRs1q1+9YMxZ6reCG4kg29qgtQhh8V9vCrGfQja/4cBHa6O7w407FPra -b2NIqtJB/47fOdACkVdFjbOVSWielDtTv7QNPi3OUfNwNE/Qqh1k5MOBDP1gif1AFzl5Z7plUos5 -3533VCBjrcOWp8WXUtNlIedlxjarUaTKSRpZVdRzY9ugvou9JLVF1SuDIAXQ3+tN44bjAjERug== ------END PRECERTIFICATE----- - ------BEGIN CERTIFICATE----- -MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw -HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgx -MjAwMDBaME0xCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRp -Z2lDZXJ0IFNIQTIgU2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83nf36QYSv -x6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bdKpPDkC55gIDvEwRqFDu1 -m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f/ld0Uzs1gN2ujkSYs58O09rg1/RrKatE -p0tYhG2SS4HD2nOLEpdIkARFdRrdNzGXkujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJ -TvOX6+guqw9ypzAO+sf0/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQI -MAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYaHR0 -cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2lj -ZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1oDOGMWh0dHA6Ly9jcmw0LmRpZ2lj -ZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYI -KwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHV -LyjnjUY4tCzhxtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB -CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl5TlPHoOlblyY -oiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA8MXW5dRNJ2Srm8c+cftIl7gz -bckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8s -jX7tN8Cp1Tm5gr8ZDOo0rwAhaPitc+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopY -JeS4d60tbvVS3bR0j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz ------END CERTIFICATE----- - ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw -HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw -MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 -dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn -TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 -BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H -4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y -7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB -o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm -8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF -BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr -EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt -tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 -UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- - diff --git a/tools/testcerts/pre2.txt b/tools/testcerts/pre2.txt deleted file mode 100644 index 4c86537..0000000 --- a/tools/testcerts/pre2.txt +++ /dev/null @@ -1,106 +0,0 @@ -Timestamp: 1399629239033 -Leafhash: 758B8612DFED6A3321215C0586C0AC9F43137CD2BBF043C86301D66DC7D1205A ------BEGIN PRECERTIFICATE----- -MIIFFzCCBAGgAwIBAgIgd+115NyVfYOnRINB2wJy2eaQRbJ6j8Zau5IdwBNpmzowCwYJKoZIhvcN -AQELMGYxLDAqBgNVBAMMI1ByZS1jZXJ0aWZpY2F0ZSBTaWduaW5nIENlcnRpZmljYXRlMRAwDgYD -VQQLDAdDQSBUZWFtMRcwFQYDVQQKDA5UQUlXQU4tQ0EgSU5DLjELMAkGA1UEBhMCVFcwHhcNMTQw -NTA5MDk1MzU3WhcNMTQwNTE2MTU1OTU5WjB0MR0wGwYDVQQDDBRjdHRlc3QwNS50d2NhLmNvbS50 -dzELMAkGA1UECwwCUkQxFzAVBgNVBAoMDlRBSVdBTi1DQSBJTkMuMQ8wDQYDVQQHDAZUYWlwZWkx -DzANBgNVBAgMBlRhaXdhbjELMAkGA1UEBhMCVFcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQDSgb3MYpsqjkNqcOJHIlEmy8ldCzXtmJfoLfvW1g8JyaGgKR6B98ceg1whThF1tPy8aqJv -fEXGivb+2El1BmxTNvSZ+bOkOT0UsD2hiIgUppD6b/ICWQrIvwrBTNnfJtrwvGD/rygpVTZQoekX -IVdapI95Cfn+36YXqjX7ixgItEx3t/nzOqBxJNI0p52m9l1sowi2/hGmvc/xqC0Cti4m177c8gP0 -u4oKQRJVF2690F748KfzIMcbS7KbDDDVhtWqwgKaRLvqD+gJAUZ1QYEyzDr5Xhhi1O0FXfhyeeCj -mRUJBENmhqElt9C1HugaBsno37JP1AQdsuVg776qQQ1PAgMBAAGjggGlMIIBoTArBgNVHSMEJDAi -gCCVnLtVYCn+QZohG69CSwl1Y2OhEQ7LbPhnh353anz2ezApBgNVHQ4EIgQgt6NL2avrK2PUt8X1 -oG0rd0Wd2ZVDVuJru2T6Z4/eJUEwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2N0dGVzdC50d2Nh -LmNvbS50dy9zc2xzZXJ2ZXIvY3R0ZXN0LmNybDAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwID -qDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwJQYDVR0RBB4wHIIUY3R0ZXN0MDUudHdj -YS5jb20udHeHBMCoAckwOgYIKwYBBQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vY3R0ZXN0 -LnR3Y2EuY29tLnR3L29jc3AwUQYDVR0gBEowSDBGBgdggR4DAQgFMDswIgYIKwYBBQUHAgEWFmh0 -dHA6Ly93d3cudHdjYS5jb20udHcwFQYIKwYBBQUHAgIwCRoHMC4xLjEuMzATBgorBgEEAdZ5AgQD -AQH/BAIFADALBgkqhkiG9w0BAQsDggEBAIkN6er89ss6KAZOH/ZpTPbXhO/J8NNq7vJBxhD4z56R -aRTJpr7Fla9zr8K3aD7bbBUpVeMqER3YA7eeOR8ITBqzMN9SpjdpDlBLcI/6S+7iUVRw4+UvEVqL -0xlCfdxftGLX+T77y7/qqLxyH+QVuSS4sKzTCfspqAaxteK32A5nWKAiJFUI/ise67o3T9f015hR -7rHj+U2AomLQwnyiMg4u3D2mYzK9q7VDGJfKIW6wrFYS/lQsFKyb4sUTyGG9VuzgSDIjCXJag7fs -MZ+/shgsVOTzHUVeHGuKsPcpps0Yvu2W3DybsVoBwtS/vePPnfNfCrDqM9vZCTurvG4KaS4= ------END PRECERTIFICATE----- - ------BEGIN CERTIFICATE----- -MIIEUTCCAzugAwIBAgIEATNR3TALBgkqhkiG9w0BAQswVDELMAkGA1UEBhMCVFcxFzAVBgNVBAoT -DlRBSVdBTi1DQSBJTkMuMRAwDgYDVQQLEwdDQSBUZWFtMRowGAYDVQQDExFSRCBUV0NBIENUVEVT -VCBDQTAeFw0xNDA1MDkwOTQzMjZaFw0xNTA1MDkxNTU5NTlaMGYxLDAqBgNVBAMMI1ByZS1jZXJ0 -aWZpY2F0ZSBTaWduaW5nIENlcnRpZmljYXRlMRAwDgYDVQQLDAdDQSBUZWFtMRcwFQYDVQQKDA5U -QUlXQU4tQ0EgSU5DLjELMAkGA1UEBhMCVFcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCtFIow0xs7VQ42AEck0o+D8pDDOvIclTPJG7j5+wc7lz1wOwbqP8w06Qa/18tg3sdk16dYFg9k -pIeOU7suaWgeHifBjjj9iXTELH4U0RP3HwxlM23WArt9a5OKM5KJlA2T9obppnfsN9fm6ZGX4TTY -JqV8x2vgXSkHhVwxl8wnZoywHlHlgThvVVi+/DzZUD8FIXz2/dPeMtSTfHQ6LqIhee9YMIVgqg/f -tPb5lOhrJEmAl56mJWi1haVYmxZDSa4+1XCJkOxEzQDPpAvIrXVgAQzr6A5jIHZ7VucTEQ5U/9lx -Gckzv6CFDRxYyjSpBZsxML/d4A1P9nKdWcABqO9PAgMBAAGjggEbMIIBFzArBgNVHSMEJDAigCCE -xPSrbrwoBcYxPScQhJ7WOGJB5N3Efkav81dvue7NsjApBgNVHQ4EIgQglZy7VWAp/kGaIRuvQksJ -dWNjoREOy2z4Z4d+d2p89nswPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2N0dGVzdC50d2NhLmNv -bS50dy9zc2xzZXJ2ZXIvY3R0ZXN0LmNybDASBgNVHRMBAf8ECDAGAQH/AgEAMBUGA1UdJQQOMAwG -CisGAQQB1nkCBAQwUQYDVR0gBEowSDBGBgdggR4DAQgFMDswIgYIKwYBBQUHAgEWFmh0dHA6Ly93 -d3cudHdjYS5jb20udHcwFQYIKwYBBQUHAgIwCRoHMC4xLjEuMzALBgkqhkiG9w0BAQsDggEBAN8v -hr/zNUNSSikqAtRVZVgcJTuN3yTlaXX4hMJFAWrbBqJuN++cE6A2BBTkaLpEZajVqPKL5AxL5KWM -dMFNkpF3i0UKbf4vnpfrQprsamDX5tKqPCAOKa8yL82CBkimOCmLx24WN+VtNitYzh/MqspApNM7 -7wCO8ncvFtS4sC1Gj5M9CjVhxKmMe15O4SZr9aZpGP7raT4CE3X95APKX5yyiAVwPcOPdPkfRRLQ -gHko60NbxaeayH5sfWa2dNPEjbOkz0SKaXurV9pzrj/2FZNhgsnRsGIJhx2BLm7FoeUC45RarDJD -YrscJ6DBR83YwJXsaFCyB7l5CP7L13Wr98E= ------END CERTIFICATE----- - ------BEGIN CERTIFICATE----- -MIIEvjCCAqagAwIBAgIQQAEzUd0AAAAAAAAAFzPdqzANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG -EwJUVzEbMBkGA1UEChMSVFdDQSBSRCBEZXBhcnRtZW50MRAwDgYDVQQLEwdDQSBUZWFtMSQwIgYD -VQQDExtSRCBUV0NBIFJvb3QgQ0EgNDA5NiBTaGEyNTYwHhcNMTQwNTA5MDMyMDUyWhcNMTUwNTA5 -MTU1OTU5WjBUMQswCQYDVQQGEwJUVzEXMBUGA1UEChMOVEFJV0FOLUNBIElOQy4xEDAOBgNVBAsT -B0NBIFRlYW0xGjAYBgNVBAMTEVJEIFRXQ0EgQ1RURVNUIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA6xAMprFXHtOkmXIgL63aTx4S20IzdrcdDTMQvwnyYLBhJf8lWz5qeOY37SaC -4VXILP54qVdML+YBa2BAQfgu6kS+/f73Bp3pSHx8LIHQCt5jdgkNS3OVYK8nQdbWXWeA64bCFdE/ -tlelHSTHtIKXE+v7ug+P5Q/RRBf0Dzi/M1fXTXqXeAga3LaPGPT7o6lZZJh7hp25aJxChIa/1X8x -99sPx/BqO/WHyYKBCU9Ym05yQFel8mpCgzSbqscKTbKPkvm0ejDANX/WCEziJ3IzR5G9kPoL/zYZ -ofIqYJMIYRsQRlD/n1ILnMxwdhN3EFlZ0e5xkyIm9TaCqeCZsdFJWQIDAQABo34wfDArBgNVHSME -JDAigCCwvM16BvA51cl2uO30/ohdOMPVrVBVG5BZ4teNnteYnTApBgNVHQ4EIgQghMT0q268KAXG -MT0nEISe1jhiQeTdxH5Gr/NXb7nuzbIwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C -AQAwDQYJKoZIhvcNAQEFBQADggIBABDkaI3GMCKBfJSfnpmxmiU1ht3cfq/9/hpJSzE6k+of5esV -D3bYW9nnKScCcBy7poeOoc3C7p9fQtsLZbNfhYpG4/Aq0aVYGtZxw/FCWnXi9rUXpSLZh1yW1uV9 -KBj2D8yzGIx99mpHifjjeoCWG0TW/aaHeIolJm2DhkPTLWjd/urN1TP8YqhEiKMHZI3SFWeeH/BV -WJKE5rX8vtLW1FPnlRPE+Z/FAa52qOyN4ie0A9IhNPs3gtc+bnhdcZaHnxkySqUvWxqQxkzAGaiO -VnPlnSlnMCn5I2KOT0XVWYOyU9PP1//V/baDftv7VpT5AOtIaz8mQ6Lp4AIcoPFeU8cgJNZhXgmp -NOv/dW8lWXH6RYxdM7NFmv98Wk3rKLCzOzR6kuXnARKOJghZf4FV+6Fvjgjf/8wLnzhSdCEbyL7A -znkOSKc9wzUcZCxF8aTWtRT8HYIu8diZo0CzPxN8OyDl5mPsYexhguPHOXyLv/EljZ8yCdy/SsgQ -JPzuqKu2a3RD4des15EzbnJOxn4DSeqoUfSfaU/KVfmUKpBEJ3ouD2SLAZ7L+4F6NPCte3HEE2kN -tOmQIwe65htXmLJxDB+dwMjE4dkA2sETaN2dQ9DqpCNkpNxuNdis/uacAAXnDNddPIlR2moCtUx8 -+Y7wlcqBHdmmg5rbFBuBN+esL8J8 ------END CERTIFICATE----- - ------BEGIN CERTIFICATE----- -MIIFyTCCA7GgAwIBAgIQQAEzK0EAAAAAAAAAFSWxNjANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQG -EwJUVzEbMBkGA1UEChMSVFdDQSBSRCBEZXBhcnRtZW50MRAwDgYDVQQLEwdDQSBUZWFtMSQwIgYD -VQQDExtSRCBUV0NBIFJvb3QgQ0EgNDA5NiBTaGEyNTYwHhcNMTMwNjI1MDMwNzIyWhcNMzMwNjI1 -MDMwNzI2WjBiMQswCQYDVQQGEwJUVzEbMBkGA1UEChMSVFdDQSBSRCBEZXBhcnRtZW50MRAwDgYD -VQQLEwdDQSBUZWFtMSQwIgYDVQQDExtSRCBUV0NBIFJvb3QgQ0EgNDA5NiBTaGEyNTYwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2Saqg7eNGISFsG+pQfB/e+VTbpg+KmAAydUrJyCPj -74Gl/MKNeMW6AqUUSiKQq+HTnrHI+I2e85cgAxbSbhXp6utJuOjfsZE5lr7KDkfok9hdMA7YvKuk -y5dLK9Qcvhj4olt3DU0GKdWgKKtMWg4WOx+Wgu50C/TGyeiMx754O09a0YXlDLji84aQbxUWCP+X -hq+LXyGqilcTe+wSVjUHWfJJz8ZeVNCz/WXBn2Sljf614T1AkeU9pTnEkJRd/S+eVNVE8gLiAJSF -/ffHTHGRZoPCTDS26hzSpBAC+va0T4IWvgGJtPNInReXGPeydxHJbsJjwyPQ9n5iclUZmAeKcG7a -Wow/xrU36euBDIp877djj5lbtb0Rq35slDAGLVy/ouLkcrurPZdJGkhcpACMi4sKK98cx/XnzP9o -wV+bDYyYlXSl3tv88CidywHI6VPN6Aio4ipsAOmol1AxbkJ+W9INiQzbdmYXD2v3c0Kvcq4/bZMw -wofoGWGBALF3VYd6aYUnaCHD9gYTPrMHVsMrYDbvlIDkORVL950xvi1SfbRRo36LtYLjupFiJOlP -xS0DxWN6tVarS+1SyHsdEJYKw+b2ty5Sko5JkCedgSXHPhkL2ap3OfHtegSDpIgWL7ydpaoTyD3y -Fev6doCPC6cnHitwBCDpoEqNIm+JK2JZYQIDAQABo3sweTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zArBgNVHSMEJDAigCCwvM16BvA51cl2uO30/ohdOMPVrVBVG5BZ4teNnteYnTAp -BgNVHQ4EIgQgsLzNegbwOdXJdrjt9P6IXTjD1a1QVRuQWeLXjZ7XmJ0wDQYJKoZIhvcNAQELBQAD -ggIBAGSVKdVIynZnTpFaK3F2jjaC2oaJ1L8CA6e5OjWi6WUshKG4kJzLASD/U8XQXA8rVSuWShmz -B7ccm4fy1SmnSvsi4JA5mSDqcIOmwZmIYBAd/+8QK/sijzyO2MNPpqSupuhWxAakHSG8/3Leij2Q -P2GEXejDq3ewtS/gT1ZVI/ZSlIYxChsKZ3UEkl4XhUhL8fir/5Z+g6WdTFvXUB3wc/JA/MZ+h5Nu -BsrnrTlxet0vu3UlyOELsF5pMe1WGayR2A56LRL3UKhjFrUJSCTYMBiqAMS3Fsvk+RXttPYtcpiB -uheX8M/X8g2WTLOklS9/QYy1VmIWZcrfExHrMxQ8FCrxMfQn8fNlkMADmcRbQYeVHHZGx7MQEjBw -py45jzcPudJTx8Ccz6r0YSxoumC9reS0hASQ/NdXh6vcWfT8qsqYohL/k9J0PbfgJuIExAStIs+Y -nn4N7HgNftijy+l0sS//rMhVcofUaJzhJcbUe4TX/SL8ZHFkSkhUSPdDd1DR+r1IWKDKd/2FxMn3 -+oKBVsjPdL0HBwwHFQja8TBb5E3vYo4XKKEOGIuFa7NcSq0pF7pK85K0XIypAwgJCXffWP9SynDo -eK+ZbSOZNOCvH67ZRUQnWo1nZds+6OplhSpWkYDYN834wXEU4zbHRvtymCbIeMZzAXzdsJM2i3zy -7bTu ------END CERTIFICATE----- - diff --git a/tools/testcerts/roots/root1.pem b/tools/testcerts/roots/root1.pem deleted file mode 100644 index e077900..0000000 --- a/tools/testcerts/roots/root1.pem +++ /dev/null @@ -1,23 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd -BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx -OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0 -eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz -ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI -wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd -tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8 -i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf -Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw -gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF -lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF -UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF -BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM -//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW -XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2 -lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn -iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67 -nfhmqA== ------END CERTIFICATE----- diff --git a/tools/testcerts/roots/root2.pem b/tools/testcerts/roots/root2.pem deleted file mode 100644 index bdb6474..0000000 --- a/tools/testcerts/roots/root2.pem +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML -QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD -VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw -NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU -cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg -Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 -+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw -Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo -aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy -2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 -7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL -VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk -VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB -IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl -j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 -e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u -G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= ------END CERTIFICATE----- diff --git a/tools/testcerts/roots/root3.pem b/tools/testcerts/roots/root3.pem deleted file mode 100644 index 81c8a7d..0000000 --- a/tools/testcerts/roots/root3.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw -KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw -MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ -MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu -Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t -Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS -OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 -MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ -NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe -h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB -Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY -JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ -V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp -myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK -mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K ------END CERTIFICATE----- diff --git a/tools/testcerts/roots/root4.pem b/tools/testcerts/roots/root4.pem deleted file mode 100644 index 3fdb770..0000000 --- a/tools/testcerts/roots/root4.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw -HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw -MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 -dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn -TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 -BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H -4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y -7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB -o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm -8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF -BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr -EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt -tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 -UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- diff --git a/tools/testcerts/roots/root5.pem b/tools/testcerts/roots/root5.pem deleted file mode 100644 index 096fd18..0000000 --- a/tools/testcerts/roots/root5.pem +++ /dev/null @@ -1,29 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFyTCCA7GgAwIBAgIQQAEzK0EAAAAAAAAAFSWxNjANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQG -EwJUVzEbMBkGA1UEChMSVFdDQSBSRCBEZXBhcnRtZW50MRAwDgYDVQQLEwdDQSBUZWFtMSQwIgYD -VQQDExtSRCBUV0NBIFJvb3QgQ0EgNDA5NiBTaGEyNTYwHhcNMTMwNjI1MDMwNzIyWhcNMzMwNjI1 -MDMwNzI2WjBiMQswCQYDVQQGEwJUVzEbMBkGA1UEChMSVFdDQSBSRCBEZXBhcnRtZW50MRAwDgYD -VQQLEwdDQSBUZWFtMSQwIgYDVQQDExtSRCBUV0NBIFJvb3QgQ0EgNDA5NiBTaGEyNTYwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2Saqg7eNGISFsG+pQfB/e+VTbpg+KmAAydUrJyCPj -74Gl/MKNeMW6AqUUSiKQq+HTnrHI+I2e85cgAxbSbhXp6utJuOjfsZE5lr7KDkfok9hdMA7YvKuk -y5dLK9Qcvhj4olt3DU0GKdWgKKtMWg4WOx+Wgu50C/TGyeiMx754O09a0YXlDLji84aQbxUWCP+X -hq+LXyGqilcTe+wSVjUHWfJJz8ZeVNCz/WXBn2Sljf614T1AkeU9pTnEkJRd/S+eVNVE8gLiAJSF -/ffHTHGRZoPCTDS26hzSpBAC+va0T4IWvgGJtPNInReXGPeydxHJbsJjwyPQ9n5iclUZmAeKcG7a -Wow/xrU36euBDIp877djj5lbtb0Rq35slDAGLVy/ouLkcrurPZdJGkhcpACMi4sKK98cx/XnzP9o -wV+bDYyYlXSl3tv88CidywHI6VPN6Aio4ipsAOmol1AxbkJ+W9INiQzbdmYXD2v3c0Kvcq4/bZMw -wofoGWGBALF3VYd6aYUnaCHD9gYTPrMHVsMrYDbvlIDkORVL950xvi1SfbRRo36LtYLjupFiJOlP -xS0DxWN6tVarS+1SyHsdEJYKw+b2ty5Sko5JkCedgSXHPhkL2ap3OfHtegSDpIgWL7ydpaoTyD3y -Fev6doCPC6cnHitwBCDpoEqNIm+JK2JZYQIDAQABo3sweTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zArBgNVHSMEJDAigCCwvM16BvA51cl2uO30/ohdOMPVrVBVG5BZ4teNnteYnTAp -BgNVHQ4EIgQgsLzNegbwOdXJdrjt9P6IXTjD1a1QVRuQWeLXjZ7XmJ0wDQYJKoZIhvcNAQELBQAD -ggIBAGSVKdVIynZnTpFaK3F2jjaC2oaJ1L8CA6e5OjWi6WUshKG4kJzLASD/U8XQXA8rVSuWShmz -B7ccm4fy1SmnSvsi4JA5mSDqcIOmwZmIYBAd/+8QK/sijzyO2MNPpqSupuhWxAakHSG8/3Leij2Q -P2GEXejDq3ewtS/gT1ZVI/ZSlIYxChsKZ3UEkl4XhUhL8fir/5Z+g6WdTFvXUB3wc/JA/MZ+h5Nu -BsrnrTlxet0vu3UlyOELsF5pMe1WGayR2A56LRL3UKhjFrUJSCTYMBiqAMS3Fsvk+RXttPYtcpiB -uheX8M/X8g2WTLOklS9/QYy1VmIWZcrfExHrMxQ8FCrxMfQn8fNlkMADmcRbQYeVHHZGx7MQEjBw -py45jzcPudJTx8Ccz6r0YSxoumC9reS0hASQ/NdXh6vcWfT8qsqYohL/k9J0PbfgJuIExAStIs+Y -nn4N7HgNftijy+l0sS//rMhVcofUaJzhJcbUe4TX/SL8ZHFkSkhUSPdDd1DR+r1IWKDKd/2FxMn3 -+oKBVsjPdL0HBwwHFQja8TBb5E3vYo4XKKEOGIuFa7NcSq0pF7pK85K0XIypAwgJCXffWP9SynDo -eK+ZbSOZNOCvH67ZRUQnWo1nZds+6OplhSpWkYDYN834wXEU4zbHRvtymCbIeMZzAXzdsJM2i3zy -7bTu ------END CERTIFICATE----- diff --git a/tools/to_catlfish.py b/tools/to_catlfish.py deleted file mode 100755 index 00a359f..0000000 --- a/tools/to_catlfish.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (c) 2015, NORDUnet A/S. -# See LICENSE for licensing information. - -import argparse -import subprocess -import sys -import select - -parser = argparse.ArgumentParser(description='') -parser.add_argument('toerl') -parser.add_argument('nodedir') -parser.add_argument('command') -args = parser.parse_args() - -p = subprocess.Popen( - [args.toerl, args.nodedir], - stdin=subprocess.PIPE) -p.stdin.write(args.command + ".\n") -p.stdin.flush() -select.select([], [], [], 0.5) -p.stdin.close() -p.wait() diff --git a/tools/treeinfo.py b/tools/treeinfo.py deleted file mode 100755 index 036aeb2..0000000 --- a/tools/treeinfo.py +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Copyright (c) 2014, NORDUnet A/S. -# See LICENSE for licensing information. - -import argparse -import urllib2 -import urllib -import json -import base64 -import sys -import struct -import hashlib -import itertools -from certtools import * -import zipfile -import os -import time - -parser = argparse.ArgumentParser(description='') -parser.add_argument('--store', default=None, metavar="dir", help='Certificates directory') - -parser.add_argument('--head', action='store_true', help="Calculate tree head") -parser.add_argument('--printnode', action='store_true', help="Print tree node") - -parser.add_argument('--treesize', type=int, default=None, metavar="treesize", help="Tree size") -parser.add_argument('--level', type=int, default=None, metavar="level", help="Level") -parser.add_argument('--index', type=int, default=None, metavar="index", help="Index") - -parser.add_argument('--follow', action='store_true', help="Follow upwards") - -parser.add_argument('--dot', default=None, metavar="file", help='Output data in dot format') - -args = parser.parse_args() - -def index_to_root(index, treesize, level=0): - path = (index, level) - height = merkle_height(treesize) - nodes = [] - while node_level(path) < height: - nodes.append(path) - path = node_above(path) - return nodes - -def set_tree_node(tree, level, index, value, overwrite=True): - if not overwrite and index in levels.setdefault(level, {}): - return - levels.setdefault(level, {})[index] = value - -def draw_path(tree, startlevel, startindex, treesize, colors): - height = merkle_height(treesize) - nodes = index_to_root(startindex, treesize, level=startlevel) - - for (index, level) in nodes: - if level == 0: - set_tree_node(tree, level, index, colors[0]) - else: - set_tree_node(tree, level, index, colors[1]) - index ^= 1 - levelsize = 2 ** level - firstleaf = index * levelsize - if firstleaf < treesize: - set_tree_node(tree, level, index, "", overwrite=False) - set_tree_node(tree, height, 0, colors[1]) - - -if args.head: - treehead = get_tree_head(args.store, args.treesize) - print base64.b16encode(treehead) -elif args.dot: - levels = {} - if args.index >= args.treesize: - sys.exit(1) - dotfile = open(args.dot, "w") - print >>dotfile, 'graph "" {' - print >>dotfile, 'ordering=out;' - print >>dotfile, 'node [style=filled];' - - height = merkle_height(args.treesize) - - draw_path(levels, 0, args.treesize - 1, args.treesize, ["0.600 0.500 0.900", "0.600 0.300 0.900"]) - - draw_path(levels, args.level, args.index, args.treesize, ["0.300 0.500 0.900", "0.300 0.200 0.900"]) - - for l in sorted(levels.keys(), reverse=True): - for i in sorted(levels[l].keys()): - print >>dotfile, "l%di%d [color=\"%s\" label=\"%s\"];" % (l, i, levels[l][i], path_as_string(i, l, args.treesize)) - if height != l: - print >>dotfile, "l%di%d -- l%di%d;" % (l + 1, i / 2, l, i) - if i & 1 == 0: - print >>dotfile, "ml%di%d [shape=point style=invis];" % (l, i) - print >>dotfile, "l%di%d -- ml%di%d [weight=100 style=invis];" % (l + 1, i / 2, l, i) - print >>dotfile, "}" - dotfile.close() -elif args.printnode: - index = args.index - level = args.level - if args.index >= args.treesize: - sys.exit(1) - height = merkle_height(args.treesize) - nodes = index_to_root(index, args.treesize, level=level) - - for (index, level) in nodes: - print level, index - if args.store: - print base64.b16encode(get_intermediate_hash(args.store, args.treesize, level, index)) - - if not args.follow: - sys.exit(0) - - index ^= 1 - levelsize = 2 ** level - - firstleaf = index * levelsize - if firstleaf < args.treesize: - print level, index - if args.store: - print base64.b16encode(get_intermediate_hash(args.store, args.treesize, level, index)) - - print height, 0 - if args.store: - print base64.b16encode(get_intermediate_hash(args.store, args.treesize, height, 0)) diff --git a/tools/validatestore.py b/tools/validatestore.py deleted file mode 100755 index 74963e0..0000000 --- a/tools/validatestore.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2014, NORDUnet A/S. -# See LICENSE for licensing information. - -import argparse -import urllib2 -import urllib -import json -import base64 -import sys -import struct -import hashlib -import itertools -from certtools import * -try: - from precerttools import * -except ImportError: - pass -import os -import signal -import select -import zipfile -import traceback - -parser = argparse.ArgumentParser(description='') -parser.add_argument('--store', default=None, metavar="dir", help='Get certificates from directory dir') -parser.add_argument('--parallel', type=int, default=1, metavar="n", help="Number of parallel workers") -args = parser.parse_args() - -from multiprocessing import Pool - -certfilepath = args.store - -if certfilepath[-1] == "/": - certfiles = [certfilepath + filename for filename in sorted(os.listdir(certfilepath)) if os.path.isfile(certfilepath + filename)] -else: - certfiles = [certfilepath] - -def submitcert((certfile, cert)): - try: - certchain = get_certs_from_string(cert) - if len(certchain) == 0: - return True - precerts = get_precerts_from_string(cert) - hash = get_hash_from_certfile(cert) - timestamp = get_timestamp_from_certfile(cert) - assert len(precerts) == 0 or len(precerts) == 1 - precert = precerts[0] if precerts else None - if precert: - if ext_key_usage_precert_signing_cert in get_ext_key_usage(certchain[0]): - issuer_key_hash = get_cert_key_hash(certchain[1]) - issuer = certchain[1] - else: - issuer_key_hash = get_cert_key_hash(certchain[0]) - issuer = None - cleanedcert = cleanprecert(precert, issuer=issuer) - mtl = pack_mtl_precert(timestamp, cleanedcert, issuer_key_hash) - leaf_hash = get_leaf_hash(mtl) - else: - mtl = pack_mtl(timestamp, certchain[0]) - leaf_hash = get_leaf_hash(mtl) - if leaf_hash == hash: - return True - else: - print certfile, repr(leaf_hash), repr(hash), precert != None - return None - except Exception, e: - print certfile - traceback.print_exc() - raise e - -def get_all_certificates(certfiles): - for certfile in certfiles: - if certfile.endswith(".zip"): - zf = zipfile.ZipFile(certfile) - for name in zf.namelist(): - yield (name, zf.read(name)) - zf.close() - else: - yield (certfile, open(certfile).read()) - -p = Pool(args.parallel, lambda: signal.signal(signal.SIGINT, signal.SIG_IGN)) - -certs = get_all_certificates(certfiles) - -try: - for result in p.imap_unordered(submitcert, certs): - if result == None: - print "error" - p.terminate() - p.join() - sys.exit(1) -except KeyboardInterrupt: - p.terminate() - p.join() diff --git a/tools/verifysct.py b/tools/verifysct.py deleted file mode 100755 index 71ea4e9..0000000 --- a/tools/verifysct.py +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2014, NORDUnet A/S. -# See LICENSE for licensing information. - -import argparse -import urllib2 -import urllib -import json -import base64 -import sys -import struct -import hashlib -import itertools -from certtools import * -import os -import signal -import select -import zipfile - -parser = argparse.ArgumentParser(description='') -parser.add_argument('baseurl', help="Base URL for CT server") -parser.add_argument('--sct-file', default=None, metavar="dir", help='SCT:s to verify') -parser.add_argument('--parallel', type=int, default=16, metavar="n", help="Number of parallel verifications") -parser.add_argument('--publickey', default=None, metavar="file", help='Public key for the CT log') -parser.add_argument('--cafile', default=None, metavar="file", help='File containing the CA cert') -args = parser.parse_args() - -create_ssl_context(cafile=args.cafile) - -from multiprocessing import Pool - -baseurl = args.baseurl - -logpublickey = get_public_key_from_file(args.publickey) if args.publickey else None - -sth = get_sth(baseurl) - -def verifysct(sctentry): - timing = timing_point() - - leafcert = base64.b64decode(sctentry["leafcert"]) - if "issuer_key_hash" in sctentry: - issuer_key_hash = base64.b64decode(sctentry["issuer_key_hash"]) - else: - issuer_key_hash = None - try: - if issuer_key_hash: - signed_entry = pack_precert(leafcert, issuer_key_hash) - else: - signed_entry = pack_cert(leafcert) - check_sct_signature(baseurl, signed_entry, sctentry["sct"], precert=issuer_key_hash, publickey=logpublickey) - timing_point(timing, "checksig") - except AssertionError, e: - print "ERROR:", e - return (None, None) - except urllib2.HTTPError, e: - print "ERROR:", e - return (None, None) - except ecdsa.keys.BadSignatureError, e: - print "ERROR: bad signature" - return (None, None) - - if issuer_key_hash: - merkle_tree_leaf = pack_mtl_precert(sctentry["sct"]["timestamp"], leafcert, issuer_key_hash) - else: - merkle_tree_leaf = pack_mtl(sctentry["sct"]["timestamp"], leafcert) - - leaf_hash = get_leaf_hash(merkle_tree_leaf) - - try: - proof = get_proof_by_hash(baseurl, leaf_hash, sth["tree_size"]) - except SystemExit: - return (None, None) - - #print proof - - leaf_index = proof["leaf_index"] - inclusion_proof = [base64.b64decode(e) for e in proof["audit_path"]] - - calc_root_hash = verify_inclusion_proof(inclusion_proof, leaf_index, sth["tree_size"], leaf_hash) - - root_hash = base64.b64decode(sth["sha256_root_hash"]) - if root_hash != calc_root_hash: - print "sth" - print base64.b16encode(root_hash) - print base64.b16encode(calc_root_hash) - assert root_hash == calc_root_hash - - timing_point(timing, "lookup") - return (True, timing["deltatimes"]) - -p = Pool(args.parallel, lambda: signal.signal(signal.SIGINT, signal.SIG_IGN)) - -sctfile = open(args.sct_file) -scts = (json.loads(row) for row in sctfile) - -nverified = 0 -lastprinted = 0 - -starttime = datetime.datetime.now() - -try: - for result, timing in p.imap_unordered(verifysct, scts): - if timing == None: - print "error" - print "verified", nverified - p.terminate() - p.join() - sys.exit(1) - if result != None: - nverified += 1 - deltatime = datetime.datetime.now() - starttime - deltatime_f = deltatime.seconds + deltatime.microseconds / 1000000.0 - rate = nverified / deltatime_f - if nverified > lastprinted + 100: - print nverified, "rate %.1f" % rate - lastprinted = nverified - #print timing, "rate %.1f" % rate - print "verified", nverified -except KeyboardInterrupt: - p.terminate() - p.join() diff --git a/tools/verifysecondary.py b/tools/verifysecondary.py deleted file mode 100755 index 9a36b32..0000000 --- a/tools/verifysecondary.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (c) 2015, NORDUnet A/S. -# See LICENSE for licensing information. - -import argparse -import base64 -import sys -import subprocess -from certtools import build_merkle_tree -from mergetools import * - -parser = argparse.ArgumentParser(description="") -parser.add_argument('--mergedb', help="Merge database", required=True) -parser.add_argument('--verifycert', help="Path to verifycert program", required=True) -parser.add_argument('--knownroots', help="Path to knownroots directory", required=True) -args = parser.parse_args() - -mergedb = args.mergedb -chainsdir = mergedb + "/chains" -logorderfile = mergedb + "/logorder" - -verifycert = subprocess.Popen([args.verifycert, args.knownroots], - stdin=subprocess.PIPE, stdout=subprocess.PIPE) - -logorder = get_logorder(logorderfile) - -for hash in logorder: - entry = read_chain(chainsdir, hash) - verify_entry(verifycert, entry, hash) - -tree = build_merkle_tree(logorder) -root_hash = tree[-1][0] - -print base64.b16encode(root_hash) diff --git a/tools/verifysecondary.sh b/tools/verifysecondary.sh deleted file mode 100755 index 4a90543..0000000 --- a/tools/verifysecondary.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cd $(dirname $0)/../catlfish -../tools/verifysecondary.py --mergedb="$1" --verifycert=../verifycert.erl --knownroots=../tools/testcerts/roots/ |