From 84b046f98c35d9da6c84323a624410fa7e9160bf Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Sun, 8 Oct 2017 05:04:04 +0800 Subject: [PATCH] WiFiClientSecure: add support for keys and certificates in PROGMEM --- .../examples/HTTPSRequestCACert/CACert.ino | 2 +- .../HTTPSRequestCACert/HTTPSRequestCACert.ino | 4 +-- .../ESP8266WiFi/src/WiFiClientSecure.cpp | 35 +++++++++++++++++++ libraries/ESP8266WiFi/src/WiFiClientSecure.h | 4 +++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/libraries/ESP8266WiFi/examples/HTTPSRequestCACert/CACert.ino b/libraries/ESP8266WiFi/examples/HTTPSRequestCACert/CACert.ino index 25973db20..9b84ed3b7 100644 --- a/libraries/ESP8266WiFi/examples/HTTPSRequestCACert/CACert.ino +++ b/libraries/ESP8266WiFi/examples/HTTPSRequestCACert/CACert.ino @@ -1,5 +1,5 @@ -const unsigned char caCert[] = { +const unsigned char caCert[] PROGMEM = { 0x30, 0x82, 0x03, 0xc5, 0x30, 0x82, 0x02, 0xad, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x02, 0xac, 0x5c, 0x26, 0x6a, 0x0b, 0x40, 0x9b, 0x8f, 0x0b, 0x79, 0xf2, 0xae, 0x46, 0x25, 0x77, 0x30, 0x0d, 0x06, 0x09, 0x2a, diff --git a/libraries/ESP8266WiFi/examples/HTTPSRequestCACert/HTTPSRequestCACert.ino b/libraries/ESP8266WiFi/examples/HTTPSRequestCACert/HTTPSRequestCACert.ino index 977f8f5c5..ddb24f7a4 100644 --- a/libraries/ESP8266WiFi/examples/HTTPSRequestCACert/HTTPSRequestCACert.ino +++ b/libraries/ESP8266WiFi/examples/HTTPSRequestCACert/HTTPSRequestCACert.ino @@ -27,7 +27,7 @@ const int httpsPort = 443; // Root certificate used by api.github.com. // Defined in "CACert" tab. -extern const unsigned char caCert[]; +extern const unsigned char caCert[] PROGMEM; extern const unsigned int caCertLen; WiFiClientSecure client; @@ -64,7 +64,7 @@ void setup() { Serial.print(asctime(&timeinfo)); // Load root certificate in DER format into WiFiClientSecure object - bool res = client.setCACert(caCert, caCertLen); + bool res = client.setCACert_P(caCert, caCertLen); if (!res) { Serial.println("Failed to load root CA certificate!"); while (true) { diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp index 84b5b640c..2fbd1897b 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.cpp @@ -209,6 +209,14 @@ public: return loadObject(type, buf.get(), size); } + bool loadObject_P(int type, PGM_VOID_P data, size_t size) + { + std::unique_ptr buf(new uint8_t[size]); + memcpy_P(buf.get(),data, size); + return loadObject(type, buf.get(), size); + } + + bool loadObject(int type, const uint8_t* data, size_t size) { int rc = ssl_obj_memory_load(_ssl_ctx, type, data, static_cast(size), nullptr); @@ -587,6 +595,33 @@ bool WiFiClientSecure::setPrivateKey(const uint8_t* pk, size_t size) return _ssl->loadObject(SSL_OBJ_RSA_KEY, pk, size); } +bool WiFiClientSecure::setCACert_P(PGM_VOID_P pk, size_t size) +{ + if (!_ssl) { + _ssl = new SSLContext; + _ssl->ref(); + } + return _ssl->loadObject_P(SSL_OBJ_X509_CACERT, pk, size); +} + +bool WiFiClientSecure::setCertificate_P(PGM_VOID_P pk, size_t size) +{ + if (!_ssl) { + _ssl = new SSLContext; + _ssl->ref(); + } + return _ssl->loadObject_P(SSL_OBJ_X509_CERT, pk, size); +} + +bool WiFiClientSecure::setPrivateKey_P(PGM_VOID_P pk, size_t size) +{ + if (!_ssl) { + _ssl = new SSLContext; + _ssl->ref(); + } + return _ssl->loadObject_P(SSL_OBJ_RSA_KEY, pk, size); +} + bool WiFiClientSecure::loadCACert(Stream& stream, size_t size) { if (!_ssl) { diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecure.h b/libraries/ESP8266WiFi/src/WiFiClientSecure.h index ae178513c..8a7c60259 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecure.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecure.h @@ -54,6 +54,10 @@ public: bool setCertificate(const uint8_t* pk, size_t size); bool setPrivateKey(const uint8_t* pk, size_t size); + bool setCACert_P(PGM_VOID_P pk, size_t size); + bool setCertificate_P(PGM_VOID_P pk, size_t size); + bool setPrivateKey_P(PGM_VOID_P pk, size_t size); + bool loadCACert(Stream& stream, size_t size); bool loadCertificate(Stream& stream, size_t size); bool loadPrivateKey(Stream& stream, size_t size);