diff options
| author | Carlosgg <carlosgilglez@gmail.com> | 2023-11-30 16:44:48 +0000 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2023-12-14 12:20:19 +1100 |
| commit | bfd6ad94ff950a4b7e3a2125db1539c5e4ca333a (patch) | |
| tree | d208c64df8939dec43f3576f033c87eb228d5537 /extmod/modssl_mbedtls.c | |
| parent | f33dfb966a1432281809e372b9d3803e7fd3cb2f (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.c | 42 |
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; } |
