Skip to content

Commit

Permalink
Add setSSLVersion call to SSL object
Browse files Browse the repository at this point in the history
Allow users to only allow specific TLS versions for connections with an
additional call in their app, similar to the setCiphers call.

Fixes #7918
  • Loading branch information
earlephilhower committed Mar 12, 2021
1 parent e07542d commit 70c8172
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 1 deletion.
12 changes: 11 additions & 1 deletion doc/esp8266wifi/bearssl-client-secure-class.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ BearSSL doesn't perform memory allocations at runtime, but it does require alloc
. A per-application secondary stack
. A per-connection TLS receive/transmit buffer plus overhead

The per-application secondary stack is approximately 5.6KB in size and is used for temporary variables during BearSSL processing. Only one stack is required, and it will be allocated whenever any `BearSSL::WiFiClientSecure` or `BearSSL::WiFiServerSecure` are instantiated. So, in the case of a global client or server, the memory will be allocated before `setup()` is called.
The per-application secondary stack is approximately 6KB in size and is used for temporary variables during BearSSL processing. Only one stack is required, and it will be allocated whenever any `BearSSL::WiFiClientSecure` or `BearSSL::WiFiServerSecure` are instantiated. So, in the case of a global client or server, the memory will be allocated before `setup()` is called.

The per-connection buffers are approximately 22KB in size, but in certain circumstances it can be reduced dramatically by using MFLN or limiting message sizes. See the `MLFN section <#mfln-or-maximum-fragment-length-negotiation-saving-ram>`__ below for more information.

Expand Down Expand Up @@ -219,3 +219,13 @@ setCiphersLessSecure()
^^^^^^^^^^^^^^^^^^^^^^

Helper function which essentially limits BearSSL to less secure ciphers than it would natively choose, but they may be helpful and faster if your server depended on specific crypto options.

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:

setSSLVersion(uint32_t min, uint32_t max)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Valid values for min and max are `BR_TLS10`, `BR_TLS11`, `BR_TLS12`. Min and max may be set to the same value if only a single TLS version is desired.
16 changes: 16 additions & 0 deletions libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ void WiFiClientSecureCtx::_clear() {
_session = nullptr;
_cipher_list = nullptr;
_cipher_cnt = 0;
_tls_min = BR_TLS10;
_tls_max = BR_TLS12;
}

void WiFiClientSecureCtx::_clearAuthenticationSettings() {
Expand Down Expand Up @@ -989,6 +991,17 @@ bool WiFiClientSecureCtx::setCiphers(const std::vector<uint16_t>& list) {
return setCiphers(&list[0], list.size());
}

bool WiFiClientSecureCtx::setSSLVersion(uint32_t min, uint32_t max) {
if ( ((min != BR_TLS10) && (min != BR_TLS11) && (min != BR_TLS12)) ||
((max != BR_TLS10) && (max != BR_TLS11) && (max != BR_TLS12)) ||
(max < min) ) {
return false; // Invalid options
}
_tls_min = min;
_tls_max = max;
return true;
}

// Installs the appropriate X509 cert validation method for a client connection
bool WiFiClientSecureCtx::_installClientX509Validator() {
if (_use_insecure || _use_fingerprint || _use_self_signed) {
Expand Down Expand Up @@ -1094,6 +1107,7 @@ bool WiFiClientSecureCtx::_connectSSL(const char* hostName) {
return false;
}
br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size);
br_ssl_engine_set_versions(_eng, _tls_min, _tls_max);

// Apply any client certificates, if supplied.
if (_sk && _sk->isRSA()) {
Expand Down Expand Up @@ -1208,6 +1222,7 @@ bool WiFiClientSecureCtx::_connectSSLServerRSA(const X509List *chain,
sk ? sk->getRSA() : nullptr, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN,
br_rsa_private_get_default(), br_rsa_pkcs1_sign_get_default());
br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size);
br_ssl_engine_set_versions(_eng, _tls_min, _tls_max);
if (cache != nullptr)
br_ssl_server_set_cache(_sc_svr.get(), cache->getCache());
if (client_CA_ta && !_installServerX509Validator(client_CA_ta)) {
Expand Down Expand Up @@ -1254,6 +1269,7 @@ bool WiFiClientSecureCtx::_connectSSLServerEC(const X509List *chain,
sk ? sk->getEC() : nullptr, BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN,
cert_issuer_key_type, br_ssl_engine_get_ec(_eng), br_ecdsa_i15_sign_asn1);
br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size);
br_ssl_engine_set_versions(_eng, _tls_min, _tls_max);
if (cache != nullptr)
br_ssl_server_set_cache(_sc_svr.get(), cache->getCache());
if (client_CA_ta && !_installServerX509Validator(client_CA_ta)) {
Expand Down
8 changes: 8 additions & 0 deletions libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ class WiFiClientSecureCtx : public WiFiClient {
bool setCiphers(const std::vector<uint16_t>& list);
bool setCiphersLessSecure(); // Only use the limited set of RSA ciphers without EC

// Limit the TLS versions BearSSL will connect with. Default is
// BR_TLS10...BR_TLS12
bool setSSLVersion(uint32_t min = BR_TLS10, uint32_t max = BR_TLS12);

protected:
bool _connectSSL(const char *hostName); // Do initial SSL handshake

Expand Down Expand Up @@ -161,6 +165,10 @@ class WiFiClientSecureCtx : public WiFiClient {
std::shared_ptr<uint16_t> _cipher_list;
uint8_t _cipher_cnt;

// TLS ciphers allowed
uint32_t _tls_min;
uint32_t _tls_max;

unsigned char *_recvapp_buf;
size_t _recvapp_len;

Expand Down

0 comments on commit 70c8172

Please sign in to comment.