From 47dce630f40d771c6e9e0ab87ee7b7781810ac11 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 8 Feb 2023 17:38:29 +0100 Subject: [PATCH] tls13: Add function to search for a supported_versions extension Move in a dedicated function the search for the supported_versions extension in a list of extensions, to be able to use it on server side as well. Signed-off-by: Ronald Cron --- library/ssl_misc.h | 26 ++++++++++++++++++ library/ssl_tls13_client.c | 46 ++++--------------------------- library/ssl_tls13_generic.c | 55 +++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 41 deletions(-) diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 14a3c7ef00..e136c35a2c 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -2048,6 +2048,32 @@ int mbedtls_ssl_tls13_fetch_handshake_msg(mbedtls_ssl_context *ssl, unsigned char **buf, size_t *buf_len); +/** + * \brief Detect if a list of extensions contains a supported_versions + * extension or not. + * + * \param[in] ssl SSL context + * \param[in] buf Address of the first byte of the extensions vector. + * \param[in] end End of the buffer containing the list of extensions. + * \param[out] extension_data If the extension is present, address of its first + * byte of data, NULL otherwise. + * \param[out] extension_data_end If the extension is present, address of the + * first byte immediately following the extension + * data, NULL otherwise. + * \return 0 if the list of extensions does not contain a supported_versions + * extension. + * \return 1 if the list of extensions contains a supported_versions + * extension. + * \return A negative value if an error occurred while parsing the + * extensions. + */ +MBEDTLS_CHECK_RETURN_CRITICAL +int mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts( + mbedtls_ssl_context *ssl, + const unsigned char *buf, const unsigned char *end, + const unsigned char **extension_data, + const unsigned char **extension_data_end); + /* * Handler of TLS 1.3 server certificate message */ diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index d10fbeb468..fedb2be96f 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1324,8 +1324,8 @@ static int ssl_tls13_is_supported_versions_ext_present( { const unsigned char *p = buf; size_t legacy_session_id_echo_len; - size_t extensions_len; - const unsigned char *extensions_end; + const unsigned char *supported_versions_ext; + const unsigned char *supported_versions_ext_end; /* * Check there is enough data to access the legacy_session_id_echo vector @@ -1347,45 +1347,9 @@ static int ssl_tls13_is_supported_versions_ext_present( MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, legacy_session_id_echo_len + 4); p += legacy_session_id_echo_len + 4; - /* Case of no extension */ - if (p == end) { - return 0; - } - - /* ... - * Extension extensions<6..2^16-1>; - * ... - * struct { - * ExtensionType extension_type; (2 bytes) - * opaque extension_data<0..2^16-1>; - * } Extension; - */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); - extensions_len = MBEDTLS_GET_UINT16_BE(p, 0); - p += 2; - - /* Check extensions do not go beyond the buffer of data. */ - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len); - extensions_end = p + extensions_len; - - while (p < extensions_end) { - unsigned int extension_type; - size_t extension_data_len; - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4); - extension_type = MBEDTLS_GET_UINT16_BE(p, 0); - extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2); - p += 4; - - if (extension_type == MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS) { - return 1; - } - - MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len); - p += extension_data_len; - } - - return 0; + return mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts( + ssl, p, end, + &supported_versions_ext, &supported_versions_ext_end); } /* Returns a negative value on failure, and otherwise diff --git a/library/ssl_tls13_generic.c b/library/ssl_tls13_generic.c index 38077ddbb7..1a10e7563b 100644 --- a/library/ssl_tls13_generic.c +++ b/library/ssl_tls13_generic.c @@ -86,6 +86,61 @@ cleanup: return ret; } +int mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts( + mbedtls_ssl_context *ssl, + const unsigned char *buf, const unsigned char *end, + const unsigned char **extension_data, + const unsigned char **extension_data_end) +{ + const unsigned char *p = buf; + size_t extensions_len; + const unsigned char *extensions_end; + + *extension_data = NULL; + *extension_data_end = NULL; + + /* Case of no extension */ + if (p == end) { + return 0; + } + + /* ... + * Extension extensions; + * ... + * struct { + * ExtensionType extension_type; (2 bytes) + * opaque extension_data<0..2^16-1>; + * } Extension; + */ + MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); + extensions_len = MBEDTLS_GET_UINT16_BE(p, 0); + p += 2; + + /* Check extensions do not go beyond the buffer of data. */ + MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len); + extensions_end = p + extensions_len; + + while (p < extensions_end) { + unsigned int extension_type; + size_t extension_data_len; + + MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4); + extension_type = MBEDTLS_GET_UINT16_BE(p, 0); + extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2); + p += 4; + MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len); + + if (extension_type == MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS) { + *extension_data = p; + *extension_data_end = p + extension_data_len; + return 1; + } + p += extension_data_len; + } + + return 0; +} + #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED) /* * STATE HANDLING: Read CertificateVerify