summaryrefslogtreecommitdiff
path: root/thirdparty/mbedtls/library/ssl_cli.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/mbedtls/library/ssl_cli.c')
-rw-r--r--thirdparty/mbedtls/library/ssl_cli.c166
1 files changed, 108 insertions, 58 deletions
diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c
index 88864b8136..7455e99d2e 100644
--- a/thirdparty/mbedtls/library/ssl_cli.c
+++ b/thirdparty/mbedtls/library/ssl_cli.c
@@ -48,10 +48,7 @@
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
-/* Implementation that should never be optimized out by the compiler */
-static void mbedtls_zeroize( void *v, size_t n ) {
- volatile unsigned char *p = v; while( n-- ) *p++ = 0;
-}
+#include "mbedtls/platform_util.h"
#endif
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
@@ -355,7 +352,7 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
*olen = 6;
}
-#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -717,6 +714,49 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl )
return( 0 );
}
+/**
+ * \brief Validate cipher suite against config in SSL context.
+ *
+ * \param suite_info cipher suite to validate
+ * \param ssl SSL context
+ * \param min_minor_ver Minimal minor version to accept a cipher suite
+ * \param max_minor_ver Maximal minor version to accept a cipher suite
+ *
+ * \return 0 if valid, else 1
+ */
+static int ssl_validate_ciphersuite( const mbedtls_ssl_ciphersuite_t * suite_info,
+ const mbedtls_ssl_context * ssl,
+ int min_minor_ver, int max_minor_ver )
+{
+ (void) ssl;
+ if( suite_info == NULL )
+ return( 1 );
+
+ if( suite_info->min_minor_ver > max_minor_ver ||
+ suite_info->max_minor_ver < min_minor_ver )
+ return( 1 );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
+ return( 1 );
+#endif
+
+#if defined(MBEDTLS_ARC4_C)
+ if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
+ suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
+ return( 1 );
+#endif
+
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+ if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
+ mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
+ return( 1 );
+#endif
+
+ return( 0 );
+}
+
static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
{
int ret;
@@ -869,31 +909,11 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
{
ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] );
- if( ciphersuite_info == NULL )
+ if( ssl_validate_ciphersuite( ciphersuite_info, ssl,
+ ssl->conf->min_minor_ver,
+ ssl->conf->max_minor_ver ) != 0 )
continue;
- if( ciphersuite_info->min_minor_ver > ssl->conf->max_minor_ver ||
- ciphersuite_info->max_minor_ver < ssl->conf->min_minor_ver )
- continue;
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
- continue;
-#endif
-
-#if defined(MBEDTLS_ARC4_C)
- if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED &&
- ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
- continue;
-#endif
-
-#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
- mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
- continue;
-#endif
-
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
ciphersuites[i] ) );
@@ -938,7 +958,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
#endif
/*
- * We don't support compression with DTLS right now: is many records come
+ * We don't support compression with DTLS right now: if many records come
* in the same datagram, uncompressing one could overwrite the next one.
* We don't want to add complexity for handling that case unless there is
* an actual need for it.
@@ -1261,7 +1281,7 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
-#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -1690,22 +1710,9 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
- suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
- if( suite_info == NULL
-#if defined(MBEDTLS_ARC4_C)
- || ( ssl->conf->arc4_disabled &&
- suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 )
-#endif
- )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
- return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
-
+ /*
+ * Perform cipher suite validation in same way as in ssl_write_client_hello.
+ */
i = 0;
while( 1 )
{
@@ -1724,6 +1731,17 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
}
}
+ suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
+ if( ssl_validate_ciphersuite( suite_info, ssl, ssl->minor_ver, ssl->minor_ver ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
+
if( comp != MBEDTLS_SSL_COMPRESS_NULL
#if defined(MBEDTLS_ZLIB_SUPPORT)
&& comp != MBEDTLS_SSL_COMPRESS_DEFLATE
@@ -2673,10 +2691,27 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
buf = ssl->in_msg;
/* certificate_types */
+ if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+ }
cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
n = cert_type_len;
- if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
+ /*
+ * In the subsequent code there are two paths that read from buf:
+ * * the length of the signature algorithms field (if minor version of
+ * SSL is 3),
+ * * distinguished name length otherwise.
+ * Both reach at most the index:
+ * ...hdr_len + 2 + n,
+ * therefore the buffer length at this point must be greater than that
+ * regardless of the actual code path.
+ */
+ if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
@@ -2691,9 +2726,32 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
| ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
#if defined(MBEDTLS_DEBUG_C)
- unsigned char* sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n;
+ unsigned char* sig_alg;
size_t i;
+#endif
+
+ /*
+ * The furthest access in buf is in the loop few lines below:
+ * sig_alg[i + 1],
+ * where:
+ * sig_alg = buf + ...hdr_len + 3 + n,
+ * max(i) = sig_alg_len - 1.
+ * Therefore the furthest access is:
+ * buf[...hdr_len + 3 + n + sig_alg_len - 1 + 1],
+ * which reduces to:
+ * buf[...hdr_len + 3 + n + sig_alg_len],
+ * which is one less than we need the buf to be.
+ */
+ if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n + sig_alg_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
+ }
+#if defined(MBEDTLS_DEBUG_C)
+ sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n;
for( i = 0; i < sig_alg_len; i += 2 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d"
@@ -2702,14 +2760,6 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
#endif
n += 2 + sig_alg_len;
-
- if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
- }
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
@@ -3289,8 +3339,8 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
if( ticket_len == 0 )
return( 0 );
- mbedtls_zeroize( ssl->session_negotiate->ticket,
- ssl->session_negotiate->ticket_len );
+ mbedtls_platform_zeroize( ssl->session_negotiate->ticket,
+ ssl->session_negotiate->ticket_len );
mbedtls_free( ssl->session_negotiate->ticket );
ssl->session_negotiate->ticket = NULL;
ssl->session_negotiate->ticket_len = 0;