mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-07-02 20:42:25 +03:00
Keep track of whether mbedtls_ssl_set_hostname() has been called
Use a special marker as ssl->hostname if mbedtls_ssl_set_hostname() has been called with NULL. If mbedtls_ssl_set_hostname() has never been called, the field is NULL, as before. 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 <Gilles.Peskine@arm.com>
This commit is contained in:
@ -1409,6 +1409,10 @@ struct mbedtls_ssl_context {
|
|||||||
*
|
*
|
||||||
* If this is \p NULL, the peer name verification is skipped, and
|
* If this is \p NULL, the peer name verification is skipped, and
|
||||||
* the server_name extension is not sent.
|
* the server_name extension is not sent.
|
||||||
|
*
|
||||||
|
* This can be a special value to indicate that mbedtls_ssl_set_hostname()
|
||||||
|
* has been called with \p NULL, as opposed to never having been called.
|
||||||
|
* See mbedtls_ssl_get_hostname_pointer().
|
||||||
*/
|
*/
|
||||||
char *hostname;
|
char *hostname;
|
||||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||||
|
@ -40,6 +40,12 @@
|
|||||||
|
|
||||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||||
|
|
||||||
|
/* A magic value for `ssl->hostname` indicating that
|
||||||
|
* mbedtls_ssl_set_hostname() has been called with `NULL`.
|
||||||
|
* If mbedtls_ssl_set_hostname() has never been called on `ssl`, then
|
||||||
|
* `ssl->hostname == NULL`. */
|
||||||
|
static const char *const ssl_hostname_skip_cn_verification = "";
|
||||||
|
|
||||||
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
|
||||||
/** Whether mbedtls_ssl_set_hostname() has been called.
|
/** Whether mbedtls_ssl_set_hostname() has been called.
|
||||||
*
|
*
|
||||||
@ -52,11 +58,6 @@
|
|||||||
static int mbedtls_ssl_has_set_hostname_been_called(
|
static int mbedtls_ssl_has_set_hostname_been_called(
|
||||||
const mbedtls_ssl_context *ssl)
|
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->hostname != NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -68,12 +69,16 @@ static
|
|||||||
#endif
|
#endif
|
||||||
const char *mbedtls_ssl_get_hostname_pointer(const mbedtls_ssl_context *ssl)
|
const char *mbedtls_ssl_get_hostname_pointer(const mbedtls_ssl_context *ssl)
|
||||||
{
|
{
|
||||||
|
if (ssl->hostname == ssl_hostname_skip_cn_verification) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return ssl->hostname;
|
return ssl->hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mbedtls_ssl_free_hostname(mbedtls_ssl_context *ssl)
|
static void mbedtls_ssl_free_hostname(mbedtls_ssl_context *ssl)
|
||||||
{
|
{
|
||||||
if (ssl->hostname != NULL) {
|
if (ssl->hostname != NULL &&
|
||||||
|
ssl->hostname != ssl_hostname_skip_cn_verification) {
|
||||||
mbedtls_platform_zeroize(ssl->hostname, strlen(ssl->hostname));
|
mbedtls_platform_zeroize(ssl->hostname, strlen(ssl->hostname));
|
||||||
mbedtls_free(ssl->hostname);
|
mbedtls_free(ssl->hostname);
|
||||||
}
|
}
|
||||||
@ -99,13 +104,19 @@ int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname)
|
|||||||
* so we can free it safely */
|
* so we can free it safely */
|
||||||
mbedtls_ssl_free_hostname(ssl);
|
mbedtls_ssl_free_hostname(ssl);
|
||||||
|
|
||||||
/* Passing NULL as hostname shall clear the old one */
|
|
||||||
|
|
||||||
if (hostname == NULL) {
|
if (hostname == NULL) {
|
||||||
ssl->hostname = NULL;
|
/* Passing NULL as hostname clears the old one, but leaves a
|
||||||
|
* special marker to indicate that mbedtls_ssl_set_hostname()
|
||||||
|
* has been called. */
|
||||||
|
/* ssl->hostname should be const, but isn't. We won't actually
|
||||||
|
* write to the buffer, so it's ok to cast away the const. */
|
||||||
|
ssl->hostname = (char *) ssl_hostname_skip_cn_verification;
|
||||||
} else {
|
} else {
|
||||||
ssl->hostname = mbedtls_calloc(1, hostname_len + 1);
|
ssl->hostname = mbedtls_calloc(1, hostname_len + 1);
|
||||||
if (ssl->hostname == NULL) {
|
if (ssl->hostname == NULL) {
|
||||||
|
/* mbedtls_ssl_set_hostname() has been called, but unsuccessfully.
|
||||||
|
* Leave ssl->hostname in the same state as if the function had
|
||||||
|
* not been called, i.e. a null pointer. */
|
||||||
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
return MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4655,9 +4655,11 @@ run_test "Authentication: server goodcert, client required, no trusted CA" \
|
|||||||
|
|
||||||
run_test "Authentication: hostname match, client required" \
|
run_test "Authentication: hostname match, client required" \
|
||||||
"$P_SRV" \
|
"$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 \
|
0 \
|
||||||
-C "does not match with the expected CN" \
|
-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_verify_cert() returned -" \
|
||||||
-C "! mbedtls_ssl_handshake returned" \
|
-C "! mbedtls_ssl_handshake returned" \
|
||||||
-C "X509 - Certificate verification failed"
|
-C "X509 - Certificate verification failed"
|
||||||
@ -4709,7 +4711,7 @@ run_test "Authentication: hostname mismatch (trailing), client required" \
|
|||||||
|
|
||||||
run_test "Authentication: hostname mismatch, client optional" \
|
run_test "Authentication: hostname mismatch, client optional" \
|
||||||
"$P_SRV" \
|
"$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 \
|
0 \
|
||||||
-c "does not match with the expected CN" \
|
-c "does not match with the expected CN" \
|
||||||
-c "x509_verify_cert() returned -" \
|
-c "x509_verify_cert() returned -" \
|
||||||
@ -4717,75 +4719,93 @@ run_test "Authentication: hostname mismatch, client optional" \
|
|||||||
|
|
||||||
run_test "Authentication: hostname mismatch, client none" \
|
run_test "Authentication: hostname mismatch, client none" \
|
||||||
"$P_SRV" \
|
"$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 \
|
0 \
|
||||||
-C "does not match with the expected CN" \
|
-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_verify_cert() returned -" \
|
||||||
-C "X509 - Certificate verification failed"
|
-C "X509 - Certificate verification failed"
|
||||||
|
|
||||||
run_test "Authentication: hostname null, client required" \
|
run_test "Authentication: hostname null, client required" \
|
||||||
"$P_SRV" \
|
"$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 \
|
0 \
|
||||||
-C "does not match with the expected CN" \
|
-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_verify_cert() returned -" \
|
||||||
-C "! mbedtls_ssl_handshake returned" \
|
-C "! mbedtls_ssl_handshake returned" \
|
||||||
-C "X509 - Certificate verification failed"
|
-C "X509 - Certificate verification failed"
|
||||||
|
|
||||||
run_test "Authentication: hostname null, client optional" \
|
run_test "Authentication: hostname null, client optional" \
|
||||||
"$P_SRV" \
|
"$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 \
|
0 \
|
||||||
-C "does not match with the expected CN" \
|
-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_verify_cert() returned -" \
|
||||||
-C "X509 - Certificate verification failed"
|
-C "X509 - Certificate verification failed"
|
||||||
|
|
||||||
run_test "Authentication: hostname null, client none" \
|
run_test "Authentication: hostname null, client none" \
|
||||||
"$P_SRV" \
|
"$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 \
|
0 \
|
||||||
-C "does not match with the expected CN" \
|
-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_verify_cert() returned -" \
|
||||||
-C "X509 - Certificate verification failed"
|
-C "X509 - Certificate verification failed"
|
||||||
|
|
||||||
run_test "Authentication: hostname unset, client required" \
|
run_test "Authentication: hostname unset, client required" \
|
||||||
"$P_SRV" \
|
"$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 \
|
0 \
|
||||||
-C "does not match with the expected CN" \
|
-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_verify_cert() returned -" \
|
||||||
-C "! mbedtls_ssl_handshake returned" \
|
-C "! mbedtls_ssl_handshake returned" \
|
||||||
-C "X509 - Certificate verification failed"
|
-C "X509 - Certificate verification failed"
|
||||||
|
|
||||||
run_test "Authentication: hostname unset, client optional" \
|
run_test "Authentication: hostname unset, client optional" \
|
||||||
"$P_SRV" \
|
"$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 \
|
0 \
|
||||||
-C "does not match with the expected CN" \
|
-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_verify_cert() returned -" \
|
||||||
-C "X509 - Certificate verification failed"
|
-C "X509 - Certificate verification failed"
|
||||||
|
|
||||||
run_test "Authentication: hostname unset, client none" \
|
run_test "Authentication: hostname unset, client none" \
|
||||||
"$P_SRV" \
|
"$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 \
|
0 \
|
||||||
-C "does not match with the expected CN" \
|
-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_verify_cert() returned -" \
|
||||||
-C "X509 - Certificate verification failed"
|
-C "X509 - Certificate verification failed"
|
||||||
|
|
||||||
run_test "Authentication: hostname unset, client default, server picks cert" \
|
run_test "Authentication: hostname unset, client default, server picks cert" \
|
||||||
"$P_SRV force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \
|
"$P_SRV 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 \
|
0 \
|
||||||
-C "does not match with the expected CN" \
|
-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_verify_cert() returned -" \
|
||||||
-C "X509 - Certificate verification failed"
|
-C "X509 - Certificate verification failed"
|
||||||
|
|
||||||
run_test "Authentication: hostname unset, client default, server picks PSK" \
|
run_test "Authentication: hostname unset, client default, server picks PSK" \
|
||||||
"$P_SRV force_ciphersuite=TLS-PSK-WITH-AES-128-CCM-8 psk=73776f726466697368 psk_identity=foo" \
|
"$P_SRV 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 \
|
0 \
|
||||||
-C "does not match with the expected CN" \
|
-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_verify_cert() returned -" \
|
||||||
-C "X509 - Certificate verification failed"
|
-C "X509 - Certificate verification failed"
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user