From f3fc894fea4245ff5697b7e2e3aa21f7ec362724 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Tue, 11 Mar 2025 12:29:36 +0530 Subject: [PATCH] fix(esp_wifi): Code cleanup for PR#15550 PR#15551 Closes https://github.com/espressif/esp-idf/pull/15550 Closes https://github.com/espressif/esp-idf/pull/15551 --- .../esp_supplicant/include/esp_eap_client.h | 26 +++----- .../esp_supplicant/src/crypto/tls_mbedtls.c | 12 ++-- .../esp_supplicant/src/esp_eap_client.c | 41 +++++++------ components/wpa_supplicant/port/include/os.h | 59 ++++++++++--------- components/wpa_supplicant/src/eap_peer/eap.c | 5 +- components/wpa_supplicant/src/eap_peer/eap.h | 2 + .../wifi_enterprise/main/Kconfig.projbuild | 17 +++--- .../main/wifi_enterprise_main.c | 7 ++- 8 files changed, 90 insertions(+), 79 deletions(-) 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 a0ca6d7c3f..22cfdd293a 100644 --- a/components/wpa_supplicant/esp_supplicant/include/esp_eap_client.h +++ b/components/wpa_supplicant/esp_supplicant/include/esp_eap_client.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -322,28 +322,20 @@ 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 + * This function sets the expected domain name for validating the certificate's subject name. + * If the provided domain name does not match the certificate's subject name, validation will fail. * - * Enabling this option will only accept certificate with the provided subject name + * @attention 1. The `domain_name` should be a NULL-terminated string. * - * @param[in] domain_match The expected domain name - * @param[in] len Length of the domain name (limited to 1~127 bytes). + * @param[in] domain_name The expected domain name. Pass `NULL` to clear the domain matching. * * @return - * - ESP_OK: The identity was set successfully. - * - ESP_ERR_INVALID_ARG: Invalid argument (len <= 0 or len >= 128). + * - ESP_OK: The domain match was set successfully. + * - ESP_ERR_INVALID_ARG: Invalid argument (length > 255). * - ESP_ERR_NO_MEM: Memory allocation failure. + * - ESP_ERR_NOT_SUPPORTED: Feature not supported. */ -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); +esp_err_t esp_eap_client_set_domain_name(const char *domain_name); #ifdef __cplusplus } 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 7922b9be7b..1e08706669 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/tls_mbedtls.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -535,11 +535,11 @@ static int set_client_config(const struct tls_connection_params *cfg, tls_contex #ifdef CONFIG_ESP_WIFI_DISABLE_KEY_USAGE_CHECK 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); - } + ret = mbedtls_ssl_set_hostname(&tls->ssl, cfg->domain_match); + if (ret != 0) { + wpa_printf(MSG_ERROR, "Failed to set hostname"); + return ret; + } #ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE if (cfg->flags & TLS_CONN_USE_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 afba2f1c6f..3ebd4beb8b 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_eap_client.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -932,6 +932,9 @@ esp_err_t esp_eap_client_set_ca_cert(const unsigned char *ca_cert, int ca_cert_l g_wpa_ca_cert_len = ca_cert_len; } + /* CA certs Set/updated, flushing current PMK cache */ + wpa_sm_pmksa_cache_flush(get_wpa_sm(), NULL); + return ESP_OK; } @@ -1192,32 +1195,36 @@ esp_err_t esp_eap_client_use_default_cert_bundle(bool use_default_bundle) #endif } -#define MAX_DOMAIN_MATCH_LEN 128 -esp_err_t esp_eap_client_set_domain_match(const char *domain_match) +#define MAX_DOMAIN_MATCH_LEN 255 /* Maximum host name defined in RFC 1035 */ +esp_err_t esp_eap_client_set_domain_name(const char *domain_name) { +#ifdef CONFIG_TLS_INTERNAL_CLIENT + return ESP_ERR_NOT_SUPPORTED; +#else + int len = domain_name ? os_strnlen(domain_name, MAX_DOMAIN_MATCH_LEN + 1) : 0; + if (len > MAX_DOMAIN_MATCH_LEN) { + return ESP_ERR_INVALID_ARG; + } + if (g_wpa_domain_match && domain_name && os_strcmp(g_wpa_domain_match, domain_name) == 0) { + return ESP_OK; + } 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; + if (!domain_name) { + return ESP_OK; } - g_wpa_domain_match = (char *)os_zalloc(len+1); - if (g_wpa_domain_match == NULL) { + g_wpa_domain_match = os_strdup(domain_name); + if (!g_wpa_domain_match) { return ESP_ERR_NO_MEM; } - os_strlcpy(g_wpa_domain_match, domain_match, len+1); + /* flushing the PMK only needed when going for a better security ie no-domain name to domain name + * or changing the domain name */ + wpa_sm_pmksa_cache_flush(get_wpa_sm(), NULL); return ESP_OK; +#endif } - -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/port/include/os.h b/components/wpa_supplicant/port/include/os.h index a3442fade9..7b8f7798be 100644 --- a/components/wpa_supplicant/port/include/os.h +++ b/components/wpa_supplicant/port/include/os.h @@ -33,8 +33,8 @@ typedef time_t os_time_t; void os_sleep(os_time_t sec, os_time_t usec); struct os_time { - os_time_t sec; - suseconds_t usec; + os_time_t sec; + suseconds_t usec; }; #define os_reltime os_time @@ -59,17 +59,17 @@ int os_get_time(struct os_time *t); /* Helper macros for handling struct os_time */ #define os_time_before(a, b) \ - ((a)->sec < (b)->sec || \ - ((a)->sec == (b)->sec && (a)->usec < (b)->usec)) + ((a)->sec < (b)->sec || \ + ((a)->sec == (b)->sec && (a)->usec < (b)->usec)) #define os_reltime_before os_time_before #define os_time_sub(a, b, res) do { \ - (res)->sec = (a)->sec - (b)->sec; \ - (res)->usec = (a)->usec - (b)->usec; \ - if ((res)->usec < 0) { \ - (res)->sec--; \ - (res)->usec += 1000000; \ - } \ + (res)->sec = (a)->sec - (b)->sec; \ + (res)->usec = (a)->usec - (b)->usec; \ + if ((res)->usec < 0) { \ + (res)->sec--; \ + (res)->usec += 1000000; \ + } \ } while (0) #define os_reltime_sub os_time_sub @@ -89,7 +89,7 @@ int os_get_time(struct os_time *t); * which is used by POSIX mktime(). */ int os_mktime(int year, int month, int day, int hour, int min, int sec, - os_time_t *t); + os_time_t *t); int os_gmtime(os_time_t t, struct os_tm *tm); @@ -190,7 +190,7 @@ int os_unsetenv(const char *name); /* We don't support file reading support */ static inline char *os_readfile(const char *name, size_t *len) { - return NULL; + return NULL; } /* @@ -230,7 +230,6 @@ static inline char *os_readfile(const char *name, size_t *len) #define os_bzero(s, n) bzero(s, n) #endif - #ifndef os_strdup #ifdef _MSC_VER #define os_strdup(s) _strdup(s) @@ -259,6 +258,9 @@ char * ets_strdup(const char *s); #ifndef os_strlen #define os_strlen(s) strlen(s) #endif +#ifndef os_strnlen +#define os_strnlen(s, n) strnlen((s), (n)) +#endif #ifndef os_strcasecmp #ifdef _MSC_VER #define os_strcasecmp(s1, s2) _stricmp((s1), (s2)) @@ -308,14 +310,15 @@ char * ets_strdup(const char *s); static inline int os_snprintf_error(size_t size, int res) { - return res < 0 || (unsigned int) res >= size; + return res < 0 || (unsigned int) res >= size; } static inline void * os_realloc_array(void *ptr, size_t nmemb, size_t size) { - if (size && nmemb > (~(size_t) 0) / size) - return NULL; - return os_realloc(ptr, nmemb * size); + if (size && nmemb > (~(size_t) 0) / size) { + return NULL; + } + return os_realloc(ptr, nmemb * size); } #ifdef CONFIG_CRYPTO_MBEDTLS @@ -334,10 +337,10 @@ static uint8_t forced_memzero_val; static inline void forced_memzero(void *ptr, size_t len) { - memset_func(ptr, 0, len); - if (len) { - forced_memzero_val = ((uint8_t *) ptr)[0]; - } + memset_func(ptr, 0, len); + if (len) { + forced_memzero_val = ((uint8_t *) ptr)[0]; + } } #endif @@ -377,23 +380,23 @@ extern const wifi_osi_funcs_t *wifi_funcs; static inline void os_timer_setfn(void *ptimer, void *pfunction, void *parg) { - return wifi_funcs->_timer_setfn(ptimer, pfunction, parg); + return wifi_funcs->_timer_setfn(ptimer, pfunction, parg); } static inline void os_timer_disarm(void *ptimer) { - return wifi_funcs->_timer_disarm(ptimer); + return wifi_funcs->_timer_disarm(ptimer); } -static inline void os_timer_arm_us(void *ptimer,uint32_t u_seconds,bool repeat_flag) +static inline void os_timer_arm_us(void *ptimer, uint32_t u_seconds, bool repeat_flag) { - return wifi_funcs->_timer_arm_us(ptimer, u_seconds, repeat_flag); + return wifi_funcs->_timer_arm_us(ptimer, u_seconds, repeat_flag); } -static inline void os_timer_arm(void *ptimer,uint32_t milliseconds,bool repeat_flag) +static inline void os_timer_arm(void *ptimer, uint32_t milliseconds, bool repeat_flag) { - return wifi_funcs->_timer_arm(ptimer, milliseconds, repeat_flag); + return wifi_funcs->_timer_arm(ptimer, milliseconds, repeat_flag); } static inline void os_timer_done(void *ptimer) { - return wifi_funcs->_timer_done(ptimer); + return wifi_funcs->_timer_done(ptimer); } #endif /* OS_H */ diff --git a/components/wpa_supplicant/src/eap_peer/eap.c b/components/wpa_supplicant/src/eap_peer/eap.c index 7c6739178d..39bd0247c0 100644 --- a/components/wpa_supplicant/src/eap_peer/eap.c +++ b/components/wpa_supplicant/src/eap_peer/eap.c @@ -67,7 +67,9 @@ bool g_wpa_suiteb_certification; bool g_wpa_default_cert_bundle; int (*esp_crt_bundle_attach_fn)(void *conf); #endif +#ifndef CONFIG_TLS_INTERNAL_CLIENT char *g_wpa_domain_match; +#endif void eap_peer_config_deinit(struct eap_sm *sm); void eap_peer_blob_deinit(struct eap_sm *sm); @@ -519,7 +521,9 @@ int eap_peer_config_init( sm->config.identity = NULL; sm->config.password = NULL; sm->config.new_password = NULL; +#ifndef CONFIG_TLS_INTERNAL_CLIENT sm->config.domain_match = g_wpa_domain_match; +#endif 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; @@ -582,7 +586,6 @@ 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 a11198d78c..93d623d1cc 100644 --- a/components/wpa_supplicant/src/eap_peer/eap.h +++ b/components/wpa_supplicant/src/eap_peer/eap.h @@ -49,7 +49,9 @@ extern bool g_wpa_suiteb_certification; extern bool g_wpa_default_cert_bundle; extern int (*esp_crt_bundle_attach_fn)(void *conf); +#ifndef CONFIG_TLS_INTERNAL_CLIENT extern char *g_wpa_domain_match; +#endif const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len); void eap_deinit_prev_method(struct eap_sm *sm, const char *txt); diff --git a/examples/wifi/wifi_enterprise/main/Kconfig.projbuild b/examples/wifi/wifi_enterprise/main/Kconfig.projbuild index bd82dfb069..3776bae400 100644 --- a/examples/wifi/wifi_enterprise/main/Kconfig.projbuild +++ b/examples/wifi/wifi_enterprise/main/Kconfig.projbuild @@ -99,15 +99,18 @@ menu "Example Configuration" help Use default CA certificate bundle for WiFi enterprise connection - config EXAMPLE_USE_SERVER_DOMAIN_MATCH - bool "Validate server cert domain" + config EXAMPLE_VALIDATE_SERVER_CERT_DOMAIN + bool "Enable server certificate domain validation" + depends on EXAMPLE_VALIDATE_SERVER_CERT + default n help - Validate the certificate domain + Enable validation of the server certificate's domain name. - config EXAMPLE_SERVER_DOMAIN_MATCH_VALUE - string "Server cert domain" - depends on EXAMPLE_USE_SERVER_DOMAIN_MATCH + config EXAMPLE_SERVER_CERT_DOMAIN + string "Expected server certificate domain" + depends on EXAMPLE_VALIDATE_SERVER_CERT_DOMAIN default "espressif.com" help - Accept only server certificates matching this domain + Specify the expected domain name for the server certificate. + The connection will be accepted only if the server certificate matches this domain. endmenu diff --git a/examples/wifi/wifi_enterprise/main/wifi_enterprise_main.c b/examples/wifi/wifi_enterprise/main/wifi_enterprise_main.c index 16909a9820..15026a9953 100644 --- a/examples/wifi/wifi_enterprise/main/wifi_enterprise_main.c +++ b/examples/wifi/wifi_enterprise/main/wifi_enterprise_main.c @@ -1,6 +1,6 @@ /* * SPDX-FileCopyrightText: 2006-2016 ARM Limited - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,6 +33,7 @@ #define EXAMPLE_EAP_ID CONFIG_EXAMPLE_EAP_ID #define EXAMPLE_EAP_USERNAME CONFIG_EXAMPLE_EAP_USERNAME #define EXAMPLE_EAP_PASSWORD CONFIG_EXAMPLE_EAP_PASSWORD +#define EXAMPLE_SERVER_CERT_DOMAIN CONFIG_EXAMPLE_SERVER_CERT_DOMAIN /* FreeRTOS event group to signal when we are connected & ready to make a request */ static EventGroupHandle_t wifi_event_group; @@ -151,8 +152,8 @@ static void initialise_wifi(void) #ifdef CONFIG_EXAMPLE_USE_DEFAULT_CERT_BUNDLE ESP_ERROR_CHECK(esp_eap_client_use_default_cert_bundle(true)); #endif -#ifdef CONFIG_EXAMPLE_USE_SERVER_DOMAIN_MATCH - ESP_ERROR_CHECK(esp_eap_client_set_domain_match(CONFIG_EXAMPLE_SERVER_DOMAIN_MATCH_VALUE)); +#ifdef CONFIG_EXAMPLE_VALIDATE_SERVER_CERT_DOMAIN + ESP_ERROR_CHECK(esp_eap_client_set_domain_name(EXAMPLE_SERVER_CERT_DOMAIN)); #endif ESP_ERROR_CHECK(esp_wifi_sta_enterprise_enable()); ESP_ERROR_CHECK(esp_wifi_start());