From d491c2d77925981747c972a0faf0af28c65f3e63 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sat, 19 Feb 2022 18:30:46 +0100 Subject: [PATCH] ssl_client.c: Adapt ciphersuite writing to TLS 1.2 case Signed-off-by: Ronald Cron --- library/ssl_client.c | 85 +++++++++++++++++++++++++++++++++----- library/ssl_misc.h | 3 ++ library/ssl_tls12_client.c | 6 +-- 3 files changed, 81 insertions(+), 13 deletions(-) diff --git a/library/ssl_client.c b/library/ssl_client.c index f6385d741b..2fe4aca5f7 100644 --- a/library/ssl_client.c +++ b/library/ssl_client.c @@ -119,10 +119,56 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl, /* Write cipher_suites * CipherSuite cipher_suites<2..2^16-2>; */ +/** + * \brief Validate cipher suite against config in SSL context. + * + * \param ssl SSL context + * \param suite_info Cipher suite to validate + * + * \return 0 if valid, else 1 + */ +static int ssl_validate_ciphersuite( + const mbedtls_ssl_context *ssl, + const mbedtls_ssl_ciphersuite_t *suite_info ) +{ + if( suite_info == NULL ) + return( 1 ); + + if( ( suite_info->min_minor_ver > ssl->conf->max_minor_ver ) || + ( suite_info->max_minor_ver < ssl->conf->min_minor_ver ) ) + return( 1 ); + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#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_KEY_EXCHANGE_ECJPAKE_ENABLED) + if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && + mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) + return( 1 ); +#endif + + /* Don't suggest PSK-based ciphersuite if no PSK is available. */ +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) + if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) && + mbedtls_ssl_conf_has_static_psk( ssl->conf ) == 0 ) + { + return( 1 ); + } +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + + return( 0 ); +} + static int ssl_write_client_hello_cipher_suites( mbedtls_ssl_context *ssl, unsigned char *buf, unsigned char *end, + int *tls12_uses_ec, size_t *out_len ) { unsigned char *p = buf; @@ -130,7 +176,8 @@ static int ssl_write_client_hello_cipher_suites( unsigned char *cipher_suites; /* Start of the cipher_suites list */ size_t cipher_suites_len; - *out_len = 0 ; + *tls12_uses_ec = 0; + *out_len = 0; /* * Ciphersuite list @@ -154,12 +201,16 @@ static int ssl_write_client_hello_cipher_suites( const mbedtls_ssl_ciphersuite_t *ciphersuite_info; ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( cipher_suite ); - if( ciphersuite_info == NULL ) - continue; - if( !( MBEDTLS_SSL_MINOR_VERSION_4 >= ciphersuite_info->min_minor_ver && - MBEDTLS_SSL_MINOR_VERSION_4 <= ciphersuite_info->max_minor_ver ) ) + + if( ssl_validate_ciphersuite( ssl, ciphersuite_info ) ) continue; +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + ( defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) ) + *tls12_uses_ec |= mbedtls_ssl_ciphersuite_uses_ec( ciphersuite_info ); +#endif + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x, %s", (unsigned int) cipher_suite, ciphersuite_info->name ) ); @@ -170,6 +221,19 @@ static int ssl_write_client_hello_cipher_suites( p += 2; } + /* + * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV + */ +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) +#endif + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) ); + MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 ); + MBEDTLS_PUT_UINT16_BE( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO, p, 0 ); + p += 2; + } + /* Write the cipher_suites length in number of bytes */ cipher_suites_len = p - cipher_suites; MBEDTLS_PUT_UINT16_BE( cipher_suites_len, buf, 0 ); @@ -217,15 +281,14 @@ static int ssl_write_client_hello_body( mbedtls_ssl_context *ssl, unsigned char *end, size_t *out_len ) { - int ret; + unsigned char *p = buf; + int tls12_uses_ec = 0; + unsigned char *p_extensions_len; /* Pointer to extensions length */ size_t output_len; /* Length of buffer used by function */ size_t extensions_len; /* Length of the list of extensions*/ - /* Buffer management */ - unsigned char *p = buf; - *out_len = 0; /* @@ -315,7 +378,9 @@ static int ssl_write_client_hello_body( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_DTLS */ /* Write cipher_suites */ - ret = ssl_write_client_hello_cipher_suites( ssl, p, end, &output_len ); + ret = ssl_write_client_hello_cipher_suites( ssl, p, end, + &tls12_uses_ec, + &output_len ); if( ret != 0 ) return( ret ); p += output_len; diff --git a/library/ssl_misc.h b/library/ssl_misc.h index f3f5f8df55..2586c6d253 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1299,6 +1299,9 @@ void mbedtls_ssl_add_hs_msg_to_checksum( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ); +#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2) +int mbedtls_ssl_conf_has_static_psk( mbedtls_ssl_config const *conf ); +#endif /** * Get the first defined PSK by order of precedence: diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index 7b609e9f2a..b20ea25d9e 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -53,7 +53,7 @@ #endif #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) -static int ssl_conf_has_static_psk( mbedtls_ssl_config const *conf ) +int mbedtls_ssl_conf_has_static_psk( mbedtls_ssl_config const *conf ) { if( conf->psk_identity == NULL || conf->psk_identity_len == 0 ) @@ -672,7 +672,7 @@ static int ssl_validate_ciphersuite( /* Don't suggest PSK-based ciphersuite if no PSK is available. */ #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) && - ssl_conf_has_static_psk( ssl->conf ) == 0 ) + mbedtls_ssl_conf_has_static_psk( ssl->conf ) == 0 ) { return( 1 ); } @@ -3495,7 +3495,7 @@ ecdh_calc_secret: /* * opaque psk_identity<0..2^16-1>; */ - if( ssl_conf_has_static_psk( ssl->conf ) == 0 ) + if( mbedtls_ssl_conf_has_static_psk( ssl->conf ) == 0 ) { /* We don't offer PSK suites if we don't have a PSK, * and we check that the server's choice is among the