Skip to content

Commit 8ab3231

Browse files
copercinime-no-dev
authored andcommitted
Add WiFiClient secure lib (espressif#184)
* Provide SSL/TLS functions to ESP32 with Arduino IDE * Generate a new random number in case of reconnection
1 parent 0fb5e5c commit 8ab3231

File tree

7 files changed

+766
-0
lines changed

7 files changed

+766
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
Wifi secure connection example for ESP32
3+
Running on TLS 1.2 using mbedTLS
4+
Suporting the following chipersuites:
5+
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384","TLS_DHE_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDHE_ECDSA_WITH_AES_256_CCM","TLS_DHE_RSA_WITH_AES_256_CCM","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384","TLS_DHE_RSA_WITH_AES_256_CBC_SHA256","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA","TLS_DHE_RSA_WITH_AES_256_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8","TLS_DHE_RSA_WITH_AES_256_CCM_8","TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256","TLS_DHE_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_CCM","TLS_DHE_RSA_WITH_AES_128_CCM","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256","TLS_DHE_RSA_WITH_AES_128_CBC_SHA256","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA","TLS_DHE_RSA_WITH_AES_128_CBC_SHA","TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8","TLS_DHE_RSA_WITH_AES_128_CCM_8","TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA","TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA","TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA","TLS_DHE_PSK_WITH_AES_256_GCM_SHA384","TLS_DHE_PSK_WITH_AES_256_CCM","TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384","TLS_DHE_PSK_WITH_AES_256_CBC_SHA384","TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA","TLS_DHE_PSK_WITH_AES_256_CBC_SHA","TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_PSK_DHE_WITH_AES_256_CCM_8","TLS_DHE_PSK_WITH_AES_128_GCM_SHA256","TLS_DHE_PSK_WITH_AES_128_CCM","TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256","TLS_DHE_PSK_WITH_AES_128_CBC_SHA256","TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA","TLS_DHE_PSK_WITH_AES_128_CBC_SHA","TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256","TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_PSK_DHE_WITH_AES_128_CCM_8","TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA","TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA","TLS_RSA_WITH_AES_256_GCM_SHA384","TLS_RSA_WITH_AES_256_CCM","TLS_RSA_WITH_AES_256_CBC_SHA256","TLS_RSA_WITH_AES_256_CBC_SHA","TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384","TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384","TLS_ECDH_RSA_WITH_AES_256_CBC_SHA","TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384","TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384","TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA","TLS_RSA_WITH_AES_256_CCM_8","TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256","TLS_RSA_WITH_CAMELLIA_256_CBC_SHA","TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384","TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384","TLS_RSA_WITH_AES_128_GCM_SHA256","TLS_RSA_WITH_AES_128_CCM","TLS_RSA_WITH_AES_128_CBC_SHA256","TLS_RSA_WITH_AES_128_CBC_SHA","TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256","TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256","TLS_ECDH_RSA_WITH_AES_128_CBC_SHA","TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256","TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256","TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA","TLS_RSA_WITH_AES_128_CCM_8","TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_RSA_WITH_CAMELLIA_128_CBC_SHA","TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256","TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256","TLS_RSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA","TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA","TLS_RSA_PSK_WITH_AES_256_GCM_SHA384","TLS_RSA_PSK_WITH_AES_256_CBC_SHA384","TLS_RSA_PSK_WITH_AES_256_CBC_SHA","TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384","TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_RSA_PSK_WITH_AES_128_GCM_SHA256","TLS_RSA_PSK_WITH_AES_128_CBC_SHA256","TLS_RSA_PSK_WITH_AES_128_CBC_SHA","TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256","TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA","TLS_PSK_WITH_AES_256_GCM_SHA384","TLS_PSK_WITH_AES_256_CCM","TLS_PSK_WITH_AES_256_CBC_SHA384","TLS_PSK_WITH_AES_256_CBC_SHA","TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384","TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384","TLS_PSK_WITH_AES_256_CCM_8","TLS_PSK_WITH_AES_128_GCM_SHA256","TLS_PSK_WITH_AES_128_CCM","TLS_PSK_WITH_AES_128_CBC_SHA256","TLS_PSK_WITH_AES_128_CBC_SHA","TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256","TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256","TLS_PSK_WITH_AES_128_CCM_8","TLS_PSK_WITH_3DES_EDE_CBC_SHA","TLS_EMPTY_RENEGOTIATION_INFO_SCSV"]
6+
2017 - Evandro Copercini - Apache 2.0 License.
7+
*/
8+
9+
#include <WiFiClientSecure.h>
10+
11+
char ssid[] = "your_network_name"; // your network SSID (name of wifi network)
12+
char pass[] = "your_password"; // your network password
13+
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
19+
20+
21+
WiFiClientSecure client;
22+
23+
void setup() {
24+
//Initialize serial and wait for port to open:
25+
Serial.begin(115200);
26+
delay(100);
27+
28+
Serial.print("Attempting to connect to SSID: ");
29+
Serial.println(ssid);
30+
WiFi.begin(ssid, pass);
31+
32+
// attempt to connect to Wifi network:
33+
while (WiFi.status() != WL_CONNECTED) {
34+
Serial.print(".");
35+
// wait 1 second for re-trying
36+
delay(1000);
37+
}
38+
39+
Serial.print("Connected to ");
40+
Serial.println(ssid);
41+
42+
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)
44+
Serial.println("Connected to server!");
45+
// Make a HTTP request:
46+
client.println("GET https://www.howsmyssl.com/a/check HTTP/1.0");
47+
client.println("Host: www.howsmyssl.com");
48+
client.println("Connection: close");
49+
client.println();
50+
}
51+
else
52+
Serial.println("Connection failed!");
53+
54+
Serial.print("Waiting for response "); //WiFiClientSecure uses a non blocking implementation
55+
while (!client.available()){
56+
delay(50); //
57+
Serial.print(".");
58+
}
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+
}
65+
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();
71+
}
72+
}
73+
74+
void loop() {
75+
// do nothing
76+
}

