diff options
Diffstat (limited to 'rpkid')
-rwxr-xr-x | rpkid/rootd.py | 146 | ||||
-rw-r--r-- | rpkid/rpki/exceptions.py | 3 | ||||
-rw-r--r-- | rpkid/rpki/left_right.py | 12 | ||||
-rw-r--r-- | rpkid/rpki/rpki_engine.py | 4 | ||||
-rw-r--r-- | rpkid/rpki/x509.py | 4 | ||||
-rw-r--r-- | rpkid/testbed.5.yaml | 8 |
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: |