ESP32 simple SSL web server

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
digitalblade
Posts: 2
Joined: Sat Apr 24, 2021 5:43 pm

ESP32 simple SSL web server

Post by digitalblade » Sat Apr 24, 2021 6:00 pm

Hi,

i'm try to implement a very very simple HTTPS server using SSL sockets. I read a pile of example, Documents and faq here and around the web.

My setup:
Esp32 WROOM WITHOUT SPIRAM
Firmware: esp32-20210418-v1.15.bin
Browser for connection testing: chrome 90.0.4430.85

Now after 3 days I still not able to solve this problem, the latest and most simple code that I use is:

Code: Select all

import esp
import gc
gc.collect()

import usocket as socket
import ussl
import machine
import network

KEY_PATH = 'client.key'
CERT_PATH = 'client.crt'

with open(KEY_PATH, 'rb') as f:
    key = f.read()

with open(CERT_PATH, 'rb') as f:
    cert = f.read()

s = socket.socket()
s.setsockopt(socket.SOL_SOCKET,  socket.SO_REUSEADDR, 1)
ap = network.WLAN(network.AP_IF)  # create access-point interface
ad = ap.ifconfig()
addr = socket.getaddrinfo('0.0.0.0', 443)[0][-1]
s.bind(addr)
s.listen(5)

gc.collect()


while True:
    print("ssl connection started")
    cl, addr = s.accept()
    scl = ussl.wrap_socket(cl, server_side=False, cert=cert, key=key)
    print(gc.mem_free())
    l = 0
    while True:
        req = scl.read(1024)
        print(req)
        if not req or b'\r\n' in req:
            break

    response = '\r\n'.join(['HTTP/1.1 200 OK',
                            'Content-Type: text/plain',
                            'OK',
                           'Connection: close', '\r\n'])
    scl.write(response.encode("utf-8"))
    scl.close()
the self signed key are created using below command:

Code: Select all

 openssl req -newkey rsa:2048 -nodes -keyout client.key -x509 -days 365 -out client.crt
I did a lot of test but I always receive an OSError: (-30592, 'MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE').
After some diggin around i found that the integer number must be translated to Hex to find the real MBEDTLS error, so I googled for 0x7780 and as far as I understand, seem an error on Certificate Handshaking.
So I tried to add the line

Code: Select all

scl.set_ciphers('AES_256_GCM_SHA384') 
after the wrap_socket, but this change the message to OSError: (-31104, 'MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO')

So, now I'm really stuck with this... my question is if exists a real working example of micro web server that can use ssl and not require external SPIRAM or to be flashed on the firmware itself (like MicroWebSrv2)

Thank you very much for any help!

digitalblade
Posts: 2
Joined: Sat Apr 24, 2021 5:43 pm

Re: ESP32 simple SSL web server

Post by digitalblade » Sun May 02, 2021 6:28 am

Hi,

sorry for bump... I just see that my question has been viewed more that 270 times and had 0 responses.

My fear is that I wrote something so stupid that don't deserve an answer or that my question is not enough clear or that has been already answered and so no one respond.

I just want to understand if my request is totally impossbile to achieve... or there is some way to do it... i don't need a full code ready... i just need to understand if is something that i did wrong on my side, so I can try to find a solution.

Thank you for any answer

cgglzpy
Posts: 47
Joined: Thu Jul 18, 2019 4:20 pm

Re: ESP32 simple SSL web server

Post by cgglzpy » Sun May 02, 2021 1:42 pm

Hi digitalblade,

I don't know if the HTTPS server is possible right now, what I know is that SSL works when the computer acts as a server, also WebREPL can be wrapped into SSL connection, so in theory HTTPS server should be possible although I'm not 100% sure. You can read this issue in Micropython repo https://github.com/micropython/micropython/issues/5543.

My advice is to try to get it working with Python on computer side first (as a client) instead of Web browser.

Another thing is self signed key and certs, the client must trust the certificate that the server is handling. So this means that the client must have the certificate before connecting to the server so at the moment of the handshake the client can verify that the server cert is the same and it can be trusted. In python you can set or indicate a path where to find trusted certs files.

For the web browser you need to add your self signed cert to the trust sources, see https://www.pico.net/kb/how-do-you-get- ... ertificate

Also using Wireshark to debug the handshake is quite useful since you can see step by step what is going on.

I don't think you can set ciphers in MicroPython SSL implementation yet. This is done by mbedtls automatically.

Code: Select all

scl.set_ciphers('AES_256_GCM_SHA384') 
This may be of help too:
https://github.com/Carglglz/upydev/blob ... _server.py

Post Reply