summaryrefslogtreecommitdiff
path: root/extmod/modssl_mbedtls.c
diff options
context:
space:
mode:
authorCarlosgg <carlosgilglez@gmail.com>2023-11-30 16:44:48 +0000
committerDamien George <damien@micropython.org>2023-12-14 12:20:19 +1100
commitbfd6ad94ff950a4b7e3a2125db1539c5e4ca333a (patch)
treed208c64df8939dec43f3576f033c87eb228d5537 /extmod/modssl_mbedtls.c
parentf33dfb966a1432281809e372b9d3803e7fd3cb2f (diff)
extmod/asyncio: Add ssl support with SSLContext.
This adds asyncio ssl support with SSLContext and the corresponding tests in `tests/net_inet` and `tests/multi_net`. Note that not doing the handshake on connect will delegate the handshake to the following `mbedtls_ssl_read/write` calls. However if the handshake fails when a client certificate is required and not presented by the peer, it needs to be notified of this handshake error (otherwise it will hang until timeout if any). Finally at MicroPython side raise the proper mbedtls error code and message. Signed-off-by: Carlos Gil <carlosgilglez@gmail.com>
Diffstat (limited to 'extmod/modssl_mbedtls.c')
-rw-r--r--extmod/modssl_mbedtls.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/extmod/modssl_mbedtls.c b/extmod/modssl_mbedtls.c
index f407d94cb..0190c96a9 100644
--- a/extmod/modssl_mbedtls.c
+++ b/extmod/modssl_mbedtls.c
@@ -166,6 +166,46 @@ STATIC NORETURN void mbedtls_raise_error(int err) {
#endif
}
+STATIC void ssl_check_async_handshake_failure(mp_obj_ssl_socket_t *sslsock, int *errcode) {
+ if (
+ #if MBEDTLS_VERSION_NUMBER >= 0x03000000
+ (*errcode < 0) && (mbedtls_ssl_is_handshake_over(&sslsock->ssl) == 0) && (*errcode != MBEDTLS_ERR_SSL_CONN_EOF)
+ #else
+ (*errcode < 0) && (*errcode != MBEDTLS_ERR_SSL_CONN_EOF)
+ #endif
+ ) {
+ // Asynchronous handshake is done by mbdetls_ssl_read/write. If the return code is
+ // MBEDTLS_ERR_XX (i.e < 0) and the handshake is not done due to a handshake failure,
+ // then notify peer with proper error code and raise local error with mbedtls_raise_error.
+
+ if (*errcode == MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE) {
+ // Check if TLSv1.3 and use proper alert for this case (to be implemented)
+ // uint8_t alert = MBEDTLS_SSL_ALERT_MSG_CERT_REQUIRED; tlsv1.3
+ // uint8_t alert = MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE; tlsv1.2
+ mbedtls_ssl_send_alert_message(&sslsock->ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
+ }
+
+ if (*errcode == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
+ // The certificate may have been rejected for several reasons.
+ char xcbuf[256];
+ uint32_t flags = mbedtls_ssl_get_verify_result(&sslsock->ssl);
+ int 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) {
+ sslsock->sock = MP_OBJ_NULL;
+ mbedtls_ssl_free(&sslsock->ssl);
+ mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("%s"), xcbuf);
+ }
+ }
+
+ sslsock->sock = MP_OBJ_NULL;
+ mbedtls_ssl_free(&sslsock->ssl);
+ mbedtls_raise_error(*errcode);
+ }
+}
+
/******************************************************************************/
// SSLContext type.
@@ -614,6 +654,7 @@ STATIC mp_uint_t socket_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errc
} else {
o->last_error = ret;
}
+ ssl_check_async_handshake_failure(o, &ret);
*errcode = ret;
return MP_STREAM_ERROR;
}
@@ -642,6 +683,7 @@ STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, in
} else {
o->last_error = ret;
}
+ ssl_check_async_handshake_failure(o, &ret);
*errcode = ret;
return MP_STREAM_ERROR;
}