Skip to content

Commit af699f4

Browse files
Allow std::vector to set a list of allowed ciphers
For C++ afficionados, allow std::vectors to be passed in to the setCipher() routine. The BearSSL object will now keep a copy of any set ciphers and free on object destruction. These custom lists should normally only be 1-4 entries long, so it is not expected to be a memory hog having this extra copy.
1 parent 4be10f8 commit af699f4

File tree

3 files changed

+36
-12
lines changed

3 files changed

+36
-12
lines changed

Diff for: libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation.ino

+8-2
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,18 @@ may make sense
205205
uint32_t now = millis();
206206
fetchURL(&client, host, port, path);
207207
uint32_t delta = millis() - now;
208-
now = millis();
209208
client.setInsecure();
210209
client.setCiphersLessSecure();
210+
now = millis();
211211
fetchURL(&client, host, port, path);
212212
uint32_t delta2 = millis() - now;
213-
Serial.printf("Using more secure: %dms\nUsing less secure ciphers: %dms\n", delta, delta2);
213+
std::vector<uint16_t> myCustomList = { BR_TLS_RSA_WITH_AES_256_CBC_SHA256, BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA };
214+
client.setInsecure();
215+
client.setCiphers(myCustomList);
216+
now = millis();
217+
fetchURL(&client, host, port, path);
218+
uint32_t delta3 = millis() - now;
219+
Serial.printf("Using more secure: %dms\nUsing less secure ciphers: %dms\nUsing custom cipher list: %dms\n", delta, delta2, delta3);
214220
}
215221

216222
void setup() {

Diff for: libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp

+22-6
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ WiFiClientSecure::~WiFiClientSecure() {
103103
_client->unref();
104104
_client = nullptr;
105105
}
106+
free(_cipher_list);
106107
_freeSSL();
107108
_local_bearssl_stack = nullptr; // Potentially delete it if we're the last SSL object
108109
if (_deleteChainKeyTA) {
@@ -735,10 +736,24 @@ extern "C" {
735736

736737
}
737738

738-
// Set the faster ciphers as the only ones allowed
739-
void WiFiClientSecure::setCiphersLessSecure()
740-
{
741-
setCiphers(faster_suites_P, sizeof(faster_suites_P)/sizeof(faster_suites_P[0]));
739+
// Set custom list of ciphers
740+
bool WiFiClientSecure::setCiphers(const uint16_t *cipherAry, int cipherCount) {
741+
free(_cipher_list);
742+
_cipher_list = (uint16_t *)malloc(cipherCount * sizeof(uint16_t));
743+
if (!_cipher_list) {
744+
return false;
745+
}
746+
memcpy_P(_cipher_list, cipherAry, cipherCount * sizeof(uint16_t));
747+
_cipher_cnt = cipherCount;
748+
return true;
749+
}
750+
751+
bool WiFiClientSecure::setCiphersLessSecure() {
752+
return setCiphers(faster_suites_P, sizeof(faster_suites_P)/sizeof(faster_suites_P[0]));
753+
}
754+
755+
bool WiFiClientSecure::setCiphers(std::vector<uint16_t> list) {
756+
return setCiphers(&list[0], list.size());
742757
}
743758

744759
// Installs the appropriate X509 cert validation method for a client connection
@@ -804,9 +819,10 @@ bool WiFiClientSecure::_connectSSL(const char* hostName) {
804819

805820
// If no cipher list yet set, use defaults
806821
if (_cipher_list == NULL) {
807-
setCiphers(suites_P, sizeof(suites_P) / sizeof(uint16_t));
822+
br_ssl_client_base_init(_sc.get(), suites_P, sizeof(suites_P) / sizeof(uint16_t));
823+
} else {
824+
br_ssl_client_base_init(_sc.get(), _cipher_list, _cipher_cnt);
808825
}
809-
br_ssl_client_base_init(_sc.get(), _cipher_list, _cipher_cnt);
810826
// Only failure possible in the installation is OOM
811827
if (!_installClientX509Validator()) {
812828
_freeSSL();

Diff for: libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#ifndef wificlientbearssl_h
2525
#define wificlientbearssl_h
26+
#include <vector>
2627
#include "WiFiClient.h"
2728
#include <bearssl/bearssl.h>
2829
#include "BearSSLHelpers.h"
@@ -106,8 +107,9 @@ class WiFiClientSecure : public WiFiClient {
106107

107108
// Select specific ciphers (i.e. optimize for speed over security)
108109
// These may be in PROGMEM or RAM, either will run properly
109-
void setCiphers(const uint16_t *cipherAry, int cipherCount) { _cipher_list = cipherAry; _cipher_cnt = cipherCount; }
110-
void setCiphersLessSecure(); // Only use the limited set of RSA ciphers without EC
110+
bool setCiphers(const uint16_t *cipherAry, int cipherCount);
111+
bool setCiphers(std::vector<uint16_t> list);
112+
bool setCiphersLessSecure(); // Only use the limited set of RSA ciphers without EC
111113

112114
// Check for Maximum Fragment Length support for given len
113115
static bool probeMaxFragmentLength(IPAddress ip, uint16_t port, uint16_t len);
@@ -176,8 +178,8 @@ class WiFiClientSecure : public WiFiClient {
176178
unsigned _knownkey_usages;
177179

178180
// Custom cipher list pointer or NULL if default
179-
const uint16_t *_cipher_list;
180-
uint16_t _cipher_cnt;
181+
uint16_t *_cipher_list;
182+
uint8_t _cipher_cnt;
181183

182184
unsigned char *_recvapp_buf;
183185
size_t _recvapp_len;

0 commit comments

Comments
 (0)