Skip to content

extmod/modssl: Add SSLContext class. #11862

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

Merged
merged 4 commits into from
Jun 26, 2023

Conversation

dpgeorge
Copy link
Member

This PR adds the SSLContext class to the ssl module, and retains the existing ssl.wrap_socket() function to maintain backwards compatibility.

CPython deprecated the ssl.wrap_socket() function since CPython 3.7 and instead one should use ssl.SSLContext().wrap_socket(). This PR makes that possible.

For the axtls implementation:

  • ssl.SSLContext is added, although it doesn't hold much state because axtls requires calling ssl_ctx_new() for each new socket
  • ssl.SSLContext.wrap_socket() is added
  • ssl.PROTOCOL_TLS_CLIENT and ssl.PROTOCOL_TLS_SERVER are added

For the mbedtls implementation:

  • ssl.SSLContext is added, and holds most of the mbedtls state
  • ssl.verify_mode is added (getter and setter)
  • ssl.SSLContext.wrap_socket() is added
  • ssl.PROTOCOL_TLS_CLIENT and ssl.PROTOCOL_TLS_SERVER are added

The signatures match CPython:

  • SSLContext(protocol)
  • SSLContext.wrap_socket(sock, *, server_side=False, do_handshake_on_connect=True, server_hostname=None)

The existing ssl.wrap_socket() functions retain their existing signature.

@dpgeorge dpgeorge added the extmod Relates to extmod/ directory in source label Jun 24, 2023
@dpgeorge
Copy link
Member Author

This is an alternative to #8968, although the commit here just does the minimal amount of work to refactor the existing ssl code/module to provide a CPython compatible (subset) of ssl.SSLContext. There's still a lot of additional things provided by #8968 that is not done here.

@github-actions
Copy link

github-actions bot commented Jun 24, 2023

Code size report:

   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64: +1024 +0.129% standard[incl +224(data)]
      stm32:    +0 +0.000% PYBV10
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% PICO
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS

@codecov
Copy link

codecov bot commented Jun 24, 2023

Codecov Report

Merging #11862 (713a451) into master (c2ea8b2) will increase coverage by 0.01%.
The diff coverage is 95.69%.

@@            Coverage Diff             @@
##           master   #11862      +/-   ##
==========================================
+ Coverage   98.40%   98.41%   +0.01%     
==========================================
  Files         155      155              
  Lines       20543    20564      +21     
==========================================
+ Hits        20215    20238      +23     
+ Misses        328      326       -2     
Impacted Files Coverage Δ
extmod/modssl_mbedtls.c 91.74% <95.69%> (+1.89%) ⬆️

@dpgeorge
Copy link
Member Author

Code size change on bare metal ports that enable mbedTLS:

rp2 PICO_W      +432
mimxrt TEENSY41 +472
stm32 PYBD_SF6  +496
esp32 GENERIC   +400

For axtls:

esp8266 GENERIC +396

@Carglglz
Copy link
Contributor

Carglglz commented Jun 25, 2023

I've just rebased #8968 on this PR and so far it looks promising, saved around 1kB-2kB of memory usage in the application I'm testing, which includes some endurance/stress testing using asyncio+TLS in unix/esp32 ports (i.e restarting the mqtt broker repeatedly to see how it deals with wrapping new ssl sockets or testing a server (microdot) doing multiple calls with ab benchmark)

So when this is merged I can submit following PRs that:

  • Adds methods to SSLContext .i.e (load_cadata, load_certchain, get_ciphers, set_ciphers)
  • Add cert_reqs kwarg to SSLContext.wrap_socket
  • Add ssl_socket.ciphers and ssl_socket.ssl_pending (this last one is a fix for unix/asyncio see 8ed1a34 )
  • Add cert date/time validation (this also needs enabling MBEDTLS_HAVE_TIME ,MBEDTLS_HAVE_TIMEDATE in mbedtls_config.h and mbedtls_port.c for esp32 port)

Here is the patch if you want to add anything of that in this PR:

diff --git a/extmod/modssl_mbedtls.c b/extmod/modssl_mbedtls.c
index 9b56907a5..5a0afdf78 100644
--- a/extmod/modssl_mbedtls.c
+++ b/extmod/modssl_mbedtls.c
@@ -37,7 +37,6 @@
 #include "py/stream.h"
 #include "py/objstr.h"

-// mbedtls_time_t
 #include "mbedtls/platform.h"
 #include "mbedtls/ssl.h"
 #include "mbedtls/x509_crt.h"
