Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 78 additions & 24 deletions include/zephyr/net/wifi_credentials.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,19 @@
#include <zephyr/net/wifi.h>
#include <zephyr/kernel.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Library that provides a way to store and load Wi-Fi credentials.
* @defgroup wifi_credentials Wi-Fi credentials library
* @ingroup networking
* @since 4.0
* @version 0.1.0
* @{
* @brief Library that provides a way to store and load Wi-Fi credentials.
*/

#ifdef __cplusplus
extern "C" {
#endif

/* this entry contains a BSSID */
#define WIFI_CREDENTIALS_FLAG_BSSID BIT(0)
Expand All @@ -32,11 +33,18 @@ extern "C" {
#define WIFI_CREDENTIALS_FLAG_2_4GHz BIT(2)
/* this entry can use the 5 GHz band */
#define WIFI_CREDENTIALS_FLAG_5GHz BIT(3)
/* this entry can use the 6 GHz band */
#define WIFI_CREDENTIALS_FLAG_6GHz BIT(4)
/* this entry requires management frame protection */
#define WIFI_CREDENTIALS_FLAG_MFP_REQUIRED BIT(4)
#define WIFI_CREDENTIALS_FLAG_MFP_REQUIRED BIT(5)
/* this entry disables management frame protection */
#define WIFI_CREDENTIALS_FLAG_MFP_DISABLED BIT(5)
#define WIFI_CREDENTIALS_FLAG_MFP_DISABLED BIT(6)
/* this entry has anonymous identity configured */
#define WIFI_CREDENTIALS_FLAG_ANONYMOUS_IDENTITY BIT(7)
/* this entry has key password configured */
#define WIFI_CREDENTIALS_FLAG_KEY_PASSWORD BIT(8)

/* Maximum length of the password */
#define WIFI_CREDENTIALS_MAX_PASSWORD_LEN \
MAX(WIFI_PSK_MAX_LEN, CONFIG_WIFI_CREDENTIALS_SAE_PASSWORD_LENGTH)

Expand All @@ -49,13 +57,38 @@ extern "C" {
*
*/
struct wifi_credentials_header {
enum wifi_security_type type; /**< Wi-Fi security type */
char ssid[WIFI_SSID_MAX_LEN]; /**< SSID (Service Set Identifier) */
size_t ssid_len; /**< Length of the SSID */
uint32_t flags; /**< Flags for controlling detail settings */
uint32_t timeout; /**< Timeout for connecting to the network */
uint8_t bssid[WIFI_MAC_ADDR_LEN]; /**< BSSID (Basic Service Set Identifier) */
uint8_t channel; /**< Channel on which the network operates */
/** Wi-Fi security type */
enum wifi_security_type type;

/** SSID (Service Set Identifier) */
char ssid[WIFI_SSID_MAX_LEN];

/** Length of the SSID */
size_t ssid_len;

/** Flags for controlling detail settings */
uint32_t flags;

/** Timeout for connecting to the network */
uint32_t timeout;

/** BSSID (Basic Service Set Identifier) */
uint8_t bssid[WIFI_MAC_ADDR_LEN];

/** Channel on which the network operates */
uint8_t channel;

/** Anonymous identifier (Limited to 16 bytes due to settings subsystem overflow) */
char anon_id[16];

/** Length of the Anonymous identifier */
uint8_t aid_length;

/** Password/PSK (Limited to 16 bytes due to settings subsystem overflow) */
char key_passwd[16];

/** Length of the Password */
uint8_t key_passwd_length;
};

/**
Expand All @@ -67,24 +100,44 @@ struct wifi_credentials_header {
*
*/
struct wifi_credentials_personal {
struct wifi_credentials_header header; /**< Header */
char password[WIFI_CREDENTIALS_MAX_PASSWORD_LEN]; /**< Password/PSK */
size_t password_len; /**< Length of the password */
/** Header */
struct wifi_credentials_header header;

/** Password/PSK */
char password[WIFI_CREDENTIALS_MAX_PASSWORD_LEN];

/** Length of the password */
size_t password_len;
};

/**
* @brief Wi-Fi Enterprise credentials entry
* @note This functionality is not yet implemented.
*/
struct wifi_credentials_enterprise {
struct wifi_credentials_header header; /**< Header */
size_t identity_len; /**< Length of the identity */
size_t anonymous_identity_len; /**< Length of the anonymous identity */
size_t password_len; /**< Length of the password */
size_t ca_cert_len; /**< Length of the CA certificate */
size_t client_cert_len; /**< Length of the client certificate */
size_t private_key_len; /**< Length of the private key */
size_t private_key_pw_len; /**< Length of the private key password */
/** Header */
struct wifi_credentials_header header;

/** Length of the identity */
size_t identity_len;

/** Length of the anonymous identity */
size_t anonymous_identity_len;

/** Length of the password */
size_t password_len;

/** Length of the CA certificate */
size_t ca_cert_len;

/** Length of the client certificate */
size_t client_cert_len;

/** Length of the private key */
size_t private_key_len;

/** Length of the private key password */
size_t private_key_pw_len;
};

/**
Expand Down Expand Up @@ -194,6 +247,7 @@ int wifi_credentials_delete_all(void);

/**
* @brief Callback type for wifi_credentials_for_each_ssid.
*
* @param[in] cb_arg arguments for the callback function. Appropriate cb_arg is
* transferred by wifi_credentials_for_each_ssid.
* @param[in] ssid SSID
Expand Down
33 changes: 33 additions & 0 deletions subsys/net/l2/wifi/wifi_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,9 @@ static int __stored_creds_to_params(struct wifi_credentials_personal *creds,
{
char *ssid = NULL;
char *psk = NULL;
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
char *key_passwd = NULL;
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */
int ret;

/* SSID */
Expand Down Expand Up @@ -1357,6 +1360,29 @@ static int __stored_creds_to_params(struct wifi_credentials_personal *creds,
/* Defaults */
params->security = creds->header.type;

#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
if (params->security == WIFI_SECURITY_TYPE_EAP_TLS) {
if (creds->header.key_passwd_length > 0) {
key_passwd = (char *)k_malloc(creds->header.key_passwd_length + 1);
if (!key_passwd) {
LOG_ERR("Failed to allocate memory for key_passwd\n");
ret = -ENOMEM;
goto err_out;
}
memset(key_passwd, 0, creds->header.key_passwd_length + 1);
ret = snprintf(key_passwd, creds->header.key_passwd_length + 1, "%s",
creds->header.key_passwd);
if (ret > creds->header.key_passwd_length) {
LOG_ERR("key_passwd string truncated\n");
ret = -EINVAL;
goto err_out;
}
params->key_passwd = key_passwd;
params->key_passwd_length = creds->header.key_passwd_length;
}
}
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */

/* If channel is set to 0 we default to ANY. 0 is not a valid Wi-Fi channel. */
params->channel = (creds->header.channel != 0) ? creds->header.channel : WIFI_CHANNEL_ANY;
params->timeout = (creds->header.timeout != 0)
Expand Down Expand Up @@ -1397,6 +1423,13 @@ static int __stored_creds_to_params(struct wifi_credentials_personal *creds,
psk = NULL;
}

#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
if (key_passwd) {
k_free(key_passwd);
key_passwd = NULL;
}
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */

return ret;
}

Expand Down
40 changes: 40 additions & 0 deletions subsys/net/lib/wifi_credentials/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,43 @@ if(WIFI_CREDENTIALS_STATIC_SSID)
"Static Wi-Fi configuration is used, please remove before deployment!"
)
endif()

if(DEFINED CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE AND NOT DEFINED CONFIG_NET_L2_WIFI_SHELL)
# Wi-Fi Enterprise test certificates handling
set(gen_inc_dir ${ZEPHYR_BINARY_DIR}/misc/generated)
set(gen_dir ${gen_inc_dir}/wifi_enterprise_test_certs)
if(NOT DEFINED WIFI_TEST_CERTS_DIR)
set(WIFI_TEST_CERTS_DIR ${ZEPHYR_BASE}/samples/net/wifi/test_certs/rsa3k)
endif()
# Create output directory for test certs
file(MAKE_DIRECTORY ${gen_dir})

# convert .pem files to array data at build time
zephyr_include_directories(${gen_inc_dir})

foreach(cert_file IN ITEMS
${WIFI_TEST_CERTS_DIR}/client.pem
${WIFI_TEST_CERTS_DIR}/client-key.pem
${WIFI_TEST_CERTS_DIR}/ca.pem
${WIFI_TEST_CERTS_DIR}/client2.pem
${WIFI_TEST_CERTS_DIR}/client-key2.pem
${WIFI_TEST_CERTS_DIR}/ca2.pem
)

if(EXISTS ${cert_file})
get_filename_component(cert_name ${cert_file} NAME)
generate_inc_file_for_target(
app
${cert_file}
${gen_dir}/${cert_name}.inc
)
else()
get_filename_component(cert_name ${cert_file} NAME)
file(WRITE ${gen_dir}/${cert_name}.inc "// Empty file generated because ${cert_file} does not exist\n")
endif()
endforeach()

# Add explicit dependency on app target for ZEPHYR_CURRENT_LIBRARY, so these
# headers are generated at the correct point in the build
add_dependencies(${ZEPHYR_CURRENT_LIBRARY} app)
endif()
2 changes: 2 additions & 0 deletions subsys/net/lib/wifi_credentials/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ config WIFI_CREDENTIALS_SHELL
bool "Shell commands to manage Wi-Fi credentials"
default y
depends on SHELL
select SHELL_GETOPT
select GETOPT_LONG
depends on !WIFI_CREDENTIALS_BACKEND_NONE

config WIFI_CREDENTIALS_CONNECT_STORED
Expand Down
1 change: 1 addition & 0 deletions subsys/net/lib/wifi_credentials/wifi_credentials.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ int wifi_credentials_get_by_ssid_personal_struct(const char *ssid, size_t ssid_l
buf->header.type != WIFI_SECURITY_TYPE_PSK &&
buf->header.type != WIFI_SECURITY_TYPE_PSK_SHA256 &&
buf->header.type != WIFI_SECURITY_TYPE_SAE &&
buf->header.type != WIFI_SECURITY_TYPE_EAP_TLS &&
buf->header.type != WIFI_SECURITY_TYPE_WPA_PSK) {
LOG_ERR("Requested WiFi credentials entry is corrupted");
ret = -EPROTO;
Expand Down
Loading
Loading