diff options
| author | Linus Nordberg <linus@nordu.net> | 2015-06-04 15:36:31 +0200 | 
|---|---|---|
| committer | Linus Nordberg <linus@nordu.net> | 2015-06-04 15:36:31 +0200 | 
| commit | b4ec3393fa5012baed85ba045f9a625495a8579d (patch) | |
| tree | 0e7d556035b2709c9b22dc1a8f4b2ddb8acc7462 | |
| parent | 1e9e9a16002252d87c25f12afb77d3eaa9367c62 (diff) | |
Revamp log creation.
Read a catlfish .cfg file and don't loop in a makefile.
| -rw-r--r-- | mklog.mk | 71 | ||||
| -rwxr-xr-x | mklog.py | 155 | 
2 files changed, 166 insertions, 60 deletions
| @@ -4,18 +4,15 @@  # LOGNAME = name of the log to create  LOGNAME ?= $$(basename $$PWD) -# NODES = list of names of non-merge nodes -NODES ?= $$(cd nodes; ls | egrep -v ^merge-) - -# MERGE_NODES = list of names of merge nodes -MERGE_NODES ?= $$(cd nodes; ls merge-*) -  # HSM_SO_PIN = SoftHSM "security officer PIN"  HSM_SO_PIN ?= f0f0  # HSM_PIN = SoftHSM PIN  HSM_PIN ?= fefe +# MKLOG = python script for creating all the keys +MKLOG ?= ./mklog.py +  # SOFTHSM_BASE_DIR = base directory for SoftHSMv2 installation  SOFTHSM_BASE_DIR ?= ~/usr @@ -25,64 +22,18 @@ SOFTHSM_UTIL ?= $(SOFTHSM_BASE_DIR)/bin/softhsm2-util  # CATLFISH_SRC = path to catlfish source code  CATLFISH_SRC ?= ~/usr/src/catlfish -test: -	@echo LOGNAME = $(LOGNAME) -	@echo NODES = $(NODES) -	@echo MERGE_NODES = $(MERGE_NODES) -.PHONY: test - -log: certs authkeys logkey.pem - -destdirs: -	@for node in $(NODES) $(MERGE_NODES); do \ -	  if [ -d nodes.out/$${node} ]; then true; \ -	    else mkdir -p nodes.out/$${node}; \ -	  fi \ -	done +log: httpscerts publickeys $(LOGNAME).pem -tests privatekeys publickeys: -	mkdir $@ +mklog: +	$(MKLOG) --logname $(LOGNAME) $(LOGNAME).cfg -tests/httpsca/key.pem: tests -	make -f $(CATLFISH_SRC)/Makefile INSTDIR=. tests-createca -tests/httpscert: -	mkdir $@ -certs: tests/httpsca/key.pem tests/httpscert destdirs -	@for cn in $(NODES); do \ -	  openssl req -new -newkey rsa:2048 \ -		-keyout tests/httpscert/$${cn}-key.pem \ -		-out tests/httpsca/$${cn}.csr -nodes \ -		-subj "/countryName=SE/stateOrProvinceName=Stockholm/organizationName=Test/CN=$${cn}"; \ -	  (cd tests/httpsca; \ -	   openssl ca -in $${cn}.csr -keyfile key.pem -out $${cn}.pem -batch); \ -	  cp tests/httpsca/$${cn}.pem tests/httpscert/; \ -	done - -authkeys: privatekeys publickeys destdirs -	for node in $(NODES) $(MERGE_NODES); do \ -	  (cd privatekeys; $(CATLFISH_SRC)/tools/create-key.sh $${node}); \ -	  mv privatekeys/$${node}.pem publickeys/; \ -	  cp privatekeys/$${node}-private.pem nodes.out/$${node}/; \ -	  cp tests/httpsca/demoCA/cacert.pem nodes.out/$${node}/; \ -	done -	@for node in $(NODES) $(MERGE_NODES); do \ -	  cp -a publickeys nodes.out/$${node}/; \ -	done - -logkey.pem: destdirs $(SOFTHSM_UTIL) -	! [ -f logkey-private.pem ] -	$(CATLFISH_SRC)/tools/create-key.sh logkey -	chmod 600 logkey-private.pem +httpscerts publickeys $(LOGNAME)-private.pem: mklog +$(LOGNAME).pem: $(LOGNAME)-private.pem $(SOFTHSM_UTIL)  	openssl pkcs8 -topk8 -nocrypt \ -		-in logkey-private.pem -out logkey-private.pkcs8 +		-in $(LOGNAME)-private.pem -out $(LOGNAME)-private.pkcs8 +	chmod 600 $(LOGNAME)-private.pkcs8  	$(SOFTHSM_UTIL) --init-token --slot 0 --label $(LOGNAME) \  		--so-pin $(HSM_SO_PIN) --pin $(HSM_PIN) -	$(SOFTHSM_UTIL) --import logkey-private.pkcs8 --slot 0 \ +	$(SOFTHSM_UTIL) --import $(LOGNAME)-private.pkcs8 --slot 0 \  		--label $(LOGNAME) --pin $(HSM_PIN) --id 00 - -	for node in $(NODES) $(MERGE_NODES); do \ -	  cp logkey.pem nodes.out/$${node}/; \ -	done - -.PHONY: destdirs certs authkeys diff --git a/mklog.py b/mklog.py new file mode 100755 index 0000000..26df433 --- /dev/null +++ b/mklog.py @@ -0,0 +1,155 @@ +#! /usr/bin/env python + +import sys +import os +import stat +import argparse +import yaml +import subprocess +import shutil + +def run_openssl(args): +    p = subprocess.Popen(['openssl'] + args, stderr=subprocess.PIPE) +    (_, out_stderr) = p.communicate() +    if p.returncode == 0: +        return True +    print >>sys.stderr, "openssl %s failure: %d: %s" % \ +        (args, p.returncode, out_stderr) +    return False + +def make_eckey(name): +    print "creating EC key \"%s\"" % name + +    privkey_filename = '%s-private.pem' % name +    pubkey_filename = '%s.pem' % name +    ecparam_args =  ['ecparam', '-name', 'prime256v1', '-genkey', '-noout', +                     '-out', privkey_filename] +    if not run_openssl(ecparam_args): +        return False +    os.chmod(privkey_filename, stat.S_IRUSR) + +    ec_args = ['ec', '-in', privkey_filename, '-pubout', '-out', pubkey_filename] +    if not run_openssl(ec_args): +        return False +    os.chmod(pubkey_filename, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) + +    return True + +def make_ca(logname, cakey_filename, cacert_filename): +    os.makedirs('./demoCA/newcerts', 0700) + +    f = open('./demoCA/index.txt', 'w') +    f.close() + +    f = open('./demoCA/serial', 'w') +    f.write('00\n') +    f.close() + +    f = open('caconfig.txt', 'w') +    f.write('[ req ]\n') +    f.write('distinguished_name = req_distinguished_name\n') +    f.write('x509_extensions = v3_ca\n') +    f.write('string_mask = utf8only\n') +    f.write('[ req_distinguished_name ]\n') +    f.write('[ v3_ca ]\n') +    f.write('basicConstraints=CA:true\n') +    f.close() +     +    subject = '/countryName=II/stateOrProvinceName=internets/organizationName=%s/commonName=ca' % logname +    req_args = ['req', '-newkey', 'rsa:2048', '-keyout', cakey_filename, '-out', +                'req.csr', '-nodes', '-subj', subject, '-config', 'caconfig.txt'] +    if not run_openssl(req_args): +        return False +    os.chmod(cakey_filename, stat.S_IRUSR) + +    ca_args = ['ca', '-in', 'req.csr', '-selfsign', '-keyfile', cakey_filename, +               '-out', cacert_filename, '-batch'] +    if not run_openssl(ca_args): +        return False + +    return True + +def make_certs(logname, nodenames): +    wdir = './httpscerts' +    if not os.access(wdir, os.F_OK): +        os.mkdir(wdir) +    os.chdir(wdir) + +    ca_key = './cakey.pem' +    ca_cert = './demoCA/cacert.pem' +    if not os.access(ca_key, os.R_OK) or not os.access(ca_cert, os.R_OK): +        if not make_ca(logname, ca_key, ca_cert): +            return False + +    for nodename in nodenames: +        key = './%s-key.pem' % nodename +        csr = './%s.csr' % nodename +        cert = './%s.pem' % nodename +        subject = '/countryName=II/stateOrProvinceName=internets/organizationName=%s/CN=%s' % (logname, nodename) + +        print "creating cert for node %s" % nodename + +        if os.access(key, os.R_OK) and os.access(cert, os.R_OK): +            continue +        req_args = ['req', '-new', '-newkey', 'rsa:2048', '-keyout', key, +                    '-out', csr, '-nodes', '-subj', subject] +        if not run_openssl(req_args): +            return False +        ca_args = ['ca', '-in', csr, '-keyfile', ca_key, '-out', cert, '-batch'] +        if not run_openssl(ca_args): +            return False + +        shutil.copy(ca_cert, '../nodes/%s/cacert.pem' % nodename) +        shutil.copy(cert, '../nodes/%s/webcert-%s.pem' % (nodename, nodename)) +        shutil.copy(key, '../nodes/%s/webkey-%s.pem' % (nodename, nodename)) + +    os.chdir('..') +    return True + +def make_authkeys(nodenames): +    wdir = './publickeys' +    if not os.access(wdir, os.F_OK): +        os.mkdir(wdir) +    os.chdir(wdir) + +    for nodename in nodenames: +        if not make_eckey(nodename): +            return False +        shutil.move('%s-private.pem' % nodename, '../nodes/%s/' % nodename) +    for nodename in nodenames: +        shutil.copytree('.', '../nodes/%s/publickeys' % nodename) + +    os.chdir('..') +    return True + +def copy_logkey(logname, nodenames): +    for nodename in nodenames: +        shutil.copy('%s.pem' % logname, 'nodes/%s/' % nodename) + +def create_destdirs(logname, nodenames): +    for nodename in nodenames: +        d = 'nodes/%s' % nodename +        if not os.access(d, os.F_OK): +            os.makedirs(d) + +def main(): +    parser = argparse.ArgumentParser(description="") +    parser.add_argument('config', help="System configuration") +    parser.add_argument('--logname', help="Log name", default="mylog") +    args = parser.parse_args() + +    logname = args.logname +    config = yaml.load(open(args.config)) +    nodenames = [node["name"] for node in +                 config["frontendnodes"] + +                 config["storagenodes"] + +                 config["signingnodes"]] +    mergenodenames = [node["name"] for node in config["mergenodes"]] + +    create_destdirs(logname, nodenames + mergenodenames) +    make_eckey(logname) +    copy_logkey(logname, nodenames + mergenodenames) +    make_certs(logname, nodenames) +    make_authkeys(nodenames + mergenodenames) + +main() | 
