diff options
author | Rob Austein <sra@hactrn.net> | 2014-02-20 06:43:48 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2014-02-20 06:43:48 +0000 |
commit | 065c44e912a7fca14ae641a09aa89d0a573c3cdf (patch) | |
tree | eccbc17bcb74d8cec5b429aeda65d940a0fbefae /rpkid | |
parent | 8453e66ddfbee5fdf8ab3bc94e88104dae50980b (diff) |
Checkpoint. Now generating something that looks a bit like a router
cert, but not right yet: RSA where should be ECDSA, EKU missing, and
EE certificate class's .reissue() method isn't working properly yet.
svn path=/branches/tk671/; revision=5673
Diffstat (limited to 'rpkid')
-rw-r--r-- | rpkid/rpki/left_right.py | 6 | ||||
-rw-r--r-- | rpkid/rpki/old_irdbd.py | 7 | ||||
-rw-r--r-- | rpkid/rpki/rpkid.py | 21 | ||||
-rw-r--r-- | rpkid/rpki/rpkid_tasks.py | 23 | ||||
-rw-r--r-- | rpkid/rpki/x509.py | 5 | ||||
-rw-r--r-- | rpkid/tests/old_irdbd.sql | 1 | ||||
-rw-r--r-- | rpkid/tests/smoketest.py | 66 |
7 files changed, 112 insertions, 17 deletions
diff --git a/rpkid/rpki/left_right.py b/rpkid/rpki/left_right.py index cb25046c..dcfc5f40 100644 --- a/rpkid/rpki/left_right.py +++ b/rpkid/rpki/left_right.py @@ -390,9 +390,9 @@ class self_elt(data_elt): results = set() for parent in self.parents: for ca in parent.cas: - for ca_detail in ca.active_ca_details: - if ca_detail.covers(resources): - results.add(ca_detail) + ca_detail = ca.active_ca_detail + if ca_detail is not None and ca_detail.covers(resources): + results.add(ca_detail) return results diff --git a/rpkid/rpki/old_irdbd.py b/rpkid/rpki/old_irdbd.py index a9585307..25ceb656 100644 --- a/rpkid/rpki/old_irdbd.py +++ b/rpkid/rpki/old_irdbd.py @@ -170,18 +170,19 @@ class main(object): self.cur.execute( """ - SELECT ee_certificate_id, gski, router_id, valid_until + SELECT ee_certificate_id, pkcs10, gski, router_id, valid_until FROM ee_certificate WHERE self_handle = %s """, (q_pdu.self_handle,)) - for ee_certificate_id, gski, router_id, valid_until in self.cur.fetchall(): + for ee_certificate_id, pkcs10, gski, router_id, valid_until in self.cur.fetchall(): - r_pdu = rpki.left_right.ee_certificates_request_elt() + r_pdu = rpki.left_right.list_ee_certificate_requests_elt() r_pdu.tag = q_pdu.tag r_pdu.self_handle = q_pdu.self_handle r_pdu.valid_until = valid_until.strftime("%Y-%m-%dT%H:%M:%SZ") + r_pdu.pkcs10 = rpki.x509.PKCS10(DER = pkcs10) r_pdu.gski = gski r_pdu.router_id = router_id diff --git a/rpkid/rpki/rpkid.py b/rpkid/rpki/rpkid.py index e825caf2..965eb9d4 100644 --- a/rpkid/rpki/rpkid.py +++ b/rpkid/rpki/rpkid.py @@ -27,6 +27,7 @@ import argparse import sys import re import random +import base64 import rpki.resource_set import rpki.up_down import rpki.left_right @@ -847,6 +848,13 @@ class ca_detail_obj(rpki.sql.sql_persistent): """ return rpki.rpkid.ghostbuster_obj.sql_fetch_where(self.gctx, "ca_detail_id = %s", (self.ca_detail_id,)) + @property + def ee_certificates(self): + """ + Fetch all EE certificate objects that link to this ca_detail. + """ + return rpki.rpkid.ee_cert_obj.sql_fetch_where(self.gctx, "ca_detail_id = %s", (self.ca_detail_id,)) + def unpublished_ghostbusters(self, when): """ Fetch all unpublished Ghostbusters objects linked to this @@ -1227,8 +1235,12 @@ class ca_detail_obj(rpki.sql.sql_persistent): self.crl_published = rpki.sundial.now() self.sql_mark_dirty() - publisher.publish(cls = rpki.publication.crl_elt, uri = self.crl_uri, obj = self.latest_crl, repository = parent.repository, - handler = self.crl_published_callback) + publisher.publish( + cls = rpki.publication.crl_elt, + uri = self.crl_uri, + obj = self.latest_crl, + repository = parent.repository, + handler = self.crl_published_callback) def crl_published_callback(self, pdu): """ @@ -1265,6 +1277,7 @@ class ca_detail_obj(rpki.sql.sql_persistent): objs.extend((c.uri_tail, c.cert) for c in self.child_certs) objs.extend((r.uri_tail, r.roa) for r in self.roas if r.roa is not None) objs.extend((g.uri_tail, g.ghostbuster) for g in self.ghostbusters) + objs.extend((e.uri_tail, e.cert) for e in self.ee_certificates) rpki.log.debug("Building manifest object %s" % uri) self.latest_manifest = rpki.x509.SignedManifest.build( @@ -2310,7 +2323,7 @@ class ee_cert_obj(rpki.sql.sql_persistent): Generate a new certificate and stuff it in a new ee_cert_obj. """ - cn, sn = subject_name.get_cn_and_dn() + cn, sn = subject_name.extract_cn_and_sn() ca = ca_detail.ca cert = ca_detail.issue_ee( @@ -2324,7 +2337,7 @@ class ee_cert_obj(rpki.sql.sql_persistent): self = cls( gctx = ca_detail.gctx, - self_id = ca.self.self_id, + self_id = ca.parent.self.self_id, ca_detail_id = ca_detail.ca_detail_id, cert = cert) diff --git a/rpkid/rpki/rpkid_tasks.py b/rpkid/rpki/rpkid_tasks.py index 7554fb89..492876aa 100644 --- a/rpkid/rpki/rpkid_tasks.py +++ b/rpkid/rpki/rpkid_tasks.py @@ -601,22 +601,30 @@ class UpdateEECertificatesTask(AbstractTask): existing[gski] = set() existing[gski].add(ee) + ca_details = set() + for req in requests: ees = existing.pop(req.gski, ()) - ca_details = self.find_covering_ca_details(resources) + resources = rpki.resource_set.resource_bag( + asn = req.asn, + v4 = req.ipv4, + v6 = req.ipv6, + valid_until = req.valid_until) + covering = self.find_covering_ca_details(resources) + ca_details.update(covering) for ee in ees: - if ee.ca_detail in ca_details: + if ee.ca_detail in covering: rpki.log.debug("Updating existing EE certificate for %s %s" % (req.gski, resources)) ee.reissue( resources = resources, publisher = publisher) - ca_details.remove(ee.ca_detail) + covering.remove(ee.ca_detail) else: rpki.log.debug("Existing EE certificate for %s %s is no longer covered" % (req.gski, resources)) ee.revoke(publisher = publisher) - for ca_detail in ca_details: + for ca_detail in covering: rpki.log.debug("No existing EE certificate for %s %s" % (req.gski, resources)) rpki.rpkid.ee_cert_obj.create( ca_detail = ca_detail, @@ -628,10 +636,17 @@ class UpdateEECertificatesTask(AbstractTask): # Anything left is an orphan for ees in existing.values(): for ee in ees: + ca_details.add(ee.ca_detail) ee.revoke(publisher = publisher) self.gctx.sql.sweep() + for ca_detail in ca_details: + ca_detail.generate_crl(publisher = publisher) + ca_detail.generate_manifest(publisher = publisher) + + self.gctx.sql.sweep() + self.gctx.checkpoint() publisher.call_pubd(self.exit, self.publication_failed) diff --git a/rpkid/rpki/x509.py b/rpkid/rpki/x509.py index 858278f2..15adf12b 100644 --- a/rpkid/rpki/x509.py +++ b/rpkid/rpki/x509.py @@ -1061,7 +1061,7 @@ class PKCS10(DER_object): @classmethod def create(cls, keypair, exts = None, is_ca = False, caRepository = None, rpkiManifest = None, signedObject = None, - cn = None, sn = None): + cn = None, sn = None, eku = None): """ Create a new request for a given keypair. """ @@ -1092,6 +1092,9 @@ class PKCS10(DER_object): if caRepository or rpkiManifest or signedObject: req.setSIA(caRepository, rpkiManifest, signedObject) + if eku: + req.setEKU(eku) + req.sign(keypair.get_POW(), rpki.POW.SHA256_DIGEST) return cls(POW = req) diff --git a/rpkid/tests/old_irdbd.sql b/rpkid/tests/old_irdbd.sql index 0f349e2b..1e5b6d28 100644 --- a/rpkid/tests/old_irdbd.sql +++ b/rpkid/tests/old_irdbd.sql @@ -107,6 +107,7 @@ CREATE TABLE ghostbuster_request ( CREATE TABLE ee_certificate ( ee_certificate_id SERIAL NOT NULL, self_handle VARCHAR(255) NOT NULL, + pkcs10 LONGBLOB NOT NULL, gski VARCHAR(27) NOT NULL, router_id INT UNSIGNED, valid_until DATETIME NOT NULL, diff --git a/rpkid/tests/smoketest.py b/rpkid/tests/smoketest.py index 043acbde..7f284550 100644 --- a/rpkid/tests/smoketest.py +++ b/rpkid/tests/smoketest.py @@ -375,6 +375,38 @@ class roa_request(object): def parse(cls, yaml): return cls(yaml.get("asn"), yaml.get("ipv4"), yaml.get("ipv6")) +class router_cert(object): + """ + Representation for a router_cert object. + """ + + def __init__(self, asn, router_id): + self.asn = rpki.resource_set.resource_set_as("".join(str(asn).split())) + self.router_id = router_id + + rpki.log.warn("Code to generate ECDSA keys not written yet, generating RSA as hack for testing") + self.keypair = rpki.x509.RSA.generate() + self.pkcs10 = rpki.x509.PKCS10.create( + keypair = self.keypair, + cn = "ROUTER-%d" % self.asn[0].min, + sn = self.router_id, + eku = (rpki.oids.id_kp_bgpsec_router,)) + self.gski = self.pkcs10.gSKI() + + def __eq__(self, other): + return self.asn == other.asn and self.router_id == other.router_id and self.gski == other.gski + + def __hash__(self): + v6 = tuple(self.v6) if self.v6 is not None else None + return tuple(self.asn).__hash__() + router_id.__hash__() + self.gski.__hash__() + + def __str__(self): + return "%s: %s: %s" % (self.asn, self.router_id, self.gski) + + @classmethod + def parse(cls, yaml): + return cls(yaml.get("asn"), yaml.get("router_id")) + class allocation_db(list): """ Representation of all the entities and allocations in the test @@ -485,6 +517,9 @@ class allocation(object): self.base.v4 |= r.v4.to_resource_set() if r.v6: self.base.v6 |= r.v6.to_resource_set() + self.router_certs = [router_cert.parse(y) for y in yaml.get("router_cert", ())] + for r in self.router_certs: + self.base.asn |= r.asn self.hosted_by = yaml.get("hosted_by") self.extra_conf = yaml.get("extra_conf", []) self.hosts = [] @@ -568,6 +603,20 @@ class allocation(object): self.roa_requests.remove(r) cb() + def apply_router_cert_add(self, yaml, cb): + for y in yaml: + r = router_cert.parse(y) + if r not in self.router_certs: + self.router_certs.append(r) + cb() + + def apply_router_cert_del(self, yaml, cb): + for y in yaml: + r = router_cert.parse(y) + if r in self.router_certs: + self.router_certs.remove(r) + cb() + def apply_rekey(self, target, cb): def done(e): @@ -728,6 +777,10 @@ class allocation(object): cur.execute("DELETE FROM registrant_net") cur.execute("DELETE FROM roa_request_prefix") cur.execute("DELETE FROM roa_request") + cur.execute("DELETE FROM ee_certificate_asn") + cur.execute("DELETE FROM ee_certificate_net") + cur.execute("DELETE FROM ee_certificate") + for s in [self] + self.hosts: for kid in s.kids: cur.execute("SELECT registrant_id FROM registrant WHERE registrant_handle = %s AND registry_handle = %s", @@ -750,9 +803,18 @@ class allocation(object): roa_request_id = cur.lastrowid for version, prefix_set in ((4, r.v4), (6, r.v6)): if prefix_set: - cur.executemany("INSERT roa_request_prefix (roa_request_id, prefix, prefixlen, max_prefixlen, version) " + cur.executemany("INSERT roa_request_prefix " + "(roa_request_id, prefix, prefixlen, max_prefixlen, version) " "VALUES (%s, %s, %s, %s, %s)", - ((roa_request_id, x.prefix, x.prefixlen, x.max_prefixlen, version) for x in prefix_set)) + ((roa_request_id, x.prefix, x.prefixlen, x.max_prefixlen, version) + for x in prefix_set)) + for r in s.router_certs: + cur.execute("INSERT ee_certificate (self_handle, pkcs10, gski, router_id, valid_until) " + "VALUES (%s, %s, %s, %s, %s)", + (s.name, r.pkcs10.get_DER(), r.gski, r.router_id, s.resources.valid_until)) + ee_certificate_id = cur.lastrowid + cur.executemany("INSERT ee_certificate_asn (ee_certificate_id, start_as, end_as) VALUES (%s, %s, %s)", + ((ee_certificate_id, a.min, a.max) for a in r.asn)) db.close() def run_daemons(self): |