summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorMagnus Ahltorp <map@kth.se>2014-09-25 12:23:00 +0200
committerMagnus Ahltorp <map@kth.se>2014-09-25 12:23:00 +0200
commit4899f85a4bfe73d166667348ffef77312ca85751 (patch)
tree63528d08f28fa96c0447c0f480964bfd5994a2ea /tools
parentd0c0ab627445f1dcb8eb3dcdb7c6bda3809a088d (diff)
submitcert: Validate SCT and compare log id
Diffstat (limited to 'tools')
-rw-r--r--tools/certtools.py41
-rwxr-xr-xtools/submitcert.py19
2 files changed, 59 insertions, 1 deletions
diff --git a/tools/certtools.py b/tools/certtools.py
index 48e7b41..13dad17 100644
--- a/tools/certtools.py
+++ b/tools/certtools.py
@@ -5,6 +5,8 @@ import urllib
import urllib2
import struct
import sys
+import hashlib
+import ecdsa
def get_cert_info(s):
p = subprocess.Popen(
@@ -77,7 +79,9 @@ def unpack_tls_array(packed_data, length_len):
padded_length[-length_len:] = packed_data[:length_len]
(length,) = struct.unpack(">Q", "".join(padded_length))
unpacked_data = packed_data[length_len:length_len+length]
- assert len(unpacked_data) == length
+ assert len(unpacked_data) == length, \
+ "data is only %d bytes long, but length is %d bytes" % \
+ (len(unpacked_data), length)
rest_data = packed_data[length_len+length:]
return (unpacked_data, rest_data)
@@ -107,3 +111,38 @@ def decode_certificate_chain(packed_certchain):
certs.append(cert)
unpacked_certchain = rest
return certs
+
+def decode_signature(signature):
+ (hash_alg, signature_alg) = struct.unpack(">bb", signature[0:2])
+ (unpacked_signature, rest) = unpack_tls_array(signature[2:], 2)
+ assert rest == ""
+ return (hash_alg, signature_alg, unpacked_signature)
+
+def check_signature(publickey, leafcert, sct):
+ calculated_logid = hashlib.sha256(publickey).digest()
+ received_logid = base64.decodestring(sct["id"])
+ assert calculated_logid == received_logid, \
+ "log id is incorrect:\n should be %s\n got %s" % \
+ (calculated_logid.encode("hex_codec"),
+ received_logid.encode("hex_codec"))
+
+ signature = base64.decodestring(sct["signature"])
+
+ version = struct.pack(">b", sct["sct_version"])
+ signature_type = struct.pack(">b", 0)
+ timestamp = struct.pack(">Q", sct["timestamp"])
+ entry_type = struct.pack(">H", 0)
+ signed_struct = version + signature_type + timestamp + \
+ entry_type + tls_array(leafcert, 3) + \
+ tls_array(base64.decodestring(sct["extensions"]), 2)
+
+ (hash_alg, signature_alg, unpacked_signature) = decode_signature(signature)
+ assert hash_alg == 4 # sha256
+ assert signature_alg == 3 # ecdsa
+
+ hash = hashlib.sha256()
+ hash.update(signed_struct)
+
+ vk = ecdsa.VerifyingKey.from_der(publickey)
+ vk.verify(unpacked_signature, signed_struct, hashfunc=hashlib.sha256,
+ sigdecode=ecdsa.util.sigdecode_der)
diff --git a/tools/submitcert.py b/tools/submitcert.py
index 7844dda..702ffb3 100755
--- a/tools/submitcert.py
+++ b/tools/submitcert.py
@@ -13,12 +13,31 @@ certfile = sys.argv[2]
lookup_in_log = True
+publickeys = {
+ "https://ct.googleapis.com/pilot/":
+ "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfahLEimAoz2t01p3uMziiLOl/fHTD"
+ "M0YDOhBRuiBARsV4UvxG2LdNgoIGLrtCzWE0J5APC2em4JlvR8EEEFMoA==",
+
+ "https://127.0.0.1:8080/":
+ "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4qWq6afhBUi0OdcWUYhyJLNXTkGqQ9"
+ "PMS5lqoCgkV2h1ZvpNjBH2u8UbgcOQwqDo66z6BWQJGolozZYmNHE2kQ==",
+
+ "https://flimsy.ct.nordu.net/":
+ "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4qWq6afhBUi0OdcWUYhyJLNXTkGqQ9"
+ "PMS5lqoCgkV2h1ZvpNjBH2u8UbgcOQwqDo66z6BWQJGolozZYmNHE2kQ==",
+}
+
+
certs = get_certs_from_file(certfile)
result = add_chain(baseurl, {"chain":certs})
print result
+publickey = base64.decodestring(publickeys[baseurl])
+
+check_signature(publickey, base64.decodestring(certs[0]), result)
+
for cert in certs:
print get_cert_info(base64.decodestring(cert))