diff options
Diffstat (limited to 'scripts/rpki')
-rw-r--r-- | scripts/rpki/left_right.py | 12 | ||||
-rw-r--r-- | scripts/rpki/sql.py | 47 | ||||
-rw-r--r-- | scripts/rpki/up_down.py | 4 |
3 files changed, 51 insertions, 12 deletions
diff --git a/scripts/rpki/left_right.py b/scripts/rpki/left_right.py index d39c2e41..820f506e 100644 --- a/scripts/rpki/left_right.py +++ b/scripts/rpki/left_right.py @@ -260,7 +260,7 @@ class self_elt(data_elt): for parent in parent_elt.sql_fetch_where(gctx, "self_id = %s" % self.self_id): r_pdu = rpki.up_down.list_pdu(gctx, parent) ca_map = dict((ca.parent_resource_class, ca) - for ca in rpki.sql.ca_obj.sql_fetch_where(gctx, "parent_id = %s", parent.parent_id)) + for ca in rpki.sql.ca_obj.sql_fetch_where(gctx, "parent_id = %s" % parent.parent_id)) for rc in r_pdu.payload: if rc.class_name in ca_map: ca = ca_map[rc.class_name] @@ -517,6 +517,16 @@ class repository_elt(data_elt): self.make_b64elt(elt, "https_ta", self.https_ta.get_DER()) return elt + def publish(self, *things): + """Placeholder for publication operation (not yet written).""" + for thing in things: + print "Should publish %s to repository %s" % (thing, self) + + def withdraw(self, *things): + """Placeholder for publication withdrawal operation (not yet written).""" + for thing in things: + print "Should withdraw %s from repository %s" % (thing, self) + class route_origin_elt(data_elt): """<route_origin/> element.""" diff --git a/scripts/rpki/sql.py b/scripts/rpki/sql.py index 8579c7a5..1bc328a5 100644 --- a/scripts/rpki/sql.py +++ b/scripts/rpki/sql.py @@ -66,8 +66,12 @@ class sql_persistant(object): @classmethod def sql_fetch(cls, gctx, id): """Fetch one object from SQL, based on its primary key.""" - results = cls.sql_fetch_where(gctx, "%s = %s" % (cls.sql_template.index, id)) - assert len(results) <= 1 + return cls.sql_fetch_where1(gctx, "%s = %s" % (cls.sql_template.index, id)) + + @classmethod + def sql_fetch_where1(cls, gctx, where): + """Fetch one object from SQL, based on an arbitrary SQL WHERE expression.""" + results = cls.sql_fetch_where(gctx, where) if len(results) == 0: return None elif len(results) == 1: @@ -212,7 +216,7 @@ class ca_obj(sql_persistant): off to the affected ca_detail for processing. """ cert_map = dict((c.get_SKI(), c) for c in rc.certs) - ca_details = ca_detail_obj.sql_fetch_where(gctx, "ca_id = %s AND latest_ca_cert IS NOT NULL", ca.ca_id) + ca_details = ca_detail_obj.sql_fetch_where(gctx, "ca_id = %s AND latest_ca_cert IS NOT NULL" % ca.ca_id) as, v4, v6 = ca_detail_obj.sql_fetch_active(gctx, ca_id).latest_ca_cert.get_3779resources() undersized = not rc.resource_set_as.issubset(as) or \ not rc.resource_set_ipv4.issubset(v4) or not rc.resource_set_ipv6.issubset(v6) @@ -261,16 +265,18 @@ class ca_obj(sql_persistant): delete it (and its little dog too...). All certs published by this CA are now invalid, so need to - withdraw them and the CRL from the repository, delete all - child_cert and ca_detail records associated with this CA, then - finally delete this CA itself. + withdraw them, the CRL, and the manifest from the repository, + delete all child_cert and ca_detail records associated with this + CA, then finally delete this CA itself. """ - raise NotImplementedError, "Need to withdraw self and children from publication" + repository = rpki.left_right.repository_elt.sql_fetch_where1(gctx, "repository.repository_id = parent.repository_id AND parent.parent_id = %s" % self.parent_id) for ca_detail in ca_detail_obj.sql_fetch_where(gctx, "ca_id = %s" % self.ca_id): for child_cert in child_cert_obj.sql_fetch_where(gctx, "ca_detail_id = %s" % ca_detail.ca_detail_id): + repository.withdraw(child_cert.cert) child_cert.sql_delete(gctx) + repository.withdraw(ca_detail.latest_crl, ca_detail.latest_manifest, ca_detail.latest_manifest_cert) ca_detail.sql_delete(gctx) self.sql_delete(gctx) @@ -395,7 +401,15 @@ class ca_detail_obj(sql_persistant): v4 = rc_v4, v6 = rc_v6) - raise NotImplementedError, "Should generate a new manifest, should publish newly-created certificate" + manifest = self.generate_manifest() + + repository = rpki.left_right.repository_elt.sql_fetch_where1(gctx, """ + repository.repository_id = parent.repository_id AND + parent.parent_id = ca.parent_id AND + ca.ca_id = %s + """ % self.ca_id) + + repository.publish(cert, manifest) if child_cert is None: return rpki.sql.child_cert_obj(child_id = child.child_id, @@ -414,6 +428,22 @@ class ca_detail_obj(sql_persistant): raise NotImplementedError, "NIY" + def generate_manifest(self, gctx): + """Generate a new manifest for this ca_detail.""" + + ca = ca_obj.sql_fetch(gctx, self.ca_id) + self_obj = rpki.left_right.self_elt.sql_fetch_where1(gctx, "self.self_id = parent.self_id AND parent.parent_id = %s" % ca.parent_id) + certs = child_cert_obj.sql_fetch_where(gctx, "child_cert.ca_detail_id = %s AND NOT child_cert.revoked" % self.ca_detail_id) + + m = rpki.x509.SignedManifest() + m.build(serial = ca.next_manifest(), + nextUpdate = time.time() + self_obj.crl_interval, + names_and_objs = [(c.gSKI() + ".cer", c) for c in certs]) + m.sign(keypair = self.manifest_private_key_id, + certs = rpki.x509.X509_chain(self.latest_manifest_cert)) + + self.latest_manifest = m + return m class child_cert_obj(sql_persistant): """Certificate that has been issued to a child.""" @@ -425,6 +455,7 @@ class child_cert_obj(sql_persistant): self.child_id = child_id self.ca_detail_id = ca_detail_id self.cert = cert + self.revoked = False if child_id or ca_detail_id or cert: self.sql_mark_dirty() diff --git a/scripts/rpki/up_down.py b/scripts/rpki/up_down.py index 5c2ad35c..9eaddd20 100644 --- a/scripts/rpki/up_down.py +++ b/scripts/rpki/up_down.py @@ -262,11 +262,9 @@ class issue_pdu(base_elt): req_key = self.pkcs10.getPublicKey() req_sia = self.pkcs10.get_SIA() req_ski = self.pkcs10.get_SKI() - child_cert = rpki.sql.child_cert_obj.sql_fetch_where(gctx, """ + child_cert = rpki.sql.child_cert_obj.sql_fetch_where1(gctx, """ child_id = %s AND ca_detail_id = %s AND ski = %s """ % (child.child_id, ca_detail.ca_detail_id, req_ski)) - assert len(child_cert) < 2 - child_cert = child_cert[0] if child_cert else None # Generate new cert or regenerate old one if necessary |