Skip to content

Commit bc8e79b

Browse files
committed
[nrf fromlist] net: lib: wifi_credentials: Add support for Enterprise security
Add support for configuring enterprise mode security. Upstream PR #: 88653 Signed-off-by: Ravi Dondaputi <[email protected]>
1 parent 5b1c2c0 commit bc8e79b

File tree

1 file changed

+203
-14
lines changed

1 file changed

+203
-14
lines changed

subsys/net/lib/wifi_credentials/wifi_credentials_shell.c

+203-14
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,27 @@
2626
#define MACSTR "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
2727

2828
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
29+
#ifdef CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES
30+
#include <zephyr/net/tls_credentials.h>
31+
enum wifi_enterprise_cert_sec_tags {
32+
WIFI_CERT_CA_SEC_TAG = 0x1020001,
33+
WIFI_CERT_CLIENT_KEY_SEC_TAG,
34+
WIFI_CERT_SERVER_KEY_SEC_TAG,
35+
WIFI_CERT_CLIENT_SEC_TAG,
36+
WIFI_CERT_SERVER_SEC_TAG,
37+
/* Phase 2 */
38+
WIFI_CERT_CA_P2_SEC_TAG,
39+
WIFI_CERT_CLIENT_KEY_P2_SEC_TAG,
40+
WIFI_CERT_CLIENT_P2_SEC_TAG,
41+
};
42+
43+
struct wifi_cert_data {
44+
enum tls_credential_type type;
45+
uint32_t sec_tag;
46+
uint8_t **data;
47+
size_t *len;
48+
};
49+
#else
2950
static const char ca_cert_test[] = {
3051
#include <wifi_enterprise_test_certs/ca.pem.inc>
3152
'\0'
@@ -52,25 +73,183 @@ static const char client_cert2_test[] = {
5273
static const char client_key2_test[] = {
5374
#include <wifi_enterprise_test_certs/client-key2.pem.inc>
5475
'\0'};
76+
#endif /* CONFIG_WIFI_CREDENTIALS_RUNTIME_CERTIFICATES */
5577
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */
5678

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

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

75254
if (net_mgmt(NET_REQUEST_WIFI_ENTERPRISE_CREDS, iface, &params, sizeof(params))) {
76255
shell_warn(sh, "Set enterprise credentials failed\n");
@@ -348,7 +527,7 @@ static int cmd_add_network(const struct shell *sh, size_t argc, char *argv[])
348527
creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_GTC ||
349528
creds.header.type == WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2 ||
350529
creds.header.type == WIFI_SECURITY_TYPE_EAP_PEAP_TLS) {
351-
cmd_wifi_set_enterprise_creds(sh, iface);
530+
wifi_set_enterprise_creds(sh, iface, 0);
352531
}
353532
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */
354533

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

370549
shell_print(sh, "\tDeleting network ssid: \"%s\", ssid_len: %d", argv[1], strlen(argv[1]));
550+
551+
#ifdef CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES
552+
/* Clear the certificates */
553+
clear_enterprise_creds_params(&enterprise_creds_params);
554+
#endif /* CONFIG_WIFI_SHELL_RUNTIME_CERTIFICATES */
555+
371556
return wifi_credentials_delete_by_ssid(argv[1], strlen(argv[1]));
372557
}
373558

@@ -382,6 +567,10 @@ static int cmd_list_networks(const struct shell *sh, size_t argc, char *argv[])
382567
static int cmd_auto_connect(const struct shell *sh, size_t argc, char *argv[])
383568
{
384569
struct net_if *iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET));
570+
571+
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
572+
wifi_set_enterprise_creds(sh, iface, 0);
573+
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE */
385574
int rc = net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, NULL, 0);
386575

387576
if (rc) {

0 commit comments

Comments
 (0)