SSLClient  1.0
Add TLS 1.2 functionality to any network library.
SSLClient< C, SessionCache > Class Template Reference

The main SSLClient class Check out README.md for more info. More...

#include <SSLClient.h>

Inheritance diagram for SSLClient< C, SessionCache >:
SSLClientImpl

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 SSLSessiongetSession (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 ()
 
SSLSessionget_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 SSLSessionget_session_array ()
 return an instance of the session array that is on the stack More...
 
virtual const SSLSessionget_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
 

Detailed Description

template<class C, size_t SessionCache = 1>
class SSLClient< C, SessionCache >

The main SSLClient class Check out README.md for more info.

Constructor & Destructor Documentation

◆ SSLClient()

template<class C , size_t SessionCache = 1>
SSLClient< C, SessionCache >::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 
)
inlineexplicit

Initialize SSLClient with all of the prerequisites needed.

Precondition
You will need to generate an array of trust_anchors (root certificates) based off of the domains you want to make SSL connections to. Check out the TrustAnchors.md file for more info.
The analog_pin should be set to input.
Parameters
clientThe base network device to create an SSL socket on. This object will be copied and the copy will be stored in SSLClient.
trust_anchorsTrust anchors used in the verification of the SSL server certificate. Check out TrustAnchors.md for more info.
trust_anchors_numThe number of objects in the trust_anchors array.
analog_pinAn analog pin to pull random bytes from, used in seeding the RNG.
debugThe level of debug logging (use the DebugLevel enum).

Member Function Documentation

◆ available()

template<class C , size_t SessionCache = 1>
virtual int SSLClient< C, SessionCache >::available ( )
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

Precondition
SSLClient::connected must be true.
Returns
The number of bytes available (can be zero), or zero if any of the pre conditions aren't satisfied.

◆ connect() [1/2]

template<class C , size_t SessionCache = 1>
virtual int SSLClient< C, SessionCache >::connect ( IPAddress  ip,
uint16_t  port 
)
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).

Precondition
The underlying client object (passed in through the constructor) is in a non- error state, and must be able to access the IP.
SSLClient can only have one connection at a time, so the client object must not already be connected.
There must be sufficient memory available on the device to verify the certificate (if the free memory drops below 8000 bytes during certain points in the connection, SSLClient will fail).
There must be a trust anchor given to the constructor that corresponds to the certificate provided by the IP address being connected to. For more information check out TrustAnchors.md .
Parameters
ipThe IP address to connect to
portthe port to connect to
Returns
1 if success, 0 if failure

◆ connect() [2/2]

template<class C , size_t SessionCache = 1>
virtual int SSLClient< C, SessionCache >::connect ( const char *  host,
uint16_t  port 
)
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)

Precondition
The underlying client object (passed in through the constructor) is in a non- error state, and must be able to access the IP.
SSLClient can only have one connection at a time, so the client object must not already be connected.
There must be sufficient memory available on the device to verify the certificate (if the free memory drops below 8000 bytes during certain points in the connection, SSLClient will fail).
There must be a trust anchor given to the constructor that corresponds to the certificate provided by the IP address being connected to. For more information check out TrustAnchors.md .
Parameters
hostThe hostname as a null-terminated c-string ("www.google.com")
portThe port to connect to on the host (443 for HTTPS)
Returns
1 of success, 0 if failure

◆ connected()

template<class C , size_t SessionCache = 1>
virtual uint8_t SSLClient< C, SessionCache >::connected ( )
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.

Returns
1 if connected, 0 if not

◆ flush()

template<class C , size_t SessionCache = 1>
virtual void SSLClient< C, SessionCache >::flush ( )
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.

◆ get_arduino_client() [1/2]

template<class C , size_t SessionCache = 1>
virtual Client& SSLClient< C, SessionCache >::get_arduino_client ( )
inlineprotectedvirtual

return an instance of m_client that is polymorphic and can be used by SSLClientImpl

Implements SSLClientImpl.

◆ get_arduino_client() [2/2]

template<class C , size_t SessionCache = 1>
virtual const Client& SSLClient< C, SessionCache >::get_arduino_client ( ) const
inlineprotectedvirtual

Implements SSLClientImpl.

◆ get_session_array() [1/2]

template<class C , size_t SessionCache = 1>
virtual SSLSession* SSLClient< C, SessionCache >::get_session_array ( )
inlineprotectedvirtual

return an instance of the session array that is on the stack

Implements SSLClientImpl.

◆ get_session_array() [2/2]

template<class C , size_t SessionCache = 1>
virtual const SSLSession* SSLClient< C, SessionCache >::get_session_array ( ) const
inlineprotectedvirtual

Implements SSLClientImpl.

◆ getClient()

template<class C , size_t SessionCache = 1>
C& SSLClient< C, SessionCache >::getClient ( )
inline

returns a reference to the client object stored in this class. Take care not to break it.

◆ getSession()

