aboutsummaryrefslogtreecommitdiff
path: root/rpkid
diff options
context:
space:
mode:
Diffstat (limited to 'rpkid')
-rw-r--r--rpkid/rpki/exceptions.py3
-rw-r--r--rpkid/rpki/https.py60
2 files changed, 35 insertions, 28 deletions
diff --git a/rpkid/rpki/exceptions.py b/rpkid/rpki/exceptions.py
index 5093d2a4..b514129b 100644
--- a/rpkid/rpki/exceptions.py
+++ b/rpkid/rpki/exceptions.py
@@ -87,3 +87,6 @@ class NotFound(Exception):
class MustBePrefix(Exception):
"""Resource range cannot be expressed as a prefix."""
+
+class TLSValidationError(Exception):
+ """TLS certificate validation error."""
diff --git a/rpkid/rpki/https.py b/rpkid/rpki/https.py
index d57c6db8..c3b96f5e 100644
--- a/rpkid/rpki/https.py
+++ b/rpkid/rpki/https.py
@@ -24,36 +24,46 @@ 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
+import POW
+
+# Not for production use!
+disable_tls_certificate_validation_exceptions = True
+
rpki_content_type = "application/x-rpki"
class Checker(tlslite.api.Checker):
"""Derived class to handle X.509 client certificate checking."""
- x509TrustList = None
-
def __init__(self, x509TrustList = None):
- """Initialize our modified checker."""
+ """Initialize our modified certificate checker."""
- if False:
- self.x509TrustList = x509TrustList
- else:
- rpki.log.debug("Ignoring HTTPS trust anchors %s, validation disabled" % repr(x509TrustList))
+ self.x509store = POW.X509Store()
+ if x509TrustList is not None:
+ for x in x509TrustList:
+ rpki.log.debug("HTTPS trust anchor %s" % x.getSubject())
+ self.x509store.addTrust(x.get_POW())
def __call__(self, tlsConnection):
- """Wrap some logging code around standard tlslite.Checker class.
+ """POW/OpenSSL-based certificate checker."""
- This is probably also the place where we need to figure out which
- trust anchor to use, since this is the first point at which we
- have access to the certificate chain provided by the client.
- """
+ if tlsConnection._client:
+ chain = tlsConnection.session.serverCertChain
+ peer = "server"
+ else:
+ chain = tlsConnection.session.clientCertChain
+ peer = "client"
- for i in range(tlsConnection.session.clientCertChain.getNumCerts()):
- x = rpki.x509.X509(tlslite = tlsConnection.session.clientCertChain.x509List[i])
- rpki.log.debug("Received cert[%d] %s" % (i, x.getSubject()))
+ chain = [rpki.x509.X509(tlslite = chain.x509List[i]) for i in range(chain.getNumCerts())]
- # Disabling this removes the need for cryptlib_py
- if self.x509TrustList is not None:
- tlslite.api.Checker.__call__(self, tlsConnection)
+ for i in range(len(chain)):
+ rpki.log.debug("Received cert[%d] %s from %s" % (i, chain[i].getSubject(), peer))
+
+ if not self.x509store.verifyChain(chain[0].get_POW(), [x.get_POW() for x in chain[1:]]):
+ if disable_tls_certificate_validation_exceptions:
+ rpki.log.warn("DANGER WILL ROBINSON! IGNORING TLS VALIDATION FAILURE!")
+ else:
+ raise rpki.exceptions.TLSValidationError
class httpsClient(tlslite.api.HTTPTLSConnection):
"""Derived class to let us replace the default Checker."""
@@ -95,7 +105,7 @@ def client(msg, privateKey, certChain, x509TrustList, url, timeout = 300):
port = u.port or 443,
privateKey = privateKey.get_tlslite(),
certChain = certChain.tlslite_certChain(),
- x509TrustList = x509TrustList.tlslite_trustList())
+ x509TrustList = x509TrustList)
httpc.connect()
httpc.sock.settimeout(timeout)
httpc.request("POST", u.path, msg, {"Content-Type" : rpki_content_type})
@@ -169,10 +179,10 @@ class httpsServer(tlslite.api.TLSSocketServerMixIn, BaseHTTPServer.HTTPServer):
privateKey = self.rpki_privateKey,
sessionCache = self.rpki_sessionCache,
checker = self.rpki_checker,
- reqCert = self.rpki_checker is not None)
+ reqCert = True)
tlsConnection.ignoreAbruptClose = True
return True
- except tlslite.api.TLSError, error:
+ except (tlslite.api.TLSError, rpki.exceptions.TLSValidationError), error:
rpki.log.warn("TLS handshake failure: " + str(error))
return False
@@ -190,12 +200,6 @@ def server(handlers, privateKey, certChain, port = 4433, host = "", x509TrustLis
httpd.rpki_privateKey = privateKey.get_tlslite()
httpd.rpki_certChain = certChain.tlslite_certChain()
httpd.rpki_sessionCache = tlslite.api.SessionCache()
-
- if x509TrustList is not None:
- x509TrustList = x509TrustList.tlslite_trustList()
- for x in x509TrustList:
- rpki.log.debug("HTTPS trust anchor %s" % rpki.x509.X509(tlslite = x).getSubject())
-
- httpd.rpki_checker = Checker(x509TrustList = x509TrustList)
+ httpd.rpki_checker = Checker(x509TrustList = x509TrustList)
httpd.serve_forever()