aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/left-right-xml1
-rw-r--r--docs/rpki-db-schema.pdfbin7305 -> 7336 bytes
-rw-r--r--docs/rpki-db-schema.sql1
-rw-r--r--rpkid/left-right-protocol-samples/pdu.003.xml2
-rw-r--r--rpkid/left-right-schema.rnc3
-rw-r--r--rpkid/left-right-schema.rng9
-rw-r--r--rpkid/rpki/gctx.py2
-rw-r--r--rpkid/rpki/left_right.py77
-rw-r--r--rpkid/rpki/relaxng.py11
-rw-r--r--rpkid/rpki/sql.py2
-rw-r--r--rpkid/testbed.1.yaml24
-rw-r--r--rpkid/testbed.py10
12 files changed, 95 insertions, 47 deletions
diff --git a/docs/left-right-xml b/docs/left-right-xml
index 1f9b983f..70e6a05f 100644
--- a/docs/left-right-xml
+++ b/docs/left-right-xml
@@ -40,6 +40,7 @@
publish_world_now="yes"
clear_extension_preferences="yes"
crl_interval="3600"
+ regen_margin="86400"
use_hsm="no">
<extension_preference name="color">Blue</extension_preference>
</self>
diff --git a/docs/rpki-db-schema.pdf b/docs/rpki-db-schema.pdf
index a9f2e89b..9b8b5a3b 100644
--- a/docs/rpki-db-schema.pdf
+++ b/docs/rpki-db-schema.pdf
Binary files differ
diff --git a/docs/rpki-db-schema.sql b/docs/rpki-db-schema.sql
index 87cb552b..4f8f8e1b 100644
--- a/docs/rpki-db-schema.sql
+++ b/docs/rpki-db-schema.sql
@@ -20,6 +20,7 @@ CREATE TABLE self (
self_id SERIAL NOT NULL,
use_hsm BOOLEAN,
crl_interval BIGINT unsigned,
+ regen_margin BIGINT unsigned,
PRIMARY KEY (self_id)
);
diff --git a/rpkid/left-right-protocol-samples/pdu.003.xml b/rpkid/left-right-protocol-samples/pdu.003.xml
index b53bb031..e9cf0d06 100644
--- a/rpkid/left-right-protocol-samples/pdu.003.xml
+++ b/rpkid/left-right-protocol-samples/pdu.003.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="US-ASCII"?>
<!--Automatically generated, do not edit.-->
<msg xmlns="http://www.hactrn.net/uris/rpki/left-right-spec/" version="1">
- <self action="set" type="query" self_id="42" rekey="yes" reissue="yes" revoke="yes" run_now="yes" publish_world_now="yes" clear_extension_preferences="yes" crl_interval="3600" use_hsm="no">
+ <self action="set" type="query" self_id="42" rekey="yes" reissue="yes" revoke="yes" run_now="yes" publish_world_now="yes" clear_extension_preferences="yes" crl_interval="3600" regen_margin="86400" use_hsm="no">
<extension_preference name="color">Blue</extension_preference>
</self>
</msg>
diff --git a/rpkid/left-right-schema.rnc b/rpkid/left-right-schema.rnc
index 32bdb678..dc511611 100644
--- a/rpkid/left-right-schema.rnc
+++ b/rpkid/left-right-schema.rnc
@@ -52,7 +52,8 @@ self_bool = (attribute rekey { "yes" }?,
attribute clear_extension_preferences { "yes" }?)
self_payload = (attribute use_hsm { "yes" | "no" }?,
- attribute crl_interval { xsd:token { maxLength="1024" } }?,
+ attribute crl_interval { xsd:positiveInteger }?,
+ attribute regen_margin { xsd:positiveInteger }?,
element extension_preference {
attribute name { xsd:token { maxLength="1024" } },
xsd:string { maxLength="512000" }
diff --git a/rpkid/left-right-schema.rng b/rpkid/left-right-schema.rng
index 0ce5da88..07558aa5 100644
--- a/rpkid/left-right-schema.rng
+++ b/rpkid/left-right-schema.rng
@@ -201,9 +201,12 @@
</optional>
<optional>
<attribute name="crl_interval">
- <data type="token">
- <param name="maxLength">1024</param>
- </data>
+ <data type="positiveInteger"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="regen_margin">
+ <data type="positiveInteger"/>
</attribute>
</optional>
<zeroOrMore>
diff --git a/rpkid/rpki/gctx.py b/rpkid/rpki/gctx.py
index 44d47f28..9be163de 100644
--- a/rpkid/rpki/gctx.py
+++ b/rpkid/rpki/gctx.py
@@ -159,7 +159,7 @@ class global_context(object):
for s in rpki.left_right.self_elt.sql_fetch_all(self):
s.client_poll()
s.update_children()
- s.generate_roas()
+ s.update_roas()
s.regenerate_crls_and_manifests()
self.sql_sweep()
return 200, "OK"
diff --git a/rpkid/rpki/left_right.py b/rpkid/rpki/left_right.py
index f684c498..4aec4417 100644
--- a/rpkid/rpki/left_right.py
+++ b/rpkid/rpki/left_right.py
@@ -214,15 +214,16 @@ class self_elt(data_elt):
"""<self/> element."""
element_name = "self"
- attributes = ("action", "type", "tag", "self_id", "crl_interval")
+ attributes = ("action", "type", "tag", "self_id", "crl_interval", "regen_margin")
elements = ("extension_preference",)
booleans = ("rekey", "reissue", "revoke", "run_now", "publish_world_now", "clear_extension_preferences")
- sql_template = rpki.sql.template("self", "self_id", "use_hsm", "crl_interval")
+ sql_template = rpki.sql.template("self", "self_id", "use_hsm", "crl_interval", "regen_margin")
self_id = None
use_hsm = False
crl_interval = None
+ regen_margin = None
def __init__(self):
"""Initialize a self_elt."""
@@ -419,15 +420,11 @@ class self_elt(data_elt):
ca_detail.generate_crl()
ca_detail.generate_manifest()
- def generate_roas(self):
- """Generate ROAs for this self's route_origin objects.
-
- This doesn't yet handle revocation or regeneration of existing
- ROAs, the underlying support for that hasn't been written yet.
- """
+ def update_roas(self):
+ """Generate or update ROAs for this self's route_origin objects."""
for route_origin in self.route_origins():
- route_origin.generate_roa()
+ route_origin.update_roa()
class bsc_elt(data_elt):
"""<bsc/> (Business Signing Context) element."""
@@ -883,6 +880,34 @@ class route_origin_elt(data_elt):
"""Generate <route_origin/> element."""
return self.make_elt()
+ def update_roa(self):
+ """Bring this route_origin's ROA up to date if necesssary."""
+
+ if self.roa is None:
+ return self.generate_roa()
+
+ ca_detail = self.ca_detail()
+
+ if ca_detail.state != "active":
+ return self.regenerate_roa()
+
+ regen_margin = rpki.sundial.timedelta(seconds = self.self().regen_margin)
+
+ if rpki.sundial.now() + regen_margin > self.cert.getNotAfter():
+ return self.regenerate_roa()
+
+ ca_resources = ca_detail.latest_ca_cert.get_3779resources()
+ ee_resources = self.cert.get_3779resources()
+
+ if ee_resources.oversized(ca_resources):
+ return self.regenerate_roa()
+
+ v4 = self.ipv4 if self.ipv4 is not None else rpki.resource_set.resource_set_ipv4()
+ v6 = self.ipv6 if self.ipv6 is not None else rpki.resource_set.resource_set_ipv6()
+
+ if ee_resources.v4 != v4 or ee_resources.v6 != v6:
+ return self.regenerate_roa()
+
def generate_roa(self):
"""Generate a ROA based on this <route_origin/> object.
@@ -918,17 +943,20 @@ class route_origin_elt(data_elt):
# first checking the ca_detail we used last time, but it may not
# be active, in which we have to check the ca_detail that replaced it.
- for parent in self.self().parents():
- for ca in parent.cas():
- ca_detail = ca.fetch_active()
+ ca_detail = self.ca_detail()
+ if ca_detail is None or ca_detail.state != "active":
+ ca_detail = None
+ for parent in self.self().parents():
+ for ca in parent.cas():
+ ca_detail = ca.fetch_active()
+ if ca_detail is not None:
+ resources = ca_detail.latest_ca_cert.get_3779resources()
+ if ((self.ipv4 is None or self.ipv4.issubset(resources.v4)) and
+ (self.ipv6 is None or self.ipv6.issubset(resources.v6))):
+ break
+ ca_detail = None
if ca_detail is not None:
- resources = ca_detail.latest_ca_cert.get_3779resources()
- if ((self.ipv4 is None or self.ipv4.issubset(resources.v4)) and
- (self.ipv6 is None or self.ipv6.issubset(resources.v6))):
- break
- ca_detail = None
- if ca_detail is not None:
- break
+ break
if ca_detail is None:
rpki.log.warn("generate_roa() could not find a covering certificate")
@@ -951,11 +979,12 @@ class route_origin_elt(data_elt):
repository.publish(self.cert, self.ee_uri(ca))
ca_detail.generate_manifest()
- def withdraw_roa(self, reissue = False):
+ def withdraw_roa(self, regenerate = False):
"""Withdraw ROA associated with this route_origin.
In order to preserve make-before-break properties without
- duplicating code, this method also handles issuing a new ROA.
+ duplicating code, this method also handles generating a
+ replacement ROA when requested.
"""
ca_detail = self.ca_detail()
@@ -968,7 +997,7 @@ class route_origin_elt(data_elt):
if ca_detail.state != 'active':
self.ca_detail_id = None
- if reissue:
+ if regenerate:
self.generate_roa()
rpki.log.debug("Withdrawing ROA and revoking its EE cert")
@@ -979,9 +1008,9 @@ class route_origin_elt(data_elt):
ca_detail.generate_crl()
ca_detail.generate_manifest()
- def reissue_roa(self):
+ def regenerate_roa(self):
"""Reissue ROA associated with this route_origin."""
- self.withdraw_roa(reissue = True)
+ self.withdraw_roa(regenerate = True)
def roa_uri(self, ca, key = None):
"""Return the publication URI for this route_origin's ROA."""
diff --git a/rpkid/rpki/relaxng.py b/rpkid/rpki/relaxng.py
index 1e9cae7b..f0c4ad57 100644
--- a/rpkid/rpki/relaxng.py
+++ b/rpkid/rpki/relaxng.py
@@ -6,7 +6,7 @@ import lxml.etree
## Parsed RelaxNG left_right schema
left_right = lxml.etree.RelaxNG(lxml.etree.fromstring('''<?xml version="1.0" encoding="UTF-8"?>
<!--
- $Id: left-right-schema.rng 1654 2008-04-11 21:09:48Z sra $
+ $Id: left-right-schema.rnc 1654 2008-04-11 21:09:48Z sra $
RelaxNG (Compact Syntax) Schema for RPKI left-right protocol.
@@ -207,9 +207,12 @@ left_right = lxml.etree.RelaxNG(lxml.etree.fromstring('''<?xml version="1.0" enc
</optional>
<optional>
<attribute name="crl_interval">
- <data type="token">
- <param name="maxLength">1024</param>
- </data>
+ <data type="positiveInteger"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="regen_margin">
+ <data type="positiveInteger"/>
</attribute>
</optional>
<zeroOrMore>
diff --git a/rpkid/rpki/sql.py b/rpkid/rpki/sql.py
index 3a9d552d..892e99b7 100644
--- a/rpkid/rpki/sql.py
+++ b/rpkid/rpki/sql.py
@@ -449,7 +449,7 @@ class ca_detail_obj(sql_persistant):
for child_cert in predecessor.child_certs():
child_cert.reissue(self)
for route_origin in predecessor.route_origins():
- route_origin.reissue_roa()
+ route_origin.regenerate_roa()
def delete(self, ca, repository):
"""Delete this ca_detail and all of the certs it issued."""
diff --git a/rpkid/testbed.1.yaml b/rpkid/testbed.1.yaml
index 628e8f3d..fcb205f2 100644
--- a/rpkid/testbed.1.yaml
+++ b/rpkid/testbed.1.yaml
@@ -15,7 +15,8 @@
# PERFORMANCE OF THIS SOFTWARE.
name: RIR
-#valid_until: 2008-07-14T12:30:00Z
+crl_interval: 60s
+regen_margin: 30s
valid_for: 2d
kids:
- name: R0
@@ -44,15 +45,16 @@ kids:
- asn: 17
ipv4: 10.3.0.1/32, 10.0.0.44/32
---
-- name: Alice
- add_as: 33
- valid_add: 2d
-# valid_until: 2009-07-14T12:30:00Z
+- sleep 30
---
-- name: Alice
-# valid_until: 2009-04-01T00:00:00
- valid_sub: 2d
+- sleep 30
---
-- name: Alice
-# valid_until: 2009-04-01T00:00:00
- valid_for: 10d
+- sleep 30
+---
+- sleep 30
+---
+- sleep 30
+---
+- sleep 30
+---
+- sleep 30
diff --git a/rpkid/testbed.py b/rpkid/testbed.py
index c3605f2d..7de56bb0 100644
--- a/rpkid/testbed.py
+++ b/rpkid/testbed.py
@@ -337,6 +337,8 @@ class allocation_db(list):
assert self.root.is_root()
if self.root.crl_interval is None:
self.root.crl_interval = timedelta.parse(cfg.get("crl_interval", "1d")).convert_to_seconds()
+ if self.root.regen_margin is None:
+ self.root.regen_margin = timedelta.parse(cfg.get("regen_margin", "1d")).convert_to_seconds()
for a in self:
if a.sia_base is None:
a.sia_base = (rootd_sia if a.is_root() else a.parent.sia_base) + a.name + "/"
@@ -344,6 +346,8 @@ class allocation_db(list):
a.base.valid_until = a.parent.base.valid_until
if a.crl_interval is None:
a.crl_interval = a.parent.crl_interval
+ if a.regen_margin is None:
+ a.regen_margin = a.parent.regen_margin
self.root.closure()
self.map = dict((a.name, a) for a in self)
self.engines = [a for a in self if not a.is_leaf()]
@@ -374,6 +378,7 @@ class allocation(object):
rpki_db_name = None
rpki_port = None
crl_interval = None
+ regen_margin = None
def __init__(self, yaml, db, parent = None):
"""Initialize one entity and insert it into the database."""
@@ -392,6 +397,8 @@ class allocation(object):
self.sia_base = yaml.get("sia_base")
if "crl_interval" in yaml:
self.crl_interval = timedelta.parse(yaml["crl_interval"]).convert_to_seconds()
+ if "regen_margin" in yaml:
+ self.regen_margin = timedelta.parse(yaml["regen_margin"]).convert_to_seconds()
self.route_origins = set()
if "route_origin" in yaml:
for y in yaml.get("route_origin"):
@@ -600,7 +607,8 @@ class allocation(object):
"""
rpki.log.info("Creating rpkid self object for %s" % self.name)
- self.self_id = self.call_rpkid(rpki.left_right.self_elt.make_pdu(action = "create", crl_interval = self.crl_interval)).self_id
+ self.self_id = self.call_rpkid(rpki.left_right.self_elt.make_pdu(
+ action = "create", crl_interval = self.crl_interval, regen_margin = self.regen_margin)).self_id
rpki.log.info("Creating rpkid BSC object for %s" % self.name)
pdu = self.call_rpkid(rpki.left_right.bsc_elt.make_pdu(action = "create", self_id = self.self_id, generate_keypair = True))