ssl.Purpose.SERVER_AUTH)
_server_ssl_defaults = ssl.create_default_context(
ssl.Purpose.CLIENT_AUTH)
+ if hasattr(ssl, 'OP_NO_COMPRESSION'):
+ # See netutil.ssl_options_to_context
+ _client_ssl_defaults.options |= ssl.OP_NO_COMPRESSION
+ _server_ssl_defaults.options |= ssl.OP_NO_COMPRESSION
else:
# Google App Engine
_client_ssl_defaults = dict(cert_reqs=None,
return ssl_options
assert isinstance(ssl_options, dict)
assert all(k in _SSL_CONTEXT_KEYWORDS for k in ssl_options), ssl_options
+ # Can't use create_default_context since this interface doesn't
+ # tell us client vs server.
context = ssl.SSLContext(
ssl_options.get('ssl_version', ssl.PROTOCOL_SSLv23))
if 'certfile' in ssl_options:
context.set_ciphers(ssl_options['ciphers'])
if hasattr(ssl, 'OP_NO_COMPRESSION'):
# Disable TLS compression to avoid CRIME and related attacks.
- # This constant wasn't added until python 3.3.
+ # This constant depends on openssl version 1.0.
+ # TODO: Do we need to do this ourselves or can we trust
+ # the defaults?
context.options |= ssl.OP_NO_COMPRESSION
return context
self.request.client_cert is None and
self.request.client_key is None):
return _client_ssl_defaults
- ssl_options = {}
- if self.request.validate_cert:
- ssl_options["cert_reqs"] = ssl.CERT_REQUIRED
- if self.request.ca_certs is not None:
- ssl_options["ca_certs"] = self.request.ca_certs
- if self.request.client_key is not None:
- ssl_options["keyfile"] = self.request.client_key
+ ssl_ctx = ssl.create_default_context(
+ ssl.Purpose.SERVER_AUTH,
+ cafile=self.request.ca_certs)
+ if not self.request.validate_cert:
+ ssl_ctx.check_hostname = False
+ ssl_ctx.verify_mode = ssl.CERT_NONE
if self.request.client_cert is not None:
- ssl_options["certfile"] = self.request.client_cert
-
- # SSL interoperability is tricky. We want to disable
- # SSLv2 for security reasons; it wasn't disabled by default
- # until openssl 1.0. The best way to do this is to use
- # the SSL_OP_NO_SSLv2, but that wasn't exposed to python
- # until 3.2. Python 2.7 adds the ciphers argument, which
- # can also be used to disable SSLv2. As a last resort
- # on python 2.6, we set ssl_version to TLSv1. This is
- # more narrow than we'd like since it also breaks
- # compatibility with servers configured for SSLv3 only,
- # but nearly all servers support both SSLv3 and TLSv1:
- # http://blog.ivanristic.com/2011/09/ssl-survey-protocol-support.html
- if sys.version_info >= (2, 7):
- # In addition to disabling SSLv2, we also exclude certain
- # classes of insecure ciphers.
- ssl_options["ciphers"] = "DEFAULT:!SSLv2:!EXPORT:!DES"
- else:
- # This is really only necessary for pre-1.0 versions
- # of openssl, but python 2.6 doesn't expose version
- # information.
- ssl_options["ssl_version"] = ssl.PROTOCOL_TLSv1
- return ssl_options
+ ssl_ctx.load_cert_chain(self.request.client_cert,
+ self.request.client_key)
+ if hasattr(ssl, 'OP_NO_COMPRESSION'):
+ # See netutil.ssl_options_to_context
+ ssl_ctx.options |= ssl.OP_NO_COMPRESSION
+ return ssl_ctx
return None
def _on_timeout(self, info=None):