Skip to content

Commit e304474

Browse files
copercinime-no-dev
authored andcommitted
WiFiSecureClient fixes and improvements (espressif#255)
* Add CA certificate in example SHA1 fingerprint is broken now: more info: https://shattered.io * Best error handling When occur an error in WiFiClientSecure library just return the error message and clean the context avoiding crash - fix for espressif#211 Translate MbedTLS error codes in messages for best understanding * Declarate certificates as const mbedtls_pk_parse_key needs a const unsigned char * certificate. In old implementation the certificate was declarated as char * so first it converts to unsigned and after to const. When we convert signed to unsigned it may result in a +1 larger output. Fix issue espressif#223
1 parent e625b3b commit e304474

File tree

5 files changed

+240
-166
lines changed

5 files changed

+240
-166
lines changed

libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino

+61-24
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,47 @@
88

99
#include <WiFiClientSecure.h>
1010

11-
char ssid[] = "your_network_name"; // your network SSID (name of wifi network)
12-
char pass[] = "your_password"; // your network password
11+
const char* ssid = "your-ssid"; // your network SSID (name of wifi network)
12+
const char* password = "your-password"; // your network password
1313

14-
char server[] = "www.howsmyssl.com"; // Server URL
15-
// You can use x.509 certificates if you want
16-
//unsigned char test_ca_cert[] = ""; //For the usage of verifying server
17-
//unsigned char test_client_key[] = ""; //For the usage of verifying client
18-
//unsigned char test_client_cert[] = ""; //For the usage of verifying client
14+
const char* server = "www.howsmyssl.com"; // Server URL
15+
16+
// www.howsmyssl.com CA certificate, to verify the server
17+
// change it to your server CA certificate
18+
// SHA1 fingerprint is broken now!
19+
20+
const char* test_ca_cert = \
21+
"-----BEGIN CERTIFICATE-----\n" \
22+
"MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n" \
23+
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n" \
24+
"DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n" \
25+
"SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n" \
26+
"GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n" \
27+
"AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n" \
28+
"q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n" \
29+
"SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n" \
30+
"Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n" \
31+
"a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n" \
32+
"/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n" \
33+
"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n" \
34+
"CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n" \
35+
"bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n" \
36+
"c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n" \
37+
"VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n" \
38+
"ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n" \
39+
"MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n" \
40+
"Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n" \
41+
"AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n" \
42+
"uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n" \
43+
"wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n" \
44+
"X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n" \
45+
"PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n" \
46+
"KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n" \
47+
"-----END CERTIFICATE-----\n";
48+
49+
// You can use x.509 client certificates if you want
50+
//const char* test_client_key = ""; //to verify the client
51+
//const char* test_client_cert = ""; //to verify the client
1952

2053

2154
WiFiClientSecure client;
@@ -27,7 +60,7 @@ void setup() {
2760

2861
Serial.print("Attempting to connect to SSID: ");
2962
Serial.println(ssid);
30-
WiFi.begin(ssid, pass);
63+
WiFi.begin(ssid, password);
3164

3265
// attempt to connect to Wifi network:
3366
while (WiFi.status() != WL_CONNECTED) {
@@ -38,39 +71,43 @@ void setup() {
3871

3972
Serial.print("Connected to ");
4073
Serial.println(ssid);
74+
75+
client.setCACert(test_ca_cert);
76+
//client.setCertificate(certificateBuff); // for client verification
77+
//client.setPrivateKey(privateKeyBuff); // for client verification
4178

4279
Serial.println("\nStarting connection to server...");
43-
if (client.connect(server, 443)) { //client.connect(server, 443, test_ca_cert, test_client_cert, test_client_key)
80+
if (!client.connect(server, 443))
81+
Serial.println("Connection failed!");
82+
else {
4483
Serial.println("Connected to server!");
4584
// Make a HTTP request:
4685
client.println("GET https://www.howsmyssl.com/a/check HTTP/1.0");
4786
client.println("Host: www.howsmyssl.com");
4887
client.println("Connection: close");
4988
client.println();
50-
}
51-
else
52-
Serial.println("Connection failed!");
5389

5490
Serial.print("Waiting for response "); //WiFiClientSecure uses a non blocking implementation
5591
while (!client.available()){
5692
delay(50); //
5793
Serial.print(".");
5894
}
59-
// if there are incoming bytes available
60-
// from the server, read them and print them:
61-
while (client.available()) {
62-
char c = client.read();
63-
Serial.write(c);
64-
}
95+
// if there are incoming bytes available
96+
// from the server, read them and print them:
97+
while (client.available()) {
98+
char c = client.read();
99+
Serial.write(c);
100+
}
65101

66-
// if the server's disconnected, stop the client:
67-
if (!client.connected()) {
68-
Serial.println();
69-
Serial.println("disconnecting from server.");
70-
client.stop();
102+
// if the server's disconnected, stop the client:
103+
if (!client.connected()) {
104+
Serial.println();
105+
Serial.println("disconnecting from server.");
106+
client.stop();
107+
}
71108
}
72109
}
73110

74111
void loop() {
75112
// do nothing
76-
}
113+
}

libraries/WiFiClientSecure/src/WiFiClientSecure.cpp

+20-15
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ WiFiClientSecure::WiFiClientSecure()
3939
_CA_cert = NULL;
4040
_cert = NULL;
4141
_private_key = NULL;
42-
next = NULL;
42+
next = NULL;
4343
}
4444

4545

@@ -58,7 +58,7 @@ WiFiClientSecure::WiFiClientSecure(int sock)
5858
_CA_cert = NULL;
5959
_cert = NULL;
6060
_private_key = NULL;
61-
next = NULL;
61+
next = NULL;
6262
}
6363

6464
WiFiClientSecure::~WiFiClientSecure()
@@ -76,34 +76,37 @@ WiFiClientSecure &WiFiClientSecure::operator=(const WiFiClientSecure &other)
7676

7777
void WiFiClientSecure::stop()
7878
{
79-
if (_connected && sslclient->socket >= 0) {
80-
stop_ssl_socket(sslclient, _CA_cert, _cert, _private_key);
79+
if (sslclient->socket >= 0) {
80+
close(sslclient->socket);
8181
sslclient->socket = -1;
8282
_connected = false;
8383
}
84+
stop_ssl_socket(sslclient, _CA_cert, _cert, _private_key);
8485
}
8586

8687
int WiFiClientSecure::connect(IPAddress ip, uint16_t port)
8788
{
88-
return connect(ip, port, _CA_cert, _cert, _private_key);
89+
return connect(ip, port, _CA_cert, _cert, _private_key);
8990
}
9091

9192
int WiFiClientSecure::connect(const char *host, uint16_t port)
9293
{
93-
return connect(host, port, _CA_cert, _cert, _private_key);
94+
return connect(host, port, _CA_cert, _cert, _private_key);
9495
}
9596

96-
int WiFiClientSecure::connect(IPAddress ip, uint16_t port, unsigned char *_CA_cert, unsigned char *_cert, unsigned char *_private_key)
97+
int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key)
9798
{
9899
int ret = start_ssl_client(sslclient, ip, port, _CA_cert, _cert, _private_key);
99100
if (ret < 0) {
100101
log_e("lwip_connect_r: %d", errno);
102+
stop();
103+
return 0;
101104
}
102105
_connected = true;
103106
return 1;
104107
}
105108

106-
int WiFiClientSecure::connect(const char *host, uint16_t port, unsigned char *_CA_cert, unsigned char *_cert, unsigned char *_private_key)
109+
int WiFiClientSecure::connect(const char *host, uint16_t port, const char *_CA_cert, const char *_cert, const char *_private_key)
107110
{
108111
struct hostent *server;
109112
server = gethostbyname(host);
@@ -137,7 +140,7 @@ size_t WiFiClientSecure::write(const uint8_t *buf, size_t size)
137140
}
138141
int res = send_ssl_data(sslclient, buf, size);
139142
if (res < 0) {
140-
log_e("%d", errno);
143+
141144
stop();
142145
res = 0;
143146
}
@@ -150,8 +153,8 @@ int WiFiClientSecure::read(uint8_t *buf, size_t size)
150153
return -1;
151154
}
152155
int res = get_ssl_receive(sslclient, buf, size);
153-
if (res < 0 && errno != EWOULDBLOCK) {
154-
printf("%d", errno);
156+
if (res < 0) {
157+
155158
stop();
156159
}
157160
return res;
@@ -163,7 +166,9 @@ int WiFiClientSecure::available()
163166
return 0;
164167
}
165168
int res = data_to_read(sslclient);
166-
169+
if (res < 0 ) {
170+
stop();
171+
}
167172
return res;
168173
}
169174

