diff --git a/ChangeLog.d/mbedtls_ssl_set_hostname.txt b/ChangeLog.d/mbedtls_ssl_set_hostname.txt new file mode 100644 index 0000000000..250a5baafa --- /dev/null +++ b/ChangeLog.d/mbedtls_ssl_set_hostname.txt @@ -0,0 +1,16 @@ +Default behavior changes + * In TLS clients, if mbedtls_ssl_set_hostname() has not been called, + mbedtls_ssl_handshake() now fails with + MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME + if certificate-based authentication of the server is attempted. + This is because authenticating a server without knowing what name + to expect is usually insecure. + +Security + * Note that TLS clients should generally call mbedtls_ssl_set_hostname() + if they use certificate authentication (i.e. not pre-shared keys). + Otherwise, in many scenarios, the server could be impersonated. + The library will now prevent the handshake and return + MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME + if mbedtls_ssl_set_hostname() has not been called. + Reported by Daniel Stenberg. diff --git a/ChangeLog.d/tls12-check-finished-calc.txt b/ChangeLog.d/tls12-check-finished-calc.txt new file mode 100644 index 0000000000..cd52d32ffd --- /dev/null +++ b/ChangeLog.d/tls12-check-finished-calc.txt @@ -0,0 +1,6 @@ +Security + * Fix a vulnerability in the TLS 1.2 handshake. If memory allocation failed + or there was a cryptographic hardware failure when calculating the + Finished message, it could be calculated incorrectly. This would break + the security guarantees of the TLS handshake. + CVE-2025-27810 diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 9a02a6a8c2..e724aa232a 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -165,6 +165,39 @@ #define MBEDTLS_ERR_SSL_VERSION_MISMATCH -0x5F00 /** Invalid value in SSL config */ #define MBEDTLS_ERR_SSL_BAD_CONFIG -0x5E80 +/* Error space gap */ +/** 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(). + */ +#define MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME -0x5D80 /* * Constants from RFC 8446 for TLS 1.3 PSK modes @@ -1222,8 +1255,8 @@ struct mbedtls_ssl_session { #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION && MBEDTLS_SSL_CLI_C */ #if defined(MBEDTLS_SSL_EARLY_DATA) && defined(MBEDTLS_SSL_ALPN) && defined(MBEDTLS_SSL_SRV_C) - char *ticket_alpn; /*!< ALPN negotiated in the session - during which the ticket was generated. */ + char *MBEDTLS_PRIVATE(ticket_alpn); /*!< ALPN negotiated in the session + during which the ticket was generated. */ #endif #if defined(MBEDTLS_HAVE_TIME) && defined(MBEDTLS_SSL_CLI_C) @@ -1582,6 +1615,14 @@ struct mbedtls_ssl_context { * Miscellaneous */ 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); + #if defined(MBEDTLS_SSL_RENEGOTIATION) int MBEDTLS_PRIVATE(renego_status); /*!< Initial, in progress, pending? */ int MBEDTLS_PRIVATE(renego_records_seen); /*!< Records since renego request, or with DTLS, @@ -1889,6 +1930,17 @@ void mbedtls_ssl_init(mbedtls_ssl_context *ssl); * \note The PSA crypto subsystem must have been initialized by * calling psa_crypto_init() before calling this function. * + * \note After setting up a client context, if certificate-based + * authentication is enabled, you should call + * mbedtls_ssl_set_hostname() to specifiy the expected + * name of the server. Otherwise, if server authentication + * is required (which is the case by default) and the + * selected key exchange involves a certificate (i.e. is not + * based on a pre-shared key), the certificate authentication + * will fail. See + * #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME + * for more information. + * * \param ssl SSL context * \param conf SSL configuration to use * @@ -3738,16 +3790,29 @@ void mbedtls_ssl_conf_sig_algs(mbedtls_ssl_config *conf, #if defined(MBEDTLS_X509_CRT_PARSE_C) /** * \brief Set or reset the hostname to check against the received - * server certificate. It sets the ServerName TLS extension, - * too, if that extension is enabled. (client-side only) + * peer certificate. On a client, this also sets the + * ServerName TLS extension, if that extension is enabled. + * On a TLS 1.3 client, this also sets the server name in + * the session resumption ticket, if that feature is enabled. * * \param ssl SSL context - * \param hostname the server hostname, may be NULL to clear hostname - - * \note Maximum hostname length MBEDTLS_SSL_MAX_HOST_NAME_LEN. + * \param hostname The server hostname. This may be \c NULL to clear + * the hostname. * - * \return 0 if successful, MBEDTLS_ERR_SSL_ALLOC_FAILED on - * allocation failure, MBEDTLS_ERR_SSL_BAD_INPUT_DATA on + * \note Maximum hostname length #MBEDTLS_SSL_MAX_HOST_NAME_LEN. + * + * \note If the hostname is \c NULL on a client, then the server + * is not authenticated: it only needs to have a valid + * certificate, not a certificate matching its name. + * Therefore you should always call this function on a client, + * unless the connection is set up to only allow + * pre-shared keys, or in scenarios where server + * impersonation is not a concern. See the documentation of + * #MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME + * for more details. + * + * \return 0 if successful, #MBEDTLS_ERR_SSL_ALLOC_FAILED on + * allocation failure, #MBEDTLS_ERR_SSL_BAD_INPUT_DATA on * too long input hostname. * * Hostname set to the one provided on success (cleared diff --git a/library/ssl_misc.h b/library/ssl_misc.h index e51a3df5ed..de8e0dae23 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -51,6 +51,22 @@ 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; + +/** Flags from ::mbedtls_ssl_context_flags_t to keep in + * mbedtls_ssl_session_reset(). + * + * The flags that are in this list are kept until explicitly updated or + * until mbedtls_ssl_free(). The flags that are not listed here are + * reset to 0 in mbedtls_ssl_session_reset(). + */ +#define MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION \ + (MBEDTLS_SSL_CONTEXT_FLAG_HOSTNAME_SET) + #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 94de3430cc..5a668a4660 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1410,6 +1410,7 @@ int mbedtls_ssl_session_reset_int(mbedtls_ssl_context *ssl, int partial) int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; ssl->state = MBEDTLS_SSL_HELLO_REQUEST; + ssl->flags &= MBEDTLS_SSL_CONTEXT_FLAGS_KEEP_AT_SESSION; ssl->tls_version = ssl->conf->max_tls_version; mbedtls_ssl_session_reset_msg_layer(ssl, partial); @@ -2455,6 +2456,31 @@ void mbedtls_ssl_conf_groups(mbedtls_ssl_config *conf, } #if defined(MBEDTLS_X509_CRT_PARSE_C) + +#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) +/** Whether mbedtls_ssl_set_hostname() has been called. + * + * \param[in] ssl SSL context + * + * \return \c 1 if mbedtls_ssl_set_hostname() has been called on \p ssl + * (including `mbedtls_ssl_set_hostname(ssl, NULL)`), + * otherwise \c 0. + */ +static int mbedtls_ssl_has_set_hostname_been_called( + const mbedtls_ssl_context *ssl) +{ + return (ssl->flags & MBEDTLS_SSL_CONTEXT_FLAG_HOSTNAME_SET) != 0; +} +#endif + +static void mbedtls_ssl_free_hostname(mbedtls_ssl_context *ssl) +{ + if (ssl->hostname != NULL) { + mbedtls_zeroize_and_free(ssl->hostname, strlen(ssl->hostname)); + } + ssl->hostname = NULL; +} + int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname) { /* Initialize to suppress unnecessary compiler warning */ @@ -2472,10 +2498,7 @@ int mbedtls_ssl_set_hostname(mbedtls_ssl_context *ssl, const char *hostname) /* Now it's clear that we will overwrite the old hostname, * so we can free it safely */ - - if (ssl->hostname != NULL) { - mbedtls_zeroize_and_free(ssl->hostname, strlen(ssl->hostname)); - } + mbedtls_ssl_free_hostname(ssl); /* Passing NULL as hostname shall clear the old one */ @@ -2492,6 +2515,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 */ @@ -5229,9 +5254,7 @@ void mbedtls_ssl_free(mbedtls_ssl_context *ssl) } #if defined(MBEDTLS_X509_CRT_PARSE_C) - if (ssl->hostname != NULL) { - mbedtls_zeroize_and_free(ssl->hostname, strlen(ssl->hostname)); - } + mbedtls_ssl_free_hostname(ssl); #endif #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) @@ -7454,6 +7477,7 @@ int mbedtls_ssl_write_finished(mbedtls_ssl_context *ssl) ret = ssl->handshake->calc_finished(ssl, ssl->out_msg + 4, ssl->conf->endpoint); if (ret != 0) { MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret); + return ret; } /* @@ -7567,6 +7591,7 @@ int mbedtls_ssl_parse_finished(mbedtls_ssl_context *ssl) ret = ssl->handshake->calc_finished(ssl, buf, ssl->conf->endpoint ^ 1); if (ret != 0) { MBEDTLS_SSL_DEBUG_RET(1, "calc_finished", ret); + return ret; } if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { @@ -8747,6 +8772,25 @@ int mbedtls_ssl_check_cert_usage(const mbedtls_x509_crt *cert, return ret; } +static int get_hostname_for_verification(mbedtls_ssl_context *ssl, + const char **hostname) +{ + if (!mbedtls_ssl_has_set_hostname_been_called(ssl)) { + MBEDTLS_SSL_DEBUG_MSG(1, ("Certificate verification without having set hostname")); + if (mbedtls_ssl_conf_get_endpoint(ssl->conf) == MBEDTLS_SSL_IS_CLIENT && + ssl->conf->authmode == MBEDTLS_SSL_VERIFY_REQUIRED) { + return MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME; + } + } + + *hostname = ssl->hostname; + if (*hostname == NULL) { + MBEDTLS_SSL_DEBUG_MSG(2, ("Certificate verification without CN verification")); + } + + return 0; +} + int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl, int authmode, mbedtls_x509_crt *chain, @@ -8772,7 +8816,13 @@ int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl, p_vrfy = ssl->conf->p_vrfy; } - int ret = 0; + const char *hostname = ""; + int ret = get_hostname_for_verification(ssl, &hostname); + if (ret != 0) { + MBEDTLS_SSL_DEBUG_RET(1, "get_hostname_for_verification", ret); + return ret; + } + int have_ca_chain_or_callback = 0; #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK) if (ssl->conf->f_ca_cb != NULL) { @@ -8785,7 +8835,7 @@ int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl, ssl->conf->f_ca_cb, ssl->conf->p_ca_cb, ssl->conf->cert_profile, - ssl->hostname, + hostname, &ssl->session_negotiate->verify_result, f_vrfy, p_vrfy); } else @@ -8812,7 +8862,7 @@ int mbedtls_ssl_verify_certificate(mbedtls_ssl_context *ssl, chain, ca_chain, ca_crl, ssl->conf->cert_profile, - ssl->hostname, + hostname, &ssl->session_negotiate->verify_result, f_vrfy, p_vrfy, rs_ctx); } diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 6a5fca57de..1f58651710 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -68,6 +68,7 @@ int main(void) #define DFL_MAX_VERSION -1 #define DFL_SHA1 -1 #define DFL_AUTH_MODE -1 +#define DFL_SET_HOSTNAME 1 #define DFL_MFL_CODE MBEDTLS_SSL_MAX_FRAG_LEN_NONE #define DFL_TRUNC_HMAC -1 #define DFL_RECSPLIT -1 @@ -397,6 +398,9 @@ int main(void) #define USAGE2 \ " auth_mode=%%s default: (library default: none)\n" \ " options: none, optional, required\n" \ + " set_hostname=%%s call mbedtls_ssl_set_hostname()?" \ + " options: no, server_name, NULL\n" \ + " default: server_name (but ignored if certs disabled)\n" \ USAGE_IO \ USAGE_KEY_OPAQUE \ USAGE_CA_CALLBACK \ @@ -498,6 +502,8 @@ struct options { int max_version; /* maximum protocol version accepted */ int allow_sha1; /* flag for SHA-1 support */ int auth_mode; /* verify mode for connection */ + int set_hostname; /* call mbedtls_ssl_set_hostname()? */ + /* 0=no, 1=yes, -1=NULL */ unsigned char mfl_code; /* code for maximum fragment length */ int trunc_hmac; /* negotiate truncated hmac or not */ int recsplit; /* enable record splitting? */ @@ -946,6 +952,7 @@ int main(int argc, char *argv[]) opt.max_version = DFL_MAX_VERSION; opt.allow_sha1 = DFL_SHA1; opt.auth_mode = DFL_AUTH_MODE; + opt.set_hostname = DFL_SET_HOSTNAME; opt.mfl_code = DFL_MFL_CODE; opt.trunc_hmac = DFL_TRUNC_HMAC; opt.recsplit = DFL_RECSPLIT; @@ -1338,6 +1345,16 @@ usage: } else { goto usage; } + } else if (strcmp(p, "set_hostname") == 0) { + if (strcmp(q, "no") == 0) { + opt.set_hostname = 0; + } else if (strcmp(q, "server_name") == 0) { + opt.set_hostname = 1; + } else if (strcmp(q, "NULL") == 0) { + opt.set_hostname = -1; + } else { + goto usage; + } } else if (strcmp(p, "max_frag_len") == 0) { if (strcmp(q, "512") == 0) { opt.mfl_code = MBEDTLS_SSL_MAX_FRAG_LEN_512; @@ -2037,10 +2054,24 @@ usage: #endif /* MBEDTLS_SSL_DTLS_SRTP */ #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) - if ((ret = mbedtls_ssl_set_hostname(&ssl, opt.server_name)) != 0) { - mbedtls_printf(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", - ret); - goto exit; + switch (opt.set_hostname) { + case -1: + if ((ret = mbedtls_ssl_set_hostname(&ssl, NULL)) != 0) { + mbedtls_printf(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", + ret); + goto exit; + } + break; + case 0: + /* Skip the call */ + break; + default: + if ((ret = mbedtls_ssl_set_hostname(&ssl, opt.server_name)) != 0) { + mbedtls_printf(" failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", + ret); + goto exit; + } + break; } #endif diff --git a/programs/ssl/ssl_test_common_source.c b/programs/ssl/ssl_test_common_source.c index 354e97ef90..e194b58dff 100644 --- a/programs/ssl/ssl_test_common_source.c +++ b/programs/ssl/ssl_test_common_source.c @@ -316,7 +316,6 @@ uint16_t ssl_sig_algs_for_test[] = { #endif /* MBEDTLS_X509_CRT_PARSE_C */ #if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED) -#if defined(MBEDTLS_X509_CRT_PARSE_C) /** Functionally equivalent to mbedtls_x509_crt_verify_info, see that function * for more info. */ @@ -351,7 +350,6 @@ static int x509_crt_verify_info(char *buf, size_t size, const char *prefix, return (int) (size - n); #endif /* MBEDTLS_X509_REMOVE_INFO */ } -#endif /* MBEDTLS_X509_CRT_PARSE_C */ static void mbedtls_print_supported_sig_algs(void) { diff --git a/tests/src/test_helpers/ssl_helpers.c b/tests/src/test_helpers/ssl_helpers.c index bffb35372b..91efd1c813 100644 --- a/tests/src/test_helpers/ssl_helpers.c +++ b/tests/src/test_helpers/ssl_helpers.c @@ -863,6 +863,10 @@ int mbedtls_test_ssl_endpoint_init( ret = mbedtls_ssl_setup(&(ep->ssl), &(ep->conf)); TEST_ASSERT(ret == 0); + if (MBEDTLS_SSL_IS_CLIENT == endpoint_type) { + ret = mbedtls_ssl_set_hostname(&(ep->ssl), "localhost"); + } + #if defined(MBEDTLS_SSL_PROTO_DTLS) && defined(MBEDTLS_SSL_SRV_C) if (endpoint_type == MBEDTLS_SSL_IS_SERVER && dtls_context != NULL) { mbedtls_ssl_conf_dtls_cookies(&(ep->conf), NULL, NULL, NULL); diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 0634c26a67..ac9b3bb1f0 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -475,6 +475,11 @@ detect_required_features() { requires_certificate_authentication;; esac + case " $CMD_LINE " in + *\ ca_callback=1\ *) + requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK;; + esac + case " $CMD_LINE " in *"programs/ssl/dtls_client "*|\ *"programs/ssl/ssl_client1 "*) @@ -2217,7 +2222,6 @@ run_test "TLS: password protected server key, two certificates" \ "$P_CLI" \ 0 -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "CA callback on client" \ "$P_SRV debug_level=3" \ "$P_CLI ca_callback=1 debug_level=3 " \ @@ -2226,7 +2230,6 @@ run_test "CA callback on client" \ -S "error" \ -C "error" -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK requires_config_enabled MBEDTLS_X509_CRT_PARSE_C requires_hash_alg SHA_256 run_test "CA callback on server" \ @@ -5893,6 +5896,215 @@ run_test "Authentication: server goodcert, client none, no trusted CA (1.2)" -C "X509 - Certificate verification failed" \ -C "SSL - No CA Chain is set, but required to operate" +# The next few tests check what happens if the server has a valid certificate +# that does not match its name (impersonation). + +run_test "Authentication: hostname match, client required" \ + "$P_SRV" \ + "$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" + +run_test "Authentication: hostname match, client required, CA callback" \ + "$P_SRV" \ + "$P_CLI auth_mode=required server_name=localhost debug_level=3 ca_callback=1" \ + 0 \ + -C "does not match with the expected CN" \ + -C "Certificate verification without having set hostname" \ + -C "Certificate verification without CN verification" \ + -c "use CA callback for X.509 CRT verification" \ + -C "x509_verify_cert() returned -" \ + -C "! mbedtls_ssl_handshake returned" \ + -C "X509 - Certificate verification failed" + +run_test "Authentication: hostname mismatch (wrong), client required" \ + "$P_SRV" \ + "$P_CLI auth_mode=required server_name=wrong-name debug_level=1" \ + 1 \ + -c "does not match with the expected CN" \ + -c "x509_verify_cert() returned -" \ + -c "! mbedtls_ssl_handshake returned" \ + -c "X509 - Certificate verification failed" + +run_test "Authentication: hostname mismatch (empty), client required" \ + "$P_SRV" \ + "$P_CLI auth_mode=required server_name= debug_level=1" \ + 1 \ + -c "does not match with the expected CN" \ + -c "x509_verify_cert() returned -" \ + -c "! mbedtls_ssl_handshake returned" \ + -c "X509 - Certificate verification failed" + +run_test "Authentication: hostname mismatch (truncated), client required" \ + "$P_SRV" \ + "$P_CLI auth_mode=required server_name=localhos debug_level=1" \ + 1 \ + -c "does not match with the expected CN" \ + -c "x509_verify_cert() returned -" \ + -c "! mbedtls_ssl_handshake returned" \ + -c "X509 - Certificate verification failed" + +run_test "Authentication: hostname mismatch (last char), client required" \ + "$P_SRV" \ + "$P_CLI auth_mode=required server_name=localhoss debug_level=1" \ + 1 \ + -c "does not match with the expected CN" \ + -c "x509_verify_cert() returned -" \ + -c "! mbedtls_ssl_handshake returned" \ + -c "X509 - Certificate verification failed" + +run_test "Authentication: hostname mismatch (trailing), client required" \ + "$P_SRV" \ + "$P_CLI auth_mode=required server_name=localhostt debug_level=1" \ + 1 \ + -c "does not match with the expected CN" \ + -c "x509_verify_cert() returned -" \ + -c "! mbedtls_ssl_handshake returned" \ + -c "X509 - Certificate verification failed" + +run_test "Authentication: hostname mismatch, client optional" \ + "$P_SRV" \ + "$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 -" \ + -C "X509 - Certificate verification failed" + +run_test "Authentication: hostname mismatch, client none" \ + "$P_SRV" \ + "$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=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=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=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=2" \ + 1 \ + -C "does not match with the expected CN" \ + -c "Certificate verification without having set hostname" \ + -C "Certificate verification without CN verification" \ + -c "get_hostname_for_verification() returned -" \ + -C "x509_verify_cert() returned -" \ + -c "! mbedtls_ssl_handshake returned" \ + -C "X509 - Certificate verification failed" + +run_test "Authentication: hostname unset, client required, CA callback" \ + "$P_SRV" \ + "$P_CLI auth_mode=required set_hostname=no debug_level=3 ca_callback=1" \ + 1 \ + -C "does not match with the expected CN" \ + -c "Certificate verification without having set hostname" \ + -C "Certificate verification without CN verification" \ + -c "get_hostname_for_verification() returned -" \ + -C "use CA callback for X.509 CRT 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=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=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=2" \ + 1 \ + -C "does not match with the expected CN" \ + -c "Certificate verification without having set hostname" \ + -C "Certificate verification without CN verification" \ + -c "get_hostname_for_verification() returned -" \ + -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=2" \ + 1 \ + -C "does not match with the expected CN" \ + -c "Certificate verification without having set hostname" \ + -C "Certificate verification without CN verification" \ + -c "get_hostname_for_verification() returned -" \ + -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=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=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" + # The purpose of the next two tests is to test the client's behaviour when receiving a server # certificate with an unsupported elliptic curve. This should usually not happen because # the client informs the server about the supported curves - it does, though, in the @@ -6237,7 +6449,6 @@ run_test "Authentication: send alt hs DN hints in CertificateRequest" \ # Tests for auth_mode, using CA callback, these are duplicated from the authentication tests # When updating these tests, modify the matching authentication tests accordingly -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: server badcert, client required" \ "$P_SRV crt_file=$DATA_FILES_PATH/server5-badsign.crt \ key_file=$DATA_FILES_PATH/server5.key" \ @@ -6249,7 +6460,6 @@ run_test "Authentication, CA callback: server badcert, client required" \ -c "! mbedtls_ssl_handshake returned" \ -c "X509 - Certificate verification failed" -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: server badcert, client optional" \ "$P_SRV crt_file=$DATA_FILES_PATH/server5-badsign.crt \ key_file=$DATA_FILES_PATH/server5.key" \ @@ -6261,7 +6471,6 @@ run_test "Authentication, CA callback: server badcert, client optional" \ -C "! mbedtls_ssl_handshake returned" \ -C "X509 - Certificate verification failed" -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: server badcert, client none" \ "$P_SRV crt_file=$DATA_FILES_PATH/server5-badsign.crt \ key_file=$DATA_FILES_PATH/server5.key" \ @@ -6280,7 +6489,6 @@ run_test "Authentication, CA callback: server badcert, client none" \ # occasion (to be fixed). If that bug's fixed, the test needs to be altered to use a # different means to have the server ignoring the client's supported curve list. -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: server ECDH p256v1, client required, p256v1 unsupported" \ "$P_SRV debug_level=1 key_file=$DATA_FILES_PATH/server5.key \ crt_file=$DATA_FILES_PATH/server5.ku-ka.crt" \ @@ -6291,7 +6499,6 @@ run_test "Authentication, CA callback: server ECDH p256v1, client required, p -c "! Certificate verification flags" \ -C "bad server certificate (ECDH curve)" # Expect failure at earlier verification stage -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: server ECDH p256v1, client optional, p256v1 unsupported" \ "$P_SRV debug_level=1 key_file=$DATA_FILES_PATH/server5.key \ crt_file=$DATA_FILES_PATH/server5.ku-ka.crt" \ @@ -6302,7 +6509,6 @@ run_test "Authentication, CA callback: server ECDH p256v1, client optional, p -c "! Certificate verification flags"\ -c "bad server certificate (ECDH curve)" # Expect failure only at ECDH params check -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT run_test "Authentication, CA callback: client SHA384, server required" \ "$P_SRV ca_callback=1 debug_level=3 auth_mode=required" \ @@ -6314,7 +6520,6 @@ run_test "Authentication, CA callback: client SHA384, server required" \ -c "Supported Signature Algorithm found: 04 " \ -c "Supported Signature Algorithm found: 05 " -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK requires_any_configs_enabled $TLS1_2_KEY_EXCHANGES_WITH_CERT run_test "Authentication, CA callback: client SHA256, server required" \ "$P_SRV ca_callback=1 debug_level=3 auth_mode=required" \ @@ -6326,7 +6531,6 @@ run_test "Authentication, CA callback: client SHA256, server required" \ -c "Supported Signature Algorithm found: 04 " \ -c "Supported Signature Algorithm found: 05 " -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: client badcert, server required" \ "$P_SRV ca_callback=1 debug_level=3 auth_mode=required" \ "$P_CLI debug_level=3 crt_file=$DATA_FILES_PATH/server5-badsign.crt \ @@ -6348,7 +6552,6 @@ run_test "Authentication, CA callback: client badcert, server required" \ # detect that its write end of the connection is closed and abort # before reading the alert message. -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: client cert not trusted, server required" \ "$P_SRV ca_callback=1 debug_level=3 auth_mode=required" \ "$P_CLI debug_level=3 crt_file=$DATA_FILES_PATH/server5-selfsigned.crt \ @@ -6366,7 +6569,6 @@ run_test "Authentication, CA callback: client cert not trusted, server requir -s "! mbedtls_ssl_handshake returned" \ -s "X509 - Certificate verification failed" -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: client badcert, server optional" \ "$P_SRV ca_callback=1 debug_level=3 auth_mode=optional" \ "$P_CLI debug_level=3 crt_file=$DATA_FILES_PATH/server5-badsign.crt \ @@ -6387,7 +6589,6 @@ run_test "Authentication, CA callback: client badcert, server optional" \ requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA requires_full_size_output_buffer -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: server max_int chain, client default" \ "$P_SRV crt_file=$DATA_FILES_PATH/dir-maxpath/c09.pem \ key_file=$DATA_FILES_PATH/dir-maxpath/09.key" \ @@ -6398,7 +6599,6 @@ run_test "Authentication, CA callback: server max_int chain, client default" requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA requires_full_size_output_buffer -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: server max_int+1 chain, client default" \ "$P_SRV crt_file=$DATA_FILES_PATH/dir-maxpath/c10.pem \ key_file=$DATA_FILES_PATH/dir-maxpath/10.key" \ @@ -6409,7 +6609,6 @@ run_test "Authentication, CA callback: server max_int+1 chain, client default requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA requires_full_size_output_buffer -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: server max_int+1 chain, client optional" \ "$P_SRV crt_file=$DATA_FILES_PATH/dir-maxpath/c10.pem \ key_file=$DATA_FILES_PATH/dir-maxpath/10.key" \ @@ -6421,7 +6620,6 @@ run_test "Authentication, CA callback: server max_int+1 chain, client optiona requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA requires_full_size_output_buffer -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: client max_int+1 chain, server optional" \ "$P_SRV ca_callback=1 debug_level=3 ca_file=$DATA_FILES_PATH/dir-maxpath/00.crt auth_mode=optional" \ "$P_CLI crt_file=$DATA_FILES_PATH/dir-maxpath/c10.pem \ @@ -6432,7 +6630,6 @@ run_test "Authentication, CA callback: client max_int+1 chain, server optiona requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA requires_full_size_output_buffer -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: client max_int+1 chain, server required" \ "$P_SRV ca_callback=1 debug_level=3 ca_file=$DATA_FILES_PATH/dir-maxpath/00.crt auth_mode=required" \ "$P_CLI crt_file=$DATA_FILES_PATH/dir-maxpath/c10.pem \ @@ -6443,7 +6640,6 @@ run_test "Authentication, CA callback: client max_int+1 chain, server require requires_config_value_equals "MBEDTLS_X509_MAX_INTERMEDIATE_CA" $MAX_IM_CA requires_full_size_output_buffer -requires_config_enabled MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK run_test "Authentication, CA callback: client max_int chain, server required" \ "$P_SRV ca_callback=1 debug_level=3 ca_file=$DATA_FILES_PATH/dir-maxpath/00.crt auth_mode=required" \ "$P_CLI crt_file=$DATA_FILES_PATH/dir-maxpath/c09.pem \