aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2016-05-05 06:23:24 +0000
committerRob Austein <sra@hactrn.net>2016-05-05 06:23:24 +0000
commit628fac246498569c4ceed6a2d4a033d9254befb0 (patch)
treee02601efadb22aff1ac1a66e50c7dae5df08e3b6
parent74609ee8900501784f7f1a3f568a42503e3a1f86 (diff)
rootd migration finally working right. I think. Could stand more testing.
svn path=/branches/tk705/; revision=6421
-rwxr-xr-xpotpourri/ca-unpickle.py91
-rw-r--r--rpki/irdbd.py10
-rw-r--r--rpki/rpkic.py14
-rw-r--r--rpki/rpkidb/models.py8
4 files changed, 105 insertions, 18 deletions
diff --git a/potpourri/ca-unpickle.py b/potpourri/ca-unpickle.py
index b2889d1d..9fa30bed 100755
--- a/potpourri/ca-unpickle.py
+++ b/potpourri/ca-unpickle.py
@@ -277,6 +277,16 @@ class Root(object):
now = rpki.sundial.now()
+ crl_interval = cfg.getint(section = "myrpki",
+ option = "tenant_crl_interval",
+ default = 6 * 60 * 60)
+
+ regen_margin = cfg.getint(section = "myrpki",
+ option = "tenant_regen_margin",
+ default = 14 * 24 * 60 * 60 + 2 * 60)
+
+ # Whole lota new BPKI glorp.
+
root_resourceholderca_serial = 1
root_resourceholderca_key = rpki.x509.RSA.generate()
root_resourceholderca_cer = rpki.x509.X509.bpki_self_certify(
@@ -362,11 +372,14 @@ class Root(object):
pathLenConstraint = 0)
serverca.next_serial += 1
+ # Various contact URIs.
+
root_up_down_path = "/up-down/{root}/{work}".format(
root = root_handle,
work = work_resourceholderca.handle)
- root_up_down_uri = fixuri.rpkid(root_up_down_path)
+ root_loopback_uri = fixuri.rpkid("/up-down/{root}/{root}".format(
+ root = root_handle))
root_publication_control_uri = fixuri.pubd("/client/{root}".format(
root = root_handle))
@@ -375,6 +388,14 @@ class Root(object):
module = cfg.get(section = "myrpki", option = "publication_rsync_module"),
handle = root_handle))
+ rpki_root_cer_uri = fixuri.rsyncd("/{module}/{gski}.cer".format(
+ module = cfg.get(section = "myrpki", option = "publication_rsync_module"),
+ gski = rpki_root_key.gSKI()))
+
+ rpki_root_crl_uri = root_rsync_uri + rpki_root_key.gSKI() + ".crl"
+
+ rpki_root_mft_uri = root_rsync_uri + rpki_root_key.gSKI() + ".mft"
+
rrdp_notification_uri = cfg.get(section = "myrpki",
option = "publication_rrdp_notification_uri")
@@ -406,6 +427,53 @@ class Root(object):
port = world.cfg.rootd.server_port):
raise RuntimeError("Pickled Rootd service_uri does not match pickled configuration")
+ # Updated RPKI root certificate, CRL and manifest.
+ # The root certificate URI here isn't really right, but it's (probably) harmless.
+
+ rpki_root_last_serial += 1
+ rpki_root_cer = rpki.x509.X509.self_certify(
+ keypair = rpki_root_key,
+ subject_key = rpki_root_key.get_public(),
+ serial = rpki_root_last_serial,
+ sia = (root_rsync_uri, rpki_root_mft_uri, None, rrdp_notification_uri),
+ notAfter = rpki_root_resources.valid_until,
+ resources = rpki_root_resources)
+
+ rpki_root_last_crl_manifest_number += 1
+
+ root_rpki_crl = rpki.x509.CRL.generate(
+ keypair = rpki_root_key,
+ issuer = rpki_root_cer,
+ serial = rpki_root_last_crl_manifest_number,
+ thisUpdate = now,
+ nextUpdate = now + rpki.sundial.timedelta(seconds = crl_interval),
+ revokedCertificates = ())
+
+ rpki_root_last_serial += 1
+ mft_cer = rpki_root_cer.issue(
+ keypair = rpki_root_key,
+ subject_key = rpki_root_mft_key.get_public(),
+ serial = rpki_root_last_serial,
+ sia = (None, None, rpki_root_mft_uri, rrdp_notification_uri),
+ resources = rpki.resource_set.resource_bag.from_inheritance(),
+ aia = rpki_root_cer_uri,
+ crldp = rpki_root_crl_uri,
+ notBefore = now,
+ notAfter = rpki_root_cer.getNotAfter(),
+ is_ca = False)
+
+ rpki_root_mft_objs = [
+ (rpki_root_key.gSKI() + ".crl", root_rpki_crl),
+ (work_resourceholderca_cer.gSKI() + ".cer", work_resourceholderca_cer)]
+
+ rpki_root_mft = rpki.x509.SignedManifest.build(
+ keypair = rpki_root_mft_key,
+ certs = mft_cer,
+ serial = rpki_root_last_crl_manifest_number,
+ thisUpdate = now,
+ nextUpdate = now + rpki.sundial.timedelta(seconds = crl_interval),
+ names_and_objs = rpki_root_mft_objs)
+
# Adjust saved working CA's parent object to point at new root.
# We supply just the path portion of the URI here, to avoid confusing fixuri.rpkid() later.
#
@@ -426,7 +494,7 @@ class Root(object):
certificate = root_hostedca_cer,
handle = root_handle,
ta = root_resourceholderca_cer,
- service_uri = root_up_down_uri,
+ service_uri = fixuri.rpkid(root_up_down_path),
parent_handle = root_handle,
child_handle = work_rpkid_parent.sender_name,
repository_type = "none",
@@ -458,7 +526,7 @@ class Root(object):
certificate = root_parent_bpki_cer,
handle = root_handle,
ta = root_resourceholderca_cer,
- service_uri = root_up_down_uri,
+ service_uri = root_loopback_uri,
parent_handle = root_handle,
child_handle = root_handle,
repository_type = "none",
@@ -535,12 +603,8 @@ class Root(object):
self.rpkid_root_Tenant = dict(
tenant_handle = root_handle,
use_hsm = False,
- crl_interval = cfg.getint(section = "myrpki",
- option = "tenant_crl_interval",
- default = 6 * 60 * 60),
- regen_margin = cfg.getint(section = "myrpki",
- option = "tenant_regen_margin",
- default = 14 * 24 * 60 * 60 + 2 * 60),
+ crl_interval = crl_interval,
+ regen_margin = regen_margin,
bpki_cert = root_hostedca_cer,
bpki_glue = None,
)
@@ -557,6 +621,7 @@ class Root(object):
self.rpkid_root_Repository = dict(
repository_handle = root_handle,
peer_contact_uri = root_publication_control_uri,
+ rrdp_notification_uri = rrdp_notification_uri,
bpki_cert = root_repository_bpki_cer,
bpki_glue = None,
last_cms_timestamp = None,
@@ -567,7 +632,7 @@ class Root(object):
parent_handle = root_handle,
bpki_cert = root_parent_bpki_cer,
bpki_glue = None,
- peer_contact_uri = root_up_down_uri,
+ peer_contact_uri = root_loopback_uri,
sia_base = root_rsync_uri,
sender_name = root_handle,
recipient_name = root_handle,
@@ -589,15 +654,15 @@ class Root(object):
self.rpkid_root_CADetail = dict(
public_key = rpki_root_key.get_public(),
private_key_id = rpki_root_key,
- latest_crl = None,
+ latest_crl = rpki_root_crl,
crl_published = None,
latest_ca_cert = rpki_root_cer,
manifest_private_key_id = rpki_root_mft_key,
manifest_public_key = rpki_root_mft_key.get_public(),
- latest_manifest = None,
+ latest_manifest = rpki_root_mft,
manifest_published = None,
state = "active",
- ca_cert_uri = root_rsync_uri + rpki_root_key.gSKI() + ".cer",
+ ca_cert_uri = rpki_root_cer_uri,
# Foreign keys: ca
)
diff --git a/rpki/irdbd.py b/rpki/irdbd.py
index 7a2c4606..98fe83ea 100644
--- a/rpki/irdbd.py
+++ b/rpki/irdbd.py
@@ -35,12 +35,16 @@ import rpki.log
import rpki.x509
import rpki.daemonize
-from lxml.etree import Element, SubElement
+from lxml.etree import Element, SubElement, tostring as ElementToString
logger = logging.getLogger(__name__)
class main(object):
+ # Whether to drop XMl into the log
+
+ debug = False
+
def handle_list_resources(self, q_pdu, r_msg):
tenant_handle = q_pdu.get("tenant_handle")
child_handle = q_pdu.get("child_handle")
@@ -117,6 +121,8 @@ class main(object):
q_cms = rpki.left_right.cms_msg(DER = q_der)
q_msg = q_cms.unwrap((serverCA.certificate, rpkid.certificate))
self.cms_timestamp = q_cms.check_replay(self.cms_timestamp, request.path)
+ if self.debug:
+ logger.debug("Received: %s", ElementToString(q_msg))
if q_msg.get("type") != "query":
raise rpki.exceptions.BadQuery("Message type is {}, expected query".format(
q_msg.get("type")))
@@ -134,6 +140,8 @@ class main(object):
if q_pdu.get("tag") is not None:
r_pdu.set("tag", q_pdu.get("tag"))
+ if self.debug:
+ logger.debug("Sending: %s", ElementToString(r_msg))
request.send_cms_response(rpki.left_right.cms_msg().wrap(
r_msg, irdbd.private_key, irdbd.certificate))
diff --git a/rpki/rpkic.py b/rpki/rpkic.py
index d90ad690..5e0efe0f 100644
--- a/rpki/rpkic.py
+++ b/rpki/rpkic.py
@@ -868,6 +868,20 @@ class main(Cmd):
@parsecmd(argsubparsers)
+ def do_force_run_now(self, args):
+ """
+ Force rpkid to run periodic tasks for this Tenant immediately.
+
+ This is not usually necessary, as rpkid runs all of these
+ tasks on a regular schedule, but this command can be useful
+ occasionally when configuration change is taking a long time
+ to percolate through a series of parent/child exchanges.
+ """
+
+ self.zoo.run_rpkid_now()
+
+
+ @parsecmd(argsubparsers)
def do_up_down_rekey(self, args):
"""
Initiate a "rekey" operation.
diff --git a/rpki/rpkidb/models.py b/rpki/rpkidb/models.py
index 31c367ba..3021a0d4 100644
--- a/rpki/rpkidb/models.py
+++ b/rpki/rpkidb/models.py
@@ -748,6 +748,7 @@ class Parent(models.Model):
@tornado.gen.coroutine
def query_up_down(self, rpkid, q_msg):
trace_call_chain()
+ #logger.debug("%r query_up_down(): %s", self, ElementToString(q_msg))
if self.root_asn_resources or self.root_ipv4_resources or self.root_ipv6_resources:
r_msg = yield self.query_up_down_root(rpkid, q_msg)
elif self.bsc is None:
@@ -773,6 +774,7 @@ class Parent(models.Model):
self.tenant.bpki_cert, self.tenant.bpki_glue,
self.bpki_cert, self.bpki_glue))
r_cms.check_replay_sql(self, self.peer_contact_uri)
+ #logger.debug("%r query_up_down(): %s", self, ElementToString(r_msg))
rpki.up_down.check_response(r_msg, q_msg.get("type"))
raise tornado.gen.Return(r_msg)
@@ -798,8 +800,6 @@ class Parent(models.Model):
trace_call_chain()
publisher = rpki.rpkid.publication_queue(rpkid = rpkid)
- #logger.debug("%r query_up_down_root(): %s", self, ElementToString(q_msg))
-
r_msg = Element(rpki.up_down.tag_message,
nsmap = rpki.up_down.nsmap,
version = rpki.up_down.version,
@@ -915,8 +915,6 @@ class Parent(models.Model):
r_msg.set("type", "error_response")
SubElement(r_msg, rpki.up_down.tag_status).text = "2001"
- #logger.debug("%r query_up_down_root(): %s", self, ElementToString(r_msg))
-
raise tornado.gen.Return(r_msg)
@@ -1875,6 +1873,8 @@ class ChildCert(models.Model):
resources = old_resources
if sia is None:
sia = old_sia
+ if len(sia) < 4 or not sia[3]:
+ sia = (sia[0], sia[1], sia[2], ca_detail.ca.parent.repository.rrdp_notification_uri)
assert resources.valid_until is not None and old_resources.valid_until is not None
if resources.asn != old_resources.asn or resources.v4 != old_resources.v4 or resources.v6 != old_resources.v6:
logger.debug("Resources changed for %r: old %s new %s", self, old_resources, resources)