@@ -46,6 +45,16 @@
 #include "mbedtls/ctr_drbg.h"
 #include "mbedtls/debug.h"
 #include "mbedtls/error.h"
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#include "mbedtls/build_info.h"
+#include "mbedtls/platform_time.h"
+#else
+#include "mbedtls/version.h"
+#endif
+#ifdef MICROPY_MBEDTLS_PLATFORM_TIME_ALT
+#include "mbedtls/mbedtls_config.h"
+
+#endif

 #define MP_STREAM_POLL_RDWR (MP_STREAM_POLL_RD | MP_STREAM_POLL_WR)

@@ -59,6 +68,7 @@ typedef struct _mp_obj_ssl_context_t {
     mbedtls_x509_crt cert;
     mbedtls_pk_context pkey;
     int authmode;
+    int cipherid [];
 } mp_obj_ssl_context_t;

 // This corresponds to an SSLSocket object.
@@ -74,9 +84,10 @@ typedef struct _mp_obj_ssl_socket_t {

 STATIC const mp_obj_type_t ssl_context_type;
 STATIC const mp_obj_type_t ssl_socket_type;
+STATIC const MP_DEFINE_STR_OBJ(mbedtls_version_obj, MBEDTLS_VERSION_STRING_FULL);

 STATIC mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t sock,
-    bool server_side, bool do_handshake_on_connect, mp_obj_t server_hostname);
+    bool server_side, bool do_handshake_on_connect, mp_obj_t server_hostname, int cert_reqs);

 /******************************************************************************/
 // Helper functions.
