Skip to content

Commit a6aadef

Browse files
committed
wifi ssl: properly handle multiple client certificates
1 parent 706a8f6 commit a6aadef

File tree

3 files changed

+95
-20
lines changed

3 files changed

+95
-20
lines changed

UNOR4USBBridge/at_handler.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ CAtHandler::CAtHandler(HardwareSerial *s) : last_server_client_sock(0) {
9292

9393
for(int i = 0; i < MAX_CLIENT_AVAILABLE; i++) {
9494
sslclients[i] = nullptr;
95+
clients_ca[i].clear();
96+
clients_cert_pem[i].clear();
97+
clients_key_pem[i].clear();
9598
}
9699

97100
/* set up serial */

UNOR4USBBridge/at_handler.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class CAtHandler {
6363
WiFiClient * clients[MAX_CLIENT_AVAILABLE];
6464
CServerClient serverClients[MAX_CLIENT_AVAILABLE];
6565
WiFiClientSecure * sslclients[MAX_CLIENT_AVAILABLE];
66+
std::vector<std::uint8_t> clients_ca[MAX_CLIENT_AVAILABLE];
67+
std::vector<std::uint8_t> clients_cert_pem[MAX_CLIENT_AVAILABLE];
68+
std::vector<std::uint8_t> clients_key_pem[MAX_CLIENT_AVAILABLE];
6669
int udps_num = 0;
6770
int servers_num = 0;
6871
int clientsToServer_num = 0;
@@ -85,10 +88,8 @@ class CAtHandler {
8588
void add_cmds_preferences();
8689
void add_cmds_se();
8790
public:
88-
std::vector<std::uint8_t> cert_buf;
91+
/* Used by cmds_se */
8992
std::vector<std::uint8_t> se_buf;
90-
std::vector<std::uint8_t> client_cert_pem;
91-
std::vector<std::uint8_t> client_key_pem;
9293

9394
/* Used by cmds_ota */
9495
std::vector<std::uint8_t> ota_cert_buf;

UNOR4USBBridge/cmds_wifi_SSL.h

Lines changed: 88 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ void CAtHandler::add_cmds_wifi_SSL() {
6868
return chAT::CommandStatus::ERROR;
6969
}
7070

71+
const int internal_sock = the_client.can_delete;
72+
if (internal_sock == -1) {
73+
return chAT::CommandStatus::ERROR;
74+
}
75+
7176
bool ca_root_custom = false;
7277
int ca_root_size = 0;
7378
if (parser.args.size() >= 2){
@@ -80,19 +85,17 @@ void CAtHandler::add_cmds_wifi_SSL() {
8085
}
8186

8287
if(ca_root_custom) {
83-
84-
85-
cert_buf = srv.inhibit_read(ca_root_size);
86-
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();
8790

8891
if(offset < ca_root_size) {
8992

90-
cert_buf.resize(ca_root_size);
93+
clients_ca[internal_sock].resize(ca_root_size);
9194
do {
92-
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);
9396
} while (offset < ca_root_size);
9497
}
95-
the_client.sslclient->setCACert((const char *)cert_buf.data());
98+
the_client.sslclient->setCACert((const char *)clients_ca[internal_sock].data());
9699
srv.continue_read();
97100
} else {
98101
#ifdef BUNDLED_CA_ROOT_CRT
@@ -137,6 +140,11 @@ void CAtHandler::add_cmds_wifi_SSL() {
137140
return chAT::CommandStatus::ERROR;
138141
}
139142

143+
const int internal_sock = the_client.can_delete;
144+
if (internal_sock == -1) {
145+
return chAT::CommandStatus::ERROR;
146+
}
147+
140148
std::vector<unsigned char> client_cert_der;
141149
client_cert_der = srv.inhibit_read(size);
142150
size_t offset = client_cert_der.size();
@@ -155,22 +163,22 @@ void CAtHandler::add_cmds_wifi_SSL() {
155163
#endif
156164

157165
/* Convert client certificate DER buffer into PEM */
158-
client_cert_pem.resize(1024);
166+
clients_cert_pem[internal_sock].resize(1024);
159167
size_t olen;
160168
mbedtls_pem_write_buffer("-----BEGIN CERTIFICATE-----\n",
161169
"-----END CERTIFICATE-----\n",
162170
client_cert_der.data(), size,
163-
client_cert_pem.data(), 1024,
171+
clients_cert_pem[internal_sock].data(), 1024,
164172
&olen);
165-
client_cert_pem.resize(olen);
173+
clients_cert_pem[internal_sock].resize(olen);
166174

167175
#if ECC_DEBUG_ENABLED
168176
log_v("_SETECCSLOT: output cert");
169-
log_v("\n%s", client_cert_pem.data());
177+
log_v("\n%s", clients_cert_pem[internal_sock].data());
170178
#endif
171179

172180
/* Set client certificate */
173-
the_client.sslclient->setCertificate((const char *)client_cert_pem.data());
181+
the_client.sslclient->setCertificate((const char *)clients_cert_pem[internal_sock].data());
174182

175183
/* Read private key from non volatile storage in DER format */
176184
std::vector<unsigned char> client_key_der;
@@ -188,21 +196,21 @@ void CAtHandler::add_cmds_wifi_SSL() {
188196
#endif
189197

190198
/* Convert private key in PEM format */
191-
client_key_pem.resize(1024);
199+
clients_key_pem[internal_sock].resize(1024);
192200
mbedtls_pem_write_buffer("-----BEGIN EC PRIVATE KEY-----\n",
193201
"-----END EC PRIVATE KEY-----\n",
194202
client_key_der.data(), len,
195-
client_key_pem.data(), 1024,
203+
clients_key_pem[internal_sock].data(), 1024,
196204
&olen);
197-
client_key_pem.resize(olen);
205+
clients_key_pem[internal_sock].resize(olen);
198206

199207
#if ECC_DEBUG_ENABLED
200208
log_v("_SETECCSLOT: output key");
201-
log_v("\n%s", client_key_pem.data());
209+
log_v("\n%s", clients_key_pem[internal_sock].data());
202210
#endif
203211

204212
/* Set client key */
205-
the_client.sslclient->setPrivateKey((const char *)client_key_pem.data());
213+
the_client.sslclient->setPrivateKey((const char *)clients_key_pem[internal_sock].data());
206214

207215
return chAT::CommandStatus::OK;
208216
}
@@ -267,6 +275,11 @@ void CAtHandler::add_cmds_wifi_SSL() {
267275
return chAT::CommandStatus::ERROR;
268276
}
269277

278+
const int internal_sock = the_client.can_delete;
279+
if (internal_sock == -1) {
280+
return chAT::CommandStatus::ERROR;
281+
}
282+
270283
auto &host = parser.args[1];
271284
if (host.empty()) {
272285
return chAT::CommandStatus::ERROR;
@@ -277,6 +290,21 @@ void CAtHandler::add_cmds_wifi_SSL() {
277290
return chAT::CommandStatus::ERROR;
278291
}
279292

293+
/* Set custom root ca */
294+
if (clients_ca[internal_sock].size()) {
295+
the_client.sslclient->setCACert((const char *)clients_ca[internal_sock].data());
296+
}
297+
/* Default ca bundle is configured automatically on connect by the WiFiSSLClient */
298+
299+
if (clients_cert_pem[internal_sock].size()) {
300+
/* Set client certificate */
301+
the_client.sslclient->setCertificate((const char *)clients_cert_pem[internal_sock].data());
302+
}
303+
if (clients_key_pem[internal_sock].size()) {
304+
/* Set client key */
305+
the_client.sslclient->setPrivateKey((const char *)clients_key_pem[internal_sock].data());
306+
}
307+
280308
if (!the_client.sslclient->connect(host.c_str(), atoi(port.c_str()))) {
281309
return chAT::CommandStatus::ERROR;
282310
}
@@ -311,6 +339,11 @@ void CAtHandler::add_cmds_wifi_SSL() {
311339
return chAT::CommandStatus::ERROR;
312340
}
313341

342+
const int internal_sock = the_client.can_delete;
343+
if (internal_sock == -1) {
344+
return chAT::CommandStatus::ERROR;
345+
}
346+
314347
auto &hostip = parser.args[1];
315348
if (hostip.empty()) {
316349
return chAT::CommandStatus::ERROR;
@@ -326,6 +359,21 @@ void CAtHandler::add_cmds_wifi_SSL() {
326359
return chAT::CommandStatus::ERROR;
327360
}
328361

362+
/* Set custom root ca */
363+
if (clients_ca[internal_sock].size()) {
364+
the_client.sslclient->setCACert((const char *)clients_ca[internal_sock].data());
365+
}
366+
/* Default ca bundle is configured automatically on connect by the WiFiSSLClient */
367+
368+
if (clients_cert_pem[internal_sock].size()) {
369+
/* Set client certificate */
370+
the_client.sslclient->setCertificate((const char *)clients_cert_pem[internal_sock].data());
371+
}
372+
if (clients_key_pem[internal_sock].size()) {
373+
/* Set client key */
374+
the_client.sslclient->setPrivateKey((const char *)clients_key_pem[internal_sock].data());
375+
}
376+
329377
if (!the_client.sslclient->connect(address, atoi(hostport.c_str()))) {
330378
return chAT::CommandStatus::ERROR;
331379
}
@@ -359,6 +407,11 @@ void CAtHandler::add_cmds_wifi_SSL() {
359407
return chAT::CommandStatus::ERROR;
360408
}
361409

410+
const int internal_sock = the_client.can_delete;
411+
if (internal_sock == -1) {
412+
return chAT::CommandStatus::ERROR;
413+
}
414+
362415
auto &host = parser.args[1];
363416
if (host.empty()) {
364417
return chAT::CommandStatus::ERROR;
@@ -381,6 +434,21 @@ void CAtHandler::add_cmds_wifi_SSL() {
381434
}
382435
}
383436

437+
/* Set custom root ca */
438+
if (clients_ca[internal_sock].size()) {
439+
the_client.sslclient->setCACert((const char *)clients_ca[internal_sock].data());
440+
}
441+
/* Default ca bundle is configured automatically on connect by the WiFiSSLClient */
442+
443+
if (clients_cert_pem[internal_sock].size()) {
444+
/* Set client certificate */
445+
the_client.sslclient->setCertificate((const char *)clients_cert_pem[internal_sock].data());
446+
}
447+
if (clients_key_pem[internal_sock].size()) {
448+
/* Set client key */
449+
the_client.sslclient->setPrivateKey((const char *)clients_key_pem[internal_sock].data());
450+
}
451+
384452
if (!the_client.sslclient->connect(host.c_str(), atoi(port.c_str()), timeout)) {
385453
return chAT::CommandStatus::ERROR;
386454
}
@@ -498,6 +566,9 @@ void CAtHandler::add_cmds_wifi_SSL() {
498566
if(the_client.can_delete >= 0) {
499567
delete sslclients[the_client.can_delete];
500568
sslclients[the_client.can_delete] = nullptr;
569+
clients_ca[the_client.can_delete].clear();
570+
clients_cert_pem[the_client.can_delete].clear();
571+
clients_key_pem[the_client.can_delete].clear();
501572
sslclients_num--;
502573
}
503574
}

0 commit comments

Comments
 (0)