Create configuration option to bypass the mbedtls_ssl_set_hostname check
Update generated files.
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index 84af7f7..9590dd3 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1713,6 +1713,46 @@
*/
//#define MBEDTLS_SSL_ASYNC_PRIVATE
+/** \def MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME
+ *
+ * In TLS clients, when a client authenticates a server through its
+ * certificate, the client normally checks three things:
+ * - the certificate chain must be valid;
+ * - the chain must start from a trusted CA;
+ * - the certificate must cover the server name that is expected by the client.
+ *
+ * Omitting any of these checks is generally insecure, and can allow a
+ * malicious server to impersonate a legitimate server.
+ *
+ * The third check may be safely skipped in some unusual scenarios,
+ * such as networks where eavesdropping is a risk but not active attacks,
+ * or a private PKI where the client equally trusts all servers that are
+ * accredited by the root CA.
+ *
+ * You should call mbedtls_ssl_set_hostname() with the expected server name
+ * before starting a TLS handshake on a client (unless the client is
+ * set up to only use PSK-based authentication, which does not rely on the
+ * host name). This configuration option controls what happens if a TLS client
+ * is configured with the authentication mode #MBEDTLS_SSL_VERIFY_REQUIRED
+ * (default), certificate authentication is enabled and the client does not
+ * call mbedtls_ssl_set_hostname():
+ *
+ * - If this option is unset (default), the connection attempt is aborted
+ * with the error #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME.
+ * - If this option is set, the TLS library does not check the server name
+ * that the certificate is valid for. This is the historical behavior
+ * of Mbed TLS, but may be insecure as explained above.
+ *
+ * Enable this option for strict backward compatibility if you have
+ * determined that it is secure in the scenario where you are using
+ * Mbed TLS.
+ *
+ * \deprecated This option exists only for backward compatibility and will
+ * be removed in the next major version of Mbed TLS.
+ *
+ */
+//#define MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME
+
/**
* \def MBEDTLS_SSL_CONTEXT_SERIALIZATION
*
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 4b3a67c..541b879 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -213,6 +213,9 @@
* #MBEDTLS_SSL_VERIFY_REQUIRED (default).
* - Certificate authentication is enabled.
* - The client does not call mbedtls_ssl_set_hostname().
+ * - The configuration option
+ * #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME
+ * is not enabled.
*/
#define MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME -0x5D80
diff --git a/library/error.c b/library/error.c
index dc75904..a0667e1 100644
--- a/library/error.c
+++ b/library/error.c
@@ -509,7 +509,7 @@
case -(MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND):
return( "SSL - Cache entry not found" );
case -(MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME):
- return( "SSL - Attempt to verify a certificate without an expected hostname. This is usually insecure. In TLS clients, when a client authenticates a server through its certificate, the client normally checks three things: - the certificate chain must be valid; - the chain must start from a trusted CA; - the certificate must cover the server name that is expected by the client. Omitting any of these checks is generally insecure, and can allow a malicious server to impersonate a legitimate server. The third check may be safely skipped in some unusual scenarios, such as networks where eavesdropping is a risk but not active attacks, or a private PKI where the client equally trusts all servers that are accredited by the root CA. You should call mbedtls_ssl_set_hostname() with the expected server name before starting a TLS handshake on a client (unless the client is set up to only use PSK-based authentication, which does not rely on the host name). If you have determined that server name verification is not required for security in your scenario, call mbedtls_ssl_set_hostname() with \\p NULL as the server name. This error is raised if all of the following conditions are met: - A TLS client is configured with the authentication mode #MBEDTLS_SSL_VERIFY_REQUIRED (default). - Certificate authentication is enabled. - The client does not call mbedtls_ssl_set_hostname()" );
+ return( "SSL - Attempt to verify a certificate without an expected hostname. This is usually insecure. In TLS clients, when a client authenticates a server through its certificate, the client normally checks three things: - the certificate chain must be valid; - the chain must start from a trusted CA; - the certificate must cover the server name that is expected by the client. Omitting any of these checks is generally insecure, and can allow a malicious server to impersonate a legitimate server. The third check may be safely skipped in some unusual scenarios, such as networks where eavesdropping is a risk but not active attacks, or a private PKI where the client equally trusts all servers that are accredited by the root CA. You should call mbedtls_ssl_set_hostname() with the expected server name before starting a TLS handshake on a client (unless the client is set up to only use PSK-based authentication, which does not rely on the host name). If you have determined that server name verification is not required for security in your scenario, call mbedtls_ssl_set_hostname() with \\p NULL as the server name. This error is raised if all of the following conditions are met: - A TLS client is configured with the authentication mode #MBEDTLS_SSL_VERIFY_REQUIRED (default). - Certificate authentication is enabled. - The client does not call mbedtls_ssl_set_hostname(). - The configuration option #MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME is not enabled" );
#endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
diff --git a/library/version_features.c b/library/version_features.c
index 6f663b1..f5734c4 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -486,6 +486,9 @@
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
"MBEDTLS_SSL_ASYNC_PRIVATE",
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+#if defined(MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME)
+ "MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME",
+#endif /* MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME */
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
"MBEDTLS_SSL_CONTEXT_SERIALIZATION",
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
diff --git a/programs/test/query_config.c b/programs/test/query_config.c
index 5d9886b..d09b7f6 100644
--- a/programs/test/query_config.c
+++ b/programs/test/query_config.c
@@ -1376,6 +1376,14 @@
}
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+#if defined(MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME)
+ if( strcmp( "MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME );
+ return( 0 );
+ }
+#endif /* MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME */
+
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
if( strcmp( "MBEDTLS_SSL_CONTEXT_SERIALIZATION", config ) == 0 )
{
@@ -3506,6 +3514,10 @@
OUTPUT_MACRO_NAME_VALUE(MBEDTLS_SSL_ASYNC_PRIVATE);
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+#if defined(MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME)
+ OUTPUT_MACRO_NAME_VALUE(MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME);
+#endif /* MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME */
+
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
OUTPUT_MACRO_NAME_VALUE(MBEDTLS_SSL_CONTEXT_SERIALIZATION);
#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
diff --git a/scripts/config.py b/scripts/config.py
index 766b5af..ef72db3 100755
--- a/scripts/config.py
+++ b/scripts/config.py
@@ -326,6 +326,7 @@
DEPRECATED = frozenset([
'MBEDTLS_SSL_PROTO_SSL3',
+ 'MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME',
'MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO',
])
diff --git a/tests/suites/test_suite_config.mbedtls_boolean.data b/tests/suites/test_suite_config.mbedtls_boolean.data
index 1a1d13f..718bd28 100644
--- a/tests/suites/test_suite_config.mbedtls_boolean.data
+++ b/tests/suites/test_suite_config.mbedtls_boolean.data
@@ -1264,6 +1264,14 @@
depends_on:!MBEDTLS_SSL_CBC_RECORD_SPLITTING:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C
pass:
+Config: MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME
+depends_on:MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C
+pass:
+
+Config: !MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME
+depends_on:!MBEDTLS_SSL_CLI_ALLOW_WEAK_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C
+pass:
+
Config: MBEDTLS_SSL_CLI_C
depends_on:MBEDTLS_SSL_CLI_C
pass: