TLS disable ECDSA for MQTT to ensure we don't break fingerprints after #22649 (#22656)

This commit is contained in:
s-hadinger 2024-12-15 19:43:51 +01:00 committed by GitHub
parent 90e0595b7f
commit 69d3fc1003
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 25 additions and 3 deletions

View File

@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
### Changed ### Changed
- ESP32 disable PSRAM check (and on restart some relay toggles) with `#define DISABLE_PSRAMCHECK` (#21266) - ESP32 disable PSRAM check (and on restart some relay toggles) with `#define DISABLE_PSRAMCHECK` (#21266)
- TLS disable ECDSA for MQTT to ensure we don't break fingerprints after #22649
### Fixed ### Fixed

View File

@ -195,6 +195,7 @@ void WiFiClientSecure_light::_clear() {
_recvapp_buf = nullptr; _recvapp_buf = nullptr;
_recvapp_len = 0; _recvapp_len = 0;
_insecure = false; // set to true when calling setPubKeyFingerprint() _insecure = false; // set to true when calling setPubKeyFingerprint()
_rsa_only = true; // for now we disable ECDSA by default
_fingerprint_any = true; // by default accept all fingerprints _fingerprint_any = true; // by default accept all fingerprints
_fingerprint1 = nullptr; _fingerprint1 = nullptr;
_fingerprint2 = nullptr; _fingerprint2 = nullptr;
@ -813,7 +814,10 @@ extern "C" {
// The tag string doesn't really matter, but it should differ depending on // The tag string doesn't really matter, but it should differ depending on
// key type. For ECDSA it's a fixed string. // key type. For ECDSA it's a fixed string.
sha1_update_len(&shactx, "ecdsa-sha2-nistp256", 19); // tag sha1_update_len(&shactx, "ecdsa", 5); // tag
int32_t curve = eckey.curve;
sha1_update_len(&shactx, &curve, 4); // curve id as int32
sha1_update_len(&shactx, "curve", 5); // tag2
sha1_update_len(&shactx, eckey.q, eckey.qlen); // exponent sha1_update_len(&shactx, eckey.q, eckey.qlen); // exponent
} }
#endif #endif
@ -888,16 +892,27 @@ extern "C" {
BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
}; };
static const uint16_t suites_RSA_ONLY[] = {
BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
};
#endif #endif
// Default initializion for our SSL clients // Default initializion for our SSL clients
static void br_ssl_client_base_init(br_ssl_client_context *cc) { static void br_ssl_client_base_init(br_ssl_client_context *cc, bool _rsa_only) {
br_ssl_client_zero(cc); br_ssl_client_zero(cc);
// forbid SSL renegotiation, as we free the Private Key after handshake // forbid SSL renegotiation, as we free the Private Key after handshake
br_ssl_engine_add_flags(&cc->eng, BR_OPT_NO_RENEGOTIATION); br_ssl_engine_add_flags(&cc->eng, BR_OPT_NO_RENEGOTIATION);
br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12);
#ifdef ESP8266
br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0]));
#else
if (_rsa_only) {
br_ssl_engine_set_suites(&cc->eng, suites_RSA_ONLY, (sizeof suites_RSA_ONLY) / (sizeof suites_RSA_ONLY[0]));
} else {
br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0]));
}
#endif
br_ssl_client_set_default_rsapub(cc); br_ssl_client_set_default_rsapub(cc);
br_ssl_engine_set_default_rsavrfy(&cc->eng); br_ssl_engine_set_default_rsavrfy(&cc->eng);
@ -945,7 +960,7 @@ bool WiFiClientSecure_light::_connectSSL(const char* hostName) {
_ctx_present = true; _ctx_present = true;
_eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr _eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr
br_ssl_client_base_init(_sc.get()); br_ssl_client_base_init(_sc.get(), _rsa_only);
if (_alpn_names && _alpn_num > 0) { if (_alpn_names && _alpn_num > 0) {
br_ssl_engine_set_protocol_names(_eng, _alpn_names, _alpn_num); br_ssl_engine_set_protocol_names(_eng, _alpn_names, _alpn_num);
} }

View File

@ -85,6 +85,10 @@ class WiFiClientSecure_light : public WiFiClient {
_fingerprint2 = f2; _fingerprint2 = f2;
_fingerprint_any = f_any; _fingerprint_any = f_any;
_insecure = true; _insecure = true;
_rsa_only = true; // if fingerprint, we limit to RSA only
}
void setRSAOnly(bool rsa_only) {
_rsa_only = rsa_only;
} }
const uint8_t * getRecvPubKeyFingerprint(void) { const uint8_t * getRecvPubKeyFingerprint(void) {
return _recv_fingerprint; return _recv_fingerprint;
@ -150,6 +154,7 @@ class WiFiClientSecure_light : public WiFiClient {
bool _fingerprint_any; // accept all fingerprints bool _fingerprint_any; // accept all fingerprints
bool _insecure; // force fingerprint bool _insecure; // force fingerprint
bool _rsa_only; // restrict to RSA only key exchange (no ECDSA - enabled to force RSA fingerprints)
const uint8_t *_fingerprint1; // fingerprint1 to be checked against const uint8_t *_fingerprint1; // fingerprint1 to be checked against
const uint8_t *_fingerprint2; // fingerprint2 to be checked against const uint8_t *_fingerprint2; // fingerprint2 to be checked against
uint8_t _recv_fingerprint[20]; // fingerprint received uint8_t _recv_fingerprint[20]; // fingerprint received

View File

@ -89,6 +89,7 @@ public:
{ {
BearSSL::WiFiClientSecure_light& wcs = static_cast<BearSSL::WiFiClientSecure_light&>(client); BearSSL::WiFiClientSecure_light& wcs = static_cast<BearSSL::WiFiClientSecure_light&>(client);
wcs.setPubKeyFingerprint(_fingerprint_any, _fingerprint_any, true); // allow all fingerprints wcs.setPubKeyFingerprint(_fingerprint_any, _fingerprint_any, true); // allow all fingerprints
wcs.setRSAOnly(false); // although we use fingerprint, we allow ECDSA
return true; return true;
} }