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
2952static 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[] = {
5275static 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[])
382569static 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