Esempio n. 1
0
    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")
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
0
 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)
Esempio n. 6
0
    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()