Diff for: libraries/WiFiClientSecure/keywords.txt

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#######################################
2+
# Syntax Coloring Map For WiFi
3+
#######################################
4+
5+
#######################################
6+
# Library (KEYWORD3)
7+
#######################################
8+
9+
WiFiClientSecure KEYWORD3
10+
11+
#######################################
12+
# Datatypes (KEYWORD1)
13+
#######################################
14+
15+
WiFiClientSecure KEYWORD1
16+
17+
#######################################
18+
# Methods and Functions (KEYWORD2)
19+
#######################################
20+
21+
connect KEYWORD2
22+
write KEYWORD2
23+
available KEYWORD2
24+
config KEYWORD2
25+
read KEYWORD2
26+
flush KEYWORD2
27+
stop KEYWORD2
28+
connected KEYWORD2
29+
setCACert KEYWORD2
30+
setCertificate KEYWORD2
31+
setPrivateKey KEYWORD2
32+
33+
#######################################
34+
# Constants (LITERAL1)
35+
#######################################

Diff for: libraries/WiFiClientSecure/library.properties

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name=WiFiClientSecure
2+
version=1.0
3+
author=Evandro Luis Copercini
4+
maintainer=Github Community
5+
sentence=Enables secure network connection (local and Internet) using the ESP32 built-in WiFi.
6+
paragraph=With this library you can make a TLS or SSL connection to a remote server.
7+
category=Communication
8+
url=
9+
architectures=esp32

Diff for: libraries/WiFiClientSecure/src/WiFiClientSecure.cpp

