aboutsummaryrefslogtreecommitdiff
path: root/rpkid
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2014-02-20 06:43:48 +0000
committerRob Austein <sra@hactrn.net>2014-02-20 06:43:48 +0000
commit065c44e912a7fca14ae641a09aa89d0a573c3cdf (patch)
treeeccbc17bcb74d8cec5b429aeda65d940a0fbefae /rpkid
parent8453e66ddfbee5fdf8ab3bc94e88104dae50980b (diff)
Checkpoint. Now generating something that looks a bit like a router
cert, but not right yet: RSA where should be ECDSA, EKU missing, and EE certificate class's .reissue() method isn't working properly yet. svn path=/branches/tk671/; revision=5673
Diffstat (limited to 'rpkid')
-rw-r--r--rpkid/rpki/left_right.py6
-rw-r--r--rpkid/rpki/old_irdbd.py7
-rw-r--r--rpkid/rpki/rpkid.py21
-rw-r--r--rpkid/rpki/rpkid_tasks.py23
-rw-r--r--rpkid/rpki/x509.py5
-rw-r--r--rpkid/tests/old_irdbd.sql1
-rw-r--r--rpkid/tests/smoketest.py66
7 files changed, 112 insertions, 17 deletions
diff --git a/rpkid/rpki/left_right.py b/rpkid/rpki/left_right.py
index cb25046c..dcfc5f40 100644
--- a/rpkid/rpki/left_right.py
+++ b/rpkid/rpki/left_right.py
@@ -390,9 +390,9 @@ class self_elt(data_elt):
results = set()
for parent in self.parents:
for ca in parent.cas:
- for ca_detail in ca.active_ca_details:
- if ca_detail.covers(resources):
- results.add(ca_detail)
+ ca_detail = ca.active_ca_detail
+ if ca_detail is not None and ca_detail.covers(resources):
+ results.add(ca_detail)
return results
diff --git a/rpkid/rpki/old_irdbd.py b/rpkid/rpki/old_irdbd.py
index a9585307..25ceb656 100644
--- a/rpkid/rpki/old_irdbd.py
+++ b/rpkid/rpki/old_irdbd.py
@@ -170,18 +170,19 @@ class main(object):
self.cur.execute(
"""
- SELECT ee_certificate_id, gski, router_id, valid_until
+ SELECT ee_certificate_id, pkcs10, gski, router_id, valid_until
FROM ee_certificate
WHERE self_handle = %s
""",
(q_pdu.self_handle,))
- for ee_certificate_id, gski, router_id, valid_until in self.cur.fetchall():
+ for ee_certificate_id, pkcs10, gski, router_id, valid_until in self.cur.fetchall():
- r_pdu = rpki.left_right.ee_certificates_request_elt()
+ r_pdu = rpki.left_right.list_ee_certificate_requests_elt()
r_pdu.tag = q_pdu.tag
r_pdu.self_handle = q_pdu.self_handle
r_pdu.valid_until = valid_until.strftime("%Y-%m-%dT%H:%M:%SZ")
+ r_pdu.pkcs10 = rpki.x509.PKCS10(DER = pkcs10)
r_pdu.gski = gski
r_pdu.router_id = router_id
diff --git a/rpkid/rpki/rpkid.py b/rpkid/rpki/rpkid.py
index e825caf2..965eb9d4 100644
--- a/rpkid/rpki/rpkid.py
+++ b/rpkid/rpki/rpkid.py
@@ -27,6 +27,7 @@ import argparse
import sys
import re
import random
+import base64
import rpki.resource_set
import rpki.up_down
import rpki.left_right
@@ -847,6 +848,13 @@ class ca_detail_obj(rpki.sql.sql_persistent):
"""
return rpki.rpkid.ghostbuster_obj.sql_fetch_where(self.gctx, "ca_detail_id = %s", (self.ca_detail_id,))
+ @property
+ def ee_certificates(self):
+ """
+ Fetch all EE certificate objects that link to this ca_detail.
+ """
+ return rpki.rpkid.ee_cert_obj.sql_fetch_where(self.gctx, "ca_detail_id = %s", (self.ca_detail_id,))
+
def unpublished_ghostbusters(self, when):
"""
Fetch all unpublished Ghostbusters objects linked to this
@@ -1227,8 +1235,12 @@ class ca_detail_obj(rpki.sql.sql_persistent):
self.crl_published = rpki.sundial.now()
self.sql_mark_dirty()
- publisher.publish(cls = rpki.publication.crl_elt, uri = self.crl_uri, obj = self.latest_crl, repository = parent.repository,
- handler = self.crl_published_callback)
+ publisher.publish(
+ cls = rpki.publication.crl_elt,
+ uri = self.crl_uri,
+ obj = self.latest_crl,
+ repository = parent.repository,
+ handler = self.crl_published_callback)
def crl_published_callback(self, pdu):
"""
@@ -1265,6 +1277,7 @@ class ca_detail_obj(rpki.sql.sql_persistent):
objs.extend((c.uri_tail, c.cert) for c in self.child_certs)
objs.extend((r.uri_tail, r.roa) for r in self.roas if r.roa is not None)
objs.extend((g.uri_tail, g.ghostbuster) for g in self.ghostbusters)
+ objs.extend((e.uri_tail, e.cert) for e in self.ee_certificates)
rpki.log.debug("Building manifest object %s" % uri)
self.latest_manifest = rpki.x509.SignedManifest.build(
@@ -2310,7 +2323,7 @@ class ee_cert_obj(rpki.sql.sql_persistent):
Generate a new certificate and stuff it in a new ee_cert_obj.
"""
- cn, sn = subject_name.get_cn_and_dn()
+ cn, sn = subject_name.extract_cn_and_sn()
ca = ca_detail.ca
cert = ca_detail.issue_ee(
@@ -2324,7 +2337,7 @@ class ee_cert_obj(rpki.sql.sql_persistent):
self = cls(
gctx = ca_detail.gctx,
- self_id = ca.self.self_id,
+ self_id = ca.parent.self.self_id,
ca_detail_id = ca_detail.ca_detail_id,
cert = cert)
diff --git a/rpkid/rpki/rpkid_tasks.py b/rpkid/rpki/rpkid_tasks.py
index 7554fb89..492876aa 100644
--- a/rpkid/rpki/rpkid_tasks.py
+++ b/rpkid/rpki/rpkid_tasks.py
@@ -601,22 +601,30 @@ class UpdateEECertificatesTask(AbstractTask):
existing[gski] = set()
existing[gski].add(ee)
+ ca_details = set()
+
for req in requests:
ees = existing.pop(req.gski, ())
- ca_details = self.find_covering_ca_details(resources)
+ resources = rpki.resource_set.resource_bag(
+ asn = req.asn,
+ v4 = req.ipv4,
+ v6 = req.ipv6,
+ valid_until = req.valid_until)
+ covering = self.find_covering_ca_details(resources)
+ ca_details.update(covering)
for ee in ees:
- if ee.ca_detail in ca_details:
+ if ee.ca_detail in covering:
rpki.log.debug("Updating existing EE certificate for %s %s" % (req.gski, resources))
ee.reissue(
resources = resources,
publisher = publisher)
- ca_details.remove(ee.ca_detail)
+ covering.remove(ee.ca_detail)
else:
rpki.log.debug("Existing EE certificate for %s %s is no longer covered" % (req.gski, resources))
ee.revoke(publisher = publisher)
- for ca_detail in ca_details:
+ for ca_detail in covering:
rpki.log.debug("No existing EE certificate for %s %s" % (req.gski, resources))
rpki.rpkid.ee_cert_obj.create(
ca_detail = ca_detail,
@@ -628,10 +636,17 @@ class UpdateEECertificatesTask(AbstractTask):
# Anything left is an orphan
for ees in existing.values():
for ee in ees:
+ ca_details.add(ee.ca_detail)
ee.revoke(publisher = publisher)
self.gctx.sql.sweep()
+ for ca_detail in ca_details:
+ ca_detail.generate_crl(publisher = publisher)
+ ca_detail.generate_manifest(publisher = publisher)
+
+ self.gctx.sql.sweep()
+
self.gctx.checkpoint()
publisher.call_pubd(self.exit, self.publication_failed)
diff --git a/rpkid/rpki/x509.py b/rpkid/rpki/x509.py
index 858278f2..15adf12b 100644
--- a/rpkid/rpki/x509.py
+++ b/rpkid/rpki/x509.py
@@ -1061,7 +1061,7 @@ class PKCS10(DER_object):
@classmethod
def create(cls, keypair, exts = None, is_ca = False,
caRepository = None, rpkiManifest = None, signedObject = None,
- cn = None, sn = None):
+ cn = None, sn = None, eku = None):
"""
Create a new request for a given keypair.
"""
@@ -1092,6 +1092,9 @@ class PKCS10(DER_object):
if caRepository or rpkiManifest or signedObject:
req.setSIA(caRepository, rpkiManifest, signedObject)
+ if eku:
+ req.setEKU(eku)
+
req.sign(keypair.get_POW(), rpki.POW.SHA256_DIGEST)
return cls(POW = req)
diff --git a/rpkid/tests/old_irdbd.sql b/rpkid/tests/old_irdbd.sql
index 0f349e2b..1e5b6d28 100644
--- a/rpkid/tests/old_irdbd.sql
+++ b/rpkid/tests/old_irdbd.sql
@@ -107,6 +107,7 @@ CREATE TABLE ghostbuster_request (
CREATE TABLE ee_certificate (
ee_certificate_id SERIAL NOT NULL,
self_handle VARCHAR(255) NOT NULL,
+ pkcs10 LONGBLOB NOT NULL,
gski VARCHAR(27) NOT NULL,
router_id INT UNSIGNED,
valid_until DATETIME NOT NULL,
diff --git a/rpkid/tests/smoketest.py b/rpkid/tests/smoketest.py
index 043acbde..7f284550 100644
--- a/rpkid/tests/smoketest.py
+++ b/rpkid/tests/smoketest.py
@@ -375,6 +375,38 @@ class roa_request(object):
def parse(cls, yaml):
return cls(yaml.get("asn"), yaml.get("ipv4"), yaml.get("ipv6"))
+class router_cert(object):
+ """
+ Representation for a router_cert object.
+ """
+
+ def __init__(self, asn, router_id):
+ self.asn = rpki.resource_set.resource_set_as("".join(str(asn).split()))
+ self.router_id = router_id
+
+ rpki.log.warn("Code to generate ECDSA keys not written yet, generating RSA as hack for testing")
+ self.keypair = rpki.x509.RSA.generate()
+ self.pkcs10 = rpki.x509.PKCS10.create(
+ keypair = self.keypair,
+ cn = "ROUTER-%d" % self.asn[0].min,
+ sn = self.router_id,
+ eku = (rpki.oids.id_kp_bgpsec_router,))
+ self.gski = self.pkcs10.gSKI()
+
+ def __eq__(self, other):
+ return self.asn == other.asn and self.router_id == other.router_id and self.gski == other.gski
+
+ def __hash__(self):
+ v6 = tuple(self.v6) if self.v6 is not None else None
+ return tuple(self.asn).__hash__() + router_id.__hash__() + self.gski.__hash__()
+
+ def __str__(self):
+ return "%s: %s: %s" % (self.asn, self.router_id, self.gski)
+
+ @classmethod
+ def parse(cls, yaml):
+ return cls(yaml.get("asn"), yaml.get("router_id"))
+
class allocation_db(list):
"""
Representation of all the entities and allocations in the test
@@ -485,6 +517,9 @@ class allocation(object):
self.base.v4 |= r.v4.to_resource_set()
if r.v6:
self.base.v6 |= r.v6.to_resource_set()
+ self.router_certs = [router_cert.parse(y) for y in yaml.get("router_cert", ())]
+ for r in self.router_certs:
+ self.base.asn |= r.asn
self.hosted_by = yaml.get("hosted_by")
self.extra_conf = yaml.get("extra_conf", [])
self.hosts = []
@@ -568,6 +603,20 @@ class allocation(object):
self.roa_requests.remove(r)
cb()
+ def apply_router_cert_add(self, yaml, cb):
+ for y in yaml:
+ r = router_cert.parse(y)
+ if r not in self.router_certs:
+ self.router_certs.append(r)
+ cb()
+
+ def apply_router_cert_del(self, yaml, cb):
+ for y in yaml:
+ r = router_cert.parse(y)
+ if r in self.router_certs:
+ self.router_certs.remove(r)
+ cb()
+
def apply_rekey(self, target, cb):
def done(e):
@@ -728,6 +777,10 @@ class allocation(object):
cur.execute("DELETE FROM registrant_net")
cur.execute("DELETE FROM roa_request_prefix")
cur.execute("DELETE FROM roa_request")
+ cur.execute("DELETE FROM ee_certificate_asn")
+ cur.execute("DELETE FROM ee_certificate_net")
+ cur.execute("DELETE FROM ee_certificate")
+
for s in [self] + self.hosts:
for kid in s.kids:
cur.execute("SELECT registrant_id FROM registrant WHERE registrant_handle = %s AND registry_handle = %s",
@@ -750,9 +803,18 @@ class allocation(object):
roa_request_id = cur.lastrowid
for version, prefix_set in ((4, r.v4), (6, r.v6)):
if prefix_set:
- cur.executemany("INSERT roa_request_prefix (roa_request_id, prefix, prefixlen, max_prefixlen, version) "
+ cur.executemany("INSERT roa_request_prefix "
+ "(roa_request_id, prefix, prefixlen, max_prefixlen, version) "
"VALUES (%s, %s, %s, %s, %s)",
- ((roa_request_id, x.prefix, x.prefixlen, x.max_prefixlen, version) for x in prefix_set))
+ ((roa_request_id, x.prefix, x.prefixlen, x.max_prefixlen, version)
+ for x in prefix_set))
+ for r in s.router_certs:
+ cur.execute("INSERT ee_certificate (self_handle, pkcs10, gski, router_id, valid_until) "
+ "VALUES (%s, %s, %s, %s, %s)",
+ (s.name, r.pkcs10.get_DER(), r.gski, r.router_id, s.resources.valid_until))
+ ee_certificate_id = cur.lastrowid
+ cur.executemany("INSERT ee_certificate_asn (ee_certificate_id, start_as, end_as) VALUES (%s, %s, %s)",
+ ((ee_certificate_id, a.min, a.max) for a in r.asn))
db.close()
def run_daemons(self):