Skip to content

RFC: change ussl to implement SSLContext #8915

@dpgeorge

Description

@dpgeorge

Currently MicroPython supports SSL/TLS connections using ussl.wrap_socket(). CPython long ago replaced this function with ssl.SSLContext:

Since Python 3.2 and 2.7.9, it is recommended to use the SSLContext.wrap_socket() of an SSLContext instance to wrap sockets as SSLSocket objects.

And in CPython ssl.wrap_socket() is deprecated since CPython version 3.7.

I propose that MicroPython also switch to using SSLContext. The reasons to change are:

  1. To more closely match CPython (it's hard to get TLS correct and having things match CPython makes it easier to write tests to compare uPy and CPy).
  2. To support more sophisticated use of TLS connections (SSLContext provide more control/options).
  3. So that uasyncio can support TLS clients and servers (CPython asyncio requires passing in an SSLContext object to asyncio.start_server() and asyncio.open_connection()).
  4. To support server_hostname in a CPython-compatible way.

One other benefit of using SSLContext is that it can be used to preallocate the large TLS buffers (16K) needed for a wrapped socket, and the buffer can be reused over and over as long as only one wrapped socket is needed at a time. This will help to reduce memory fragmentation and guarantee that sockets can be wrapped without running out of memory.

The proposed ussl module would now look like this:

# constants
PROTOCOL_TLS_CLIENT
PROTOCOL_TLS_SERVER

class SSLSocket:
    # same as existing ssl socket object

class SSLContext:
    def __init__(self, protocol):
        # protocol is PROTOCOL_TLS_CLIENT or PROTOCOL_TLS_SERVER
    def load_cert_chain(self, certfile, keyfile):
        # load certificate/key from a file
    def wrap_socket(self, sock, *, server_side=False, do_handshake_on_connect=True, server_hostname=None):
        # wrap a socket and return an SSLSocket

def wrap_socket(...):
    # existing function for backwards compatibility

Things to discuss/decide:

  1. Should probably keep the existing ussl.wrap_socket() for backwards compatibility for a couple of releases. It could print a deprecation warning.
  2. load_cert_chain() takes filenames as arguments and loads the key/cert from a file. This is different to the existing key/cert args in ussl.wrap_socket() (which are not CPython compatible) that take a str/bytes object containing the key/cert data. The question is if we should add, as a MicroPython-extension, a way to pass in data directly like this, and if yes how that would be done. For example add keyword-only args like load_cert_chain(self, certfile, keyfile, *, keydata, certdata), or a new method like load_cert_chain_data(self, keydata, certdata).
  3. Whether to implement it in C or Python.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementFeature requests, new feature implementationsrfcRequest for Comment

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy