diff --git a/docs/_r_e_a_d_m_e_8md.html b/docs/_r_e_a_d_m_e_8md.html deleted file mode 100644 index 700c3e4..0000000 --- a/docs/_r_e_a_d_m_e_8md.html +++ /dev/null @@ -1,105 +0,0 @@ - - -
- - - - -
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
Go to the source code of this file.
--Classes | |
class | SSLClient |
The main SSLClient class. Check out README.md for more info. More... | |
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
#include "SSLClientParameters.h"
-Classes | |
struct | ssl_pem_decode_state |
- SSLClient
- v1.5.0
-
- |
-
#include "bearssl.h"
#include <vector>
Go to the source code of this file.
--Classes | |
class | SSLClientParameters |
This class stores data required for SSLClient to use mutual authentication. More... | |
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
#include "SSLObj.h"
-Classes | |
struct | ssl_pem_decode_state |
- SSLClient
- v1.5.0
-
- |
-
#include <cstring>
#include "bearssl_pem.h"
#include <vector>
Go to the source code of this file.
--Namespaces | |
SSLObj | |
This namespace works with raw DER byte arrays for use later with TLS mutual auth. | |
-Functions | |
const std::vector< unsigned char > | SSLObj::make_vector_pem (const char *data, const size_t len) |
Convert a PEM buffer into a vector of raw DER bytes. More... | |
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
#include "bearssl.h"
#include "Arduino.h"
Go to the source code of this file.
--Classes | |
class | SSLSession |
This class stores values which allow SSLClient to save and resume SSL sessions. More... | |
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
Cssl_pem_decode_state | |
CSSLClient | The main SSLClient class. Check out README.md for more info |
CSSLClientParameters | This class stores data required for SSLClient to use mutual authentication |
CSSLSession | This class stores values which allow SSLClient to save and resume SSL sessions |
- SSLClient
- v1.5.0
-
- |
-
This is the complete list of members for SSLClient, including all inherited members.
-available() override | SSLClient | |
connect(IPAddress ip, uint16_t port) override | SSLClient | |
connect(const char *host, uint16_t port) override | SSLClient | |
connected() override | SSLClient | |
DebugLevel enum name | SSLClient | |
Error enum name | SSLClient | |
flush() override | SSLClient | |
getClient() | SSLClient | inline |
getSession(const char *host) | SSLClient | |
getSessionCount() const | SSLClient | inline |
getTimeout() const | SSLClient | inline |
operator bool() | SSLClient | inline |
peek() override | SSLClient | |
read(uint8_t *buf, size_t size) override | SSLClient | |
read() override | SSLClient | inline |
removeSession(const char *host) | SSLClient | |
setMutualAuthParams(const SSLClientParameters ¶ms) | SSLClient | |
setTimeout(unsigned int t) | SSLClient | inline |
SSL_BR_CONNECT_FAIL enum value | SSLClient | |
SSL_BR_WRITE_ERROR enum value | SSLClient | |
SSL_CLIENT_CONNECT_FAIL enum value | SSLClient | |
SSL_CLIENT_WRTIE_ERROR enum value | SSLClient | |
SSL_ERROR enum value | SSLClient | |
SSL_INFO enum value | SSLClient | |
SSL_INTERNAL_ERROR enum value | SSLClient | |
SSL_NONE enum value | SSLClient | |
SSL_OK enum value | SSLClient | |
SSL_OUT_OF_MEMORY enum value | SSLClient | |
SSL_WARN enum value | SSLClient | |
SSLClient(Client &client, const br_x509_trust_anchor *trust_anchors, const size_t trust_anchors_num, const int analog_pin, const size_t max_sessions=1, const DebugLevel debug=SSL_WARN) | SSLClient | explicit |
stop() override | SSLClient | |
write(const uint8_t *buf, size_t size) override | SSLClient | |
write(uint8_t b) override | SSLClient | inline |
- SSLClient
- v1.5.0
-
- |
-
The main SSLClient class. Check out README.md for more info. - More...
- -#include <SSLClient.h>
-Public Types | |
enum | Error { - SSL_OK = 0, -SSL_CLIENT_CONNECT_FAIL = 2, -SSL_BR_CONNECT_FAIL = 3, -SSL_CLIENT_WRTIE_ERROR = 4, - - SSL_BR_WRITE_ERROR = 5, -SSL_INTERNAL_ERROR = 6, -SSL_OUT_OF_MEMORY = 7 - - } |
Static constants defining the possible errors encountered. More... | |
enum | DebugLevel { SSL_NONE = 0, -SSL_ERROR = 1, -SSL_WARN = 2, -SSL_INFO = 3 - } |
Level of verbosity used in logging for SSLClient. More... | |
-Public Member Functions | |
SSLClient (Client &client, const br_x509_trust_anchor *trust_anchors, const size_t trust_anchors_num, const int analog_pin, const size_t max_sessions=1, const DebugLevel debug=SSL_WARN) | |
Initialize SSLClient with all of the prerequisites needed. More... | |
int | connect (IPAddress ip, uint16_t port) override |
Connect over SSL to a host specified by an IP address. More... | |
int | connect (const char *host, uint16_t port) override |
Connect over SSL to a host specified by a hostname. More... | |
size_t | write (const uint8_t *buf, size_t size) override |
Write some bytes to the SSL connection. More... | |
size_t | write (uint8_t b) override |
int | available () override |
Returns the number of bytes available to read from the data that has been received and decrypted. More... | |
int | read (uint8_t *buf, size_t size) override |
Read size bytes from the SSL client buffer, copying them into *buf, and return the number of bytes read. More... | |
int | read () override |
Read a single byte, or -1 if none is available. More... | |
int | peek () override |
View the first byte of the buffer, without removing it from the SSLClient Buffer. More... | |
void | flush () override |
Force writing the buffered bytes from SSLClient::write to the network. More... | |
void | stop () override |
Close the connection. More... | |
uint8_t | connected () override |
Check if the device is connected. More... | |
void | setMutualAuthParams (const SSLClientParameters ¶ms) |
Add a client certificate and enable support for mutual auth. More... | |
SSLSession * | getSession (const char *host) |
Gets a session reference corresponding to a host and IP, or a reference to a empty session if none exist. More... | |
void | removeSession (const char *host) |
Clear the session corresponding to a host and IP. More... | |
size_t | getSessionCount () const |
Get the maximum number of SSL sessions that can be stored at once. More... | |
operator bool () | |
Equivalent to SSLClient::connected() > 0. More... | |
Client & | getClient () |
Returns a reference to the client object stored in this class. Take care not to break it. More... | |
void | setTimeout (unsigned int t) |
Set the timeout when waiting for an SSL response. More... | |
unsigned int | getTimeout () const |
Get the timeout when waiting for an SSL response. More... | |
enum SSLClient::DebugLevel | -
Level of verbosity used in logging for SSLClient.
-Use these values when initializing SSLClient to set how many logs you would like to see in the Serial monitor.
-enum SSLClient::Error | -
Static constants defining the possible errors encountered.
-If SSLClient encounters an error, it will generally output logs into the serial monitor. If you need a way of programmatically checking the errors, you can do so with SSLClient::getWriteError(), which will return one of these values.
-Enumerator | |
---|---|
SSL_OK | |
SSL_CLIENT_CONNECT_FAIL | The underlying client failed to connect, probably not an issue with SSL - |
SSL_BR_CONNECT_FAIL | BearSSL failed to complete the SSL handshake, check logs for bear ssl error output - |
SSL_CLIENT_WRTIE_ERROR | The underlying client failed to write a payload, probably not an issue with SSL - |
SSL_BR_WRITE_ERROR | An internal error occurred with BearSSL, check logs for diagnosis. - |
SSL_INTERNAL_ERROR | An internal error occurred with SSLClient, and you probably need to submit an issue on Github. - |
SSL_OUT_OF_MEMORY | SSLClient detected that there was not enough memory (>8000 bytes) to continue. - |
-
|
- -explicit | -
Initialize SSLClient with all of the prerequisites needed.
-client | The base network device to create an SSL socket on. This object will be copied and the copy will be stored in SSLClient. |
trust_anchors | Trust anchors used in the verification of the SSL server certificate. Check out TrustAnchors.md for more info. |
trust_anchors_num | The number of objects in the trust_anchors array. |
analog_pin | An analog pin to pull random bytes from, used in seeding the RNG. |
max_sessions | The maximum number of SSL sessions to store connection information from. |
debug | The level of debug logging (use the ::DebugLevel enum). |
-
|
- -override | -
Returns the number of bytes available to read from the data that has been received and decrypted.
-This function updates the state of the SSL engine (including writing any data, see SSLClient::write) and as a result should be called periodically when expecting data. Additionally, since if there are no bytes and if SSLClient::connected is false this function returns zero (this same behavior is found in EthernetClient), it is prudent to ensure in your own code that the preconditions are met before checking this function to prevent an ambiguous result.
-The implementation for this function can be found in SSLClientImpl::available
-
-
|
- -override | -
Connect over SSL to a host specified by an IP address.
-SSLClient::connect(host, port) should be preferred over this function, as verifying the domain name is a step in ensuring the certificate is legitimate, which is important to the security of the device. Additionally, SSL sessions cannot be resumed when using this function, which can drastically increase initial connect time.
-This function initializes the socket by calling m_client::connect(IPAddress, uint16_t) with the parameters supplied, then once the socket is open, uses BearSSL to to complete a SSL handshake. Due to the design of the SSL standard, this function will probably take an extended period (1-4sec) to negotiate the handshake and finish the connection. This function runs until the SSL handshake succeeds or fails.
-SSL requires the client to generate some random bits (to be later combined with some random bits from the server), so SSLClient uses the least significant bits from the analog pin supplied in the constructor. The random bits are generated from 16 consecutive analogReads, and given to BearSSL before the handshake starts.
-The implementation for this function can be found in SSLClientImpl::connect_impl(IPAddress, uint16_t).
-ip | The IP address to connect to |
port | the port to connect to |
-
|
- -override | -
Connect over SSL to a host specified by a hostname.
-This function initializes the socket by calling m_client::connect(const char*, uint16_t) with the parameters supplied, then once the socket is open, uses BearSSL to complete a SSL handshake. This function runs until the SSL handshake succeeds or fails.
-SSL requires the client to generate some random bits (to be later combined with some random bits from the server), so SSLClient uses the least significant bits from the analog pin supplied in the constructor. The random bits are generated from 16 consecutive analogReads, and given to BearSSL before the handshake starts.
-This function will usually take around 4-10 seconds. If possible, this function also attempts to resume the SSL session if one is present matching the hostname string, which will reduce connection time to 100-500ms. To read more about this functionality, check out Session Caching in the README.
-The implementation for this function can be found in SSLClientImpl::connect_impl(const char*, uint16_t)
-host | The hostname as a null-terminated c-string ("www.google.com") |
port | The port to connect to on the host (443 for HTTPS) |
-
|
- -override | -
Check if the device is connected.
-Use this function to determine if SSLClient is still connected and a SSL connection is active. It should be noted that this function should be called before SSLClient::available– both functions send and receive data with the SSLClient::m_client device, however SSLClient::available has some delays built in to protect SSLClient::m_client from being polled too frequently, and SSLClient::connected contains logic to ensure that if the socket is dropped SSLClient will react accordingly.
-The implementation for this function can be found in SSLClientImpl::connected_impl.
-
-
|
- -override | -
Force writing the buffered bytes from SSLClient::write to the network.
-This function is blocking until all bytes from the buffer are written. For an explanation of how writing with SSLClient works, please see SSLClient::write. The implementation for this function can be found in SSLClientImpl::flush.
- -
-
|
- -inline | -
Returns a reference to the client object stored in this class. Take care not to break it.
- -SSLSession * SSLClient::getSession | -( | -const char * | -host | ) | -- |
Gets a session reference corresponding to a host and IP, or a reference to a empty session if none exist.
-If no session corresponding to the host and IP exist, then this function will cycle through sessions in a rotating order. This allows the session cache to continually store sessions, however it will also result in old sessions being cleared and returned. In general, it is a good idea to use a SessionCache size equal to the number of domains you plan on connecting to.
-The implementation for this function can be found at SSLClientImpl::get_session_impl.
-host | A hostname c string, or NULL if one is not available |
addr | An IP address |
-
|
- -inline | -
Get the maximum number of SSL sessions that can be stored at once.
-
-
|
- -inline | -
Get the timeout when waiting for an SSL response.
-
-
|
- -inline | -
Equivalent to SSLClient::connected() > 0.
-
-
|
- -override | -
View the first byte of the buffer, without removing it from the SSLClient Buffer.
-The implementation for this function can be found in SSLClientImpl::peek
-
|
- -override | -
Read size bytes from the SSL client buffer, copying them into *buf, and return the number of bytes read.
-This function checks if bytes are ready to be read by calling SSLClient::available, and if so copies size number of bytes from the IO buffer into the buf pointer. Data read using this function will not include any SSL or socket commands, as the Client and BearSSL will capture those and process them separately.
-If you find that you are having a lot of timeout errors, SSLClient may be experiencing a buffer overflow. Checkout README.md for more information.
-The implementation for this function can be found in SSLClientImpl::read_impl(uint8_t*, size_t)
-buf | The pointer to the buffer to put SSL application data into |
size | The size (in bytes) to copy to the buffer |
-
|
- -inlineoverride | -
Read a single byte, or -1 if none is available.
- - -void SSLClient::removeSession | -( | -const char * | -host | ) | -- |
Clear the session corresponding to a host and IP.
-The implementation for this function can be found at SSLClientImpl::remove_session_impl.
-host | A hostname c string, or nullptr if one is not available |
addr | An IP address |
void SSLClient::setMutualAuthParams | -( | -const SSLClientParameters & | -params | ) | -- |
-
|
- -inline | -
Set the timeout when waiting for an SSL response.
-t | The timeout value, in milliseconds (defaults to 30 seconds if not set). Do not set to zero. |
-
|
- -override | -
Close the connection.
-If the SSL session is still active, all incoming data is discarded and BearSSL will attempt to close the session gracefully (will write to the network), and then call m_client::stop. If the session is not active or an error was encountered previously, this function will simply call m_client::stop. The implementation for this function can be found in SSLClientImpl::peek.
- -
-
|
- -override | -
Write some bytes to the SSL connection.
-Assuming all preconditions are met, this function writes data to the BearSSL IO buffer, BUT does not initially send the data. Instead, you must call SSLClient::available or SSLClient::flush, which will detect that the buffer is ready for writing, and will write the data to the network. Alternatively, if this function is requested to write a larger amount of data than SSLClientImpl::m_iobuf can handle, data will be written to the network in pages the size of SSLClientImpl::m_iobuf until all the data in buf is sent–attempting to keep all writes to the network grouped together. For information on why this is the case check out README.md .
-The implementation for this function can be found in SSLClientImpl::write_impl(const uint8_t*, size_t)
-buf | the pointer to a buffer of bytes to copy |
size | the number of bytes to copy from the buffer |
-
|
- -inlineoverride | -
- SSLClient
- v1.5.0
-
- |
-
This is the complete list of members for SSLClientParameters, including all inherited members.
-fromDER(const char *cert_der, const size_t cert_len, const char *key_der, const size_t key_len) | SSLClientParameters | static |
fromPEM(const char *cert_pem, const size_t cert_len, const char *key_pem, const size_t key_len) | SSLClientParameters | static |
getCertChain() const | SSLClientParameters | inline |
getCertType() const | SSLClientParameters | inline |
getECKey() const | SSLClientParameters | inline |
getRSAKey() const | SSLClientParameters | inline |
SSLClientParameters(const char *cert, const size_t cert_len, const char *key, const size_t key_len, bool is_der) | SSLClientParameters | protected |
- SSLClient
- v1.5.0
-
- |
-
This class stores data required for SSLClient to use mutual authentication. - More...
- -#include <SSLClientParameters.h>
-Public Member Functions | |
const br_x509_certificate * | getCertChain () const |
int | getCertType () const |
const br_ec_private_key * | getECKey () const |
const br_rsa_private_key * | getRSAKey () const |
-Static Public Member Functions | |
static SSLClientParameters | fromPEM (const char *cert_pem, const size_t cert_len, const char *key_pem, const size_t key_len) |
Create mutual authentication parameters from a PEM certificate and private key. More... | |
static SSLClientParameters | fromDER (const char *cert_der, const size_t cert_len, const char *key_der, const size_t key_len) |
Create mutual authentication parameters from a DER certificate and private key. More... | |
-Protected Member Functions | |
SSLClientParameters (const char *cert, const size_t cert_len, const char *key, const size_t key_len, bool is_der) | |
This class stores data required for SSLClient to use mutual authentication.
- -This file contains a simple utility class to store parameters about an SSL Session for reuse later.TLS mutual authentication is a process in which both the server and client perform cryptographic operations to verify the authenticity of eachother, for more information check out this article: https://medium.com/sitewards/the-magic-of-tls-x509-and-mutual-authentication-explained-b2162dec4401 . If this struct is provided to SSLClient::SSLClient via SSLClient::setMutualAuthParams, SSLClient will automatically send a client certificate if one is requested by the server. This will happen for all SSLClient connections, and may cause issues for websites that do not need mutual authentication—as a result, please only turn on mutual authentication if you are sure it is neccesary.
-SSLClientParameters supports both ECC and RSA client certificates. I recommend using ECC certificates if possible, as SSLClientParameters will make a copy of both the certificate and the private key in memory, and ECC keys tend to be smaller than RSA ones.
-
-
|
- -protected | -
-
|
- -static | -
Create mutual authentication parameters from a DER certificate and private key.
-Use this function to create a mutual tls context from a DER client certificate and DER private key. This function will copy the certificate and private key, extract the needed information from the private key, and store both that information and the copied cert into a SSLClientParameters object. Given the key parsed correctly, you can then use SSLClient::setMutualAuthParams at the begining of your sketch to enable mTLS with SSLClient. This function supports both ECC and RSA certificate/private keys (use EC keys wherever possible, as they are signifigantly smaller and faster), however SSLClient only supports the p256, p384, and p512 curves for ECC.
-Because SSLClientParameters creates a copy of both the certificate and key, you do not need to ensure that the data pointed to by cert_der or key_der is accessible after this function (i.e. you can free them afterwards).
-Please note that if the private key is incorrect, this function will not report an error, and instead SSLClient will fall back to regular TLS when making a connection.
-cert_der | A DER encoded certificate, can be ECC or RSA. |
cert_len | The number of bytes in cert_der. |
key_der | A DER encoded private key, can be ECC or RSA. |
key_len | The number of bytes in key_ders |
-
|
- -static | -
Create mutual authentication parameters from a PEM certificate and private key.
-Use this function to create a mutual tls context from a PEM client certificate and PEM private key. This function will convert the PEM certificates into DER format (creating a copy in the process), extract the needed information from the private key, and store that information into a SSLClientParameters object. Given the certifiate and key parsed correctly, you can then use SSLClient::setMutualAuthParams at the begining of your sketch to enable mTLS with SSLClient. This function supports both ECC and RSA certificate/private keys (use EC keys wherever possible, as they are signifigantly smaller and faster), however SSLClient only supports the p256, p384, and p512 curves for ECC.
-Because SSLClientParameters creates a copy of both the certificate and key, you do not need to ensure that the data pointed to by cert_pem or key_pem is accessible after this function (i.e. you can free them afterwards).
-Please note that if the certificate or private key are incorrect, this function will not report an error, and instead SSLClient will fall back to regular TLS when making a connection.
-cert_pem | A PEM formatted certificate, including the "BEGIN" and "END" header/footers. Can be ECC or RSA. cert_pem supports both LF and CRLF for endlines, but all other constraints on a valid PEM file apply. |
cert_len | The number of bytes in cert_pem. |
key_pem | A PEM formatted private key, including the "BEGIN" and "END" header/footers. Can be ECC or RSA. key_pem supports both LF and CRLF for endlines, but all other constraints \ on a valid PEM file apply. |
key_len | The number of bytes in key_pem |
-
|
- -inline | -
mTLS information used by SSLClient during authentication
- -
-
|
- -inline | -
mTLS information used by SSLClient during authentication
- -
-
|
- -inline | -
mTLS information used by SSLClient during authentication
- -
-
|
- -inline | -
mTLS information used by SSLClient during authentication
- -
- SSLClient
- v1.5.0
-
- |
-
This is the complete list of members for SSLSession, including all inherited members.
-get_hostname() const | SSLSession | inline |
SSLSession(const char *hostname) | SSLSession | inline |
to_br_session() | SSLSession | inline |
- SSLClient
- v1.5.0
-
- |
-
This class stores values which allow SSLClient to save and resume SSL sessions. - More...
- -#include <SSLSession.h>
-Public Member Functions | |
SSLSession (const char *hostname) | |
SSLSession constructor. More... | |
const String & | get_hostname () const |
Get the hostname string associated with this session. More... | |
br_ssl_session_parameters * | to_br_session () |
Returns a pointer to the ::br_ssl_session_parameters component of this class. More... | |
This class stores values which allow SSLClient to save and resume SSL sessions.
- -This file contains a simple utility class to store parameters about an SSL Session for reuse later.This class was created to extend the values stored in br_ssl_session_parameters, which allow BearSSL to resume an SSL session. When testing BearSSL's session resumption feature, it was observed that BearSSL can only resume a session that was was started with the same server. This becomes an issue when using repeated requests to a domain name which can resolve to multiple IP addresses ("api.github.com"), as the device will switch between two or three servers. Since BearSSL only stores one session at a time, this results in session resumption being few and far between.
-To remedy this problem, an SSLSession stores the IPAddress and hostname, along with the parameters in br_ssl_session_parameters struct. Using this data, SSLClient is able to remember which IPAddress is associated with which session, allowing it to reconnect to the last IPAddress, as opposed to any associated with the domain.
-
-
|
- -inline | -
SSLSession constructor.
-Sets all parameters to zero, and invalidates the session
- -
-
|
- -inline | -
Get the hostname string associated with this session.
-
-
|
- -inline | -
Returns a pointer to the ::br_ssl_session_parameters component of this class.
- -
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
-Directories | |
directory | SSLClient |
- SSLClient
- v1.5.0
-
- |
-
-Directories | |
directory | libraries |
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
-Files | |
file | SSLClient.cpp |
file | SSLClient.h [code] |
file | SSLClientParameters.cpp |
file | SSLClientParameters.h [code] |
file | SSLSession.h [code] |
file | time_macros.h [code] |
- SSLClient
- v1.5.0
-
- |
-
-Directories | |
directory | Arduino |
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
- SSLClient
- v1.5.0
-
- |
-
▼Cbr_ssl_session_parameters | |
CSSLSession | This class stores values which allow SSLClient to save and resume SSL sessions |
▼CClient | |
CSSLClient | The main SSLClient class. Check out README.md for more info |
Cssl_pem_decode_state | |
CSSLClientParameters | This class stores data required for SSLClient to use mutual authentication |
- SSLClient
- v1.5.0
-
- |
-
SSLClient requires at least 110kb flash and 7kb RAM, and will not compile otherwise. This means that most Arduino boards are not supported. Check your board's specifications before attempting to use this library.
-You can also view this README in doxygen.
-SSLClient is a simple library to add TLS 1.2 functionality to any network library implementing the Arduino Client interface, including the Arduino EthernetClient and WiFiClient classes (though it is better to prefer WiFClient.connectSSL if implemented). In other words, SSLClient implements encrypted communication through SSL on devices that do not otherwise support it.
-SSLClient has been tested on the SAMD21, ESP32, TIVA C, and STM32 (in progress). SSClient does not currently support the ESP8266 (see this issue).
-Using SSLClient should be similar to using any other Arduino-based Client class, since this library was developed around compatibility with EthernetClient. There are a few extra things, however, that you will need to get started:
-Once all those are ready, you can create a simple SSLClient object like this:
Where:
SSLClient(BaseClientType() ...)
wouldn't work).TAs
.TAs_NUM
.AnalogPin - The analog pin to pull random data from (step 4).
-For example, if I am using EthernetClient, a generated array of 2 trust anchors, and the analog pin A7, I would declare an SSLClient instance using:
Once that is setup, simply use SSLClient as you would the base client class:
Note: client.connect("www.arduino.cc", 443)
can take 5-15 seconds to finish. This an unavoidable consequence of the SSL protocol, and is detailed in Implementation Notes.
For more information on SSLClient, check out the examples, API documentation, or the rest of this README.
-SSLClient was created to integrate SSL seamlessly with the Arduino infrastructure, and so it does just that: implementing the brilliant BearSSL as a proxy in front of any Arduino socket library. BearSSL is designed with low flash footprint in mind, and as a result does little verification of improper programming, relying on the developer to ensure the code is correct. Since SSLClient is built specifically for the Arduino ecosystem, most of SSLClient's code adds those programming checks back in, making debugging a fast and simple process.
-SSLClient also allows for changing the debugging level by adding an additional parameter to the constructor:
Logging is always outputted through the Arduino Serial interface, so you'll need to setup Serial before you can view the SSL logs. Log levels are enumerated in ::DebugLevel. The log level is set to SSL_WARN
by default.
When SSLClient encounters an error, it will attempt to terminate the SSL session gracefully if possible, and then close the socket. Simple error information can be found from SSLClient::getWriteError(), which will return a value from the ::Error enum. For more detailed diagnostics, you can look at the serial logs, which will be displayed if the log level is at SSL_ERROR
or lower.
As you may have noticed in the documentation for SSLClient::write, calling this function does not actually write to the network. Instead, you must call SSLClient::available or SSLClient::flush, which will detect that the buffer is ready and write to the network (see SSLClient::write for details).
-This was implemented as a buffered function because examples in Arduino libraries will often write to the network like so:
Notice that every single write() call immediately writes to the network, which is fine with most network clients. With SSL, however, if we are encrypting and writing to the network every write() call, this will result in a lot of small encryption tasks. Encryption takes a lot of time and code, so to reduce the overhead of an SSL connection, SSLClient::write implicitly buffers until the developer states that they are waiting for data to be received with SSLClient::available. A simple example can be found below:
-If you would like to trigger a network write manually without using the SSLClient::available, you can also call SSLClient::flush, which will write all data and return when finished.
-As detailed in the resources section, SSL handshakes take an extended period (1-4sec) to negotiate. To remedy this problem, BearSSL is able to keep a SSL session cache of the clients it has connected to. If BearSSL successfully resumes an SSL session, it can reduce connection time to 100-500ms.
-In order to use SSL session resumption:
SSLClient automatically stores an IP address and hostname in each session, ensuring that if you call connect("www.google.com")
SSLClient will use the SSL session with that hostname. However, because some websites have multiple servers on a single IP address (github.com being an example), you may find that even if you are connecting to the same host the connection does not resume. This is a flaw in the SSL session protocol — though it has been resolved in TLS 1.3, the lack of widespread adoption of the new protocol prevents it from being used here. SSL sessions can also expire based on server criteria, which will result in a standard 4-10 second connection.
You can test whether or not a website can resume SSL Sessions using the Session Example included with this library. Because of all the confounding factors of SSL Sessions, it is generally prudent while programming to assume the session will always fail to resume.
-SSL sessions take a lot of memory to store, so by default SSLClient will only store one at a time. You can change this behavior by adding the following to your SSLClient declaration:
Where SomeNumber
is the number of sessions you would like to store. For example this declaration can store 3 sessions:
Sessions are managed internally using the SSLSession::getSession function. This function will cycle through sessions in a rotating order, allowing the session cache to continually overwrite old sessions. In general, it is a good idea to use a SessionCache size equal to the number of domains you plan on connecting to.
-If you need to clear a session, you can do so using the SSLSession::removeSession function.
-Some ideas that didn't quite fit in the API documentation.
-If you are using the Arduino Ethernet library, you will need to modify the library to support the large buffer sizes required by SSL (detailed in resources). You can either modify the library yourself, or use this fork of the Ethernet library with the modification. To use the fork, simply install the library using the "add a .zip library" button in Arduino, and replace #include "Ethernet.h"
with #include "EthernetLarge.h"
in your sketch. Alternatively if for some reason this solution does not work, you can apply the modification using the instructions below.
First find the location of the library in the directory where Arduino is installed (C:\Program Files (x86)\Arduino
on Windows). Inside of this directory, navigate to libraries\Ethernet\src
(C:\Program Files (x86)\Arduino\libraries\Ethernet\src
on Windows). Modify Ethernet.h
to replace these lines:
With this:
You may need to use sudo
or administrator permissions to make this modification. We change MAX_SOCK_NUM
and ETHERNET_LARGE_BUFFERS
so the Ethernet hardware can allocate a larger space for SSLClient, however a downside of this modification is we are now only able to have two sockets concurrently. As most microprocessors barely have enough memory for one SSL connection, this limitation will rarely be encountered in practice.
The SSL protocol requires that SSLClient generate some random bits before connecting with a server. BearSSL provides a random number generator but requires a some entropy for a seed. Normally this seed is generated by taking the microsecond time using the internal clock, however since most microcontrollers are not build with this feature another source must be found. As a simple solution, SSLClient uses a floating analog pin as an external source of random data, passed through to the constructor in the analog_pin
argument. Before every connection, SSLClient will take the bottom byte from 16 analog reads on analog_pin
, and combine these bytes into a 16 byte random number, which is used as a seed for BearSSL. To ensure the most random data, it is recommended that this analog pin be either floating or connected to a location not modifiable by the microcontroller (i.e. a battery voltage readout).
SSLClient uses BearSSL's minimal x509 verification engine to verify the certificate of an SSL connection. This engine requires the developer create a trust anchor array using values stored in trusted root certificates. Check out this document for more details on this component of SSLClient.
-BearSSL also features a known certificate validation engine, which only allows for a single domain in exchange for a significantly reduced resource usage (flash and CPU time). This functionality is planned to be implemented in the future.
-The SSL protocol recommends a device support many different encryption algorithms, as well as protocols for SSL itself. The complexity of both of those components results in many medium sized components forming an extremely large whole. Additionally, most embedded processors lack the sophisticated math hardware commonly found in a modern CPU, and as a result require more instructions to create the encryption algorithms SSL requires. This not only increases size but makes the algorithms slow and memory intensive.
-To illustrate this, I will run some tests on various domains below. I haven't yet, but I will.
-If flash footprint is becoming a problem, there are numerous debugging strings (~3kb estimated) that can be removed from SSLClient.h
, SSLClientImpl.h
, and SSLClientImpl.cpp
. I have not figured out a way to configure compilation of these strings, so you will need to modify the library to remove them yourself.
SSL is a buffered protocol, and since most microcontrollers have limited resources (see Resources), SSLClient is limited in the size of its buffers. A common problem I encountered with SSL connections is buffer overflow, caused by the server sending too much data at once. This problem is caused by the microcontroller being unable to copy and decrypt data faster than it is being received, forcing some data to be discarded. This usually puts BearSSL in an unrecoverable state, forcing SSLClient to close the connection with a write error. If you are experiencing frequent timeout problems, this could be the reason why.
-In order to remedy this problem, the device must be able to read the data faster than it is being received, or alternatively have a cache large enough to store the entire payload. Since SSL's encryption forces the device to read slowly, this means we must increase the cache size. Depending on your platform, there are a number of ways this can be done:
By default, SSLClient supports only TLS1.2 and the ciphers listed in this file under suites[]
, and the list is relatively small to keep the connection secure and the flash footprint down. These ciphers should work for most applications, however if for some reason you would like to use an older version of TLS or a different cipher, you can change the BearSSL profile being used by SSLClient to an alternate one with support for older protocols. To do this, edit SSLClientImpl::SSLClientImpl
to change these lines:
to this:
If for some unfortunate reason you need SSL 3.0 or SSL 2.0, you will need to modify the BearSSL profile to enable support. Check out the BearSSL profiles documentation and I wish you the best of luck.
-t |
- SSLClient
- v1.5.0
-
- |
-
SSLClient uses BearSSL's minimal x509 verification engine to verify the certificate of an SSL connection. This engine requires the developer create a trust anchor array using values stored in trusted root certificates. In short, these trust anchor arrays allow BearSSL to verify that the server being connected to is who they say they are, and not someone malicious. You can read more about certificates and why they are important here.
-SSLClient stores trust anchors in hardcoded constant variables, passed into SSLClient::SSLClient
during setup. These constants are generally stored in their own header file as found in the BearSSL docs. This header file will look something like:
A full example of a trust anchor header can be found in this file. Full documentation for the format of these variables can be found in the BearSSL documentation for br_x509_trust_anchor.
-For HTTPS, there a couple of tools you can use. Ordered from easiest to hardest:
pycert_bearssl.py download
command once the utility is set up.brssl
command line utility, included in the BearSSL source. You will need to compile this file yourself.For other kinds of SSL connections, you will need to find the root certificate being used by your host. You can check out this StackExchange post for numerous methods of acquiring this certificate from a server. If these methods are not sufficient, you may need to request this certificate from your network administrator. Once you have the certificate, convert it to PEM format if needed (I use this website), and use the pycert_bearssl.py convert --no-search
command to convert the certificate into a trust anchor header.
Once you've generated a trust anchor array, add it to your Arduino sketch using the Sketch->Add File
button in the Arduino IDE, and link it to your SSLClient like so:
Where yourtrustanchorfile.h
contains a generated trust anchor array names TAs
, with length TAs_NUM
. BearSSL will now automatically use these trust anchors when SSLClient::connect
is called.