summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorMagnus Ahltorp <map@kth.se>2015-03-18 14:27:18 +0100
committerMagnus Ahltorp <map@kth.se>2015-03-23 16:14:47 +0100
commit0a76e4d080a8349456d04434dcb2d4b381eb8ec4 (patch)
tree118a189f7901b0833f3b363a40fe66ba3da48bad /tools
parent15d5d6fd5cffdea185d18fbd4feb62afa23b9d12 (diff)
Added precert handling for SCT calculation
Diffstat (limited to 'tools')
-rw-r--r--tools/certtools.py20
-rwxr-xr-xtools/submitcert.py38
-rwxr-xr-xtools/verifysct.py17
3 files changed, 58 insertions, 17 deletions
diff --git a/tools/certtools.py b/tools/certtools.py
index 1436863..cc423af 100644
--- a/tools/certtools.py
+++ b/tools/certtools.py
@@ -257,7 +257,7 @@ def create_sth_signature(tree_size, timestamp, root_hash, baseurl, key=None):
return create_signature(baseurl, tree_head, key=key)
-def check_sct_signature(baseurl, leafcert, sct):
+def check_sct_signature(baseurl, signed_entry, sct, precert=False):
publickey = base64.decodestring(publickeys[baseurl])
calculated_logid = hashlib.sha256(publickey).digest()
received_logid = base64.decodestring(sct["id"])
@@ -271,9 +271,12 @@ def check_sct_signature(baseurl, leafcert, sct):
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)
+ if precert:
+ entry_type = struct.pack(">H", 1)
+ else:
+ entry_type = struct.pack(">H", 0)
signed_struct = version + signature_type + timestamp + \
- entry_type + tls_array(leafcert, 3) + \
+ entry_type + signed_entry + \
tls_array(base64.decodestring(sct["extensions"]), 2)
check_signature(baseurl, signature, signed_struct)
@@ -292,15 +295,22 @@ def pack_mtl(timestamp, leafcert):
def pack_mtl_precert(timestamp, cleanedcert, issuer_key_hash):
entry_type = struct.pack(">H", 1)
extensions = ""
- assert len(issuer_key_hash) == 32
timestamped_entry = struct.pack(">Q", timestamp) + entry_type + \
- issuer_key_hash + tls_array(cleanedcert, 3) + tls_array(extensions, 2)
+ pack_precert(cleanedcert, issuer_key_hash) + tls_array(extensions, 2)
version = struct.pack(">b", 0)
leaf_type = struct.pack(">b", 0)
merkle_tree_leaf = version + leaf_type + timestamped_entry
return merkle_tree_leaf
+def pack_precert(cleanedcert, issuer_key_hash):
+ assert len(issuer_key_hash) == 32
+
+ return issuer_key_hash + tls_array(cleanedcert, 3)
+
+def pack_cert(cert):
+ return tls_array(cert, 3)
+
def unpack_mtl(merkle_tree_leaf):
version = merkle_tree_leaf[0:1]
leaf_type = merkle_tree_leaf[1:2]
diff --git a/tools/submitcert.py b/tools/submitcert.py
index 1c79544..2e8cc33 100755
--- a/tools/submitcert.py
+++ b/tools/submitcert.py
@@ -13,6 +13,11 @@ import struct
import hashlib
import itertools
from certtools import *
+from certtools import *
+try:
+ from precerttools import *
+except ImportError:
+ pass
import os
import signal
import select
@@ -51,8 +56,20 @@ def submitcert((certfile, cert)):
try:
if precert:
+ if ext_key_usage_precert_signing_cert in get_ext_key_usage(certchain[0]):
+ issuer_key_hash = get_cert_key_hash(certchain[1])
+ issuer = certchain[1]
+ else:
+ issuer_key_hash = get_cert_key_hash(certchain[0])
+ issuer = None
+ cleanedcert = cleanprecert(precert, issuer=issuer)
+ signed_entry = pack_precert(cleanedcert, issuer_key_hash)
+ leafcert = cleanedcert
result = add_prechain(baseurl, {"chain":map(base64.b64encode, [precert] + certchain)})
else:
+ signed_entry = pack_cert(certchain[0])
+ leafcert = certchain[0]
+ issuer_key_hash = None
result = add_chain(baseurl, {"chain":map(base64.b64encode, certchain)})
except SystemExit:
print "EXIT:", certfile
@@ -67,7 +84,7 @@ def submitcert((certfile, cert)):
try:
if args.check_sct:
- check_sct_signature(baseurl, certchain[0], result)
+ check_sct_signature(baseurl, signed_entry, result, precert=precert)
timing_point(timing, "checksig")
except AssertionError, e:
print "ERROR:", certfile, e
@@ -81,7 +98,7 @@ def submitcert((certfile, cert)):
if lookup_in_log:
- merkle_tree_leaf = pack_mtl(result["timestamp"], certchain[0])
+ merkle_tree_leaf = pack_mtl(result["timestamp"], leafcert)
leaf_hash = get_leaf_hash(merkle_tree_leaf)
@@ -119,7 +136,7 @@ def submitcert((certfile, cert)):
print "and submitted chain has length", len(submittedcertchain)
timing_point(timing, "lookup")
- return ((certchain[0], result), timing["deltatimes"])
+ return ((leafcert, issuer_key_hash, result), timing["deltatimes"])
def get_ncerts(certfiles):
n = 0
@@ -142,9 +159,12 @@ def get_all_certificates(certfiles):
else:
yield (certfile, open(certfile).read())
-def save_sct(sct, sth):
+def save_sct(sct, sth, leafcert, issuer_key_hash):
sctlog = open(args.sct_file, "a")
- json.dump({"leafcert": base64.b64encode(leafcert), "sct": sct, "sth": sth}, sctlog)
+ sctentry = {"leafcert": base64.b64encode(leafcert), "sct": sct, "sth": sth}
+ if issuer_key_hash:
+ sctentry["issuer_key_hash"] = base64.b64encode(issuer_key_hash)
+ json.dump(sctentry, sctlog)
sctlog.write("\n")
sctlog.close()
@@ -163,8 +183,8 @@ certs = get_all_certificates(certfiles)
(result, timing) = submitcert(certs.next())
if result != None:
nsubmitted += 1
- (leafcert, sct) = result
- save_sct(sct, sth)
+ (leafcert, issuer_key_hash, sct) = result
+ save_sct(sct, sth, leafcert, issuer_key_hash)
if args.pre_warm:
select.select([], [], [], 3.0)
@@ -181,8 +201,8 @@ try:
sys.exit(1)
if result != None:
nsubmitted += 1
- (leafcert, sct) = result
- save_sct(sct, sth)
+ (leafcert, issuer_key_hash, sct) = result
+ save_sct(sct, sth, leafcert, issuer_key_hash)
deltatime = datetime.datetime.now() - starttime
deltatime_f = deltatime.seconds + deltatime.microseconds / 1000000.0
rate = nsubmitted / deltatime_f
diff --git a/tools/verifysct.py b/tools/verifysct.py
index 699a0ad..27ab4c9 100755
--- a/tools/verifysct.py
+++ b/tools/verifysct.py
@@ -34,8 +34,16 @@ def verifysct(sctentry):
timing = timing_point()
leafcert = base64.b64decode(sctentry["leafcert"])
+ if "issuer_key_hash" in sctentry:
+ issuer_key_hash = base64.b64decode(sctentry["issuer_key_hash"])
+ else:
+ issuer_key_hash = None
try:
- check_sct_signature(baseurl, leafcert, sctentry["sct"])
+ if issuer_key_hash:
+ signed_entry = pack_precert(leafcert, issuer_key_hash)
+ else:
+ signed_entry = pack_cert(leafcert)
+ check_sct_signature(baseurl, signed_entry, sctentry["sct"], precert=issuer_key_hash)
timing_point(timing, "checksig")
except AssertionError, e:
print "ERROR:", e
@@ -47,7 +55,10 @@ def verifysct(sctentry):
print "ERROR: bad signature"
return (None, None)
- merkle_tree_leaf = pack_mtl(sctentry["sct"]["timestamp"], leafcert)
+ if issuer_key_hash:
+ merkle_tree_leaf = pack_mtl_precert(sctentry["sct"]["timestamp"], leafcert, issuer_key_hash)
+ else:
+ merkle_tree_leaf = pack_mtl(sctentry["sct"]["timestamp"], leafcert)
leaf_hash = get_leaf_hash(merkle_tree_leaf)
@@ -76,7 +87,7 @@ def verifysct(sctentry):
p = Pool(args.parallel, lambda: signal.signal(signal.SIGINT, signal.SIG_IGN))
sctfile = open(args.sct_file)
-scts = [json.loads(row) for row in sctfile]
+scts = (json.loads(row) for row in sctfile)
nverified = 0
lastprinted = 0