aboutsummaryrefslogtreecommitdiff
path: root/ca
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2014-08-04 22:16:34 +0000
committerRob Austein <sra@hactrn.net>2014-08-04 22:16:34 +0000
commit1d32064a1cfa3a32e99533f80030fd84b1c66b3b (patch)
treeb633d54158057185141db1f30cc8a170caa448ee /ca
parentaff5a1ca9e692a68fccff07bb7ed03b5bfa035df (diff)
rootd now uses publication protocol. Not yet usable outside smoketest
harness: still need to work out what BPKI configuration looks like with modern IRDB, and rootd doesn't yet handle restart correctly (will fail if any of its outputs already exist in pubd's database). svn path=/branches/tk705/; revision=5911
Diffstat (limited to 'ca')
-rw-r--r--ca/rpki-confgen.xml84
-rw-r--r--ca/tests/smoketest.py199
2 files changed, 158 insertions, 125 deletions
diff --git a/ca/rpki-confgen.xml b/ca/rpki-confgen.xml
index 5468db50..7eb62111 100644
--- a/ca/rpki-confgen.xml
+++ b/ca/rpki-confgen.xml
@@ -647,10 +647,9 @@
</doc>
<doc>
- Ok, if that wasn't enough to scare you off: rootd is a mess, and
- needs to be rewritten, or, better, merged into rpkid. It
- doesn't use the publication protocol, and it requires far too
- many configuration parameters.
+ Ok, if that wasn't enough to scare you off: rootd is a mess,
+ needs to be rewritten, or, better, merged into rpkid, and
+ requires far too many configuration parameters.
</doc>
<doc>
@@ -735,16 +734,14 @@
</doc>
</option>
- <option name = "rpki-root-dir"
- value = "${myrpki::publication_base_directory}">
+ <option name = "rpki_data_dir"
+ value = "${myrpki::bpki_servers_directory}">
<doc>
- Where rootd should write its output. Yes, rootd should be using
- pubd instead of publishing directly, but it doesn't. This
- needs to match pubd's configuration.
+ Directory where rootd should store its RPKI data files.
</doc>
</option>
- <option name = "rpki-base-uri"
+ <option name = "rpki_base_uri"
value = "rsync://${myrpki::publication_rsync_server}/${myrpki::publication_rsync_module}/">
<doc>
rsync URI corresponding to directory containing rootd's outputs.
@@ -758,52 +755,65 @@
</doc>
</option>
- <option name = "rpki-root-key"
- value = "${myrpki::bpki_servers_directory}/root.key">
+ <option name = "rpki-root-cert-file"
+ value = "${rootd::rpki_data_dir}/root.cer">
<doc>
- Private key corresponding to rootd's root RPKI certificate.
+ Filename (as opposed to rsync URI) of rootd's root RPKI
+ certificate.
</doc>
</option>
- <option name = "rpki-root-cert"
- value = "${myrpki::publication_root_cert_directory}/root.cer">
+ <option name = "rpki-root-key-file"
+ value = "${rootd::rpki_data_dir}/root.key">
<doc>
- Filename (as opposed to rsync URI) of rootd's root RPKI
- certificate.
+ Private key corresponding to rootd's root RPKI certificate.
</doc>
</option>
- <option name = "rpki-subject-pkcs10"
- value = "${myrpki::bpki_servers_directory}/rootd.subject.pkcs10">
+ <option name = "rpki-root-crl-uri"
+ value = "${rootd::rpki_base_uri}/root.crl">
<doc>
- Where rootd should stash a copy of the PKCS #10 request it gets
- from its one (and only) child
+ URI of the CRL for rootd's root RPKI certificate.
</doc>
</option>
- <option name = "rpki-subject-lifetime"
- value = "30d">
+ <option name = "rpki-root-crl-file"
+ value = "${rootd::rpki_data_dir}/root.crl">
<doc>
- Lifetime of the one and only RPKI certificate rootd issues.
+ Filename of the CRL for rootd's root RPKI certificate.
</doc>
</option>
- <option name = "rpki-root-crl"
- value = "root.crl">
+ <option name = "rpki-root-manifest-uri"
+ value = "${rootd::rpki_base_uri}/root.mft">
<doc>
- Filename (relative to rootd-base-uri and rpki-root-dir) of the CRL
- for rootd's root RPKI certificate.
+ URI of the manifest for rootd's root RPKI certificate.
</doc>
</option>
- <option name = "rpki-root-manifest"
- value = "root.mft">
+ <option name = "rpki-root-manifest-file"
+ value = "${rootd::rpki_data_dir}/root.mft">
<doc>
Filename (relative to rootd-base-uri and rpki-root-dir) of the
manifest for rootd's root RPKI certificate.
</doc>
</option>
+ <option name = "rpki-subject-pkcs10-file"
+ value = "${rootd::rpki_data_dir}/subject.pkcs10">
+ <doc>
+ Where rootd should stash a copy of the PKCS #10 request it gets
+ from its one (and only) child
+ </doc>
+ </option>
+
+ <option name = "rpki-subject-lifetime"
+ value = "30d">
+ <doc>
+ Lifetime of the one and only RPKI certificate rootd issues.
+ </doc>
+ </option>
+
<option name = "rpki-class-name"
value = "${myrpki::handle}">
<doc>
@@ -812,11 +822,17 @@
</doc>
</option>
- <option name = "rpki-subject-cert"
- value = "${myrpki::handle}.cer">
+ <option name = "rpki-subject-cert-uri"
+ value = "${rootd::rpki_base_uri}/${myrpki::handle}.cer">
+ <doc>
+ URI of the one (and only) RPKI certificate rootd issues.
+ </doc>
+ </option>
+
+ <option name = "rpki-subject-cert-file"
+ value = "${rootd::rpki_data_dir}/${myrpki::handle}.cer">
<doc>
- Filename (relative to rootd-base-uri and rpki-root-dir) of the one
- (and only) RPKI certificate rootd issues.
+ Filename of the one (and only) RPKI certificate rootd issues.
</doc>
</option>
diff --git a/ca/tests/smoketest.py b/ca/tests/smoketest.py
index 53e65b9f..28905d90 100644
--- a/ca/tests/smoketest.py
+++ b/ca/tests/smoketest.py
@@ -221,7 +221,7 @@ def main():
a.setup_bpki_certs()
setup_publication(pubd_sql)
- setup_rootd(db.root, y.get("rootd", {}))
+ setup_rootd(db.root, y.get("rootd", {}), db)
setup_rsyncd()
setup_rcynic()
@@ -250,11 +250,18 @@ def main():
# the code until final exit is all closures.
def start():
- rpki.async.iterator(db.engines, create_rpki_objects, yaml_loop)
+ rpki.async.iterator(db.engines, create_rpki_objects, create_pubd_objects)
def create_rpki_objects(iterator, a):
a.create_rpki_objects(iterator)
+ def create_pubd_objects():
+ call_pubd([rpki.publication_control.client_elt.make_pdu(action = "create",
+ client_handle = db.root.client_handle + "-" + rootd_name,
+ base_uri = rootd_sia,
+ bpki_cert = cross_certify(rootd_name + "-TA", pubd_name + "-TA"))],
+ cb = lambda ignored: yaml_loop())
+
def yaml_loop():
# This is probably where we should be updating expired BPKI
@@ -749,13 +756,13 @@ class allocation(object):
logger.info("Writing config files for %s", self.name)
assert self.rpki_port is not None
- d = { "my_name" : self.name,
- "irdb_db_name" : self.irdb_db_name,
- "irdb_db_pass" : irdb_db_pass,
- "irdb_port" : self.irdb_port,
- "rpki_db_name" : self.rpki_db_name,
- "rpki_db_pass" : rpki_db_pass,
- "rpki_port" : self.rpki_port }
+ d = dict(my_name = self.name,
+ irdb_db_name = self.irdb_db_name,
+ irdb_db_pass = irdb_db_pass,
+ irdb_port = self.irdb_port,
+ rpki_db_name = self.rpki_db_name,
+ rpki_db_pass = rpki_db_pass,
+ rpki_port = self.rpki_port)
f = open(self.name + ".conf", "w")
f.write(conf_fmt_1 % d)
for line in self.extra_conf:
@@ -935,45 +942,7 @@ class allocation(object):
certificant = self.name + "-SELF"
else:
certifier = self.name + "-SELF"
- certfile = certifier + "-" + certificant + ".cer"
-
- logger.info("Cross certifying %s into %s's BPKI (%s)", certificant, certifier, certfile)
-
- child = rpki.x509.X509(Auto_file = certificant + ".cer")
- parent = rpki.x509.X509(Auto_file = certifier + ".cer")
- keypair = rpki.x509.RSA(Auto_file = certifier + ".key")
- serial_file = certifier + ".srl"
-
- now = rpki.sundial.now()
- notAfter = now + rpki.sundial.timedelta(days = 30)
-
- try:
- f = open(serial_file, "r")
- serial = f.read()
- f.close()
- serial = int(serial.splitlines()[0], 16)
- except IOError:
- serial = 1
-
- x = parent.bpki_cross_certify(
- keypair = keypair,
- source_cert = child,
- serial = serial,
- notAfter = notAfter,
- now = now)
-
- f = open(serial_file, "w")
- f.write("%02x\n" % (serial + 1))
- f.close()
-
- f = open(certfile, "w")
- f.write(x.get_PEM())
- f.close()
-
- logger.debug("Cross certified %s:", certfile)
- logger.debug(" Issuer %s [%s]", x.getIssuer(), x.hAKI())
- logger.debug(" Subject %s [%s]", x.getSubject(), x.hSKI())
- return x
+ return cross_certify(certificant, certifier)
def create_rpki_objects(self, cb):
"""
@@ -992,13 +961,11 @@ class allocation(object):
selves = [self] + self.hosts
- for i, s in enumerate(selves):
- logger.info("Creating RPKI objects for [%d] %s", i, s.name)
-
rpkid_pdus = []
pubd_pdus = []
- for s in selves:
+ for i, s in enumerate(selves):
+ logger.info("Creating RPKI objects for [%d] %s", i, s.name)
rpkid_pdus.append(rpki.left_right.self_elt.make_pdu(
action = "create",
@@ -1188,17 +1155,18 @@ def setup_bpki_cert_chain(name, ee = (), ca = ()):
s = "exec >/dev/null 2>&1\n"
#s = "set -x\n"
for kind in ("TA",) + ee + ca:
- d = { "name" : name,
- "kind" : kind,
- "ca" : "false" if kind in ee else "true",
- "openssl" : prog_openssl }
+ d = dict(name = name,
+ kind = kind,
+ ca = "false" if kind in ee else "true",
+ openssl = prog_openssl)
f = open("%(name)s-%(kind)s.conf" % d, "w")
f.write(bpki_cert_fmt_1 % d)
f.close()
if not os.path.exists("%(name)s-%(kind)s.key" % d):
s += bpki_cert_fmt_2 % d
s += bpki_cert_fmt_3 % d
- d = { "name" : name, "openssl" : prog_openssl }
+ d = dict(name = name,
+ openssl = prog_openssl)
s += bpki_cert_fmt_4 % d
for kind in ee + ca:
d["kind"] = kind
@@ -1208,20 +1176,24 @@ def setup_bpki_cert_chain(name, ee = (), ca = ()):
s += bpki_cert_fmt_6 % d
subprocess.check_call(s, shell = True)
-def setup_rootd(rpkid, rootd_yaml):
+def setup_rootd(rpkid, rootd_yaml, db):
"""
Write the config files for rootd.
"""
rpkid.cross_certify(rootd_name + "-TA", reverse = True)
+ cross_certify(pubd_name + "-TA", rootd_name + "-TA")
logger.info("Writing config files for %s", rootd_name)
- d = { "rootd_name" : rootd_name,
- "rootd_port" : rootd_port,
- "rpkid_name" : rpkid.name,
- "rootd_sia" : rootd_sia,
- "rsyncd_dir" : rsyncd_dir,
- "openssl" : prog_openssl,
- "lifetime" : rootd_yaml.get("lifetime", "30d") }
+ d = dict(rootd_name = rootd_name,
+ rootd_port = rootd_port,
+ rpkid_name = rpkid.name,
+ pubd_name = pubd_name,
+ rootd_sia = rootd_sia,
+ rsyncd_dir = rsyncd_dir,
+ openssl = prog_openssl,
+ lifetime = rootd_yaml.get("lifetime", "30d"),
+ pubd_port = pubd_port,
+ rootd_handle = db.root.client_handle + "-" + rootd_name)
f = open(rootd_name + ".conf", "w")
f.write(rootd_fmt_1 % d)
f.close()
@@ -1238,9 +1210,9 @@ def setup_rcynic():
"""
logger.info("Config file for rcynic")
- d = { "rcynic_name" : rcynic_name,
- "rootd_name" : rootd_name,
- "rootd_sia" : rootd_sia }
+ d = dict(rcynic_name = rcynic_name,
+ rootd_name = rootd_name,
+ rootd_sia = rootd_sia)
f = open(rcynic_name + ".conf", "w")
f.write(rcynic_fmt_1 % d)
f.close()
@@ -1251,10 +1223,10 @@ def setup_rsyncd():
"""
logger.info("Config file for rsyncd")
- d = { "rsyncd_name" : rsyncd_name,
- "rsyncd_port" : rsyncd_port,
- "rsyncd_module" : rsyncd_module,
- "rsyncd_dir" : rsyncd_dir }
+ d = dict(rsyncd_name = rsyncd_name,
+ rsyncd_port = rsyncd_port,
+ rsyncd_module = rsyncd_module,
+ rsyncd_dir = rsyncd_dir)
f = open(rsyncd_name + ".conf", "w")
f.write(rsyncd_fmt_1 % d)
f.close()
@@ -1283,12 +1255,12 @@ def setup_publication(pubd_sql):
if "DROP TABLE IF EXISTS" not in sql.upper():
raise
db.close()
- d = { "pubd_name" : pubd_name,
- "pubd_port" : pubd_port,
- "pubd_db_name" : pubd_db_name,
- "pubd_db_user" : pubd_db_user,
- "pubd_db_pass" : pubd_db_pass,
- "pubd_dir" : rsyncd_dir }
+ d = dict(pubd_name = pubd_name,
+ pubd_port = pubd_port,
+ pubd_db_name = pubd_db_name,
+ pubd_db_user = pubd_db_user,
+ pubd_db_pass = pubd_db_pass,
+ pubd_dir = rsyncd_dir)
f = open(pubd_name + ".conf", "w")
f.write(pubd_fmt_1 % d)
f.close()
@@ -1323,7 +1295,7 @@ def call_pubd(pdus, cb):
logger.debug(r_cms.pretty_print_content())
assert r_msg.is_reply
for r_pdu in r_msg:
- assert not isinstance(r_pdu, rpki.publication_control.report_error_elt)
+ r_pdu.raise_if_error()
cb(r_msg)
def call_pubd_eb(e):
@@ -1335,6 +1307,48 @@ def call_pubd(pdus, cb):
callback = call_pubd_cb,
errback = call_pubd_eb)
+
+def cross_certify(certificant, certifier):
+ """
+ Cross-certify and return the resulting certificate.
+ """
+
+ certfile = certifier + "-" + certificant + ".cer"
+
+ logger.info("Cross certifying %s into %s's BPKI (%s)", certificant, certifier, certfile)
+
+ child = rpki.x509.X509(Auto_file = certificant + ".cer")
+ parent = rpki.x509.X509(Auto_file = certifier + ".cer")
+ keypair = rpki.x509.RSA(Auto_file = certifier + ".key")
+ serial_file = certifier + ".srl"
+
+ now = rpki.sundial.now()
+ notAfter = now + rpki.sundial.timedelta(days = 30)
+
+ try:
+ with open(serial_file, "r") as f:
+ serial = int(f.read().splitlines()[0], 16)
+ except IOError:
+ serial = 1
+
+ x = parent.bpki_cross_certify(
+ keypair = keypair,
+ source_cert = child,
+ serial = serial,
+ notAfter = notAfter,
+ now = now)
+
+ with open(serial_file, "w") as f:
+ f.write("%02x\n" % (serial + 1))
+
+ with open(certfile, "w") as f:
+ f.write(x.get_PEM())
+
+ logger.debug("Cross certified %s:", certfile)
+ logger.debug(" Issuer %s [%s]", x.getIssuer(), x.hAKI())
+ logger.debug(" Subject %s [%s]", x.getSubject(), x.hSKI())
+ return x
+
last_rcynic_run = None
def run_rcynic():
@@ -1533,24 +1547,28 @@ rootd-bpki-cert = %(rootd_name)s-RPKI.cer
rootd-bpki-key = %(rootd_name)s-RPKI.key
rootd-bpki-crl = %(rootd_name)s-TA.crl
child-bpki-cert = %(rootd_name)s-TA-%(rpkid_name)s-SELF.cer
+pubd-bpki-cert = %(rootd_name)s-TA-%(pubd_name)s-TA.cer
server-port = %(rootd_port)s
-rpki-root-dir = %(rsyncd_dir)sroot
-rpki-base-uri = %(rootd_sia)sroot/
-rpki-root-cert-uri = %(rootd_sia)sroot.cer
+rpki-class-name = trunk
+
+pubd-contact-uri = http://localhost:%(pubd_port)d/client/%(rootd_handle)s
-rpki-root-key = root.key
-rpki-root-cert = root.cer
+rpki-root-cert-file = root.cer
+rpki-root-cert-uri = %(rootd_sia)sroot.cer
+rpki-root-key-file = root.key
-rpki-subject-pkcs10 = %(rootd_name)s.subject.pkcs10
+rpki-subject-cert-file = trunk.cer
+rpki-subject-cert-uri = %(rootd_sia)sroot/trunk.cer
+rpki-subject-pkcs10-file= trunk.p10
rpki-subject-lifetime = %(lifetime)s
-rpki-root-crl = root.crl
-rpki-root-manifest = root.mft
+rpki-root-crl-file = root.crl
+rpki-root-crl-uri = %(rootd_sia)sroot/root.crl
-rpki-class-name = trunk
-rpki-subject-cert = trunk.cer
+rpki-root-manifest-file = root.mft
+rpki-root-manifest-uri = %(rootd_sia)sroot/root.mft
include-bpki-crl = yes
enable_tracebacks = yes
@@ -1610,8 +1628,7 @@ awk '!/-----(BEGIN|END)/' >>%(rootd_name)s.tal &&
-outform DER \
-extfile %(rootd_name)s.conf \
-extensions req_x509_rpki_ext \
- -signkey root.key &&
-ln -f root.cer %(rsyncd_dir)s
+ -signkey root.key
'''
rcynic_fmt_1 = '''\