1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#!/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)
|