diff --git a/include/zephyr/net/wifi_certs.h b/include/zephyr/net/wifi_certs.h new file mode 100644 index 000000000000..30b6e4f7087c --- /dev/null +++ b/include/zephyr/net/wifi_certs.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef WIFI_CERTS_H__ +#define WIFI_CERTS_H__ + +#include +#include +#include + +/** + * Set Wi-Fi Enterprise credentials. + * + * Sets up the required credentials for Enterprise mode in both + * Access Point and Station modes. + * + * Certificates typically used: + * - CA certificate + * - Client certificate + * - Client private key + * - Server certificate and server key (for AP mode) + * + * @param iface Network interface + * @param AP or Station mode + * + * @return 0 if ok, < 0 if error + */ +int wifi_set_enterprise_credentials(struct net_if *iface, bool is_ap); + +/** + * Clear Wi-Fi enterprise credentials + * + * @param Wi-Fi enterprise params + */ +void wifi_clear_enterprise_credentials(void); + +#endif /* WIFI_CERTS_H__ */ diff --git a/modules/hostap/Kconfig b/modules/hostap/Kconfig index 5d245323d1f5..f921549d77a9 100644 --- a/modules/hostap/Kconfig +++ b/modules/hostap/Kconfig @@ -198,6 +198,7 @@ config WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE select MBEDTLS_SERVER_NAME_INDICATION if MBEDTLS_BUILTIN select MBEDTLS_X509_CRL_PARSE_C select MBEDTLS_TLS_VERSION_1_2 + select WIFI_CERTIFICATE_LIB depends on !WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE @@ -302,6 +303,7 @@ config WIFI_NM_HOSTAPD_AP config WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE bool "Hostapd crypto enterprise support" + select WIFI_CERTIFICATE_LIB depends on WIFI_NM_HOSTAPD_AP if WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE diff --git a/subsys/net/l2/wifi/CMakeLists.txt b/subsys/net/l2/wifi/CMakeLists.txt index ba86052895ed..f91964d9d83a 100644 --- a/subsys/net/l2/wifi/CMakeLists.txt +++ b/subsys/net/l2/wifi/CMakeLists.txt @@ -13,6 +13,7 @@ zephyr_library_include_directories_ifdef( ) zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_MGMT wifi_mgmt.c) +zephyr_library_sources_ifdef(CONFIG_WIFI_CERTIFICATE_LIB wifi_certs.c) zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_SHELL wifi_shell.c) zephyr_library_sources_ifdef(CONFIG_WIFI_NM wifi_nm.c) zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_UTILS wifi_utils.c) diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index a2e029a592be..4b1d309066c3 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -126,6 +126,11 @@ config WIFI_ENT_IDENTITY_MAX_USERS help This option defines the maximum number of identity users allowed connection. +config WIFI_CERTIFICATE_LIB + bool + help + Enable this option to process certificates in enterprise mode. + if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE config WIFI_SHELL_RUNTIME_CERTIFICATES diff --git a/subsys/net/l2/wifi/wifi_certs.c b/subsys/net/l2/wifi/wifi_certs.c new file mode 100644 index 000000000000..eccab564bf0b --- /dev/null +++ b/subsys/net/l2/wifi/wifi_certs.c @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(net_wifi_certs, LOG_LEVEL_INF); + +#include +#include +#include +#include +#include +#include + +static struct wifi_enterprise_creds_params enterprise_creds_params = { 0 }; + +#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES +#include +enum wifi_enterprise_cert_sec_tags { + WIFI_CERT_CA_SEC_TAG = 0x1020001, + WIFI_CERT_CLIENT_KEY_SEC_TAG, + WIFI_CERT_SERVER_KEY_SEC_TAG, + WIFI_CERT_CLIENT_SEC_TAG, + WIFI_CERT_SERVER_SEC_TAG, + /* Phase 2 */ + WIFI_CERT_CA_P2_SEC_TAG, + WIFI_CERT_CLIENT_KEY_P2_SEC_TAG, + WIFI_CERT_CLIENT_P2_SEC_TAG, +}; + +struct wifi_cert_data { + enum tls_credential_type type; + uint32_t sec_tag; + uint8_t **data; + size_t *len; +}; +#else +static const char ca_cert_test[] = { + #include + '\0' +}; + +static const char client_cert_test[] = { + #include + '\0' +}; + +static const char client_key_test[] = { + #include + '\0' +}; + +static const char ca_cert2_test[] = { + #include + '\0'}; + +static const char client_cert2_test[] = { + #include + '\0'}; + +static const char client_key2_test[] = { + #include + '\0'}; + +static const char server_cert_test[] = { + #include + '\0' +}; + +static const char server_key_test[] = { + #include + '\0' +}; +#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ + +#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES +static int process_certificates(struct wifi_cert_data *certs, size_t cert_count) +{ + for (size_t i = 0; i < cert_count; i++) { + int err; + size_t len = 0; + uint8_t *cert_tmp; + + err = tls_credential_get(certs[i].sec_tag, certs[i].type, NULL, &len); + if (err != -EFBIG) { + LOG_ERR("Failed to get credential tag: %d length, err: %d", + certs[i].sec_tag, err); + return err; + } + + cert_tmp = k_malloc(len); + if (!cert_tmp) { + LOG_ERR("Failed to allocate memory for credential tag: %d", + certs[i].sec_tag); + return -ENOMEM; + } + + err = tls_credential_get(certs[i].sec_tag, certs[i].type, cert_tmp, &len); + if (err) { + LOG_ERR("Failed to get credential tag: %d", certs[i].sec_tag); + k_free(cert_tmp); + return err; + } + + *certs[i].data = cert_tmp; + *certs[i].len = len; + } + + return 0; +} + +static void set_enterprise_creds_params(bool is_ap) +{ + struct wifi_cert_data certs_common[] = { + { + .type = TLS_CREDENTIAL_CA_CERTIFICATE, + .sec_tag = WIFI_CERT_CA_SEC_TAG, + .data = &enterprise_creds_params.ca_cert, + .len = &enterprise_creds_params.ca_cert_len, + }, + }; + struct wifi_cert_data certs_sta[] = { + { + .type = TLS_CREDENTIAL_PRIVATE_KEY, + .sec_tag = WIFI_CERT_CLIENT_KEY_SEC_TAG, + .data = &enterprise_creds_params.client_key, + .len = &enterprise_creds_params.client_key_len, + }, + { + .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, + .sec_tag = WIFI_CERT_CLIENT_SEC_TAG, + .data = &enterprise_creds_params.client_cert, + .len = &enterprise_creds_params.client_cert_len, + }, + { + .type = TLS_CREDENTIAL_CA_CERTIFICATE, + .sec_tag = WIFI_CERT_CA_P2_SEC_TAG, + .data = &enterprise_creds_params.ca_cert2, + .len = &enterprise_creds_params.ca_cert2_len, + }, + { + .type = TLS_CREDENTIAL_PRIVATE_KEY, + .sec_tag = WIFI_CERT_CLIENT_KEY_P2_SEC_TAG, + .data = &enterprise_creds_params.client_key2, + .len = &enterprise_creds_params.client_key2_len, + }, + { + .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, + .sec_tag = WIFI_CERT_CLIENT_P2_SEC_TAG, + .data = &enterprise_creds_params.client_cert2, + .len = &enterprise_creds_params.client_cert2_len, + }, + }; + + struct wifi_cert_data certs_ap[] = { + { + .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, + .sec_tag = WIFI_CERT_SERVER_SEC_TAG, + .data = &enterprise_creds_params.server_cert, + .len = &enterprise_creds_params.server_cert_len, + }, + { + .type = TLS_CREDENTIAL_PRIVATE_KEY, + .sec_tag = WIFI_CERT_SERVER_KEY_SEC_TAG, + .data = &enterprise_creds_params.server_key, + .len = &enterprise_creds_params.server_key_len, + }, + }; + + memset(&enterprise_creds_params, 0, sizeof(struct wifi_enterprise_creds_params)); + + /* Process common certificates */ + if (process_certificates(certs_common, ARRAY_SIZE(certs_common)) != 0) { + goto cleanup; + } + + /* Process STA-specific certificates */ + if (!is_ap) { + if (process_certificates(certs_sta, ARRAY_SIZE(certs_sta)) != 0) { + goto cleanup; + } + } + + /* Process AP-specific certificates if is_ap is true */ + if (is_ap) { + if (process_certificates(certs_ap, ARRAY_SIZE(certs_ap)) != 0) { + goto cleanup; + } + } + + return; + +cleanup: + for (size_t i = 0; i < ARRAY_SIZE(certs_common); i++) { + if (certs_common[i].data) { + k_free(*certs_common[i].data); + } + } + + if (!is_ap) { + for (size_t i = 0; i < ARRAY_SIZE(certs_sta); i++) { + if (certs_sta[i].data) { + k_free(*certs_sta[i].data); + } + } + } + + if (is_ap) { + for (size_t i = 0; i < ARRAY_SIZE(certs_ap); i++) { + if (certs_ap[i].data) { + k_free(*certs_ap[i].data); + } + } + } +} + +void wifi_clear_enterprise_credentials(void) +{ + size_t i; + + const uint8_t *certs[] = { + enterprise_creds_params.ca_cert, + enterprise_creds_params.client_cert, + enterprise_creds_params.client_key, + enterprise_creds_params.server_cert, + enterprise_creds_params.server_key, + enterprise_creds_params.ca_cert2, + enterprise_creds_params.client_cert2, + enterprise_creds_params.client_key2, + }; + + for (i = 0; i < ARRAY_SIZE(certs); i++) { + k_free((void *)certs[i]); + } + memset(&enterprise_creds_params, 0, sizeof(struct wifi_enterprise_creds_params)); +} +#else +int config_process_blob(struct wpa_config *config, char *name, uint8_t *data, + uint32_t data_len) +{ + struct wpa_config_blob *blob; + + if (!data || !data_len) { + return -1; + } + + blob = os_zalloc(sizeof(*blob)); + if (blob == NULL) { + return -1; + } + + blob->data = os_zalloc(data_len); + if (blob->data == NULL) { + os_free(blob); + return -1; + } + + blob->name = os_strdup(name); + + if (blob->name == NULL) { + wpa_config_free_blob(blob); + return -1; + } + + os_memcpy(blob->data, data, data_len); + blob->len = data_len; + + wpa_config_set_blob(config, blob); + + return 0; +} + +int process_certificates(void) +{ + struct wpa_supplicant *wpa_s; + int ret; + char if_name[CONFIG_NET_INTERFACE_NAME_LEN + 1]; + struct net_if *iface = net_if_get_wifi_sta(); + + ret = net_if_get_name(iface, if_name, sizeof(if_name)); + if (!ret) { + LOG_ERR("Cannot get interface name (%d)", ret); + return -1; + } + + wpa_s = zephyr_get_handle_by_ifname(if_name); + if (!wpa_s) { + LOG_ERR("Unable to find the interface: %s, quitting", if_name); + return -1; + } + + wifi_set_enterprise_credentials(iface, 0); + + if (config_process_blob(wpa_s->conf, "ca_cert", + enterprise_creds_params.ca_cert, + enterprise_creds_params.ca_cert_len)) { + return -1; + } + + if (config_process_blob(wpa_s->conf, "client_cert", + enterprise_creds_params.client_cert, + enterprise_creds_params.client_cert_len)) { + return -1; + } + + if (config_process_blob(wpa_s->conf, "private_key", + enterprise_creds_params.client_key, + enterprise_creds_params.client_key_len)) { + return -1; + } + + return 0; +} + +static void set_enterprise_creds_params(bool is_ap) +{ + enterprise_creds_params.ca_cert = (uint8_t *)ca_cert_test; + enterprise_creds_params.ca_cert_len = ARRAY_SIZE(ca_cert_test); + + if (!is_ap) { + enterprise_creds_params.client_cert = (uint8_t *)client_cert_test; + enterprise_creds_params.client_cert_len = ARRAY_SIZE(client_cert_test); + enterprise_creds_params.client_key = (uint8_t *)client_key_test; + enterprise_creds_params.client_key_len = ARRAY_SIZE(client_key_test); + enterprise_creds_params.ca_cert2 = (uint8_t *)ca_cert2_test; + enterprise_creds_params.ca_cert2_len = ARRAY_SIZE(ca_cert2_test); + enterprise_creds_params.client_cert2 = (uint8_t *)client_cert2_test; + enterprise_creds_params.client_cert2_len = ARRAY_SIZE(client_cert2_test); + enterprise_creds_params.client_key2 = (uint8_t *)client_key2_test; + enterprise_creds_params.client_key2_len = ARRAY_SIZE(client_key2_test); + + return; + } + + enterprise_creds_params.server_cert = (uint8_t *)server_cert_test; + enterprise_creds_params.server_cert_len = ARRAY_SIZE(server_cert_test); + enterprise_creds_params.server_key = (uint8_t *)server_key_test; + enterprise_creds_params.server_key_len = ARRAY_SIZE(server_key_test); +} + +void wifi_clear_enterprise_credentials(void) +{ + /** + * No operation needed because Wi-Fi credentials + * are statically configured at build time and + * no dynamic memory needs to be freed. + */ +} +#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ + +int wifi_set_enterprise_credentials(struct net_if *iface, bool is_ap) +{ +#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES + wifi_clear_enterprise_credentials(); +#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ + set_enterprise_creds_params(is_ap); + if (net_mgmt(NET_REQUEST_WIFI_ENTERPRISE_CREDS, iface, + &enterprise_creds_params, sizeof(enterprise_creds_params))) { + LOG_WRN("Set enterprise credentials failed\n"); + return -1; + } + + return 0; +} diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index a62d8e0eb824..61a83565ff00 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -30,67 +30,10 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #include "net_shell_private.h" #include -#if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE || \ - defined CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE -#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES -#include -enum wifi_enterprise_cert_sec_tags { - WIFI_CERT_CA_SEC_TAG = 0x1020001, - WIFI_CERT_CLIENT_KEY_SEC_TAG, - WIFI_CERT_SERVER_KEY_SEC_TAG, - WIFI_CERT_CLIENT_SEC_TAG, - WIFI_CERT_SERVER_SEC_TAG, - /* Phase 2 */ - WIFI_CERT_CA_P2_SEC_TAG, - WIFI_CERT_CLIENT_KEY_P2_SEC_TAG, - WIFI_CERT_CLIENT_P2_SEC_TAG, -}; - -struct wifi_cert_data { - enum tls_credential_type type; - uint32_t sec_tag; - uint8_t **data; - size_t *len; -}; -#else -static const char ca_cert_test[] = { - #include - '\0' -}; - -static const char client_cert_test[] = { - #include - '\0' -}; - -static const char client_key_test[] = { - #include - '\0' -}; - -static const char ca_cert2_test[] = { - #include - '\0'}; - -static const char client_cert2_test[] = { - #include - '\0'}; -static const char client_key2_test[] = { - #include - '\0'}; - -static const char server_cert_test[] = { - #include - '\0' -}; - -static const char server_key_test[] = { - #include - '\0' -}; -#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ -#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ +#ifdef CONFIG_WIFI_CERTIFICATE_LIB +#include +#endif #define WIFI_SHELL_MODULE "wifi" @@ -130,12 +73,6 @@ static struct { }; uint8_t all; }; -#if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE || \ - defined CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE -#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES - struct wifi_enterprise_creds_params enterprise_creds_params; -#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ -#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ } context; static struct net_mgmt_event_callback wifi_shell_mgmt_cb; @@ -203,223 +140,6 @@ static struct net_if *get_iface(enum iface_type type, int argc, char *argv[]) return iface; } -#if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE || \ - defined CONFIG_WIFI_NM_HOSTAPD_CRYPTO_ENTERPRISE -#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES -static int process_certificates(struct wifi_cert_data *certs, size_t cert_count) -{ - for (size_t i = 0; i < cert_count; i++) { - int err; - size_t len = 0; - uint8_t *cert_tmp; - - err = tls_credential_get(certs[i].sec_tag, certs[i].type, NULL, &len); - if (err != -EFBIG) { - LOG_ERR("Failed to get credential tag: %d length, err: %d", - certs[i].sec_tag, err); - return err; - } - - cert_tmp = k_malloc(len); - if (!cert_tmp) { - LOG_ERR("Failed to allocate memory for credential tag: %d", - certs[i].sec_tag); - return -ENOMEM; - } - - err = tls_credential_get(certs[i].sec_tag, certs[i].type, cert_tmp, &len); - if (err) { - LOG_ERR("Failed to get credential tag: %d", certs[i].sec_tag); - k_free(cert_tmp); - return err; - } - - *certs[i].data = cert_tmp; - *certs[i].len = len; - } - - return 0; -} - -static void set_enterprise_creds_params(struct wifi_enterprise_creds_params *params, - bool is_ap) -{ - struct wifi_cert_data certs_common[] = { - { - .type = TLS_CREDENTIAL_CA_CERTIFICATE, - .sec_tag = WIFI_CERT_CA_SEC_TAG, - .data = ¶ms->ca_cert, - .len = ¶ms->ca_cert_len, - }, - }; - - struct wifi_cert_data certs_sta[] = { - { - .type = TLS_CREDENTIAL_PRIVATE_KEY, - .sec_tag = WIFI_CERT_CLIENT_KEY_SEC_TAG, - .data = ¶ms->client_key, - .len = ¶ms->client_key_len, - }, - { - .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, - .sec_tag = WIFI_CERT_CLIENT_SEC_TAG, - .data = ¶ms->client_cert, - .len = ¶ms->client_cert_len, - }, - { - .type = TLS_CREDENTIAL_CA_CERTIFICATE, - .sec_tag = WIFI_CERT_CA_P2_SEC_TAG, - .data = ¶ms->ca_cert2, - .len = ¶ms->ca_cert2_len, - }, - { - .type = TLS_CREDENTIAL_PRIVATE_KEY, - .sec_tag = WIFI_CERT_CLIENT_KEY_P2_SEC_TAG, - .data = ¶ms->client_key2, - .len = ¶ms->client_key2_len, - }, - { - .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, - .sec_tag = WIFI_CERT_CLIENT_P2_SEC_TAG, - .data = ¶ms->client_cert2, - .len = ¶ms->client_cert2_len, - }, - }; - - struct wifi_cert_data certs_ap[] = { - { - .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, - .sec_tag = WIFI_CERT_SERVER_SEC_TAG, - .data = ¶ms->server_cert, - .len = ¶ms->server_cert_len, - }, - { - .type = TLS_CREDENTIAL_PRIVATE_KEY, - .sec_tag = WIFI_CERT_SERVER_KEY_SEC_TAG, - .data = ¶ms->server_key, - .len = ¶ms->server_key_len, - }, - }; - - memset(params, 0, sizeof(*params)); - - /* Process common certificates */ - if (process_certificates(certs_common, ARRAY_SIZE(certs_common)) != 0) { - goto cleanup; - } - - /* Process STA-specific certificates */ - if (!is_ap) { - if (process_certificates(certs_sta, ARRAY_SIZE(certs_sta)) != 0) { - goto cleanup; - } - } - - /* Process AP-specific certificates if is_ap is true */ - if (is_ap) { - if (process_certificates(certs_ap, ARRAY_SIZE(certs_ap)) != 0) { - goto cleanup; - } - } - - memcpy(&context.enterprise_creds_params, params, sizeof(*params)); - return; - -cleanup: - for (size_t i = 0; i < ARRAY_SIZE(certs_common); i++) { - if (certs_common[i].data) { - k_free(*certs_common[i].data); - } - } - - if (!is_ap) { - for (size_t i = 0; i < ARRAY_SIZE(certs_sta); i++) { - if (certs_sta[i].data) { - k_free(*certs_sta[i].data); - } - } - } - - if (is_ap) { - for (size_t i = 0; i < ARRAY_SIZE(certs_ap); i++) { - if (certs_ap[i].data) { - k_free(*certs_ap[i].data); - } - } - } -} - -static void clear_enterprise_creds_params(struct wifi_enterprise_creds_params *params) -{ - size_t i; - - if (!params) { - return; - } - - const uint8_t *certs[] = { - params->ca_cert, - params->client_cert, - params->client_key, - params->server_cert, - params->server_key, - params->ca_cert2, - params->client_cert2, - params->client_key2, - }; - - for (i = 0; i < ARRAY_SIZE(certs); i++) { - k_free((void *)certs[i]); - } - memset(params, 0, sizeof(*params)); -} -#else -static void set_enterprise_creds_params(struct wifi_enterprise_creds_params *params, - bool is_ap) -{ - params->ca_cert = (uint8_t *)ca_cert_test; - params->ca_cert_len = ARRAY_SIZE(ca_cert_test); - - if (!is_ap) { - params->client_cert = (uint8_t *)client_cert_test; - params->client_cert_len = ARRAY_SIZE(client_cert_test); - params->client_key = (uint8_t *)client_key_test; - params->client_key_len = ARRAY_SIZE(client_key_test); - params->ca_cert2 = (uint8_t *)ca_cert2_test; - params->ca_cert2_len = ARRAY_SIZE(ca_cert2_test); - params->client_cert2 = (uint8_t *)client_cert2_test; - params->client_cert2_len = ARRAY_SIZE(client_cert2_test); - params->client_key2 = (uint8_t *)client_key2_test; - params->client_key2_len = ARRAY_SIZE(client_key2_test); - - return; - } - - params->server_cert = (uint8_t *)server_cert_test; - params->server_cert_len = ARRAY_SIZE(server_cert_test); - params->server_key = (uint8_t *)server_key_test; - params->server_key_len = ARRAY_SIZE(server_key_test); -} -#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ - -static int wifi_set_enterprise_creds(const struct shell *sh, struct net_if *iface, - bool is_ap) -{ - struct wifi_enterprise_creds_params params = {0}; - -#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES - clear_enterprise_creds_params(&context.enterprise_creds_params); -#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ - set_enterprise_creds_params(¶ms, is_ap); - if (net_mgmt(NET_REQUEST_WIFI_ENTERPRISE_CREDS, iface, ¶ms, sizeof(params))) { - PR_WARNING("Set enterprise credentials failed\n"); - return -1; - } - - return 0; -} -#endif - static bool parse_number(const struct shell *sh, long *param, char *str, char *pname, long min, long max) { @@ -1239,7 +959,7 @@ static int cmd_wifi_connect(const struct shell *sh, size_t argc, cnx_params.security == WIFI_SECURITY_TYPE_EAP_PEAP_GTC || cnx_params.security == WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2 || cnx_params.security == WIFI_SECURITY_TYPE_EAP_PEAP_TLS) { - wifi_set_enterprise_creds(sh, iface, 0); + wifi_set_enterprise_credentials(iface, 0); } #endif @@ -1283,7 +1003,7 @@ static int cmd_wifi_disconnect(const struct shell *sh, size_t argc, #ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES /* Clear the certificates */ - clear_enterprise_creds_params(&context.enterprise_creds_params); + wifi_clear_enterprise_credentials(); #endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ return 0; @@ -2341,7 +2061,7 @@ static int cmd_wifi_ap_disable(const struct shell *sh, size_t argc, #ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES /* Clear the certificates */ - clear_enterprise_creds_params(&context.enterprise_creds_params); + wifi_clear_enterprise_credentials(); #endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ return 0; diff --git a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c index c5b8c2a88a39..3966a2404bcb 100644 --- a/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c +++ b/subsys/net/lib/wifi_credentials/wifi_credentials_shell.c @@ -22,247 +22,15 @@ #include +#ifdef CONFIG_WIFI_CERTIFICATE_LIB +#include +#endif + LOG_MODULE_REGISTER(wifi_credentials_shell, CONFIG_WIFI_CREDENTIALS_LOG_LEVEL); #define MAX_BANDS_STR_LEN 64 #define MACSTR "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx" -#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE -#ifdef CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES -#include -enum wifi_enterprise_cert_sec_tags { - WIFI_CERT_CA_SEC_TAG = 0x1020001, - WIFI_CERT_CLIENT_KEY_SEC_TAG, - WIFI_CERT_SERVER_KEY_SEC_TAG, - WIFI_CERT_CLIENT_SEC_TAG, - WIFI_CERT_SERVER_SEC_TAG, - /* Phase 2 */ - WIFI_CERT_CA_P2_SEC_TAG, - WIFI_CERT_CLIENT_KEY_P2_SEC_TAG, - WIFI_CERT_CLIENT_P2_SEC_TAG, -}; - -struct wifi_cert_data { - enum tls_credential_type type; - uint32_t sec_tag; - uint8_t **data; - size_t *len; -}; -#else -static const char ca_cert_test[] = { - #include - '\0' -}; - -static const char client_cert_test[] = { - #include - '\0' -}; - -static const char client_key_test[] = { - #include - '\0' -}; - -static const char ca_cert2_test[] = { - #include - '\0'}; - -static const char client_cert2_test[] = { - #include - '\0'}; - -static const char client_key2_test[] = { - #include - '\0'}; -#endif /* CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES */ -#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ - -#if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE -#ifdef CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES - -struct wifi_enterprise_creds_params enterprise_creds_params; - -static int process_certificates(struct wifi_cert_data *certs, size_t cert_count) -{ - for (size_t i = 0; i < cert_count; i++) { - int err; - size_t len = 0; - uint8_t *cert_tmp; - - err = tls_credential_get(certs[i].sec_tag, certs[i].type, NULL, &len); - if (err != -EFBIG) { - LOG_ERR("Failed to get credential tag: %d length, err: %d", - certs[i].sec_tag, err); - return err; - } - - cert_tmp = k_malloc(len); - if (!cert_tmp) { - LOG_ERR("Failed to allocate memory for credential tag: %d", - certs[i].sec_tag); - return -ENOMEM; - } - - err = tls_credential_get(certs[i].sec_tag, certs[i].type, cert_tmp, &len); - if (err) { - LOG_ERR("Failed to get credential tag: %d", certs[i].sec_tag); - k_free(cert_tmp); - return err; - } - - *certs[i].data = cert_tmp; - *certs[i].len = len; - } - - return 0; -} - -static void set_enterprise_creds_params(struct wifi_enterprise_creds_params *params, - bool is_ap) -{ - struct wifi_cert_data certs_common[] = { - { - .type = TLS_CREDENTIAL_CA_CERTIFICATE, - .sec_tag = WIFI_CERT_CA_SEC_TAG, - .data = ¶ms->ca_cert, - .len = ¶ms->ca_cert_len, - }, - }; - - struct wifi_cert_data certs_sta[] = { - { - .type = TLS_CREDENTIAL_PRIVATE_KEY, - .sec_tag = WIFI_CERT_CLIENT_KEY_SEC_TAG, - .data = ¶ms->client_key, - .len = ¶ms->client_key_len, - }, - { - .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, - .sec_tag = WIFI_CERT_CLIENT_SEC_TAG, - .data = ¶ms->client_cert, - .len = ¶ms->client_cert_len, - }, - { - .type = TLS_CREDENTIAL_CA_CERTIFICATE, - .sec_tag = WIFI_CERT_CA_P2_SEC_TAG, - .data = ¶ms->ca_cert2, - .len = ¶ms->ca_cert2_len, - }, - { - .type = TLS_CREDENTIAL_PRIVATE_KEY, - .sec_tag = WIFI_CERT_CLIENT_KEY_P2_SEC_TAG, - .data = ¶ms->client_key2, - .len = ¶ms->client_key2_len, - }, - { - .type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE, - .sec_tag = WIFI_CERT_CLIENT_P2_SEC_TAG, - .data = ¶ms->client_cert2, - .len = ¶ms->client_cert2_len, - }, - }; - - memset(params, 0, sizeof(*params)); - - /* Process common certificates */ - if (process_certificates(certs_common, ARRAY_SIZE(certs_common)) != 0) { - goto cleanup; - } - - /* Process STA-specific certificates */ - if (!is_ap) { - if (process_certificates(certs_sta, ARRAY_SIZE(certs_sta)) != 0) { - goto cleanup; - } - } - - memcpy(&enterprise_creds_params, params, sizeof(*params)); - return; - -cleanup: - for (size_t i = 0; i < ARRAY_SIZE(certs_common); i++) { - if (certs_common[i].data) { - k_free(*certs_common[i].data); - *certs_common[i].data = NULL; - } - } - - if (!is_ap) { - for (size_t i = 0; i < ARRAY_SIZE(certs_sta); i++) { - if (certs_sta[i].data) { - k_free(*certs_sta[i].data); - *certs_sta[i].data = NULL; - } - } - } - -} - -static void clear_enterprise_creds_params(struct wifi_enterprise_creds_params *params) -{ - if (params == NULL) { - return; - } - - const uint8_t *certs[] = { - params->ca_cert, - params->client_cert, - params->client_key, - params->ca_cert2, - params->client_cert2, - params->client_key2, - }; - - for (size_t i = 0; i < ARRAY_SIZE(certs); i++) { - k_free((void *)certs[i]); - } - memset(params, 0, sizeof(*params)); -} -#else -static void set_enterprise_creds_params(struct wifi_enterprise_creds_params *params, - bool is_ap) -{ - params->ca_cert = (uint8_t *)ca_cert_test; - params->ca_cert_len = ARRAY_SIZE(ca_cert_test); - - if (!is_ap) { - params->client_cert = (uint8_t *)client_cert_test; - params->client_cert_len = ARRAY_SIZE(client_cert_test); - params->client_key = (uint8_t *)client_key_test; - params->client_key_len = ARRAY_SIZE(client_key_test); - params->ca_cert2 = (uint8_t *)ca_cert2_test; - params->ca_cert2_len = ARRAY_SIZE(ca_cert2_test); - params->client_cert2 = (uint8_t *)client_cert2_test; - params->client_cert2_len = ARRAY_SIZE(client_cert2_test); - params->client_key2 = (uint8_t *)client_key2_test; - params->client_key2_len = ARRAY_SIZE(client_key2_test); - - return; - } -} -#endif /* CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES */ - -static int wifi_set_enterprise_creds(const struct shell *sh, struct net_if *iface, - bool is_ap) -{ - struct wifi_enterprise_creds_params params = {0}; - -#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES - clear_enterprise_creds_params(&enterprise_creds_params); -#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ - - set_enterprise_creds_params(¶ms, is_ap); - - if (net_mgmt(NET_REQUEST_WIFI_ENTERPRISE_CREDS, iface, ¶ms, sizeof(params))) { - shell_warn(sh, "Set enterprise credentials failed\n"); - return -1; - } - - return 0; -} -#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ - static void print_network_info(void *cb_arg, const char *ssid, size_t ssid_len) { int ret = 0; @@ -530,7 +298,7 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[]) creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_GTC || creds.header.type == WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2 || creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_TLS) { - wifi_set_enterprise_creds(sh, iface, 0); + wifi_set_enterprise_credentials(iface, 0); } #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ @@ -553,7 +321,7 @@ static int cmd_delete_network(const struct shell *sh, size_t argc, char *argv[]) #ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES /* Clear the certificates */ - clear_enterprise_creds_params(&enterprise_creds_params); + wifi_clear_enterprise_credentials(); #endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */ return wifi_credentials_delete_by_ssid(argv[1], strlen(argv[1])); @@ -572,7 +340,7 @@ static int cmd_auto_connect(const struct shell *sh, size_t argc, char *argv[]) struct net_if *iface = net_if_get_wifi_sta(); #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE - wifi_set_enterprise_creds(sh, iface, 0); + wifi_set_enterprise_credentials(iface, 0); #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */ int rc = net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, NULL, 0); diff --git a/west.yml b/west.yml index 91d959de4fba..042f342209a2 100644 --- a/west.yml +++ b/west.yml @@ -281,7 +281,7 @@ manifest: - hal - name: hostap path: modules/lib/hostap - revision: bc5d22f5838d017b889d1452a5854f9a32895414 + revision: pull/92/head - name: liblc3 revision: 48bbd3eacd36e99a57317a0a4867002e0b09e183 path: modules/lib/liblc3