Skip to content

Commit 29b5ae4

Browse files
committed
SSLClient: add certificate loading from filesystem
1 parent 6afcf54 commit 29b5ae4

File tree

8 files changed

+166
-19
lines changed

8 files changed

+166
-19
lines changed

libraries/Ethernet/src/EthernetSSLClient.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@ EthernetSSLClient::EthernetSSLClient()
66

77
sslclient = new sslclient_context;
88
_client = new EthernetClient;
9-
ssl_init(sslclient, _client);
9+
1010
_timeout = 1000;
1111
_CA_cert = NULL;
12+
_CA_path = "/mbedtls";
1213
_cert = NULL;
1314
_private_key = NULL;
1415
_pskIdent = NULL;
1516
_psKey = NULL;
1617

18+
ssl_init(sslclient, _client, _CA_path);
19+
1720
sslclient->handshake_timeout = 5000;
1821
}
1922

libraries/SSLClient/src/SSLClient.cpp

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,18 @@ SSLClient::SSLClient()
3131
_connected = false;
3232

3333
sslclient = new sslclient_context;
34-
ssl_init(sslclient, nullptr);
34+
3535
_timeout = 1000;
3636
_use_insecure = false;
3737
_CA_cert = NULL;
38+
_CA_path = NULL;
3839
_cert = NULL;
3940
_private_key = NULL;
4041
_pskIdent = NULL;
4142
_psKey = NULL;
4243

44+
ssl_init(sslclient, nullptr, _CA_path);
45+
4346
sslclient->handshake_timeout = 5000;
4447
}
4548

@@ -48,15 +51,38 @@ SSLClient::SSLClient(Client* client)
4851
_connected = false;
4952

5053
sslclient = new sslclient_context;
51-
ssl_init(sslclient, client);
54+
55+
_timeout = 1000;
56+
_use_insecure = false;
57+
_CA_cert = NULL;
58+
_CA_path = "/mbedtls";
59+
_cert = NULL;
60+
_private_key = NULL;
61+
_pskIdent = NULL;
62+
_psKey = NULL;
63+
64+
ssl_init(sslclient, client, _CA_path);
65+
66+
sslclient->handshake_timeout = 5000;
67+
}
68+
69+
SSLClient::SSLClient(Client* client, String ca_path)
70+
{
71+
_connected = false;
72+
73+
sslclient = new sslclient_context;
74+
5275
_timeout = 1000;
5376
_use_insecure = false;
5477
_CA_cert = NULL;
78+
_CA_path = ca_path.c_str();
5579
_cert = NULL;
5680
_private_key = NULL;
5781
_pskIdent = NULL;
5882
_psKey = NULL;
5983

84+
ssl_init(sslclient, client, _CA_path);
85+
6086
sslclient->handshake_timeout = 5000;
6187
}
6288

@@ -80,7 +106,7 @@ int SSLClient::connect(IPAddress ip, uint16_t port)
80106
{
81107
if (_pskIdent && _psKey)
82108
return connect(ip, port, _pskIdent, _psKey);
83-
return connect(ip, port, _CA_cert, _cert, _private_key);
109+
return connect(ip, port, _CA_cert, _CA_path, _cert, _private_key);
84110
}
85111

