-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add SSL Session capability to speed reconnections (#5160)
SSL Sessions enable most of the SSL handshake to be skipped when both client and server agree to use them. Add a BearSSLSession class and an optional setting to the SSL client to enable this. Note that SSL sessions are unrelated to HTTP sessions. They are ephemeral and only relate to the SSL parameters, not anything at the HTTP protocol level.
- Loading branch information
1 parent
8e11836
commit 6314093
Showing
4 changed files
with
191 additions
and
2 deletions.
There are no files selected for viewing
156 changes: 156 additions & 0 deletions
156
libraries/ESP8266WiFi/examples/BearSSL_Sessions/BearSSL_Sessions.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
// Example of using SSL sessions to speed up SSL connection initiation | ||
// | ||
// September 2018 by Earle F. Philhower, III | ||
// Released to the public domain | ||
|
||
#include <ESP8266WiFi.h> | ||
#include <time.h> | ||
|
||
const char *ssid = "...."; | ||
const char *pass = "...."; | ||
|
||
const char * host = "api.github.com"; | ||
const uint16_t port = 443; | ||
const char * path = "/"; | ||
|
||
void setup() { | ||
Serial.begin(115200); | ||
Serial.println(); | ||
Serial.println(); | ||
|
||
Serial.printf("Connecting to %s\n", ssid); | ||
WiFi.mode(WIFI_STA); | ||
WiFi.begin(ssid, pass); | ||
|
||
while (WiFi.status() != WL_CONNECTED) { | ||
delay(500); | ||
Serial.print("."); | ||
} | ||
Serial.println("\nConnected"); | ||
Serial.println("IP Address: "); | ||
Serial.println(WiFi.localIP()); | ||
|
||
// Set up time to allow for certificate validation | ||
configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov"); | ||
|
||
Serial.print("Waiting for NTP time sync: "); | ||
time_t now = time(nullptr); | ||
while (now < 8 * 3600 * 2) { | ||
delay(500); | ||
Serial.print("."); | ||
now = time(nullptr); | ||
} | ||
Serial.println(""); | ||
struct tm timeinfo; | ||
gmtime_r(&now, &timeinfo); | ||
Serial.print("Current time: "); | ||
Serial.print(asctime(&timeinfo)); | ||
} | ||
|
||
// Try and connect using a WiFiClientBearSSL to specified host:port and dump HTTP response | ||
void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_t port, const char *path) { | ||
if (!path) { | ||
path = "/"; | ||
} | ||
|
||
Serial.printf("Trying: %s:443...", host); | ||
client->connect(host, port); | ||
if (!client->connected()) { | ||
Serial.printf("*** Can't connect. ***\n-------\n"); | ||
return; | ||
} | ||
Serial.printf("Connected!\n-------\n"); | ||
client->write("GET "); | ||
client->write(path); | ||
client->write(" HTTP/1.0\r\nHost: "); | ||
client->write(host); | ||
client->write("\r\nUser-Agent: ESP8266\r\n"); | ||
client->write("\r\n"); | ||
uint32_t to = millis() + 5000; | ||
if (client->connected()) { | ||
do { | ||
char tmp[32]; | ||
memset(tmp, 0, 32); | ||
int rlen = client->read((uint8_t*)tmp, sizeof(tmp) - 1); | ||
yield(); | ||
if (rlen < 0) { | ||
break; | ||
} | ||
// Only print out first line up to \r, then abort connection | ||
char *nl = strchr(tmp, '\r'); | ||
if (nl) { | ||
*nl = 0; | ||
Serial.print(tmp); | ||
break; | ||
} | ||
Serial.print(tmp); | ||
} while (millis() < to); | ||
} | ||
client->stop(); | ||
Serial.printf("\n-------\n\n"); | ||
} | ||
|
||
|
||
void loop() { | ||
static const char digicert[] PROGMEM = R"EOF( | ||
-----BEGIN CERTIFICATE----- | ||
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs | ||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 | ||
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j | ||
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL | ||
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 | ||
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug | ||
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm | ||
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW | ||
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM | ||
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB | ||
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 | ||
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg | ||
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF | ||
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA | ||
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec | ||
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z | ||
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF | ||
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 | ||
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe | ||
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep | ||
+OkuE6N36B9K | ||
-----END CERTIFICATE----- | ||
)EOF"; | ||
uint32_t start, finish; | ||
BearSSL::WiFiClientSecure client; | ||
BearSSLX509List cert(digicert); | ||
|
||
Serial.printf("Connecting without sessions..."); | ||
start = millis(); | ||
client.setTrustAnchors(&cert); | ||
fetchURL(&client, host, port, path); | ||
finish = millis(); | ||
Serial.printf("Total time: %dms\n", finish - start); | ||
|
||
BearSSLSession session; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
earlephilhower
Author
Collaborator
|
||
client.setSession(&session); | ||
Serial.printf("Connecting with an unitialized session..."); | ||
start = millis(); | ||
client.setTrustAnchors(&cert); | ||
fetchURL(&client, host, port, path); | ||
finish = millis(); | ||
Serial.printf("Total time: %dms\n", finish - start); | ||
|
||
Serial.printf("Connecting with the just initialized session..."); | ||
start = millis(); | ||
client.setTrustAnchors(&cert); | ||
fetchURL(&client, host, port, path); | ||
finish = millis(); | ||
Serial.printf("Total time: %dms\n", finish - start); | ||
|
||
Serial.printf("Connecting again with the initialized session..."); | ||
start = millis(); | ||
client.setTrustAnchors(&cert); | ||
fetchURL(&client, host, port, path); | ||
finish = millis(); | ||
Serial.printf("Total time: %dms\n", finish - start); | ||
|
||
delay(10000); // Avoid DDOSing github | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The documentation says
Would you mind adding an example to show exactly that: how the session can survive deep-sleep if persisted to RTC RAM?