Search code examples
python-3.xsslcertificatetornado

Unable to connect to the Tornado SSL based server from Tornado Client


I am new to the ssl and stuff, I have generated the self signed certificates using openssl.

openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 3650 -out certificate.pem

Where Server has the following Code.

if __name__ == "__main__":
    context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
    context.load_cert_chain("/home/rootkit/ssl/certificate.pem",
                            "/home/rootkit/ssl/key.pem")

    http_server = tornado.httpserver.HTTPServer(Application(), ssl_options=context)
    #
    # http_server = tornado.httpserver.HTTPServer(Application(), ssl_options={
    #     'certfile': '/home/rootkit/ssl/certificate.pem',
    #     'keyfile': '/home/rootkit/ssl/key.pem',
    # })
    http_server.listen(8888)
    tornado.ioloop.IOLoop.current().start()

When I access the url from chrome it just give the exception because it is not signed by any authority so I proceed it as unsafe.

But if I see the traffic via wireshark it shows the encrypted traffic.

But when I tried to connect with the Tornado Client it throws the following error.

    WARNING:tornado.general:SSL Error on 6 ('127.0.0.1', 8888): [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)
    ERROR:tornado.application:Exception in callback functools.partial(<function wrap.<locals>.null_wrapper at 0xb72e514c>, <Task finished coro=<check_status() done, defined at /home/rootkit/PycharmProjects/websocketserver/file_upload/websocketclient.py:82> exception=SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)')>)
    Traceback (most recent call last):
      File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/ioloop.py", line 758, in _run_callback
        ret = callback()
      File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/stack_context.py", line 300, in null_wrapper
        return fn(*args, **kwargs)
      File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/ioloop.py", line 779, in _discard_future_result
        future.result()
      File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
        raise self._exception
      File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
        result = coro.throw(exc)
      File "/home/rootkit/PycharmProjects/websocketserver/file_upload/websocketclient.py", line 89, in check_status
        param = await client.fetch(request)
      File "/usr/lib/python3.5/asyncio/futures.py", line 361, in __iter__
        yield self  # This tells Task to wait for completion.
      File "/usr/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
        future.result()
      File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
        raise self._exception
      File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/simple_httpclient.py", line 272, in run
        max_buffer_size=self.max_buffer_size)
      File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/gen.py", line 1133, in run
        value = future.result()
      File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
        raise self._exception
      File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/gen.py", line 1141, in run
        yielded = self.gen.throw(*exc_info)
      File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/tcpclient.py", line 242, in connect
        server_hostname=host)
      File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/gen.py", line 1133, in run
        value = future.result()
      File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
        raise self._exception
      File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/iostream.py", line 1501, in _do_ssl_handshake
        self.socket.do_handshake()
      File "/usr/lib/python3.5/ssl.py", line 988, in do_handshake
        self._sslobj.do_handshake()
      File "/usr/lib/python3.5/ssl.py", line 633, in do_handshake
        self._sslobj.do_handshake()
    ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)

Here is the Client code.

async def check_status():
    url = "https://127.0.0.1:8888/"
    request = httpclient.HTTPRequest(url=url,
                                        method="GET",
                                        client_key="/home/rootkit/client.key",
                                        client_cert="/home/rootkit/ssl/client.pem")
    client = httpclient.AsyncHTTPClient()
    param = await client.fetch(request)
    print(param)

I have generated the client certificates using the came command I used for the server.

What could be the possible issue. What I am missing ?


Solution

  • I got the answer from the github repo that is,

    The "client" certificate is a totally different thing: a way for the server to authenticate the client, so called "mutual authentication". It does nothing in this case because the server is not set up to check the client's certificate. It does not cause the client to skip validation of the server's certificate. To do that like you do for chrome, use validate_cert=False.

    (standard disclaimer that you need to make sure that you don't accidentally leave validate_cert=False in when this code makes it into some real-world product or service)

    So I just need to remove the client side validation of the certificate.

    For "real production use" you probably want to generate a real trusted server certificate for your real dns domain, for example with "Let's Encrypt".

    validate_cert=False will encrypt the traffic but not validate the certificate ?

    So I changed my client to

    async def check_status():
    url = "https://127.0.0.1:8888/"
    request = httpclient.HTTPRequest(url=url,
                                        method="GET",
                                        validate_cert=False)
    client = httpclient.AsyncHTTPClient()
    param = await client.fetch(request)
    print(param.body)