Skip to content

Commit 9f04eb6

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 e157f2f commit 9f04eb6

File tree

2 files changed

+230
-14
lines changed

2 files changed

+230
-14
lines changed

subsys/net/lib/wifi_credentials/Kconfig

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,31 @@ 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+
help
85+
This option enables providing Wi-Fi enterprise security certificates at run-time.
86+
Uses the TLS credentials subsystem to store and manage the certificates.
87+
88+
if WIFI_CREDENTIALS_RUNTIME_CERTIFICATES
89+
90+
config HEAP_MEM_POOL_ADD_SIZE_WIFI_CERT
91+
int "Wi-Fi enterprise security certificates memory pool size"
92+
# STA - 6 certs and each assume 1500 bytes
93+
default 12000
94+
help
95+
The size of the memory pool used by the Wi-Fi enterprise security certificates.
96+
97+
endif # WIFI_CREDENTIALS_RUNTIME_CERTIFICATES
98+
99+
endif # WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
100+
76101
endif # WIFI_CREDENTIALS_CONNECT_STORED
77102

78103
endif # WIFI_CREDENTIALS

subsys/net/lib/wifi_credentials/wifi_credentials_shell.c

Lines changed: 205 additions & 14 deletions
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,183 @@ 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,.len = &params->ca_cert2_len,
150+
},
151+
{
152+
.type = TLS_CREDENTIAL_PRIVATE_KEY,
153+
.sec_tag = WIFI_CERT_CLIENT_KEY_P2_SEC_TAG,
154+
.data = &params->client_key2,
155+
.len = &params->client_key2_len,
156+
},
157+
{
158+
.type = TLS_CREDENTIAL_PUBLIC_CERTIFICATE,
159+
.sec_tag = WIFI_CERT_CLIENT_P2_SEC_TAG,
160+
.data = &params->client_cert2,
161+
.len = &params->client_cert2_len,
162+
},
163+
};
164+
165+
memset(params, 0, sizeof(*params));
166+
167+
/* Process common certificates */
168+
if (process_certificates(certs_common, ARRAY_SIZE(certs_common)) != 0) {
169+
goto cleanup;
170+
}
171+
172+
/* Process STA-specific certificates */
173+
if (!is_ap) {
174+
if (process_certificates(certs_sta, ARRAY_SIZE(certs_sta)) != 0) {
175+
goto cleanup;
176+
}
177+
}
178+
179+
memcpy(&enterprise_creds_params, params, sizeof(*params));
180+
return;
181+
182+
cleanup:
183+
for (size_t i = 0; i < ARRAY_SIZE(certs_common); i++) {
184+
if (certs_common[i].data) {
185+
k_free(*certs_common[i].data);
186+
}
187+
}
188+
189+
if (!is_ap) {
190+
for (size_t i = 0; i < ARRAY_SIZE(certs_sta); i++) {
191+
if (certs_sta[i].data) {
192+
k_free(*certs_sta[i].data);
193+
}
194+
}
195+
}
196+
197+
}
198+
199+
static void clear_enterprise_creds_params(struct wifi_enterprise_creds_params *params)
200+
{
201+
size_t i;
202+
203+
if (!params) {
204+
return;
205+
}
206+
207+
const uint8_t *certs[] = {
208+
params->ca_cert,
209+
params->client_cert,
210+
params->client_key,
211+
params->ca_cert2,
212+
params->client_cert2,
213+
params->client_key2,
214+
};
215+
216+
for (i = 0; i < ARRAY_SIZE(certs); i++) {
217+
k_free((void *)certs[i]);
218+
}
219+
memset(params, 0, sizeof(*params));
220+
}
221+
#else
222+
static void set_enterprise_creds_params(struct wifi_enterprise_creds_params *params,
223+
bool is_ap)
224+
{
225+
params->ca_cert = (uint8_t *)ca_cert_test;
226+
params->ca_cert_len = ARRAY_SIZE(ca_cert_test);
227+
228+
if (!is_ap) {
229+
params->client_cert = (uint8_t *)client_cert_test;
230+
params->client_cert_len = ARRAY_SIZE(client_cert_test);
231+
params->client_key = (uint8_t *)client_key_test;
232+
params->client_key_len = ARRAY_SIZE(client_key_test);
233+
params->ca_cert2 = (uint8_t *)ca_cert2_test;
234+
params->ca_cert2_len = ARRAY_SIZE(ca_cert2_test);
235+
params->client_cert2 = (uint8_t *)client_cert2_test;
236+
params->client_cert2_len = ARRAY_SIZE(client_cert2_test);
237+
params->client_key2 = (uint8_t *)client_key2_test;
238+
params->client_key2_len = ARRAY_SIZE(client_key2_test);
239+
240+
return;
241+
}
242+
}
243+
#endif /* CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES */
244+
245+
static int wifi_set_enterprise_creds(const struct shell *sh, struct net_if *iface,
246+
bool is_ap)
59247
{
60248
struct wifi_enterprise_creds_params params = {0};
61249

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);
250+
#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES
251+
clear_enterprise_creds_params(&enterprise_creds_params);
252+
#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */
253+
254+
set_enterprise_creds_params(&params, is_ap);
74255

75256
if (net_mgmt(NET_REQUEST_WIFI_ENTERPRISE_CREDS, iface, &params, sizeof(params))) {
76257
shell_warn(sh, "Set enterprise credentials failed\n");
@@ -348,7 +529,7 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[])
348529
creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_GTC ||
349530
creds.header.type == WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2 ||
350531
creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_TLS) {
351-
cmd_wifi_set_enterprise_creds(sh, iface);
532+
wifi_set_enterprise_creds(sh, iface, 0);
352533
}
353534
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */
354535

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

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

@@ -382,6 +569,10 @@ static int cmd_list_networks(const struct shell *sh, size_t argc, char *argv[])
382569
static int cmd_auto_connect(const struct shell *sh, size_t argc, char *argv[])
383570
{
384571
struct net_if *iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET));
572+
573+
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
574+
wifi_set_enterprise_creds(sh, iface, 0);
575+
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */
385576
int rc = net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, NULL, 0);
386577

387578
if (rc) {

0 commit comments

Comments
 (0)