|
| 1 | +// Example of using SSL sessions to speed up SSL connection initiation |
| 2 | +// |
| 3 | +// September 2018 by Earle F. Philhower, III |
| 4 | +// Released to the public domain |
| 5 | + |
| 6 | +#include <ESP8266WiFi.h> |
| 7 | +#include <time.h> |
| 8 | + |
| 9 | +const char *ssid = "...."; |
| 10 | +const char *pass = "...."; |
| 11 | + |
| 12 | +const char * host = "api.github.com"; |
| 13 | +const uint16_t port = 443; |
| 14 | +const char * path = "/"; |
| 15 | + |
| 16 | +void setup() { |
| 17 | + Serial.begin(115200); |
| 18 | + Serial.println(); |
| 19 | + Serial.println(); |
| 20 | + |
| 21 | + Serial.printf("Connecting to %s\n", ssid); |
| 22 | + WiFi.mode(WIFI_STA); |
| 23 | + WiFi.begin(ssid, pass); |
| 24 | + |
| 25 | + while (WiFi.status() != WL_CONNECTED) { |
| 26 | + delay(500); |
| 27 | + Serial.print("."); |
| 28 | + } |
| 29 | + Serial.println("\nConnected"); |
| 30 | + Serial.println("IP Address: "); |
| 31 | + Serial.println(WiFi.localIP()); |
| 32 | + |
| 33 | + // Set up time to allow for certificate validation |
| 34 | + configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov"); |
| 35 | + |
| 36 | + Serial.print("Waiting for NTP time sync: "); |
| 37 | + time_t now = time(nullptr); |
| 38 | + while (now < 8 * 3600 * 2) { |
| 39 | + delay(500); |
| 40 | + Serial.print("."); |
| 41 | + now = time(nullptr); |
| 42 | + } |
| 43 | + Serial.println(""); |
| 44 | + struct tm timeinfo; |
| 45 | + gmtime_r(&now, &timeinfo); |
| 46 | + Serial.print("Current time: "); |
| 47 | + Serial.print(asctime(&timeinfo)); |
| 48 | +} |
| 49 | + |
| 50 | +// Try and connect using a WiFiClientBearSSL to specified host:port and dump HTTP response |
| 51 | +void fetchURL(BearSSL::WiFiClientSecure *client, const char *host, const uint16_t port, const char *path) { |
| 52 | + if (!path) { |
| 53 | + path = "/"; |
| 54 | + } |
| 55 | + |
| 56 | + Serial.printf("Trying: %s:443...", host); |
| 57 | + client->connect(host, port); |
| 58 | + if (!client->connected()) { |
| 59 | + Serial.printf("*** Can't connect. ***\n-------\n"); |
| 60 | + return; |
| 61 | + } |
| 62 | + Serial.printf("Connected!\n-------\n"); |
| 63 | + client->write("GET "); |
| 64 | + client->write(path); |
| 65 | + client->write(" HTTP/1.0\r\nHost: "); |
| 66 | + client->write(host); |
| 67 | + client->write("\r\nUser-Agent: ESP8266\r\n"); |
| 68 | + client->write("\r\n"); |
| 69 | + uint32_t to = millis() + 5000; |
| 70 | + if (client->connected()) { |
| 71 | + do { |
| 72 | + char tmp[32]; |
| 73 | + memset(tmp, 0, 32); |
| 74 | + int rlen = client->read((uint8_t*)tmp, sizeof(tmp) - 1); |
| 75 | + yield(); |
| 76 | + if (rlen < 0) { |
| 77 | + break; |
| 78 | + } |
| 79 | + // Only print out first line up to \r, then abort connection |
| 80 | + char *nl = strchr(tmp, '\r'); |
| 81 | + if (nl) { |
| 82 | + *nl = 0; |
| 83 | + Serial.print(tmp); |
| 84 | + break; |
| 85 | + } |
| 86 | + Serial.print(tmp); |
| 87 | + } while (millis() < to); |
| 88 | + } |
| 89 | + client->stop(); |
| 90 | + Serial.printf("\n-------\n\n"); |
| 91 | +} |
| 92 | + |
| 93 | + |
| 94 | +void loop() { |
| 95 | + static const char digicert[] PROGMEM = R"EOF( |
| 96 | +-----BEGIN CERTIFICATE----- |
| 97 | +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs |
| 98 | +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 |
| 99 | +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j |
| 100 | +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL |
| 101 | +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 |
| 102 | +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug |
| 103 | +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm |
| 104 | ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW |
| 105 | +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM |
| 106 | +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB |
| 107 | +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 |
| 108 | +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg |
| 109 | +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF |
| 110 | +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA |
| 111 | +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec |
| 112 | +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z |
| 113 | +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF |
| 114 | +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 |
| 115 | +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe |
| 116 | +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep |
| 117 | ++OkuE6N36B9K |
| 118 | +-----END CERTIFICATE----- |
| 119 | +)EOF"; |
| 120 | + uint32_t start, finish; |
| 121 | + BearSSL::WiFiClientSecure client; |
| 122 | + BearSSLX509List cert(digicert); |
| 123 | + |
| 124 | + Serial.printf("Connecting without sessions..."); |
| 125 | + start = millis(); |
| 126 | + client.setTrustAnchors(&cert); |
| 127 | + fetchURL(&client, host, port, path); |
| 128 | + finish = millis(); |
| 129 | + Serial.printf("Total time: %dms\n", finish - start); |
| 130 | + |
| 131 | + BearSSLSession session; |
| 132 | + client.setSession(&session); |
| 133 | + Serial.printf("Connecting with an unitialized session..."); |
| 134 | + start = millis(); |
| 135 | + client.setTrustAnchors(&cert); |
| 136 | + fetchURL(&client, host, port, path); |
| 137 | + finish = millis(); |
| 138 | + Serial.printf("Total time: %dms\n", finish - start); |
| 139 | + |
| 140 | + Serial.printf("Connecting with the just initialized session..."); |
| 141 | + start = millis(); |
| 142 | + client.setTrustAnchors(&cert); |
| 143 | + fetchURL(&client, host, port, path); |
| 144 | + finish = millis(); |
| 145 | + Serial.printf("Total time: %dms\n", finish - start); |
| 146 | + |
| 147 | + Serial.printf("Connecting again with the initialized session..."); |
| 148 | + start = millis(); |
| 149 | + client.setTrustAnchors(&cert); |
| 150 | + fetchURL(&client, host, port, path); |
| 151 | + finish = millis(); |
| 152 | + Serial.printf("Total time: %dms\n", finish - start); |
| 153 | + |
| 154 | + delay(10000); // Avoid DDOSing github |
| 155 | +} |
| 156 | + |
0 commit comments