summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/certtools.py36
-rwxr-xr-xtools/halt.py19
-rwxr-xr-xtools/merge.py49
-rwxr-xr-xtools/testcase1.py9
4 files changed, 88 insertions, 25 deletions
diff --git a/tools/certtools.py b/tools/certtools.py
index 2fb1492..222497f 100644
--- a/tools/certtools.py
+++ b/tools/certtools.py
@@ -6,6 +6,7 @@ import json
import base64
import urllib
import urllib2
+import urlparse
import struct
import sys
import hashlib
@@ -182,10 +183,35 @@ def check_signature(baseurl, signature, data):
vk.verify(unpacked_signature, data, hashfunc=hashlib.sha256,
sigdecode=ecdsa.util.sigdecode_der)
-def create_signature(privatekey, data):
+def http_request(url, data=None, key=None):
+ req = urllib2.Request(url, data)
+ (keyname, keyfile) = key
+ privatekey = get_eckey_from_file(keyfile)
sk = ecdsa.SigningKey.from_der(privatekey)
- unpacked_signature = sk.sign(data, hashfunc=hashlib.sha256,
- sigencode=ecdsa.util.sigencode_der)
+ parsed_url = urlparse.urlparse(url)
+ if data == None:
+ data = parsed_url.query
+ method = "GET"
+ else:
+ method = "POST"
+ signature = sk.sign("%s\0%s\0%s" % (method, parsed_url.path, data), hashfunc=hashlib.sha256,
+ sigencode=ecdsa.util.sigencode_der)
+ req.add_header('X-Catlfish-Auth', base64.b64encode(signature) + ";key=" + keyname)
+ result = urllib2.urlopen(req).read()
+ return result
+
+def get_signature(baseurl, data, key=None):
+ try:
+ params = json.dumps({"plop_version":1, "data": base64.b64encode(data)})
+ result = http_request(baseurl + "ct/signing/sth", params, key=key)
+ parsed_result = json.loads(result)
+ return base64.b64decode(parsed_result.get(u"result"))
+ except urllib2.HTTPError, e:
+ print "ERROR: get_signature", e.read()
+ sys.exit(1)
+
+def create_signature(baseurl, data, key=None):
+ unpacked_signature = get_signature(baseurl, data, key)
return encode_signature(4, 3, unpacked_signature)
def check_sth_signature(baseurl, sth):
@@ -200,14 +226,14 @@ def check_sth_signature(baseurl, sth):
check_signature(baseurl, signature, tree_head)
-def create_sth_signature(tree_size, timestamp, root_hash, privatekey):
+def create_sth_signature(tree_size, timestamp, root_hash, baseurl, key=None):
version = struct.pack(">b", 0)
signature_type = struct.pack(">b", 1)
timestamp_packed = struct.pack(">Q", timestamp)
tree_size_packed = struct.pack(">Q", tree_size)
tree_head = version + signature_type + timestamp_packed + tree_size_packed + root_hash
- return create_signature(privatekey, tree_head)
+ return create_signature(baseurl, tree_head, key=key)
def check_sct_signature(baseurl, leafcert, sct):
publickey = base64.decodestring(publickeys[baseurl])
diff --git a/tools/halt.py b/tools/halt.py
new file mode 100755
index 0000000..cfbf14e
--- /dev/null
+++ b/tools/halt.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2014, NORDUnet A/S.
+# See LICENSE for licensing information.
+
+import argparse
+import subprocess
+import sys
+
+parser = argparse.ArgumentParser(description='')
+parser.add_argument('toerl')
+parser.add_argument('nodedir')
+args = parser.parse_args()
+
+p = subprocess.Popen(
+ [args.toerl, args.nodedir],
+ stdin=subprocess.PIPE)
+p.communicate("halt().\n")
diff --git a/tools/merge.py b/tools/merge.py
index f4a007d..c137f4b 100755
--- a/tools/merge.py
+++ b/tools/merge.py
@@ -11,14 +11,19 @@ import urllib
import urllib2
import sys
import time
-from certtools import build_merkle_tree, create_sth_signature, check_sth_signature, get_eckey_from_file, timing_point
+import ecdsa
+import hashlib
+import urlparse
+from certtools import build_merkle_tree, create_sth_signature, check_sth_signature, get_eckey_from_file, timing_point, http_request
parser = argparse.ArgumentParser(description="")
parser.add_argument("--baseurl", metavar="url", help="Base URL for CT server", required=True)
parser.add_argument("--frontend", action="append", metavar="url", help="Base URL for frontend server", required=True)
parser.add_argument("--storage", action="append", metavar="url", help="Base URL for storage server", required=True)
parser.add_argument("--mergedb", metavar="dir", help="Merge database directory", required=True)
-parser.add_argument("--keyfile", metavar="keyfile", help="File containing log key", required=True)
+parser.add_argument("--signing", metavar="url", help="Base URL for signing server", required=True)
+parser.add_argument("--own-keyname", metavar="keyname", help="The key name of the merge node", required=True)
+parser.add_argument("--own-keyfile", metavar="keyfile", help="The file containing the private key of the merge node", required=True)
parser.add_argument("--nomerge", action='store_true', help="Don't actually do merge")
args = parser.parse_args()
@@ -29,6 +34,8 @@ storagenodes = args.storage
chainsdir = args.mergedb + "/chains"
logorderfile = args.mergedb + "/logorder"
+own_key = (args.own_keyname, args.own_keyfile)
+
def parselogrow(row):
return base64.b16decode(row)
@@ -54,7 +61,7 @@ def add_to_logorder(key):
def get_new_entries(baseurl):
try:
- result = urllib2.urlopen(baseurl + "ct/storage/fetchnewentries").read()
+ result = http_request(baseurl + "ct/storage/fetchnewentries", key=own_key)
parsed_result = json.loads(result)
if parsed_result.get(u"result") == u"ok":
return [base64.b64decode(entry) for entry in parsed_result[u"entries"]]
@@ -67,7 +74,7 @@ def get_new_entries(baseurl):
def get_entries(baseurl, hashes):
try:
params = urllib.urlencode({"hash":[base64.b64encode(hash) for hash in hashes]}, doseq=True)
- result = urllib2.urlopen(baseurl + "ct/storage/getentry?" + params).read()
+ result = http_request(baseurl + "ct/storage/getentry?" + params, key=own_key)
parsed_result = json.loads(result)
if parsed_result.get(u"result") == u"ok":
entries = dict([(base64.b64decode(entry["hash"]), base64.b64decode(entry["entry"])) for entry in parsed_result[u"entries"]])
@@ -82,7 +89,7 @@ def get_entries(baseurl, hashes):
def get_curpos(baseurl):
try:
- result = urllib2.urlopen(baseurl + "ct/frontend/currentposition").read()
+ result = http_request(baseurl + "ct/frontend/currentposition", key=own_key)
parsed_result = json.loads(result)
if parsed_result.get(u"result") == u"ok":
return parsed_result[u"position"]
@@ -94,8 +101,8 @@ def get_curpos(baseurl):
def sendlog(baseurl, submission):
try:
- result = urllib2.urlopen(baseurl + "ct/frontend/sendlog",
- json.dumps(submission)).read()
+ result = http_request(baseurl + "ct/frontend/sendlog",
+ json.dumps(submission), key=own_key)
return json.loads(result)
except urllib2.HTTPError, e:
print "ERROR: sendlog", e.read()
@@ -110,8 +117,8 @@ def sendlog(baseurl, submission):
def sendentry(baseurl, entry, hash):
try:
- result = urllib2.urlopen(baseurl + "ct/frontend/sendentry",
- json.dumps({"entry":base64.b64encode(entry), "treeleafhash":base64.b64encode(hash)})).read()
+ result = http_request(baseurl + "ct/frontend/sendentry",
+ json.dumps({"entry":base64.b64encode(entry), "treeleafhash":base64.b64encode(hash)}), key=own_key)
return json.loads(result)
except urllib2.HTTPError, e:
print "ERROR: sendentry", e.read()
@@ -126,8 +133,8 @@ def sendentry(baseurl, entry, hash):
def sendsth(baseurl, submission):
try:
- result = urllib2.urlopen(baseurl + "ct/frontend/sendsth",
- json.dumps(submission)).read()
+ result = http_request(baseurl + "ct/frontend/sendsth",
+ json.dumps(submission), key=own_key)
return json.loads(result)
except urllib2.HTTPError, e:
print "ERROR: sendsth", e.read()
@@ -142,7 +149,7 @@ def sendsth(baseurl, submission):
def get_missingentries(baseurl):
try:
- result = urllib2.urlopen(baseurl + "ct/frontend/missingentries").read()
+ result = http_request(baseurl + "ct/frontend/missingentries", key=own_key)
parsed_result = json.loads(result)
if parsed_result.get(u"result") == u"ok":
return parsed_result[u"entries"]
@@ -208,10 +215,9 @@ tree = build_merkle_tree(logorder)
tree_size = len(logorder)
root_hash = tree[-1][0]
timestamp = int(time.time() * 1000)
-privatekey = get_eckey_from_file(args.keyfile)
tree_head_signature = create_sth_signature(tree_size, timestamp,
- root_hash, privatekey)
+ root_hash, args.signing, key=own_key)
sth = {"tree_size": tree_size, "timestamp": timestamp,
"sha256_root_hash": base64.b64encode(root_hash),
@@ -233,7 +239,10 @@ for frontendnode in frontendnodes:
print "current position", curpos
entries = [base64.b64encode(entry) for entry in logorder[curpos:]]
for chunk in chunks(entries, 1000):
- sendlog(frontendnode, {"start": curpos, "hashes": chunk})
+ sendlogresult = sendlog(frontendnode, {"start": curpos, "hashes": chunk})
+ if sendlogresult["result"] != "ok":
+ print "sendlog:", sendlogresult
+ sys.exit(1)
curpos += len(chunk)
print curpos,
sys.stdout.flush()
@@ -244,8 +253,14 @@ for frontendnode in frontendnodes:
print "missing entries:", len(missingentries)
for missingentry in missingentries:
hash = base64.b64decode(missingentry)
- sendentry(frontendnode, read_chain(hash), hash)
+ sendentryresult = sendentry(frontendnode, read_chain(hash), hash)
+ if sendentryresult["result"] != "ok":
+ print "send sth:", sendentryresult
+ sys.exit(1)
timing_point(timing, "send missing")
- sendsth(frontendnode, sth)
+ sendsthresult = sendsth(frontendnode, sth)
+ if sendsthresult["result"] != "ok":
+ print "send sth:", sendsthresult
+ sys.exit(1)
timing_point(timing, "send sth")
print timing["deltatimes"]
diff --git a/tools/testcase1.py b/tools/testcase1.py
index a41a783..73613fb 100755
--- a/tools/testcase1.py
+++ b/tools/testcase1.py
@@ -136,13 +136,13 @@ def get_and_check_entry(timestamp, chain, leaf_index):
len(submittedcertchain))
def merge():
- return subprocess.call(["./merge.py", "--baseurl", "https://127.0.0.1:8080/", "--frontend", "https://127.0.0.1:8082/", "--storage", "https://127.0.0.1:8081/", "--mergedb", "../rel/mergedb", "--keyfile", "../rel/test/eckey.pem"])
-
-print_and_check_tree_size(0)
+ return subprocess.call(["./merge.py", "--baseurl", "https://127.0.0.1:8080/", "--frontend", "https://127.0.0.1:8082/", "--storage", "https://127.0.0.1:8081/", "--mergedb", "../rel/mergedb", "--signing", "https://127.0.0.1:8088/", "--own-keyname", "merge-1", "--own-keyfile", "../rel/privatekeys/merge-1-private.pem"])
mergeresult = merge()
assert_equal(mergeresult, 0, "merge", quiet=True)
+print_and_check_tree_size(0)
+
testgroup("cert1")
result1 = do_add_chain(cc1)
@@ -230,6 +230,9 @@ get_and_validate_proof(result4["timestamp"], cc3, 2, 3)
get_and_validate_proof(result5["timestamp"], cc4, 3, 3)
get_and_validate_proof(result6["timestamp"], cc5, 4, 1)
+mergeresult = merge()
+assert_equal(mergeresult, 0, "merge", quiet=True)
+
for first_size in range(1, 5):
for second_size in range(first_size + 1, 6):
get_and_validate_consistency_proof(size_sth[first_size], size_sth[second_size], first_size, second_size)