ESP32: fix silent WSS connection failure (missing setInsecure path) - #175
Open
iollama wants to merge 2 commits into
Open
ESP32: fix silent WSS connection failure (missing setInsecure path)#175iollama wants to merge 2 commits into
iollama wants to merge 2 commits into
Conversation
SecuredEsp32TcpClient exposes setCACert(), setCertificate() and setPrivateKey(), but has no setInsecure() -- even though the underlying WiFiClientSecure provides one. upgradeToSecuredConnection() is written as though the method exists. Because it does not, there is no way to reach WiFiClientSecure::setInsecure() through this class, and a client that asks for an insecure connection never gets one. The TLS handshake then fails with no diagnostic.
The ESP8266 branch of upgradeToSecuredConnection() ends in an else that calls setInsecure() when the caller supplied no fingerprint, trust anchors or client certificate. The ESP32 branch has no such fallback. The result is that on ESP32, calling WebsocketsClient::setInsecure() and then connect() to a wss:// endpoint leaves WiFiClientSecure in its default certificate-verification mode with no CA bundle loaded. Verification cannot succeed, so the handshake fails. It fails silently: connect() returns false with no message, no onEvent callback and nothing on the serial console, so it presents as a network or credentials problem rather than a library one. See issues gilmaimon#120, gilmaimon#101 and gilmaimon#152. This mirrors the existing ESP8266 behaviour rather than introducing new policy, and only takes effect when no credentials were supplied -- the CA cert, client certificate and private key paths are unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On ESP32,
wss://connections fail whenever the caller has not supplied TLS credentials -- and theyfail silently.
connect()returnsfalsewith no message, noonEventcallback and nothing onthe serial console, so it reads as a network or credentials problem rather than a library one.
This appears to be what's behind #120, #101 and #152.
Cause
Two gaps that combine:
1.
SecuredEsp32TcpClienthas nosetInsecure().src/tiny_websockets/network/esp32/esp32_tcp.hppwrapsWiFiClientSecureand forwardssetCACert(),setCertificate()andsetPrivateKey()-- but notsetInsecure(), even thoughWiFiClientSecureprovides it. There is no way to reach it through this class.2. The ESP32 branch of
upgradeToSecuredConnection()has no fallback.In
src/websockets_client.cpp, the ESP8266 branch ends with:The
#elif defined(ESP32)branch below it applies each optional credential and then stops. With nocredentials supplied, nothing disables verification, so
WiFiClientSecurestays in its defaultcertificate-verification mode with no CA bundle loaded. Verification cannot succeed and the
handshake dies.
WebsocketsClient::setInsecure()exists and clears the credential pointers, so calling it actuallyguarantees you land in the broken path -- the API that should make this work is the one that
triggers the failure.
Reproduction
masterwss://hostExpected: handshake completes, as it does on ESP8266 with the same code.
Actual:
connect()returnsfalse. No error, no callback, no output.The same sketch against a plain
ws://endpoint connects fine, which is what sends people lookingat their network and their credentials instead of at TLS.
The change
Two commits, one per gap:
ESP32: add missing setInsecure() to SecuredEsp32TcpClient-- forwards to the underlyingWiFiClientSecure, alongside the three setters already there.ESP32: fall back to insecure when no TLS credentials are configured-- adds theelsebranch,mirroring ESP8266.
+6 lines, no deletions, no behaviour change for anyone who does supply a CA cert, client
certificate or private key -- the fallback only runs when none were given. ESP8266 and Teensy41 are
untouched.
Note on provenance
These two patches have been running in production for months in
VA5, an ESP32-S3 voice assistant that talks to the
OpenAI Realtime API over WSS. It currently vendors a patched copy of this library because of exactly
this bug. I'd much rather depend on upstream -- happy to reshape the patch however you prefer.