aboutsummaryrefslogtreecommitdiff
path: root/rpkid
diff options
context:
space:
mode:
Diffstat (limited to 'rpkid')
-rwxr-xr-xrpkid/rootd.py146
-rw-r--r--rpkid/rpki/exceptions.py3
-rw-r--r--rpkid/rpki/left_right.py12
-rw-r--r--rpkid/rpki/rpki_engine.py4
-rw-r--r--rpkid/rpki/x509.py4
-rw-r--r--rpkid/testbed.5.yaml8
6 files changed, 106 insertions, 71 deletions
diff --git a/rpkid/rootd.py b/rpkid/rootd.py
index cc5240d5..cccf4805 100755
--- a/rpkid/rootd.py
+++ b/rpkid/rootd.py
@@ -50,12 +50,85 @@ def del_subject_cert():
rpki.log.debug("Deleting subject cert %s" % filename)
os.remove(filename)
-def stash_subject_pkcs10(pkcs10):
- if rpki_subject_pkcs10:
- rpki.log.debug("Writing subject PKCS #10 %s" % rpki_subject_pkcs10)
- f = open(rpki_subject_pkcs10, "wb")
- f.write(pkcs10.get_DER())
- f.close()
+def get_subject_pkcs10():
+ filename = rpki_subject_pkcs10
+ try:
+ x = rpki.x509.PKCS10(Auto_file = filename)
+ rpki.log.debug("Read subject PKCS #10 %s" % filename)
+ return x
+ except IOError:
+ return None
+
+def set_subject_pkcs10(pkcs10):
+ rpki.log.debug("Writing subject PKCS #10 %s" % rpki_subject_pkcs10)
+ f = open(rpki_subject_pkcs10, "wb")
+ f.write(pkcs10.get_DER())
+ f.close()
+
+def issue_subject_cert_maybe():
+ subject_cert = get_subject_cert()
+ if subject_cert is not None:
+ if not subject_cert.expired():
+ return subject_cert
+ rpki.log.debug("Subject certificate has expired")
+ pkcs10 = get_subject_pkcs10()
+ if pkcs10 is None:
+ rpki.log.debug("No saved PKCS #10 request")
+ return None
+ resources = rpki_root_cert.get_3779resources()
+ rpki.log.info("Generating subject cert with resources " + str(resources))
+ req_key = pkcs10.getPublicKey()
+ req_sia = pkcs10.get_SIA()
+ crldp = rpki_base_uri + rpki_root_crl
+ now = rpki.sundial.now()
+ subject_cert = rpki_root_cert.issue(
+ keypair = rpki_root_key,
+ subject_key = req_key,
+ serial = int(time.time()),
+ sia = req_sia,
+ aia = rpki_root_cert_uri,
+ crldp = crldp,
+ resources = resources,
+ notAfter = now + rpki_subject_lifetime)
+ crl = rpki.x509.CRL.generate(
+ keypair = rpki_root_key,
+ issuer = rpki_root_cert,
+ serial = 1,
+ thisUpdate = now,
+ nextUpdate = now + rpki_subject_lifetime,
+ revokedCertificates = ())
+ rpki.log.debug("Writing CRL %s" % (rpki_root_dir + rpki_root_crl))
+ f = open(rpki_root_dir + rpki_root_crl, "wb")
+ f.write(crl.get_DER())
+ f.close()
+ manifest_resources = rpki.resource_set.resource_bag(
+ asn = rpki.resource_set.resource_set_as("<inherit>"),
+ v4 = rpki.resource_set.resource_set_ipv4("<inherit>"),
+ v6 = rpki.resource_set.resource_set_ipv6("<inherit>"))
+ manifest_keypair = rpki.x509.RSA.generate()
+ manifest_cert = rpki_root_cert.issue(
+ keypair = rpki_root_key,
+ subject_key = manifest_keypair.get_RSApublic(),
+ serial = int(time.time()) + 1,
+ sia = None,
+ aia = rpki_root_cert_uri,
+ crldp = crldp,
+ resources = manifest_resources,
+ notAfter = now + rpki_subject_lifetime,
+ is_ca = False)
+ manifest = rpki.x509.SignedManifest.build(
+ serial = int(time.time()),
+ thisUpdate = now,
+ nextUpdate = now + rpki_subject_lifetime,
+ names_and_objs = [(rpki_subject_cert, subject_cert), (rpki_root_crl, crl)],
+ keypair = manifest_keypair,
+ certs = manifest_cert)
+ rpki.log.debug("Writing manifest %s" % (rpki_root_dir + rpki_root_manifest))
+ f = open(rpki_root_dir + rpki_root_manifest, "wb")
+ f.write(manifest.get_DER())
+ f.close()
+ set_subject_cert(subject_cert)
+ return subject_cert
def compose_response(r_msg):
rc = rpki.up_down.class_elt()
@@ -64,7 +137,7 @@ def compose_response(r_msg):
rc.from_resource_bag(rpki_root_cert.get_3779resources())
rc.issuer = rpki_root_cert
r_msg.payload.classes.append(rc)
- subject_cert = get_subject_cert()
+ subject_cert = issue_subject_cert_maybe()
if subject_cert is not None:
rc.certs.append(rpki.up_down.certificate_elt())
rc.certs[0].cert_url = rpki.up_down.multi_uri(rpki_base_uri + rpki_subject_cert)
@@ -77,64 +150,9 @@ class list_pdu(rpki.up_down.list_pdu):
class issue_pdu(rpki.up_down.issue_pdu):
def serve_pdu(self, q_msg, r_msg, ignored):
- stash_subject_pkcs10(self.pkcs10)
self.pkcs10.check_valid_rpki()
+ set_subject_pkcs10(self.pkcs10)
r_msg.payload = rpki.up_down.issue_response_pdu()
- subject_cert = get_subject_cert()
- if subject_cert is None:
- resources = rpki_root_cert.get_3779resources()
- rpki.log.info("Generating subject cert with resources " + str(resources))
- req_key = self.pkcs10.getPublicKey()
- req_sia = self.pkcs10.get_SIA()
- crldp = rpki_base_uri + rpki_root_crl
- now = rpki.sundial.now()
- subject_cert = rpki_root_cert.issue(
- keypair = rpki_root_key,
- subject_key = req_key,
- serial = int(time.time()),
- sia = req_sia,
- aia = rpki_root_cert_uri,
- crldp = crldp,
- resources = resources,
- notAfter = now + rpki_subject_lifetime)
- set_subject_cert(subject_cert)
- crl = rpki.x509.CRL.generate(
- keypair = rpki_root_key,
- issuer = rpki_root_cert,
- serial = 1,
- thisUpdate = now,
- nextUpdate = now + rpki_subject_lifetime,
- revokedCertificates = ())
- rpki.log.debug("Writing CRL %s" % (rpki_root_dir + rpki_root_crl))
- f = open(rpki_root_dir + rpki_root_crl, "wb")
- f.write(crl.get_DER())
- f.close()
- manifest_resources = rpki.resource_set.resource_bag(
- asn = rpki.resource_set.resource_set_as("<inherit>"),
- v4 = rpki.resource_set.resource_set_ipv4("<inherit>"),
- v6 = rpki.resource_set.resource_set_ipv6("<inherit>"))
- manifest_keypair = rpki.x509.RSA.generate()
- manifest_cert = rpki_root_cert.issue(
- keypair = rpki_root_key,
- subject_key = manifest_keypair.get_RSApublic(),
- serial = int(time.time()) + 1,
- sia = None,
- aia = rpki_root_cert_uri,
- crldp = crldp,
- resources = manifest_resources,
- notAfter = now + rpki_subject_lifetime,
- is_ca = False)
- manifest = rpki.x509.SignedManifest.build(
- serial = int(time.time()),
- thisUpdate = now,
- nextUpdate = now + rpki_subject_lifetime,
- names_and_objs = [(rpki_subject_cert, subject_cert), (rpki_root_crl, crl)],
- keypair = manifest_keypair,
- certs = manifest_cert)
- rpki.log.debug("Writing manifest %s" % (rpki_root_dir + rpki_root_manifest))
- f = open(rpki_root_dir + rpki_root_manifest, "wb")
- f.write(manifest.get_DER())
- f.close()
compose_response(r_msg)
class revoke_pdu(rpki.up_down.revoke_pdu):
@@ -224,7 +242,7 @@ rpki_root_cert_uri = cfg.get("rpki-root-cert-uri", rpki_base_uri + "Root.ce
rpki_root_manifest = cfg.get("rpki-root-manifest", "Root.mnf")
rpki_root_crl = cfg.get("rpki-root-crl", "Root.crl")
rpki_subject_cert = cfg.get("rpki-subject-cert", "Subroot.cer")
-rpki_subject_pkcs10 = cfg.get("rpki-subject-pkcs10", "")
+rpki_subject_pkcs10 = cfg.get("rpki-subject-pkcs10", "Subroot.pkcs10")
rpki_subject_lifetime = rpki.sundial.timedelta.parse(cfg.get("rpki-subject-lifetime", "30d"))
diff --git a/rpkid/rpki/exceptions.py b/rpkid/rpki/exceptions.py
index 4c1183be..393700e6 100644
--- a/rpkid/rpki/exceptions.py
+++ b/rpkid/rpki/exceptions.py
@@ -77,6 +77,9 @@ class BadSender(RPKI_Exception):
class ClassNameMismatch(RPKI_Exception):
"""class_name does not match child context."""
+class ClassNameUnknown(RPKI_Exception):
+ """Unknown class_name."""
+
class SKIMismatch(RPKI_Exception):
"""SKI value in response does not match request."""
diff --git a/rpkid/rpki/left_right.py b/rpkid/rpki/left_right.py
index 55127bef..82bf93f4 100644
--- a/rpkid/rpki/left_right.py
+++ b/rpkid/rpki/left_right.py
@@ -174,6 +174,8 @@ class self_elt(data_elt):
now = rpki.sundial.now()
+ rsn = now + rpki.sundial.timedelta(seconds = self.regen_margin)
+
for child in self.children():
child_certs = child.child_certs()
if not child_certs:
@@ -188,12 +190,14 @@ class self_elt(data_elt):
continue
old_resources = child_cert.cert.get_3779resources()
new_resources = irdb_resources.intersection(old_resources)
- if old_resources != new_resources:
- rpki.log.debug("Need to reissue %s" % repr(child_cert))
+ if old_resources != new_resources or (old_resources.valid_until < rsn and irdb_resources.valid_until > now):
+ rpki.log.debug("Need to reissue child certificate SKI %s" % child_cert.cert.gSKI())
child_cert.reissue(
ca_detail = ca_detail,
resources = new_resources)
elif old_resources.valid_until < now:
+ rpki.log.debug("Child certificate SKI %s has expired: cert.valid_until %s, irdb.valid_until %s"
+ % (child_cert.cert.gSKI(), old_resources.valid_until, irdb_resources.valid_until))
ca = ca_detail.ca()
parent = ca.parent()
repository = parent.repository()
@@ -392,9 +396,11 @@ class child_elt(data_elt):
if not class_name.isdigit():
raise rpki.exceptions.BadClassNameSyntax, "Bad class name %s" % class_name
ca = rpki.rpki_engine.ca_obj.sql_fetch(self.gctx, long(class_name))
+ if ca is None:
+ raise rpki.exceptions.ClassNameUnknown, "Unknown class name %s" % class_name
parent = ca.parent()
if self.self_id != parent.self_id:
- raise rpki.exceptions.ClassNameMismatch, "child.self_id = %d, parent.self_id = %d" % (self.self_id, parent.self_id)
+ raise rpki.exceptions.ClassNameMismatch, "Class name mismatch: child.self_id = %d, parent.self_id = %d" % (self.self_id, parent.self_id)
return ca
def serve_post_save_hook(self, q_pdu, r_pdu):
diff --git a/rpkid/rpki/rpki_engine.py b/rpkid/rpki/rpki_engine.py
index 1e9f8518..1185f4ce 100644
--- a/rpkid/rpki/rpki_engine.py
+++ b/rpkid/rpki/rpki_engine.py
@@ -118,9 +118,13 @@ class rpkid_context(object):
try:
self.sql.ping()
for s in rpki.left_right.self_elt.sql_fetch_all(self):
+ rpki.log.debug("Self %s polling parents" % s.self_id)
s.client_poll()
+ rpki.log.debug("Self %s updating children" % s.self_id)
s.update_children()
+ rpki.log.debug("Self %s updating ROAs" % s.self_id)
s.update_roas()
+ rpki.log.debug("Self %s regenerating CRLs and manifests" % s.self_id)
s.regenerate_crls_and_manifests()
self.sql.sweep()
return 200, "OK"
diff --git a/rpkid/rpki/x509.py b/rpkid/rpki/x509.py
index 2c8d20b1..53dfab79 100644
--- a/rpkid/rpki/x509.py
+++ b/rpkid/rpki/x509.py
@@ -333,6 +333,10 @@ class X509(DER_object):
"""Extract the public key from this certificate."""
return RSApublic(DER = self.get_POWpkix().tbs.subjectPublicKeyInfo.toString())
+ def expired(self):
+ """Test whether this certificate has expired."""
+ return self.getNotAfter() <= rpki.sundial.now()
+
def issue(self, keypair, subject_key, serial, sia, aia, crldp, notAfter,
cn = None, resources = None, is_ca = True):
"""Issue a certificate."""
diff --git a/rpkid/testbed.5.yaml b/rpkid/testbed.5.yaml
index 3d1498a6..7c06ede2 100644
--- a/rpkid/testbed.5.yaml
+++ b/rpkid/testbed.5.yaml
@@ -15,11 +15,11 @@
# PERFORMANCE OF THIS SOFTWARE.
rootd:
- lifetime: 2m
+ lifetime: 2m30s
name: RIR
-crl_interval: 90s
-regen_margin: 1m
-valid_for: 2m
+crl_interval: 1m30s
+regen_margin: 2m
+valid_for: 2m30s
kids:
- name: R0
kids: