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

Adds TLS-PSK support to Python SSL context #14396

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

aminop1us
Copy link

This pull request adds support to the ssl module for TLS-PSK (pre-shared key) authentication. This implementation is code compatible with CPython 3.13 for both client and server side, for example as described here:
https://docs.python.org/3.13/library/ssl.html#ssl.SSLContext.set_psk_server_callback
https://docs.python.org/3.13/library/ssl.html#ssl.SSLContext.set_psk_client_callback

The strong motivation for adding this functionality to MicroPython is that typical TSL using PKI on microcontrollers is heavy and resource intensive. For the kinds of platforms that MicroPython is targeting, many developers will prefer the lighter and simpler PSK alternative, particularly for development and testing. In fact this is exactly the target that TLS-PSK was designed for, so MicroPython would benefit greatly from this support being built-in to the ssl module. Since CPython 3.13 added this as a standard, we tried to be as compliant as possible. We are currently using these TLS-PSK capabilities in several in-house projects, and wanted to share it back in the hope that others might benefit from this, too.

Note: due to the underlying MBEDTLS library not supporting client side callbacks for TLS-PSK, we kept the client-side callback API compatible with CPython, but call the callback immediately and pass the returned identity and key to MBEDTLS when it creates the TLS connection. We tried to keep to CPython compatibility as much as possible for interoperability. We have tested with simple server and client code that runs on both our MicroPython branch as well as CPython 3.13.0a3.

We have tried to follow the MicroPython standard coding conventions, but if there are any requests for changes before it can be merged, please let us know and we will do our best to assist in any changes required.

In summary, this implementation allows the application to set a TLS PSK callback function on SSLContext for server-side connections, so the callback function is called for each handshake. Here is the documentation from the set_psk_server_callback link above:
"The parameter callback is a callable object with the signature: def callback(identity: str | None) -> bytes. The identity parameter is an optional identity sent by the client which can be used to select a corresponding PSK. The return value is a bytes-like object representing the pre-shared key. Return a zero length PSK to reject the connection."

moprg added 4 commits April 30, 2024 10:30
Signed-off-by: moprg <moprg@yannix.com>
Signed-off-by: moprg <moprg@yannix.com>
Signed-off-by: moprg <moprg@yannix.com>
Signed-off-by: moprg <moprg@yannix.com>
@aminop1us aminop1us marked this pull request as ready for review April 30, 2024 04:00
Copy link

codecov bot commented Apr 30, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.39%. Comparing base (cfd5a8e) to head (93340fa).

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #14396   +/-   ##
=======================================
  Coverage   98.39%   98.39%           
=======================================
  Files         161      161           
  Lines       21204    21229   +25     
=======================================
+ Hits        20864    20889   +25     
  Misses        340      340           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

Code size report:

   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64: +2968 +0.358% standard[incl +192(data)]
      stm32:    +0 +0.000% PYBV10
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS

@Carglglz
Copy link
Contributor

@aminop1us since this would be a new feature, could you add a test (see tests/multi_net for examples) so the code coverage can pass, thanks 👍🏼

@aminop1us
Copy link
Author

@aminop1us since this would be a new feature, could you add a test (see tests/multi_net for examples) so the code coverage can pass, thanks 👍🏼

thank for your suggestion, I will add a new test case.

Signed-off-by: moprg <moprg@yannix.com>
@aminop1us
Copy link
Author

@aminop1us since this would be a new feature, could you add a test (see tests/multi_net for examples) so the code coverage can pass, thanks 👍🏼

I added the test and updated the pull request

@aminop1us
Copy link
Author

please let me know if there is anything else I can do

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants