def test_alpn_error(self): with pytest.raises(exceptions.TlsException, match="must be a function"): tls.create_client_context(alpn_select_callback="foo") with pytest.raises(exceptions.TlsException, match="ALPN error"): tls.create_client_context(alpn_select="foo", alpn_select_callback="bar")
def convert_to_ssl(self, sni=None, alpn_protos=None, **sslctx_kwargs): context = tls.create_client_context( alpn_protos=alpn_protos, sni=sni, **sslctx_kwargs ) self.connection = SSL.Connection(context, self.connection) if sni: self.sni = sni self.connection.set_tlsext_host_name(sni.encode("idna")) self.connection.set_connect_state() try: self.connection.do_handshake() except SSL.Error as v: if self.ssl_verification_error: raise self.ssl_verification_error else: raise exceptions.TlsException("SSL handshake error: %s" % repr(v)) self.cert = certs.SSLCert(self.connection.get_peer_certificate()) # Keep all server certificates in a list for i in self.connection.get_peer_cert_chain(): self.server_certs.append(certs.SSLCert(i)) self.ssl_established = True self.rfile.set_descriptor(self.connection) self.wfile.set_descriptor(self.connection)
def convert_to_tls(self, sni=None, alpn_protos=None, **sslctx_kwargs): context = tls.create_client_context( alpn_protos=alpn_protos, sni=sni, **sslctx_kwargs ) self.connection = SSL.Connection(context, self.connection) if sni: self.sni = sni self.connection.set_tlsext_host_name(sni.encode("idna")) self.connection.set_connect_state() try: self.connection.do_handshake() except SSL.Error as v: if self.ssl_verification_error: raise self.ssl_verification_error else: raise exceptions.TlsException("SSL handshake error: %s" % repr(v)) self.cert = certs.Cert(self.connection.get_peer_certificate()) # Keep all server certificates in a list for i in self.connection.get_peer_cert_chain(): self.server_certs.append(certs.Cert(i)) self.tls_established = True self.rfile.set_descriptor(self.connection) self.wfile.set_descriptor(self.connection)
def convert_to_tls(self, sni=None, alpn_protos=None, **sslctx_kwargs): context = tls.create_client_context(alpn_protos=alpn_protos, sni=sni, **sslctx_kwargs) self.connection = SSL.Connection(context, self.connection) if sni: self.sni = sni self.connection.set_tlsext_host_name(sni.encode("idna")) self.connection.set_connect_state() try: idle_timeout = self.connection_idle_seconds if idle_timeout != -1: timeout = idle_timeout else: timeout = 60 if self.channel is not None: self.channel.ask("ssl_handshake_started", self) TimeoutHelper.wrap_with_timeout(self.connection.do_handshake, timeout) except SSL.Error as v: if self.ssl_verification_error: raise self.ssl_verification_error else: raise exceptions.TlsException("SSL handshake error: %s" % repr(v)) finally: if self.channel is not None: self.channel.ask("ssl_handshake_finished", self) self.cert = certs.Cert(self.connection.get_peer_certificate()) # Keep all server certificates in a list for i in self.connection.get_peer_cert_chain(): self.server_certs.append(certs.Cert(i)) self.tls_established = True self.rfile.set_descriptor(self.connection) self.wfile.set_descriptor(self.connection)
def test_invalid_ssl_method_should_fail(self): fake_ssl_method = 100500 with pytest.raises(exceptions.TlsException): tls.create_client_context(method=fake_ssl_method)
def create_proxy_server_ssl_conn(self, tls_start: tls.TlsStartData) -> None: client = tls_start.context.client server = cast(context.Server, tls_start.conn) assert server.address if server.sni is True: server.sni = client.sni or server.address[0].encode() if not server.alpn_offers: if client.alpn_offers: if ctx.options.http2: server.alpn_offers = tuple(client.alpn_offers) else: server.alpn_offers = tuple(x for x in client.alpn_offers if x != b"h2") elif client.tls_established: # We would perfectly support HTTP/1 -> HTTP/2, but we want to keep things on the same protocol version. # There are some edge cases where we want to mirror the regular server's behavior accurately, # for example header capitalization. server.alpn_offers = [] elif ctx.options.http2: server.alpn_offers = tls.HTTP_ALPNS else: server.alpn_offers = tls.HTTP1_ALPNS # We pass through the list of ciphers send by the client, because some HTTP/2 servers # will select a non-HTTP/2 compatible cipher from our default list and then hang up # because it's incompatible with h2. if not server.cipher_list: if ctx.options.ciphers_server: server.cipher_list = ctx.options.ciphers_server.split(":") elif client.cipher_list: # We used to filter for known ciphers here, but that doesn't seem to make sense. # According to OpenSSL docs, the control string str should be universally # usable and not depend on details of the library configuration (ciphers compiled in). server.cipher_list = list(client.cipher_list) args = net_tls.client_arguments_from_options(ctx.options) client_certs = args.pop("client_certs") client_cert: Optional[str] = None if client_certs: client_certs = os.path.expanduser(client_certs) if os.path.isfile(client_certs): client_cert = client_certs else: server_name: str = (server.sni or server.address[0].encode("idna")).decode() path = os.path.join(client_certs, f"{server_name}.pem") if os.path.exists(path): client_cert = path args["cipher_list"] = ':'.join( server.cipher_list) if server.cipher_list else None ssl_ctx = net_tls.create_client_context( cert=client_cert, sni=server.sni.decode("idna") if server.sni else None, # TODO: Should pass-through here. alpn_protos=server.alpn_offers, **args) tls_start.ssl_conn = SSL.Connection(ssl_ctx) tls_start.ssl_conn.set_tlsext_host_name(server.sni) tls_start.ssl_conn.set_connect_state()