diff --git a/doc/esp8266wifi/bearssl-client-secure-class.rst b/doc/esp8266wifi/bearssl-client-secure-class.rst index 48a6485391..6c83de77ec 100644 --- a/doc/esp8266wifi/bearssl-client-secure-class.rst +++ b/doc/esp8266wifi/bearssl-client-secure-class.rst @@ -34,7 +34,7 @@ There are many configuration options that require passing in a pointer to an obj BearSSL::WiFiClientSecure client; const char x509CA PROGMEM = "......."; void setup() { - BearSSLX509List x509(x509CA); + BearSSL::X509List x509(x509CA); client.setTrustAnchor(&x509); } void loop() { @@ -73,7 +73,7 @@ TLS Sessions TLS supports the notion of a session (completely independent and different from HTTP sessions) which allow clients to reconnect to a server without having to renegotiate encryption settings or validate X509 certificates. This can save significant time (3-4 seconds in the case of EC keys) and can help save power by allowing the ESP8266 to sleep for a long time, reconnect and transmit some samples using the SSL session, and then jump back to sleep quicker. -`BearSSLSession` is an opaque class. Use the `BearSSL::WiFiClientSecure.setSession(&BearSSLSession)` method to apply it before the first `BearSSL::WiFiClientSecure.connect()` and it will be updated with session parameters during the operation of the connection. After the connection has had `.close()` called on it, serialize the `BearSSLSession` object to stable storage (EEPROM, RTC RAM, etc.) and restore it before trying to reconnect. See the `BearSSL_Sessions` example for a detailed example. +`BearSSL::Session` is an opaque class. Use the `BearSSL::WiFiClientSecure.setSession(&BearSSLSession)` method to apply it before the first `BearSSL::WiFiClientSecure.connect()` and it will be updated with session parameters during the operation of the connection. After the connection has had `.close()` called on it, serialize the `BearSSL::Session` object to stable storage (EEPROM, RTC RAM, etc.) and restore it before trying to reconnect. See the `BearSSL_Sessions` example for a detailed example. `Sessions <#sessions-resuming-connections-fast>`__ contains additional information on the sessions API. @@ -82,15 +82,15 @@ X.509 Certificate(s) X509 certificates are used to identify peers in TLS connections. Normally only the server identifies itself, but the client can also supply an X509 certificate if desired (this is often done in MQTT applications). The certificate contains many fields, but the most interesting in our applications are the name, the public key, and potentially a chain of signing that leads back to a trusted authority (like a global internet CA or a company-wide private certificate authority). -Any call that takes an X509 certificate can also take a list of X509 certificates, so there is no special `X509` class, simply `BearSSLX509List` (which may only contain a single certificate). +Any call that takes an X509 certificate can also take a list of X509 certificates, so there is no special `X509` class, simply `BearSSL::X509List` (which may only contain a single certificate). Generating a certificate to be used to validate using the constructor .. code:: cpp - BearSSLX509List(const char *pemX509); + BearSSL::X509List(const char *pemX509); ...or... - BearSSLX509List(const uint8_t *derCert, size_t derLen); + BearSSL::X509List(const uint8_t *derCert, size_t derLen); If you need to add additional certificates (unlikely in normal operation), the `::append()` operation can be used. @@ -100,7 +100,7 @@ Certificate Stores The web browser you're using to read this document keeps a list of 100s of certification authorities (CAs) worldwide that it trusts to attest to the identity of websites. -In many cases your application will know the specific CA it needs to validate web or MQTT servers against (often just a single, self-signing CA private to your institution). Simply load your private CA in a `BearSSLX509List` and use that as your trust anchor. +In many cases your application will know the specific CA it needs to validate web or MQTT servers against (often just a single, self-signing CA private to your institution). Simply load your private CA in a `BearSSL::X509List` and use that as your trust anchor. However, there are cases where you will not know beforehand which CA you will need (i.e. a user enters a website through a keypad), and you need to keep the list of CAs just like your web browser. In those cases, you need to generate a certificate bundle on the PC while compiling your application, upload the `certs.ar` bundle to SPIFFS or SD when uploading your application binary, and pass it to a `BearSSL::CertStore()` in order to validate TLS peers. @@ -129,7 +129,7 @@ setInsecure() Don't verify any X509 certificates. There is no guarantee that the server connected to is the one you think it is in this case, but this call will mimic the behavior of the deprecated axTLS code. -setKnownKey(const BearSSLPublicKey *pk) +setKnownKey(const BearSSL::PublicKey *pk) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Assume the server is using the specific public key. This does not verify the identity of the server or the X509 certificate it sends, it simply assumes that its public key is the one given. If the server updates its public key at a later point then connections will fail. @@ -139,7 +139,7 @@ setFingerprint(const uint8_t fp[20]) / setFingerprint(const char *fpStr) Verify the SHA1 fingerprint of the certificate returned matches this one. If the server certificate changes, it will fail. If an array of 20 bytes are sent in, it is assumed they are the binary SHA1 values. If a `char*` string is passed in, it is parsed as a series of human-readable hex values separated by spaces or colons (e.g. `setFingerprint("00:01:02:03:...:1f");`) -setTrustAnchors(BearSSLX509List *ta) +setTrustAnchors(BearSSL::X509List *ta) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use the passed-in certificate(s) as a trust anchor, accepting remote certificates signed by any of these. If you have many trust anchors it may make sense to use a `BearSSL::CertStore` because it will only require RAM for a single trust anchor (while the `setTrustAnchors` call requires memory for all certificates in the list). @@ -183,7 +183,7 @@ In certain applications where the TLS server does not support MFLN (not many do Sessions (Resuming connections fast) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -setSession(BearSSLSession &sess) +setSession(BearSSL::Session &sess) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If you are connecting to a server repeatedly in a fixed time period (usually 30 or 60 minutes, but normally configurable at the server), a TLS session can be used to cache crypto settings and speed up connections significantly. @@ -212,5 +212,3 @@ setCiphersLessSecure() ^^^^^^^^^^^^^^^^^^^^^^ Helper function which essentially limits BearSSL to ciphers that were supported by the deprecated axTLS. These may be less secure than the ones BearSSL would natively choose, but they may be helpful and faster if your server depended on specific axTLS crypto options. - - diff --git a/doc/esp8266wifi/bearssl-server-secure-class.rst b/doc/esp8266wifi/bearssl-server-secure-class.rst index e1114f254d..c8ef1947dd 100644 --- a/doc/esp8266wifi/bearssl-server-secure-class.rst +++ b/doc/esp8266wifi/bearssl-server-secure-class.rst @@ -23,12 +23,12 @@ This example command will generate a RSA 2048-bit key and certificate: Again, it is up to the application author to generate this certificate and key and keep the private key safe and **private.** -setRSACert(const BearSSLX509List *chain, const BearSSLPrivateKey *sk) +setRSACert(const BearSSL::X509List *chain, const BearSSL::PrivateKey *sk) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Sets a RSA certificate and key to be used by the server when connections are received. Needs to be called before `begin()` -setECCert(const BearSSLX509List *chain, unsigned cert_issuer_key_type, const BearSSLPrivateKey *sk) +setECCert(const BearSSL::X509List *chain, unsigned cert_issuer_key_type, const BearSSL::PrivateKey *sk) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Sets an elliptic curve certificate and key for the server. Needs to be called before `begin()`. @@ -38,7 +38,7 @@ Requiring Client Certificates TLS servers can request the client to identify itself by transmitting a certificate during handshake. If the client cannot transmit the certificate, the connection will be dropped by the server. -setClientTrustAnchor(const BearSSLX509List *client_CA_ta) +setClientTrustAnchor(const BearSSL::X509List *client_CA_ta) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Sets the trust anchor (normally a self-signing CA) that all received certificates will be verified against. Needs to be called before `begin()`. diff --git a/libraries/ESP8266HTTPUpdateServer/examples/SecureBearSSLUpdater/SecureBearSSLUpdater.ino b/libraries/ESP8266HTTPUpdateServer/examples/SecureBearSSLUpdater/SecureBearSSLUpdater.ino index 1a230fca57..f7ec895e71 100644 --- a/libraries/ESP8266HTTPUpdateServer/examples/SecureBearSSLUpdater/SecureBearSSLUpdater.ino +++ b/libraries/ESP8266HTTPUpdateServer/examples/SecureBearSSLUpdater/SecureBearSSLUpdater.ino @@ -101,7 +101,7 @@ void setup() MDNS.begin(host); - httpServer.setRSACert(new BearSSLX509List(serverCert), new BearSSLPrivateKey(serverKey)); + httpServer.setRSACert(new BearSSL::X509List(serverCert), new BearSSL::PrivateKey(serverKey)); httpUpdater.setup(&httpServer, update_path, update_username, update_password); httpServer.begin(); diff --git a/libraries/ESP8266WebServer/examples/HelloServerBearSSL/HelloServerBearSSL.ino b/libraries/ESP8266WebServer/examples/HelloServerBearSSL/HelloServerBearSSL.ino index acc466c77d..5ce0a2b44d 100644 --- a/libraries/ESP8266WebServer/examples/HelloServerBearSSL/HelloServerBearSSL.ino +++ b/libraries/ESP8266WebServer/examples/HelloServerBearSSL/HelloServerBearSSL.ino @@ -123,7 +123,7 @@ void setup(void){ Serial.println("MDNS responder started"); } - server.setRSACert(new BearSSLX509List(serverCert), new BearSSLPrivateKey(serverKey)); + server.setRSACert(new BearSSL::X509List(serverCert), new BearSSL::PrivateKey(serverKey)); server.on("/", handleRoot); diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServerSecureBearSSL.cpp b/libraries/ESP8266WebServer/src/ESP8266WebServerSecureBearSSL.cpp index 63ab49ceb6..83428ff1d7 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServerSecureBearSSL.cpp +++ b/libraries/ESP8266WebServer/src/ESP8266WebServerSecureBearSSL.cpp @@ -46,12 +46,12 @@ ESP8266WebServerSecure::ESP8266WebServerSecure(int port) { } -void ESP8266WebServerSecure::setRSACert(const BearSSLX509List *chain, const BearSSLPrivateKey *sk) +void ESP8266WebServerSecure::setRSACert(const X509List *chain, const PrivateKey *sk) { _serverSecure.setRSACert(chain, sk); } -void ESP8266WebServerSecure::setECCert(const BearSSLX509List *chain, unsigned cert_issuer_key_type, const BearSSLPrivateKey *sk) +void ESP8266WebServerSecure::setECCert(const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk) { _serverSecure.setECCert(chain, cert_issuer_key_type, sk); } @@ -83,7 +83,7 @@ void ESP8266WebServerSecure::begin() { void ESP8266WebServerSecure::handleClient() { if (_currentStatus == HC_NONE) { - BearSSL::WiFiClientSecure client = _serverSecure.available(); + WiFiClientSecure client = _serverSecure.available(); if (!client) { return; } @@ -136,7 +136,7 @@ void ESP8266WebServerSecure::handleClient() { } if (!keepCurrentClient) { - _currentClientSecure = BearSSL::WiFiClientSecure(); + _currentClientSecure = WiFiClientSecure(); _currentStatus = HC_NONE; _currentUpload.reset(); } diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServerSecureBearSSL.h b/libraries/ESP8266WebServer/src/ESP8266WebServerSecureBearSSL.h index 86785f81b0..d7a69a973a 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServerSecureBearSSL.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServerSecureBearSSL.h @@ -37,8 +37,8 @@ class ESP8266WebServerSecure : public ESP8266WebServer virtual ~ESP8266WebServerSecure(); void setBufferSizes(int recv, int xmit); - void setRSACert(const BearSSLX509List *chain, const BearSSLPrivateKey *sk); - void setECCert(const BearSSLX509List *chain, unsigned cert_issuer_key_type, const BearSSLPrivateKey *sk); + void setRSACert(const X509List *chain, const PrivateKey *sk); + void setECCert(const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk); WiFiClient client() override { return _currentClientSecure; } @@ -61,8 +61,8 @@ class ESP8266WebServerSecure : public ESP8266WebServer size_t _currentClientWrite_P (PGM_P bytes, size_t len) override { return _currentClientSecure.write_P(bytes, len); } protected: - BearSSL::WiFiServerSecure _serverSecure; - BearSSL::WiFiClientSecure _currentClientSecure; + WiFiServerSecure _serverSecure; + WiFiClientSecure _currentClientSecure; }; }; diff --git a/libraries/ESP8266WiFi/examples/BearSSL_Server/BearSSL_Server.ino b/libraries/ESP8266WiFi/examples/BearSSL_Server/BearSSL_Server.ino index 6b72a5e23b..51ba64dae2 100644 --- a/libraries/ESP8266WiFi/examples/BearSSL_Server/BearSSL_Server.ino +++ b/libraries/ESP8266WiFi/examples/BearSSL_Server/BearSSL_Server.ino @@ -121,8 +121,8 @@ void setup() { Serial.println(WiFi.localIP()); // Attach the server private cert/key combo - BearSSLX509List *serverCertList = new BearSSLX509List(server_cert); - BearSSLPrivateKey *serverPrivKey = new BearSSLPrivateKey(server_private_key); + BearSSL::X509List *serverCertList = new BearSSL::X509List(server_cert); + BearSSL::PrivateKey *serverPrivKey = new BearSSL::PrivateKey(server_private_key); server.setRSACert(serverCertList, serverPrivKey); // Actually start accepting connections diff --git a/libraries/ESP8266WiFi/examples/BearSSL_ServerClientCert/BearSSL_ServerClientCert.ino b/libraries/ESP8266WiFi/examples/BearSSL_ServerClientCert/BearSSL_ServerClientCert.ino index 9580ef53da..e4ea4badb8 100644 --- a/libraries/ESP8266WiFi/examples/BearSSL_ServerClientCert/BearSSL_ServerClientCert.ino +++ b/libraries/ESP8266WiFi/examples/BearSSL_ServerClientCert/BearSSL_ServerClientCert.ino @@ -197,12 +197,12 @@ void setup() { setClock(); // Required for X.509 validation // Attach the server private cert/key combo - BearSSLX509List *serverCertList = new BearSSLX509List(server_cert); - BearSSLPrivateKey *serverPrivKey = new BearSSLPrivateKey(server_private_key); + BearSSL::X509List *serverCertList = new BearSSL::X509List(server_cert); + BearSSL::PrivateKey *serverPrivKey = new BearSSL::PrivateKey(server_private_key); server.setRSACert(serverCertList, serverPrivKey); // Require a certificate validated by the trusted CA - BearSSLX509List *serverTrustedCA = new BearSSLX509List(ca_cert); + BearSSL::X509List *serverTrustedCA = new BearSSL::X509List(ca_cert); server.setClientTrustAnchor(serverTrustedCA); // Actually start accepting connections diff --git a/libraries/ESP8266WiFi/examples/BearSSL_Sessions/BearSSL_Sessions.ino b/libraries/ESP8266WiFi/examples/BearSSL_Sessions/BearSSL_Sessions.ino index 55604a3f73..10588ee896 100644 --- a/libraries/ESP8266WiFi/examples/BearSSL_Sessions/BearSSL_Sessions.ino +++ b/libraries/ESP8266WiFi/examples/BearSSL_Sessions/BearSSL_Sessions.ino @@ -119,7 +119,7 @@ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep )EOF"; uint32_t start, finish; BearSSL::WiFiClientSecure client; - BearSSLX509List cert(digicert); + BearSSL::X509List cert(digicert); Serial.printf("Connecting without sessions..."); start = millis(); @@ -128,7 +128,7 @@ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep finish = millis(); Serial.printf("Total time: %dms\n", finish - start); - BearSSLSession session; + BearSSL::Session session; client.setSession(&session); Serial.printf("Connecting with an unitialized session..."); start = millis(); diff --git a/libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation.ino b/libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation.ino index f59c6fca18..b1c0b96019 100644 --- a/libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation.ino +++ b/libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation.ino @@ -144,7 +144,7 @@ wQIDAQAB -----END PUBLIC KEY----- )KEY"; BearSSL::WiFiClientSecure client; - BearSSLPublicKey key(pubkey); + BearSSL::PublicKey key(pubkey); client.setKnownKey(&key); fetchURL(&client, host, port, path); } @@ -186,7 +186,7 @@ BearSSL does verify the notValidBefore/After fields. )EOF"); BearSSL::WiFiClientSecure client; - BearSSLX509List cert(digicert); + BearSSL::X509List cert(digicert); client.setTrustAnchors(&cert); Serial.printf("Try validating without setting the time (should fail)\n"); fetchURL(&client, host, port, path); diff --git a/libraries/ESP8266WiFi/keywords.txt b/libraries/ESP8266WiFi/keywords.txt index 29919efc39..66012c113b 100644 --- a/libraries/ESP8266WiFi/keywords.txt +++ b/libraries/ESP8266WiFi/keywords.txt @@ -19,11 +19,14 @@ WiFiServerSecure KEYWORD1 WiFiUDP KEYWORD1 WiFiClientSecure KEYWORD1 ESP8266WiFiMulti KEYWORD1 -BearSSLX509List KEYWORD1 -BearSSLPrivateKey KEYWORD1 -BearSSLPublicKey KEYWORD1 +BearSSL KEYWORD1 +X509List KEYWORD1 +PrivateKey KEYWORD1 +PublicKey KEYWORD1 CertStoreSPIFFSBearSSL KEYWORD1 CertStoreSDBearSSL KEYWORD1 +Session KEYWORD1 + ####################################### # Methods and Functions (KEYWORD2) diff --git a/libraries/ESP8266WiFi/src/BearSSLHelpers.cpp b/libraries/ESP8266WiFi/src/BearSSLHelpers.cpp index 38fcccd70d..e3d7ba1489 100644 --- a/libraries/ESP8266WiFi/src/BearSSLHelpers.cpp +++ b/libraries/ESP8266WiFi/src/BearSSLHelpers.cpp @@ -622,33 +622,36 @@ namespace brssl { }; +namespace BearSSL { + + // ----- Public Key ----- -BearSSLPublicKey::BearSSLPublicKey() { +PublicKey::PublicKey() { _key = nullptr; } -BearSSLPublicKey::BearSSLPublicKey(const char *pemKey) { +PublicKey::PublicKey(const char *pemKey) { _key = nullptr; parse(pemKey); } -BearSSLPublicKey::BearSSLPublicKey(const uint8_t *derKey, size_t derLen) { +PublicKey::PublicKey(const uint8_t *derKey, size_t derLen) { _key = nullptr; parse(derKey, derLen); } -BearSSLPublicKey::~BearSSLPublicKey() { +PublicKey::~PublicKey() { if (_key) { brssl::free_public_key(_key); } } -bool BearSSLPublicKey::parse(const char *pemKey) { +bool PublicKey::parse(const char *pemKey) { return parse((const uint8_t *)pemKey, strlen_P(pemKey)); } -bool BearSSLPublicKey::parse(const uint8_t *derKey, size_t derLen) { +bool PublicKey::parse(const uint8_t *derKey, size_t derLen) { if (_key) { brssl::free_public_key(_key); _key = nullptr; @@ -657,28 +660,28 @@ bool BearSSLPublicKey::parse(const uint8_t *derKey, size_t derLen) { return _key ? true : false; } -bool BearSSLPublicKey::isRSA() const { +bool PublicKey::isRSA() const { if (!_key || _key->key_type != BR_KEYTYPE_RSA) { return false; } return true; } -bool BearSSLPublicKey::isEC() const { +bool PublicKey::isEC() const { if (!_key || _key->key_type != BR_KEYTYPE_EC) { return false; } return true; } -const br_rsa_public_key *BearSSLPublicKey::getRSA() const { +const br_rsa_public_key *PublicKey::getRSA() const { if (!_key || _key->key_type != BR_KEYTYPE_RSA) { return nullptr; } return &_key->key.rsa; } -const br_ec_public_key *BearSSLPublicKey::getEC() const { +const br_ec_public_key *PublicKey::getEC() const { if (!_key || _key->key_type != BR_KEYTYPE_EC) { return nullptr; } @@ -687,31 +690,31 @@ const br_ec_public_key *BearSSLPublicKey::getEC() const { // ----- Private Key ----- -BearSSLPrivateKey::BearSSLPrivateKey() { +PrivateKey::PrivateKey() { _key = nullptr; } -BearSSLPrivateKey::BearSSLPrivateKey(const char *pemKey) { +PrivateKey::PrivateKey(const char *pemKey) { _key = nullptr; parse(pemKey); } -BearSSLPrivateKey::BearSSLPrivateKey(const uint8_t *derKey, size_t derLen) { +PrivateKey::PrivateKey(const uint8_t *derKey, size_t derLen) { _key = nullptr; parse(derKey, derLen); } -BearSSLPrivateKey::~BearSSLPrivateKey() { +PrivateKey::~PrivateKey() { if (_key) { brssl::free_private_key(_key); } } -bool BearSSLPrivateKey::parse(const char *pemKey) { +bool PrivateKey::parse(const char *pemKey) { return parse((const uint8_t *)pemKey, strlen_P(pemKey)); } -bool BearSSLPrivateKey::parse(const uint8_t *derKey, size_t derLen) { +bool PrivateKey::parse(const uint8_t *derKey, size_t derLen) { if (_key) { brssl::free_private_key(_key); _key = nullptr; @@ -720,41 +723,43 @@ bool BearSSLPrivateKey::parse(const uint8_t *derKey, size_t derLen) { return _key ? true : false; } -bool BearSSLPrivateKey::isRSA() const { +bool PrivateKey::isRSA() const { if (!_key || _key->key_type != BR_KEYTYPE_RSA) { return false; } return true; } -bool BearSSLPrivateKey::isEC() const { +bool PrivateKey::isEC() const { if (!_key || _key->key_type != BR_KEYTYPE_EC) { return false; } return true; } -const br_rsa_private_key *BearSSLPrivateKey::getRSA() const { +const br_rsa_private_key *PrivateKey::getRSA() const { if (!_key || _key->key_type != BR_KEYTYPE_RSA) { return nullptr; } return &_key->key.rsa; } -const br_ec_private_key *BearSSLPrivateKey::getEC() const { +const br_ec_private_key *PrivateKey::getEC() const { if (!_key || _key->key_type != BR_KEYTYPE_EC) { return nullptr; } return &_key->key.ec; } -BearSSLX509List::BearSSLX509List() { +// ----- Certificate Lists ----- + +X509List::X509List() { _count = 0; _cert = nullptr; _ta = nullptr; } -BearSSLX509List::BearSSLX509List(const char *pemCert) { +X509List::X509List(const char *pemCert) { _count = 0; _cert = nullptr; _ta = nullptr; @@ -762,14 +767,14 @@ BearSSLX509List::BearSSLX509List(const char *pemCert) { } -BearSSLX509List::BearSSLX509List(const uint8_t *derCert, size_t derLen) { +X509List::X509List(const uint8_t *derCert, size_t derLen) { _count = 0; _cert = nullptr; _ta = nullptr; append(derCert, derLen); } -BearSSLX509List::~BearSSLX509List() { +X509List::~X509List() { brssl::free_certificates(_cert, _count); // also frees cert for (size_t i = 0; i < _count; i++) { brssl::free_ta_contents(&_ta[i]); @@ -777,11 +782,11 @@ BearSSLX509List::~BearSSLX509List() { free(_ta); } -bool BearSSLX509List::append(const char *pemCert) { +bool X509List::append(const char *pemCert) { return append((const uint8_t *)pemCert, strlen_P(pemCert)); } -bool BearSSLX509List::append(const uint8_t *derCert, size_t derLen) { +bool X509List::append(const uint8_t *derCert, size_t derLen) { size_t numCerts; br_x509_certificate *newCerts = brssl::read_certificates((const char *)derCert, derLen, &numCerts); if (!newCerts) { @@ -819,3 +824,6 @@ bool BearSSLX509List::append(const uint8_t *derCert, size_t derLen) { return true; } + +}; + diff --git a/libraries/ESP8266WiFi/src/BearSSLHelpers.h b/libraries/ESP8266WiFi/src/BearSSLHelpers.h index 6cfe4e4aec..2e3a05740d 100644 --- a/libraries/ESP8266WiFi/src/BearSSLHelpers.h +++ b/libraries/ESP8266WiFi/src/BearSSLHelpers.h @@ -31,15 +31,17 @@ namespace brssl { class private_key; }; +namespace BearSSL { + // Holds either a single public RSA or EC key for use when BearSSL wants a pubkey. // Copies all associated data so no need to keep input PEM/DER keys. // All inputs can be either in RAM or PROGMEM. -class BearSSLPublicKey { +class PublicKey { public: - BearSSLPublicKey(); - BearSSLPublicKey(const char *pemKey); - BearSSLPublicKey(const uint8_t *derKey, size_t derLen); - ~BearSSLPublicKey(); + PublicKey(); + PublicKey(const char *pemKey); + PublicKey(const uint8_t *derKey, size_t derLen); + ~PublicKey(); bool parse(const char *pemKey); bool parse(const uint8_t *derKey, size_t derLen); @@ -51,7 +53,7 @@ class BearSSLPublicKey { const br_ec_public_key *getEC() const; // Disable the copy constructor, we're pointer based - BearSSLPublicKey(const BearSSLPublicKey& that) = delete; + PublicKey(const PublicKey& that) = delete; private: brssl::public_key *_key; @@ -60,12 +62,12 @@ class BearSSLPublicKey { // Holds either a single private RSA or EC key for use when BearSSL wants a secretkey. // Copies all associated data so no need to keep input PEM/DER keys. // All inputs can be either in RAM or PROGMEM. -class BearSSLPrivateKey { +class PrivateKey { public: - BearSSLPrivateKey(); - BearSSLPrivateKey(const char *pemKey); - BearSSLPrivateKey(const uint8_t *derKey, size_t derLen); - ~BearSSLPrivateKey(); + PrivateKey(); + PrivateKey(const char *pemKey); + PrivateKey(const uint8_t *derKey, size_t derLen); + ~PrivateKey(); bool parse(const char *pemKey); bool parse(const uint8_t *derKey, size_t derLen); @@ -77,7 +79,7 @@ class BearSSLPrivateKey { const br_ec_private_key *getEC() const; // Disable the copy constructor, we're pointer based - BearSSLPrivateKey(const BearSSLPrivateKey& that) = delete; + PrivateKey(const PrivateKey& that) = delete; private: brssl::private_key *_key; @@ -89,12 +91,12 @@ class BearSSLPrivateKey { // for a more memory efficient way). // Copies all associated data so no need to keep input PEM/DER certs. // All inputs can be either in RAM or PROGMEM. -class BearSSLX509List { +class X509List { public: - BearSSLX509List(); - BearSSLX509List(const char *pemCert); - BearSSLX509List(const uint8_t *derCert, size_t derLen); - ~BearSSLX509List(); + X509List(); + X509List(const char *pemCert); + X509List(const uint8_t *derCert, size_t derLen); + ~X509List(); bool append(const char *pemCert); bool append(const uint8_t *derCert, size_t derLen); @@ -111,7 +113,7 @@ class BearSSLX509List { } // Disable the copy constructor, we're pointer based - BearSSLX509List(const BearSSLX509List& that) = delete; + X509List(const X509List& that) = delete; private: size_t _count; @@ -121,19 +123,19 @@ class BearSSLX509List { // Opaque object which wraps the BearSSL SSL session to make repeated connections // significantly faster. Completely optional. -namespace BearSSL { - class WiFiClientSecure; -}; +class WiFiClientSecure; -class BearSSLSession { - friend class BearSSL::WiFiClientSecure; +class Session { + friend class WiFiClientSecure; public: - BearSSLSession() { memset(&_session, 0, sizeof(_session)); } + Session() { memset(&_session, 0, sizeof(_session)); } private: br_ssl_session_parameters *getSession() { return &_session; } // The actual BearSSL ession information br_ssl_session_parameters _session; }; +}; + #endif diff --git a/libraries/ESP8266WiFi/src/CertStoreBearSSL.cpp b/libraries/ESP8266WiFi/src/CertStoreBearSSL.cpp index 41f8e2d2bf..d0cc2066d9 100644 --- a/libraries/ESP8266WiFi/src/CertStoreBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/CertStoreBearSSL.cpp @@ -170,7 +170,7 @@ const br_x509_trust_anchor *CertStore::findHashedTA(void *ctx, void *hashed_dn, return nullptr; } cs->_data->close(); - cs->_x509 = new BearSSLX509List(der, ci.length); + cs->_x509 = new X509List(der, ci.length); free(der); br_x509_trust_anchor *ta = (br_x509_trust_anchor*)cs->_x509->getTrustAnchors(); diff --git a/libraries/ESP8266WiFi/src/CertStoreBearSSL.h b/libraries/ESP8266WiFi/src/CertStoreBearSSL.h index faa1c5b982..cc5a3432ec 100644 --- a/libraries/ESP8266WiFi/src/CertStoreBearSSL.h +++ b/libraries/ESP8266WiFi/src/CertStoreBearSSL.h @@ -67,7 +67,7 @@ class CertStore { protected: CertStoreFile *_index = nullptr; CertStoreFile *_data = nullptr; - BearSSLX509List *_x509 = nullptr; + X509List *_x509 = nullptr; // These need to be static as they are callbacks from BearSSL C code static const br_x509_trust_anchor *findHashedTA(void *ctx, void *hashed_dn, size_t len); diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 1491773b4e..99a271b3d7 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -123,8 +123,8 @@ WiFiClientSecure::~WiFiClientSecure() { } WiFiClientSecure::WiFiClientSecure(ClientContext* client, - const BearSSLX509List *chain, const BearSSLPrivateKey *sk, - int iobuf_in_size, int iobuf_out_size, const BearSSLX509List *client_CA_ta) { + const X509List *chain, const PrivateKey *sk, + int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta) { _clear(); _clearAuthenticationSettings(); _ensureStackAvailable(); @@ -141,9 +141,9 @@ WiFiClientSecure::WiFiClientSecure(ClientContext* client, } WiFiClientSecure::WiFiClientSecure(ClientContext *client, - const BearSSLX509List *chain, - unsigned cert_issuer_key_type, const BearSSLPrivateKey *sk, - int iobuf_in_size, int iobuf_out_size, const BearSSLX509List *client_CA_ta) { + const X509List *chain, + unsigned cert_issuer_key_type, const PrivateKey *sk, + int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta) { _clear(); _clearAuthenticationSettings(); _ensureStackAvailable(); @@ -159,13 +159,13 @@ WiFiClientSecure::WiFiClientSecure(ClientContext *client, } } -void WiFiClientSecure::setClientRSACert(const BearSSLX509List *chain, const BearSSLPrivateKey *sk) { +void WiFiClientSecure::setClientRSACert(const X509List *chain, const PrivateKey *sk) { _chain = chain; _sk = sk; } -void WiFiClientSecure::setClientECCert(const BearSSLX509List *chain, - const BearSSLPrivateKey *sk, unsigned allowed_usages, unsigned cert_issuer_key_type) { +void WiFiClientSecure::setClientECCert(const X509List *chain, + const PrivateKey *sk, unsigned allowed_usages, unsigned cert_issuer_key_type) { _chain = chain; _sk = sk; _allowed_usages = allowed_usages; @@ -939,7 +939,7 @@ bool WiFiClientSecure::_connectSSL(const char* hostName) { // Slightly different X509 setup for servers who want to validate client // certificates, so factor it out as it's used in RSA and EC servers. -bool WiFiClientSecure::_installServerX509Validator(const BearSSLX509List *client_CA_ta) { +bool WiFiClientSecure::_installServerX509Validator(const X509List *client_CA_ta) { if (client_CA_ta) { _ta = client_CA_ta; // X509 minimal validator. Checks dates, cert chain for trusted CA, etc. @@ -966,9 +966,9 @@ bool WiFiClientSecure::_installServerX509Validator(const BearSSLX509List *client } // Called by WiFiServerBearSSL when an RSA cert/key is specified. -bool WiFiClientSecure::_connectSSLServerRSA(const BearSSLX509List *chain, - const BearSSLPrivateKey *sk, - const BearSSLX509List *client_CA_ta) { +bool WiFiClientSecure::_connectSSLServerRSA(const X509List *chain, + const PrivateKey *sk, + const X509List *client_CA_ta) { _freeSSL(); _oom_err = false; _sc_svr = std::make_shared(); @@ -996,9 +996,9 @@ bool WiFiClientSecure::_connectSSLServerRSA(const BearSSLX509List *chain, } // Called by WiFiServerBearSSL when an elliptic curve cert/key is specified. -bool WiFiClientSecure::_connectSSLServerEC(const BearSSLX509List *chain, - unsigned cert_issuer_key_type, const BearSSLPrivateKey *sk, - const BearSSLX509List *client_CA_ta) { +bool WiFiClientSecure::_connectSSLServerEC(const X509List *chain, + unsigned cert_issuer_key_type, const PrivateKey *sk, + const X509List *client_CA_ta) { _freeSSL(); _oom_err = false; _sc_svr = std::make_shared(); @@ -1311,7 +1311,7 @@ bool WiFiClientSecure::setCACert(const uint8_t* pk, size_t size) { delete _ta; _ta = nullptr; } - _ta = new BearSSLX509List(pk, size); + _ta = new X509List(pk, size); _deleteChainKeyTA = true; return _ta ? true : false; } @@ -1321,7 +1321,7 @@ bool WiFiClientSecure::setCertificate(const uint8_t* pk, size_t size) { delete _chain; _chain = nullptr; } - _chain = new BearSSLX509List(pk, size); + _chain = new X509List(pk, size); _deleteChainKeyTA = true; return _chain ? true : false; } @@ -1331,7 +1331,7 @@ bool WiFiClientSecure::setPrivateKey(const uint8_t* pk, size_t size) { delete _sk; _sk = nullptr; } - _sk = new BearSSLPrivateKey(pk, size); + _sk = new PrivateKey(pk, size); _deleteChainKeyTA = true; return _sk ? true : false; diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h index bf4ced5c4f..e9b4875894 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h @@ -59,7 +59,7 @@ class WiFiClientSecure : public WiFiClient { bool stop(unsigned int maxWaitMs = 0) override; // Allow sessions to be saved/restored automatically to a memory area - void setSession(BearSSLSession *session) { _session = session; } + void setSession(Session *session) { _session = session; } // Don't validate the chain, just accept whatever is given. VERY INSECURE! void setInsecure() { @@ -67,7 +67,7 @@ class WiFiClientSecure : public WiFiClient { _use_insecure = true; } // Assume a given public key, don't validate or use cert info at all - void setKnownKey(const BearSSLPublicKey *pk, unsigned usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN) { + void setKnownKey(const PublicKey *pk, unsigned usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN) { _clearAuthenticationSettings(); _knownkey = pk; _knownkey_usages = usages; @@ -86,7 +86,7 @@ class WiFiClientSecure : public WiFiClient { _use_self_signed = true; } // Install certificates of trusted CAs or specific site - void setTrustAnchors(const BearSSLX509List *ta) { + void setTrustAnchors(const X509List *ta) { _clearAuthenticationSettings(); _ta = ta; } @@ -95,8 +95,8 @@ class WiFiClientSecure : public WiFiClient { _now = now; } // Install a client certificate for this connection, in case the server requires it (i.e. MQTT) - void setClientRSACert(const BearSSLX509List *cert, const BearSSLPrivateKey *sk); - void setClientECCert(const BearSSLX509List *cert, const BearSSLPrivateKey *sk, + void setClientRSACert(const X509List *cert, const PrivateKey *sk); + void setClientECCert(const X509List *cert, const PrivateKey *sk, unsigned allowed_usages, unsigned cert_issuer_key_type); // Sets the requested buffer size for transmit and receive @@ -168,7 +168,7 @@ class WiFiClientSecure : public WiFiClient { std::shared_ptr _iobuf_in; std::shared_ptr _iobuf_out; time_t _now; - const BearSSLX509List *_ta; + const X509List *_ta; CertStore *_certStore; int _iobuf_in_size; int _iobuf_out_size; @@ -177,13 +177,13 @@ class WiFiClientSecure : public WiFiClient { // Optional storage space pointer for session parameters // Will be used on connect and updated on close - BearSSLSession *_session; + Session *_session; bool _use_insecure; bool _use_fingerprint; uint8_t _fingerprint[20]; bool _use_self_signed; - const BearSSLPublicKey *_knownkey; + const PublicKey *_knownkey; unsigned _knownkey_usages; // Custom cipher list pointer or NULL if default @@ -201,27 +201,27 @@ class WiFiClientSecure : public WiFiClient { bool _wait_for_handshake(); // Sets and return the _handshake_done after connecting // Optional client certificate - const BearSSLX509List *_chain; - const BearSSLPrivateKey *_sk; + const X509List *_chain; + const PrivateKey *_sk; unsigned _allowed_usages; unsigned _cert_issuer_key_type; // Methods for handling server.available() call which returns a client connection. friend class WiFiServerSecure; // Server needs to access these constructors - WiFiClientSecure(ClientContext *client, const BearSSLX509List *chain, unsigned cert_issuer_key_type, - const BearSSLPrivateKey *sk, int iobuf_in_size, int iobuf_out_size, const BearSSLX509List *client_CA_ta); - WiFiClientSecure(ClientContext* client, const BearSSLX509List *chain, const BearSSLPrivateKey *sk, - int iobuf_in_size, int iobuf_out_size, const BearSSLX509List *client_CA_ta); + WiFiClientSecure(ClientContext *client, const X509List *chain, unsigned cert_issuer_key_type, + const PrivateKey *sk, int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta); + WiFiClientSecure(ClientContext* client, const X509List *chain, const PrivateKey *sk, + int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta); // RSA keyed server - bool _connectSSLServerRSA(const BearSSLX509List *chain, const BearSSLPrivateKey *sk, const BearSSLX509List *client_CA_ta); + bool _connectSSLServerRSA(const X509List *chain, const PrivateKey *sk, const X509List *client_CA_ta); // EC keyed server - bool _connectSSLServerEC(const BearSSLX509List *chain, unsigned cert_issuer_key_type, const BearSSLPrivateKey *sk, - const BearSSLX509List *client_CA_ta); + bool _connectSSLServerEC(const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk, + const X509List *client_CA_ta); // X.509 validators differ from server to client bool _installClientX509Validator(); // Set up X509 validator for a client conn. - bool _installServerX509Validator(const BearSSLX509List *client_CA_ta); // Setup X509 client cert validation, if supplied + bool _installServerX509Validator(const X509List *client_CA_ta); // Setup X509 client cert validation, if supplied uint8_t *_streamLoad(Stream& stream, size_t size); diff --git a/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.cpp index e7c3321bf8..206955a765 100644 --- a/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.cpp @@ -56,14 +56,14 @@ WiFiServerSecure::~WiFiServerSecure() { // Specify a RSA-signed certificate and key for the server. Only copies the pointer, the // caller needs to preserve this chain and key for the life of the object. -void WiFiServerSecure::setRSACert(const BearSSLX509List *chain, const BearSSLPrivateKey *sk) { +void WiFiServerSecure::setRSACert(const X509List *chain, const PrivateKey *sk) { _chain = chain; _sk = sk; } // Specify a EC-signed certificate and key for the server. Only copies the pointer, the // caller needs to preserve this chain and key for the life of the object. -void WiFiServerSecure::setECCert(const BearSSLX509List *chain, unsigned cert_issuer_key_type, const BearSSLPrivateKey *sk) { +void WiFiServerSecure::setECCert(const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk) { _chain = chain; _cert_issuer_key_type = cert_issuer_key_type; _sk = sk; @@ -99,8 +99,8 @@ WiFiClientSecure WiFiServerSecure::available(uint8_t* status) { void WiFiServerSecure::setServerKeyAndCert(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen) { - BearSSLX509List *chain = new BearSSLX509List(cert, certLen); - BearSSLPrivateKey *sk = new BearSSLPrivateKey(key, keyLen); + X509List *chain = new X509List(cert, certLen); + PrivateKey *sk = new PrivateKey(key, keyLen); if (!chain || !key) { // OOM, fail gracefully delete chain; diff --git a/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.h b/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.h index 0f165d2f40..3695e5f012 100644 --- a/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.h +++ b/libraries/ESP8266WiFi/src/WiFiServerSecureBearSSL.h @@ -43,14 +43,14 @@ class WiFiServerSecure : public WiFiServer { // Set the server's RSA key and x509 certificate (required, pick one). // Caller needs to preserve the chain and key throughout the life of the server. - void setRSACert(const BearSSLX509List *chain, const BearSSLPrivateKey *sk); + void setRSACert(const X509List *chain, const PrivateKey *sk); // Set the server's EC key and x509 certificate (required, pick one) // Caller needs to preserve the chain and key throughout the life of the server. - void setECCert(const BearSSLX509List *chain, unsigned cert_issuer_key_type, const BearSSLPrivateKey *sk); + void setECCert(const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk); // Require client certificates validated against the passed in x509 trust anchor // Caller needs to preserve the cert throughout the life of the server. - void setClientTrustAnchor(const BearSSLX509List *client_CA_ta) { + void setClientTrustAnchor(const X509List *client_CA_ta) { _client_CA_ta = client_CA_ta; } @@ -62,12 +62,12 @@ class WiFiServerSecure : public WiFiServer { void setServerKeyAndCert_P(const uint8_t *key, int keyLen, const uint8_t *cert, int certLen); private: - const BearSSLX509List *_chain = nullptr; + const X509List *_chain = nullptr; unsigned _cert_issuer_key_type = 0; - const BearSSLPrivateKey *_sk = nullptr; + const PrivateKey *_sk = nullptr; int _iobuf_in_size = BR_SSL_BUFSIZE_INPUT; int _iobuf_out_size = 837; - const BearSSLX509List *_client_CA_ta = nullptr; + const X509List *_client_CA_ta = nullptr; bool _deleteChainAndKey = false; };