diff --git a/docs/bearssl-client-secure-class.rst b/docs/bearssl-client-secure-class.rst index 9b7b0642f..aeb1739e3 100644 --- a/docs/bearssl-client-secure-class.rst +++ b/docs/bearssl-client-secure-class.rst @@ -113,6 +113,19 @@ Limiting TLS(SSL) Versions By default, BearSSL will connect with TLS 1.0, TLS 1.1, or TLS 1.2 protocols (depending on the request of the remote side). If you want to limit to a subset, use the following call: +setTLSConnectTimeout(int connectTimeout) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Because the Pico doesn't have any cryptographic acceleration, TLS connections can take up to 10 or 15 seconds to complete whereas the default `Stream` and `WiFiClent` timeout is only 5 seconds. To allow for this large difference, the timeout used for a `WiFiClientSecure::connect()` call is different from that used for a normal read or write (or normal `WiFiClient::connect()` call). + +By default, the connection phase of a TLS `WiFiClientSecure::connect()` is set to 15 seconds (all other read/writes use the value set with `setTimeout`). If your application needs to reduce this connection timeout, simply call: + +.. code :: cpp + + WiFiClientSecure::setTLSConnectTimeout(5000); // Value is in milliseconds + +This setting is global for all TLS connections. + setSSLVersion(uint32_t min, uint32_t max) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/libraries/WiFi/src/WiFiClass.h b/libraries/WiFi/src/WiFiClass.h index ae77700d0..a4b44ccbf 100644 --- a/libraries/WiFi/src/WiFiClass.h +++ b/libraries/WiFi/src/WiFiClass.h @@ -416,6 +416,7 @@ class WiFiClass { int ping(IPAddress host, uint8_t ttl = 128); void setTimeout(unsigned long timeout); + void setTLSConnectTimeout(unsigned long timeout); void setFeedWatchdogFunc(FeedHostProcessorWatchdogFuncPointer func); void feedWatchdog(); @@ -434,6 +435,7 @@ class WiFiClass { bool _beginInternal(const char* ssid, const char *passphrase, const uint8_t *bssid = nullptr); int _timeout = 15000; + int _tlsTimeout = 15000; String _ssid; uint8_t _bssid[6]; String _password; diff --git a/libraries/WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/WiFi/src/WiFiClientSecureBearSSL.cpp index 9211c031a..50f17eabc 100644 --- a/libraries/WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/WiFi/src/WiFiClientSecureBearSSL.cpp @@ -62,10 +62,9 @@ extern "C" uint32_t __picoRand() { namespace BearSSL { -void WiFiClientSecureCtx::_clear() { - // TLS handshake may take more than the 5 second default timeout - _timeout = 15000; +int WiFiClientSecure::_tlsConnectTimeout = 15000; +void WiFiClientSecureCtx::_clear() { _sc = nullptr; _sc_svr = nullptr; _eng = nullptr; @@ -268,7 +267,6 @@ void WiFiClientSecureCtx::_freeSSL() { _recvapp_len = 0; // This connection is toast _handshake_done = false; - _timeout = 15000; } bool WiFiClientSecureCtx::_clientConnected() { @@ -1206,7 +1204,12 @@ bool WiFiClientSecureCtx::_connectSSL(const char* hostName) { return false; } + // Just on connection, use the TLS timeout + auto holdTime = _timeout; + _timeout = WiFiClientSecure::_tlsConnectTimeout; auto ret = _wait_for_handshake(); + // Restore the prior timeout for normal use + _timeout = holdTime; #if defined(DEBUG_RP2040_CORE) && defined(DEBUG_RP2040_PORT) if (!ret) { char err[256]; @@ -1222,11 +1225,6 @@ bool WiFiClientSecureCtx::_connectSSL(const char* hostName) { _x509_insecure = nullptr; _x509_knownkey = nullptr; - // reduce timeout after successful handshake to fail fast if server stop accepting our data for whatever reason - if (ret) { - _timeout = 5000; - } - return ret; } diff --git a/libraries/WiFi/src/WiFiClientSecureBearSSL.h b/libraries/WiFi/src/WiFiClientSecureBearSSL.h index 3bf2b5294..1e5609443 100644 --- a/libraries/WiFi/src/WiFiClientSecureBearSSL.h +++ b/libraries/WiFi/src/WiFiClientSecureBearSSL.h @@ -578,6 +578,12 @@ class WiFiClientSecure : public WiFiClient { return _ctx->connect(host, port, rootCABuff, cli_cert, cli_key); } + // TLS handshake can take >10s, so we have a different connect timeout vs. normal read/write. Allow users to override the default, though. + static int _tlsConnectTimeout; + static void setTLSConnectTimeout(int ms) { + WiFiClientSecure::_tlsConnectTimeout = ms; + } + private: std::shared_ptr _ctx;