From ff6e94bf5876c51bed17ea325eaa72ef29b8d1fd Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Sun, 14 Jul 2019 07:14:51 -0700 Subject: [PATCH 1/5] Add a dump of received FP and CERT when in debug mode To simplify BearSSL debugging, print the received FP (when it doesn't match the expected) and the binary certificate (always), when in debug mode. --- .../src/WiFiClientSecureBearSSL.cpp | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index bc68ed3daf..012a88e4a3 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -654,6 +654,13 @@ extern "C" { if (!xc->done_cert) { br_sha1_update(&xc->sha1_cert, buf, len); br_x509_decoder_push(&xc->ctx, (const void*)buf, len); +#ifdef DEBUG_ESP_SSL + DEBUG_BSSL("CERT: "); + for (size_t i=0; isha1_cert, res); if (xc->match_fingerprint && memcmp(res, xc->match_fingerprint, sizeof(res))) { +#ifdef DEBUG_ESP_SSL DEBUG_BSSL("insecure_end_chain: Received cert FP doesn't match\n"); + char buff[3 * sizeof(res) + 5]; + buff[0] = 0; + for (size_t i=0; imatch_fingerprint[i] & 0xff); + strcat(buff, hex); + } + DEBUG_BSSL("insecure_end_chain: wanted %s\n", buff); + buff[0] =0; + for (size_t i=0; i Date: Sun, 14 Jul 2019 09:07:56 -0700 Subject: [PATCH 2/5] Update to -n- versions of string fcns, resize array Per review, clean up and comment. --- .../ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 012a88e4a3..e64e83fc16 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -685,19 +685,19 @@ extern "C" { if (xc->match_fingerprint && memcmp(res, xc->match_fingerprint, sizeof(res))) { #ifdef DEBUG_ESP_SSL DEBUG_BSSL("insecure_end_chain: Received cert FP doesn't match\n"); - char buff[3 * sizeof(res) + 5]; + char buff[3 * sizeof(res) + 1]; // 3 chars per byte XX_, and null buff[0] = 0; for (size_t i=0; imatch_fingerprint[i] & 0xff); - strcat(buff, hex); + char hex[4]; // XX_\0 + snprintf(hex, sizeof(hex), "%02x ", xc->match_fingerprint[i] & 0xff); + strncat(buff, hex, sizeof(buff)); } - DEBUG_BSSL("insecure_end_chain: wanted %s\n", buff); + DEBUG_BSSL("insecure_end_chain: expected %s\n", buff); buff[0] =0; for (size_t i=0; i Date: Sun, 14 Jul 2019 09:14:18 -0700 Subject: [PATCH 3/5] Replace strncat with strlcat to correct intent --- libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index e64e83fc16..5691f1cf5d 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -690,14 +690,14 @@ extern "C" { for (size_t i=0; imatch_fingerprint[i] & 0xff); - strncat(buff, hex, sizeof(buff)); + strlcat(buff, hex, sizeof(buff)); } DEBUG_BSSL("insecure_end_chain: expected %s\n", buff); buff[0] =0; for (size_t i=0; i Date: Sun, 14 Jul 2019 10:52:54 -0700 Subject: [PATCH 4/5] Add documentation section on FP mismatch in rare instances. --- doc/esp8266wifi/bearssl-client-secure-class.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/esp8266wifi/bearssl-client-secure-class.rst b/doc/esp8266wifi/bearssl-client-secure-class.rst index 4eee8ef54a..c8c54521db 100644 --- a/doc/esp8266wifi/bearssl-client-secure-class.rst +++ b/doc/esp8266wifi/bearssl-client-secure-class.rst @@ -109,7 +109,7 @@ See the `BearSSL_CertStore` example for full details as the `BearSSL::CertStore` Supported Crypto ~~~~~~~~~~~~~~~~ -Please see the `BearSSL website `__ for detailed cryptographic information. In general, TLS 1.2, TLS 1.1, and TLS 1.0 are supported with RSA and Elliptic Curve keys and a very rich set of hashing and symmetric encryption codes. Please note that Elliptic Curve (EC) key operations take a significant amount of time. +Please see the `BearSSL website `__ for detailed cryptographic information. In general, TLS 1.2, TLS 1.1, and TLS 1.0 are supported with RSA and Elliptic Curve keys and a very rich set of hashing and symmetric encryption codes. Please note that Elliptic Curve (EC) key operations take a significant amount of time. BearSSL::WiFiClientSecure Class @@ -139,6 +139,8 @@ 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");`) +This fingerprint is calcuated on the raw X509 certificate served by the server. In very rare cases, these certificates have certain encodings which should be normalized before taking a fingerprint (but in order to preserve memory BearSSL does not do this normalization since it would need RAM for an entire copy of the cert), and the fingerprint BearSSL calculates will not match the fingerprint OpenSSL calculates. In this case, you can enable SSL debugging and get a dump of BEarSSL's calculated fingerprint and use that one in your code, or use full certificate validation. See the `original issue and debug here `__. + setTrustAnchors(BearSSL::X509List \*ta) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From de24f633718ad129aed3b13681330034bb582efa Mon Sep 17 00:00:00 2001 From: Develo Date: Sun, 14 Jul 2019 16:21:18 -0400 Subject: [PATCH 5/5] Update bearssl-client-secure-class.rst Fix typo --- doc/esp8266wifi/bearssl-client-secure-class.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/esp8266wifi/bearssl-client-secure-class.rst b/doc/esp8266wifi/bearssl-client-secure-class.rst index c8c54521db..dc6886342a 100644 --- a/doc/esp8266wifi/bearssl-client-secure-class.rst +++ b/doc/esp8266wifi/bearssl-client-secure-class.rst @@ -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");`) -This fingerprint is calcuated on the raw X509 certificate served by the server. In very rare cases, these certificates have certain encodings which should be normalized before taking a fingerprint (but in order to preserve memory BearSSL does not do this normalization since it would need RAM for an entire copy of the cert), and the fingerprint BearSSL calculates will not match the fingerprint OpenSSL calculates. In this case, you can enable SSL debugging and get a dump of BEarSSL's calculated fingerprint and use that one in your code, or use full certificate validation. See the `original issue and debug here `__. +This fingerprint is calcuated on the raw X509 certificate served by the server. In very rare cases, these certificates have certain encodings which should be normalized before taking a fingerprint (but in order to preserve memory BearSSL does not do this normalization since it would need RAM for an entire copy of the cert), and the fingerprint BearSSL calculates will not match the fingerprint OpenSSL calculates. In this case, you can enable SSL debugging and get a dump of BearSSL's calculated fingerprint and use that one in your code, or use full certificate validation. See the `original issue and debug here `__. setTrustAnchors(BearSSL::X509List \*ta) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^