#!/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)