diff options
-rw-r--r-- | rpki/pubdb/migrations/0003_auto_20151025_1757.py | 19 | ||||
-rw-r--r-- | rpki/rpkid_tasks.py | 12 | ||||
-rw-r--r-- | rpki/rpkidb/migrations/0009_auto_20151025_1804.py | 34 | ||||
-rw-r--r-- | rpki/rpkidb/models.py | 59 |
4 files changed, 86 insertions, 38 deletions
diff --git a/rpki/pubdb/migrations/0003_auto_20151025_1757.py b/rpki/pubdb/migrations/0003_auto_20151025_1757.py new file mode 100644 index 00000000..f92cc419 --- /dev/null +++ b/rpki/pubdb/migrations/0003_auto_20151025_1757.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pubdb', '0002_auto_20151023_2151'), + ] + + operations = [ + migrations.AlterField( + model_name='publishedobject', + name='der', + field=models.BinaryField(), + ), + ] diff --git a/rpki/rpkid_tasks.py b/rpki/rpkid_tasks.py index b6713447..642d5dda 100644 --- a/rpki/rpkid_tasks.py +++ b/rpki/rpkid_tasks.py @@ -209,24 +209,26 @@ class UpdateChildrenTask(AbstractTask): old_aia = child_cert.cert.get_AIA()[0] new_aia = ca_detail.ca_cert_uri + assert child_cert.gski == child_cert.cert.gSKI() + if new_resources.empty(): - logger.debug("Resources shrank to the null set, revoking and withdrawing child %s certificate SKI %s", child.child_handle, child_cert.cert.gSKI()) + logger.debug("Resources shrank to the null set, revoking and withdrawing child %s certificate g(SKI) %s", child.child_handle, child_cert.gski) child_cert.revoke(publisher = publisher) ca_detail.generate_crl(publisher = publisher) ca_detail.generate_manifest(publisher = publisher) elif (old_resources != new_resources or old_aia != new_aia or (old_resources.valid_until < rsn and irdb_resources.valid_until > now and old_resources.valid_until != irdb_resources.valid_until)): - logger.debug("Need to reissue child %s certificate SKI %s", child.child_handle, child_cert.cert.gSKI()) + logger.debug("Need to reissue child %s certificate g(SKI) %s", child.child_handle, child_cert.gski) if old_resources != new_resources: - logger.debug("Child %s SKI %s resources changed: old %s new %s", child.child_handle, child_cert.cert.gSKI(), old_resources, new_resources) + logger.debug("Child %s g(SKI) %s resources changed: old %s new %s", child.child_handle, child_cert.gski, old_resources, new_resources) if old_resources.valid_until != irdb_resources.valid_until: - logger.debug("Child %s SKI %s validity changed: old %s new %s", child.child_handle, child_cert.cert.gSKI(), old_resources.valid_until, irdb_resources.valid_until) + logger.debug("Child %s g(SKI) %s validity changed: old %s new %s", child.child_handle, child_cert.gski, old_resources.valid_until, irdb_resources.valid_until) new_resources.valid_until = irdb_resources.valid_until child_cert.reissue(ca_detail = ca_detail, resources = new_resources, publisher = publisher) elif old_resources.valid_until < now: - logger.debug("Child %s certificate SKI %s has expired: cert.valid_until %s, irdb.valid_until %s", child.child_handle, child_cert.cert.gSKI(), old_resources.valid_until, irdb_resources.valid_until) + logger.debug("Child %s certificate g(SKI) %s has expired: cert.valid_until %s, irdb.valid_until %s", child.child_handle, child_cert.gski, old_resources.valid_until, irdb_resources.valid_until) child_cert.delete() publisher.queue(uri = child_cert.uri, old_obj = child_cert.cert, repository = ca_detail.ca.parent.repository) ca_detail.generate_manifest(publisher = publisher) diff --git a/rpki/rpkidb/migrations/0009_auto_20151025_1804.py b/rpki/rpkidb/migrations/0009_auto_20151025_1804.py new file mode 100644 index 00000000..9ffc0650 --- /dev/null +++ b/rpki/rpkidb/migrations/0009_auto_20151025_1804.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('rpkidb', '0008_auto_20151023_2151'), + ] + + operations = [ + migrations.RemoveField( + model_name='childcert', + name='ski', + ), + migrations.RemoveField( + model_name='eecertificate', + name='ski', + ), + migrations.AddField( + model_name='childcert', + name='gski', + field=models.CharField(default='fred', max_length=27), + preserve_default=False, + ), + migrations.AddField( + model_name='eecertificate', + name='gski', + field=models.CharField(default='wilma', max_length=27), + preserve_default=False, + ), + ] diff --git a/rpki/rpkidb/models.py b/rpki/rpkidb/models.py index 32028a1f..1a293360 100644 --- a/rpki/rpkidb/models.py +++ b/rpki/rpkidb/models.py @@ -552,6 +552,10 @@ class Parent(models.Model): Result is a dictionary with the resource class name as key and a set of SKIs as value. + + This, like everything else dealing with SKIs in the up-down + protocol, is mis-named: we're really dealing with g(SKI) values, + not raw SKI values. Sorry. """ r_msg = yield self.up_down_list_query(rpkid = rpkid) @@ -574,7 +578,7 @@ class Parent(models.Model): """ for ski in skis_to_revoke: - logger.debug("Asking parent %r to revoke class %r, SKI %s", self, rc_name, ski) + logger.debug("Asking parent %r to revoke class %r, g(SKI) %s", self, rc_name, ski) yield self.up_down_revoke_query(rpkid = rpkid, class_name = rc_name, ski = ski) @@ -776,7 +780,7 @@ class CA(models.Model): rc_cert, rc_cert_uri = cert_map.pop(ca_detail.public_key.gSKI(), (None, None)) if rc_cert is None: - logger.warning("SKI %s in resource class %s is in database but missing from list_response to %s from %s, " + logger.warning("g(SKI) %s in resource class %s is in database but missing from list_response to %s from %s, " "maybe parent certificate went away?", ca_detail.public_key.gSKI(), class_name, parent.tenant.tenant_handle, parent.parent_handle) publisher = rpki.rpkid.publication_queue(rpkid) @@ -813,7 +817,7 @@ class CA(models.Model): old_resources = current_resources) if cert_map: - logger.warning("Unknown certificate SKI%s %s in resource class %s in list_response to %s from %s, maybe you want to \"revoke_forgotten\"?", + logger.warning("Unknown certificate g(SKI)%s %s in resource class %s in list_response to %s from %s, maybe you want to \"revoke_forgotten\"?", "" if len(cert_map) == 1 else "s", ", ".join(cert_map), class_name, parent.tenant.tenant_handle, parent.parent_handle) @@ -1093,7 +1097,7 @@ class CADetail(models.Model): @tornado.gen.coroutine def revoke(self, rpkid): """ - Request revocation of all certificates whose SKI matches the key + Request revocation of all certificates whose g(SKI) matches the key for this ca_detail. Tasks: @@ -1116,7 +1120,7 @@ class CADetail(models.Model): gski = self.latest_ca_cert.gSKI() - logger.debug("Asking parent to revoke CA certificate %s", gski) + logger.debug("Asking parent to revoke CA certificate matching g(SKI) = %s", gski) r_msg = yield self.ca.parent.up_down_revoke_query(rpkid = rpkid, class_name = self.ca.parent_resource_class, ski = gski) @@ -1126,7 +1130,7 @@ class CADetail(models.Model): if r_msg[0].get("ski") != gski: raise rpki.exceptions.SKIMismatch - logger.debug("Parent revoked %s, starting cleanup", gski) + logger.debug("Parent revoked g(SKI) %s, starting cleanup", gski) crl_interval = rpki.sundial.timedelta(seconds = self.ca.parent.tenant.crl_interval) @@ -1299,7 +1303,7 @@ class CADetail(models.Model): child_cert.cert = cert child_cert.ca_detail = self logger.debug("Reusing existing child_cert %r", child_cert) - child_cert.ski = cert.get_SKI() + child_cert.gski = cert.gSKI() child_cert.published = rpki.sundial.now() child_cert.save() publisher.queue( @@ -1622,7 +1626,7 @@ class Child(models.Model): publisher = rpki.rpkid.publication_queue(rpkid) try: - child_cert = self.child_certs.get(ca_detail = ca_detail, ski = req_key.get_SKI()) + child_cert = self.child_certs.get(ca_detail = ca_detail, gski = req_key.gSKI()) except ChildCert.DoesNotExist: child_cert = ca_detail.issue( @@ -1659,11 +1663,10 @@ class Child(models.Model): key = q_msg[0] assert key.tag == rpki.up_down.tag_key class_name = key.get("class_name") - ski = base64.urlsafe_b64decode(key.get("ski") + "=") publisher = rpki.rpkid.publication_queue(rpkid) for child_cert in ChildCert.objects.filter(ca_detail__ca__parent__tenant = self.tenant, ca_detail__ca__parent_resource_class = class_name, - ski = ski): + gski = key.get("ski")): child_cert.revoke(publisher = publisher) yield publisher.call_pubd() SubElement(r_msg, key.tag, class_name = class_name, ski = key.get("ski")) @@ -1705,7 +1708,7 @@ class Child(models.Model): class ChildCert(models.Model): cert = CertificateField() published = SundialField(null = True) - ski = models.BinaryField() + gski = models.CharField(max_length = 27) # Assumes SHA-1 -- SHA-256 would be 43, SHA-512 would be 86, etc. child = models.ForeignKey(Child, related_name = "child_certs") ca_detail = models.ForeignKey(CADetail, related_name = "child_certs") @@ -1716,7 +1719,7 @@ class ChildCert(models.Model): Return the tail (filename) portion of the URI for this child_cert. """ - return self.cert.gSKI() + ".cer" + return self.gski + ".cer" @property @@ -1792,7 +1795,7 @@ class ChildCert(models.Model): logger.debug("No change to %r", self) return self if must_revoke: - for x in child.child_certs.filter(ca_detail = ca_detail, ski = self.ski): + for x in child.child_certs.filter(ca_detail = ca_detail, gski = self.gski): logger.debug("Revoking child_cert %r", x) x.revoke(publisher = publisher) ca_detail.generate_crl(publisher = publisher) @@ -1820,7 +1823,7 @@ class ChildCert(models.Model): class EECertificate(models.Model): - ski = models.BinaryField() + gski = models.CharField(max_length = 27) # Assumes SHA-1 -- SHA-256 would be 43, SHA-512 would be 86, etc. cert = CertificateField() published = SundialField(null = True) tenant = models.ForeignKey(Tenant, related_name = "ee_certificates") @@ -1828,22 +1831,6 @@ class EECertificate(models.Model): @property - def gski(self): - """ - Calculate g(SKI), for ease of comparison with XML. - - Although, really, one has to ask why we don't just store g(SKI) - instead of SKI.... - """ - - return base64.urlsafe_b64encode(self.ski).rstrip("=") - - @gski.setter - def gski(self, val): - self.ski = base64.urlsafe_b64decode(val + ("=" * ((4 - len(val)) % 4))) - - - @property def uri(self): """ Return the publication URI for this ee_cert_obj. @@ -1859,7 +1846,7 @@ class EECertificate(models.Model): ee_cert_obj. """ - return self.cert.gSKI() + ".cer" + return self.gski + ".cer" @classmethod @@ -1868,8 +1855,14 @@ class EECertificate(models.Model): Generate a new EE certificate. """ + # The low-level X.509 code really ought to supply the singleton + # tuple wrapper when handed a string, but that yak will need to + # wait until another day for its shave. + cn, sn = subject_name.extract_cn_and_sn() - sia = (None, None, ca_detail.ca.sia_uri + subject_key.gSKI() + ".cer", ca_detail.ca.parent.repository.rrdp_notification_uri) + sia = (None, None, + (ca_detail.ca.sia_uri + subject_key.gSKI() + ".cer",), + (ca_detail.ca.parent.repository.rrdp_notification_uri,)) cert = ca_detail.issue_ee( ca = ca_detail.ca, subject_key = subject_key, @@ -1879,7 +1872,7 @@ class EECertificate(models.Model): cn = cn, sn = sn, eku = eku) - self = cls(tenant = ca_detail.ca.parent.tenant, ca_detail = ca_detail, cert = cert, ski = subject_key.get_SKI()) + self = cls(tenant = ca_detail.ca.parent.tenant, ca_detail = ca_detail, cert = cert, gski = subject_key.gSKI()) publisher.queue( uri = self.uri, new_obj = self.cert, |