Skip to content
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

Move BearSSLHelpers into BearSSL namespace #5315

Merged
merged 4 commits into from
Nov 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
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
20 changes: 9 additions & 11 deletions doc/esp8266wifi/bearssl-client-secure-class.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ There are many configuration options that require passing in a pointer to an obj
BearSSL::WiFiClientSecure client;
const char x509CA PROGMEM = ".......";
void setup() {
BearSSLX509List x509(x509CA);
BearSSL::X509List x509(x509CA);
client.setTrustAnchor(&x509);
}
void loop() {
Expand Down Expand Up @@ -73,7 +73,7 @@ TLS Sessions

TLS supports the notion of a session (completely independent and different from HTTP sessions) which allow clients to reconnect to a server without having to renegotiate encryption settings or validate X509 certificates. This can save significant time (3-4 seconds in the case of EC keys) and can help save power by allowing the ESP8266 to sleep for a long time, reconnect and transmit some samples using the SSL session, and then jump back to sleep quicker.

`BearSSLSession` is an opaque class. Use the `BearSSL::WiFiClientSecure.setSession(&BearSSLSession)` method to apply it before the first `BearSSL::WiFiClientSecure.connect()` and it will be updated with session parameters during the operation of the connection. After the connection has had `.close()` called on it, serialize the `BearSSLSession` object to stable storage (EEPROM, RTC RAM, etc.) and restore it before trying to reconnect. See the `BearSSL_Sessions` example for a detailed example.
`BearSSL::Session` is an opaque class. Use the `BearSSL::WiFiClientSecure.setSession(&BearSSLSession)` method to apply it before the first `BearSSL::WiFiClientSecure.connect()` and it will be updated with session parameters during the operation of the connection. After the connection has had `.close()` called on it, serialize the `BearSSL::Session` object to stable storage (EEPROM, RTC RAM, etc.) and restore it before trying to reconnect. See the `BearSSL_Sessions` example for a detailed example.

`Sessions <#sessions-resuming-connections-fast>`__ contains additional information on the sessions API.

Expand All @@ -82,15 +82,15 @@ X.509 Certificate(s)

X509 certificates are used to identify peers in TLS connections. Normally only the server identifies itself, but the client can also supply an X509 certificate if desired (this is often done in MQTT applications). The certificate contains many fields, but the most interesting in our applications are the name, the public key, and potentially a chain of signing that leads back to a trusted authority (like a global internet CA or a company-wide private certificate authority).

Any call that takes an X509 certificate can also take a list of X509 certificates, so there is no special `X509` class, simply `BearSSLX509List` (which may only contain a single certificate).
Any call that takes an X509 certificate can also take a list of X509 certificates, so there is no special `X509` class, simply `BearSSL::X509List` (which may only contain a single certificate).

Generating a certificate to be used to validate using the constructor

.. code:: cpp

BearSSLX509List(const char *pemX509);
BearSSL::X509List(const char *pemX509);
...or...
BearSSLX509List(const uint8_t *derCert, size_t derLen);
BearSSL::X509List(const uint8_t *derCert, size_t derLen);

If you need to add additional certificates (unlikely in normal operation), the `::append()` operation can be used.

Expand All @@ -100,7 +100,7 @@ Certificate Stores

The web browser you're using to read this document keeps a list of 100s of certification authorities (CAs) worldwide that it trusts to attest to the identity of websites.

In many cases your application will know the specific CA it needs to validate web or MQTT servers against (often just a single, self-signing CA private to your institution). Simply load your private CA in a `BearSSLX509List` and use that as your trust anchor.
In many cases your application will know the specific CA it needs to validate web or MQTT servers against (often just a single, self-signing CA private to your institution). Simply load your private CA in a `BearSSL::X509List` and use that as your trust anchor.

However, there are cases where you will not know beforehand which CA you will need (i.e. a user enters a website through a keypad), and you need to keep the list of CAs just like your web browser. In those cases, you need to generate a certificate bundle on the PC while compiling your application, upload the `certs.ar` bundle to SPIFFS or SD when uploading your application binary, and pass it to a `BearSSL::CertStore()` in order to validate TLS peers.

Expand Down Expand Up @@ -129,7 +129,7 @@ setInsecure()

Don't verify any X509 certificates. There is no guarantee that the server connected to is the one you think it is in this case, but this call will mimic the behavior of the deprecated axTLS code.

setKnownKey(const BearSSLPublicKey *pk)
setKnownKey(const BearSSL::PublicKey *pk)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Assume the server is using the specific public key. This does not verify the identity of the server or the X509 certificate it sends, it simply assumes that its public key is the one given. If the server updates its public key at a later point then connections will fail.
Expand All @@ -139,7 +139,7 @@ setFingerprint(const uint8_t fp[20]) / setFingerprint(const char *fpStr)

Verify the SHA1 fingerprint of the certificate returned matches this one. If the server certificate changes, it will fail. If an array of 20 bytes are sent in, it is assumed they are the binary SHA1 values. If a `char*` string is passed in, it is parsed as a series of human-readable hex values separated by spaces or colons (e.g. `setFingerprint("00:01:02:03:...:1f");`)

setTrustAnchors(BearSSLX509List *ta)
setTrustAnchors(BearSSL::X509List *ta)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Use the passed-in certificate(s) as a trust anchor, accepting remote certificates signed by any of these. If you have many trust anchors it may make sense to use a `BearSSL::CertStore` because it will only require RAM for a single trust anchor (while the `setTrustAnchors` call requires memory for all certificates in the list).
Expand Down Expand Up @@ -183,7 +183,7 @@ In certain applications where the TLS server does not support MFLN (not many do
Sessions (Resuming connections fast)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

setSession(BearSSLSession &sess)
setSession(BearSSL::Session &sess)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you are connecting to a server repeatedly in a fixed time period (usually 30 or 60 minutes, but normally configurable at the server), a TLS session can be used to cache crypto settings and speed up connections significantly.
Expand Down Expand Up @@ -212,5 +212,3 @@ setCiphersLessSecure()
^^^^^^^^^^^^^^^^^^^^^^

Helper function which essentially limits BearSSL to ciphers that were supported by the deprecated axTLS. These may be less secure than the ones BearSSL would natively choose, but they may be helpful and faster if your server depended on specific axTLS crypto options.


6 changes: 3 additions & 3 deletions doc/esp8266wifi/bearssl-server-secure-class.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ This example command will generate a RSA 2048-bit key and certificate:

Again, it is up to the application author to generate this certificate and key and keep the private key safe and **private.**

setRSACert(const BearSSLX509List *chain, const BearSSLPrivateKey *sk)
setRSACert(const BearSSL::X509List *chain, const BearSSL::PrivateKey *sk)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Sets a RSA certificate and key to be used by the server when connections are received. Needs to be called before `begin()`

setECCert(const BearSSLX509List *chain, unsigned cert_issuer_key_type, const BearSSLPrivateKey *sk)
setECCert(const BearSSL::X509List *chain, unsigned cert_issuer_key_type, const BearSSL::PrivateKey *sk)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Sets an elliptic curve certificate and key for the server. Needs to be called before `begin()`.
Expand All @@ -38,7 +38,7 @@ Requiring Client Certificates

TLS servers can request the client to identify itself by transmitting a certificate during handshake. If the client cannot transmit the certificate, the connection will be dropped by the server.

setClientTrustAnchor(const BearSSLX509List *client_CA_ta)
setClientTrustAnchor(const BearSSL::X509List *client_CA_ta)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Sets the trust anchor (normally a self-signing CA) that all received certificates will be verified against. Needs to be called before `begin()`.
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void setup()

MDNS.begin(host);

httpServer.setRSACert(new BearSSLX509List(serverCert), new BearSSLPrivateKey(serverKey));
httpServer.setRSACert(new BearSSL::X509List(serverCert), new BearSSL::PrivateKey(serverKey));
httpUpdater.setup(&httpServer, update_path, update_username, update_password);
httpServer.begin();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ void setup(void){
Serial.println("MDNS responder started");
}

server.setRSACert(new BearSSLX509List(serverCert), new BearSSLPrivateKey(serverKey));
server.setRSACert(new BearSSL::X509List(serverCert), new BearSSL::PrivateKey(serverKey));

server.on("/", handleRoot);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ ESP8266WebServerSecure::ESP8266WebServerSecure(int port)
{
}

void ESP8266WebServerSecure::setRSACert(const BearSSLX509List *chain, const BearSSLPrivateKey *sk)
void ESP8266WebServerSecure::setRSACert(const X509List *chain, const PrivateKey *sk)
{
_serverSecure.setRSACert(chain, sk);
}

void ESP8266WebServerSecure::setECCert(const BearSSLX509List *chain, unsigned cert_issuer_key_type, const BearSSLPrivateKey *sk)
void ESP8266WebServerSecure::setECCert(const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk)
{
_serverSecure.setECCert(chain, cert_issuer_key_type, sk);
}
Expand Down Expand Up @@ -83,7 +83,7 @@ void ESP8266WebServerSecure::begin() {

void ESP8266WebServerSecure::handleClient() {
if (_currentStatus == HC_NONE) {
BearSSL::WiFiClientSecure client = _serverSecure.available();
WiFiClientSecure client = _serverSecure.available();
if (!client) {
return;
}
Expand Down Expand Up @@ -136,7 +136,7 @@ void ESP8266WebServerSecure::handleClient() {
}

if (!keepCurrentClient) {
_currentClientSecure = BearSSL::WiFiClientSecure();
_currentClientSecure = WiFiClientSecure();
_currentStatus = HC_NONE;
_currentUpload.reset();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ class ESP8266WebServerSecure : public ESP8266WebServer
virtual ~ESP8266WebServerSecure();

void setBufferSizes(int recv, int xmit);
void setRSACert(const BearSSLX509List *chain, const BearSSLPrivateKey *sk);
void setECCert(const BearSSLX509List *chain, unsigned cert_issuer_key_type, const BearSSLPrivateKey *sk);
void setRSACert(const X509List *chain, const PrivateKey *sk);
void setECCert(const X509List *chain, unsigned cert_issuer_key_type, const PrivateKey *sk);

WiFiClient client() override { return _currentClientSecure; }

Expand All @@ -61,8 +61,8 @@ class ESP8266WebServerSecure : public ESP8266WebServer
size_t _currentClientWrite_P (PGM_P bytes, size_t len) override { return _currentClientSecure.write_P(bytes, len); }

protected:
BearSSL::WiFiServerSecure _serverSecure;
BearSSL::WiFiClientSecure _currentClientSecure;
WiFiServerSecure _serverSecure;
WiFiClientSecure _currentClientSecure;
};

};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ void setup() {
Serial.println(WiFi.localIP());

// Attach the server private cert/key combo
BearSSLX509List *serverCertList = new BearSSLX509List(server_cert);
BearSSLPrivateKey *serverPrivKey = new BearSSLPrivateKey(server_private_key);
BearSSL::X509List *serverCertList = new BearSSL::X509List(server_cert);
BearSSL::PrivateKey *serverPrivKey = new BearSSL::PrivateKey(server_private_key);
server.setRSACert(serverCertList, serverPrivKey);

// Actually start accepting connections
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,12 @@ void setup() {
setClock(); // Required for X.509 validation

// Attach the server private cert/key combo
BearSSLX509List *serverCertList = new BearSSLX509List(server_cert);
BearSSLPrivateKey *serverPrivKey = new BearSSLPrivateKey(server_private_key);
BearSSL::X509List *serverCertList = new BearSSL::X509List(server_cert);
BearSSL::PrivateKey *serverPrivKey = new BearSSL::PrivateKey(server_private_key);
server.setRSACert(serverCertList, serverPrivKey);

// Require a certificate validated by the trusted CA
BearSSLX509List *serverTrustedCA = new BearSSLX509List(ca_cert);
BearSSL::X509List *serverTrustedCA = new BearSSL::X509List(ca_cert);
server.setClientTrustAnchor(serverTrustedCA);

// Actually start accepting connections
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
)EOF";
uint32_t start, finish;
BearSSL::WiFiClientSecure client;
BearSSLX509List cert(digicert);
BearSSL::X509List cert(digicert);

Serial.printf("Connecting without sessions...");
start = millis();
Expand All @@ -128,7 +128,7 @@ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
finish = millis();
Serial.printf("Total time: %dms\n", finish - start);

BearSSLSession session;
BearSSL::Session session;
client.setSession(&session);
Serial.printf("Connecting with an unitialized session...");
start = millis();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ wQIDAQAB
-----END PUBLIC KEY-----
)KEY";
BearSSL::WiFiClientSecure client;
BearSSLPublicKey key(pubkey);
BearSSL::PublicKey key(pubkey);
client.setKnownKey(&key);
fetchURL(&client, host, port, path);
}
Expand Down Expand Up @@ -186,7 +186,7 @@ BearSSL does verify the notValidBefore/After fields.
)EOF");

BearSSL::WiFiClientSecure client;
BearSSLX509List cert(digicert);
BearSSL::X509List cert(digicert);
client.setTrustAnchors(&cert);
Serial.printf("Try validating without setting the time (should fail)\n");
fetchURL(&client, host, port, path);
Expand Down
9 changes: 6 additions & 3 deletions libraries/ESP8266WiFi/keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ WiFiServerSecure KEYWORD1
WiFiUDP KEYWORD1
WiFiClientSecure KEYWORD1
ESP8266WiFiMulti KEYWORD1
BearSSLX509List KEYWORD1
BearSSLPrivateKey KEYWORD1
BearSSLPublicKey KEYWORD1
BearSSL KEYWORD1
X509List KEYWORD1
PrivateKey KEYWORD1
PublicKey KEYWORD1
CertStoreSPIFFSBearSSL KEYWORD1
CertStoreSDBearSSL KEYWORD1
Session KEYWORD1


#######################################
# Methods and Functions (KEYWORD2)
Expand Down
Loading