diff options
author | Rob Austein <sra@hactrn.net> | 2008-04-07 23:02:39 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2008-04-07 23:02:39 +0000 |
commit | 7cd197b5a208ba4dc9b2430f9e20e28f504e7892 (patch) | |
tree | 16fea9eed8b64ab1ac99e2e1a0393dba2d3722bd | |
parent | 14bd2769a9392101fd34b33ffa7d5d211511d97e (diff) |
Hideously inefficient first cut at dynamic TLS trust anchor handling.
With this enabled, client certificate validation finally works.
Efficiency issues deferred until new trust anchor model is in place,
since it will need to be rewritten at that point anyway.
svn path=/rpkid/rpki/gctx.py; revision=1628
-rw-r--r-- | rpkid/rpki/gctx.py | 33 | ||||
-rw-r--r-- | rpkid/rpki/https.py | 16 | ||||
-rwxr-xr-x | rpkid/rpkid.py | 17 | ||||
-rw-r--r-- | rpkid/testbed.py | 7 | ||||
-rw-r--r-- | rpkid/testpoke.py | 9 |
5 files changed, 63 insertions, 19 deletions
diff --git a/rpkid/rpki/gctx.py b/rpkid/rpki/gctx.py index b1ecdcd0..fd25b5ba 100644 --- a/rpkid/rpki/gctx.py +++ b/rpkid/rpki/gctx.py @@ -23,6 +23,9 @@ import traceback, os, time, getopt, sys, MySQLdb, lxml.etree import rpki.resource_set, rpki.up_down, rpki.left_right, rpki.x509, rpki.sql import rpki.https, rpki.config, rpki.cms, rpki.exceptions, rpki.relaxng, rpki.log +# This should be wrapped somewhere in rpki.x509 eventually +import POW + class global_context(object): """A container for various global parameters.""" @@ -159,3 +162,33 @@ class global_context(object): s.regenerate_crls_and_manifests() self.sql_sweep() return 200, "OK" + + def build_x509store(self): + """Build a dynamic x509store object. This is horribly + inefficient, so will require some kind of caching scheme + eventually, but the task at hand is just to confirm that this + method will work at all. + """ + + store = POW.X509Store() + + def add_anchors(x, y = None): + if x is not None: + rpki.log.debug("HTTPS dynamic trust anchor %s" % x.getSubject()) + store.addTrust(x.get_POW()) + if y is not None and y != x: + rpki.log.debug("HTTPS dynamic trust anchor %s" % y.getSubject()) + store.addTrust(y.get_POW()) + + for parent in rpki.left_right.parent_elt.sql_fetch_all(self): + add_anchors(parent.cms_ta, parent.https_ta) + + for child in rpki.left_right.child_elt.sql_fetch_all(self): + add_anchors(child.cms_ta) + + for repository in rpki.left_right.repository_elt.sql_fetch_all(self): + add_anchors(repository.cms_ta, repository.https_ta) + + add_anchors(self.https_ta_irbe[0]) + + return store diff --git a/rpkid/rpki/https.py b/rpkid/rpki/https.py index 9659fe73..7fd0c5f2 100644 --- a/rpkid/rpki/https.py +++ b/rpkid/rpki/https.py @@ -24,11 +24,11 @@ general version should use SQL anyway. import httplib, BaseHTTPServer, tlslite.api, glob, traceback, urlparse, socket import rpki.x509, rpki.exceptions, rpki.log -# This probably should be wrapped somewhere in rpki.x509 eventually +# This should be wrapped somewhere in rpki.x509 eventually import POW -# Not for production use! -disable_tls_certificate_validation_exceptions = True +# Do not set this to True for production use! +disable_tls_certificate_validation_exceptions = False rpki_content_type = "application/x-rpki" @@ -45,6 +45,8 @@ class Checker(tlslite.api.Checker): for x in trust_anchors: rpki.log.debug("HTTPS trust anchor %s" % x.getSubject()) self.x509store.addTrust(x.get_POW()) + else: + rpki.log.debug("HTTPS dynamic trust anchors") def x509store_thunk(self): if self.dynamic_x509store is not None: @@ -105,6 +107,9 @@ def client(msg, client_key, client_certs, server_ta, url, timeout = 300): u.query == "" and \ u.fragment == "" + for client_cert in client_certs: + rpki.log.debug("Sending client TLS cert %s" % client_cert.getSubject()) + # We could add a "settings = foo" argument to the following call to # pass in a tlslite.HandshakeSettings object that would let us # insist on, eg, particular SSL/TLS versions. @@ -177,6 +182,7 @@ class httpsServer(tlslite.api.TLSSocketServerMixIn, BaseHTTPServer.HTTPServer): assert self.rpki_server_certs is not None assert self.rpki_server_key is not None assert self.rpki_sessionCache is not None + try: # # We could add a "settings = foo" argument to the following call @@ -194,7 +200,7 @@ class httpsServer(tlslite.api.TLSSocketServerMixIn, BaseHTTPServer.HTTPServer): rpki.log.warn("TLS handshake failure: " + str(error)) return False -def server(handlers, server_key, server_certs, port = 4433, host = "", client_ta = None): +def server(handlers, server_key, server_certs, port = 4433, host = "", client_ta = None, dynamic_x509store = None): """Run an HTTPS server and wait (forever) for connections.""" if not isinstance(handlers, (tuple, list)): @@ -208,6 +214,6 @@ def server(handlers, server_key, server_certs, port = 4433, host = "", client_ta httpd.rpki_server_key = server_key.get_tlslite() httpd.rpki_server_certs = server_certs.tlslite_certChain() httpd.rpki_sessionCache = tlslite.api.SessionCache() - httpd.rpki_checker = Checker(trust_anchors = client_ta) + httpd.rpki_checker = Checker(trust_anchors = client_ta, dynamic_x509store = dynamic_x509store) httpd.serve_forever() diff --git a/rpkid/rpkid.py b/rpkid/rpkid.py index e6fbb370..7ea22a46 100755 --- a/rpkid/rpkid.py +++ b/rpkid/rpkid.py @@ -52,11 +52,12 @@ if startup_msg: gctx = rpki.gctx.global_context(cfg) -rpki.https.server(server_key = gctx.https_key, - server_certs = gctx.https_certs, - client_ta = gctx.https_ta_irbe, - host = gctx.https_server_host, - port = gctx.https_server_port, - handlers = (("/left-right", gctx.left_right_handler), - ("/up-down/", gctx.up_down_handler), - ("/cronjob", gctx.cronjob_handler))) +rpki.https.server(host = gctx.https_server_host, + port = gctx.https_server_port, + server_key = gctx.https_key, + server_certs = gctx.https_certs, + client_ta = gctx.https_ta_irbe, + dynamic_x509store = gctx.build_x509store, + handlers = (("/left-right", gctx.left_right_handler), + ("/up-down/", gctx.up_down_handler), + ("/cronjob", gctx.cronjob_handler))) diff --git a/rpkid/testbed.py b/rpkid/testbed.py index daa73f50..a6843a08 100644 --- a/rpkid/testbed.py +++ b/rpkid/testbed.py @@ -409,7 +409,7 @@ class allocation(object): def apply_revoke(self, target): if self.is_leaf(): rpki.log.info("Attempting to revoke YAML leaf %s" % self.name) - subprocess.check_call((prog_python, prog_poke, "-y", self.name + ".yaml", "-r", "revoke")) + subprocess.check_call((prog_python, prog_poke, "-y", self.name + ".yaml", "-r", "revoke", "-d")) elif target is None: rpki.log.info("Revoking <self/> %s" % self.name) self.call_rpkid(rpki.left_right.self_elt.make_pdu(action = "set", self_id = self.self_id, revoke = "yes")) @@ -634,8 +634,8 @@ class allocation(object): def run_yaml(self): """Run YAML scripts for this leaf entity.""" rpki.log.info("Running YAML for %s" % self.name) - subprocess.check_call((prog_python, prog_poke, "-y", self.name + ".yaml", "-r", "list")) - subprocess.check_call((prog_python, prog_poke, "-y", self.name + ".yaml", "-r", "issue")) + subprocess.check_call((prog_python, prog_poke, "-y", self.name + ".yaml", "-r", "list", "-d")) + subprocess.check_call((prog_python, prog_poke, "-y", self.name + ".yaml", "-r", "issue", "-d")) def setup_biz_cert_chain(name): """Build a set of business certs.""" @@ -764,6 +764,7 @@ cms-cert-chain-file: [ %(my_name)s-RPKI-CA.cer ] ssl-cert-file: %(my_name)s-RPKI-EE.cer ssl-key-file: %(my_name)s-RPKI-EE.key ssl-ca-cert-file: %(parent_name)s-RPKI-TA.cer +ssl-cert-chain-file: [ %(my_name)s-RPKI-CA.cer ] requests: list: diff --git a/rpkid/testpoke.py b/rpkid/testpoke.py index 185c99ea..d964b72c 100644 --- a/rpkid/testpoke.py +++ b/rpkid/testpoke.py @@ -21,6 +21,7 @@ Configuration file is YAML to be compatable with APNIC rpki_poke.pl tool. Usage: python testpoke.py [ { -y | --yaml } configfile ] [ { -r | --request } requestname ] + [ { -d | --debug } ] [ { -h | --help } ] Default configuration file is testpoke.yaml, override with --yaml option. @@ -29,7 +30,7 @@ Default configuration file is testpoke.yaml, override with --yaml option. import os, time, getopt, sys, lxml, yaml import rpki.resource_set, rpki.up_down, rpki.left_right, rpki.x509 import rpki.https, rpki.config, rpki.cms, rpki.exceptions -import rpki.relaxng, rpki.oids +import rpki.relaxng, rpki.oids, rpki.log os.environ["TZ"] = "UTC" time.tzset() @@ -41,7 +42,7 @@ def usage(code): yaml_file = "testpoke.yaml" yaml_cmd = None -opts,argv = getopt.getopt(sys.argv[1:], "y:r:h?", ["yaml=", "request=", "help"]) +opts,argv = getopt.getopt(sys.argv[1:], "y:r:h?d", ["yaml=", "request=", "help", "debug"]) for o,a in opts: if o in ("-h", "--help", "-?"): usage(0) @@ -49,6 +50,8 @@ for o,a in opts: yaml_file = a elif o in ("-r", "--request"): yaml_cmd = a + elif o in ("-d", "--debug"): + rpki.log.init("testpoke") if argv: usage(1) @@ -125,7 +128,7 @@ cms_cert = get_PEM("cms-cert", rpki.x509.X509) cms_key = get_PEM("cms-key", rpki.x509.RSA) cms_certs = get_PEM_chain("cms-cert-chain", cms_cert) -https_ta = get_PEM("ssl-ta", rpki.x509.X509) +https_ta = get_PEM("ssl-ca-cert", rpki.x509.X509) https_key = get_PEM("ssl-key", rpki.x509.RSA) https_cert = get_PEM("ssl-cert", rpki.x509.X509) https_certs = get_PEM_chain("ssl-cert-chain", https_cert) |