Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track use of extensions to avoid duplicate extensions in the same message #114

Open
wants to merge 3 commits into
base: tls13-prototype
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion include/mbedtls/ssl_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,9 @@ struct mbedtls_ssl_handshake_params
int max_minor_ver; /*!< max. minor version client*/
int cli_exts; /*!< client extension presence*/
#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
int extensions_present; /*!< which extension were present; the */
int extensions_present; /*!< which extensions are present; used
and set by
`mbedtls_ssl_extensions_present()`*/
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */

#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && defined(MBEDTLS_SSL_TLS13_CTLS)
Expand Down Expand Up @@ -1743,4 +1745,39 @@ int mbedtls_ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl );
void mbedtls_ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_PROTO_DTLS */

/* Reset list of present extensions */
static inline void mbedtls_ssl_reset_extensions_present( mbedtls_ssl_context *ssl )
{
ssl->handshake->extensions_present = NO_EXTENSION;
}

/* Check presence of extensions and optionally set the extension flag */
static inline int mbedtls_ssl_extensions_present( mbedtls_ssl_context *ssl,
int extension_flag,
int set_extension_flag )
{
int ret = 0;

ret = ssl->handshake->extensions_present & extension_flag;
if( set_extension_flag )
ssl->handshake->extensions_present |= extension_flag;
return( ret );
}

/* Check presence of extensions and send an alert if one of them is already
* present. Update the list of present extensions */
static inline int mbedtls_ssl_check_extensions_present( mbedtls_ssl_context *ssl,
int extension_flag )
{
int ret = 0;

if( ( ret = mbedtls_ssl_extensions_present( ssl, extension_flag, 0 ) ) )
SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );

/* Update extension list */
ssl->handshake->extensions_present |= extension_flag;

return( ret );
}

