diff options
author | Rob Austein <sra@hactrn.net> | 2008-03-04 20:31:10 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2008-03-04 20:31:10 +0000 |
commit | a5bde1c8c5713e68dd3992018ab22c39a6b4f532 (patch) | |
tree | 40573faa6dabf0d84b46358a48658190405fa92a | |
parent | 10e0713d12e065a6005849c4b9d7914ddb14ab8a (diff) |
Checkpoint
svn path=/rpkid/rpki/left_right.py; revision=1547
-rw-r--r-- | rpkid/rpki/left_right.py | 74 | ||||
-rw-r--r-- | rpkid/rpki/sql.py | 22 |
2 files changed, 71 insertions, 25 deletions
diff --git a/rpkid/rpki/left_right.py b/rpkid/rpki/left_right.py index 7d34887b..a461566f 100644 --- a/rpkid/rpki/left_right.py +++ b/rpkid/rpki/left_right.py @@ -856,30 +856,70 @@ class route_origin_elt(data_elt): return self.make_elt() def generate_roa(self, gctx): - """Generate a ROA based on this <route_origin/> object.""" - content = rpki.roa.RouteOriginAttestation() - content.version.set(0) - content.asID.set(self.as_number) - content.exactMatch.set(self.exact_match) - content.ipAddrBlocks.set((a.to_roa_tuple() for a in (self.v4, self.v6) if a)) - - # Current ROA spec urges one-off EE certs, so we need to generate - # a new keypair, issue an EE cert using our ca_detail, and use - # that cert to sign the CMS. See - # ca_detail_obj.generate_manifest() for details, may want to - # refactor it to share code. + """Generate a ROA based on this <route_origin/> object. + + At present this does not support ROAs with multiple signatures + (neither does the current CMS code). + + At present we have no way of performing a direct lookup from a + desired set of resources to a covering certificate, so we have to + search. This could be quite slow if we have a lot of active + ca_detail objects. Punt on the issue for now, revisit if + profiling shows this as a hotspot. + + Once we have the right covering certificate, we generate the ROA + payload, generate a new EE certificate, use the EE certificate to + sign the ROA payload, publish the result, then throw away the + private key for the EE cert, all per the ROA specification. This + implies that generating a lot of ROAs will tend to thrash + /dev/random, but there is not much we can do about that. + """ + + # Ugly and expensive search for covering ca_detail, there has to + # be a better way... + + for parents in self.self(gctx).parents(gctx): + for ca in parent.cas(gctx): + ca_detail = ca.fetch_active(gctx) + if ca_detail is not None: + resources = ca_detail.latest_ca_cert.get_3779resources() + if self.v4.issubset(resources.v4) and self.v6.issubset(resources.v6): + break + ca_detail = None + if ca_detail is not None: + break + + if ca_detail is None: + rpki.log.warn("generate_roa() could not find a covering certificate") + return + + resources = rpki.resource_set.resource_bag(v4 = self.v4, v6 = self.v6) + + payload = rpki.roa.RouteOriginAttestation() + payload.version.set(0) + payload.asID.set(self.as_number) + payload.exactMatch.set(self.exact_match) + payload.ipAddrBlocks.set((a.to_roa_tuple() for a in (self.v4, self.v6) if a)) keypair = rpki.x509.RSA() keypair.generate() - # ... and then a miracle occurs ... + ee_cert = ca_detail.issue_ee(ca, resources) - self.roa = rpki.cms.sign(content.toString(), keypair, cert) + self.roa = rpki.cms.sign(payload.toString(), keypair, (ee_cert,)) self.sql_mark_dirty() - # Publish the ROA somewhere around here. If we implemented the - # suppress_publication attribute and it were set, we'd skip this - # step, but we don't, so we don't. + # Publish the ROA. Filename? Hash of EE cert's public key? + + # Generate new manifest. If we're generating a lot of ROAs we + # would want to batch this, but get it right before worrying about + # making it fast. + + # Maybe the ca_detail object needs some kind of "manifest dirty" + # bit so that we can batch manifest updates? More likely we'd use + # a Python set(), same as we do for SQL dirty. + + # Link this route_origin to the ca_detail that signed its ROA. raise rpki.exceptions.NotImplementedYet diff --git a/rpkid/rpki/sql.py b/rpkid/rpki/sql.py index 1fafadad..5adc4028 100644 --- a/rpkid/rpki/sql.py +++ b/rpkid/rpki/sql.py @@ -561,15 +561,10 @@ class ca_detail_obj(sql_persistant): self.sql_store(gctx) return self - def generate_manifest_cert(self, ca): - """Generate a new manifest certificate for this ca_detail.""" + def issue_ee(self, ca, resources): + """Issue a new EE certificate.""" - resources = rpki.resource_set.resource_bag( - as = rpki.resource_set.resource_set_as("<inherit>"), - v4 = rpki.resource_set.resource_set_ipv4("<inherit>"), - v6 = rpki.resource_set.resource_set_ipv6("<inherit>")) - - self.latest_manifest_cert = self.latest_ca_cert.issue( + return self.latest_ca_cert.issue( keypair = self.private_key_id, subject_key = self.manifest_public_key, serial = ca.next_serial_number(), @@ -580,6 +575,17 @@ class ca_detail_obj(sql_persistant): notAfter = self.latest_ca_cert.getNotAfter(), is_ca = False) + + def generate_manifest_cert(self, ca): + """Generate a new manifest certificate for this ca_detail.""" + + resources = rpki.resource_set.resource_bag( + as = rpki.resource_set.resource_set_as("<inherit>"), + v4 = rpki.resource_set.resource_set_ipv4("<inherit>"), + v6 = rpki.resource_set.resource_set_ipv6("<inherit>")) + + self.latest_manifest_cert = self.issue_ee(ca, resources) + def issue(self, gctx, ca, child, subject_key, sia, resources, child_cert = None): """Issue a new certificate to a child. Optional child_cert argument specifies an existing child_cert object to update in |