diff options
author | Rob Austein <sra@hactrn.net> | 2007-09-23 23:32:37 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2007-09-23 23:32:37 +0000 |
commit | 81d8e851fe9fed622bc298732b42148ed1716e6c (patch) | |
tree | a4ede4c1987baa09dde392ab3ecc473cb7ae5b10 | |
parent | 9faa8e61bedb91f316593c428af77a9378b610e1 (diff) |
Implement up-down "list" command.
svn path=/scripts/rpki/sql.py; revision=1011
-rw-r--r-- | scripts/rpki/sql.py | 31 | ||||
-rw-r--r-- | scripts/rpki/up_down.py | 55 | ||||
-rw-r--r-- | scripts/rpki/x509.py | 10 |
3 files changed, 69 insertions, 27 deletions
diff --git a/scripts/rpki/sql.py b/scripts/rpki/sql.py index 2831a447..c67062f2 100644 --- a/scripts/rpki/sql.py +++ b/scripts/rpki/sql.py @@ -1,6 +1,6 @@ # $Id$ -import MySQLdb +import MySQLdb, rpki.x509 def connect(cfg, section="sql"): """Connect to a MySQL database using connection parameters from an @@ -57,7 +57,7 @@ class sql_persistant(object): @classmethod def sql_fetch(cls, db, cur, id): - results = cls.sql_fetch_where(db, cur, "WHERE %s = %s" % (cls.sql_template.index, id)) + results = cls.sql_fetch_where(db, cur, "%s = %s" % (cls.sql_template.index, id)) assert len(results) <= 1 if len(results) == 0: return None @@ -75,7 +75,7 @@ class sql_persistant(object): if where is None: cur.execute(cls.sql_template.select) else: - cur.execute(cls.sql_template.select + where) + cur.execute(cls.sql_template.select + " WHERE " + where) results = [] for row in cur.fetchall(): key = (cls, row[0]) @@ -167,6 +167,31 @@ class ca_detail_obj(sql_persistant): def __init__(self): self.certs = [] + def sql_decode(self, vals): + sql_persistant.sql_decode(self, vals) + + self.private_key_handle = rpki.x509.RSA_Keypair(DER = self.private_key_handle) + if self.public_key is not None: + assert self.private_key_handle.get_public_DER() == self.public_key + + self.latest_ca_cert_over_public_key = rpki.x509.X509(DER = self.latest_ca_cert_over_public_key) + + self.manifest_ee_private_key_handle = rpki.x509.RSA_Keypair(DER = self.manifest_ee_private_key_handle) + if self.manifest_ee_public_key is not None: + assert self.manifest_ee_private_key_handle.get_public_DER() == self.manifest_ee_public_key + + self.manifest_ee_cert = rpki.x509.X509(DER = self.manifest_ee_cert) + + # todo: manifest, crl + + def sql_encode(self): + d = sql_persistant.sql_encode(self) + d["private_key_handle"] = self.private_key_handle.get_DER() + d["latest_ca_cert_over_public_key"] = self.latest_ca_cert_over_public_key.get_DER() + d["manifest_ee_private_key_handle"] = self.manifest_ee_private_key_handle.get_DER() + d["manifest_ee_cert"] = self.manifest_ee_cert.get_DER() + return d + class ca_obj(sql_persistant): """Internal CA object.""" diff --git a/scripts/rpki/up_down.py b/scripts/rpki/up_down.py index dbaba3fd..2996fe59 100644 --- a/scripts/rpki/up_down.py +++ b/scripts/rpki/up_down.py @@ -141,28 +141,41 @@ class list_pdu(base_elt): return [] def serve_pdu(self, gctx, r_msg, child): - raise NotImplementedError - - # Tasks: - - # 1) extract child's resource set from irdb - # - irdb_as, irdb_ipv4, irdb_ipv6 = rpki.left_right.irdb_query(gctx, child.self_id, child.child_id) - - # 2) for every ca, compute intersection of child's resource set - # with ca's resource set; if result is non-null, this ca is one - # of the resource classes for this child - # - # 3) establish ca_child_link bindings based on (2)? - # - # 4) generate result pdu, unless we do that as part of (2) - r_msg.payload = list_response_pdu() - for ca in rpki.sql.fetch_column(gctx.cur, "SELECT ca_id FROM child_ca_link WHERE child_id = %s" % child.child_id): - klass = class_elt() - r_msg.payload.classes.append(klass) - klass.class_name = ca.ca_id - raise NotImplementedError + irdb_as, irdb_v4, irdb_v6 = rpki.left_right.irdb_query(gctx, child.self_id, child.child_id) + for ca_id in rpki.sql.fetch_column(gctx.cur, "SELECT ca_id FROM ca WHERE ca.parent_id = parent.parent_id AND parent.self_id = %s" % child.self_id): + ca_details = rpki.sql.ca_detail_elt.sql_fetch_where(gctx.db, gctx.cur, "ca_id = %s" % ca_id) + if not ca_details: + continue + rc_as, rc_v4, rc_v6 = ca_detail[0].latest_ca_cert_over_public_key.get_3779resources() + for ca_detail in ca_details[1:]: + as, v4, v6 = ca_detail.latest_ca_cert_over_public_key.get_3779resources() + rc_as.union(as) + rc_v4.union(v4) + rc_v6.union(v6) + rc_as.intersection(irdb_as) + rc_v4.intersection(irdb_v4) + rc_v6.intersection(irdb_v6) + if not rc_as and not rc_v4 and not rc_v6: + continue + rc = class_elt() + rc.class_name = str(ca_id) + rc.cert_url = "rsync://niy.invalid" + rc.resource_set_as = rc_as + rc.resource_set_ipv4 = rc_v4 + rc.resource_set_ipv6 = rc_v6 + for ca_detail in ca_details: + as, v4, v6 = ca_detail.latest_ca_cert_over_public_key.get_3779resources() + as.intersection(irdb_as) + v4.intersection(irdb_v4) + v6.intersection(irdb_v6) + if not as and not v4 and not v6: + continue + c = certificate_elt() + c.cert_url = "rsync://niy.invalid" + c.cert = ca_detail.latest_ca_cert_over_public_key + rc.certs.append(c) + r_msg.payload.classes.append(rc) class list_response_pdu(base_elt): """Up-Down protocol "list_response" PDU.""" diff --git a/scripts/rpki/x509.py b/scripts/rpki/x509.py index 2082986c..0c3639b2 100644 --- a/scripts/rpki/x509.py +++ b/scripts/rpki/x509.py @@ -12,7 +12,7 @@ bring together the functionality I need in a way that hides at least some of the nasty details. This involves a lot of format conversion. """ -import POW, tlslite.api, POW.pkix, base64, rpki.exceptions +import POW, tlslite.api, POW.pkix, base64, rpki.exceptions, rpki.resource_set class PEM_converter(object): """Convert between DER and PEM encodings for various kinds of ASN.1 data.""" @@ -202,14 +202,18 @@ class X509(DER_object): self.POW_extensions = exts return self.POW_extensions - def getAKI(self): + def get_AKI(self): """Get the AKI extension from this certificate.""" return self._get_POW_extensions().get("authorityKeyIdentifier") - def getSKI(self): + def get_SKI(self): """Get the SKI extension from this certificate.""" return self._get_POW_extensions().get("subjectKeyIdentifier") + def get_3779resources(self): + """Get RFC 3779 resources as rpki.resource_set objects.""" + return rpki.resource_set.parse_extensions(self.get_POWpkix().getExtensions()) + class X509_chain(list): """Collections of certs. |