template<class C , size_t SessionCache = 1>
virtual SSLSession& SSLClient< C, SessionCache >::getSession ( const char *  host,
const IPAddress &  addr 
)
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.

Parameters
hostA hostname c string, or NULL if one is not available
addrAn IP address
Returns
A reference to an SSLSession object

◆ getSessionCount()

template<class C , size_t SessionCache = 1>
virtual size_t SSLClient< C, SessionCache >::getSessionCount ( ) const
inlinevirtual

Get the maximum number of SSL sessions that can be stored at once.

Returns
The SessionCache template parameter.

Implements SSLClientImpl.

◆ localPort()

template<class C , size_t SessionCache = 1>
virtual uint16_t SSLClient< C, SessionCache >::localPort ( )
inlinevirtual

Returns the local port, C::localPort exists. Else return 0.

Implements SSLClientImpl.

◆ operator bool()

template<class C , size_t SessionCache = 1>
virtual SSLClient< C, SessionCache >::operator bool ( )
inlinevirtual

Equivalent to SSLClient::connected() > 0.

Returns
true if connected, false if not

◆ operator!=() [1/2]

template<class C , size_t SessionCache = 1>
virtual bool SSLClient< C, SessionCache >::operator!= ( const bool  value)
inlinevirtual
See also
SSLClient::operator bool

◆ operator!=() [2/2]

template<class C , size_t SessionCache = 1>
virtual bool SSLClient< C, SessionCache >::operator!= ( const C &  rhs)
inlinevirtual

Returns whether or not two SSLClient objects do not have the same underlying client object.

◆ operator==() [1/2]

template<class C , size_t SessionCache = 1>
virtual bool SSLClient< C, SessionCache >::operator== ( const bool  value)
inlinevirtual
See also
SSLClient::operator bool

◆ operator==() [2/2]

template<class C , size_t SessionCache = 1>
virtual bool SSLClient< C, SessionCache >::operator== ( const C &  rhs)
inlinevirtual

Returns whether or not two SSLClient objects have the same underlying client object.

◆ peek()

template<class C , size_t SessionCache = 1>
virtual int SSLClient< C, SessionCache >::peek ( )
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

Precondition
SSLClient::available must be >0
Returns
The first byte received, or -1 if the preconditions are not satisfied (warning: do not use if your data may be -1, as the return value is ambiguous)

◆ read() [1/2]

template<class C , size_t SessionCache = 1>
virtual int SSLClient< C, SessionCache >::read ( )
inlinevirtual

Read a single byte, or -1 if none is available.

See also
SSLClient::read(uint8_t*, size_t)

◆ read() [2/2]

template<class C , size_t SessionCache = 1>
virtual int SSLClient< C, SessionCache >::read ( uint8_t *  buf,
size_t  size 
)
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)

Precondition
SSLClient::available must be >0
Parameters
bufThe pointer to the buffer to put SSL application data into
sizeThe size (in bytes) to copy to the buffer
Returns
The number of bytes copied (<= size), or -1 if the preconditions are not satisfied.

◆ remoteIP()

template<class C , size_t SessionCache = 1>
virtual IPAddress SSLClient< C, SessionCache >::remoteIP ( )
inlinevirtual

Returns the remote IP, if C::remoteIP exists. Else return INADDR_NONE.

Implements SSLClientImpl.

◆ remotePort()

template<class C , size_t SessionCache = 1>
virtual uint16_t SSLClient< C, SessionCache >::remotePort ( )
inlinevirtual

Returns the remote port, if C::remotePort exists. Else return 0.

Implements SSLClientImpl.

◆ removeSession()

template<class C , size_t SessionCache = 1>
virtual void SSLClient< C, SessionCache >::removeSession ( const char *  host,
const IPAddress &  addr 
)
inlinevirtual

Clear the session corresponding to a host and IP.

The implementation for this function can be found at SSLClientImpl::remove_session_impl.

Parameters
hostA hostname c string, or NULL if one is not available
addrAn IP address

◆ stop()

template<class C , size_t SessionCache = 1>
virtual void SSLClient< C, SessionCache >::stop ( )
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.

◆ write() [1/2]

template<class C , size_t SessionCache = 1>
virtual size_t SSLClient< C, SessionCache >::write ( uint8_t  b)
inlinevirtual
See also
SSLClient::write(uint8_t*, size_t)

◆ write() [2/2]

template<class C , size_t SessionCache = 1>
virtual size_t SSLClient< C, SessionCache >::write ( const uint8_t *  buf,
size_t  size 
)
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)

Precondition
The socket and SSL layer must be connected, meaning SSLClient::connected must be true.
BearSSL must not be waiting for the recipt of user data (if it is, there is probably an error with how the protocol in implemented in your code).
Parameters
bufthe pointer to a buffer of bytes to copy
sizethe number of bytes to copy from the buffer
Returns
The number of bytes copied to the buffer (size), or zero if the BearSSL engine fails to become ready for writing data.

The documentation for this class was generated from the following file: