diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index fa2429d07c..288d9b3c5c 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -486,6 +486,7 @@ #define MBEDTLS_SSL_HS_SERVER_HELLO 2 #define MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST 3 #define MBEDTLS_SSL_HS_NEW_SESSION_TICKET 4 +#define MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS 8 // NEW IN TLS 1.3 #define MBEDTLS_SSL_HS_CERTIFICATE 11 #define MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE 12 #define MBEDTLS_SSL_HS_CERTIFICATE_REQUEST 13 diff --git a/library/ssl_tls13_client.c b/library/ssl_tls13_client.c index 979db31449..5ed01aade2 100644 --- a/library/ssl_tls13_client.c +++ b/library/ssl_tls13_client.c @@ -1395,11 +1395,134 @@ cleanup: } /* - * Handler for MBEDTLS_SSL_ENCRYPTED_EXTENSIONS + * + * EncryptedExtensions message + * + * The EncryptedExtensions message contains any extensions which + * should be protected, i.e., any which are not needed to establish + * the cryptographic context. */ -static int ssl_tls1_3_process_encrypted_extensions( mbedtls_ssl_context *ssl ) + +/* + * Overview + */ + +/* Main entry point; orchestrates the other functions */ +static int ssl_tls13_process_encrypted_extensions( mbedtls_ssl_context *ssl ); + +static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl, + const unsigned char *buf, + const unsigned char *end ); +static int ssl_tls13_postprocess_encrypted_extensions( mbedtls_ssl_context *ssl ); + +/* + * Handler for MBEDTLS_SSL_ENCRYPTED_EXTENSIONS + */ +static int ssl_tls13_process_encrypted_extensions( mbedtls_ssl_context *ssl ) +{ + int ret; + unsigned char *buf; + size_t buf_len; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse encrypted extensions" ) ); + + MBEDTLS_SSL_PROC_CHK( mbedtls_ssl_tls1_3_fetch_handshake_msg( ssl, + MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, + &buf, &buf_len ) ); + + /* Process the message contents */ + MBEDTLS_SSL_PROC_CHK( + ssl_tls13_parse_encrypted_extensions( ssl, buf, buf + buf_len ) ); + + mbedtls_ssl_tls1_3_add_hs_msg_to_checksum( + ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, buf, buf_len ); + + MBEDTLS_SSL_PROC_CHK( ssl_tls13_postprocess_encrypted_extensions( ssl ) ); + +cleanup: + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse encrypted extensions" ) ); + return( ret ); + +} + +/* Parse EncryptedExtensions message + * struct { + * Extension extensions<0..2^16-1>; + * } EncryptedExtensions; + */ +static int ssl_tls13_parse_encrypted_extensions( mbedtls_ssl_context *ssl, + const unsigned char *buf, + const unsigned char *end ) +{ + int ret = 0; + size_t extensions_len; + const unsigned char *p = buf; + const unsigned char *extensions_end; + + MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 2 ); + extensions_len = MBEDTLS_GET_UINT16_BE( p, 0 ); + p += 2; + + MBEDTLS_SSL_DEBUG_BUF( 3, "encrypted extensions", p, extensions_len ); + extensions_end = p + extensions_len; + MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, extensions_len ); + + while( p < extensions_end ) + { + unsigned int extension_type; + size_t extension_data_len; + + /* + * struct { + * ExtensionType extension_type; (2 bytes) + * opaque extension_data<0..2^16-1>; + * } Extension; + */ + 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 ); + + /* The client MUST check EncryptedExtensions for the + * presence of any forbidden extensions and if any are found MUST abort + * the handshake with an "unsupported_extension" alert. + */ + switch( extension_type ) + { + + case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extensions supported groups" ) ); + break; + + default: + MBEDTLS_SSL_DEBUG_MSG( + 3, ( "unsupported extension found: %u ", extension_type) ); + MBEDTLS_SSL_PEND_FATAL_ALERT( + MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT, \ + MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION ); + return ( MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION ); + } + + p += extension_data_len; + } + + /* Check that we consumed all the message. */ + if( p != end ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "EncryptedExtension lengths misaligned" ) ); + MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR, \ + MBEDTLS_ERR_SSL_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_DECODE_ERROR ); + } + + return( ret ); +} + +static int ssl_tls13_postprocess_encrypted_extensions( mbedtls_ssl_context *ssl ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "%s hasn't been implemented", __func__ ) ); mbedtls_ssl_handshake_set_state( ssl, MBEDTLS_SSL_CERTIFICATE_REQUEST ); return( 0 ); } @@ -1516,7 +1639,7 @@ int mbedtls_ssl_tls13_handshake_client_step( mbedtls_ssl_context *ssl ) break; case MBEDTLS_SSL_ENCRYPTED_EXTENSIONS: - ret = ssl_tls1_3_process_encrypted_extensions( ssl ); + ret = ssl_tls13_process_encrypted_extensions( ssl ); break; case MBEDTLS_SSL_CERTIFICATE_REQUEST: diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 8fbe67739b..f9bfec2e1e 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -8808,7 +8808,7 @@ requires_openssl_tls1_3 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL requires_config_disabled MBEDTLS_USE_PSA_CRYPTO run_test "TLS1.3: Test client hello msg work - openssl" \ - "$O_NEXT_SRV -tls1_3 -msg" \ + "$O_NEXT_SRV -tls1_3 -msg -no_middlebox" \ "$P_CLI debug_level=3 min_version=tls1_3 max_version=tls1_3" \ 1 \ -c "SSL - The requested feature is not available" \ @@ -8828,13 +8828,14 @@ run_test "TLS1.3: Test client hello msg work - openssl" \ -c "<= ssl_tls1_3_process_server_hello" \ -c "server hello, chosen ciphersuite: ( 1301 ) - TLS1-3-AES-128-GCM-SHA256" \ -c "ECDH curve: x25519" \ - -c "=> ssl_tls1_3_process_server_hello" + -c "=> ssl_tls1_3_process_server_hello" \ + -c "<= parse encrypted extensions" requires_gnutls_tls1_3 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL requires_config_disabled MBEDTLS_USE_PSA_CRYPTO run_test "TLS1.3: Test client hello msg work - gnutls" \ - "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3 --debug=4" \ + "$G_NEXT_SRV --priority=NORMAL:-VERS-ALL:+VERS-TLS1.3:%DISABLE_TLS13_COMPAT_MODE --debug=4" \ "$P_CLI debug_level=3 min_version=tls1_3 max_version=tls1_3" \ 1 \ -c "SSL - The requested feature is not available" \ @@ -8854,8 +8855,8 @@ run_test "TLS1.3: Test client hello msg work - gnutls" \ -c "<= ssl_tls1_3_process_server_hello" \ -c "server hello, chosen ciphersuite: ( 1301 ) - TLS1-3-AES-128-GCM-SHA256" \ -c "ECDH curve: x25519" \ - -c "=> ssl_tls1_3_process_server_hello" - + -c "=> ssl_tls1_3_process_server_hello" \ + -c "<= parse encrypted extensions" # Test heap memory usage after handshake requires_config_enabled MBEDTLS_MEMORY_DEBUG