class ClientTLSOptionsFactory(object): """Factory for Twisted SSLClientConnectionCreators that are used to make connections to remote servers for federation. Uses one of two OpenSSL context objects for all connections, depending on whether we should do SSL certificate verification. get_options decides whether we should do SSL certificate verification and constructs an SSLClientConnectionCreator factory accordingly. """ def __init__(self, config): self._config = config # Check if we're using a custom list of a CA certificates trust_root = config.federation_ca_trust_root if trust_root is None: # Use CA root certs provided by OpenSSL trust_root = platformTrust() self._verify_ssl_context = CertificateOptions( trustRoot=trust_root).getContext() self._verify_ssl_context.set_info_callback(self._context_info_cb) self._no_verify_ssl_context = CertificateOptions().getContext() self._no_verify_ssl_context.set_info_callback(self._context_info_cb) def get_options(self, host): # Check if certificate verification has been enabled should_verify = self._config.federation_verify_certificates # Check if we've disabled certificate verification for this host if should_verify: for regex in self._config.federation_certificate_verification_whitelist: if regex.match(host): should_verify = False break ssl_context = (self._verify_ssl_context if should_verify else self._no_verify_ssl_context) return SSLClientConnectionCreator(host, ssl_context, should_verify) @staticmethod def _context_info_cb(ssl_connection, where, ret): """The 'information callback' for our openssl context object.""" # we assume that the app_data on the connection object has been set to # a TLSMemoryBIOProtocol object. (This is done by SSLClientConnectionCreator) tls_protocol = ssl_connection.get_app_data() try: # ... we further assume that SSLClientConnectionCreator has set the # '_synapse_tls_verifier' attribute to a ConnectionVerifier object. tls_protocol._synapse_tls_verifier.verify_context_info_cb( ssl_connection, where) except: # noqa: E722, taken from the twisted implementation logger.exception("Error during info_callback") f = Failure() tls_protocol.failVerification(f)
class RegularPolicyForHTTPS: """Factory for Twisted SSLClientConnectionCreators that are used to make connections to remote servers, for other than federation. Always uses the same OpenSSL context object, which uses the default OpenSSL CA trust root. """ def __init__(self): trust_root = platformTrust() self._ssl_context = CertificateOptions( trustRoot=trust_root).getContext() self._ssl_context.set_info_callback(_context_info_cb) def creatorForNetloc(self, hostname, port): return SSLClientConnectionCreator(hostname, self._ssl_context, True)