summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Ahltorp <map@kth.se>2017-01-27 16:11:11 +0100
committerLinus Nordberg <linus@nordu.net>2017-02-01 10:46:27 +0100
commitc0d8aceccb0961a25ee58a163441bbcbe6d6ea3d (patch)
tree90c98ad5f286a2475c1dd04ca7ddd70df6669aea
parent50667bc5c4896557415ab28269d2aea3ac534bf4 (diff)
Verify config file signature
Read log key from config file in more places. Check STH signature in storagegc.py
-rw-r--r--test/catlfish-test-local-1.cfg4
-rw-r--r--test/catlfish-test-local-merge-2.cfg4
-rw-r--r--test/catlfish-test-local-merge.cfg4
-rw-r--r--test/catlfish-test-local-signing.cfg4
-rw-r--r--test/logadminkey-private.pem5
-rw-r--r--test/logadminkey.pem4
-rwxr-xr-xtest/scripts/light-system-test-prepare.sh2
-rwxr-xr-xtools/compileconfig.py10
-rwxr-xr-xtools/loginfo.py5
-rwxr-xr-xtools/merge_sth.py3
-rw-r--r--tools/mergetools.py6
-rw-r--r--tools/readconfig.py54
-rwxr-xr-xtools/storagegc.py7
13 files changed, 97 insertions, 15 deletions
diff --git a/test/catlfish-test-local-1.cfg b/test/catlfish-test-local-1.cfg
index adc3e84..1795649 100644
--- a/test/catlfish-test-local-1.cfg
+++ b/test/catlfish-test-local-1.cfg
@@ -30,5 +30,9 @@ paths:
ratelimits:
add_chain: 10 per second
+logadminkey: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQ
+ Ah9sZ2CD+JeLbprS6AFcZbo0TGCH0rtEnr2Q3JW0ylhfA+
+ 0/WLu755b3soVX/wI23vqCVGC7N9fOB2WUltveQ==
+
#options:
# - sctcaching
diff --git a/test/catlfish-test-local-merge-2.cfg b/test/catlfish-test-local-merge-2.cfg
index 579e360..b871313 100644
--- a/test/catlfish-test-local-merge-2.cfg
+++ b/test/catlfish-test-local-merge-2.cfg
@@ -18,3 +18,7 @@ paths:
publickeys: publickeys
logpublickey: keys/logkey.pem
privatekeys: privatekeys
+
+logadminkey: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQ
+ Ah9sZ2CD+JeLbprS6AFcZbo0TGCH0rtEnr2Q3JW0ylhfA+
+ 0/WLu755b3soVX/wI23vqCVGC7N9fOB2WUltveQ==
diff --git a/test/catlfish-test-local-merge.cfg b/test/catlfish-test-local-merge.cfg
index 273b68e..3b4d45f 100644
--- a/test/catlfish-test-local-merge.cfg
+++ b/test/catlfish-test-local-merge.cfg
@@ -8,3 +8,7 @@ paths:
privatekeys: privatekeys
verifycert_bin: ../bin/verifycert.erl.escript
known_roots: known_roots/
+
+logadminkey: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQ
+ Ah9sZ2CD+JeLbprS6AFcZbo0TGCH0rtEnr2Q3JW0ylhfA+
+ 0/WLu755b3soVX/wI23vqCVGC7N9fOB2WUltveQ==
diff --git a/test/catlfish-test-local-signing.cfg b/test/catlfish-test-local-signing.cfg
index 386001e..df91bcd 100644
--- a/test/catlfish-test-local-signing.cfg
+++ b/test/catlfish-test-local-signing.cfg
@@ -19,3 +19,7 @@ paths:
# slot: 0
# label: mylabel
# pin: ffff
+
+logadminkey: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQ
+ Ah9sZ2CD+JeLbprS6AFcZbo0TGCH0rtEnr2Q3JW0ylhfA+
+ 0/WLu755b3soVX/wI23vqCVGC7N9fOB2WUltveQ==
diff --git a/test/logadminkey-private.pem b/test/logadminkey-private.pem
new file mode 100644
index 0000000..4464169
--- /dev/null
+++ b/test/logadminkey-private.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIKoa7p5gnAgd9L2t5N1L73MJ1OCj/zItvGoVMtsKPy4JoAoGCCqGSM49
+AwEHoUQDQgAEQAh9sZ2CD+JeLbprS6AFcZbo0TGCH0rtEnr2Q3JW0ylhfA+0/WLu
+755b3soVX/wI23vqCVGC7N9fOB2WUltveQ==
+-----END EC PRIVATE KEY-----
diff --git a/test/logadminkey.pem b/test/logadminkey.pem
new file mode 100644
index 0000000..43ff2c4
--- /dev/null
+++ b/test/logadminkey.pem
@@ -0,0 +1,4 @@
+-----BEGIN PUBLIC KEY-----
+MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQAh9sZ2CD+JeLbprS6AFcZbo0TGC
+H0rtEnr2Q3JW0ylhfA+0/WLu755b3soVX/wI23vqCVGC7N9fOB2WUltveQ==
+-----END PUBLIC KEY-----
diff --git a/test/scripts/light-system-test-prepare.sh b/test/scripts/light-system-test-prepare.sh
index df45d25..84b06cd 100755
--- a/test/scripts/light-system-test-prepare.sh
+++ b/test/scripts/light-system-test-prepare.sh
@@ -50,7 +50,6 @@ printf 0 > mergedb-secondary/verifiedsize
mkdir known_roots
cp ${top_srcdir}/tools/testcerts/roots/* known_roots
mkdir privatekeys
-mkdir publickeys
echo "apikeys:" > api-keys.cfg
for node in ${NODES}; do \
(cd privatekeys ; ${top_srcdir}/tools/create-key.sh ${node})
@@ -66,6 +65,7 @@ echo "cafingerprint: ${cafingerprint}" >> api-keys.cfg
cat ${top_srcdir}/test/catlfish-test.cfg.in api-keys.cfg > ${top_srcdir}/test/catlfish-test.cfg
+openssl dgst -sha256 -sign ${top_srcdir}/test/logadminkey-private.pem -out ${top_srcdir}/test/catlfish-test.cfg.sig ${top_srcdir}/test/catlfish-test.cfg
for machine in ${MACHINES}; do \
${top_srcdir}/tools/compileconfig.py --config ${top_srcdir}/test/catlfish-test.cfg --localconfig ${top_srcdir}/test/catlfish-test-local-${machine}.cfg
mkdir -p machine/machine-${machine}/db
diff --git a/tools/compileconfig.py b/tools/compileconfig.py
index 0ee3fab..b5e5053 100755
--- a/tools/compileconfig.py
+++ b/tools/compileconfig.py
@@ -5,7 +5,7 @@
import argparse
import sys
-import yaml
+import readconfig
import re
import base64
@@ -405,7 +405,6 @@ def gen_testmakefile(config, testmakefile, machines, shellvars=False):
configfile.close()
-
def main():
parser = argparse.ArgumentParser(description="")
parser.add_argument('--config', help="System configuration", required=True)
@@ -415,13 +414,16 @@ def main():
parser.add_argument("--machines", type=int, metavar="n", help="Number of machines")
args = parser.parse_args()
- config = yaml.load(open(args.config))
if args.testmakefile and args.machines:
+ config = readconfig.read_config(args.config)
gen_testmakefile(config, args.testmakefile, args.machines)
elif args.testshellvars and args.machines:
+ config = readconfig.read_config(args.config)
gen_testmakefile(config, args.testshellvars, args.machines, shellvars=True)
elif args.localconfig:
- localconfig = yaml.load(open(args.localconfig))
+ localconfig = readconfig.read_config(args.localconfig)
+ config = readconfig.verify_and_read_config(args.config, localconfig["logadminkey"])
+
localnodes = localconfig["localnodes"]
for localnode in localnodes:
gen_config(localnode, config, localconfig)
diff --git a/tools/loginfo.py b/tools/loginfo.py
index c61ad1b..1537c5e 100755
--- a/tools/loginfo.py
+++ b/tools/loginfo.py
@@ -6,7 +6,7 @@
import sys
import argparse
-import yaml
+import readconfig
from certtools import create_ssl_context, get_sth
def main():
@@ -26,8 +26,7 @@ def main():
required=True)
parser.add_argument('baseurl', help="Log base URL")
args = parser.parse_args()
- #config = yaml.load(open(args.config))
- localconfig = yaml.load(open(args.localconfig))
+ localconfig = readconfig.read_config(args.localconfig)
paths = localconfig["paths"]
create_ssl_context(cafile=paths["https_cacertfile"])
diff --git a/tools/merge_sth.py b/tools/merge_sth.py
index 6b1bb60..2bc19dd 100755
--- a/tools/merge_sth.py
+++ b/tools/merge_sth.py
@@ -12,6 +12,7 @@ import json
import urllib2
import time
import requests
+import base64
from base64 import b64encode
from mergetools import parse_args, get_nfetched, hexencode, hexdecode, \
get_logorder, get_sth
@@ -31,7 +32,7 @@ def merge_sth(args, config, localconfig):
sthfile = mergedb + "/sth"
logorderfile = mergedb + "/logorder"
currentsizefile = mergedb + "/fetched"
- logpublickey = get_public_key_from_file(paths["logpublickey"])
+ logpublickey = base64.decodestring(config["logpublickey"])
backupquorum = config.get("backup-quorum-size", 0)
assert backupquorum <= len(mergenodes) - 1
create_ssl_context(cafile=paths["https_cacertfile"])
diff --git a/tools/mergetools.py b/tools/mergetools.py
index f49e789..0afec24 100644
--- a/tools/mergetools.py
+++ b/tools/mergetools.py
@@ -7,7 +7,7 @@ import hashlib
import sys
import struct
import json
-import yaml
+import readconfig
import argparse
import requests
try:
@@ -430,8 +430,8 @@ def parse_args():
help="Print timing information")
args = parser.parse_args()
- config = yaml.load(open(args.config))
- localconfig = yaml.load(open(args.localconfig))
+ localconfig = readconfig.read_config(args.localconfig)
+ config = readconfig.verify_and_read_config(args.config, localconfig["logadminkey"])
set_api_keys(config)
diff --git a/tools/readconfig.py b/tools/readconfig.py
new file mode 100644
index 0000000..5079691
--- /dev/null
+++ b/tools/readconfig.py
@@ -0,0 +1,54 @@
+import io
+import ecdsa
+import hashlib
+import yaml
+import base64
+import sys
+
+class ErrorHandlingDict(dict):
+ def __init__(self, filename, path):
+ self._filename = filename
+ self._path = path
+ dict.__init__({})
+ def __missing__(self, key):
+ if self._path:
+ path = ", ".join(self._path)
+ else:
+ path = "the top level"
+ print >>sys.stderr, "error: could not find configuration key '%s' at %s in %s" % (key, path, self._filename)
+ sys.exit(1)
+
+def errorhandlify(term, filename, path=[]):
+ if isinstance(term, basestring):
+ return term
+ elif isinstance(term, int):
+ return term
+ elif isinstance(term, dict):
+ result = ErrorHandlingDict(filename, path)
+ for k, v in term.items():
+ result[k] = errorhandlify(v, filename, path + [k])
+ return result
+ elif isinstance(term, list):
+ return [errorhandlify(e, filename, path + ["item %d" % i]) for i, e in enumerate(term, start=1)]
+ else:
+ print "unknown type", type(term)
+ sys.exit(1)
+
+def verify_and_read_config(filename, publickey_base64):
+ rawconfig = open(filename).read()
+ signature = open(filename + ".sig").read()
+
+ publickey = base64.decodestring(publickey_base64)
+
+ try:
+ vk = ecdsa.VerifyingKey.from_der(publickey)
+ vk.verify(signature, rawconfig, hashfunc=hashlib.sha256,
+ sigdecode=ecdsa.util.sigdecode_der)
+ except ecdsa.keys.BadSignatureError:
+ print >>sys.stderr, "error: configuration file %s did not have a correct signature" % (filename,)
+ sys.exit(1)
+
+ return errorhandlify(yaml.load(io.BytesIO(rawconfig), yaml.SafeLoader), filename)
+
+def read_config(filename):
+ return errorhandlify(yaml.load(open(filename), yaml.SafeLoader), filename)
diff --git a/tools/storagegc.py b/tools/storagegc.py
index 38b5379..6360495 100755
--- a/tools/storagegc.py
+++ b/tools/storagegc.py
@@ -9,7 +9,7 @@ import urllib
import json
import base64
import sys
-import yaml
+import readconfig
from certtools import *
parser = argparse.ArgumentParser(description='')
@@ -17,8 +17,8 @@ parser.add_argument('--config', help="System configuration", required=True)
parser.add_argument('--localconfig', help="Local configuration", required=True)
args = parser.parse_args()
-config = yaml.load(open(args.config))
-localconfig = yaml.load(open(args.localconfig))
+localconfig = readconfig.read_config(args.localconfig)
+config = readconfig.verify_and_read_config(args.config, localconfig["logadminkey"])
paths = localconfig["paths"]
db_path = paths["db"]
@@ -27,6 +27,7 @@ create_ssl_context(cafile=paths.get("public_cacertfile", None))
baseurl = config["baseurl"]
sth = get_sth(baseurl)
+check_sth_signature(baseurl, sth, base64.decodestring(config["logpublickey"]))
def verifyleafhash(leaf_hash):
try: