aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2008-03-04 20:31:10 +0000
committerRob Austein <sra@hactrn.net>2008-03-04 20:31:10 +0000
commita5bde1c8c5713e68dd3992018ab22c39a6b4f532 (patch)
tree40573faa6dabf0d84b46358a48658190405fa92a
parent10e0713d12e065a6005849c4b9d7914ddb14ab8a (diff)
Checkpoint
svn path=/rpkid/rpki/left_right.py; revision=1547
-rw-r--r--rpkid/rpki/left_right.py74
-rw-r--r--rpkid/rpki/sql.py22
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