@@ -156,6 +167,7 @@ STATIC mp_obj_t ssl_context_make_new(const mp_obj_type_t *type_in, size_t n_args
     mp_obj_ssl_context_t *self = m_new_obj(mp_obj_ssl_context_t);
     #endif
     self->base.type = type_in;
+    self->cipherid[0] = 0;

     // Initialise mbedTLS state.
     mbedtls_ssl_config_init(&self->conf);
@@ -169,6 +181,16 @@ STATIC mp_obj_t ssl_context_make_new(const mp_obj_type_t *type_in, size_t n_args
     // Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose
     mbedtls_debug_set_threshold(3);
     #endif
+    #ifdef MICROPY_MBEDTLS_PLATFORM_TIME_ALT
+    mbedtls_platform_set_time(platform_mbedtls_time);
+    #endif
+    // DEBUG MBEDTLS_PLATFORM
+    // time_t mbt;
+    // time_t mbtz;
+    // mbt = mbedtls_time(NULL);
+    // mbtz = platform_mbedtls_time(NULL);
+    // printf("secs mbt : %lu \n\n", mbt);
+    // printf("secs mbtz: %lu \n\n", mbtz);

     const byte seed[] = "upy";
     int ret = mbedtls_ctr_drbg_seed(&self->ctr_drbg, mbedtls_entropy_func, &self->entropy, seed, sizeof(seed));
@@ -236,6 +258,57 @@ STATIC mp_obj_t ssl_context___del__(mp_obj_t self_in) {
 STATIC MP_DEFINE_CONST_FUN_OBJ_1(ssl_context___del___obj, ssl_context___del__);
 #endif

+// Ciphersuites
+
+STATIC mp_obj_t mod_ssl_get_ciphers() {
+    mp_obj_t list = mp_obj_new_list(0, NULL);
+    const int *cipher_list = mbedtls_ssl_list_ciphersuites();
+    while (*cipher_list) {
+        const char *cipher_name = mbedtls_ssl_get_ciphersuite_name(*cipher_list);
+        mp_obj_list_append(list,
+            MP_OBJ_FROM_PTR(mp_obj_new_str(cipher_name,
+                strlen(cipher_name))));
+        cipher_list++;
+        if (!*cipher_list) {
+            break;
+        }
+
+    }
+
+    return list;
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ssl_get_ciphers_obj, mod_ssl_get_ciphers);
+
+
+STATIC mp_obj_t mod_ssl_set_ciphers(mp_obj_t self_in, mp_obj_t ciphersuite) {
+    mp_obj_ssl_context_t *self = MP_OBJ_TO_PTR(self_in);
+    // check that ciphersuite is a list of str?
+    mp_obj_list_t *ciphers = MP_OBJ_TO_PTR(ciphersuite);
+
+    for (int i = 0, n = ciphers->len; i < n; i++) {
+
+        if (ciphers->items[i] != mp_const_none) {
+            const char *ciphername = mp_obj_str_get_str(ciphers->items[i]);
+            const int id = mbedtls_ssl_get_ciphersuite_id(ciphername);
+            self->cipherid[i] = id;
+            if (id == 0) {
+                mbedtls_raise_error(MBEDTLS_ERR_SSL_BAD_CONFIG);
+            }
+
+        }
+    }
+
+    self->cipherid[ciphers->len + 1] = 0;
+
+    return mp_const_none;
+
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_ssl_set_ciphers_obj, mod_ssl_set_ciphers);
+
+// SSLContext.load_certchain
+
 STATIC void ssl_context_load_key(mp_obj_ssl_context_t *self, mp_obj_t key_obj, mp_obj_t cert_obj) {
     size_t key_len;
     const byte *key = (const byte *)mp_obj_str_get_data(key_obj, &key_len);
@@ -264,6 +337,37 @@ STATIC void ssl_context_load_key(mp_obj_ssl_context_t *self, mp_obj_t key_obj, m
     }
 }

+STATIC mp_obj_t mod_ssl_load_certchain(size_t n_args, const mp_obj_t *pos_args,
+    mp_map_t *kw_args) {
+
+    static const mp_arg_t allowed_args[] = {
+        { MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
+        { MP_QSTR_cert, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
+    };
+
+    mp_obj_ssl_context_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+    // struct cert_chain_args args;
+    mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+    mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args,
+        args);
+
+    if (args[0].u_obj != mp_const_none) {
+        ssl_context_load_key(self, args[0].u_obj, args[1].u_obj);
+
+    }
+
+    return mp_const_none;
+
+
+
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_load_certchain_obj, 1, mod_ssl_load_certchain);
+
+
+
+// SSLContext.load_cadata
+
 STATIC void ssl_context_load_cadata(mp_obj_ssl_context_t *self, mp_obj_t cadata_obj) {
     size_t cacert_len;
     const byte *cacert = (const byte *)mp_obj_str_get_data(cadata_obj, &cacert_len);
@@ -276,12 +380,26 @@ STATIC void ssl_context_load_cadata(mp_obj_ssl_context_t *self, mp_obj_t cadata_
     mbedtls_ssl_conf_ca_chain(&self->conf, &self->cacert, NULL);
 }

+STATIC mp_obj_t mod_ssl_load_cadata(mp_obj_t self_in, mp_obj_t cadata) {
+    mp_obj_ssl_context_t *self = MP_OBJ_TO_PTR(self_in);
+    if (cadata != mp_const_none) {
+        ssl_context_load_cadata(self, cadata);
+    }
+
+    return mp_const_none;
+
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_ssl_load_cadata_obj, mod_ssl_load_cadata);
+
+
 STATIC mp_obj_t ssl_context_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
-    enum { ARG_server_side, ARG_do_handshake_on_connect, ARG_server_hostname };
+    enum { ARG_server_side, ARG_do_handshake_on_connect, ARG_server_hostname, ARG_cert_reqs  };
     static const mp_arg_t allowed_args[] = {
         { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
         { MP_QSTR_do_handshake_on_connect, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
         { MP_QSTR_server_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
+        { MP_QSTR_cert_reqs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = MBEDTLS_SSL_VERIFY_NONE}},
     };

     // Parse arguments.
@@ -292,14 +410,19 @@ STATIC mp_obj_t ssl_context_wrap_socket(size_t n_args, const mp_obj_t *pos_args,

     // Create and return the new SSLSocket object.
     return ssl_socket_make_new(self, sock, args[ARG_server_side].u_bool,
-        args[ARG_do_handshake_on_connect].u_bool, args[ARG_server_hostname].u_obj);
+        args[ARG_do_handshake_on_connect].u_bool, args[ARG_server_hostname].u_obj, args[ARG_cert_reqs].u_int);
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ssl_context_wrap_socket_obj, 2, ssl_context_wrap_socket);

+// add load_certchain, load_cadata, get/set ciphersuites
 STATIC const mp_rom_map_elem_t ssl_context_locals_dict_table[] = {
     #if MICROPY_PY_SSL_FINALISER
     { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&ssl_context___del___obj) },
     #endif
+    { MP_ROM_QSTR(MP_QSTR_get_ciphers), MP_ROM_PTR(&mod_ssl_get_ciphers_obj)},
+    { MP_ROM_QSTR(MP_QSTR_set_ciphers), MP_ROM_PTR(&mod_ssl_set_ciphers_obj)},
+    { MP_ROM_QSTR(MP_QSTR_load_cadata), MP_ROM_PTR(&mod_ssl_load_cadata_obj)},
+    { MP_ROM_QSTR(MP_QSTR_load_certchain), MP_ROM_PTR(&mod_ssl_load_certchain_obj)},
     { MP_ROM_QSTR(MP_QSTR_wrap_socket), MP_ROM_PTR(&ssl_context_wrap_socket_obj) },
 };
 STATIC MP_DEFINE_CONST_DICT(ssl_context_locals_dict, ssl_context_locals_dict_table);
@@ -351,12 +474,12 @@ STATIC int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) {
     }
 }

+
 STATIC mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t sock,
-    bool server_side, bool do_handshake_on_connect, mp_obj_t server_hostname) {
+    bool server_side, bool do_handshake_on_connect, mp_obj_t server_hostname, int cert_reqs) {

     // Verify the socket object has the full stream protocol
     mp_get_stream_raise(sock, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);
-
     #if MICROPY_PY_SSL_FINALISER
     mp_obj_ssl_socket_t *o = m_new_obj_with_finaliser(mp_obj_ssl_socket_t);
     #else
@@ -367,8 +490,22 @@ STATIC mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t
     o->poll_mask = 0;
     o->last_error = 0;

+
     int ret;
+    uint32_t flags = 0;
+    int *cid = &ssl_context->cipherid[0];
+    /* printf("cipherid: %d\n", *cid); */
+
+    // Ciphersuite Config
+    if (*cid != 0) {
+        mbedtls_ssl_conf_ciphersuites(&ssl_context->conf, (const int *)&ssl_context->cipherid);
+    }
+
+
     mbedtls_ssl_init(&o->ssl);
+    // Authmode
+    mbedtls_ssl_conf_authmode(&ssl_context->conf, cert_reqs);
+

     ret = mbedtls_ssl_setup(&o->ssl, &ssl_context->conf);
     if (ret != 0) {
@@ -385,6 +522,7 @@ STATIC mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t

     mbedtls_ssl_set_bio(&o->ssl, &o->sock, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL);

+
     if (do_handshake_on_connect) {
         while ((ret = mbedtls_ssl_handshake(&o->ssl)) != 0) {
             if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
@@ -399,10 +537,29 @@ STATIC mp_obj_t ssl_socket_make_new(mp_obj_ssl_context_t *ssl_context, mp_obj_t
     return MP_OBJ_FROM_PTR(o);

 cleanup:
+    if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
+        flags = mbedtls_ssl_get_verify_result(&o->ssl);
+
+    }
+
     mbedtls_ssl_free(&o->ssl);
-    mbedtls_raise_error(ret);
+
+    if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
+        char xcbuf[512];
+        ret = mbedtls_x509_crt_verify_info(xcbuf, sizeof(xcbuf), "\n", flags);
+        // The length of the string written (not including the terminated nul byte),
+        // or a negative err code.
+        if (ret > 0) {
+            mp_raise_ValueError(MP_ERROR_TEXT(xcbuf));
+        } else {
+            mbedtls_raise_error(ret);
+        }
+    } else {
+        mbedtls_raise_error(ret);
+    }
 }

+
 STATIC mp_obj_t mod_ssl_getpeercert(mp_obj_t o_in, mp_obj_t binary_form) {
     mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
     if (!mp_obj_is_true(binary_form)) {
@@ -416,6 +573,17 @@ STATIC mp_obj_t mod_ssl_getpeercert(mp_obj_t o_in, mp_obj_t binary_form) {
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_ssl_getpeercert_obj, mod_ssl_getpeercert);

+STATIC mp_obj_t mod_ssl_cipher(mp_obj_t o_in) {
+    mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
+    const char *cipher_suite = mbedtls_ssl_get_ciphersuite(&o->ssl);
+    const char *tls_version = mbedtls_ssl_get_version(&o->ssl);
+    mp_obj_t tuple[2] = {mp_obj_new_str(cipher_suite, strlen(cipher_suite)),
+                         mp_obj_new_str(tls_version, strlen(tls_version))};
+
+    return mp_obj_new_tuple(2, tuple);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ssl_cipher_obj, mod_ssl_cipher);
+
 STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) {
     mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(o_in);
     o->poll_mask = 0;
@@ -486,6 +654,14 @@ STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) {
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking);

+STATIC mp_obj_t socket_ssl_pending(mp_obj_t self_in) {
+    mp_obj_ssl_socket_t *o = MP_OBJ_TO_PTR(self_in);
+    int check_pending = 0;
+    check_pending = mbedtls_ssl_check_pending(&o->ssl);
+    return mp_obj_new_int(check_pending);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_ssl_pending_obj, socket_ssl_pending);
+
 STATIC mp_uint_t socket_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) {
     mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(o_in);
     mp_uint_t ret = 0;
@@ -548,6 +724,8 @@ STATIC const mp_rom_map_elem_t ssl_socket_locals_dict_table[] = {
     { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&mp_stream_ioctl_obj) },
     #endif
     { MP_ROM_QSTR(MP_QSTR_getpeercert), MP_ROM_PTR(&mod_ssl_getpeercert_obj) },
+    { MP_ROM_QSTR(MP_QSTR_cipher), MP_ROM_PTR(&mod_ssl_cipher_obj) },
+    { MP_ROM_QSTR(MP_QSTR_ssl_pending), MP_ROM_PTR(&socket_ssl_pending_obj) },
 };
 STATIC MP_DEFINE_CONST_DICT(ssl_socket_locals_dict, ssl_socket_locals_dict_table);

@@ -614,7 +792,7 @@ STATIC mp_obj_t mod_ssl_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_

     // Create and return the new SSLSocket object.
     return ssl_socket_make_new(ssl_context, sock, args[ARG_server_side].u_bool,
-        args[ARG_do_handshake].u_bool, args[ARG_server_hostname].u_obj);
+        args[ARG_do_handshake].u_bool, args[ARG_server_hostname].u_obj, args[ARG_cert_reqs].u_int);
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, mod_ssl_wrap_socket);

@@ -628,6 +806,7 @@ STATIC const mp_rom_map_elem_t mp_module_ssl_globals_table[] = {
     { MP_ROM_QSTR(MP_QSTR_SSLContext), MP_ROM_PTR(&ssl_context_type) },

     // Constants.
+    { MP_ROM_QSTR(MP_QSTR_MBEDTLS_VERSION), MP_ROM_PTR(&mbedtls_version_obj)},
     { MP_ROM_QSTR(MP_QSTR_PROTOCOL_TLS_CLIENT), MP_ROM_INT(MBEDTLS_SSL_IS_CLIENT) },
     { MP_ROM_QSTR(MP_QSTR_PROTOCOL_TLS_SERVER), MP_ROM_INT(MBEDTLS_SSL_IS_SERVER) },
     { MP_ROM_QSTR(MP_QSTR_CERT_NONE), MP_ROM_INT(MBEDTLS_SSL_VERIFY_NONE) },

And next would follow the TLS support for asyncio in a separate PR I guess. 👀

dpgeorge added 4 commits June 26, 2023 16:34
This commit adds the SSLContext class to the ssl module, and retains the
existing ssl.wrap_socket() function to maintain backwards compatibility.

CPython deprecated the ssl.wrap_socket() function since CPython 3.7 and
instead one should use ssl.SSLContext().wrap_socket().  This commit makes
that possible.

For the axtls implementation:
- ssl.SSLContext is added, although it doesn't hold much state because
  axtls requires calling ssl_ctx_new() for each new socket
- ssl.SSLContext.wrap_socket() is added
- ssl.PROTOCOL_TLS_CLIENT and ssl.PROTOCOL_TLS_SERVER are added

For the mbedtls implementation:
- ssl.SSLContext is added, and holds most of the mbedtls state
- ssl.verify_mode is added (getter and setter)
- ssl.SSLContext.wrap_socket() is added
- ssl.PROTOCOL_TLS_CLIENT and ssl.PROTOCOL_TLS_SERVER are added

The signatures match CPython:
- SSLContext(protocol)
- SSLContext.wrap_socket(sock, *, server_side=False,
    do_handshake_on_connect=True, server_hostname=None)

The existing ssl.wrap_socket() functions retain their existing signature.

Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
For coverage.

Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
@dpgeorge dpgeorge force-pushed the extmod-ssl-add-sslcontext branch from 64e5a91 to 713a451 Compare June 26, 2023 06:36
@dpgeorge dpgeorge merged commit 713a451 into micropython:master Jun 26, 2023
@dpgeorge
Copy link
Member Author

Thanks @Carglglz for testing this PR. It's now merged, so feel free to follow up with your changes.

(Note that I didn't add any of the above patches.)

@dpgeorge dpgeorge deleted the extmod-ssl-add-sslcontext branch June 26, 2023 07:06
@Carglglz
Copy link
Contributor

@dpgeorge done in #11888 , #11896 and #11897, if you could review them, that would be great 👍🏼

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

Successfully merging this pull request may close these issues.

2 participants