@@ -175,17 +180,17 @@ uint8_t WiFiClientSecure::connected()
175180
return _connected;
176181
}
177182

178-
void WiFiClientSecure::setCACert(unsigned char *rootCA)
183+
void WiFiClientSecure::setCACert (const char *rootCA)
179184
{
180185
_CA_cert = rootCA;
181186
}
182187

183-
void WiFiClientSecure::setCertificate (unsigned char *client_ca)
188+
void WiFiClientSecure::setCertificate (const char *client_ca)
184189
{
185190
_cert = client_ca;
186191
}
187192

188-
void WiFiClientSecure::setPrivateKey (unsigned char *private_key)
193+
void WiFiClientSecure::setPrivateKey (const char *private_key)
189194
{
190195
_private_key = private_key;
191196
}

libraries/WiFiClientSecure/src/WiFiClientSecure.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ class WiFiClientSecure : public Client
3131
bool _connected;
3232
sslclient_context *sslclient;
3333

34-
unsigned char *_CA_cert;
35-
unsigned char *_cert;
36-
unsigned char *_private_key;
34+
const char *_CA_cert;
35+
const char *_cert;
36+
const char *_private_key;
3737

3838
public:
3939
WiFiClientSecure *next;
@@ -42,8 +42,8 @@ class WiFiClientSecure : public Client
4242
~WiFiClientSecure();
4343
int connect(IPAddress ip, uint16_t port);
4444
int connect(const char *host, uint16_t port);
45-
int connect(IPAddress ip, uint16_t port, unsigned char *rootCABuff, unsigned char *cli_cert, unsigned char *cli_key);
46-
int connect(const char *host, uint16_t port, unsigned char *rootCABuff, unsigned char *cli_cert, unsigned char *cli_key);
45+
int connect(IPAddress ip, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key);
46+
int connect(const char *host, uint16_t port, const char *rootCABuff, const char *cli_cert, const char *cli_key);
4747
size_t write(uint8_t data);
4848
size_t write(const uint8_t *buf, size_t size);
4949
int available();
@@ -57,9 +57,9 @@ class WiFiClientSecure : public Client
5757
void stop();
5858
uint8_t connected();
5959

60-
void setCACert(unsigned char *rootCA);
61-
void setCertificate(unsigned char *client_ca);
62-
void setPrivateKey (unsigned char *private_key);
60+
void setCACert(const char *rootCA);
61+
void setCertificate(const char *client_ca);
62+
void setPrivateKey (const char *private_key);
6363

6464
operator bool()
6565
{

0 commit comments

Comments
 (0)