diff options
-rw-r--r-- | docs/left-right-xml | 1 | ||||
-rw-r--r-- | docs/rpki-db-schema.pdf | bin | 7305 -> 7336 bytes | |||
-rw-r--r-- | docs/rpki-db-schema.sql | 1 | ||||
-rw-r--r-- | rpkid/left-right-protocol-samples/pdu.003.xml | 2 | ||||
-rw-r--r-- | rpkid/left-right-schema.rnc | 3 | ||||
-rw-r--r-- | rpkid/left-right-schema.rng | 9 | ||||
-rw-r--r-- | rpkid/rpki/gctx.py | 2 | ||||
-rw-r--r-- | rpkid/rpki/left_right.py | 77 | ||||
-rw-r--r-- | rpkid/rpki/relaxng.py | 11 | ||||
-rw-r--r-- | rpkid/rpki/sql.py | 2 | ||||
-rw-r--r-- | rpkid/testbed.1.yaml | 24 | ||||
-rw-r--r-- | rpkid/testbed.py | 10 |
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 Binary files differindex a9f2e89b..9b8b5a3b 100644 --- a/docs/rpki-db-schema.pdf +++ b/docs/rpki-db-schema.pdf 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)) |