aboutsummaryrefslogtreecommitdiff
path: root/rpkid
diff options
context:
space:
mode:
Diffstat (limited to 'rpkid')
-rw-r--r--rpkid/rpki/irdb/models.py136
-rw-r--r--rpkid/rpki/rpkic.py44
2 files changed, 115 insertions, 65 deletions
diff --git a/rpkid/rpki/irdb/models.py b/rpkid/rpki/irdb/models.py
index 9ab50de5..2cc3f5aa 100644
--- a/rpkid/rpki/irdb/models.py
+++ b/rpkid/rpki/irdb/models.py
@@ -154,13 +154,7 @@ class CertificateManager(django.db.models.Manager):
changed = False
try:
- # Seriously icky, but does what we need. Rewrite using some
- # kind of method routine that returns the key names.
- try:
- keys = self.model._meta.unique_together[0] or ("handle",)
- except (AttributeError, IndexError):
- keys = ("handle",)
- obj = self.get(**dict((k, kwargs[k]) for k in keys))
+ obj = self.get(**self._get_or_certify_keys(kwargs))
except self.model.DoesNotExist:
obj = self.model(**kwargs)
@@ -178,10 +172,24 @@ class CertificateManager(django.db.models.Manager):
return obj, changed
+ def _get_or_certify_keys(self, kwargs):
+ return dict((k, kwargs[k]) for k in self.model._meta.unique_together[0])
+
+class ResourceHolderCAManager(CertificateManager):
+ def _get_or_certify_keys(self, kwargs):
+ return { "handle" : kwargs["handle"] }
+
+class ServerCAManager(CertificateManager):
+ def _get_or_certify_keys(self, kwargs):
+ return { "pk" : 1 }
+
+class ReferralCertificateManager(CertificateManager):
+ def _get_or_certify_keys(self, kwargs):
+ return { "issuer" : kwargs["issuer"] }
+
###
class CA(django.db.models.Model):
- handle = HandleField(unique = True)
certificate = CertificateField()
private_key = RSAKeyField()
latest_crl = CRLField()
@@ -195,27 +203,21 @@ class CA(django.db.models.Model):
last_crl_update = SundialField()
next_crl_update = SundialField()
- objects = CertificateManager()
-
# These should come from somewhere, but I don't yet know where
ca_certificate_lifetime = rpki.sundial.timedelta(days = 3652)
crl_interval = rpki.sundial.timedelta(days = 1)
- def __unicode__(self):
- return self.handle
+ class Meta:
+ abstract = True
def avow(self):
if self.private_key is None:
self.private_key = rpki.x509.RSA.generate()
- if self.handle:
- subject_name = rpki.x509.X501DN("%s BPKI resource CA" % self.handle)
- else:
- subject_name = rpki.x509.X501DN("%s BPKI server CA" % socket.gethostname())
now = rpki.sundial.now()
notAfter = now + self.ca_certificate_lifetime
self.certificate = rpki.x509.X509.bpki_self_certify(
keypair = self.private_key,
- subject_name = subject_name,
+ subject_name = self.subject_name,
serial = self.next_serial,
now = now,
notAfter = notAfter)
@@ -263,6 +265,27 @@ class CA(django.db.models.Model):
self.next_crl_update = now + self.crl_interval
self.next_crl_number += 1
+class ServerCA(CA):
+ objects = ServerCAManager()
+
+ def __unicode__(self):
+ return ""
+
+ @property
+ def subject_name(self):
+ return rpki.x509.X501DN("%s BPKI server CA" % socket.gethostname())
+
+class ResourceHolderCA(CA):
+ handle = HandleField(unique = True)
+ objects = ResourceHolderCAManager()
+
+ def __unicode__(self):
+ return self.handle
+
+ @property
+ def subject_name(self):
+ return rpki.x509.X501DN("%s BPKI resource CA" % self.handle)
+
class Certificate(django.db.models.Model):
certificate = CertificateField()
@@ -286,25 +309,25 @@ class CrossCertification(Certificate):
def avow(self):
self.certificate = self.issuer.certify(
- subject_name = self.ta.getSubject(),
- subject_key = self.ta.getPublicKey(),
- interval = self.default_interval,
- is_ca = True,
+ subject_name = self.ta.getSubject(),
+ subject_key = self.ta.getPublicKey(),
+ validity_interval = self.default_interval,
+ is_ca = True,
pathLenConstraint = 0)
def __unicode__(self):
return self.handle
class HostedCA(Certificate):
- issuer = django.db.models.ForeignKey(CA)
- hosted = django.db.models.OneToOneField(CA, related_name = "hosted_by")
+ issuer = django.db.models.ForeignKey(ServerCA)
+ hosted = django.db.models.OneToOneField(ResourceHolderCA, related_name = "hosted_by")
def avow(self):
self.certificate = self.issuer.certify(
- subject_name = self.hosted_ca.getSubject(),
- subject_key = self.hosted_ca.getPublicKey(),
- interval = self.default_interval,
- is_ca = True,
+ subject_name = self.hosted_ca.getSubject(),
+ subject_key = self.hosted_ca.getPublicKey(),
+ validity_interval = self.default_interval,
+ is_ca = True,
pathLenConstraint = 1)
class Meta:
@@ -314,51 +337,72 @@ class HostedCA(Certificate):
return self.hosted_ca.handle
class Revocation(django.db.models.Model):
- issuer = django.db.models.ForeignKey(CA, related_name = "revocations")
serial = django.db.models.BigIntegerField()
revoked = SundialField()
expires = SundialField()
class Meta:
+ abstract = True
unique_together = ("issuer", "serial")
+class ServerRevocation(Revocation):
+ issuer = django.db.models.ForeignKey(ServerCA, related_name = "revocations")
+
+class ResourceHolderRevocation(Revocation):
+ issuer = django.db.models.ForeignKey(ResourceHolderCA, related_name = "revocations")
+
class EECertificate(Certificate):
- issuer = django.db.models.ForeignKey(CA, related_name = "ee_certificates")
- purpose = EnumField(choices = ("rpkid", "pubd", "irdbd", "irbe", "rootd", "referral"))
private_key = RSAKeyField()
class Meta:
- unique_together = ("issuer", "purpose")
+ abstract = True
def avow(self):
if self.private_key is None:
self.private_key = rpki.x509.RSA.generate()
- subject_name = rpki.x509.X501DN("%s BPKI %s EE" % (
- self.issuer.handle if self.issuer.handle else socket.gethostname(),
- self.get_purpose_display()))
self.certificate = self.issuer.certify(
- subject_name = subject_name,
+ subject_name = self.subject_name,
subject_key = self.private_key.get_RSApublic(),
validity_interval = self.default_interval,
is_ca = False)
+class ServerCertificate(EECertificate):
+ issuer = django.db.models.ForeignKey(ServerCA, related_name = "ee_certificates")
+ purpose = EnumField(choices = ("rpkid", "pubd", "irdbd", "irbe", "rootd"))
+
+ class Meta:
+ unique_together = ("issuer", "purpose")
+
+ @property
+ def subject_name(self):
+ return rpki.x509.X501DN("%s BPKI %s EE" % (socket.gethostname(), self.get_purpose_display()))
+
+class ReferralCertificate(EECertificate):
+ issuer = django.db.models.OneToOneField(ResourceHolderCA, related_name = "referral_certificate")
+ objects = ReferralCertificateManager()
+
+ @property
+ def subject_name(self):
+ return rpki.x509.X501DN("%s BPKI Referral EE" % self.issuer.handle)
+
+
class BSC(Certificate):
- issuer = django.db.models.ForeignKey(CA, related_name = "bscs")
+ issuer = django.db.models.ForeignKey(ResourceHolderCA, related_name = "bscs")
handle = HandleField()
pkcs10 = PKCS10Field()
def avow(self):
self.certificate = self.issuer.certify(
- subject_name = self.pkcs10.getSubject(),
- subject_key = self.pkcs10.getPublicKey(),
- interval = self.default_interval,
- is_ca = False)
+ subject_name = self.pkcs10.getSubject(),
+ subject_key = self.pkcs10.getPublicKey(),
+ validity_interval = self.default_interval,
+ is_ca = False)
def __unicode__(self):
return self.handle
class Child(CrossCertification):
- issuer = django.db.models.ForeignKey(CA, related_name = "children")
+ issuer = django.db.models.ForeignKey(ResourceHolderCA, related_name = "children")
name = django.db.models.TextField(null = True, blank = True)
valid_until = SundialField()
@@ -380,7 +424,7 @@ class ChildNet(django.db.models.Model):
unique_together = ("child", "start_ip", "end_ip", "version")
class Parent(CrossCertification):
- issuer = django.db.models.ForeignKey(CA, related_name = "parents")
+ issuer = django.db.models.ForeignKey(ResourceHolderCA, related_name = "parents")
parent_handle = HandleField()
child_handle = HandleField()
service_uri = django.db.models.CharField(max_length = 255)
@@ -389,7 +433,7 @@ class Parent(CrossCertification):
referral_authorization = SignedReferralField(null = True, blank = True)
class ROARequest(django.db.models.Model):
- issuer = django.db.models.ForeignKey(CA, related_name = "roa_requests")
+ issuer = django.db.models.ForeignKey(ResourceHolderCA, related_name = "roa_requests")
asn = django.db.models.BigIntegerField()
class ROARequestPrefix(django.db.models.Model):
@@ -403,18 +447,18 @@ class ROARequestPrefix(django.db.models.Model):
unique_together = ("roa_request", "version", "prefix", "prefixlen", "max_prefixlen")
class GhostbusterRequest(django.db.models.Model):
- issuer = django.db.models.ForeignKey(CA, related_name = "ghostbuster_requests")
+ issuer = django.db.models.ForeignKey(ResourceHolderCA, related_name = "ghostbuster_requests")
parent = django.db.models.ForeignKey(Parent, related_name = "ghostbuster_requests", null = True)
vcard = django.db.models.TextField()
class Repository(CrossCertification):
- issuer = django.db.models.ForeignKey(CA, related_name = "repositories")
+ issuer = django.db.models.ForeignKey(ResourceHolderCA, related_name = "repositories")
client_handle = HandleField()
service_uri = django.db.models.CharField(max_length = 255)
sia_base = django.db.models.TextField()
parent = django.db.models.OneToOneField(Parent, related_name = "repository")
class Client(CrossCertification):
- issuer = django.db.models.ForeignKey(CA, related_name = "clients")
+ issuer = django.db.models.ForeignKey(ServerCA, related_name = "clients")
sia_base = django.db.models.TextField()
diff --git a/rpkid/rpki/rpkic.py b/rpkid/rpki/rpkic.py
index ea2b7b2a..88e3f26b 100644
--- a/rpkid/rpki/rpkic.py
+++ b/rpkid/rpki/rpkic.py
@@ -218,12 +218,12 @@ class main(rpki.cli.Cmd):
def reset_identity(self):
try:
- self.resource_ca = rpki.irdb.CA.objects.get(handle = self.handle)
- except rpki.irdb.CA.DoesNotExist:
+ self.resource_ca = rpki.irdb.ResourceHolderCA.objects.get(handle = self.handle)
+ except rpki.irdb.ResourceHolderCA.DoesNotExist:
self.resource_ca = None
try:
- self.server_ca = rpki.irdb.CA.objects.get(handle = "*")
- except rpki.irdb.CA.DoesNotExist:
+ self.server_ca = rpki.irdb.ServerCA.objects.get()
+ except rpki.irdb.ServerCA.DoesNotExist:
self.server_ca = None
def help_overview(self):
@@ -252,7 +252,7 @@ class main(rpki.cli.Cmd):
self.reset_identity()
def complete_select_identity(self, *args):
- return self.irdb_handle_complete(rpki.irdb.CA, *args)
+ return self.irdb_handle_complete(rpki.irdb.ResourceHolderCA, *args)
def do_initialize(self, arg):
@@ -266,23 +266,23 @@ class main(rpki.cli.Cmd):
if arg:
raise BadCommandSyntax, "This command takes no arguments"
- self.resource_ca, created = rpki.irdb.CA.objects.get_or_certify(handle = self.handle)
+ self.resource_ca, created = rpki.irdb.ResourceHolderCA.objects.get_or_certify(handle = self.handle)
if created:
print "Created new BPKI resource CA for identity %s" % self.handle
if self.run_rpkid or self.run_pubd or self.run_rootd:
- self.server_ca, created = rpki.irdb.CA.objects.get_or_certify(handle = "*")
+ self.server_ca, created = rpki.irdb.ServerCA.objects.get_or_certify()
if created:
print "Created new BPKI server CA"
if self.run_rpkid:
- rpki.irdb.EECertificate.objects.get_or_certify(issuer = self.server_ca, purpose = "rpkid")
- rpki.irdb.EECertificate.objects.get_or_certify(issuer = self.server_ca, purpose = "irdbd")
+ rpki.irdb.ServerCertificate.objects.get_or_certify(issuer = self.server_ca, purpose = "rpkid")
+ rpki.irdb.ServerCertificate.objects.get_or_certify(issuer = self.server_ca, purpose = "irdbd")
if self.run_pubd:
- rpki.irdb.EECertificate.objects.get_or_certify(issuer = self.server_ca, purpose = "pubd")
+ rpki.irdb.ServerCertificate.objects.get_or_certify(issuer = self.server_ca, purpose = "pubd")
if self.run_rpkid or self.run_pubd:
- rpki.irdb.EECertificate.objects.get_or_certify(issuer = self.server_ca, purpose = "irbe")
+ rpki.irdb.ServerCertificate.objects.get_or_certify(issuer = self.server_ca, purpose = "irbe")
if self.run_rootd:
- rpki.irdb.EECertificate.objects.get_or_certify(issuer = self.server_ca, purpose = "rootd")
+ rpki.irdb.ServerCertificate.objects.get_or_certify(issuer = self.server_ca, purpose = "rootd")
## @todo
# Why do we issue root's EE certificate under our server CA?
@@ -345,19 +345,25 @@ class main(rpki.cli.Cmd):
Most likely this should be run under cron.
"""
- for model in (rpki.irdb.CA,
- rpki.irdb.EECertificate,
+ for model in (rpki.irdb.ServerCA,
+ rpki.irdb.ResourceHolderCA,
+ rpki.irdb.ServerCertificate,
+ rpki.irdb.HostedCA,
+ rpki.irdb.ReferralCertificate,
rpki.irdb.BSC,
rpki.irdb.Child,
rpki.irdb.Parent,
rpki.irdb.Client,
rpki.irdb.Repository):
- for obj in model.all():
+ for obj in model.objects.all():
print "Regenerating certificate", obj.certificate.getSubject()
obj.avow()
- for ca in rpki.irdb.CA.all():
- print "Regenerating CRL for", ca.handle if ca.handle else "[servers]"
+ print "Regenerating Server CRL"
+ self.server_ca.generate_crl()
+
+ for ca in rpki.irdb.ResourceHolderCA.objects.all():
+ print "Regenerating CRL for", ca.handle
ca.generate_crl()
def do_configure_child(self, arg):
@@ -547,7 +553,7 @@ class main(rpki.cli.Cmd):
client_ta = rpki.x509.X509(Base64 = client.findtext("bpki_client_ta"))
- if sia_base is None and client.get("handle") == self.handle and self.bpki_resources.ca.certificate == client_ta:
+ if sia_base is None and client.get("handle") == self.handle and self.resource_ca.certificate == client_ta:
print "This looks like self-hosted publication"
sia_base = "rsync://%s/%s/%s/" % (self.rsync_server, self.rsync_module, self.handle)
@@ -869,7 +875,7 @@ class main(rpki.cli.Cmd):
action = "set",
bpki_crl = self.server_ca.latest_crl))
- for ca in rpki.irdb.CA.objects.exclude(handle = "*"):
+ for ca in rpki.irdb.ResourceHolderCA.objects.all():
# See what rpkid and pubd already have on file for this entity.