Skip to content

Commit 69aefcf

Browse files
committed
extmod/modussl_mbedtls: Wire in support for DTLS.
Signed-off-by: Damien Tournoud <damien@platform.sh>
1 parent 42eab32 commit 69aefcf

File tree

4 files changed

+103
-4
lines changed

4 files changed

+103
-4
lines changed

docs/library/ssl.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,32 @@ Exceptions
117117

118118
This exception does NOT exist. Instead its base class, OSError, is used.
119119

120+
DTLS support
121+
------------
122+
123+
.. admonition:: Difference to CPython
124+
:class: attention
125+
126+
This is a MicroPython extension.
127+
128+
This module supports DTLS in client and server mode via the ``ssl.PROTOCOL_DTLS_CLIENT``
129+
and ``ssl.PROTOCOL_DTLS_SERVER`` constants that can be used as the `protocol` argument
130+
of ``ssl.SSLContext``.
131+
132+
In this case the underlying socket is expected to behave as a datagram socket (i.e.
133+
like the socket opened with ``socket.socket`` with ``socket.AF_INET`` as `af` and
134+
``socket.SOCK_DGRAM`` as `type`.
135+
136+
DTLS is only supported on ports that use mbed TLS, and it is not enabled by default:
137+
it requires enabling `MBEDTLS_SSL_PROTO_DTLS` in the specific port configuration.
138+
120139
Constants
121140
---------
122141

123142
.. data:: ssl.PROTOCOL_TLS_CLIENT
124143
ssl.PROTOCOL_TLS_SERVER
144+
ssl.PROTOCOL_DTLS_CLIENT (when DTLS support is enabled)
145+
ssl.PROTOCOL_DTLS_SERVER (when DTLS support is enabled)
125146

126147
Supported values for the *protocol* parameter.
127148

extmod/modssl_mbedtls.c

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
#include "py/stream.h"
3838
#include "py/objstr.h"
3939
#include "py/reader.h"
40+
#include "py/smallint.h"
41+
#include "py/mphal.h"
4042
#include "extmod/vfs.h"
4143

4244
// mbedtls_time_t
@@ -46,6 +48,9 @@
4648
#include "mbedtls/pk.h"
4749
#include "mbedtls/entropy.h"
4850
#include "mbedtls/ctr_drbg.h"
51+
#ifdef MBEDTLS_SSL_PROTO_DTLS
52+
#include "mbedtls/timing.h"
53+
#endif
4954
#include "mbedtls/debug.h"
5055
#include "mbedtls/error.h"
5156
#if MBEDTLS_VERSION_NUMBER >= 0x03000000
@@ -56,6 +61,14 @@
5661

5762
#define MP_STREAM_POLL_RDWR (MP_STREAM_POLL_RD | MP_STREAM_POLL_WR)
5863

64+
#define MP_ENDPOINT_IS_SERVER (1 << 0)
65+
#define MP_TRANSPORT_IS_DTLS (1 << 1)
66+
67+
#define MP_PROTOCOL_TLS_CLIENT 0
68+
#define MP_PROTOCOL_TLS_SERVER MP_ENDPOINT_IS_SERVER
69+
#define MP_PROTOCOL_DTLS_CLIENT MP_TRANSPORT_IS_DTLS
70+
#define MP_PROTOCOL_DTLS_SERVER MP_ENDPOINT_IS_SERVER | MP_TRANSPORT_IS_DTLS
71+
5972
// This corresponds to an SSLContext object.
6073
typedef struct _mp_obj_ssl_context_t {
6174
mp_obj_base_t base;
@@ -78,6 +91,12 @@ typedef struct _mp_obj_ssl_socket_t {
7891

7992
uintptr_t poll_mask; // Indicates which read or write operations the protocol needs next
8093
int last_error; // The last error code, if any
94+
95+
#ifdef MBEDTLS_SSL_PROTO_DTLS
96+
mp_uint_t timer_start_ms;
97+
mp_int_t timer_fin_ms;
98+
mp_int_t timer_int_ms;
99+
#endif
81100
} mp_obj_ssl_socket_t;
82101

83102
STATIC const mp_obj_type_t ssl_context_type;
@@ -213,7 +232,10 @@ STATIC mp_obj_t ssl_context_make_new(const mp_obj_type_t *type_in, size_t n_args
213232
mp_arg_check_num(n_args, n_kw, 1, 1, false);
214233

215234
// This is the "protocol" argument.
216-
mp_int_t endpoint = mp_obj_get_int(args[0]);
235+
mp_int_t protocol = mp_obj_get_int(args[0]);
236+
237+
int endpoint = (protocol & MP_ENDPOINT_IS_SERVER) ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT;
238+
int transport = (protocol & MP_TRANSPORT_IS_DTLS) ? MBEDTLS_SSL_TRANSPORT_DATAGRAM : MBEDTLS_SSL_TRANSPORT_STREAM;
217239

218240
// Create SSLContext object.
219241
#if MICROPY_PY_SSL_FINALISER
@@ -250,7 +272,7 @@ STATIC mp_obj_t ssl_context_make_new(const mp_obj_type_t *type_in, size_t n_args
250272
}
251273

252274
ret = mbedtls_ssl_config_defaults(&self->conf, endpoint,
253-
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
275+
transport, MBEDTLS_SSL_PRESET_DEFAULT);
254276
if (ret != 0) {
255277
mbedtls_raise_error(ret);
256278
}
@@ -518,6 +540,41 @@ STATIC int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) {
518540
}
519541
}
520542

543+
#ifdef MBEDTLS_SSL_PROTO_DTLS
544+
STATIC void _mbedtls_timing_set_delay(void *ctx, uint32_t int_ms, uint32_t fin_ms) {
545+
mp_obj_ssl_socket_t *o = (mp_obj_ssl_socket_t *)ctx;
546+
547+
o->timer_int_ms = int_ms;
548+
o->timer_fin_ms = fin_ms;
549+
550+
if (fin_ms != 0) {
551+
o->timer_start_ms = mp_hal_ticks_ms() & (MICROPY_PY_TIME_TICKS_PERIOD - 1);
552+
}
553+
}
554+
555+
STATIC int _mbedtls_timing_get_delay(void *ctx) {
556+
mp_obj_ssl_socket_t *o = (mp_obj_ssl_socket_t *)ctx;
557+
558+
if (o->timer_fin_ms == 0) {
559+
return -1;
560+
}
561+
562+
mp_uint_t now = mp_hal_ticks_ms() & (MICROPY_PY_TIME_TICKS_PERIOD - 1);
563+
mp_int_t elapsed_ms = ((now - o->timer_start_ms + MICROPY_PY_TIME_TICKS_PERIOD / 2) & (MICROPY_PY_TIME_TICKS_PERIOD - 1))
564+
- MICROPY_PY_TIME_TICKS_PERIOD / 2;
565+
566+
if (elapsed_ms >= o->timer_fin_ms) {
567+
return 2;
568+
}
569+
570+
if (elapsed_ms >= o->timer_int_ms) {
571+
return 1;
572+
}
573+
574+
return 0;
575+
}
576+
#endif
577+
521578
STATIC mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t sock,
522579
bool server_side, bool do_handshake_on_connect, mp_obj_t server_hostname) {
523580

@@ -558,6 +615,12 @@ STATIC mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t
558615
mp_raise_ValueError(MP_ERROR_TEXT("CERT_REQUIRED requires server_hostname"));
559616
}
560617