#endif /* ssl_internal.h */
105 changes: 88 additions & 17 deletions library/ssl_tls13_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,7 @@ int mbedtls_ssl_write_pre_shared_key_ext( mbedtls_ssl_context *ssl,

*olen = 0;

if( !( ssl->handshake->extensions_present & PSK_KEY_EXCHANGE_MODES_EXTENSION ) )
if( !( mbedtls_ssl_extensions_present( ssl, PSK_KEY_EXCHANGE_MODES_EXTENSION, 0 ) ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "The psk_key_exchange_modes extension has not been added." ) );
return( MBEDTLS_ERR_SSL_BAD_HS_PSK_KEY_EXCHANGE_MODES_EXT );
Expand Down Expand Up @@ -1593,8 +1593,8 @@ static int ssl_client_hello_write( mbedtls_ssl_context* ssl,
unsigned char* ciphersuite_start;
size_t ciphersuite_count;

/* Keeping track of the included extensions */
ssl->handshake->extensions_present = NO_EXTENSION;
/* Keeping track of the included extension */
mbedtls_ssl_reset_extensions_present( ssl );

#if defined(MBEDTLS_SSL_TLS13_CTLS)
if( ssl->handshake->ctls == MBEDTLS_SSL_TLS13_CTLS_USE )
Expand Down Expand Up @@ -1910,7 +1910,7 @@ static int ssl_client_hello_write( mbedtls_ssl_context* ssl,
buf += cur_ext_len;

if( ret == 0 )
ssl->handshake->extensions_present |= PSK_KEY_EXCHANGE_MODES_EXTENSION;
mbedtls_ssl_extensions_present( ssl, PSK_KEY_EXCHANGE_MODES_EXTENSION, 1 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */

Expand All @@ -1927,7 +1927,7 @@ static int ssl_client_hello_write( mbedtls_ssl_context* ssl,
total_ext_len += cur_ext_len;
buf += cur_ext_len;

if( ret == 0 ) ssl->handshake->extensions_present |= SUPPORTED_GROUPS_EXTENSION;
if( ret == 0 ) mbedtls_ssl_extensions_present( ssl, SUPPORTED_GROUPS_EXTENSION, 1 );
}

/* The supported_signature_algorithms extension is REQUIRED for
Expand All @@ -1940,7 +1940,7 @@ static int ssl_client_hello_write( mbedtls_ssl_context* ssl,
total_ext_len += cur_ext_len;
buf += cur_ext_len;

if( ret == 0 ) ssl->handshake->extensions_present |= SIGNATURE_ALGORITHM_EXTENSION;
if( ret == 0 ) mbedtls_ssl_extensions_present( ssl, SIGNATURE_ALGORITHM_EXTENSION, 1 );
}
/* We need to send the key shares under three conditions:
* 1 ) A certificate-based ciphersuite is being offered. In this case
Expand All @@ -1957,16 +1957,16 @@ static int ssl_client_hello_write( mbedtls_ssl_context* ssl,
total_ext_len += cur_ext_len;
buf += cur_ext_len;

if( ret == 0 ) ssl->handshake->extensions_present |= KEY_SHARE_EXTENSION;
if( ret == 0 ) mbedtls_ssl_extensions_present( ssl, KEY_SHARE_EXTENSION, 1 );
}
else if( ssl->handshake->extensions_present & SUPPORTED_GROUPS_EXTENSION && ssl->handshake->extensions_present & SIGNATURE_ALGORITHM_EXTENSION )
else if( mbedtls_ssl_extensions_present( ssl, SUPPORTED_GROUPS_EXTENSION | SIGNATURE_ALGORITHM_EXTENSION, 0 ) )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocker: This is functionally incorrect since the present implementaiton of mbedtls_ssl_extensions_present() only checks whether a non-zero part of the flag is present, not whether the entire flag is present.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed mbedtls_ssl_extensions_present() to support a conjunction of extensions

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be easier to independently call mbedtls_ssl_extensions_present() for each extension rather than calling it once to check several extensions though...

{
/* We are using a certificate-based key exchange */
ret = ssl_write_key_shares_ext( ssl, buf, end, &cur_ext_len );
total_ext_len += cur_ext_len;
buf += cur_ext_len;

if( ret == 0 ) ssl->handshake->extensions_present |= KEY_SHARE_EXTENSION;
if( ret == 0 ) mbedtls_ssl_extensions_present( ssl, KEY_SHARE_EXTENSION, 1 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */

Expand All @@ -1986,7 +1986,7 @@ static int ssl_client_hello_write( mbedtls_ssl_context* ssl,
buf += cur_ext_len;

if( ret == 0 )
ssl->handshake->extensions_present |= PRE_SHARED_KEY_EXTENSION;
mbedtls_ssl_extensions_present( ssl, PRE_SHARED_KEY_EXTENSION, 1 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */

Expand Down Expand Up @@ -2114,7 +2114,7 @@ static int ssl_parse_server_psk_identity_ext( mbedtls_ssl_context *ssl,
}

/* buf += 2; */
ssl->handshake->extensions_present |= PRE_SHARED_KEY_EXTENSION;
mbedtls_ssl_extensions_present( ssl, PRE_SHARED_KEY_EXTENSION, 1 );
return( 0 );
}

Expand Down Expand Up @@ -2212,7 +2212,7 @@ static int ssl_parse_key_shares_ext( mbedtls_ssl_context *ssl,
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}

ssl->handshake->extensions_present |= KEY_SHARE_EXTENSION;
mbedtls_ssl_extensions_present( ssl, KEY_SHARE_EXTENSION, 1 );
return( ret );
}
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
Expand Down Expand Up @@ -2467,6 +2467,9 @@ static int ssl_certificate_request_parse( mbedtls_ssl_context* ssl,
/*
* Parse extensions
*/

mbedtls_ssl_reset_extensions_present( ssl );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this change made?


ext_len = ( p[0] << 8 ) | ( p[1] );

/* At least one extension needs to be present, namely signature_algorithms ext. */
Expand Down Expand Up @@ -2500,6 +2503,12 @@ static int ssl_certificate_request_parse( mbedtls_ssl_context* ssl,
case MBEDTLS_TLS_EXT_SIG_ALG:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );

if( ( ret = mbedtls_ssl_check_extensions_present( ssl, SIGNATURE_ALGORITHM_EXTENSION ) ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_ssl_check_extensions_present" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}

if( ( ret = mbedtls_ssl_parse_signature_algorithms_ext( ssl, ext + 4, (size_t)ext_size ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_ssl_parse_signature_algorithms_ext" ) );
Expand Down Expand Up @@ -2659,6 +2668,8 @@ static int ssl_encrypted_extensions_parse( mbedtls_ssl_context* ssl,
/* skip handshake header */
buf += mbedtls_ssl_hs_hdr_len( ssl );

mbedtls_ssl_reset_extensions_present( ssl );

ext_len = ( ( buf[0] << 8 ) | ( buf[1] ) );

buf += 2; /* skip extension length */
Expand Down Expand Up @@ -2707,6 +2718,12 @@ static int ssl_encrypted_extensions_parse( mbedtls_ssl_context* ssl,
case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) );

if( ( ret = mbedtls_ssl_check_extensions_present( ssl, MAX_FRAGMENT_LENGTH_EXTENSION ) ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_ssl_check_extensions_present" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_ENCRYPTED_EXTENSIONS );
}

if( ( ret = ssl_parse_max_fragment_length_ext( ssl,
ext + 4, ext_size ) ) != 0 )
{
Expand All @@ -2721,6 +2738,12 @@ static int ssl_encrypted_extensions_parse( mbedtls_ssl_context* ssl,
case MBEDTLS_TLS_EXT_ALPN:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );

if( ( ret = mbedtls_ssl_check_extensions_present( ssl, ALPN_EXTENSION ) ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_ssl_check_extensions_present" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_ENCRYPTED_EXTENSIONS );
}

if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, (size_t)ext_size ) ) != 0 )
{
return( ret );
Expand Down Expand Up @@ -3172,6 +3195,8 @@ static int ssl_server_hello_parse( mbedtls_ssl_context* ssl,
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}

mbedtls_ssl_reset_extensions_present( ssl );

ext_len = ( ( buf[0] << 8 ) | ( buf[1] ) );
buf += 2; /* skip extension length */

Expand Down Expand Up @@ -3207,6 +3232,13 @@ static int ssl_server_hello_parse( mbedtls_ssl_context* ssl,
#if defined(MBEDTLS_CID)
case MBEDTLS_TLS_EXT_CID:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found CID extension" ) );

if( ( ret = mbedtls_ssl_check_extensions_present( ssl, CID_EXTENSION ) ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_ssl_check_extensions_present" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}

if( ssl->conf->cid == MBEDTLS_CID_CONF_DISABLED )
break;

Expand All @@ -3219,6 +3251,12 @@ static int ssl_server_hello_parse( mbedtls_ssl_context* ssl,
case MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_versions extension" ) );

if( ( ret = mbedtls_ssl_check_extensions_present( ssl, SUPPORTED_VERSION_EXTENSION ) ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_ssl_check_extensions_present" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}

ret = ssl_parse_supported_version_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
Expand All @@ -3227,6 +3265,13 @@ static int ssl_server_hello_parse( mbedtls_ssl_context* ssl,
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
case MBEDTLS_TLS_EXT_PRE_SHARED_KEY:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found pre_shared_key extension" ) );

if( ( ret = mbedtls_ssl_check_extensions_present( ssl, PRE_SHARED_KEY_EXTENSION ) ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_ssl_check_extensions_present" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}

if( ( ret = ssl_parse_server_psk_identity_ext( ssl, ext + 4, (size_t)ext_size ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_server_psk_identity_ext" ), ret );
Expand All @@ -3239,6 +3284,12 @@ static int ssl_server_hello_parse( mbedtls_ssl_context* ssl,
case MBEDTLS_TLS_EXT_KEY_SHARES:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found key_shares extension" ) );

if( ( ret = mbedtls_ssl_check_extensions_present( ssl, KEY_SHARE_EXTENSION ) ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_ssl_check_extensions_present" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}

if( ( ret = ssl_parse_key_shares_ext( ssl, ext + 4, (size_t)ext_size ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_parse_key_shares_ext", ret );
Expand Down Expand Up @@ -3279,14 +3330,14 @@ static int ssl_server_hello_postprocess( mbedtls_ssl_context* ssl )
* ELSE unknown key exchange mechanism.
*/

if( ssl->handshake->extensions_present & PRE_SHARED_KEY_EXTENSION )
if( mbedtls_ssl_extensions_present( ssl, PRE_SHARED_KEY_EXTENSION, 0 ) )
{
if( ssl->handshake->extensions_present & KEY_SHARE_EXTENSION )
if( mbedtls_ssl_extensions_present( ssl, KEY_SHARE_EXTENSION, 0 ) )
ssl->session_negotiate->key_exchange = MBEDTLS_KEY_EXCHANGE_ECDHE_PSK;
else
ssl->session_negotiate->key_exchange = MBEDTLS_KEY_EXCHANGE_PSK;
}
else if( ssl->handshake->extensions_present & KEY_SHARE_EXTENSION )
else if( mbedtls_ssl_extensions_present( ssl, KEY_SHARE_EXTENSION, 0 ) )
ssl->session_negotiate->key_exchange = MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA;
else
{
Expand Down Expand Up @@ -3555,6 +3606,8 @@ static int ssl_hrr_parse( mbedtls_ssl_context* ssl,
return( MBEDTLS_ERR_SSL_BAD_HS_HELLO_RETRY_REQUEST );
}

mbedtls_ssl_reset_extensions_present( ssl );

ext_len = ( ( buf[0] << 8 ) | ( buf[1] ) );
buf += 2; /* skip extension length */

Expand Down Expand Up @@ -3589,6 +3642,12 @@ static int ssl_hrr_parse( mbedtls_ssl_context* ssl,
#if defined(MBEDTLS_SSL_COOKIE_C)
case MBEDTLS_TLS_EXT_COOKIE:

if( ( ret = mbedtls_ssl_check_extensions_present( ssl, COOKIE_EXTENSION ) ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_ssl_check_extensions_present" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_HELLO_RETRY_REQUEST );
}

/* Retrieve length field of cookie */
if( ext_size >= 2 )
{
Expand Down Expand Up @@ -3628,6 +3687,12 @@ static int ssl_hrr_parse( mbedtls_ssl_context* ssl,
case MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_versions extension" ) );

if( ( ret = mbedtls_ssl_check_extensions_present( ssl, SUPPORTED_VERSION_EXTENSION ) ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_ssl_check_extensions_present" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_HELLO_RETRY_REQUEST );
}

ret = ssl_parse_supported_version_ext( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
Expand All @@ -3638,6 +3703,12 @@ static int ssl_hrr_parse( mbedtls_ssl_context* ssl,

MBEDTLS_SSL_DEBUG_BUF( 3, "key_share extension", ext + 4, ext_size );

if( ( ret = mbedtls_ssl_check_extensions_present( ssl, KEY_SHARE_EXTENSION ) ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_ssl_check_extensions_present" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_HELLO_RETRY_REQUEST );
}

/* Read selected_group */
tls_id = ( ( ext[4] << 8 ) | ( ext[5] ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected_group ( %d )", tls_id ) );
Expand Down Expand Up @@ -4120,7 +4191,7 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
*
* Reset extensions we have seen so far.
*/
ssl->handshake->extensions_present = NO_EXTENSION;
mbedtls_ssl_reset_extensions_present( ssl );
ret = ssl_server_hello_process( ssl );

if( ret != 0 )
Expand Down Expand Up @@ -4210,7 +4281,7 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
* message and not the HRR anymore.
*/
/* reset extensions we have seen so far */
ssl->handshake->extensions_present = NO_EXTENSION;
mbedtls_ssl_reset_extensions_present( ssl );
ret = ssl_server_hello_process( ssl );

if( ret != 0 )
Expand Down
2 changes: 1 addition & 1 deletion library/ssl_tls13_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -4982,7 +4982,7 @@ int mbedtls_ssl_write_early_data_ext( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_SSL_SRV_C)
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
{
if( ( ssl->handshake->extensions_present & EARLY_DATA_EXTENSION ) == 0 )
if( !( mbedtls_ssl_extensions_present( ssl, EARLY_DATA_EXTENSION, 0 ) ) )
return( 0 );

if( ssl->conf->key_exchange_modes != MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_KE ||
Expand Down
Loading