diff --git a/.gitignore b/.gitignore index 6a8fcb1..99ca00b 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,6 @@ *.app # vscode IDE settings -.vscode/** \ No newline at end of file +.vscode/** + +doxy \ No newline at end of file diff --git a/docs/html/_r_e_a_d_m_e_8md.html b/docs/html/_r_e_a_d_m_e_8md.html new file mode 100644 index 0000000..1db9a61 --- /dev/null +++ b/docs/html/_r_e_a_d_m_e_8md.html @@ -0,0 +1,106 @@ + + +
+ + + + +
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
Go to the source code of this file.
++Classes | |
class | SSLClient< C, SessionCache > |
The main SSLClient class Check out README.md for more info. More... | |
+Macros | |
#define | SSLClient_H_ |
#define SSLClient_H_ | +
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
#include "SSLClient.h"
+Variables | |
char * | __brkval |
char* __brkval | +
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
Go to the source code of this file.
++Classes | |
class | SSLClientImpl |
Implementation code to be inherited by SSLClient. More... | |
+Enumerations | |
enum | Error { + SSL_OK = 0, +SSL_CLIENT_CONNECT_FAIL, +SSL_BR_CONNECT_FAIL, +SSL_CLIENT_WRTIE_ERROR, + + SSL_BR_WRITE_ERROR, +SSL_INTERNAL_ERROR, +SSL_OUT_OF_MEMORY + + } |
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... | |
enum 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 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. + |
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
#include "bearssl.h"
#include "Arduino.h"
#include "IPAddress.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
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+Functions | |
void | br_client_init_TLS12_only (br_ssl_client_context *cc, br_x509_minimal_context *xc, const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num) |
void br_client_init_TLS12_only | +( | +br_ssl_client_context * | +cc, | +
+ | + | br_x509_minimal_context * | +xc, | +
+ | + | const br_x509_trust_anchor * | +trust_anchors, | +
+ | + | size_t | +trust_anchors_num | +
+ | ) | ++ |
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
CSSLClient | The main SSLClient class Check out README.md for more info |
CSSLClientImpl | Implementation code to be inherited by SSLClient |
CSSLSession | This class stores values which allow SSLClient to save and resume SSL sessions |
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
Go to the source code of this file.
++Macros | |
#define | TAs_NUM 1 |
#define TAs_NUM 1 | +
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
This is the complete list of members for SSLClient< C, SessionCache >, including all inherited members.
+available() | SSLClient< C, SessionCache > | inlinevirtual |
available_impl() | SSLClientImpl | |
connect(IPAddress ip, uint16_t port) | SSLClient< C, SessionCache > | inlinevirtual |
connect(const char *host, uint16_t port) | SSLClient< C, SessionCache > | inlinevirtual |
connect_impl(IPAddress ip, uint16_t port) | SSLClientImpl | |
connect_impl(const char *host, uint16_t port) | SSLClientImpl | |
connected() | SSLClient< C, SessionCache > | inlinevirtual |
connected_impl() | SSLClientImpl | |
flush() | SSLClient< C, SessionCache > | inlinevirtual |
flush_impl() | SSLClientImpl | |
get_arduino_client() | SSLClient< C, SessionCache > | inlineprotectedvirtual |
get_arduino_client() const | SSLClient< C, SessionCache > | inlineprotectedvirtual |
get_session_array() | SSLClient< C, SessionCache > | inlineprotectedvirtual |
get_session_array() const | SSLClient< C, SessionCache > | inlineprotectedvirtual |
get_session_impl(const char *host, const IPAddress &addr) | SSLClientImpl | |
getClient() | SSLClient< C, SessionCache > | inline |
getSession(const char *host, const IPAddress &addr) | SSLClient< C, SessionCache > | inlinevirtual |
getSessionCount() const | SSLClient< C, SessionCache > | inlinevirtual |
localPort() | SSLClient< C, SessionCache > | inlinevirtual |
m_error(const T str, const char *func_name) const | SSLClientImpl | inlineprotected |
m_info(const T str, const char *func_name) const | SSLClientImpl | inlineprotected |
m_print(const T str, const char *func_name, const DebugLevel level) const | SSLClientImpl | inlineprotected |
m_print_br_error(const unsigned br_error_code, const DebugLevel level) const | SSLClientImpl | protected |
m_print_prefix(const char *func_name, const DebugLevel level) const | SSLClientImpl | protected |
m_print_ssl_error(const int ssl_error, const DebugLevel level) const | SSLClientImpl | protected |
m_warn(const T str, const char *func_name) const | SSLClientImpl | inlineprotected |
operator bool() | SSLClient< C, SessionCache > | inlinevirtual |
operator!=(const bool value) | SSLClient< C, SessionCache > | inlinevirtual |
operator!=(const C &rhs) | SSLClient< C, SessionCache > | inlinevirtual |
operator==(const bool value) | SSLClient< C, SessionCache > | inlinevirtual |
operator==(const C &rhs) | SSLClient< C, SessionCache > | inlinevirtual |
peek() | SSLClient< C, SessionCache > | inlinevirtual |
peek_impl() | SSLClientImpl | |
read() | SSLClient< C, SessionCache > | inlinevirtual |
read(uint8_t *buf, size_t size) | SSLClient< C, SessionCache > | inlinevirtual |
read_impl(uint8_t *buf, size_t size) | SSLClientImpl | |
remoteIP() | SSLClient< C, SessionCache > | inlinevirtual |
remotePort() | SSLClient< C, SessionCache > | inlinevirtual |
remove_session_impl(const char *host, const IPAddress &addr) | SSLClientImpl | |
removeSession(const char *host, const IPAddress &addr) | SSLClient< C, SessionCache > | inlinevirtual |
SSLClient(const C &client, const br_x509_trust_anchor *trust_anchors, const size_t trust_anchors_num, const int analog_pin, const DebugLevel debug=SSL_WARN) | SSLClient< C, SessionCache > | inlineexplicit |
SSLClientImpl(const br_x509_trust_anchor *trust_anchors, const size_t trust_anchors_num, const int analog_pin, const DebugLevel debug) | SSLClientImpl | explicit |
stop() | SSLClient< C, SessionCache > | inlinevirtual |
stop_impl() | SSLClientImpl | |
write(uint8_t b) | SSLClient< C, SessionCache > | inlinevirtual |
write(const uint8_t *buf, size_t size) | SSLClient< C, SessionCache > | inlinevirtual |
write_impl(const uint8_t *buf, size_t size) | SSLClientImpl |
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
The main SSLClient class Check out README.md for more info. + More...
+ +#include <SSLClient.h>
+Public Member Functions | |
SSLClient (const C &client, const br_x509_trust_anchor *trust_anchors, const size_t trust_anchors_num, const int analog_pin, const DebugLevel debug=SSL_WARN) | |
Initialize SSLClient with all of the prerequisites needed. More... | |
virtual int | connect (IPAddress ip, uint16_t port) |
Connect over SSL to a host specified by an IP address. More... | |
virtual int | connect (const char *host, uint16_t port) |
Connect over SSL to a host specified by a hostname. More... | |
virtual size_t | write (uint8_t b) |
virtual size_t | write (const uint8_t *buf, size_t size) |
Write some bytes to the SSL connection. More... | |
virtual int | available () |
Returns the number of bytes availible to read from the SSL Socket. More... | |
virtual int | read () |
Read a single byte, or -1 if none is available. More... | |
virtual int | read (uint8_t *buf, size_t size) |
Read size bytes from the SSL socket buffer, copying them into *buf, and return the number of bytes read. More... | |
virtual int | peek () |
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 More... | |
virtual void | flush () |
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. More... | |
virtual void | stop () |
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. More... | |
virtual uint8_t | connected () |
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 SSLClient::available should be preferred over this function for rapid polling–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. More... | |
virtual SSLSession & | getSession (const char *host, const IPAddress &addr) |
Get a session reference corresponding to a host and IP, or a reference to a empty session if none exist. More... | |
virtual void | removeSession (const char *host, const IPAddress &addr) |
Clear the session corresponding to a host and IP. More... | |
virtual size_t | getSessionCount () const |
Get the maximum number of SSL sessions that can be stored at once. More... | |
virtual | operator bool () |
Equivalent to SSLClient::connected() > 0. More... | |
virtual bool | operator== (const bool value) |
virtual bool | operator!= (const bool value) |
virtual bool | operator== (const C &rhs) |
Returns whether or not two SSLClient objects have the same underlying client object. More... | |
virtual bool | operator!= (const C &rhs) |
Returns whether or not two SSLClient objects do not have the same underlying client object. More... | |
virtual uint16_t | localPort () |
Returns the local port, C::localPort exists. Else return 0. More... | |
virtual IPAddress | remoteIP () |
Returns the remote IP, if C::remoteIP exists. Else return INADDR_NONE. More... | |
virtual uint16_t | remotePort () |
Returns the remote port, if C::remotePort exists. Else return 0. More... | |
C & | getClient () |
returns a reference to the client object stored in this class. Take care not to break it. More... | |
Public Member Functions inherited from SSLClientImpl | |
SSLClientImpl (const br_x509_trust_anchor *trust_anchors, const size_t trust_anchors_num, const int analog_pin, const DebugLevel debug) | |
int | connect_impl (IPAddress ip, uint16_t port) |
int | connect_impl (const char *host, uint16_t port) |
size_t | write_impl (const uint8_t *buf, size_t size) |
int | available_impl () |
int | read_impl (uint8_t *buf, size_t size) |
int | peek_impl () |
void | flush_impl () |
void | stop_impl () |
uint8_t | connected_impl () |
SSLSession & | get_session_impl (const char *host, const IPAddress &addr) |
void | remove_session_impl (const char *host, const IPAddress &addr) |
+Protected Member Functions | |
virtual Client & | get_arduino_client () |
return an instance of m_client that is polymorphic and can be used by SSLClientImpl More... | |
virtual const Client & | get_arduino_client () const |
virtual SSLSession * | get_session_array () |
return an instance of the session array that is on the stack More... | |
virtual const SSLSession * | get_session_array () const |
Protected Member Functions inherited from SSLClientImpl | |
void | m_print_prefix (const char *func_name, const DebugLevel level) const |
Prints a debugging prefix to all logs, so we can attatch them to useful information. More... | |
void | m_print_ssl_error (const int ssl_error, const DebugLevel level) const |
Prints the string associated with a write error. More... | |
void | m_print_br_error (const unsigned br_error_code, const DebugLevel level) const |
Print the text string associated with a BearSSL error code. More... | |
template<typename T > | |
void | m_print (const T str, const char *func_name, const DebugLevel level) const |
debugging print function, only prints if m_debug is true More... | |
template<typename T > | |
void | m_info (const T str, const char *func_name) const |
Prints a info message to serial, if info messages are enabled. More... | |
template<typename T > | |
void | m_warn (const T str, const char *func_name) const |
template<typename T > | |
void | m_error (const T str, const char *func_name) const |
+
|
+ +inlineexplicit | +
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. |
debug | The level of debug logging (use the DebugLevel enum). |
+
|
+ +inlinevirtual | +
Returns the number of bytes availible to read from the SSL Socket.
+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
+
+
|
+ +inlinevirtual | +
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, 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 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 |
+
|
+ +inlinevirtual | +
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 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) |
+
|
+ +inlinevirtual | +
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 SSLClient::available should be preferred over this function for rapid polling–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.
+The implementation for this function can be found in SSLClientImpl::connected_impl.
+
+
|
+ +inlinevirtual | +
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.
+ +
+
|
+ +inlineprotectedvirtual | +
return an instance of m_client that is polymorphic and can be used by SSLClientImpl
+ +Implements SSLClientImpl.
+ +
+
|
+ +inlineprotectedvirtual | +
Implements SSLClientImpl.
+ +
+
|
+ +inlineprotectedvirtual | +
return an instance of the session array that is on the stack
+ +Implements SSLClientImpl.
+ +
+
|
+ +inlineprotectedvirtual | +
Implements SSLClientImpl.
+ +
+
|
+ +inline | +
returns a reference to the client object stored in this class. Take care not to break it.
+ +
+
|
+ +inlinevirtual | +
Get 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 |
+
|
+ +inlinevirtual | +
Get the maximum number of SSL sessions that can be stored at once.
+Implements SSLClientImpl.
+ +
+
|
+ +inlinevirtual | +
Returns the local port, C::localPort exists. Else return 0.
+ +Implements SSLClientImpl.
+ +
+
|
+ +inlinevirtual | +
Equivalent to SSLClient::connected() > 0.
+
+
|
+ +inlinevirtual | +
+
|
+ +inlinevirtual | +
Returns whether or not two SSLClient objects do not have the same underlying client object.
+ +
+
|
+ +inlinevirtual | +
+
|
+ +inlinevirtual | +
Returns whether or not two SSLClient objects have the same underlying client object.
+ +
+
|
+ +inlinevirtual | +
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
+
+
|
+ +inlinevirtual | +
Read a single byte, or -1 if none is available.
+ + +
+
|
+ +inlinevirtual | +
Read size bytes from the SSL socket 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 |
+
|
+ +inlinevirtual | +
Returns the remote IP, if C::remoteIP exists. Else return INADDR_NONE.
+ +Implements SSLClientImpl.
+ +
+
|
+ +inlinevirtual | +
Returns the remote port, if C::remotePort exists. Else return 0.
+ +Implements SSLClientImpl.
+ +
+
|
+ +inlinevirtual | +
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 NULL if one is not available |
addr | An IP address |
+
|
+ +inlinevirtual | +
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.
+ +
+
|
+ +inlinevirtual | +
+
|
+ +inlinevirtual | +
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 |
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
This is the complete list of members for SSLClientImpl, including all inherited members.
+available_impl() | SSLClientImpl | |
connect_impl(IPAddress ip, uint16_t port) | SSLClientImpl | |
connect_impl(const char *host, uint16_t port) | SSLClientImpl | |
connected_impl() | SSLClientImpl | |
flush_impl() | SSLClientImpl | |
get_arduino_client()=0 | SSLClientImpl | protectedpure virtual |
get_arduino_client() const =0 | SSLClientImpl | protectedpure virtual |
get_session_array()=0 | SSLClientImpl | protectedpure virtual |
get_session_array() const =0 | SSLClientImpl | protectedpure virtual |
get_session_impl(const char *host, const IPAddress &addr) | SSLClientImpl | |
getSessionCount() const =0 | SSLClientImpl | pure virtual |
localPort()=0 | SSLClientImpl | pure virtual |
m_error(const T str, const char *func_name) const | SSLClientImpl | inlineprotected |
m_info(const T str, const char *func_name) const | SSLClientImpl | inlineprotected |
m_print(const T str, const char *func_name, const DebugLevel level) const | SSLClientImpl | inlineprotected |
m_print_br_error(const unsigned br_error_code, const DebugLevel level) const | SSLClientImpl | protected |
m_print_prefix(const char *func_name, const DebugLevel level) const | SSLClientImpl | protected |
m_print_ssl_error(const int ssl_error, const DebugLevel level) const | SSLClientImpl | protected |
m_warn(const T str, const char *func_name) const | SSLClientImpl | inlineprotected |
peek_impl() | SSLClientImpl | |
read_impl(uint8_t *buf, size_t size) | SSLClientImpl | |
remoteIP()=0 | SSLClientImpl | pure virtual |
remotePort()=0 | SSLClientImpl | pure virtual |
remove_session_impl(const char *host, const IPAddress &addr) | SSLClientImpl | |
SSLClientImpl(const br_x509_trust_anchor *trust_anchors, const size_t trust_anchors_num, const int analog_pin, const DebugLevel debug) | SSLClientImpl | explicit |
stop_impl() | SSLClientImpl | |
write_impl(const uint8_t *buf, size_t size) | SSLClientImpl |
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
Implementation code to be inherited by SSLClient. + More...
+ +#include <SSLClientImpl.h>
+Public Member Functions | |
SSLClientImpl (const br_x509_trust_anchor *trust_anchors, const size_t trust_anchors_num, const int analog_pin, const DebugLevel debug) | |
int | connect_impl (IPAddress ip, uint16_t port) |
int | connect_impl (const char *host, uint16_t port) |
size_t | write_impl (const uint8_t *buf, size_t size) |
int | available_impl () |
int | read_impl (uint8_t *buf, size_t size) |
int | peek_impl () |
void | flush_impl () |
void | stop_impl () |
uint8_t | connected_impl () |
SSLSession & | get_session_impl (const char *host, const IPAddress &addr) |
void | remove_session_impl (const char *host, const IPAddress &addr) |
virtual uint16_t | localPort ()=0 |
virtual IPAddress | remoteIP ()=0 |
virtual uint16_t | remotePort ()=0 |
virtual size_t | getSessionCount () const =0 |
+Protected Member Functions | |
virtual Client & | get_arduino_client ()=0 |
virtual const Client & | get_arduino_client () const =0 |
virtual SSLSession * | get_session_array ()=0 |
virtual const SSLSession * | get_session_array () const =0 |
void | m_print_prefix (const char *func_name, const DebugLevel level) const |
Prints a debugging prefix to all logs, so we can attatch them to useful information. More... | |
void | m_print_ssl_error (const int ssl_error, const DebugLevel level) const |
Prints the string associated with a write error. More... | |
void | m_print_br_error (const unsigned br_error_code, const DebugLevel level) const |
Print the text string associated with a BearSSL error code. More... | |
template<typename T > | |
void | m_print (const T str, const char *func_name, const DebugLevel level) const |
debugging print function, only prints if m_debug is true More... | |
template<typename T > | |
void | m_info (const T str, const char *func_name) const |
Prints a info message to serial, if info messages are enabled. More... | |
template<typename T > | |
void | m_warn (const T str, const char *func_name) const |
template<typename T > | |
void | m_error (const T str, const char *func_name) const |
Implementation code to be inherited by SSLClient.
+
+
|
+ +explicit | +
int SSLClientImpl::available_impl | +( | +) | ++ |
int SSLClientImpl::connect_impl | +( | +IPAddress | +ip, | +
+ | + | uint16_t | +port | +
+ | ) | ++ |
int SSLClientImpl::connect_impl | +( | +const char * | +host, | +
+ | + | uint16_t | +port | +
+ | ) | ++ |
uint8_t SSLClientImpl::connected_impl | +( | +) | ++ |
void SSLClientImpl::flush_impl | +( | +) | ++ |
+
|
+ +protectedpure virtual | +
See SSLClient::get_arduino_client
+ +Implemented in SSLClient< C, SessionCache >.
+ +
+
|
+ +protectedpure virtual | +
Implemented in SSLClient< C, SessionCache >.
+ +
+
|
+ +protectedpure virtual | +
See SSLClient::get_session_array
+ +Implemented in SSLClient< C, SessionCache >.
+ +
+
|
+ +protectedpure virtual | +
Implemented in SSLClient< C, SessionCache >.
+ +SSLSession & SSLClientImpl::get_session_impl | +( | +const char * | +host, | +
+ | + | const IPAddress & | +addr | +
+ | ) | ++ |
+
|
+ +pure virtual | +
See SSLClient::getSessionCount
+ +Implemented in SSLClient< C, SessionCache >.
+ +
+
|
+ +pure virtual | +
Implemented in SSLClient< C, SessionCache >.
+ +
+
|
+ +inlineprotected | +
+
|
+ +inlineprotected | +
Prints a info message to serial, if info messages are enabled.
+ +
+
|
+ +inlineprotected | +
debugging print function, only prints if m_debug is true
+ +
+
|
+ +protected | +
Print the text string associated with a BearSSL error code.
+ +
+
|
+ +protected | +
Prints a debugging prefix to all logs, so we can attatch them to useful information.
+ +
+
|
+ +protected | +
Prints the string associated with a write error.
+ +
+
|
+ +inlineprotected | +
int SSLClientImpl::peek_impl | +( | +) | ++ |
int SSLClientImpl::read_impl | +( | +uint8_t * | +buf, | +
+ | + | size_t | +size | +
+ | ) | ++ |
+
|
+ +pure virtual | +
Implemented in SSLClient< C, SessionCache >.
+ +
+
|
+ +pure virtual | +
Implemented in SSLClient< C, SessionCache >.
+ +void SSLClientImpl::remove_session_impl | +( | +const char * | +host, | +
+ | + | const IPAddress & | +addr | +
+ | ) | ++ |
void SSLClientImpl::stop_impl | +( | +) | ++ |
size_t SSLClientImpl::write_impl | +( | +const uint8_t * | +buf, | +
+ | + | size_t | +size | +
+ | ) | ++ |
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
This is the complete list of members for SSLSession, including all inherited members.
+clear_parameters() | SSLSession | |
get_hostname() const | SSLSession | inline |
get_ip() const | SSLSession | inline |
is_valid_session() const | SSLSession | inline |
operator=(const SSLSession &)=delete | SSLSession | |
set_parameters(const IPAddress &ip, const char *hostname=NULL) | SSLSession | |
SSLSession() | SSLSession | inlineexplicit |
to_br_session() | SSLSession | inline |
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
This class stores values which allow SSLClient to save and resume SSL sessions. + More...
+ +#include <SSLSession.h>
+Public Member Functions | |
SSLSession () | |
SSLSession constructor. More... | |
SSLSession & | operator= (const SSLSession &)=delete |
use clear_parameters or set_parameters instead More... | |
const String & | get_hostname () const |
Get the hostname string associated with this session. More... | |
const IPAddress & | get_ip () const |
Get ::IPAddress associated with this session. More... | |
bool | is_valid_session () const |
void | set_parameters (const IPAddress &ip, const char *hostname=NULL) |
Set the ip address and hostname of the session. More... | |
void | clear_parameters () |
delete the parameters and invalidate the session Roughly equivalent to this_session = SSLSession(), however this function preserves the String object, allowing it to better handle the dynamic memory needed. 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.
+
+
|
+ +inlineexplicit | +
SSLSession constructor.
+Sets all parameters to zero, and invalidates the session
+ +void SSLSession::clear_parameters | +( | +) | ++ |
delete the parameters and invalidate the session Roughly equivalent to this_session = SSLSession(), however this function preserves the String object, allowing it to better handle the dynamic memory needed.
+ +
+
|
+ +inline | +
Get the hostname string associated with this session.
+
+
|
+ +inline | +
Get ::IPAddress associated with this session.
+
+
|
+ +inline | +
+
|
+ +delete | +
use clear_parameters or set_parameters instead
+ +void SSLSession::set_parameters | +( | +const IPAddress & | +ip, | +
+ | + | const char * | +hostname = NULL |
+
+ | ) | ++ |
Set the ip address and hostname of the session.
+This function stores the ip Address object and hostname object into the session object. If hostname is not null or ip address is not blank, and the ::br_ssl_session_parameters values are non-zero it then validates the session.
+ip | The IP address of the host associated with the session |
hostname | The string hostname ("www.google.com") associated with the session. Take care that this value is corrent, SSLSession performs no validation of the hostname. |
+
|
+ +inline | +
returns a pointer to the ::br_ssl_session_parameters component of this class
+ +
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+Files | |
file | SSLClient.h [code] |
file | SSLClientImpl.cpp |
file | SSLClientImpl.h [code] |
file | SSLSession.cpp |
file | SSLSession.h [code] |
file | time_macros.h [code] |
file | TLS12_only_profile.c |
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
▼ readme | |
cert.h | |
▼ src | |
SSLClient.h | |
SSLClientImpl.cpp | |
SSLClientImpl.h | |
SSLSession.cpp | |
SSLSession.h | |
time_macros.h | |
TLS12_only_profile.c |
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
▼Cbr_ssl_session_parameters | |
CSSLSession | This class stores values which allow SSLClient to save and resume SSL sessions |
▼CClient | |
▼CSSLClientImpl | Implementation code to be inherited by SSLClient |
CSSLClient< C, SessionCache > | The main SSLClient class Check out README.md for more info |
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
t |
+ SSLClient
+ 1.0
+
+ Add TLS 1.2 functionality to any network library.
+ |
+
SSLClient requires at least 110kb flash and 8kb 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.
+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.
+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:
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 the code adds those programming checks back in, making debugging a fast and simple process. The rest manages the state of BearSSL, and ensures a manageable memory footprint.
+Additionally, the bulk of SSLClient is split into two components: a template class SSLClient, and an implementation class SSLClientImpl. The template class serves to abstract some functions not implemented in the Arduino Client interface (such as EthernetClient::remoteIP
), and the implementation class is the rest of the SSLClient library.
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 Error. 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 [this enumeration](link-me). 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](link-me), calling this function does not actually write to the network. Instead, you must call [SSLClient::available](link-me) or [SSLClient::flush](link-me), which will detect that the buffer is ready and write to the network (see [SSLClient::write](link-me) 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 a IP address that recognizes the SSL session instead of another IP address associated with "www.google.com"
. 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.
+Some ideas that didn't quite fit in the API documentation.
+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.
+