aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rpkid/rpki/irdb/models.py8
-rw-r--r--rpkid/rpki/rpkic.py236
-rw-r--r--scripts/convert-from-entitydb-to-sql.py5
3 files changed, 118 insertions, 131 deletions
diff --git a/rpkid/rpki/irdb/models.py b/rpkid/rpki/irdb/models.py
index 20f38d6c..34656363 100644
--- a/rpkid/rpki/irdb/models.py
+++ b/rpkid/rpki/irdb/models.py
@@ -296,7 +296,8 @@ class CrossCertification(Certificate):
return self.handle
class HostedCA(Certificate):
- hosted_ca = OneToOneField(CA, related_name = "hosting_ca")
+ issuer = django.db.models.ForeignKey(CA)
+ hosted = django.db.models.OneToOneField(CA, related_name = "hosted_by")
def avow(self):
self.certificate = self.issuer.certify(
@@ -306,6 +307,9 @@ class HostedCA(Certificate):
is_ca = True,
pathLenConstraint = 1)
+ class Meta:
+ unique_together = ("issuer", "hosted")
+
def __unicode__(self):
return self.hosted_ca.handle
@@ -412,3 +416,5 @@ class Repository(CrossCertification):
class Client(CrossCertification):
issuer = django.db.models.ForeignKey(CA, related_name = "clients")
+ sia_base = django.db.models.TextField()
+
diff --git a/rpkid/rpki/rpkic.py b/rpkid/rpki/rpkic.py
index f77eefbb..5a0aff85 100644
--- a/rpkid/rpki/rpkic.py
+++ b/rpkid/rpki/rpkic.py
@@ -178,6 +178,8 @@ class main(rpki.cli.Cmd):
self.cfg = rpki.config.parser(self.cfg_file, "myrpki")
+ self.cfg.set_global_flags()
+
if self.handle is None:
self.handle = self.cfg.get("handle")
@@ -592,7 +594,8 @@ class main(rpki.cli.Cmd):
rpki.irdb.Client.get_or_certify(
issuer = self.server_ca,
handle = client_handle,
- ta = client_ta)
+ ta = client_ta,
+ sia_base = sia_base)
e = Element("repository", type = "confirmed",
client_handle = client_handle,
@@ -828,8 +831,6 @@ class main(rpki.cli.Cmd):
bsc_handle = "bsc"
- self.cfg.set_global_flags()
-
# Default values for CRL parameters are low, for testing. Not
# quite as low as they once were, too much expired CRL whining.
@@ -870,32 +871,18 @@ class main(rpki.cli.Cmd):
for ca in rpki.irdb.CA.objects.exclude(handle = ""):
- # rpkid_xcert is the server CA cross-certifying this resource CA
- # so that stuff trusted by this resource CA will validate for
- # rpkid. The resource cross-certifies parents and children with
- # PathLen 0 so that parent and child EE certs can be rolled;
- # this cross-certification therefore needs to be PathLen 1.
- #
- # HostedCA class in models is an attempt to represent this.
- # Not yet hacked into other code.
-
- rpkid_xcert = rpki.x509.X509(PEM_file = self.bpki_servers.fxcert(
- b64 = hosted_cacert.get_Base64(),
- path_restriction = 1))
-
# See what rpkid and pubd already have on file for this entity.
if self.run_pubd:
- client_pdus = dict((x.client_handle, x)
- for x in call_pubd(rpki.publication.client_elt.make_pdu(action = "list"))
- if isinstance(x, rpki.publication.client_elt))
+ pubd_reply = call_pubd(rpki.publication.client_elt.make_pdu(action = "list"))
+ client_pdus = dict((x.client_handle, x) for x in pubd_reply if isinstance(x, rpki.publication.client_elt))
rpkid_reply = call_rpkid(
- rpki.left_right.self_elt.make_pdu( action = "get", tag = "self", self_handle = handle),
- rpki.left_right.bsc_elt.make_pdu( action = "list", tag = "bsc", self_handle = handle),
- rpki.left_right.repository_elt.make_pdu(action = "list", tag = "repository", self_handle = handle),
- rpki.left_right.parent_elt.make_pdu( action = "list", tag = "parent", self_handle = handle),
- rpki.left_right.child_elt.make_pdu( action = "list", tag = "child", self_handle = handle))
+ rpki.left_right.self_elt.make_pdu( action = "get", tag = "self", self_handle = ca.handle),
+ rpki.left_right.bsc_elt.make_pdu( action = "list", tag = "bsc", self_handle = ca.handle),
+ rpki.left_right.repository_elt.make_pdu(action = "list", tag = "repository", self_handle = ca.handle),
+ rpki.left_right.parent_elt.make_pdu( action = "list", tag = "parent", self_handle = ca.handle),
+ rpki.left_right.child_elt.make_pdu( action = "list", tag = "child", self_handle = ca.handle))
self_pdu = rpkid_reply[0]
bsc_pdus = dict((x.bsc_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.bsc_elt))
@@ -906,27 +893,28 @@ class main(rpki.cli.Cmd):
pubd_query = []
rpkid_query = []
+ self_cert = rpki.irdb.HostedCA.objects.get_or_certify(
+ issuer = self.server_ca,
+ hosted = ca)[0]
+
# There should be exactly one <self/> object per hosted entity, by definition
if (isinstance(self_pdu, rpki.left_right.report_error_elt) or
self_pdu.crl_interval != self_crl_interval or
self_pdu.regen_margin != self_regen_margin or
- self_pdu.bpki_cert != rpkid_xcert):
+ self_pdu.bpki_cert != self_cert.certificate):
rpkid_query.append(rpki.left_right.self_elt.make_pdu(
action = "create" if isinstance(self_pdu, rpki.left_right.report_error_elt) else "set",
tag = "self",
- self_handle = handle,
- bpki_cert = rpkid_xcert,
+ self_handle = ca.handle,
+ bpki_cert = self.cert.certificate,
crl_interval = self_crl_interval,
regen_margin = self_regen_margin))
- # In general we only need one <bsc/> per <self/>. BSC objects are a
- # little unusual in that the PKCS #10 subelement is generated by rpkid
- # in response to generate_keypair, so there's more of a separation
- # between create and set than with other objects.
-
- bsc_cert = findbase64(tree, "bpki_bsc_certificate")
- bsc_crl = findbase64(tree, "bpki_crl", rpki.x509.CRL)
+ # In general we only need one <bsc/> per <self/>. BSC objects
+ # are a little unusual in that the keypair and PKCS #10
+ # subelement is generated by rpkid, so complete setup requires
+ # two round trips.
bsc_pdu = bsc_pdus.pop(bsc_handle, None)
@@ -934,25 +922,53 @@ class main(rpki.cli.Cmd):
rpkid_query.append(rpki.left_right.bsc_elt.make_pdu(
action = "create",
tag = "bsc",
- self_handle = handle,
+ self_handle = ca.handle,
bsc_handle = bsc_handle,
generate_keypair = "yes"))
- elif bsc_pdu.signing_cert != bsc_cert or bsc_pdu.signing_cert_crl != bsc_crl:
+
+ elif bsc_pdu.pkcs10_request is None:
rpkid_query.append(rpki.left_right.bsc_elt.make_pdu(
action = "set",
tag = "bsc",
- self_handle = handle,
+ self_handle = ca.handle,
bsc_handle = bsc_handle,
- signing_cert = bsc_cert,
- signing_cert_crl = bsc_crl))
+ generate_keypair = "yes"))
rpkid_query.extend(rpki.left_right.bsc_elt.make_pdu(
- action = "destroy", self_handle = handle, bsc_handle = b) for b in bsc_pdus)
+ action = "destroy", self_handle = ca.handle, bsc_handle = b) for b in bsc_pdus)
+
+ # If we've already got actions queued up, run them now, so we
+ # can finish setting up the BSC before anything tries to use it.
+
+ if rpkid_query:
+ rpkid_reply = call_rpkid(*rpkid_query)
+ bsc_pdus = dict((x.bsc_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.bsc_elt))
+ bsc_pdu = bsc_pdus.pop(bsc_handle, None)
+ for r in rpkid_reply:
+ if isinstance(r, rpki.left_right.report_error_elt):
+ print "rpkid reported failure:", r.error_code
+ if r.error_text:
+ print r.error_text
+ if any(isinstance(r, rpki.left_right.report_error_elt) for r in rpkid_reply):
+ raise CouldntTalkToDaemon
+
+ rpkid_query = []
- bsc_req = None
+ assert bsc_pdu.pkcs10_request is not None
- if bsc_pdu and bsc_pdu.pkcs10_request:
- bsc_req = bsc_pdu.pkcs10_request
+ bsc = rpki.irdb.BSC.get_or_certify(
+ issuer = ca,
+ handle = bsc_handle,
+ pkcs10 = bsc_pdu.pkcs10_request)[0]
+
+ if bsc_pdu.signing_cert != bsc.certificate or bsc_pdu.signing_cert_crl != ca.latest_crl:
+ rpkid_query.append(rpki.left_right.bsc_elt.make_pdu(
+ action = "set",
+ tag = "bsc",
+ self_handle = ca.handle,
+ bsc_handle = bsc_handle,
+ signing_cert = bsc.certificate,
+ signing_cert_crl = ca.latest_crl))
# At present we need one <repository/> per <parent/>, not because
# rpkid requires that, but because pubd does. pubd probably should
@@ -960,122 +976,105 @@ class main(rpki.cli.Cmd):
# trees, but for the moment the easiest way forward is just to
# enforce a 1:1 mapping between <parent/> and <repository/> objects
- for repository in tree.getiterator("repository"):
+ for repository in ca.repositories:
- repository_handle = repository.get("handle")
- repository_pdu = repository_pdus.pop(repository_handle, None)
- repository_uri = repository.get("service_uri")
- repository_cert = findbase64(repository, "bpki_certificate")
+ repository_pdu = repository_pdus.pop(repository.handle, None)
if (repository_pdu is None or
repository_pdu.bsc_handle != bsc_handle or
- repository_pdu.peer_contact_uri != repository_uri or
- repository_pdu.bpki_cert != repository_cert):
+ repository_pdu.peer_contact_uri != repository.service_uri or
+ repository_pdu.bpki_cert != repository.certificate):
rpkid_query.append(rpki.left_right.repository_elt.make_pdu(
action = "create" if repository_pdu is None else "set",
- tag = repository_handle,
- self_handle = handle,
- repository_handle = repository_handle,
+ tag = repository.handle,
+ self_handle = ca.handle,
+ repository_handle = repository.handle,
bsc_handle = bsc_handle,
- peer_contact_uri = repository_uri,
- bpki_cert = repository_cert))
+ peer_contact_uri = repository.service_uri,
+ bpki_cert = repository.certificate))
rpkid_query.extend(rpki.left_right.repository_elt.make_pdu(
- action = "destroy", self_handle = handle, repository_handle = r) for r in repository_pdus)
+ action = "destroy", self_handle = ca.handle, repository_handle = r) for r in repository_pdus)
# <parent/> setup code currently assumes 1:1 mapping between
# <repository/> and <parent/>, and further assumes that the handles
# for an associated pair are the identical (that is:
# parent.repository_handle == parent.parent_handle).
- for parent in tree.getiterator("parent"):
+ for parent in ca.parents:
- parent_handle = parent.get("handle")
- parent_pdu = parent_pdus.pop(parent_handle, None)
- parent_uri = parent.get("service_uri")
- parent_myhandle = parent.get("myhandle")
- parent_sia_base = parent.get("sia_base")
- parent_cms_cert = findbase64(parent, "bpki_cms_certificate")
+ parent_pdu = parent_pdus.pop(parent.handle, None)
if (parent_pdu is None or
parent_pdu.bsc_handle != bsc_handle or
- parent_pdu.repository_handle != parent_handle or
- parent_pdu.peer_contact_uri != parent_uri or
- parent_pdu.sia_base != parent_sia_base or
- parent_pdu.sender_name != parent_myhandle or
- parent_pdu.recipient_name != parent_handle or
- parent_pdu.bpki_cms_cert != parent_cms_cert):
+ parent_pdu.repository_handle != parent.handle or
+ parent_pdu.peer_contact_uri != parent.service_uri or
+ parent_pdu.sia_base != parent.repository.sia_base or
+ parent_pdu.sender_name != parent.child_handle or
+ parent_pdu.recipient_name != parent.parent_handle or
+ parent_pdu.bpki_cms_cert != parent.certificate):
rpkid_query.append(rpki.left_right.parent_elt.make_pdu(
action = "create" if parent_pdu is None else "set",
- tag = parent_handle,
- self_handle = handle,
- parent_handle = parent_handle,
+ tag = parent.handle,
+ self_handle = ca.handle,
+ parent_handle = parent.handle,
bsc_handle = bsc_handle,
- repository_handle = parent_handle,
- peer_contact_uri = parent_uri,
- sia_base = parent_sia_base,
- sender_name = parent_myhandle,
- recipient_name = parent_handle,
- bpki_cms_cert = parent_cms_cert))
+ repository_handle = parent.handle,
+ peer_contact_uri = parent.service_uri,
+ sia_base = parent.repository.sia_base,
+ sender_name = parent.child_handle,
+ recipient_name = parent.parent_handle,
+ bpki_cms_cert = parent.certificate))
rpkid_query.extend(rpki.left_right.parent_elt.make_pdu(
- action = "destroy", self_handle = handle, parent_handle = p) for p in parent_pdus)
+ action = "destroy", self_handle = ca.handle, parent_handle = p) for p in parent_pdus)
# Children are simpler than parents, because they call us, so no URL
# to construct and figuring out what certificate to use is their
# problem, not ours.
- for child in tree.getiterator("child"):
+ for child in ca.children:
- child_handle = child.get("handle")
- child_pdu = child_pdus.pop(child_handle, None)
- child_cert = findbase64(child, "bpki_certificate")
+ child_pdu = child_pdus.pop(child.handle, None)
if (child_pdu is None or
child_pdu.bsc_handle != bsc_handle or
- child_pdu.bpki_cert != child_cert):
+ child_pdu.bpki_cert != child.certificate):
rpkid_query.append(rpki.left_right.child_elt.make_pdu(
action = "create" if child_pdu is None else "set",
- tag = child_handle,
- self_handle = handle,
- child_handle = child_handle,
+ tag = child.handle,
+ self_handle = ca.handle,
+ child_handle = child.handle,
bsc_handle = bsc_handle,
- bpki_cert = child_cert))
+ bpki_cert = child.certificate))
rpkid_query.extend(rpki.left_right.child_elt.make_pdu(
- action = "destroy", self_handle = handle, child_handle = c) for c in child_pdus)
+ action = "destroy", self_handle = ca.handle, child_handle = c) for c in child_pdus)
# Publication setup.
+ # Um, why are we doing this per resource holder?
+
if self.run_pubd:
- for f in self.entitydb.iterate("pubclients"):
- c = etree_read(f)
+ for client in self.server_ca.clients:
- client_handle = c.get("client_handle")
- client_base_uri = c.get("sia_base")
- client_bpki_cert = rpki.x509.X509(PEM_file = self.bpki_servers.fxcert(
- b64 = c.findtext("bpki_client_ta"),
- handle = client_handle,
- bpki_type = rpki.irdb.Client))
- client_pdu = client_pdus.pop(client_handle, None)
+ client_pdu = client_pdus.pop(client.handle, None)
if (client_pdu is None or
- client_pdu.base_uri != client_base_uri or
- client_pdu.bpki_cert != client_bpki_cert):
+ client_pdu.base_uri != client.sia_base or
+ client_pdu.bpki_cert != client.certificate):
pubd_query.append(rpki.publication.client_elt.make_pdu(
action = "create" if client_pdu is None else "set",
- client_handle = client_handle,
- bpki_cert = client_bpki_cert,
- base_uri = client_base_uri))
+ client_handle = client.handle,
+ bpki_cert = client.certificate,
+ base_uri = client.sia_base))
pubd_query.extend(rpki.publication.client_elt.make_pdu(
action = "destroy", client_handle = p) for p in client_pdus)
# If we changed anything, ship updates off to daemons
- failed = False
-
if rpkid_query:
rpkid_reply = call_rpkid(*rpkid_query)
bsc_pdus = dict((x.bsc_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.bsc_elt))
@@ -1083,38 +1082,19 @@ class main(rpki.cli.Cmd):
bsc_req = bsc_pdus[bsc_handle].pkcs10_request
for r in rpkid_reply:
if isinstance(r, rpki.left_right.report_error_elt):
- failed = True
print "rpkid reported failure:", r.error_code
if r.error_text:
print r.error_text
-
- if failed:
- raise CouldntTalkToDaemon
+ if any(isinstance(r, rpki.left_right.report_error_elt) for r in rpkid_reply):
+ raise CouldntTalkToDaemon
if pubd_query:
assert self.run_pubd
pubd_reply = call_pubd(*pubd_query)
for r in pubd_reply:
if isinstance(r, rpki.publication.report_error_elt):
- failed = True
print "pubd reported failure:", r.error_code
if r.error_text:
print r.error_text
-
- if failed:
- raise CouldntTalkToDaemon
-
- # Rewrite XML.
-
- e = tree.find("bpki_bsc_pkcs10")
- if e is not None:
- tree.remove(e)
- if bsc_req is not None:
- SubElement(tree, "bpki_bsc_pkcs10").text = bsc_req.get_Base64()
-
- tree.set("service_uri", rpkid_base + "up-down/" + handle)
-
- etree_write(tree, xmlfile,
- msg = None if xmlfile is my_xmlfile else 'Send this file back to the hosted entity ("%s")' % handle)
-
- irdb.close()
+ if any(isinstance(r, rpki.publication.report_error_elt) for r in pubd_reply):
+ raise CouldntTalkToDaemon
diff --git a/scripts/convert-from-entitydb-to-sql.py b/scripts/convert-from-entitydb-to-sql.py
index aa15b461..8c1e6bbb 100644
--- a/scripts/convert-from-entitydb-to-sql.py
+++ b/scripts/convert-from-entitydb-to-sql.py
@@ -363,11 +363,12 @@ for filename in glob.iglob(os.path.join(entitydb, "pubclients", "*.xml")):
xcert_filenames.discard(xcfn)
xcert = rpki.x509.X509(Auto_file = xcfn)
- rpki.irdb.Repository.objects.get_or_create(
+ rpki.irdb.Client.objects.get_or_create(
handle = client_handle,
ta = ta,
certificate = xcert,
- issuer = server_ca)
+ issuer = server_ca,
+ sia_base = e.get("sia_base"))
if copy_csv_data: