11#pragma once
22
33#include " zephyr/sys/printk.h"
4+ #if defined(CONFIG_FILE_SYSTEM)
5+ #include < zephyr/fs/fs.h>
6+ #endif
7+
48#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
59#include < zephyr/net/tls_credentials.h>
6- #define CA_CERTIFICATE_TAG 1
10+ #define CA_CERTIFICATE_TAG_BASE 1
711#endif
812
913#include < zephyr/net/socket.h>
@@ -14,6 +18,47 @@ class ZephyrSocketWrapper {
1418 bool is_ssl = false ;
1519 int ssl_sock_temp_char = -1 ;
1620
21+ #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) && defined(CONFIG_FILE_SYSTEM)
22+ inline static char *cadata = nullptr ;
23+
24+ bool loadCADataFromFS (const char *cert_path = " /wlan:/cacert.pem" ) {
25+ struct fs_file_t file;
26+ fs_file_t_init (&file);
27+
28+ if (fs_open (&file, cert_path, FS_O_READ) != 0 ) {
29+ return false ;
30+ }
31+
32+ // Get file size
33+ struct fs_dirent entry;
34+ if (fs_stat (cert_path, &entry) != 0 ) {
35+ fs_close (&file);
36+ return false ;
37+ }
38+
39+ size_t file_size = entry.size ;
40+
41+ // Allocate buffer for entire file
42+ cadata = (char *)k_malloc (file_size);
43+ if (!cadata) {
44+ fs_close (&file);
45+ return false ;
46+ }
47+
48+ // Read entire file
49+ ssize_t bytes_read = fs_read (&file, cadata, file_size);
50+ fs_close (&file);
51+
52+ if (bytes_read != file_size) {
53+ k_free (cadata);
54+ cadata = nullptr ;
55+ return false ;
56+ }
57+
58+ return true ;
59+ }
60+ #endif
61+
1762public:
1863 ZephyrSocketWrapper () : sock_fd(-1 ) {
1964 }
@@ -102,7 +147,7 @@ class ZephyrSocketWrapper {
102147 }
103148
104149#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
105- bool connectSSL (const char *host, uint16_t port, const char *ca_certificate_pem = nullptr ) {
150+ bool connectSSL (const char *host, uint16_t port, const char *cert = nullptr ) {
106151
107152 // Resolve address
108153 struct addrinfo hints = {0 };
@@ -115,9 +160,9 @@ class ZephyrSocketWrapper {
115160 int ret;
116161 bool rv = false ;
117162
118- sec_tag_t sec_tag_opt[] = {
119- CA_CERTIFICATE_TAG,
120- } ;
163+ sec_tag_t sec_tag_opt[2 ];
164+ int tag_count = 0 ;
165+ int tag = CA_CERTIFICATE_TAG_BASE ;
121166
122167 struct timeval timeout_opt = {
123168 .tv_sec = 0 ,
@@ -138,21 +183,39 @@ class ZephyrSocketWrapper {
138183 goto exit;
139184 }
140185
141- if (ca_certificate_pem != nullptr ) {
142- ret = tls_credential_add (CA_CERTIFICATE_TAG, TLS_CREDENTIAL_CA_CERTIFICATE,
143- ca_certificate_pem, strlen (ca_certificate_pem) + 1 );
144- if (ret != 0 ) {
186+ #if defined(CONFIG_FILE_SYSTEM)
187+ // Try to load builtin CA from filesystem (once)
188+ if (cadata == nullptr && loadCADataFromFS ()) {
189+ // Successfully loaded, add with tag (ignore errors)
190+ if (tls_credential_add (tag++, TLS_CREDENTIAL_CA_CERTIFICATE, cadata,
191+ strlen (cadata) + 1 )) {
145192 goto exit;
146193 }
147194 }
195+ #endif
196+
197+ // Add custom CA if provided (uses next available tag)
198+ if (cert != nullptr ) {
199+ if (tls_credential_add (tag++, TLS_CREDENTIAL_CA_CERTIFICATE, cert, strlen (cert) + 1 ) !=
200+ 0 ) {
201+ goto exit;
202+ }
203+ }
204+
205+ // Build sequential tag list
206+ tag_count = tag - CA_CERTIFICATE_TAG_BASE;
207+ for (int i = 0 ; i < tag_count; i++) {
208+ sec_tag_opt[i] = CA_CERTIFICATE_TAG_BASE + i;
209+ }
148210
149211 sock_fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2);
150212 if (sock_fd < 0 ) {
151213 goto exit;
152214 }
153215
154216 if (setsockopt (sock_fd, SOL_TLS, TLS_HOSTNAME, host, strlen (host)) ||
155- setsockopt (sock_fd, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_opt, sizeof (sec_tag_opt)) ||
217+ setsockopt (sock_fd, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_opt,
218+ sizeof (sec_tag_t ) * tag_count) ||
156219 setsockopt (sock_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout_opt, sizeof (timeout_opt))) {
157220 goto exit;
158221 }
0 commit comments