86112
int SSLClient::connect(IPAddress ip, uint16_t port, int32_t timeout){
@@ -92,23 +118,23 @@ int SSLClient::connect(const char *host, uint16_t port)
92118
{
93119
if (_pskIdent && _psKey)
94120
return connect(host, port, _pskIdent, _psKey);
95-
return connect(host, port, _CA_cert, _cert, _private_key);
121+
return connect(host, port, _CA_cert, _CA_path, _cert, _private_key);
96122
}
97123

98124
int SSLClient::connect(const char *host, uint16_t port, int32_t timeout){
99125
_timeout = timeout;
100126
return connect(host, port);
101127
}
102128

103-
int SSLClient::connect(IPAddress ip, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key)
129+
int SSLClient::connect(IPAddress ip, uint16_t port, const char *_CA_cert, const char *_CA_path, const char *_cert, const char *_private_key)
104130
{
105-
return connect(ip.toString().c_str(), port, _CA_cert, _cert, _private_key);
131+
return connect(ip.toString().c_str(), port, _CA_cert, _CA_path, _cert, _private_key);
106132
}
107133

108-
int SSLClient::connect(const char *host, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key)
134+
int SSLClient::connect(const char *host, uint16_t port, const char *_CA_cert, const char *_CA_path, const char *_cert, const char *_private_key)
109135
{
110136
log_d("Connecting to %s:%d", host, port);
111-
int ret = start_ssl_client(sslclient, host, port, _timeout, _CA_cert, _cert, _private_key, NULL, NULL, _use_insecure);
137+
int ret = start_ssl_client(sslclient, host, port, _timeout, _CA_cert, _CA_path, _cert, _private_key, NULL, NULL, _use_insecure);
112138
_lastError = ret;
113139
if (ret < 0) {
114140
log_e("start_ssl_client: %d", ret);
@@ -126,7 +152,7 @@ int SSLClient::connect(IPAddress ip, uint16_t port, const char *pskIdent, const
126152

127153
int SSLClient::connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey) {
128154
log_v("start_ssl_client with PSK");
129-
int ret = start_ssl_client(sslclient, host, port, _timeout, NULL, NULL, NULL, _pskIdent, _psKey, _use_insecure);
155+
int ret = start_ssl_client(sslclient, host, port, _timeout, NULL, NULL, NULL, NULL, _pskIdent, _psKey, _use_insecure);
130156
_lastError = ret;
131157
if (ret < 0) {
132158
log_e("start_ssl_client: %d", ret);
@@ -241,6 +267,12 @@ void SSLClient::setCACert (const char *rootCA)
241267
_CA_cert = rootCA;
242268
}
243269

270+
void SSLClient::setCAPath (const char *rootCAPath)
271+
{
272+
log_d("Set root CA Path");
273+
_CA_path = rootCAPath;
274+
}
275+
244276
void SSLClient::setCertificate (const char *client_ca)
245277
{
246278
log_d("Set client CA");

libraries/SSLClient/src/SSLClient.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class SSLClient : public Client
3232
int _timeout = 0;
3333
bool _use_insecure;
3434
const char *_CA_cert;
35+
const char *_CA_path;
3536
const char *_cert;
3637
const char *_private_key;
3738
const char *_pskIdent; // identity for PSK cipher suites
@@ -44,14 +45,15 @@ class SSLClient : public Client
4445
public:
4546
SSLClient();
4647
SSLClient(Client* client);
48+
SSLClient(Client* client, String ca_path);
4749
~SSLClient();
4850

4951
int connect(IPAddress ip, uint16_t port);
5052
int connect(IPAddress ip, uint16_t port, int32_t timeout);
5153
int connect(const char *host, uint16_t port);
5254
int connect(const char *host, uint16_t port, int32_t timeout);
53-
int connect(IPAddress ip, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key);
54-
int connect(const char *host, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key);
55+
int connect(IPAddress ip, uint16_t port, const char *rootCABuff, const char *rootCAPath, const char *cli_cert, const char *cli_key);
56+
int connect(const char *host, uint16_t port, const char *rootCABuff, const char *rootCAPath, const char *cli_cert, const char *cli_key);
5557
int connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psKey);
5658
int connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey);
5759

@@ -69,6 +71,7 @@ class SSLClient : public Client
6971

7072
void setPreSharedKey(const char *pskIdent, const char *psKey); // psKey in Hex
7173
void setCACert(const char *rootCA);
74+
void setCAPath(const char *rootCAPath);
7275
void setCertificate(const char *client_ca);
7376
void setPrivateKey (const char *private_key);
7477
bool loadCACert(Stream& stream, size_t size);

libraries/SSLClient/src/ssl_client.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <algorithm>
1313
#include <string>
1414
#include "ssl_client.h"
15+
#include "ssl_fs_io.h"
1516

1617

1718
#if !defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) && !defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
@@ -59,7 +60,7 @@ static int client_net_recv( void *ctx, unsigned char *buf, size_t len ) {
5960
//if (!client->connected()) {
6061
// log_e("Not connected!");
6162
// return -2;
62-
// }
63+
//}
6364

6465
int result = client->read(buf, len);
6566
log_d("SSL client RX res=%d len=%d", result, len);
@@ -139,7 +140,7 @@ static int client_net_send( void *ctx, const unsigned char *buf, size_t len ) {
139140
}
140141

141142

142-
void ssl_init(sslclient_context *ssl_client, Client *client)
143+
void ssl_init(sslclient_context *ssl_client, Client *client, const char * ca_path)
143144
{
144145
// reset embedded pointers to zero
145146
memset(ssl_client, 0, sizeof(sslclient_context));
@@ -152,10 +153,12 @@ void ssl_init(sslclient_context *ssl_client, Client *client)
152153

153154
mbedtls_ssl_conf_dbg(&ssl_client->ssl_conf, mbedtls_debug_print, NULL);
154155
mbedtls_debug_set_threshold(DEBUG_LEVEL);
156+
157+
mbedtls_fs_init(ca_path);
155158
}
156159

157160

158-
int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure)
161+
int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *rootCAPath, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure)
159162
{
160163
char buf[512];
161164
int ret, flags;
@@ -243,6 +246,24 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
243246
log_e("mbedtls_ssl_conf_psk returned %d", ret);
244247
return handle_error(ret);
245248
}
249+
} else if (rootCAPath != NULL){
250+
log_v("Setting up filesystem default ca chain with path %s", rootCAPath);
251+
mbedtls_x509_crt_init(&ssl_client->ca_cert);
252+
mbedtls_ssl_conf_authmode(&ssl_client->ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
253+
ret = mbedtls_x509_crt_parse_path(&ssl_client->ca_cert, rootCAPath);
254+
if(ret != 0) {
255+
if(ret < 0) {
256+
log_e("error parsing ca certs from filesystem");
257+
return handle_error(ret);
258+
} else {
259+
log_w("partly parsed %d certs from filesystem", ret);
260+
}
261+
}
262+
mbedtls_ssl_conf_ca_chain(&ssl_client->ssl_conf, &ssl_client->ca_cert, NULL);
263+
if (ret < 0) {
264+
mbedtls_x509_crt_free(&ssl_client->ca_cert);
265+
return handle_error(ret);
266+
}
246267
} else {
247268
return -1;
248269
}
@@ -316,12 +337,14 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
316337
mbedtls_x509_crt_verify_info(buf, sizeof(buf), " ! ", flags);
317338
log_e("Failed to verify peer certificate! verification info: %s", buf);
318339
stop_ssl_socket(ssl_client, rootCABuff, cli_cert, cli_key); //It's not safe continue.
340+
319341
return handle_error(ret);
320342
} else {
321343
log_v("Certificate verified.");
322344
}
323345

324-
if (rootCABuff != NULL) {
346+
if ((rootCABuff != NULL) || ((rootCAPath != NULL))) {
347+
log_e("free buffer");
325348
mbedtls_x509_crt_free(&ssl_client->ca_cert);
326349
}
327350

libraries/SSLClient/src/ssl_client.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ typedef struct sslclient_context {
3535
mbedtls_x509_crt client_cert;
3636
mbedtls_pk_context client_key;
3737

38+
char* ca_path;
39+
3840
unsigned long handshake_timeout;
3941
} sslclient_context;
4042

4143

42-
void ssl_init(sslclient_context *ssl_client, Client *client);
43-
int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure);
44+
void ssl_init(sslclient_context *ssl_client, Client *client, const char *ca_path);
45+
int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t port, int timeout, const char *rootCABuff, const char *rootCAPath, const char *cli_cert, const char *cli_key, const char *pskIdent, const char *psKey, bool insecure);
4446
void stop_ssl_socket(sslclient_context *ssl_client, const char *rootCABuff, const char *cli_cert, const char *cli_key);
4547
int data_to_read(sslclient_context *ssl_client);
4648
int send_ssl_data(sslclient_context *ssl_client, const uint8_t *data, uint16_t len);