618+
#ifdef MBEDTLS_SSL_PROTO_DTLS
619+
mbedtls_ssl_set_timer_cb(&o->ssl, o,
620+
_mbedtls_timing_set_delay,
621+
_mbedtls_timing_get_delay);
622+
#endif
623+
561624
mbedtls_ssl_set_bio(&o->ssl, &o->sock, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL);
562625

563626
if (do_handshake_on_connect) {
@@ -760,6 +823,12 @@ STATIC const mp_rom_map_elem_t ssl_socket_locals_dict_table[] = {
760823
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
761824
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
762825
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
826+
#ifdef MBEDTLS_SSL_PROTO_DTLS
827+
{ MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&mp_stream_read1_obj) },
828+
{ MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&mp_stream_readinto_obj) },
829+
{ MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&mp_stream_write1_obj) },
830+
{ MP_ROM_QSTR(MP_QSTR_sendall), MP_ROM_PTR(&mp_stream_write_obj) },
831+
#endif
763832
{ MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
764833
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) },
765834
#if MICROPY_PY_SSL_FINALISER
@@ -853,8 +922,12 @@ STATIC const mp_rom_map_elem_t mp_module_ssl_globals_table[] = {
853922

854923
// Constants.
855924
{ MP_ROM_QSTR(MP_QSTR_MBEDTLS_VERSION), MP_ROM_PTR(&mbedtls_version_obj)},
856-
{ MP_ROM_QSTR(MP_QSTR_PROTOCOL_TLS_CLIENT), MP_ROM_INT(MBEDTLS_SSL_IS_CLIENT) },
857-
{ MP_ROM_QSTR(MP_QSTR_PROTOCOL_TLS_SERVER), MP_ROM_INT(MBEDTLS_SSL_IS_SERVER) },
925+
{ MP_ROM_QSTR(MP_QSTR_PROTOCOL_TLS_CLIENT), MP_ROM_INT(MP_PROTOCOL_TLS_CLIENT) },
926+
{ MP_ROM_QSTR(MP_QSTR_PROTOCOL_TLS_SERVER), MP_ROM_INT(MP_PROTOCOL_TLS_SERVER) },
927+
#ifdef MBEDTLS_SSL_PROTO_DTLS
928+
{ MP_ROM_QSTR(MP_QSTR_PROTOCOL_DTLS_CLIENT), MP_ROM_INT(MP_PROTOCOL_DTLS_CLIENT) },
929+
{ MP_ROM_QSTR(MP_QSTR_PROTOCOL_DTLS_SERVER), MP_ROM_INT(MP_PROTOCOL_DTLS_SERVER) },
930+
#endif
858931
{ MP_ROM_QSTR(MP_QSTR_CERT_NONE), MP_ROM_INT(MBEDTLS_SSL_VERIFY_NONE) },
859932
{ MP_ROM_QSTR(MP_QSTR_CERT_OPTIONAL), MP_ROM_INT(MBEDTLS_SSL_VERIFY_OPTIONAL) },
860933
{ MP_ROM_QSTR(MP_QSTR_CERT_REQUIRED), MP_ROM_INT(MBEDTLS_SSL_VERIFY_REQUIRED) },

ports/esp32/boards/sdkconfig.base

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y
6262
CONFIG_MBEDTLS_HAVE_TIME_DATE=y
6363
CONFIG_MBEDTLS_PLATFORM_TIME_ALT=y
6464
CONFIG_MBEDTLS_HAVE_TIME=y
65+
# Enable DTLS
66+
CONFIG_MBEDTLS_SSL_PROTO_DTLS=y
6567

6668
# Disable ALPN support as it's not implemented in MicroPython
6769
CONFIG_MBEDTLS_SSL_ALPN=n

ports/unix/mbedtls/mbedtls_config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
// Set mbedtls configuration
3030
#define MBEDTLS_CIPHER_MODE_CTR // needed for MICROPY_PY_CRYPTOLIB_CTR
3131

32+
// Enable DTLS
33+
#define MBEDTLS_SSL_PROTO_DTLS
34+
3235
// Enable mbedtls modules
3336
#define MBEDTLS_HAVEGE_C
3437
#define MBEDTLS_TIMING_C

0 commit comments

Comments
 (0)
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