From 77bd71ec2987849491ec5d6d889eb77bad882f67 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Wed, 28 Oct 2020 07:22:41 -0700 Subject: [PATCH] Add Stream loaders for BearSSL (#7675) Fixes #7671 Allows for code to do things like read certs from LittleFS or even HTTP connections with code like: File cert = LittleFS.open("/client-crt.pem", "r"); clientCert = new X509List(cert, cert.size()); cert.close(); --- libraries/ESP8266WiFi/src/BearSSLHelpers.cpp | 40 ++++++++++++++++++++ libraries/ESP8266WiFi/src/BearSSLHelpers.h | 6 +++ 2 files changed, 46 insertions(+) diff --git a/libraries/ESP8266WiFi/src/BearSSLHelpers.cpp b/libraries/ESP8266WiFi/src/BearSSLHelpers.cpp index b3d1b60c2..ea1546965 100644 --- a/libraries/ESP8266WiFi/src/BearSSLHelpers.cpp +++ b/libraries/ESP8266WiFi/src/BearSSLHelpers.cpp @@ -626,6 +626,17 @@ namespace brssl { return pk; } + static uint8_t *loadStream(Stream& stream, size_t size) { + uint8_t *dest = (uint8_t *)malloc(size); + if (!dest) { + return nullptr; // OOM error + } + if (size != stream.readBytes(dest, size)) { + free(dest); // Error during read + return nullptr; + } + return dest; + } }; @@ -648,6 +659,15 @@ PublicKey::PublicKey(const uint8_t *derKey, size_t derLen) { parse(derKey, derLen); } +PublicKey::PublicKey(Stream &stream, size_t size) { + _key = nullptr; + auto buff = brssl::loadStream(stream, size); + if (buff) { + parse(buff, size); + free(buff); + } +} + PublicKey::~PublicKey() { if (_key) { brssl::free_public_key(_key); @@ -711,6 +731,15 @@ PrivateKey::PrivateKey(const uint8_t *derKey, size_t derLen) { parse(derKey, derLen); } +PrivateKey::PrivateKey(Stream &stream, size_t size) { + _key = nullptr; + auto buff = brssl::loadStream(stream, size); + if (buff) { + parse(buff, size); + free(buff); + } +} + PrivateKey::~PrivateKey() { if (_key) { brssl::free_private_key(_key); @@ -781,6 +810,17 @@ X509List::X509List(const uint8_t *derCert, size_t derLen) { append(derCert, derLen); } +X509List::X509List(Stream &stream, size_t size) { + _count = 0; + _cert = nullptr; + _ta = nullptr; + auto buff = brssl::loadStream(stream, size); + if (buff) { + append(buff, size); + free(buff); + } +} + X509List::~X509List() { brssl::free_certificates(_cert, _count); // also frees cert for (size_t i = 0; i < _count; i++) { diff --git a/libraries/ESP8266WiFi/src/BearSSLHelpers.h b/libraries/ESP8266WiFi/src/BearSSLHelpers.h index 5c1b67546..c101e8a59 100644 --- a/libraries/ESP8266WiFi/src/BearSSLHelpers.h +++ b/libraries/ESP8266WiFi/src/BearSSLHelpers.h @@ -43,6 +43,8 @@ class PublicKey { PublicKey(); PublicKey(const char *pemKey); PublicKey(const uint8_t *derKey, size_t derLen); + PublicKey(Stream& stream, size_t size); + PublicKey(Stream& stream) : PublicKey(stream, stream.available()) { }; ~PublicKey(); bool parse(const char *pemKey); @@ -69,6 +71,8 @@ class PrivateKey { PrivateKey(); PrivateKey(const char *pemKey); PrivateKey(const uint8_t *derKey, size_t derLen); + PrivateKey(Stream& stream, size_t size); + PrivateKey(Stream& stream) : PrivateKey(stream, stream.available()) { }; ~PrivateKey(); bool parse(const char *pemKey); @@ -98,6 +102,8 @@ class X509List { X509List(); X509List(const char *pemCert); X509List(const uint8_t *derCert, size_t derLen); + X509List(Stream& stream, size_t size); + X509List(Stream& stream) : X509List(stream, stream.available()) { }; ~X509List(); bool append(const char *pemCert);