diff options
-rw-r--r-- | tools/certtools.py | 41 | ||||
-rwxr-xr-x | tools/submitcert.py | 19 |
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)) |