diff options
| author | Angus Gratton <angus@redyak.com.au> | 2025-06-05 15:32:38 +1000 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2025-07-23 15:47:16 +1000 |
| commit | 9b7d85227e67a7edd608aab4ff7eb4a838651f75 (patch) | |
| tree | 4a4681d5567f3782771c7c68367890b66fc56059 /docs/library/ssl.rst | |
| parent | 41e0ec96cb10580c8d77156ed51c2e34bc2fc0ac (diff) | |
extmod/mbedtls: Implement recommended DTLS features, make optional.
- DTLS spec recommends HelloVerify and Anti Replay protection be enabled,
and these are enabled in the default mbedTLS config. Implement them here.
- To help compensate for the possible increase in code size, add a
MICROPY_PY_SSL_DTLS build config macro that's enabled for EXTRA and
above by default.
This allows bare metal mbedTLS ports to use DTLS with HelloVerify support.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
Diffstat (limited to 'docs/library/ssl.rst')
| -rw-r--r-- | docs/library/ssl.rst | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/docs/library/ssl.rst b/docs/library/ssl.rst index 4327c74ba..c86101872 100644 --- a/docs/library/ssl.rst +++ b/docs/library/ssl.rst @@ -66,7 +66,7 @@ class SSLContext Set the available ciphers for sockets created with this context. *ciphers* should be a list of strings in the `IANA cipher suite format <https://wiki.mozilla.org/Security/Cipher_Suites>`_ . -.. method:: SSLContext.wrap_socket(sock, *, server_side=False, do_handshake_on_connect=True, server_hostname=None) +.. method:: SSLContext.wrap_socket(sock, *, server_side=False, do_handshake_on_connect=True, server_hostname=None, client_id=None) Takes a `stream` *sock* (usually socket.socket instance of ``SOCK_STREAM`` type), and returns an instance of ssl.SSLSocket, wrapping the underlying stream. @@ -89,6 +89,9 @@ class SSLContext server certificate. It also sets the name for Server Name Indication (SNI), allowing the server to present the proper certificate. + - *client_id* is a MicroPython-specific extension argument used only when implementing a DTLS + Server. See :ref:`dtls` for details. + .. warning:: Some implementations of ``ssl`` module do NOT validate server certificates, @@ -117,6 +120,8 @@ Exceptions This exception does NOT exist. Instead its base class, OSError, is used. +.. _dtls: + DTLS support ------------ @@ -125,16 +130,47 @@ DTLS support This is a MicroPython extension. -This module supports DTLS in client and server mode via the `PROTOCOL_DTLS_CLIENT` -and `PROTOCOL_DTLS_SERVER` constants that can be used as the ``protocol`` argument -of `SSLContext`. +On most ports, this module supports DTLS in client and server mode via the +`PROTOCOL_DTLS_CLIENT` and `PROTOCOL_DTLS_SERVER` constants that can be used as +the ``protocol`` argument of `SSLContext`. In this case the underlying socket is expected to behave as a datagram socket (i.e. like the socket opened with ``socket.socket`` with ``socket.AF_INET`` as ``af`` and ``socket.SOCK_DGRAM`` as ``type``). -DTLS is only supported on ports that use mbed TLS, and it is not enabled by default: -it requires enabling ``MBEDTLS_SSL_PROTO_DTLS`` in the specific port configuration. +DTLS is only supported on ports that use mbedTLS, and it is enabled by default +in most configurations but can be manually disabled by defining +``MICROPY_PY_SSL_DTLS`` to 0. + +DTLS server support +^^^^^^^^^^^^^^^^^^^ + +MicroPython's DTLS server support is configured with "Hello Verify" as required +for DTLS 1.2. This is transparent for DTLS clients, but there are relevant +considerations when implementing a DTLS server in MicroPython: + +- The server should pass an additional argument *client_id* when calling + `SSLContext.wrap_socket()`. This ID must be a `bytes` object (or similar) with + a transport-specific identifier representing the client. + + The simplest approach is to convert the tuple of ``(client_ip, client_port)`` + returned from ``socket.recv_from()`` into a byte string, i.e.:: + + _, client_addr = sock.recvfrom(1, socket.MSG_PEEK) + sock.connect(client_addr) # Connect back to the client + sock = ssl_ctx.wrap_socket(sock, server_side=True, + client_id=repr(client_addr).encode()) + +- The first time a client connects, the server call to ``wrap_socket`` will fail + with a `OSError` error "Hello Verify Required". This is because the DTLS + "Hello Verify" cookie is not yet known by the client. If the same client + connects a second time then ``wrap_socket`` will succeed. + +- DTLS cookies for "Hello Verify" are associated with the `SSLContext` object, + so the same `SSLContext` object should be used to wrap a subsequent connection + from the same client. The cookie implementation includes a timeout and has + constant memory use regardless of how many clients connect, so it's OK to + reuse the same `SSLContext` object for the lifetime of the server. Constants --------- |
