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,184 @@ 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 ,
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+ * certs_common [i ].data = NULL ;
188+ }
189+ }
190+
191+ if (!is_ap ) {
192+ for (size_t i = 0 ; i < ARRAY_SIZE (certs_sta ); i ++ ) {
193+ if (certs_sta [i ].data ) {
194+ k_free (* certs_sta [i ].data );
195+ * certs_sta [i ].data = NULL ;
196+ }
197+ }
198+ }
199+
200+ }
201+
202+ static void clear_enterprise_creds_params (struct wifi_enterprise_creds_params * params )
203+ {
204+ if (params == NULL ) {
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 (size_t 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
382570static 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