Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Native SSL Library #2202

Closed
brentru opened this issue Oct 7, 2019 · 9 comments
Closed

Add Native SSL Library #2202

brentru opened this issue Oct 7, 2019 · 9 comments

Comments

@brentru
Copy link
Member

brentru commented Oct 7, 2019

We're currently using the mbedTLS implementation of the TLS and SSL protocols on the ESP32 Co-Processor/AirLifts by communicating with an ESP32 running nina-fw from CircuitPython. While this solution is stable, a native CircuitPython SSL/TLS library would be faster, remove the hardware dependency for an ESP32 and allow for different transports (not just wifi).

Some embedded ssl/tls implementations:
BearSSL: https://bearssl.org
AxTLS: http://axtls.sourceforge.net

@dhalbert dhalbert added this to the Long term milestone Oct 31, 2019
@moto-timo
Copy link

Would be great to have a common TLS approach.

@tannewt
Copy link
Member

tannewt commented Feb 1, 2021

We could have the ssl module actually do SSL over the wrapped socket.

@timonsku
Copy link

This would be great to have so Wiznet and potentially other Ethernet MACs like in the i.MX RT can support SSL too. Are there any plans yet?

@askpatrickw
Copy link

There are MicroPython SSL implementations, could they be used as a starting point?

@tannewt
Copy link
Member

tannewt commented Jan 27, 2022

@timonsku No plans for Adafruit-funded folks.

@askpatrickw Yup! Definitely. Their code is usually well done and a good reference.

@nabber00
Copy link

Seems like WolfSSL Python should be pretty easy to add?

@dhalbert
Copy link
Collaborator

Seems like WolfSSL Python should be pretty easy to add?

The WolfSSL library is GPL2 and commercial. We don't put GPL code in CircuitPython so as not to GPL-ize the whole thing, and the commercial restrictions are also an issue.

@anecdata
Copy link
Member

I think the CircuitPython core elements are now in place for this, but it needs some changes in the ESP32SPI-related libraries (and possibly NINA) to make the ESP32 sockets compatible. There's a compatibility checklist in #8954. The native ssl module is only installed on certain boards though.

Tested config:

  • UnexpectedMaker FeatherS3 Adafruit CircuitPython 9.1.0-beta.2 on 2024-05-15; FeatherS3 with ESP32S3
  • Adafruit Airlift FeatherWing (NINA v1.7.1)
  • libraries are current release ...9.x-mpy-20240516

This code tries to simulate an HTTPS Request over ESP32SPI using a native-ssl-wrapped socket (the socket comes from NINA, the wrapper comes from the ESP32-S3):

import time
import os
import board
import digitalio
import socketpool
import ssl
import wifi
import adafruit_connection_manager
from adafruit_esp32spi import adafruit_esp32spi

HOST = "httpbin.org"
PATH = "/get"
PORT = 443

time.sleep(3)  # wait for serial

buf = bytearray(1024)

spi = board.SPI()
esp32_cs = digitalio.DigitalInOut(board.D13)
esp32_reset = digitalio.DigitalInOut(board.D12)
esp32_ready = digitalio.DigitalInOut(board.D11)
radio = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)

radio2 = wifi.radio

pool = adafruit_connection_manager.get_radio_socketpool(radio)  # ESP32SPI
ssl_context = adafruit_connection_manager.get_radio_ssl_context(radio2)  # native wifi

print(f'Connecting to wifi... ', end='')
radio.connect(os.getenv("WIFI_SSID"), os.getenv("WIFI_PASSWORD"))
print(f'{radio.ipv4_address}')

for _ in range(0, 10):
    print(f'{"-"*25}')
    print('Creating TCP client socket...')
    s = pool.socket(pool.AF_INET, pool.SOCK_STREAM)
    ss = ssl_context.wrap_socket(s, server_hostname=HOST)
    print('Connecting to remote socket...')
    ss.connect((HOST, PORT))

    sbytes = f'GET {PATH} HTTP/1.1\r\nHost: {HOST}:{PORT}\r\n\r\n'.encode()
    # note that esp32spi doesn't return the number of bytes sent like CPython:
    ssize = ss.send(sbytes)
    print(f'Sent {ssize} bytes: {sbytes}')

    rsize = ss.recv_into(buf)
    print(f'Received {rsize} bytes: {buf[:rsize]}')

    ss.close()
    time.sleep(1)
code.py output:
Connecting to wifi... 192.168.6.74
-------------------------
Creating TCP client socket...
Traceback (most recent call last):
  File "code.py", line 38, in <module>
AttributeError: 'Socket' object has no attribute 'type'

@jepler
Copy link
Member

jepler commented Jun 14, 2024

It's now possible to use the core ssl module with sockets implemented in Python (#8954); this actually works with wiznet. However, nobody's checked whether this actually works with airlift; it might require changes in the airlift socket implementation to correctly align with the standard socket. If it doesn't, the esp32spi github repo is probably the right place to open issues.

Additionally, few or no builds for board with an airlift include the core ssl module. If there are combos for which this is sensible, a PR within CircuitPython to enable SSL would be the way to go.

@jepler jepler closed this as completed Jun 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants