Skip to content

Commit 6e740d6

Browse files
committed
[nrf fromlist] net: lib: wifi_credentials: Add support for Enterprise security
Add support for configuring enterprise mode security. Fixes SHEL-3573. Upstream PR #: 88653 Signed-off-by: Ravi Dondaputi <[email protected]>
1 parent 000bf2d commit 6e740d6

File tree

2 files changed

+234
-16
lines changed

2 files changed

+234
-16
lines changed

subsys/net/lib/wifi_credentials/Kconfig

+26
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,32 @@ config WIFI_CREDENTIALS_CONNECT_STORED_CONNECTION_TIMEOUT
7373
help
7474
Wait period before falling back to the next entry in the list of stored SSIDs.
7575

76+
77+
if WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
78+
79+
config WIFI_CREDENTIALS_RUNTIME_CERTIFICATES
80+
bool "Provide Wi-Fi enterprise security certificates at run-time"
81+
select TLS_CREDENTIALS
82+
select TLS_CREDENTIALS_SHELL
83+
select BASE64
84+
default y if WIFI_SHELL_RUNTIME_CERTIFICATES
85+
help
86+
This option enables providing Wi-Fi enterprise security certificates at run-time.
87+
Uses the TLS credentials subsystem to store and manage the certificates.
88+
89+
if WIFI_CREDENTIALS_RUNTIME_CERTIFICATES
90+
91+
config HEAP_MEM_POOL_ADD_SIZE_WIFI_CERT
92+
int "Wi-Fi enterprise security certificates memory pool size"
93+
# STA - 6 certs and each assume 1500 bytes
94+
default 12000
95+
help
96+
The size of the memory pool used by the Wi-Fi enterprise security certificates.
97+
98+
endif # WIFI_CREDENTIALS_RUNTIME_CERTIFICATES
99+
100+
endif # WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
101+
76102
endif # WIFI_CREDENTIALS_CONNECT_STORED
77103

78104
endif # WIFI_CREDENTIALS

subsys/net/lib/wifi_credentials/wifi_credentials_shell.c

+208-16
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,33 @@
2222

2323
#include <zephyr/net/wifi_credentials.h>
2424

25+
LOG_MODULE_REGISTER(wifi_credentials_shell, CONFIG_WIFI_CREDENTIALS_LOG_LEVEL);
26+
2527
#define MAX_BANDS_STR_LEN 64
2628
#define MACSTR "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
2729

2830
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
31+
#ifdef CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES
32+
#include <zephyr/net/tls_credentials.h>
33+
enum wifi_enterprise_cert_sec_tags {
34+
WIFI_CERT_CA_SEC_TAG = 0x1020001,
35+
WIFI_CERT_CLIENT_KEY_SEC_TAG,
36+
WIFI_CERT_SERVER_KEY_SEC_TAG,
37+
WIFI_CERT_CLIENT_SEC_TAG,
38+
WIFI_CERT_SERVER_SEC_TAG,
39+
/* Phase 2 */
40+
WIFI_CERT_CA_P2_SEC_TAG,
41+
WIFI_CERT_CLIENT_KEY_P2_SEC_TAG,
42+
WIFI_CERT_CLIENT_P2_SEC_TAG,
43+
};
44+
45+
struct wifi_cert_data {
46+
enum tls_credential_type type;
47+
uint32_t sec_tag;
48+
uint8_t **data;
49+
size_t *len;
50+
};
51+
#else
2952
static const char ca_cert_test[] = {
3053
#include <wifi_enterprise_test_certs/ca.pem.inc>
3154
'\0'
@@ -52,25 +75,184 @@ static const char client_cert2_test[] = {
5275
static const char client_key2_test[] = {
5376
#include <wifi_enterprise_test_certs/client-key2.pem.inc>
5477
'\0'};
78+
#endif /* CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES */
5579
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */
5680

5781
#if defined CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
58-
static int cmd_wifi_set_enterprise_creds(const struct shell *sh, struct net_if *iface)
82+
#ifdef CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES
83+
84+
struct wifi_enterprise_creds_params enterprise_creds_params;
85+
86+
static int process_certificates(struct wifi_cert_data *certs, size_t cert_count)
87+
{
88+
for (size_t i = 0; i < cert_count; i++) {
89+
int err;
90+
size_t len = 0;
91+
uint8_t *cert_tmp;
92+
93+
err = tls_credential_get(certs[i].sec_tag, certs[i].type, NULL, &len);
94+
if (err != -EFBIG) {
95+
LOG_ERR("Failed to get credential tag: %d length, err: %d",
96+
certs[i].sec_tag, err);
97+
return err;
98+
}
99+
100+
cert_tmp = k_malloc(len);
101+
if (!cert_tmp) {
102+
LOG_ERR("Failed to allocate memory for credential tag: %d",
103+
certs[i].sec_tag);
104+
return -ENOMEM;
105+
}
106+
107+
err = tls_credential_get(certs[i].sec_tag, certs[i].type, cert_tmp, &len);
108+
if (err) {
109+
LOG_ERR("Failed to get credential tag: %d", certs[i].sec_tag);
110+
k_free(cert_tmp);
111+
return err;
112+
}
113+
114+
*certs[i].data = cert_tmp;
115+
*certs[i].len = len;
116+
}
117+
118+
return 0;
119+
}
120+
121+
static void set_enterprise_creds_params(struct wifi_enterprise_creds_params *params,
122+
bool is_ap)
123+
{
124+
struct wifi_cert_data certs_common[] = {
125+
{
126+
.type = TLS_CREDENTIAL_CA_CERTIFICATE,
127+
.sec_tag = WIFI_CERT_CA_SEC_TAG,
128+
.data = &params->ca_cert,
129+
.len = &params->ca_cert_len,
130+
},
131+
};
132+
133+
struct wifi_cert_data certs_sta[] = {
134+
{
135+
.type = TLS_CREDENTIAL_PRIVATE_KEY,
136+
.sec_tag = WIFI_CERT_CLIENT_KEY_SEC_TAG,
137+
.data = &params->client_key,
138+
.len = &params->client_key_len,
139+
},
140+
{
141+
.type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE,
142+
.sec_tag = WIFI_CERT_CLIENT_SEC_TAG,
143+
.data = &params->client_cert,
144+
.len = &params->client_cert_len,
145+
},
146+
{
147+
.type = TLS_CREDENTIAL_CA_CERTIFICATE,
148+
.sec_tag = WIFI_CERT_CA_P2_SEC_TAG,
149+
.data = &params->ca_cert2,
150+
.len = &params->ca_cert2_len,
151+
},
152+
{
153+
.type = TLS_CREDENTIAL_PRIVATE_KEY,
154+
.sec_tag = WIFI_CERT_CLIENT_KEY_P2_SEC_TAG,
155+
.data = &params->client_key2,
156+
.len = &params->client_key2_len,
157+
},
158+
{
159+
.type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE,
160+
.sec_tag = WIFI_CERT_CLIENT_P2_SEC_TAG,
161+
.data = &params->client_cert2,
162+
.len = &params->client_cert2_len,
163+
},
164+
};
165+
166+
memset(params, 0, sizeof(*params));
167+
168+
/* Process common certificates */
169+
if (process_certificates(certs_common, ARRAY_SIZE(certs_common)) != 0) {
170+
goto cleanup;
171+
}
172+
173+
/* Process STA-specific certificates */
174+
if (!is_ap) {
175+
if (process_certificates(certs_sta, ARRAY_SIZE(certs_sta)) != 0) {
176+
goto cleanup;
177+
}
178+
}
179+
180+
memcpy(&enterprise_creds_params, params, sizeof(*params));
181+
return;
182+
183+
cleanup:
184+
for (size_t i = 0; i < ARRAY_SIZE(certs_common); i++) {
185+
if (certs_common[i].data) {
186+
k_free(*certs_common[i].data);
187+
}
188+
}
189+
190+
if (!is_ap) {
191+
for (size_t i = 0; i < ARRAY_SIZE(certs_sta); i++) {
192+
if (certs_sta[i].data) {
193+
k_free(*certs_sta[i].data);
194+
}
195+
}
196+
}
197+
198+
}
199+
200+
static void clear_enterprise_creds_params(struct wifi_enterprise_creds_params *params)
201+
{
202+
size_t i;
203+
204+
if (!params) {
205+
return;
206+
}
207+
208+
const uint8_t *certs[] = {
209+
params->ca_cert,
210+
params->client_cert,
211+
params->client_key,
212+
params->ca_cert2,
213+
params->client_cert2,
214+
params->client_key2,
215+
};
216+
217+
for (i = 0; i < ARRAY_SIZE(certs); i++) {
218+
k_free((void *)certs[i]);
219+
}
220+
memset(params, 0, sizeof(*params));
221+
}
222+
#else
223+
static void set_enterprise_creds_params(struct wifi_enterprise_creds_params *params,
224+
bool is_ap)
225+
{
226+
params->ca_cert = (uint8_t *)ca_cert_test;
227+
params->ca_cert_len = ARRAY_SIZE(ca_cert_test);
228+
229+
if (!is_ap) {
230+
params->client_cert = (uint8_t *)client_cert_test;
231+
params->client_cert_len = ARRAY_SIZE(client_cert_test);
232+
params->client_key = (uint8_t *)client_key_test;
233+
params->client_key_len = ARRAY_SIZE(client_key_test);
234+
params->ca_cert2 = (uint8_t *)ca_cert2_test;
235+
params->ca_cert2_len = ARRAY_SIZE(ca_cert2_test);
236+
params->client_cert2 = (uint8_t *)client_cert2_test;
237+
params->client_cert2_len = ARRAY_SIZE(client_cert2_test);
238+
params->client_key2 = (uint8_t *)client_key2_test;
239+
params->client_key2_len = ARRAY_SIZE(client_key2_test);
240+
241+
return;
242+
}
243+
}
244+
#endif /* CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES */
245+
246+
static int wifi_set_enterprise_creds(const struct shell *sh, struct net_if *iface,
247+
bool is_ap)
59248
{
60249
struct wifi_enterprise_creds_params params = {0};
61250

62-
params.ca_cert = (uint8_t *)ca_cert_test;
63-
params.ca_cert_len = ARRAY_SIZE(ca_cert_test);
64-
params.client_cert = (uint8_t *)client_cert_test;
65-
params.client_cert_len = ARRAY_SIZE(client_cert_test);
66-
params.client_key = (uint8_t *)client_key_test;
67-
params.client_key_len = ARRAY_SIZE(client_key_test);
68-
params.ca_cert2 = (uint8_t *)ca_cert2_test;
69-
params.ca_cert2_len = ARRAY_SIZE(ca_cert2_test);
70-
params.client_cert2 = (uint8_t *)client_cert2_test;
71-
params.client_cert2_len = ARRAY_SIZE(client_cert2_test);
72-
params.client_key2 = (uint8_t *)client_key2_test;
73-
params.client_key2_len = ARRAY_SIZE(client_key2_test);
251+
#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES
252+
clear_enterprise_creds_params(&enterprise_creds_params);
253+
#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */
254+
255+
set_enterprise_creds_params(&params, is_ap);
74256

75257
if (net_mgmt(NET_REQUEST_WIFI_ENTERPRISE_CREDS, iface, &params, sizeof(params))) {
76258
shell_warn(sh, "Set enterprise credentials failed\n");
@@ -340,15 +522,15 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[])
340522
}
341523

342524
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
343-
struct net_if *iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET));
525+
struct net_if *iface = net_if_get_wifi_sta();
344526

