From 434016e2eb6812be245277ceda39a56713be284c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 20 Feb 2025 18:49:59 +0100 Subject: [PATCH] Keep track of whether mbedtls_ssl_set_hostname() has been called No behavior change apart from now emitting a different log message depending on whether mbedtls_ssl_set_hostname() has been called with NULL or not at all. Signed-off-by: Gilles Peskine --- include/mbedtls/ssl.h | 2 ++ library/ssl_misc.h | 6 ++++++ library/ssl_tls.c | 9 +++----- tests/ssl-opt.sh | 50 ++++++++++++++++++++++++++++++++----------- 4 files changed, 48 insertions(+), 19 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 7c3a3d9433..fa46fa7451 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1671,6 +1671,8 @@ struct mbedtls_ssl_context { int MBEDTLS_PRIVATE(state); /*!< SSL handshake: current state */ /** Mask of `MBEDTLS_SSL_CONTEXT_FLAG_XXX`. + * See `mbedtls_ssl_context_flags_t` in ssl_misc.h. + * * This field is not saved by mbedtls_ssl_session_save(). */ uint32_t MBEDTLS_PRIVATE(flags); diff --git a/library/ssl_misc.h b/library/ssl_misc.h index 9f91861f64..2d54172818 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -51,6 +51,12 @@ extern const mbedtls_error_pair_t psa_to_ssl_errors[7]; #define MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED #endif +/** Flag values for mbedtls_ssl_context::flags. */ +typedef enum { + /** Set if mbedtls_ssl_set_hostname() has been called. */ + MBEDTLS_SSL_CONTEXT_FLAG_HOSTNAME_SET = 1, +} mbedtls_ssl_context_flags_t; + #define MBEDTLS_SSL_INITIAL_HANDSHAKE 0 #define MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS 1 /* In progress */ #define MBEDTLS_SSL_RENEGOTIATION_DONE 2 /* Done or aborted */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index dd1beb98b7..998cac2ce4 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -2529,12 +2529,7 @@ void mbedtls_ssl_conf_groups(mbedtls_ssl_config *conf, static int mbedtls_ssl_has_set_hostname_been_called( const mbedtls_ssl_context *ssl) { - /* We can't tell the difference between the case where - * mbedtls_ssl_set_hostname() has not been called at all, and - * the case where it was last called with NULL. For the time - * being, we assume the latter, i.e. we behave as if there had - * been an implicit call to mbedtls_ssl_set_hostname(ssl, NULL). */ - return ssl->hostname != NULL; + return (ssl->flags & MBEDTLS_SSL_CONTEXT_FLAG_HOSTNAME_SET) != 0; } #endif @@ -2580,6 +2575,8 @@ int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname) ssl->hostname[hostname_len] = '\0'; } + ssl->flags |= MBEDTLS_SSL_CONTEXT_FLAG_HOSTNAME_SET; + return 0; } #endif /* MBEDTLS_X509_CRT_PARSE_C */ diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index e541a81983..ecff16ec8d 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -5943,9 +5943,11 @@ run_test "Authentication: server goodcert, client none, no trusted CA (1.2)" run_test "Authentication: hostname match, client required" \ "$P_SRV" \ - "$P_CLI auth_mode=required server_name=localhost debug_level=1" \ + "$P_CLI auth_mode=required server_name=localhost debug_level=2" \ 0 \ -C "does not match with the expected CN" \ + -C "Certificate verification without having set hostname" \ + -C "Certificate verification without CN verification" \ -C "x509_verify_cert() returned -" \ -C "! mbedtls_ssl_handshake returned" \ -C "X509 - Certificate verification failed" @@ -5997,7 +5999,7 @@ run_test "Authentication: hostname mismatch (trailing), client required" \ run_test "Authentication: hostname mismatch, client optional" \ "$P_SRV" \ - "$P_CLI auth_mode=optional server_name=wrong-name debug_level=1" \ + "$P_CLI auth_mode=optional server_name=wrong-name debug_level=2" \ 0 \ -c "does not match with the expected CN" \ -c "x509_verify_cert() returned -" \ @@ -6005,93 +6007,115 @@ run_test "Authentication: hostname mismatch, client optional" \ run_test "Authentication: hostname mismatch, client none" \ "$P_SRV" \ - "$P_CLI auth_mode=none server_name=wrong-name debug_level=1" \ + "$P_CLI auth_mode=none server_name=wrong-name debug_level=2" \ 0 \ -C "does not match with the expected CN" \ + -C "Certificate verification without having set hostname" \ + -C "Certificate verification without CN verification" \ -C "x509_verify_cert() returned -" \ -C "X509 - Certificate verification failed" run_test "Authentication: hostname null, client required" \ "$P_SRV" \ - "$P_CLI auth_mode=required set_hostname=NULL debug_level=1" \ + "$P_CLI auth_mode=required set_hostname=NULL debug_level=2" \ 0 \ -C "does not match with the expected CN" \ + -C "Certificate verification without having set hostname" \ + -c "Certificate verification without CN verification" \ -C "x509_verify_cert() returned -" \ -C "! mbedtls_ssl_handshake returned" \ -C "X509 - Certificate verification failed" run_test "Authentication: hostname null, client optional" \ "$P_SRV" \ - "$P_CLI auth_mode=optional set_hostname=NULL debug_level=1" \ + "$P_CLI auth_mode=optional set_hostname=NULL debug_level=2" \ 0 \ -C "does not match with the expected CN" \ + -C "Certificate verification without having set hostname" \ + -c "Certificate verification without CN verification" \ -C "x509_verify_cert() returned -" \ -C "X509 - Certificate verification failed" run_test "Authentication: hostname null, client none" \ "$P_SRV" \ - "$P_CLI auth_mode=none set_hostname=NULL debug_level=1" \ + "$P_CLI auth_mode=none set_hostname=NULL debug_level=2" \ 0 \ -C "does not match with the expected CN" \ + -C "Certificate verification without having set hostname" \ + -C "Certificate verification without CN verification" \ -C "x509_verify_cert() returned -" \ -C "X509 - Certificate verification failed" run_test "Authentication: hostname unset, client required" \ "$P_SRV" \ - "$P_CLI auth_mode=required set_hostname=no debug_level=1" \ + "$P_CLI auth_mode=required set_hostname=no debug_level=2" \ 0 \ -C "does not match with the expected CN" \ + -c "Certificate verification without having set hostname" \ + -c "Certificate verification without CN verification" \ -C "x509_verify_cert() returned -" \ -C "! mbedtls_ssl_handshake returned" \ -C "X509 - Certificate verification failed" run_test "Authentication: hostname unset, client optional" \ "$P_SRV" \ - "$P_CLI auth_mode=optional set_hostname=no debug_level=1" \ + "$P_CLI auth_mode=optional set_hostname=no debug_level=2" \ 0 \ -C "does not match with the expected CN" \ + -c "Certificate verification without having set hostname" \ + -c "Certificate verification without CN verification" \ -C "x509_verify_cert() returned -" \ -C "X509 - Certificate verification failed" run_test "Authentication: hostname unset, client none" \ "$P_SRV" \ - "$P_CLI auth_mode=none set_hostname=no debug_level=1" \ + "$P_CLI auth_mode=none set_hostname=no debug_level=2" \ 0 \ -C "does not match with the expected CN" \ + -C "Certificate verification without having set hostname" \ + -C "Certificate verification without CN verification" \ -C "x509_verify_cert() returned -" \ -C "X509 - Certificate verification failed" run_test "Authentication: hostname unset, client default, server picks cert, 1.2" \ "$P_SRV force_version=tls12 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \ - "$P_CLI psk=73776f726466697368 psk_identity=foo set_hostname=no debug_level=1" \ + "$P_CLI psk=73776f726466697368 psk_identity=foo set_hostname=no debug_level=2" \ 0 \ -C "does not match with the expected CN" \ + -c "Certificate verification without having set hostname" \ + -c "Certificate verification without CN verification" \ -C "x509_verify_cert() returned -" \ -C "X509 - Certificate verification failed" requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED run_test "Authentication: hostname unset, client default, server picks cert, 1.3" \ "$P_SRV force_version=tls13 tls13_kex_modes=ephemeral" \ - "$P_CLI psk=73776f726466697368 psk_identity=foo set_hostname=no debug_level=1" \ + "$P_CLI psk=73776f726466697368 psk_identity=foo set_hostname=no debug_level=2" \ 0 \ -C "does not match with the expected CN" \ + -c "Certificate verification without having set hostname" \ + -c "Certificate verification without CN verification" \ -C "x509_verify_cert() returned -" \ -C "X509 - Certificate verification failed" run_test "Authentication: hostname unset, client default, server picks PSK, 1.2" \ "$P_SRV force_version=tls12 force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8 psk=73776f726466697368 psk_identity=foo" \ - "$P_CLI psk=73776f726466697368 psk_identity=foo set_hostname=no debug_level=1" \ + "$P_CLI psk=73776f726466697368 psk_identity=foo set_hostname=no debug_level=2" \ 0 \ -C "does not match with the expected CN" \ + -C "Certificate verification without having set hostname" \ + -C "Certificate verification without CN verification" \ -C "x509_verify_cert() returned -" \ -C "X509 - Certificate verification failed" requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED run_test "Authentication: hostname unset, client default, server picks PSK, 1.3" \ "$P_SRV force_version=tls13 tls13_kex_modes=psk psk=73776f726466697368 psk_identity=foo" \ - "$P_CLI psk=73776f726466697368 psk_identity=foo set_hostname=no debug_level=1" \ + "$P_CLI psk=73776f726466697368 psk_identity=foo set_hostname=no debug_level=2" \ 0 \ -C "does not match with the expected CN" \ + -C "Certificate verification without having set hostname" \ + -C "Certificate verification without CN verification" \ -C "x509_verify_cert() returned -" \ -C "X509 - Certificate verification failed"