Search code examples
pythonsslwebsocket

Websocket connection to remote server gives error "SSL alert number 40"


Please forgive me if this question seems long. I am in process of developing an IOT device which talk to a website over websockets. My IOT device supports TCP communication using sockets right now. Before moving to websockets in the IOT device, I thought of trying websockets on my raspberry pi 4. So I did a simple setup where I have a wesocket server running on render.com whose link I have in following format:

<wss://web-socket-xxx.onrender.com>

I used following python script on raspberry pi to connect to webserver:

import websockets
import asyncio

async def ws_client():
    print("WebSocket: Client Connection Initiated.")
    url = "wss://web-socket-9wz7.onrender.com"
    # Connect to the server
    async with websockets.connect(url) as ws:
        print(ws.remote_address)
        print(ws.path)
        print("request headers")
        print(ws.request_headers)
        print("response headers")
        print(ws.response_headers)
        print(ws.subprotocol)
        name = input("Your Name (type 'exit' to quit): ")

        if name == 'exit':
            exit()

        age = input("Your Age: ")
        # Send values to the server
        await ws.send(f"{name}")
        await ws.send(f"{age}")

        # Stay alive forever, listen to incoming msgs
        while True:
            msg = await ws.recv()
            print(msg)

# Start the connection
asyncio.run(ws_client())

Above script works perfectly fine. Websocket communication happens without any problem.

Since I cant used Python code on my IOT device I started looking into any opensource C implementations of websocket which I could compile on raspberry pi. I chose following github repo for this purpose

https://github.com/jeremyhahn/cwebsocket

I compiled websocket client based on above repo on raspberry pi and tried connecting to the websocket server. I faced following error:

cwebsocket: starting cwebsocket client
cwebsocket: cwebsocket_client_init: stack limit min=8388608, max=-1
cwebsocket: cwebsocket_client_connect: hostname=web-socket-xxxx.onrender.com, port=443, resource=/, querystring=, secure=1
cwebsocket: cwebsocket_client_connect: using secure (SSL) connection
4159651904:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../ssl/record/rec_layer_s3.c:1562:SSL alert number 40
cwebsocket: exiting cwebsocket

I checked the same websocket client with a local websocket server and it works fine, but every time I try to connect to remote websocket server on render.com I face the same error. Could anyone please point me what is going wrong with remote websocket server?


Solution

  • From a short look at the implementation it looks like that there is no support for SNI - but the server requires SNI. That's likely the cause of the problem you see, i.e. server returning a handshake error alert.

    A possible fix would be to add SSL_set_tlsext_host_name before calling SSL_connect in the code.

    But I would recommend to better not use the library at all. It is unchanged since 7 years and looks abandoned - even though it states "cwebsocket is currently in a development state.". More serious, it does not seem to have implemented any kind of certificate validation. This should be considered a critical and obvious security issue, which kind of indicates to me that whoever wrote this code had (at time of writing this code) no proper understanding of code security. More problems than such obvious ones are thus likely.