345527
/* Load the enterprise credentials if needed */
346528
if (creds.header.type == WIFI_SECURITY_TYPE_EAP_TLS ||
347529
creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_MSCHAPV2 ||
348530
creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_GTC ||
349531
creds.header.type == WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2 ||
350532
creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_TLS) {
351-
cmd_wifi_set_enterprise_creds(sh, iface);
533+
wifi_set_enterprise_creds(sh, iface, 0);
352534
}
353535
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */
354536

@@ -368,6 +550,12 @@ static int cmd_delete_network(const struct shell *sh, size_t argc, char *argv[])
368550
}
369551

370552
shell_print(sh, "\tDeleting network ssid: \"%s\", ssid_len: %d", argv[1], strlen(argv[1]));
553+
554+
#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES
555+
/* Clear the certificates */
556+
clear_enterprise_creds_params(&enterprise_creds_params);
557+
#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */
558+
371559
return wifi_credentials_delete_by_ssid(argv[1], strlen(argv[1]));
372560
}
373561

@@ -381,7 +569,11 @@ static int cmd_list_networks(const struct shell *sh, size_t argc, char *argv[])
381569

382570
static int cmd_auto_connect(const struct shell *sh, size_t argc, char *argv[])
383571
{
384-
struct net_if *iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET));
572+
struct net_if *iface = net_if_get_wifi_sta();
573+
574+
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
575+
wifi_set_enterprise_creds(sh, iface, 0);
576+
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */
385577
int rc = net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, NULL, 0);
386578

387579
if (rc) {

0 commit comments

Comments
 (0)