From 6512554f42798e5447cfd8ca4e65140e20dcf17f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 27 Aug 2015 16:37:35 +0200 Subject: [PATCH] Fix handling of long PSK identities backport from c3b5d83 see #238 --- ChangeLog | 3 +++ library/ssl_cli.c | 22 ++++++++++++++++++++++ library/ssl_tls.c | 7 +++++++ 3 files changed, 32 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5d505b502..89a89f8fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,9 @@ Bugfix * Fix unused function warning when using MBEDTLS_MDx_ALT or MBEDTLS_SHAxxx_ALT (found by Henrik) (#239) * Fix memory corruption in pkey programs (found by yankuncheng) (#210) + * Fix memory corruption on client with overlong PSK identity, around + SSL_MAX_CONTENT_LEN or higher - not triggerrable remotely (found by + Aleksandrs Saveljevs) (#238) = mbed TLS 1.3.12 released 2015-08-11 diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 0c62c3448..7f46cbb33 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -1578,6 +1578,12 @@ static int ssl_write_encrypted_pms( ssl_context *ssl, size_t len_bytes = ssl->minor_ver == SSL_MINOR_VERSION_0 ? 0 : 2; unsigned char *p = ssl->handshake->premaster + pms_offset; + if( offset + len_bytes > SSL_MAX_CONTENT_LEN ) + { + SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + /* * Generate (part of) the pre-master as * struct { @@ -2349,6 +2355,14 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) i = 4; n = ssl->psk_identity_len; + + if( i + 2 + n > SSL_MAX_CONTENT_LEN ) + { + SSL_DEBUG_MSG( 1, ( "psk identity too long or " + "SSL buffer too short" ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + ssl->out_msg[i++] = (unsigned char)( n >> 8 ); ssl->out_msg[i++] = (unsigned char)( n ); @@ -2377,6 +2391,14 @@ static int ssl_write_client_key_exchange( ssl_context *ssl ) * ClientDiffieHellmanPublic public (DHM send G^X mod P) */ n = ssl->handshake->dhm_ctx.len; + + if( i + 2 + n > SSL_MAX_CONTENT_LEN ) + { + SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long" + " or SSL buffer too short" ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + ssl->out_msg[i++] = (unsigned char)( n >> 8 ); ssl->out_msg[i++] = (unsigned char)( n ); diff --git a/library/ssl_tls.c b/library/ssl_tls.c index b8a5e6edc..96e867b69 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -4047,6 +4047,13 @@ int ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len, if( psk_len > POLARSSL_PSK_MAX_LEN ) return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + /* Identity len will be encoded on two bytes */ + if( ( psk_identity_len >> 16 ) != 0 || + psk_identity_len > SSL_MAX_CONTENT_LEN ) + { + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + if( ssl->psk != NULL || ssl->psk_identity != NULL ) { polarssl_free( ssl->psk );