aboutsummaryrefslogtreecommitdiff
path: root/ca
diff options
context:
space:
mode:
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 = '''\