From 4899f85a4bfe73d166667348ffef77312ca85751 Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Thu, 25 Sep 2014 12:23:00 +0200 Subject: submitcert: Validate SCT and compare log id --- tools/certtools.py | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'tools/certtools.py') 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) -- cgit v1.1