Skip to content

Allow cipher specification for BearSSL #5151

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 21, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,25 @@ BearSSL does verify the notValidBefore/After fields.
fetchURL(&client, host, port, path);
}

void fetchAxTLS() {
Serial.printf(R"EOF(
The ciphers used to set up the SSL connection can be configured to
be the same as axTLS. They are faster, but less secure, so if you care
about security you won't want to do this.
)EOF");
BearSSL::WiFiClientSecure client;
client.setInsecure();
uint32_t now = millis();
fetchURL(&client, host, port, path);
uint32_t delta = millis() - now;
now = millis();
client.setInsecure();
client.setAxTLSCiphers();
fetchURL(&client, host, port, path);
uint32_t delta2 = millis() - now;
Serial.printf("Using more secure: %dms\nUsiing axTLS ciphers: %dms\n", delta, delta2);
}

void setup() {
Serial.begin(115200);
Serial.println();
Expand Down Expand Up @@ -220,6 +239,7 @@ void setup() {
fetchSelfSigned();
fetchKnownKey();
fetchCertAuthority();
fetchAxTLS();
}


Expand Down
27 changes: 23 additions & 4 deletions libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ void WiFiClientSecure::_clearAuthenticationSettings() {


WiFiClientSecure::WiFiClientSecure() : WiFiClient() {
_cipher_list = NULL;
_cipher_cnt = 0;
_clear();
_clearAuthenticationSettings();
_certStore = nullptr; // Don't want to remove cert store on a clear, should be long lived
Expand Down Expand Up @@ -685,6 +687,13 @@ extern "C" {
BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA
};

// For apps which want to use less secure but faster axTLS ciphers, only
static const uint16_t axtls_suites_P[] PROGMEM = {
BR_TLS_RSA_WITH_AES_256_CBC_SHA256,
BR_TLS_RSA_WITH_AES_128_CBC_SHA256,
BR_TLS_RSA_WITH_AES_256_CBC_SHA,
BR_TLS_RSA_WITH_AES_128_CBC_SHA };

// Install hashes into the SSL engine
static void br_ssl_client_install_hashes(br_ssl_engine_context *eng) {
br_ssl_engine_set_hash(eng, br_md5_ID, &br_md5_vtable);
Expand All @@ -705,9 +714,9 @@ extern "C" {
}

// Default initializion for our SSL clients
static void br_ssl_client_base_init(br_ssl_client_context *cc) {
uint16_t suites[sizeof(suites_P) / sizeof(uint16_t)];
memcpy_P(suites, suites_P, sizeof(suites_P));
static void br_ssl_client_base_init(br_ssl_client_context *cc, const uint16_t *cipher_list, int cipher_cnt) {
uint16_t suites[cipher_cnt];
memcpy_P(suites, cipher_list, cipher_cnt * sizeof(cipher_list[0]));
br_ssl_client_zero(cc);
br_ssl_engine_set_versions(&cc->eng, BR_TLS10, BR_TLS12);
br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0]));
Expand All @@ -726,6 +735,12 @@ extern "C" {

}

// Set the AXTLS ciphers as the only ones allowed
void WiFiClientSecure::setAxTLSCiphers()
{
setCiphers(axtls_suites_P, sizeof(axtls_suites_P)/sizeof(axtls_suites_P[0]));
}

// Installs the appropriate X509 cert validation method for a client connection
bool WiFiClientSecure::_installClientX509Validator() {
if (_use_insecure || _use_fingerprint || _use_self_signed) {
Expand Down Expand Up @@ -787,7 +802,11 @@ bool WiFiClientSecure::_connectSSL(const char* hostName) {
return false;
}

br_ssl_client_base_init(_sc.get());
// If no cipher list yet set, use defaults
if (_cipher_list == NULL) {
setCiphers(suites_P, sizeof(suites_P) / sizeof(uint16_t));
}
br_ssl_client_base_init(_sc.get(), _cipher_list, _cipher_cnt);
// Only failure possible in the installation is OOM
if (!_installClientX509Validator()) {
_freeSSL();
Expand Down
11 changes: 10 additions & 1 deletion libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,17 @@ class WiFiClientSecure : public WiFiClient {
_certStore = certStore;
}

// Select specific ciphers (i.e. optimize for speed over security)
// These may be in PROGMEM or RAM, either will run properly
void setCiphers(const uint16_t *cipherAry, int cipherCount) { _cipher_list = cipherAry; _cipher_cnt = cipherCount; }
void setAxTLSCiphers(); // Only use the limited set of axTLS ciphers

// Check for Maximum Fragment Length support for given len
static bool probeMaxFragmentLength(IPAddress ip, uint16_t port, uint16_t len);
static bool probeMaxFragmentLength(const char *hostname, uint16_t port, uint16_t len);
static bool probeMaxFragmentLength(const String host, uint16_t port, uint16_t len);

// AXTLS compatbile wrappers
// AXTLS compatible wrappers
bool verify(const char* fingerprint, const char* domain_name) { (void) fingerprint; (void) domain_name; return false; } // Can't handle this case, need app code changes
bool verifyCertChain(const char* domain_name) { (void)domain_name; return connected(); } // If we're connected, the cert passed validation during handshake

Expand Down Expand Up @@ -170,6 +175,10 @@ class WiFiClientSecure : public WiFiClient {
const BearSSLPublicKey *_knownkey;
unsigned _knownkey_usages;

// Custom cipher list pointer or NULL if default
const uint16_t *_cipher_list;
uint16_t _cipher_cnt;

unsigned char *_recvapp_buf;
size_t _recvapp_len;

Expand Down