diff --git a/ChangeLog.d/issue4398.txt b/ChangeLog.d/issue4398.txt new file mode 100644 index 000000000..b7f241391 --- /dev/null +++ b/ChangeLog.d/issue4398.txt @@ -0,0 +1,3 @@ +API changes + * Replace MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE by a runtime + configuration function mbedtls_ssl_conf_preference_order(). Fixes #4398. diff --git a/docs/3.0-migration-guide.d/turn_SSL_SRV_RESPECT_CLIENT_PREFERENCE_config_opt_to_runtime_opt.md b/docs/3.0-migration-guide.d/turn_SSL_SRV_RESPECT_CLIENT_PREFERENCE_config_opt_to_runtime_opt.md new file mode 100644 index 000000000..6a6554dfb --- /dev/null +++ b/docs/3.0-migration-guide.d/turn_SSL_SRV_RESPECT_CLIENT_PREFERENCE_config_opt_to_runtime_opt.md @@ -0,0 +1,14 @@ +Turn MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE configuration option into a runtime option +-- + +This change affects users who were enabling MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE +option in the `config.h` + +This option has been removed and a new function with similar functionality has +been introduced into the SSL API. + +This new function `mbedtls_ssl_conf_preference_order()` can be used to +change the preferred order of ciphersuites on the server to those used on the client, +e.g.: `mbedtls_ssl_conf_preference_order(ssl_config, MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT)` +has the same effect as enabling the removed option. The default state is to use +the server order of suites. diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 3139b223d..c1106a6e8 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1471,16 +1471,6 @@ */ #define MBEDTLS_SSL_RENEGOTIATION -/** - * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE - * - * Pick the ciphersuite according to the client's preferences rather than ours - * in the SSL Server module (MBEDTLS_SSL_SRV_C). - * - * Uncomment this macro to respect client's ciphersuite order - */ -//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE - /** * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH * diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 8f21a9a55..b2f5c67a2 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -201,6 +201,9 @@ #define MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED 0 #define MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED 1 +#define MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT 1 +#define MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_SERVER 0 + /* * Default range for DTLS retransmission timer value, in milliseconds. * RFC 6347 4.2.4.1 says from 1 second to 60 seconds. @@ -1186,6 +1189,9 @@ struct mbedtls_ssl_config #if defined(MBEDTLS_SSL_SRV_C) unsigned int MBEDTLS_PRIVATE(cert_req_ca_list) : 1; /*!< enable sending CA list in Certificate Request messages? */ + unsigned int respect_cli_pref : 1; /*!< pick the ciphersuite according to + the client's preferences rather + than ours */ #endif #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) unsigned int MBEDTLS_PRIVATE(ignore_unexpected_cid) : 1; /*!< Determines whether DTLS @@ -2493,9 +2499,12 @@ const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_co * The ciphersuites array is not copied, and must remain * valid for the lifetime of the ssl_config. * - * Note: The server uses its own preferences - * over the preference of the client unless - * MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE is defined! + * Note: By default, the server chooses its preferred + * ciphersuite among those that the client supports. If + * mbedtls_ssl_conf_preference_order() is called to prefer + * the client's preferences, the server instead chooses + * the client's preferred ciphersuite among those that + * the server supports. * * \param conf SSL configuration * \param ciphersuites 0-terminated list of allowed ciphersuites @@ -3293,6 +3302,19 @@ void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code ); #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ +#if defined(MBEDTLS_SSL_SRV_C) +/** + * \brief Pick the ciphersuites order according to the second parameter + * in the SSL Server module (MBEDTLS_SSL_SRV_C). + * (Default, if never called: MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_SERVER) + * + * \param conf SSL configuration + * \param order Server or client (MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_SERVER + * or MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) + */ +void mbedtls_ssl_conf_preference_order( mbedtls_ssl_config *conf, int order ); +#endif /* MBEDTLS_SSL_SRV_C */ + #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) /** * \brief Activate negotiation of truncated HMAC diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 4fe6b02f1..c70c21f85 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -1872,27 +1872,43 @@ read_record_header: got_common_suite = 0; ciphersuites = ssl->conf->ciphersuite_list; ciphersuite_info = NULL; -#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) - for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) - for( i = 0; ciphersuites[i] != 0; i++ ) -#else - for( i = 0; ciphersuites[i] != 0; i++ ) + + if (ssl->conf->respect_cli_pref == MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) + { for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) -#endif - { - if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || - p[1] != ( ( ciphersuites[i] ) & 0xFF ) ) - continue; + for( i = 0; ciphersuites[i] != 0; i++ ) + { + if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || + p[1] != ( ( ciphersuites[i] ) & 0xFF ) ) + continue; - got_common_suite = 1; + got_common_suite = 1; - if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], - &ciphersuite_info ) ) != 0 ) - return( ret ); + if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], + &ciphersuite_info ) ) != 0 ) + return( ret ); - if( ciphersuite_info != NULL ) - goto have_ciphersuite; - } + if( ciphersuite_info != NULL ) + goto have_ciphersuite; + } + } else { + for( i = 0; ciphersuites[i] != 0; i++ ) + for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) + { + if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || + p[1] != ( ( ciphersuites[i] ) & 0xFF ) ) + continue; + + got_common_suite = 1; + + if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], + &ciphersuite_info ) ) != 0 ) + return( ret ); + + if( ciphersuite_info != NULL ) + goto have_ciphersuite; + } + } if( got_common_suite ) { @@ -4416,4 +4432,10 @@ int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ) return( ret ); } + +void mbedtls_ssl_conf_preference_order( mbedtls_ssl_config *conf, int order ) +{ + conf->respect_cli_pref = order; +} + #endif /* MBEDTLS_SSL_SRV_C */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 3bdc1cfa4..8ef98af20 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -6189,6 +6189,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #if defined(MBEDTLS_SSL_SRV_C) conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED; + conf->respect_cli_pref = MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_SERVER; #endif #if defined(MBEDTLS_SSL_PROTO_DTLS)