From 2ae0c295c9a5ee5c210bd5c4579101c42c126cd9 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Mon, 27 Feb 2017 20:17:04 -0800 Subject: [PATCH 1/8] Add WiFiServerSecure, a HTTPS enabled web server Using the standard framework, patch in support for the server mode of axtls. User-supplied X509 certificates and RSA key are used for encryption. Users can generate self-signed certificates or use ones with a real CA. To generate a certificate and key usable under Linux or Windows with OpenSSL tools the following sequence of operations are needed: ...snip... BITS=512 pushd /tmp openssl genrsa -out tls.ca_key.pem $BITS openssl genrsa -out tls.key_$BITS.pem $BITS openssl rsa -in tls.key_$BITS.pem -out tls.key_$BITS -outform DER cat > certs.conf < + +const char* ssid = "your-ssid"; +const char* password = "your-password"; + +// The certificate is stored in PMEM +static const uint8_t x509[] ICACHE_RODATA_ATTR = { + 0x30, 0x82, 0x01, 0xc9, 0x30, 0x82, 0x01, 0x32, 0x02, 0x09, 0x00, 0xe6, + 0x60, 0x8d, 0xa3, 0x47, 0x8f, 0x57, 0x7a, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x29, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x70, + 0x73, 0x79, 0x63, 0x68, 0x6f, 0x70, 0x6c, 0x75, 0x67, 0x31, 0x12, 0x30, + 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x31, 0x32, 0x37, 0x2e, + 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, + 0x32, 0x32, 0x34, 0x30, 0x38, 0x30, 0x35, 0x33, 0x36, 0x5a, 0x17, 0x0d, + 0x33, 0x30, 0x31, 0x31, 0x30, 0x33, 0x30, 0x38, 0x30, 0x35, 0x33, 0x36, + 0x5a, 0x30, 0x29, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x0a, 0x70, 0x73, 0x79, 0x63, 0x68, 0x6f, 0x70, 0x6c, 0x75, 0x67, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x31, + 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9f, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, + 0x00, 0xb6, 0x59, 0xd0, 0x57, 0xbc, 0x3e, 0xb9, 0xa0, 0x6c, 0xf5, 0xd5, + 0x46, 0x49, 0xaa, 0x9a, 0xb3, 0xbf, 0x09, 0xa9, 0xbb, 0x82, 0x3b, 0xdf, + 0xb7, 0xe3, 0x5a, 0x8e, 0x31, 0xf7, 0x27, 0xdf, 0xaa, 0xed, 0xa3, 0xd6, + 0xf6, 0x74, 0x35, 0xfc, 0x8d, 0x0b, 0xbc, 0xa2, 0x96, 0x10, 0x57, 0xe8, + 0xb2, 0xaa, 0x94, 0xf2, 0x47, 0x12, 0x4e, 0x3f, 0x7c, 0x5e, 0x90, 0xfe, + 0xad, 0x75, 0x88, 0xca, 0x7b, 0x9a, 0x18, 0x15, 0xbe, 0x3d, 0xe0, 0x31, + 0xb5, 0x45, 0x7f, 0xe7, 0x9d, 0x22, 0x99, 0x65, 0xba, 0x63, 0x70, 0x81, + 0x3b, 0x37, 0x22, 0x97, 0x64, 0xc5, 0x57, 0x8c, 0x98, 0x9c, 0x10, 0x36, + 0x98, 0xf0, 0x0b, 0x19, 0x28, 0x16, 0x9a, 0x40, 0x31, 0x5f, 0xbc, 0xd9, + 0x8e, 0x73, 0x68, 0xe1, 0x6a, 0x5d, 0x91, 0x0b, 0x4f, 0x73, 0xa4, 0x6b, + 0x8f, 0xa5, 0xad, 0x12, 0x09, 0x32, 0xa7, 0x66, 0x3b, 0x02, 0x03, 0x01, + 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x1b, 0x46, 0x78, + 0xd1, 0xfa, 0x21, 0xc1, 0xd6, 0x75, 0xc0, 0x83, 0x59, 0x57, 0x05, 0xd5, + 0xae, 0xf8, 0x8c, 0x78, 0x03, 0x65, 0x3b, 0xbf, 0xef, 0x70, 0x3f, 0x78, + 0xc6, 0xe1, 0x5a, 0xac, 0xb1, 0x93, 0x5b, 0x41, 0x35, 0x45, 0x47, 0xf8, + 0x07, 0x86, 0x40, 0x34, 0xa2, 0x9e, 0x2a, 0x16, 0x8d, 0xea, 0xf9, 0x1e, + 0x1f, 0xd7, 0x70, 0xb4, 0x28, 0x6b, 0xd8, 0xf5, 0x3f, 0x33, 0x3f, 0xc2, + 0x2c, 0x69, 0xf2, 0xa3, 0x54, 0x4d, 0xbf, 0x7d, 0xf9, 0xde, 0x05, 0x0c, + 0x9c, 0xe3, 0x1b, 0x72, 0x07, 0x7b, 0x41, 0x76, 0x1a, 0x57, 0x03, 0x5d, + 0xb2, 0xff, 0x4c, 0x17, 0xbd, 0xd7, 0x73, 0x32, 0x98, 0x26, 0x6b, 0x2c, + 0xc4, 0xbf, 0x6e, 0x01, 0x36, 0x8b, 0xbf, 0x00, 0x48, 0x9c, 0xfb, 0x3d, + 0x7d, 0x76, 0x1f, 0x55, 0x96, 0x43, 0xc5, 0x4e, 0xc1, 0xa3, 0xa1, 0x6a, + 0x94, 0x5f, 0x84, 0x3a, 0xdd +}; + +// And so is the key. These could also be in DRAM +static const uint8_t rsakey[] ICACHE_RODATA_ATTR = { + 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xb6, + 0x59, 0xd0, 0x57, 0xbc, 0x3e, 0xb9, 0xa0, 0x6c, 0xf5, 0xd5, 0x46, 0x49, + 0xaa, 0x9a, 0xb3, 0xbf, 0x09, 0xa9, 0xbb, 0x82, 0x3b, 0xdf, 0xb7, 0xe3, + 0x5a, 0x8e, 0x31, 0xf7, 0x27, 0xdf, 0xaa, 0xed, 0xa3, 0xd6, 0xf6, 0x74, + 0x35, 0xfc, 0x8d, 0x0b, 0xbc, 0xa2, 0x96, 0x10, 0x57, 0xe8, 0xb2, 0xaa, + 0x94, 0xf2, 0x47, 0x12, 0x4e, 0x3f, 0x7c, 0x5e, 0x90, 0xfe, 0xad, 0x75, + 0x88, 0xca, 0x7b, 0x9a, 0x18, 0x15, 0xbe, 0x3d, 0xe0, 0x31, 0xb5, 0x45, + 0x7f, 0xe7, 0x9d, 0x22, 0x99, 0x65, 0xba, 0x63, 0x70, 0x81, 0x3b, 0x37, + 0x22, 0x97, 0x64, 0xc5, 0x57, 0x8c, 0x98, 0x9c, 0x10, 0x36, 0x98, 0xf0, + 0x0b, 0x19, 0x28, 0x16, 0x9a, 0x40, 0x31, 0x5f, 0xbc, 0xd9, 0x8e, 0x73, + 0x68, 0xe1, 0x6a, 0x5d, 0x91, 0x0b, 0x4f, 0x73, 0xa4, 0x6b, 0x8f, 0xa5, + 0xad, 0x12, 0x09, 0x32, 0xa7, 0x66, 0x3b, 0x02, 0x03, 0x01, 0x00, 0x01, + 0x02, 0x81, 0x81, 0x00, 0xa8, 0x55, 0xf9, 0x33, 0x45, 0x20, 0x52, 0x94, + 0x7a, 0x81, 0xe6, 0xc4, 0xe0, 0x34, 0x92, 0x63, 0xe4, 0xb3, 0xb2, 0xf0, + 0xda, 0xa5, 0x13, 0x3d, 0xda, 0xb0, 0x3a, 0x1c, 0x7e, 0x21, 0x5d, 0x25, + 0x9a, 0x03, 0x69, 0xea, 0x52, 0x15, 0x94, 0x73, 0x50, 0xa6, 0x6f, 0x21, + 0x41, 0x2d, 0x26, 0x2f, 0xe9, 0xb1, 0x5e, 0x87, 0xa5, 0xaa, 0x7e, 0x88, + 0xfd, 0x73, 0xb4, 0xe7, 0xc4, 0x5c, 0xe7, 0x2d, 0xeb, 0x9e, 0x6b, 0xe1, + 0xf1, 0x38, 0x45, 0xf4, 0x10, 0x12, 0xac, 0x79, 0x40, 0x72, 0xf0, 0x45, + 0x89, 0x5c, 0x9d, 0x8b, 0x7b, 0x5d, 0x69, 0xd9, 0x11, 0xf9, 0x25, 0xff, + 0xe1, 0x2a, 0xb3, 0x6d, 0x49, 0x18, 0x8d, 0x38, 0x0a, 0x6f, 0x0f, 0xbd, + 0x48, 0xd0, 0xdd, 0xcb, 0x41, 0x5c, 0x2a, 0x75, 0xa0, 0x51, 0x43, 0x4a, + 0x0b, 0xf6, 0xa2, 0xd2, 0xe9, 0xda, 0x37, 0xca, 0x2d, 0xd7, 0x22, 0x01, + 0x02, 0x41, 0x00, 0xe7, 0x11, 0xea, 0x93, 0xf4, 0x0b, 0xe6, 0xa0, 0x1a, + 0x57, 0x2d, 0xee, 0x96, 0x05, 0x5c, 0xa1, 0x08, 0x8f, 0x9c, 0xac, 0x9a, + 0x72, 0x60, 0x5a, 0x41, 0x2a, 0x92, 0x38, 0x36, 0xa5, 0xfe, 0xb9, 0x35, + 0xb2, 0x06, 0xbb, 0x02, 0x58, 0xc8, 0x93, 0xd6, 0x09, 0x6f, 0x57, 0xd7, + 0xc1, 0x2e, 0x90, 0xb3, 0x09, 0xdd, 0x0c, 0x63, 0x99, 0x91, 0xb7, 0xe4, + 0xcc, 0x6f, 0x78, 0x24, 0xbc, 0x3b, 0x7b, 0x02, 0x41, 0x00, 0xca, 0x06, + 0x4a, 0x09, 0x36, 0x08, 0xaa, 0x27, 0x08, 0x91, 0x86, 0xc5, 0x17, 0x14, + 0x6e, 0x24, 0x9a, 0x86, 0xd1, 0xbc, 0x41, 0xb1, 0x42, 0x5e, 0xe8, 0x80, + 0x5a, 0x8f, 0x7c, 0x9b, 0xe8, 0xcc, 0x28, 0xe1, 0xa2, 0x8f, 0xe9, 0xdc, + 0x60, 0xd5, 0x00, 0x34, 0x76, 0x32, 0x36, 0x00, 0x93, 0x69, 0x6b, 0xab, + 0xc6, 0x8b, 0x70, 0x95, 0x4e, 0xc2, 0x27, 0x4a, 0x24, 0x73, 0xbf, 0xcd, + 0x24, 0x41, 0x02, 0x40, 0x40, 0x46, 0x75, 0x90, 0x0e, 0x54, 0xb9, 0x24, + 0x53, 0xef, 0x68, 0x31, 0x73, 0xbd, 0xae, 0x14, 0x85, 0x43, 0x1d, 0x7b, + 0xcd, 0xc2, 0x7f, 0x16, 0xdc, 0x05, 0xb1, 0x82, 0xbd, 0x80, 0xd3, 0x28, + 0x45, 0xcd, 0x6d, 0x9d, 0xdb, 0x7b, 0x42, 0xe0, 0x0c, 0xab, 0xb7, 0x33, + 0x22, 0x2a, 0xf4, 0x7e, 0xff, 0xae, 0x80, 0xb4, 0x8f, 0x88, 0x0a, 0x46, + 0xb2, 0xf8, 0x43, 0x11, 0x92, 0x76, 0x61, 0xbd, 0x02, 0x40, 0x5c, 0x86, + 0x3a, 0xdc, 0x33, 0x1a, 0x0e, 0xcb, 0xa7, 0xb9, 0xf6, 0xae, 0x47, 0x5e, + 0xbc, 0xff, 0x18, 0xa2, 0x8c, 0x66, 0x1a, 0xf4, 0x13, 0x00, 0xa2, 0x9d, + 0x3e, 0x5c, 0x9e, 0xe6, 0x4c, 0xdd, 0x4c, 0x0f, 0xe2, 0xc2, 0xe4, 0x89, + 0x60, 0xf3, 0xcc, 0x8f, 0x3a, 0x5e, 0xce, 0xaa, 0xbe, 0xd8, 0xb6, 0x4e, + 0x4a, 0xb5, 0x4c, 0x0f, 0xa5, 0xad, 0x78, 0x0f, 0x15, 0xd8, 0xc9, 0x4c, + 0x2b, 0xc1, 0x02, 0x40, 0x4e, 0xe9, 0x78, 0x48, 0x94, 0x11, 0x75, 0xc1, + 0xa2, 0xc7, 0xff, 0xf0, 0x73, 0xa2, 0x93, 0xd7, 0x67, 0xc7, 0xf8, 0x96, + 0xac, 0x15, 0xaa, 0xe5, 0x5d, 0x18, 0x18, 0x29, 0xa9, 0x9a, 0xfc, 0xac, + 0x48, 0x4d, 0xa0, 0xca, 0xa2, 0x34, 0x09, 0x7c, 0x13, 0x22, 0x4c, 0xfc, + 0x31, 0x75, 0xa0, 0x21, 0x1e, 0x7a, 0x91, 0xbc, 0xb1, 0x97, 0xde, 0x43, + 0xe1, 0x40, 0x2b, 0xe3, 0xbd, 0x98, 0x44, 0xad +}; + + + +// Create an instance of the server +// specify the port to listen on as an argument +WiFiServerSecure server(443); + +void setup() { + Serial.begin(115200); + delay(10); + + // prepare GPIO2 + pinMode(2, OUTPUT); + digitalWrite(2, 0); + + // Connect to WiFi network + Serial.println(); + Serial.println(); + Serial.print("Connecting to "); + Serial.println(ssid); + + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(""); + Serial.println("WiFi connected"); + + // Set the certificates from PMEM (if using DRAM remove the _P from the call) + server.setServerKeyAndCert_P(rsakey, sizeof(rsakey), x509, sizeof(x509)); + + // Start the server + server.begin(); + Serial.println("Server started"); + + // Print the IP address + Serial.println(WiFi.localIP()); +} + +void loop() { + // Check if a client has connected + WiFiClientSecure client = server.available(); + if (!client) { + return; + } + + // Wait until the client sends some data + Serial.println("new client"); + unsigned long timeout = millis() + 3000; + while(!client.available() && millis() < timeout){ + delay(1); + } + if (millis() > timeout) { + Serial.println("timeout"); + client.flush(); + client.stop(); + return; + } + + // Read the first line of the request + String req = client.readStringUntil('\r'); + Serial.println(req); + client.flush(); + + // Match the request + int val; + if (req.indexOf("/gpio/0") != -1) + val = 0; + else if (req.indexOf("/gpio/1") != -1) + val = 1; + else { + Serial.println("invalid request"); + client.stop(); + return; + } + + // Set GPIO2 according to the request + digitalWrite(2, val); + + client.flush(); + + // Prepare the response + String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\r\n\r\nGPIO is now "; + s += (val)?"high":"low"; + s += "\n"; + + // Send the response to the client + client.print(s); + delay(1); + Serial.println("Client disonnected"); + + // The client will actually be disconnected + // when the function returns and 'client' object is detroyed +} + diff --git a/libraries/ESP8266WiFi/keywords.txt b/libraries/ESP8266WiFi/keywords.txt index 4e9c68d8bf..8abe60374b 100644 --- a/libraries/ESP8266WiFi/keywords.txt +++ b/libraries/ESP8266WiFi/keywords.txt @@ -15,6 +15,7 @@ ESP8266WiFi KEYWORD3 WiFi KEYWORD1 WiFiClient KEYWORD1 WiFiServer KEYWORD1 +WiFiServerSecure KEYWORD1 WiFiUDP KEYWORD1 WiFiClientSecure KEYWORD1 diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFi.h b/libraries/ESP8266WiFi/src/ESP8266WiFi.h index 50223af19e..9d6e7f9942 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFi.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFi.h @@ -38,6 +38,7 @@ extern "C" { #include "WiFiClient.h" #include "WiFiServer.h" +#include "WiFiServerSecure.h" #include "WiFiClientSecure.h" #ifdef DEBUG_ESP_WIFI diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp index da7248fab6..926df97bbe 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp @@ -103,6 +103,23 @@ class SSLContext } } + void connectServer(ClientContext *ctx) { + s_io_ctx = ctx; + _ssl = ssl_server_new(_ssl_ctx, 0); + _isServer = true; + + int timeout_ms = 5000; + uint32_t t = millis(); + + while (millis() - t < timeout_ms && ssl_handshake_status(_ssl) != SSL_OK) { + uint8_t* data; + int rc = ssl_read(_ssl, &data); + if (rc < SSL_OK) { + break; + } + } + } + void stop() { s_io_ctx = nullptr; @@ -110,7 +127,8 @@ class SSLContext bool connected() { - return _ssl != nullptr && ssl_handshake_status(_ssl) == SSL_OK; + if (_isServer) return _ssl != nullptr; + else return _ssl != nullptr && ssl_handshake_status(_ssl) == SSL_OK; } int read(uint8_t* dst, size_t size) @@ -218,6 +236,14 @@ class SSLContext return s_io_ctx; } + int loadServerX509Cert(const uint8_t *cert, int len) { + return ssl_obj_memory_load(SSLContext::_ssl_ctx, SSL_OBJ_X509_CERT, cert, len, NULL); + } + + int loadServerRSAKey(const uint8_t *rsakey, int len) { + return ssl_obj_memory_load(SSLContext::_ssl_ctx, SSL_OBJ_RSA_KEY, rsakey, len, NULL); + } + protected: int _readAll() { @@ -242,6 +268,7 @@ class SSLContext return _available; } + bool _isServer = false; static SSL_CTX* _ssl_ctx; static int _ssl_ctx_refcnt; SSL* _ssl = nullptr; @@ -285,6 +312,42 @@ WiFiClientSecure& WiFiClientSecure::operator=(const WiFiClientSecure& rhs) return *this; } +// Only called by the WifiServerSecure, need to get the keys/certs loaded before beginning +WiFiClientSecure::WiFiClientSecure(ClientContext* client, bool usePMEM, const uint8_t *rsakey, int rsakeyLen, const uint8_t *cert, int certLen) +{ + _client = client; + if (_ssl) { + _ssl->unref(); + _ssl = nullptr; + } + + _ssl = new SSLContext; + _ssl->ref(); + + if (usePMEM) { + // When using PMEM based certs, allocate stack and copy from flash to DRAM, call SSL functions to avoid + // heap fragmentation that would happen w/malloc() + uint8_t *stackData = (uint8_t*)alloca(max(certLen, rsakeyLen)); + if (rsakey && rsakeyLen) { + memcpy_P(stackData, rsakey, rsakeyLen); + _ssl->loadServerRSAKey(stackData, rsakeyLen); + } + if (cert && certLen) { + memcpy_P(stackData, cert, certLen); + _ssl->loadServerX509Cert(stackData, certLen); + } + } else { + if (rsakey && rsakeyLen) { + _ssl->loadServerRSAKey(rsakey, rsakeyLen); + } + if (cert && certLen) { + _ssl->loadServerX509Cert(cert, certLen); + } + } + _client->ref(); + _ssl->connectServer(client); +} + int WiFiClientSecure::connect(IPAddress ip, uint16_t port) { if (!WiFiClient::connect(ip, port)) { diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.h b/libraries/ESP8266WiFi/src/WiFiClientSecure.h index 4b5b9c9343..31eb522f66 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecure.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.h @@ -34,6 +34,8 @@ class WiFiClientSecure : public WiFiClient { ~WiFiClientSecure() override; WiFiClientSecure(const WiFiClientSecure&); WiFiClientSecure& operator=(const WiFiClientSecure&); + // Only called by WiFiServerSecure + WiFiClientSecure(ClientContext* client, bool usePMEM, const uint8_t *rsakey, int rsakeyLen, const uint8_t *cert, int certLen); int connect(IPAddress ip, uint16_t port) override; int connect(const char* name, uint16_t port) override; diff --git a/libraries/ESP8266WiFi/src/WiFiServer.h b/libraries/ESP8266WiFi/src/WiFiServer.h index 06f7d9c597..6c1e37c7c7 100644 --- a/libraries/ESP8266WiFi/src/WiFiServer.h +++ b/libraries/ESP8266WiFi/src/WiFiServer.h @@ -35,6 +35,9 @@ class ClientContext; class WiFiClient; class WiFiServer : public Server { + // Secure server needs access to all the private entries here + friend class WiFiServerSecure; + private: uint16_t _port; IPAddress _addr; diff --git a/libraries/ESP8266WiFi/src/WiFiServerSecure.cpp b/libraries/ESP8266WiFi/src/WiFiServerSecure.cpp new file mode 100644 index 0000000000..f527269a6e --- /dev/null +++ b/libraries/ESP8266WiFi/src/WiFiServerSecure.cpp @@ -0,0 +1,78 @@ +/* + WiFiServerSecure.cpp - SSL server for esp8266, mostly compatible + with Arduino WiFi shield library + + Copyright (c) 2017 Earle F. Philhower, III + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#define LWIP_INTERNAL + +extern "C" { + #include "osapi.h" + #include "ets_sys.h" +} + +#include "debug.h" +#include "ESP8266WiFi.h" +#include "WiFiClient.h" +#include "WiFiServer.h" +#include "lwip/opt.h" +#include "lwip/tcp.h" +#include "lwip/inet.h" +#include "include/ClientContext.h" +#include "WiFiServerSecure.h" + +WiFiServerSecure::WiFiServerSecure(IPAddress addr, uint16_t port) : WiFiServer(addr, port) +{ +} + +WiFiServerSecure::WiFiServerSecure(uint16_t port) : WiFiServer(port) +{ +} + +void WiFiServerSecure::setServerKeyAndCert(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen) +{ + this->usePMEM = false; + this->rsakey = key; + this->rsakeyLen = keyLen; + this->cert = cert; + this->certLen = certLen; +} + +void WiFiServerSecure::setServerKeyAndCert_P(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen) +{ + this->usePMEM = true; + this->rsakey = key; + this->rsakeyLen = keyLen; + this->cert = cert; + this->certLen = certLen; +} + +WiFiClientSecure WiFiServerSecure::available(uint8_t* status) +{ + if (_unclaimed) { + WiFiClientSecure result(_unclaimed, usePMEM, rsakey, rsakeyLen, cert, certLen); + _unclaimed = _unclaimed->next(); + result.setNoDelay(_noDelay); + DEBUGV("WS:av\r\n"); + return result; + } + + optimistic_yield(1000); + return WiFiClientSecure(); +} + diff --git a/libraries/ESP8266WiFi/src/WiFiServerSecure.h b/libraries/ESP8266WiFi/src/WiFiServerSecure.h new file mode 100644 index 0000000000..2f78970a0a --- /dev/null +++ b/libraries/ESP8266WiFi/src/WiFiServerSecure.h @@ -0,0 +1,43 @@ +/* + WiFiServerSecure.h - Library for Arduino ESP8266 + Copyright (c) 2017 Earle F. Philhower, III + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef wifiserversecure_h +#define wifiserversecure_h + +#include "WiFiServer.h" +class WiFiClientSecure; + +class WiFiServerSecure : public WiFiServer { +public: + WiFiServerSecure(IPAddress addr, uint16_t port); + WiFiServerSecure(uint16_t port); + void setServerKeyAndCert(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen); + void setServerKeyAndCert_P(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen); + virtual ~WiFiServerSecure() {} + WiFiClientSecure available(uint8_t* status = NULL); +private: + bool usePMEM = false; + const uint8_t *rsakey = nullptr; + int rsakeyLen = 0; + const uint8_t *cert = nullptr; + int certLen = 0; +}; + +#endif + From 5f97b10fdc56c1ea942bbfed910c9f1904d672bd Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Fri, 17 Mar 2017 20:52:37 -0700 Subject: [PATCH 2/8] Add self-signed cert generation script example --- .../WiFiHTTPSServer/WiFiHTTPSServer.ino | 5 +- .../WiFiHTTPSServer/make-self-signed-cert.sh | 49 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100755 libraries/ESP8266WiFi/examples/WiFiHTTPSServer/make-self-signed-cert.sh diff --git a/libraries/ESP8266WiFi/examples/WiFiHTTPSServer/WiFiHTTPSServer.ino b/libraries/ESP8266WiFi/examples/WiFiHTTPSServer/WiFiHTTPSServer.ino index c228b7f3b3..98c4085687 100644 --- a/libraries/ESP8266WiFi/examples/WiFiHTTPSServer/WiFiHTTPSServer.ino +++ b/libraries/ESP8266WiFi/examples/WiFiHTTPSServer/WiFiHTTPSServer.ino @@ -2,9 +2,10 @@ * This sketch demonstrates how to set up a simple HTTP-like server using HTTPS encryption. * A sample self-signed certificate is included. For your own application, please be sure * to GENERATE YOUR OWN AND REPLACE. + * * The server will set a GPIO pin depending on the request - * http://server_ip/gpio/0 will set the GPIO2 low, - * http://server_ip/gpio/1 will set the GPIO2 high + * https://server_ip/gpio/0 will set the GPIO2 low, + * https://server_ip/gpio/1 will set the GPIO2 high * server_ip is the IP address of the ESP8266 module, will be * printed to Serial when the module is connected. */ diff --git a/libraries/ESP8266WiFi/examples/WiFiHTTPSServer/make-self-signed-cert.sh b/libraries/ESP8266WiFi/examples/WiFiHTTPSServer/make-self-signed-cert.sh new file mode 100755 index 0000000000..0744804e3e --- /dev/null +++ b/libraries/ESP8266WiFi/examples/WiFiHTTPSServer/make-self-signed-cert.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# This script generates a self-signed certificate for use by the ESP8266 +# Replace your-name-here with somethine appropriate before running and use +# the generated .H files in your code as follows: +# +# static const uint8_t rsakey[] ICACHE_RODATA_ATTR = { +# #include "key.h" +# }; +# +# static const uint8_t x509[] ICACHE_RODATA_ATTR = { +# #include "x509.h" +# }; +# +# .... +# WiFiServerSecure server(443); +# server.setServerKeyAndCert_P(rsakey, sizeof(rsakey), x509, sizeof(x509)); +# .... + +# 1024 or 512. 512 saves memory... +BITS=512 +C=$PWD +pushd /tmp + +openssl genrsa -out tls.ca_key.pem $BITS +openssl genrsa -out tls.key_$BITS.pem $BITS +openssl rsa -in tls.key_$BITS.pem -out tls.key_$BITS -outform DER +cat > certs.conf < "$C/key.h" +xxd -i tls.x509_$BITS.cer | sed 's/.*{//' | sed 's/\};//' | sed 's/unsigned.*//' > "$C/x509.h" + +rm -f tls.ca_key.pem tls.key_$BITS.pem tls.key_$BITS certs.conf tls.ca_x509.req tls.x509_$BITS.req tls.ca_x509.pem tls.x509_$BITS.pem tls.srl tls.x509_$BITS.cer tls.ca_x509.cer + +popd From a566ea3e1bea8d667da643b9bec17790540e84e3 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Sat, 18 Mar 2017 07:54:48 -0700 Subject: [PATCH 3/8] Use a SHA-256 digest certificate, SHA1 deprecated --- .../WiFiHTTPSServer/WiFiHTTPSServer.ino | 144 +++++++----------- 1 file changed, 54 insertions(+), 90 deletions(-) diff --git a/libraries/ESP8266WiFi/examples/WiFiHTTPSServer/WiFiHTTPSServer.ino b/libraries/ESP8266WiFi/examples/WiFiHTTPSServer/WiFiHTTPSServer.ino index 98c4085687..1214277b9d 100644 --- a/libraries/ESP8266WiFi/examples/WiFiHTTPSServer/WiFiHTTPSServer.ino +++ b/libraries/ESP8266WiFi/examples/WiFiHTTPSServer/WiFiHTTPSServer.ino @@ -17,100 +17,64 @@ const char* password = "your-password"; // The certificate is stored in PMEM static const uint8_t x509[] ICACHE_RODATA_ATTR = { - 0x30, 0x82, 0x01, 0xc9, 0x30, 0x82, 0x01, 0x32, 0x02, 0x09, 0x00, 0xe6, - 0x60, 0x8d, 0xa3, 0x47, 0x8f, 0x57, 0x7a, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x29, - 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0a, 0x70, - 0x73, 0x79, 0x63, 0x68, 0x6f, 0x70, 0x6c, 0x75, 0x67, 0x31, 0x12, 0x30, - 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x31, 0x32, 0x37, 0x2e, - 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, - 0x32, 0x32, 0x34, 0x30, 0x38, 0x30, 0x35, 0x33, 0x36, 0x5a, 0x17, 0x0d, - 0x33, 0x30, 0x31, 0x31, 0x30, 0x33, 0x30, 0x38, 0x30, 0x35, 0x33, 0x36, - 0x5a, 0x30, 0x29, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x0c, 0x0a, 0x70, 0x73, 0x79, 0x63, 0x68, 0x6f, 0x70, 0x6c, 0x75, 0x67, - 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x31, - 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x30, 0x81, 0x9f, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, - 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, - 0x00, 0xb6, 0x59, 0xd0, 0x57, 0xbc, 0x3e, 0xb9, 0xa0, 0x6c, 0xf5, 0xd5, - 0x46, 0x49, 0xaa, 0x9a, 0xb3, 0xbf, 0x09, 0xa9, 0xbb, 0x82, 0x3b, 0xdf, - 0xb7, 0xe3, 0x5a, 0x8e, 0x31, 0xf7, 0x27, 0xdf, 0xaa, 0xed, 0xa3, 0xd6, - 0xf6, 0x74, 0x35, 0xfc, 0x8d, 0x0b, 0xbc, 0xa2, 0x96, 0x10, 0x57, 0xe8, - 0xb2, 0xaa, 0x94, 0xf2, 0x47, 0x12, 0x4e, 0x3f, 0x7c, 0x5e, 0x90, 0xfe, - 0xad, 0x75, 0x88, 0xca, 0x7b, 0x9a, 0x18, 0x15, 0xbe, 0x3d, 0xe0, 0x31, - 0xb5, 0x45, 0x7f, 0xe7, 0x9d, 0x22, 0x99, 0x65, 0xba, 0x63, 0x70, 0x81, - 0x3b, 0x37, 0x22, 0x97, 0x64, 0xc5, 0x57, 0x8c, 0x98, 0x9c, 0x10, 0x36, - 0x98, 0xf0, 0x0b, 0x19, 0x28, 0x16, 0x9a, 0x40, 0x31, 0x5f, 0xbc, 0xd9, - 0x8e, 0x73, 0x68, 0xe1, 0x6a, 0x5d, 0x91, 0x0b, 0x4f, 0x73, 0xa4, 0x6b, - 0x8f, 0xa5, 0xad, 0x12, 0x09, 0x32, 0xa7, 0x66, 0x3b, 0x02, 0x03, 0x01, - 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x1b, 0x46, 0x78, - 0xd1, 0xfa, 0x21, 0xc1, 0xd6, 0x75, 0xc0, 0x83, 0x59, 0x57, 0x05, 0xd5, - 0xae, 0xf8, 0x8c, 0x78, 0x03, 0x65, 0x3b, 0xbf, 0xef, 0x70, 0x3f, 0x78, - 0xc6, 0xe1, 0x5a, 0xac, 0xb1, 0x93, 0x5b, 0x41, 0x35, 0x45, 0x47, 0xf8, - 0x07, 0x86, 0x40, 0x34, 0xa2, 0x9e, 0x2a, 0x16, 0x8d, 0xea, 0xf9, 0x1e, - 0x1f, 0xd7, 0x70, 0xb4, 0x28, 0x6b, 0xd8, 0xf5, 0x3f, 0x33, 0x3f, 0xc2, - 0x2c, 0x69, 0xf2, 0xa3, 0x54, 0x4d, 0xbf, 0x7d, 0xf9, 0xde, 0x05, 0x0c, - 0x9c, 0xe3, 0x1b, 0x72, 0x07, 0x7b, 0x41, 0x76, 0x1a, 0x57, 0x03, 0x5d, - 0xb2, 0xff, 0x4c, 0x17, 0xbd, 0xd7, 0x73, 0x32, 0x98, 0x26, 0x6b, 0x2c, - 0xc4, 0xbf, 0x6e, 0x01, 0x36, 0x8b, 0xbf, 0x00, 0x48, 0x9c, 0xfb, 0x3d, - 0x7d, 0x76, 0x1f, 0x55, 0x96, 0x43, 0xc5, 0x4e, 0xc1, 0xa3, 0xa1, 0x6a, - 0x94, 0x5f, 0x84, 0x3a, 0xdd + 0x30, 0x82, 0x01, 0x3d, 0x30, 0x81, 0xe8, 0x02, 0x09, 0x00, 0xfe, 0x56, + 0x46, 0xf2, 0x78, 0xc6, 0x51, 0x17, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x26, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x45, 0x53, + 0x50, 0x38, 0x32, 0x36, 0x36, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, + 0x31, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x33, 0x31, 0x38, 0x31, + 0x34, 0x34, 0x39, 0x31, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x30, 0x31, 0x31, + 0x32, 0x35, 0x31, 0x34, 0x34, 0x39, 0x31, 0x38, 0x5a, 0x30, 0x26, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x07, 0x45, 0x53, + 0x50, 0x38, 0x32, 0x36, 0x36, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x09, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, + 0x31, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, + 0x41, 0x00, 0xc6, 0x72, 0x6c, 0x12, 0xe1, 0x20, 0x4d, 0x10, 0x0c, 0xf7, + 0x3a, 0x2a, 0x5a, 0x49, 0xe2, 0x2d, 0xc9, 0x7a, 0x63, 0x1d, 0xef, 0xc6, + 0xbb, 0xa3, 0xd6, 0x6f, 0x59, 0xcb, 0xd5, 0xf6, 0xbe, 0x34, 0x83, 0x33, + 0x50, 0x80, 0xec, 0x49, 0x63, 0xbf, 0xee, 0x59, 0x94, 0x67, 0x8b, 0x8d, + 0x81, 0x85, 0x23, 0x24, 0x06, 0x52, 0x76, 0x55, 0x9d, 0x18, 0x09, 0xb3, + 0x3c, 0x10, 0x40, 0x05, 0x01, 0xf3, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x03, 0x41, 0x00, 0x69, 0xdc, 0x6c, 0x9b, 0xa7, 0x62, 0x57, + 0x7e, 0x03, 0x01, 0x45, 0xad, 0x9a, 0x83, 0x90, 0x3a, 0xe7, 0xdf, 0xe8, + 0x8f, 0x46, 0x00, 0xd3, 0x5f, 0x2b, 0x0a, 0xde, 0x92, 0x1b, 0xc5, 0x04, + 0xc5, 0xc0, 0x76, 0xf4, 0xf6, 0x08, 0x36, 0x97, 0x27, 0x82, 0xf1, 0x60, + 0x76, 0xc2, 0xcd, 0x67, 0x6c, 0x4b, 0x6c, 0xca, 0xfd, 0x97, 0xfd, 0x33, + 0x9e, 0x12, 0x67, 0x6b, 0x98, 0x7e, 0xd5, 0x80, 0x8f }; // And so is the key. These could also be in DRAM static const uint8_t rsakey[] ICACHE_RODATA_ATTR = { - 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xb6, - 0x59, 0xd0, 0x57, 0xbc, 0x3e, 0xb9, 0xa0, 0x6c, 0xf5, 0xd5, 0x46, 0x49, - 0xaa, 0x9a, 0xb3, 0xbf, 0x09, 0xa9, 0xbb, 0x82, 0x3b, 0xdf, 0xb7, 0xe3, - 0x5a, 0x8e, 0x31, 0xf7, 0x27, 0xdf, 0xaa, 0xed, 0xa3, 0xd6, 0xf6, 0x74, - 0x35, 0xfc, 0x8d, 0x0b, 0xbc, 0xa2, 0x96, 0x10, 0x57, 0xe8, 0xb2, 0xaa, - 0x94, 0xf2, 0x47, 0x12, 0x4e, 0x3f, 0x7c, 0x5e, 0x90, 0xfe, 0xad, 0x75, - 0x88, 0xca, 0x7b, 0x9a, 0x18, 0x15, 0xbe, 0x3d, 0xe0, 0x31, 0xb5, 0x45, - 0x7f, 0xe7, 0x9d, 0x22, 0x99, 0x65, 0xba, 0x63, 0x70, 0x81, 0x3b, 0x37, - 0x22, 0x97, 0x64, 0xc5, 0x57, 0x8c, 0x98, 0x9c, 0x10, 0x36, 0x98, 0xf0, - 0x0b, 0x19, 0x28, 0x16, 0x9a, 0x40, 0x31, 0x5f, 0xbc, 0xd9, 0x8e, 0x73, - 0x68, 0xe1, 0x6a, 0x5d, 0x91, 0x0b, 0x4f, 0x73, 0xa4, 0x6b, 0x8f, 0xa5, - 0xad, 0x12, 0x09, 0x32, 0xa7, 0x66, 0x3b, 0x02, 0x03, 0x01, 0x00, 0x01, - 0x02, 0x81, 0x81, 0x00, 0xa8, 0x55, 0xf9, 0x33, 0x45, 0x20, 0x52, 0x94, - 0x7a, 0x81, 0xe6, 0xc4, 0xe0, 0x34, 0x92, 0x63, 0xe4, 0xb3, 0xb2, 0xf0, - 0xda, 0xa5, 0x13, 0x3d, 0xda, 0xb0, 0x3a, 0x1c, 0x7e, 0x21, 0x5d, 0x25, - 0x9a, 0x03, 0x69, 0xea, 0x52, 0x15, 0x94, 0x73, 0x50, 0xa6, 0x6f, 0x21, - 0x41, 0x2d, 0x26, 0x2f, 0xe9, 0xb1, 0x5e, 0x87, 0xa5, 0xaa, 0x7e, 0x88, - 0xfd, 0x73, 0xb4, 0xe7, 0xc4, 0x5c, 0xe7, 0x2d, 0xeb, 0x9e, 0x6b, 0xe1, - 0xf1, 0x38, 0x45, 0xf4, 0x10, 0x12, 0xac, 0x79, 0x40, 0x72, 0xf0, 0x45, - 0x89, 0x5c, 0x9d, 0x8b, 0x7b, 0x5d, 0x69, 0xd9, 0x11, 0xf9, 0x25, 0xff, - 0xe1, 0x2a, 0xb3, 0x6d, 0x49, 0x18, 0x8d, 0x38, 0x0a, 0x6f, 0x0f, 0xbd, - 0x48, 0xd0, 0xdd, 0xcb, 0x41, 0x5c, 0x2a, 0x75, 0xa0, 0x51, 0x43, 0x4a, - 0x0b, 0xf6, 0xa2, 0xd2, 0xe9, 0xda, 0x37, 0xca, 0x2d, 0xd7, 0x22, 0x01, - 0x02, 0x41, 0x00, 0xe7, 0x11, 0xea, 0x93, 0xf4, 0x0b, 0xe6, 0xa0, 0x1a, - 0x57, 0x2d, 0xee, 0x96, 0x05, 0x5c, 0xa1, 0x08, 0x8f, 0x9c, 0xac, 0x9a, - 0x72, 0x60, 0x5a, 0x41, 0x2a, 0x92, 0x38, 0x36, 0xa5, 0xfe, 0xb9, 0x35, - 0xb2, 0x06, 0xbb, 0x02, 0x58, 0xc8, 0x93, 0xd6, 0x09, 0x6f, 0x57, 0xd7, - 0xc1, 0x2e, 0x90, 0xb3, 0x09, 0xdd, 0x0c, 0x63, 0x99, 0x91, 0xb7, 0xe4, - 0xcc, 0x6f, 0x78, 0x24, 0xbc, 0x3b, 0x7b, 0x02, 0x41, 0x00, 0xca, 0x06, - 0x4a, 0x09, 0x36, 0x08, 0xaa, 0x27, 0x08, 0x91, 0x86, 0xc5, 0x17, 0x14, - 0x6e, 0x24, 0x9a, 0x86, 0xd1, 0xbc, 0x41, 0xb1, 0x42, 0x5e, 0xe8, 0x80, - 0x5a, 0x8f, 0x7c, 0x9b, 0xe8, 0xcc, 0x28, 0xe1, 0xa2, 0x8f, 0xe9, 0xdc, - 0x60, 0xd5, 0x00, 0x34, 0x76, 0x32, 0x36, 0x00, 0x93, 0x69, 0x6b, 0xab, - 0xc6, 0x8b, 0x70, 0x95, 0x4e, 0xc2, 0x27, 0x4a, 0x24, 0x73, 0xbf, 0xcd, - 0x24, 0x41, 0x02, 0x40, 0x40, 0x46, 0x75, 0x90, 0x0e, 0x54, 0xb9, 0x24, - 0x53, 0xef, 0x68, 0x31, 0x73, 0xbd, 0xae, 0x14, 0x85, 0x43, 0x1d, 0x7b, - 0xcd, 0xc2, 0x7f, 0x16, 0xdc, 0x05, 0xb1, 0x82, 0xbd, 0x80, 0xd3, 0x28, - 0x45, 0xcd, 0x6d, 0x9d, 0xdb, 0x7b, 0x42, 0xe0, 0x0c, 0xab, 0xb7, 0x33, - 0x22, 0x2a, 0xf4, 0x7e, 0xff, 0xae, 0x80, 0xb4, 0x8f, 0x88, 0x0a, 0x46, - 0xb2, 0xf8, 0x43, 0x11, 0x92, 0x76, 0x61, 0xbd, 0x02, 0x40, 0x5c, 0x86, - 0x3a, 0xdc, 0x33, 0x1a, 0x0e, 0xcb, 0xa7, 0xb9, 0xf6, 0xae, 0x47, 0x5e, - 0xbc, 0xff, 0x18, 0xa2, 0x8c, 0x66, 0x1a, 0xf4, 0x13, 0x00, 0xa2, 0x9d, - 0x3e, 0x5c, 0x9e, 0xe6, 0x4c, 0xdd, 0x4c, 0x0f, 0xe2, 0xc2, 0xe4, 0x89, - 0x60, 0xf3, 0xcc, 0x8f, 0x3a, 0x5e, 0xce, 0xaa, 0xbe, 0xd8, 0xb6, 0x4e, - 0x4a, 0xb5, 0x4c, 0x0f, 0xa5, 0xad, 0x78, 0x0f, 0x15, 0xd8, 0xc9, 0x4c, - 0x2b, 0xc1, 0x02, 0x40, 0x4e, 0xe9, 0x78, 0x48, 0x94, 0x11, 0x75, 0xc1, - 0xa2, 0xc7, 0xff, 0xf0, 0x73, 0xa2, 0x93, 0xd7, 0x67, 0xc7, 0xf8, 0x96, - 0xac, 0x15, 0xaa, 0xe5, 0x5d, 0x18, 0x18, 0x29, 0xa9, 0x9a, 0xfc, 0xac, - 0x48, 0x4d, 0xa0, 0xca, 0xa2, 0x34, 0x09, 0x7c, 0x13, 0x22, 0x4c, 0xfc, - 0x31, 0x75, 0xa0, 0x21, 0x1e, 0x7a, 0x91, 0xbc, 0xb1, 0x97, 0xde, 0x43, - 0xe1, 0x40, 0x2b, 0xe3, 0xbd, 0x98, 0x44, 0xad + 0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xc6, 0x72, + 0x6c, 0x12, 0xe1, 0x20, 0x4d, 0x10, 0x0c, 0xf7, 0x3a, 0x2a, 0x5a, 0x49, + 0xe2, 0x2d, 0xc9, 0x7a, 0x63, 0x1d, 0xef, 0xc6, 0xbb, 0xa3, 0xd6, 0x6f, + 0x59, 0xcb, 0xd5, 0xf6, 0xbe, 0x34, 0x83, 0x33, 0x50, 0x80, 0xec, 0x49, + 0x63, 0xbf, 0xee, 0x59, 0x94, 0x67, 0x8b, 0x8d, 0x81, 0x85, 0x23, 0x24, + 0x06, 0x52, 0x76, 0x55, 0x9d, 0x18, 0x09, 0xb3, 0x3c, 0x10, 0x40, 0x05, + 0x01, 0xf3, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x35, 0x0b, 0x74, + 0xd3, 0xff, 0x15, 0x51, 0x44, 0x0f, 0x13, 0x2e, 0x9b, 0x0f, 0x93, 0x5c, + 0x3f, 0xfc, 0xf1, 0x17, 0xf9, 0x72, 0x94, 0x5e, 0xa7, 0xc6, 0xb3, 0xf0, + 0xfe, 0xc9, 0x6c, 0xb1, 0x1e, 0x83, 0xb3, 0xc6, 0x45, 0x3a, 0x25, 0x60, + 0x7c, 0x3d, 0x92, 0x7d, 0x53, 0xec, 0x49, 0x8d, 0xb5, 0x45, 0x10, 0x99, + 0x9b, 0xc6, 0x22, 0x3a, 0x68, 0xc7, 0x13, 0x4e, 0xb6, 0x04, 0x61, 0x21, + 0x01, 0x02, 0x21, 0x00, 0xea, 0x8c, 0x21, 0xd4, 0x7f, 0x3f, 0xb6, 0x91, + 0xfa, 0xf8, 0xb9, 0x2d, 0xcb, 0x36, 0x36, 0x02, 0x5f, 0xf0, 0x0c, 0x6e, + 0x87, 0xaa, 0x5c, 0x14, 0xf6, 0x56, 0x8e, 0x12, 0x92, 0x25, 0xde, 0xb3, + 0x02, 0x21, 0x00, 0xd8, 0x99, 0x01, 0xf1, 0x04, 0x0b, 0x98, 0xa3, 0x71, + 0x56, 0x1d, 0xea, 0x6f, 0x45, 0xd1, 0x36, 0x70, 0x76, 0x8b, 0xab, 0x69, + 0x30, 0x58, 0x9c, 0xe0, 0x45, 0x97, 0xe7, 0xb6, 0xb5, 0xef, 0xc1, 0x02, + 0x21, 0x00, 0xa2, 0x01, 0x06, 0xc0, 0xf2, 0xdf, 0xbc, 0x28, 0x1a, 0xb4, + 0xbf, 0x9b, 0x5c, 0xd8, 0x65, 0xf7, 0xbf, 0xf2, 0x5b, 0x73, 0xe0, 0xeb, + 0x0f, 0xcd, 0x3e, 0xd5, 0x4c, 0x2e, 0x91, 0x99, 0xec, 0xb7, 0x02, 0x20, + 0x4b, 0x9d, 0x46, 0xd7, 0x3c, 0x01, 0x4c, 0x5d, 0x2a, 0xb0, 0xd4, 0xaa, + 0xc6, 0x03, 0xca, 0xa0, 0xc5, 0xac, 0x2c, 0xe0, 0x3f, 0x4d, 0x98, 0x71, + 0xd3, 0xbd, 0x97, 0xe5, 0x55, 0x9c, 0xb8, 0x41, 0x02, 0x20, 0x02, 0x42, + 0x9f, 0xd1, 0x06, 0x35, 0x3b, 0x42, 0xf5, 0x64, 0xaf, 0x6d, 0xbf, 0xcd, + 0x2c, 0x3a, 0xcd, 0x0a, 0x9a, 0x4d, 0x7c, 0xad, 0x29, 0xd6, 0x36, 0x57, + 0xd5, 0xdf, 0x34, 0xeb, 0x26, 0x03 }; From 73b008fbb545050439f2695b0098668b0e935154 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Thu, 25 May 2017 23:57:32 +0200 Subject: [PATCH 4/8] fix for multiple servers (use std::map) --- .../ESP8266WiFi/src/WiFiClientSecure.cpp | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp index 96be81485b..2e7d449d23 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp @@ -40,6 +40,8 @@ extern "C" #include "include/ClientContext.h" #include "c_types.h" +#include // is it too much? + #ifdef DEBUG_ESP_SSL #define DEBUG_SSL #endif @@ -59,6 +61,7 @@ class SSLContext _ssl_ctx = ssl_ctx_new(SSL_SERVER_VERIFY_LATER | SSL_DEBUG_OPTS | SSL_CONNECT_IN_PARTS | SSL_READ_BLOCKING | SSL_NO_DEFAULT_KEY, 0); } ++_ssl_ctx_refcnt; + _fd = ++_fdcounter; } ~SSLContext() @@ -72,8 +75,6 @@ class SSLContext if (_ssl_ctx_refcnt == 0) { ssl_ctx_free(_ssl_ctx); } - - s_io_ctx = nullptr; } void ref() @@ -93,11 +94,11 @@ class SSLContext SSL_EXTENSIONS* ext = ssl_ext_new(); ssl_ext_set_host_name(ext, hostName); ssl_ext_set_max_fragment_size(ext, 4096); - s_io_ctx = ctx; + s_io_ctx[_fd] = ctx; if (_ssl) { ssl_free(_ssl); } - _ssl = ssl_client_new(_ssl_ctx, 0, nullptr, 0, ext); + _ssl = ssl_client_new(_ssl_ctx, _fd, nullptr, 0, ext); uint32_t t = millis(); while (millis() - t < timeout_ms && ssl_handshake_status(_ssl) != SSL_OK) { @@ -110,8 +111,8 @@ class SSLContext } void connectServer(ClientContext *ctx) { - s_io_ctx = ctx; - _ssl = ssl_server_new(_ssl_ctx, 0); + s_io_ctx[_fd] = ctx; + _ssl = ssl_server_new(_ssl_ctx, _fd); _isServer = true; int timeout_ms = 5000; @@ -128,7 +129,6 @@ class SSLContext void stop() { - s_io_ctx = nullptr; } bool connected() @@ -238,8 +238,7 @@ class SSLContext static ClientContext* getIOContext(int fd) { - (void) fd; - return s_io_ctx; + return s_io_ctx[fd]; } int loadServerX509Cert(const uint8_t *cert, int len) { @@ -277,16 +276,19 @@ class SSLContext bool _isServer = false; static SSL_CTX* _ssl_ctx; static int _ssl_ctx_refcnt; + static int _fdcounter; // increased in constructor + int _fd; // axtls file descriptor SSL* _ssl = nullptr; int _refcnt = 0; const uint8_t* _read_ptr = nullptr; size_t _available = 0; - static ClientContext* s_io_ctx; + static std::map s_io_ctx; }; SSL_CTX* SSLContext::_ssl_ctx = nullptr; int SSLContext::_ssl_ctx_refcnt = 0; -ClientContext* SSLContext::s_io_ctx = nullptr; +int SSLContext::_fdcounter = 0; +std::map SSLContext::s_io_ctx; WiFiClientSecure::WiFiClientSecure() { From e7f047c603ed1f05062743e41abb031c21f55dc4 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Mon, 29 May 2017 02:13:43 +0200 Subject: [PATCH 5/8] remove axtls file descriptor from map in destructor --- libraries/ESP8266WiFi/src/WiFiClientSecure.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp index 2e7d449d23..9043b2d80a 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp @@ -75,6 +75,8 @@ class SSLContext if (_ssl_ctx_refcnt == 0) { ssl_ctx_free(_ssl_ctx); } + + s_io_ctx.erase(_fd); } void ref() From 75e609b23999077accd8e0114068e736f611a172 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Mon, 29 May 2017 02:23:04 +0200 Subject: [PATCH 6/8] minor fix for Wall Werror --- libraries/ESP8266WiFi/src/WiFiClientSecure.cpp | 2 +- libraries/ESP8266WiFi/src/WiFiServerSecure.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp index 9043b2d80a..8425aa2f63 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp @@ -117,7 +117,7 @@ class SSLContext _ssl = ssl_server_new(_ssl_ctx, _fd); _isServer = true; - int timeout_ms = 5000; + const uint32_t timeout_ms = 5000; uint32_t t = millis(); while (millis() - t < timeout_ms && ssl_handshake_status(_ssl) != SSL_OK) { diff --git a/libraries/ESP8266WiFi/src/WiFiServerSecure.cpp b/libraries/ESP8266WiFi/src/WiFiServerSecure.cpp index f527269a6e..5b5e90c612 100644 --- a/libraries/ESP8266WiFi/src/WiFiServerSecure.cpp +++ b/libraries/ESP8266WiFi/src/WiFiServerSecure.cpp @@ -64,6 +64,7 @@ void WiFiServerSecure::setServerKeyAndCert_P(const uint8_t *key, int keyLen, con WiFiClientSecure WiFiServerSecure::available(uint8_t* status) { + (void) status; if (_unclaimed) { WiFiClientSecure result(_unclaimed, usePMEM, rsakey, rsakeyLen, cert, certLen); _unclaimed = _unclaimed->next(); From d043f5db2c36c7c240ce6d7ef395114d292ccdb8 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Mon, 29 May 2017 02:36:33 +0200 Subject: [PATCH 7/8] fix fd removal from map --- libraries/ESP8266WiFi/src/WiFiClientSecure.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp index 8425aa2f63..cb73526a19 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp @@ -61,7 +61,7 @@ class SSLContext _ssl_ctx = ssl_ctx_new(SSL_SERVER_VERIFY_LATER | SSL_DEBUG_OPTS | SSL_CONNECT_IN_PARTS | SSL_READ_BLOCKING | SSL_NO_DEFAULT_KEY, 0); } ++_ssl_ctx_refcnt; - _fd = ++_fdcounter; + _fd = 0; // 0 = no yet used } ~SSLContext() @@ -76,7 +76,9 @@ class SSLContext ssl_ctx_free(_ssl_ctx); } - s_io_ctx.erase(_fd); + if (_fd) { + s_io_ctx.erase(_fd); + } } void ref() @@ -113,6 +115,7 @@ class SSLContext } void connectServer(ClientContext *ctx) { + _fd = ++_fdcounter; s_io_ctx[_fd] = ctx; _ssl = ssl_server_new(_ssl_ctx, _fd); _isServer = true; From e9d279cbfd0d1807064b48e96d5a30de84b246c7 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Mon, 29 May 2017 02:42:28 +0200 Subject: [PATCH 8/8] fix typo for fd removal from map --- libraries/ESP8266WiFi/src/WiFiClientSecure.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp index cb73526a19..4d5ba050ed 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp @@ -98,6 +98,7 @@ class SSLContext SSL_EXTENSIONS* ext = ssl_ext_new(); ssl_ext_set_host_name(ext, hostName); ssl_ext_set_max_fragment_size(ext, 4096); + _fd = ++_fdcounter; s_io_ctx[_fd] = ctx; if (_ssl) { ssl_free(_ssl);