diff --git a/components/wpa_supplicant/esp_supplicant/include/esp_eap_client.h b/components/wpa_supplicant/esp_supplicant/include/esp_eap_client.h index 1cbfac781e..a0ca6d7c3f 100644 --- a/components/wpa_supplicant/esp_supplicant/include/esp_eap_client.h +++ b/components/wpa_supplicant/esp_supplicant/include/esp_eap_client.h @@ -321,6 +321,30 @@ esp_err_t esp_eap_client_set_fast_params(esp_eap_fast_config config); */ esp_err_t esp_eap_client_use_default_cert_bundle(bool use_default_bundle); +/** + * @brief Set name for certificate domain name validation + * + * Enabling this option will only accept certificate with the provided subject name + * + * @param[in] domain_match The expected domain name + * @param[in] len Length of the domain name (limited to 1~127 bytes). + * + * @return + * - ESP_OK: The identity was set successfully. + * - ESP_ERR_INVALID_ARG: Invalid argument (len <= 0 or len >= 128). + * - ESP_ERR_NO_MEM: Memory allocation failure. + */ +esp_err_t esp_eap_client_set_domain_match(const char *domain_match); + +/** + * @brief Clear the domain name for certificate validation + * + * This function clears the domain name that was previously set for the EAP client. + * After calling this function, the EAP client will no longer use the previously + * configured domain name during the authentication process. + */ +void esp_eap_client_clear_domain_match(void); + #ifdef __cplusplus } #endif diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c b/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c index ff3699b497..55a76a0300 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c @@ -536,6 +536,11 @@ static int set_client_config(const struct tls_connection_params *cfg, tls_contex mbedtls_ssl_set_verify( &tls->ssl, tls_disable_key_usages, NULL ); #endif /*CONFIG_ESP_WIFI_DISABLE_KEY_USAGE_CHECK*/ + if (cfg->domain_match) { + mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_REQUIRED); + mbedtls_ssl_set_hostname(&tls->ssl, cfg->domain_match); + } + #ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE if (cfg->flags & TLS_CONN_USE_DEFAULT_CERT_BUNDLE) { wpa_printf(MSG_INFO, "Using default cert bundle"); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c b/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c index d8d59bb92f..afba2f1c6f 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c @@ -1191,3 +1191,33 @@ esp_err_t esp_eap_client_use_default_cert_bundle(bool use_default_bundle) return ESP_FAIL; #endif } + +#define MAX_DOMAIN_MATCH_LEN 128 +esp_err_t esp_eap_client_set_domain_match(const char *domain_match) +{ + if (g_wpa_domain_match) { + os_free(g_wpa_domain_match); + g_wpa_domain_match = NULL; + } + + int len = os_strlen(domain_match); + if (len > MAX_DOMAIN_MATCH_LEN) { + return ESP_ERR_INVALID_ARG; + } + g_wpa_domain_match = (char *)os_zalloc(len+1); + if (g_wpa_domain_match == NULL) { + return ESP_ERR_NO_MEM; + } + + os_strlcpy(g_wpa_domain_match, domain_match, len+1); + + return ESP_OK; +} + +void esp_eap_client_clear_domain_match(void) +{ + if (g_wpa_domain_match) { + os_free(g_wpa_domain_match); + } + g_wpa_domain_match = NULL; +} \ No newline at end of file diff --git a/components/wpa_supplicant/src/eap_peer/eap.c b/components/wpa_supplicant/src/eap_peer/eap.c index bce12af1fc..7c6739178d 100644 --- a/components/wpa_supplicant/src/eap_peer/eap.c +++ b/components/wpa_supplicant/src/eap_peer/eap.c @@ -67,6 +67,7 @@ bool g_wpa_suiteb_certification; bool g_wpa_default_cert_bundle; int (*esp_crt_bundle_attach_fn)(void *conf); #endif +char *g_wpa_domain_match; void eap_peer_config_deinit(struct eap_sm *sm); void eap_peer_blob_deinit(struct eap_sm *sm); @@ -518,7 +519,7 @@ int eap_peer_config_init( sm->config.identity = NULL; sm->config.password = NULL; sm->config.new_password = NULL; - + sm->config.domain_match = g_wpa_domain_match; sm->config.private_key_passwd = private_key_passwd; sm->config.client_cert = (u8 *)sm->blob[0].name; sm->config.private_key = (u8 *)sm->blob[1].name; @@ -581,6 +582,7 @@ int eap_peer_config_init( sm->config.flags |= TLS_CONN_USE_DEFAULT_CERT_BUNDLE; } #endif + /* To be used only for EAP-FAST */ if (g_wpa_phase1_options) { sm->config.phase1 = g_wpa_phase1_options; diff --git a/components/wpa_supplicant/src/eap_peer/eap.h b/components/wpa_supplicant/src/eap_peer/eap.h index 0651bd5ec5..a11198d78c 100644 --- a/components/wpa_supplicant/src/eap_peer/eap.h +++ b/components/wpa_supplicant/src/eap_peer/eap.h @@ -49,6 +49,8 @@ extern bool g_wpa_suiteb_certification; extern bool g_wpa_default_cert_bundle; extern int (*esp_crt_bundle_attach_fn)(void *conf); +extern char *g_wpa_domain_match; + const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len); void eap_deinit_prev_method(struct eap_sm *sm, const char *txt); struct wpabuf * eap_sm_build_nak(struct eap_sm *sm, EapType type, u8 id); diff --git a/components/wpa_supplicant/src/eap_peer/eap_config.h b/components/wpa_supplicant/src/eap_peer/eap_config.h index 60eda8c954..6dee56c7ac 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_config.h +++ b/components/wpa_supplicant/src/eap_peer/eap_config.h @@ -159,6 +159,21 @@ struct eap_peer_config { */ const u8 *private_key_passwd; + /** + * domain_match - Constraint for server domain name + * + * If set, this FQDN is used as a full match requirement for the + * server certificate in SubjectAltName dNSName element(s). If a + * matching dNSName is found, this constraint is met. If no dNSName + * values are present, this constraint is matched against SubjectName CN + * using same full match comparison. This behavior is similar to + * domain_suffix_match, but has the requirement of a full match, i.e., + * no subdomains or wildcard matches are allowed. Case-insensitive + * comparison is used, so "Example.com" matches "example.com", but would + * not match "test.Example.com". + */ + char *domain_match; + /** * Phase 2 */ diff --git a/components/wpa_supplicant/src/eap_peer/eap_tls_common.c b/components/wpa_supplicant/src/eap_peer/eap_tls_common.c index b3ebfa7362..abb2a26749 100644 --- a/components/wpa_supplicant/src/eap_peer/eap_tls_common.c +++ b/components/wpa_supplicant/src/eap_peer/eap_tls_common.c @@ -74,6 +74,7 @@ static void eap_tls_params_from_conf1(struct tls_connection_params *params, params->client_cert = (char *) config->client_cert; params->private_key = (char *) config->private_key; params->private_key_passwd = (char *) config->private_key_passwd; + params->domain_match = config->domain_match; eap_tls_params_flags(params, config->phase1); if (wifi_sta_get_enterprise_disable_time_check()) params->flags |= TLS_CONN_DISABLE_TIME_CHECKS;