@@ -11,6 +11,8 @@ INCBIN(x509_crt_bundle, PATH_CERT_BUNDLE);
11
11
#endif
12
12
13
13
#include " at_handler.h"
14
+ #include " mbedtls/pem.h"
15
+ #include " SSE.h"
14
16
15
17
#ifndef WIFI_CLIENT_DEF_CONN_TIMEOUT_MS
16
18
#define WIFI_CLIENT_DEF_CONN_TIMEOUT_MS (3000 )
@@ -66,6 +68,11 @@ void CAtHandler::add_cmds_wifi_SSL() {
66
68
return chAT::CommandStatus::ERROR;
67
69
}
68
70
71
+ const int internal_sock = the_client.can_delete ;
72
+ if (internal_sock == -1 ) {
73
+ return chAT::CommandStatus::ERROR;
74
+ }
75
+
69
76
bool ca_root_custom = false ;
70
77
int ca_root_size = 0 ;
71
78
if (parser.args .size () >= 2 ){
@@ -78,19 +85,17 @@ void CAtHandler::add_cmds_wifi_SSL() {
78
85
}
79
86
80
87
if (ca_root_custom) {
81
-
82
-
83
- cert_buf = srv.inhibit_read (ca_root_size);
84
- size_t offset = cert_buf.size ();
88
+ clients_ca[internal_sock] = srv.inhibit_read (ca_root_size);
89
+ size_t offset = clients_ca[internal_sock].size ();
85
90
86
91
if (offset < ca_root_size) {
87
92
88
- cert_buf .resize (ca_root_size);
93
+ clients_ca[internal_sock] .resize (ca_root_size);
89
94
do {
90
- offset += serial->read (cert_buf .data () + offset, ca_root_size - offset);
95
+ offset += serial->read (clients_ca[internal_sock] .data () + offset, ca_root_size - offset);
91
96
} while (offset < ca_root_size);
92
97
}
93
- the_client.sslclient ->setCACert ((const char *)cert_buf .data ());
98
+ the_client.sslclient ->setCACert ((const char *)clients_ca[internal_sock] .data ());
94
99
srv.continue_read ();
95
100
} else {
96
101
#ifdef BUNDLED_CA_ROOT_CRT
@@ -110,6 +115,120 @@ void CAtHandler::add_cmds_wifi_SSL() {
110
115
return chAT::CommandStatus::ERROR;
111
116
}
112
117
};
118
+
119
+ /* ....................................................................... */
120
+ command_table[_SETECCSLOT] = [this ](auto & srv, auto & parser) {
121
+ /* ....................................................................... */
122
+ switch (parser.cmd_mode ) {
123
+ case chAT::CommandMode::Write: {
124
+ if (parser.args .size () != 3 ) {
125
+ return chAT::CommandStatus::ERROR;
126
+ }
127
+
128
+ auto &sock_num = parser.args [0 ];
129
+ auto &slot_num = parser.args [1 ];
130
+ auto &cert_len = parser.args [2 ];
131
+ if (sock_num.empty () || slot_num.empty () || cert_len.empty ()) {
132
+ return chAT::CommandStatus::ERROR;
133
+ }
134
+
135
+ int sock = atoi (sock_num.c_str ());
136
+ int size = atoi (cert_len.c_str ());
137
+
138
+ CClientWrapper the_client = getClient (sock);
139
+ if (the_client.sslclient == nullptr ) {
140
+ return chAT::CommandStatus::ERROR;
141
+ }
142
+
143
+ const int internal_sock = the_client.can_delete ;
144
+ if (internal_sock == -1 ) {
145
+ return chAT::CommandStatus::ERROR;
146
+ }
147
+
148
+ std::vector<unsigned char > client_cert_der;
149
+ client_cert_der = srv.inhibit_read (size);
150
+ size_t offset = client_cert_der.size ();
151
+
152
+ if (offset < size) {
153
+ client_cert_der.resize (size);
154
+ do {
155
+ offset += serial->read (client_cert_der.data () + offset, size - offset);
156
+ } while (offset < size);
157
+ }
158
+ srv.continue_read ();
159
+
160
+ #if ECC_DEBUG_ENABLED
161
+ log_v (" _SETECCSLOT: input cert" );
162
+ log_buf_v ((const uint8_t *)client_cert_der.data (), size);
163
+ #endif
164
+
165
+ /* Convert client certificate DER buffer into PEM */
166
+ clients_cert_pem[internal_sock].resize (1024 );
167
+ size_t olen;
168
+ int ret = -1 ;
169
+ if ((ret = mbedtls_pem_write_buffer (" -----BEGIN CERTIFICATE-----\n " ,
170
+ " -----END CERTIFICATE-----\n " ,
171
+ client_cert_der.data (), size,
172
+ clients_cert_pem[internal_sock].data (), 1024 ,
173
+ &olen)) != 0 )
174
+ {
175
+ log_e (" failed\n ! mbedtls_pem_write_buffer returned -0x%04x" , (unsigned int ) -ret);
176
+ clients_cert_pem[internal_sock].clear ();
177
+ return chAT::CommandStatus::ERROR;
178
+ }
179
+ clients_cert_pem[internal_sock].resize (olen);
180
+
181
+ #if ECC_DEBUG_ENABLED
182
+ log_v (" _SETECCSLOT: output cert" );
183
+ log_v (" \n %s" , clients_cert_pem[internal_sock].data ());
184
+ #endif
185
+
186
+ /* Set client certificate */
187
+ the_client.sslclient ->setCertificate ((const char *)clients_cert_pem[internal_sock].data ());
188
+
189
+ /* Read private key from non volatile storage in DER format */
190
+ std::vector<unsigned char > client_key_der;
191
+ int len = sse.getBytesLength (slot_num.c_str ());
192
+ client_key_der.resize (len);
193
+ if ((ret = sse.getBytes (slot_num.c_str (), client_key_der.data (), len)) < len) {
194
+ log_e (" failed\n ! sse.getBytes returned -0x%04x" , (unsigned int ) -ret);
195
+ return chAT::CommandStatus::ERROR;
196
+ }
197
+
198
+ #if ECC_DEBUG_ENABLED
199
+ log_v (" _SETECCSLOT: input key" );
200
+ log_buf_v ((const uint8_t *)client_key_der.data (), ret);
201
+ #endif
202
+
203
+ /* Convert private key in PEM format */
204
+ clients_key_pem[internal_sock].resize (1024 );
205
+ if ((ret = mbedtls_pem_write_buffer (" -----BEGIN EC PRIVATE KEY-----\n " ,
206
+ " -----END EC PRIVATE KEY-----\n " ,
207
+ client_key_der.data (), len,
208
+ clients_key_pem[internal_sock].data (), 1024 ,
209
+ &olen)) != 0 )
210
+ {
211
+ log_e (" failed\n ! mbedtls_pem_write_buffer returned -0x%04x" , (unsigned int ) -ret);
212
+ clients_cert_pem[internal_sock].clear ();
213
+ return chAT::CommandStatus::ERROR;
214
+ }
215
+ clients_key_pem[internal_sock].resize (olen);
216
+
217
+ #if ECC_DEBUG_ENABLED
218
+ log_v (" _SETECCSLOT: output key" );
219
+ log_v (" \n %s" , clients_key_pem[internal_sock].data ());
220
+ #endif
221
+
222
+ /* Set client key */
223
+ the_client.sslclient ->setPrivateKey ((const char *)clients_key_pem[internal_sock].data ());
224
+
225
+ return chAT::CommandStatus::OK;
226
+ }
227
+ default :
228
+ return chAT::CommandStatus::ERROR;
229
+ }
230
+ };
231
+
113
232
/* ....................................................................... */
114
233
command_table[_SSLCLIENTSTATE] = [this ](auto & srv, auto & parser) {
115
234
/* ....................................................................... */
@@ -166,6 +285,11 @@ void CAtHandler::add_cmds_wifi_SSL() {
166
285
return chAT::CommandStatus::ERROR;
167
286
}
168
287
288
+ const int internal_sock = the_client.can_delete ;
289
+ if (internal_sock == -1 ) {
290
+ return chAT::CommandStatus::ERROR;
291
+ }
292
+
169
293
auto &host = parser.args [1 ];
170
294
if (host.empty ()) {
171
295
return chAT::CommandStatus::ERROR;
@@ -176,6 +300,21 @@ void CAtHandler::add_cmds_wifi_SSL() {
176
300
return chAT::CommandStatus::ERROR;
177
301
}
178
302
303
+ /* Set custom root ca */
304
+ if (clients_ca[internal_sock].size ()) {
305
+ the_client.sslclient ->setCACert ((const char *)clients_ca[internal_sock].data ());
306
+ }
307
+ /* Default ca bundle is configured automatically on connect by the WiFiSSLClient */
308
+
309
+ if (clients_cert_pem[internal_sock].size ()) {
310
+ /* Set client certificate */
311
+ the_client.sslclient ->setCertificate ((const char *)clients_cert_pem[internal_sock].data ());
312
+ }
313
+ if (clients_key_pem[internal_sock].size ()) {
314
+ /* Set client key */
315
+ the_client.sslclient ->setPrivateKey ((const char *)clients_key_pem[internal_sock].data ());
316
+ }
317
+
179
318
if (!the_client.sslclient ->connect (host.c_str (), atoi (port.c_str ()))) {
180
319
return chAT::CommandStatus::ERROR;
181
320
}
@@ -210,6 +349,11 @@ void CAtHandler::add_cmds_wifi_SSL() {
210
349
return chAT::CommandStatus::ERROR;
211
350
}
212
351
352
+ const int internal_sock = the_client.can_delete ;
353
+ if (internal_sock == -1 ) {
354
+ return chAT::CommandStatus::ERROR;
355
+ }
356
+
213
357
auto &hostip = parser.args [1 ];
214
358
if (hostip.empty ()) {
215
359
return chAT::CommandStatus::ERROR;
@@ -225,6 +369,21 @@ void CAtHandler::add_cmds_wifi_SSL() {
225
369
return chAT::CommandStatus::ERROR;
226
370
}
227
371
372
+ /* Set custom root ca */
373
+ if (clients_ca[internal_sock].size ()) {
374
+ the_client.sslclient ->setCACert ((const char *)clients_ca[internal_sock].data ());
375
+ }
376
+ /* Default ca bundle is configured automatically on connect by the WiFiSSLClient */
377
+
378
+ if (clients_cert_pem[internal_sock].size ()) {
379
+ /* Set client certificate */
380
+ the_client.sslclient ->setCertificate ((const char *)clients_cert_pem[internal_sock].data ());
381
+ }
382
+ if (clients_key_pem[internal_sock].size ()) {
383
+ /* Set client key */
384
+ the_client.sslclient ->setPrivateKey ((const char *)clients_key_pem[internal_sock].data ());
385
+ }
386
+
228
387
if (!the_client.sslclient ->connect (address, atoi (hostport.c_str ()))) {
229
388
return chAT::CommandStatus::ERROR;
230
389
}
@@ -258,6 +417,11 @@ void CAtHandler::add_cmds_wifi_SSL() {
258
417
return chAT::CommandStatus::ERROR;
259
418
}
260
419
420
+ const int internal_sock = the_client.can_delete ;
421
+ if (internal_sock == -1 ) {
422
+ return chAT::CommandStatus::ERROR;
423
+ }
424
+
261
425
auto &host = parser.args [1 ];
262
426
if (host.empty ()) {
263
427
return chAT::CommandStatus::ERROR;
@@ -280,6 +444,21 @@ void CAtHandler::add_cmds_wifi_SSL() {
280
444
}
281
445
}
282
446
447
+ /* Set custom root ca */
448
+ if (clients_ca[internal_sock].size ()) {
449
+ the_client.sslclient ->setCACert ((const char *)clients_ca[internal_sock].data ());
450
+ }
451
+ /* Default ca bundle is configured automatically on connect by the WiFiSSLClient */
452
+
453
+ if (clients_cert_pem[internal_sock].size ()) {
454
+ /* Set client certificate */
455
+ the_client.sslclient ->setCertificate ((const char *)clients_cert_pem[internal_sock].data ());
456
+ }
457
+ if (clients_key_pem[internal_sock].size ()) {
458
+ /* Set client key */
459
+ the_client.sslclient ->setPrivateKey ((const char *)clients_key_pem[internal_sock].data ());
460
+ }
461
+
283
462
if (!the_client.sslclient ->connect (host.c_str (), atoi (port.c_str ()), timeout)) {
284
463
return chAT::CommandStatus::ERROR;
285
464
}
@@ -397,6 +576,9 @@ void CAtHandler::add_cmds_wifi_SSL() {
397
576
if (the_client.can_delete >= 0 ) {
398
577
delete sslclients[the_client.can_delete ];
399
578
sslclients[the_client.can_delete ] = nullptr ;
579
+ clients_ca[the_client.can_delete ].clear ();
580
+ clients_cert_pem[the_client.can_delete ].clear ();
581
+ clients_key_pem[the_client.can_delete ].clear ();
400
582
sslclients_num--;
401
583
}
402
584
}
0 commit comments