Merge pull request #4413 from gilles-peskine-arm/tls_ext_cid-config
Allow configuring MBEDTLS_TLS_EXT_CID at compile time
diff --git a/.travis.yml b/.travis.yml
index 48faa48..39ae19c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,6 +14,8 @@
- graphviz
- gcc-arm-none-eabi
- libnewlib-arm-none-eabi
+ - gcc-arm-linux-gnueabi
+ - libc6-dev-armel-cross
language: python # Needed to get pip for Python 3
python: 3.5 # version from Ubuntu 16.04
install:
@@ -22,7 +24,7 @@
- tests/scripts/all.sh -k 'check_*'
- tests/scripts/all.sh -k test_default_out_of_box
- tests/scripts/all.sh -k test_ref_configs
- - tests/scripts/all.sh -k build_arm_none_eabi_gcc_arm5vte build_arm_none_eabi_gcc_m0plus
+ - tests/scripts/all.sh -k build_arm_linux_gnueabi_gcc_arm5vte build_arm_none_eabi_gcc_m0plus
- name: full configuration
script:
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 167d741..c846120 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1334,10 +1334,24 @@
/*
* Record layer transformations
*/
- mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform_in); /*!< current transform params (in) */
- mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform_out); /*!< current transform params (in) */
- mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform); /*!< negotiated transform params */
- mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform_negotiate); /*!< transform params in negotiation */
+ mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform_in); /*!< current transform params (in)
+ * This is always a reference,
+ * never an owning pointer. */
+ mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform_out); /*!< current transform params (out)
+ * This is always a reference,
+ * never an owning pointer. */
+ mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform); /*!< negotiated transform params
+ * This pointer owns the transform
+ * it references. */
+ mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform_negotiate); /*!< transform params in negotiation
+ * This pointer owns the transform
+ * it references. */
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ /*! The application data transform in TLS 1.3.
+ * This pointer owns the transform it references. */
+ mbedtls_ssl_transform *MBEDTLS_PRIVATE(transform_application);
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
/*
* Timers
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index e0a1c24..59c5460 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -4210,23 +4210,8 @@
{
int ret = 0;
- if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) );
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
- {
- if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
- return( ret );
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
/* Change state now, so that it is right in mbedtls_ssl_read_record(), used
* by DTLS for dropping out-of-sequence ChangeCipherSpec records */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 64b0abb..b4f841a 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -562,6 +562,13 @@
uint16_t mtu; /*!< Handshake mtu, used to fragment outgoing messages */
#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ /*! TLS 1.3 transforms for 0-RTT and encrypted handshake messages.
+ * Those pointers own the transforms they reference. */
+ mbedtls_ssl_transform *transform_handshake;
+ mbedtls_ssl_transform *transform_earlydata;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
/*
* Checksum contexts
*/
@@ -976,7 +983,13 @@
unsigned update_hs_digest );
int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want );
-int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_write_handshake_msg_ext( mbedtls_ssl_context *ssl,
+ int update_checksum );
+static inline int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
+{
+ return( mbedtls_ssl_write_handshake_msg_ext( ssl, 1 /* update checksum */ ) );
+}
+
int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush );
int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl );
diff --git a/library/ssl_msg.c b/library/ssl_msg.c
index cf2eab5..a03f192 100644
--- a/library/ssl_msg.c
+++ b/library/ssl_msg.c
@@ -2389,7 +2389,8 @@
* (including handshake headers but excluding record headers)
* - ssl->out_msg: the record contents (handshake headers + content)
*/
-int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_write_handshake_msg_ext( mbedtls_ssl_context *ssl,
+ int update_checksum )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const size_t hs_len = ssl->out_msglen - 4;
@@ -2498,7 +2499,7 @@
#endif /* MBEDTLS_SSL_PROTO_DTLS */
/* Update running hashes of handshake messages seen */
- if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
+ if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST && update_checksum != 0 )
ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen );
}
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index d82ec04..3d67393 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -4258,23 +4258,8 @@
{
int ret = 0;
- if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
MBEDTLS_SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) );
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
- {
- if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
- return( ret );
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
switch( ssl->state )
{
case MBEDTLS_SSL_HELLO_REQUEST:
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 2306c71..cd75ec0 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3280,9 +3280,9 @@
* If partial is non-zero, keep data in the input buffer and client ID.
* (Use when a DTLS client reconnects from the same port.)
*/
-int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
+static void ssl_session_reset_msg_layer( mbedtls_ssl_context *ssl,
+ int partial )
{
- int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
size_t in_buf_len = ssl->in_buf_len;
size_t out_buf_len = ssl->out_buf_len;
@@ -3291,16 +3291,65 @@
size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
#endif
-#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \
- !defined(MBEDTLS_SSL_SRV_C)
- ((void) partial);
+#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || !defined(MBEDTLS_SSL_SRV_C)
+ partial = 0;
#endif
- ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
-
/* Cancel any possibly running timer */
mbedtls_ssl_set_timer( ssl, 0 );
+ mbedtls_ssl_reset_in_out_pointers( ssl );
+
+ /* Reset incoming message parsing */
+ ssl->in_offt = NULL;
+ ssl->nb_zero = 0;
+ ssl->in_msgtype = 0;
+ ssl->in_msglen = 0;
+ ssl->in_hslen = 0;
+ ssl->keep_current_message = 0;
+ ssl->transform_in = NULL;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ ssl->next_record_offset = 0;
+ ssl->in_epoch = 0;
+#endif
+
+ /* Keep current datagram if partial == 1 */
+ if( partial == 0 )
+ {
+ ssl->in_left = 0;
+ memset( ssl->in_buf, 0, in_buf_len );
+ }
+
+ /* Reset outgoing message writing */
+ ssl->out_msgtype = 0;
+ ssl->out_msglen = 0;
+ ssl->out_left = 0;
+ memset( ssl->out_buf, 0, out_buf_len );
+ memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
+ ssl->transform_out = NULL;
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ mbedtls_ssl_dtls_replay_reset( ssl );
+#endif
+
+ if( ssl->transform )
+ {
+ mbedtls_ssl_transform_free( ssl->transform );
+ mbedtls_free( ssl->transform );
+ ssl->transform = NULL;
+ }
+}
+
+int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
+
+ ssl_session_reset_msg_layer( ssl, partial );
+
+ /* Reset renegotiation state */
#if defined(MBEDTLS_SSL_RENEGOTIATION)
ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE;
ssl->renego_records_seen = 0;
@@ -3311,53 +3360,8 @@
#endif
ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION;
- ssl->in_offt = NULL;
- mbedtls_ssl_reset_in_out_pointers( ssl );
-
- ssl->in_msgtype = 0;
- ssl->in_msglen = 0;
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- ssl->next_record_offset = 0;
- ssl->in_epoch = 0;
-#endif
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- mbedtls_ssl_dtls_replay_reset( ssl );
-#endif
-
- ssl->in_hslen = 0;
- ssl->nb_zero = 0;
-
- ssl->keep_current_message = 0;
-
- ssl->out_msgtype = 0;
- ssl->out_msglen = 0;
- ssl->out_left = 0;
-
- memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
-
- ssl->transform_in = NULL;
- ssl->transform_out = NULL;
-
- ssl->session_in = NULL;
+ ssl->session_in = NULL;
ssl->session_out = NULL;
-
- memset( ssl->out_buf, 0, out_buf_len );
-
-#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
- if( partial == 0 )
-#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
- {
- ssl->in_left = 0;
- memset( ssl->in_buf, 0, in_buf_len );
- }
-
- if( ssl->transform )
- {
- mbedtls_ssl_transform_free( ssl->transform );
- mbedtls_free( ssl->transform );
- ssl->transform = NULL;
- }
-
if( ssl->session )
{
mbedtls_ssl_session_free( ssl->session );
@@ -5126,12 +5130,40 @@
/*
* Perform a single step of the SSL handshake
*/
+static int ssl_prepare_handshake_step( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
+ {
+ if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ return( ret );
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ return( ret );
+}
+
int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl )
{
- int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- if( ssl == NULL || ssl->conf == NULL )
+ if( ssl == NULL ||
+ ssl->conf == NULL ||
+ ssl->handshake == NULL ||
+ ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+ {
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ ret = ssl_prepare_handshake_step( ssl );
+ if( ret != 0 )
+ return( ret );
#if defined(MBEDTLS_SSL_CLI_C)
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
@@ -5463,6 +5495,13 @@
handle_buffer_resizing( ssl, 1, mbedtls_ssl_get_input_buflen( ssl ),
mbedtls_ssl_get_output_buflen( ssl ) );
#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ mbedtls_free( handshake->transform_earlydata );
+ mbedtls_free( handshake->transform_handshake );
+ handshake->transform_earlydata = NULL;
+ handshake->transform_handshake = NULL;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
}
void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
@@ -6161,6 +6200,11 @@
mbedtls_free( ssl->session_negotiate );
}
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ mbedtls_ssl_transform_free( ssl->transform_application );
+ mbedtls_free( ssl->transform_application );
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
if( ssl->session )
{
mbedtls_ssl_session_free( ssl->session );
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 5d2710c..af05dd9 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -161,6 +161,7 @@
: ${ARMC5_BIN_DIR:=/usr/bin}
: ${ARMC6_BIN_DIR:=/usr/bin}
: ${ARM_NONE_EABI_GCC_PREFIX:=arm-none-eabi-}
+ : ${ARM_LINUX_GNUEABI_GCC_PREFIX:=arm-linux-gnueabi-}
# if MAKEFLAGS is not set add the -j option to speed up invocations of make
if [ -z "${MAKEFLAGS+set}" ]; then
@@ -230,6 +231,9 @@
--arm-none-eabi-gcc-prefix=<string>
Prefix for a cross-compiler for arm-none-eabi
(default: "${ARM_NONE_EABI_GCC_PREFIX}")
+ --arm-linux-gnueabi-gcc-prefix=<string>
+ Prefix for a cross-compiler for arm-linux-gnueabi
+ (default: "${ARM_LINUX_GNUEABI_GCC_PREFIX}")
--armcc Run ARM Compiler builds (on by default).
--except Exclude the COMPONENTs listed on the command line,
instead of running only those.
@@ -387,6 +391,7 @@
case "$1" in
--append-outcome) append_outcome=1;;
--arm-none-eabi-gcc-prefix) shift; ARM_NONE_EABI_GCC_PREFIX="$1";;
+ --arm-linux-gnueabi-gcc-prefix) shift; ARM_LINUX_GNUEABI_GCC_PREFIX="$1";;
--armcc) no_armcc=;;
--armc5-bin-dir) shift; ARMC5_BIN_DIR="$1";;
--armc6-bin-dir) shift; ARMC6_BIN_DIR="$1";;
@@ -2369,14 +2374,29 @@
${ARM_NONE_EABI_GCC_PREFIX}size library/*.o
}
-component_build_arm_none_eabi_gcc_arm5vte () {
- msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=arm5vte" # ~ 10s
+component_build_arm_linux_gnueabi_gcc_arm5vte () {
+ msg "build: ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc -march=arm5vte" # ~ 10s
scripts/config.py baremetal
# Build for a target platform that's close to what Debian uses
# for its "armel" distribution (https://wiki.debian.org/ArmEabiPort).
# See https://github.com/ARMmbed/mbedtls/pull/2169 and comments.
- # It would be better to build with arm-linux-gnueabi-gcc but
- # we don't have that on our CI at this time.
+ # Build everything including programs, see for example
+ # https://github.com/ARMmbed/mbedtls/pull/3449#issuecomment-675313720
+ make CC="${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc" AR="${ARM_LINUX_GNUEABI_GCC_PREFIX}ar" CFLAGS='-Werror -Wall -Wextra -march=armv5te -O1' LDFLAGS='-march=armv5te'
+
+ msg "size: ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc -march=armv5te -O1"
+ ${ARM_LINUX_GNUEABI_GCC_PREFIX}size library/*.o
+}
+support_build_arm_linux_gnueabi_gcc_arm5vte () {
+ type ${ARM_LINUX_GNUEABI_GCC_PREFIX}gcc >/dev/null 2>&1
+}
+
+component_build_arm_none_eabi_gcc_arm5vte () {
+ msg "build: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=arm5vte" # ~ 10s
+ scripts/config.py baremetal
+ # This is an imperfect substitute for
+ # component_build_arm_linux_gnueabi_gcc_arm5vte
+ # in case the gcc-arm-linux-gnueabi toolchain is not available
make CC="${ARM_NONE_EABI_GCC_PREFIX}gcc" AR="${ARM_NONE_EABI_GCC_PREFIX}ar" CFLAGS='-std=c99 -Werror -Wall -Wextra -march=armv5te -O1' LDFLAGS='-march=armv5te' SHELL='sh -x' lib
msg "size: ${ARM_NONE_EABI_GCC_PREFIX}gcc -march=armv5te -O1"
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 01265ae..9ee6b76 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -77,6 +77,14 @@
O_LEGACY_CLI=false
fi
+if [ -n "${OPENSSL_NEXT:-}" ]; then
+ O_NEXT_SRV="$OPENSSL_NEXT s_server -www -cert data_files/server5.crt -key data_files/server5.key"
+ O_NEXT_CLI="echo 'GET / HTTP/1.0' | $OPENSSL_NEXT s_client"
+else
+ O_NEXT_SRV=false
+ O_NEXT_CLI=false
+fi
+
if [ -n "${GNUTLS_NEXT_SERV:-}" ]; then
G_NEXT_SRV="$GNUTLS_NEXT_SERV --x509certfile data_files/server5.crt --x509keyfile data_files/server5.key"
else
@@ -346,6 +354,57 @@
fi
}
+requires_openssl_next() {
+ if [ -z "${OPENSSL_NEXT_AVAILABLE:-}" ]; then
+ if which "${OPENSSL_NEXT:-}" >/dev/null 2>&1; then
+ OPENSSL_NEXT_AVAILABLE="YES"
+ else
+ OPENSSL_NEXT_AVAILABLE="NO"
+ fi
+ fi
+ if [ "$OPENSSL_NEXT_AVAILABLE" = "NO" ]; then
+ SKIP_NEXT="YES"
+ fi
+}
+
+# skip next test if tls1_3 is not available
+requires_openssl_tls1_3() {
+ requires_openssl_next
+ if [ "$OPENSSL_NEXT_AVAILABLE" = "NO" ]; then
+ OPENSSL_TLS1_3_AVAILABLE="NO"
+ fi
+ if [ -z "${OPENSSL_TLS1_3_AVAILABLE:-}" ]; then
+ if $OPENSSL_NEXT s_client -help 2>&1 | grep tls1_3 >/dev/null
+ then
+ OPENSSL_TLS1_3_AVAILABLE="YES"
+ else
+ OPENSSL_TLS1_3_AVAILABLE="NO"
+ fi
+ fi
+ if [ "$OPENSSL_TLS1_3_AVAILABLE" = "NO" ]; then
+ SKIP_NEXT="YES"
+ fi
+}
+
+# skip next test if tls1_3 is not available
+requires_gnutls_tls1_3() {
+ requires_gnutls_next
+ if [ "$GNUTLS_NEXT_AVAILABLE" = "NO" ]; then
+ GNUTLS_TLS1_3_AVAILABLE="NO"
+ fi
+ if [ -z "${GNUTLS_TLS1_3_AVAILABLE:-}" ]; then
+ if $GNUTLS_NEXT_CLI -l 2>&1 | grep VERS-TLS1.3 >/dev/null
+ then
+ GNUTLS_TLS1_3_AVAILABLE="YES"
+ else
+ GNUTLS_TLS1_3_AVAILABLE="NO"
+ fi
+ fi
+ if [ "$GNUTLS_TLS1_3_AVAILABLE" = "NO" ]; then
+ SKIP_NEXT="YES"
+ fi
+}
+
# skip next test if IPv6 isn't available on this host
requires_ipv6() {
if [ -z "${HAS_IPV6:-}" ]; then
@@ -8487,6 +8546,24 @@
-c "EAP-TLS IV is:" \
-s "EAP-TLS IV is:"
+# openssl feature tests: check if tls1.3 exists.
+requires_openssl_tls1_3
+run_test "TLS1.3: Test openssl tls1_3 feature" \
+ "$O_NEXT_SRV -tls1_3 -msg" \
+ "$O_NEXT_CLI -tls1_3 -msg" \
+ 0 \
+ -c "TLS 1.3" \
+ -s "TLS 1.3"
+
+# gnutls feature tests: check if tls1.3 exists.
+requires_gnutls_tls1_3
+run_test "TLS1.3: Test gnutls tls1_3 feature" \
+ "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3" \
+ "$G_NEXT_CLI localhost --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 -V" \
+ 0 \
+ -s "Version: TLS1.3" \
+ -c "Version: TLS1.3"
+
# TLS1.3 test cases
# TODO: remove or rewrite this test case if #4832 is resolved.
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2