ESP32 Micro Python SSL Сервер WebSocket не работает - PullRequest
0 голосов
/ 19 января 2020

Я пытаюсь настроить сервер защищенных сокетов на esp32 с микро python. Я использовал / попробовал последний bulid (esp32-idf3-20200117-v1.12-68-g3032ae115.bin) с самозаверяющим сертификатом.

Я видел много проблем, связанных с утечкой памяти, с ssl.wrap_socket () на esp32 / esp8266, но то, что я получил, отличается:

mbedtls_ssl_handshake error: -4310
Traceback (most recent call last):
  File "boot.py", line 100, in <module>
OSError: [Errno 5] EIO

, и, конечно, соединение не устанавливается. Я пытаюсь подключиться с моего ноутбука. Точно такой же код на стороне клиента работает, если я запускаю сервер защищенных сокетов на самом ноутбуке (127.0.0.1), поэтому я предполагаю, что на стороне клиента все в порядке и проблема на стороне сервера.

Я мог бы пока не нашли решения этой проблемы. Я пробовал сертификат и ключ в формате 'der' и 'pem', результат один и тот же.

Код игрушечного сервера, который я пробовал:

import esp
esp.osdebug(None)

import gc
gc.collect()

import usocket as socket
import ssl
import machine
import network

KEY_PATH = 'server_key.der'
CERT_PATH = 'server_cert.der'

ssid= "AP_local"
pw="passwd"
ap = network.WLAN(network.AP_IF)  # create access-point interface
ap.config(essid=ssid, password=pw, authmode=4)  # set the ESSID of the access point
ap.ifconfig(('192.168.3.1', '255.25.255.0', '192.168.3.1', '8.8.8.8'))
ap.active(True)


with open(KEY_PATH, 'rb') as f:
    key = f.read()
print(key)
print(" ")
with open(CERT_PATH, 'rb') as f:
    cert = f.read()


#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET,  socket.SO_REUSEADDR, 1)
ad = ap.ifconfig()
addr = socket.getaddrinfo(ad[0], 8443)[0][-1]
s.bind(addr)
s.listen(5)

import gc
gc.collect()


while True:
    print("ssl connection started")
    cl, addr = s.accept()
    scl = ssl.wrap_socket(cl, server_side=True, 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()

Надеюсь, кто-нибудь может мне помочь, спасибо!

1 Ответ

0 голосов
/ 20 января 2020

ОК, потратив несколько дней на поиск, чтение и тестирование, я нашел решение и возможную причину этой проблемы. Надеюсь, это немного поможет другим. Я хочу подчеркнуть, что я не копался в исходном коде mbedtls, поэтому рассуждения несколько феноменологичны.

Сначала я попытался подключиться из программы python с настройками по умолчанию, которые завершились неудачно, как показано выше. , Затем я попытался с openssl cli, что также не удалось. Я попытался с примером, приведенным на https://github.com/micropython/micropython/blob/master/examples/network/http_server_ssl.py и снова не удалось, но с другими кодами ошибок. Наконец я нашел очень полезную страницу: https://tls.mbed.org/api/ssl_8h.html#a55ed67b6e414f9b381ff536d9ea6b9c0, которая помогла понять, где возникает проблема. Теперь, в зависимости от требований, возникали разные ошибки: -7900, -7780, -7380, -7d00.

Оказалось, что, хотя в документации используемый костюм шифра автоматически согласовывается во время рукопожатия, но есть некоторая ошибка в Это или реализация некоторых из них в микро python отличается.

Я не проверял все доступные шифры на своем ноутбуке, но, например: шифр AES_256_GCM_SHA384 работает. Для меня этого сейчас достаточно.

...