+190
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/*
2+
WiFiClientSecure.cpp - Client Secure class for ESP32
3+
Copyright (c) 2016 Hristo Gochkov All right reserved.
4+
Additions Copyright (C) 2017 Evandro Luis Copercini.
5+
6+
This library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2.1 of the License, or (at your option) any later version.
10+
11+
This library is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public
17+
License along with this library; if not, write to the Free Software
18+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19+
*/
20+
21+
#include "WiFiClientSecure.h"
22+
#include <lwip/sockets.h>
23+
#include <lwip/netdb.h>
24+
#include <errno.h>
25+
26+
#undef connect
27+
#undef write
28+
#undef read
29+
30+
31+
WiFiClientSecure::WiFiClientSecure()
32+
{
33+
_connected = false;
34+
35+
sslclient = new sslclient_context;
36+
ssl_init(sslclient);
37+
sslclient->socket = -1;
38+
39+
_CA_cert = NULL;
40+
_cert = NULL;
41+
_private_key = NULL;
42+
}
43+
44+
45+
WiFiClientSecure::WiFiClientSecure(int sock)
46+
{
47+
_connected = false;
48+
49+
sslclient = new sslclient_context;
50+
ssl_init(sslclient);
51+
sslclient->socket = sock;
52+
53+
if (sock >= 0) {
54+
_connected = true;
55+
}
56+
57+
_CA_cert = NULL;
58+
_cert = NULL;
59+
_private_key = NULL;
60+
}
61+
62+
WiFiClientSecure::~WiFiClientSecure()
63+
{
64+
stop();
65+
}
66+
67+
WiFiClientSecure &WiFiClientSecure::operator=(const WiFiClientSecure &other)
68+
{
69+
stop();
70+
sslclient->socket = other.sslclient->socket;
71+
_connected = other._connected;
72+
return *this;
73+
}
74+
75+
void WiFiClientSecure::stop()
76+
{
77+
if (_connected && sslclient->socket >= 0) {
78+
stop_ssl_socket(sslclient, _CA_cert, _cert, _private_key);
79+
sslclient->socket = -1;
80+
_connected = false;
81+
}
82+
}
83+
84+
int WiFiClientSecure::connect(IPAddress ip, uint16_t port)
85+
{
86+
connect(ip, port, _CA_cert, _cert, _private_key);
87+
}
88+
89+
int WiFiClientSecure::connect(const char *host, uint16_t port)
90+
{
91+
connect(host, port, _CA_cert, _cert, _private_key);
92+
}
93+
94+
int WiFiClientSecure::connect(IPAddress ip, uint16_t port, unsigned char *_CA_cert, unsigned char *_cert, unsigned char *_private_key)
95+
{
96+
int ret = start_ssl_client(sslclient, ip, port, _CA_cert, _cert, _private_key);
97+
if (ret < 0) {
98+
log_e("lwip_connect_r: %d", errno);
99+
}
100+
_connected = true;
101+
return 1;
102+
}
103+
104+
int WiFiClientSecure::connect(const char *host, uint16_t port, unsigned char *_CA_cert, unsigned char *_cert, unsigned char *_private_key)
105+
{
106+
struct hostent *server;
107+
server = gethostbyname(host);
108+
if (server == NULL) {
109+
return 0;
110+
}
111+
IPAddress srv((const uint8_t *)(server->h_addr));
112+
return connect(srv, port, _CA_cert, _cert, _private_key);
113+
}
114+
115+
116+
size_t WiFiClientSecure::write(uint8_t data)
117+
{
118+
return write(&data, 1);
119+
}
120+
121+
int WiFiClientSecure::read()
122+
{
123+
uint8_t data = 0;
124+
int res = read(&data, 1);
125+
if (res < 0) {
126+
return res;
127+
}
128+
return data;
129+
}
130+
131+
size_t WiFiClientSecure::write(const uint8_t *buf, size_t size)
132+
{
133+
if (!_connected) {
134+
return 0;
135+
}
136+
int res = send_ssl_data(sslclient, buf, size);
137+
if (res < 0) {
138+
log_e("%d", errno);
139+
stop();
140+
res = 0;
141+
}
142+
return res;
143+
}
144+
145+
int WiFiClientSecure::read(uint8_t *buf, size_t size)
146+
{
147+
if (!available()) {
148+
return -1;
149+
}
150+
int res = get_ssl_receive(sslclient, buf, size);
151+
if (res < 0 && errno != EWOULDBLOCK) {
152+
printf("%d", errno);
153+
stop();
154+
}
155+
return res;
156+
}
157+
158+
int WiFiClientSecure::available()
159+
{
160+
if (!_connected) {
161+
return 0;
162+
}
163+
int res = data_to_read(sslclient);
164+
165+
return res;
166+
}
167+
168+
uint8_t WiFiClientSecure::connected()
169+
{
170+
uint8_t dummy = 0;
171+
read(&dummy, 0);
172+
173+
return _connected;
174+
}
175+
176+
void WiFiClientSecure::setCACert(unsigned char *rootCA)
177+
{
178+
_CA_cert = rootCA;
179+
}
180+
181+
void WiFiClientSecure::setCertificate (unsigned char *client_ca)
182+
{
183+
_cert = client_ca;
184+
}
185+
186+
void WiFiClientSecure::setPrivateKey (unsigned char *private_key)
187+
{
188+
_private_key = private_key;
189+
}
190+

0 commit comments

Comments
 (0)