libraries/SSLClient/src/ssl_fs_io.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
ssl_fs_io.cpp
3+
Copyright (c) 2023 Arduino SA. All right reserved.
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
#include "Arduino.h"
21+
#include "QSPIFlashBlockDevice.h"
22+
#include "FATFileSystem.h"
23+
#include "ssl_fs_io.h"
24+
#include "ssl_debug.h"
25+
26+
static BlockDevice * get_mbedtls_bd()
27+
{
28+
static QSPIFlashBlockDevice root(PIN_QSPI_CLK, PIN_QSPI_SS, PIN_QSPI_D0, PIN_QSPI_D1, PIN_QSPI_D2, PIN_QSPI_D3);
29+
return &root;
30+
}
31+
32+
static FATFileSystem * get_mbedtls_fs()
33+
{
34+
static FATFileSystem mbedtls_fs("mbedtls");
35+
return &mbedtls_fs;
36+
}
37+
38+
void mbedtls_fs_init(const char * path)
39+
{
40+
if(!path) {
41+
return;
42+
}
43+
44+
BlockDevice * bd = get_mbedtls_bd();
45+
FATFileSystem *fs = get_mbedtls_fs();
46+
47+
if(!fs->mount(bd)) {
48+
//log_e("Failed to mount mbedtls fs");
49+
}
50+
}

libraries/SSLClient/src/ssl_fs_io.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
ssl_fs_io.h
3+
Copyright (c) 2023 Arduino SA. All right reserved.
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
#ifndef SSL_FS_IO_H_INC
21+
#define SSL_FS_IO_H_INC
22+
23+
#ifdef __cplusplus
24+
extern "C" {
25+
#endif
26+
void mbedtls_fs_init(const char * path);
27+
#ifdef __cplusplus
28+
}
29+
#endif
30+
31+
#endif // #ifndef SSL_FS_IO_H_INC

libraries/WiFi/src/WiFiSSLClient.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@ WiFiSSLClient::WiFiSSLClient()
66

77
sslclient = new sslclient_context;
88
_client = new WiFiClient;
9-
ssl_init(sslclient, _client);
9+
1010
_timeout = 1000;
1111
_CA_cert = NULL;
12+
_CA_path = "/mbedtls";
1213
_cert = NULL;
1314
_private_key = NULL;
1415
_pskIdent = NULL;
1516
_psKey = NULL;
1617

18+
ssl_init(sslclient, _client, _CA_path);
19+
1720
sslclient->handshake_timeout = 5000;
1821
}
1922

0 commit comments

Comments
 (0)