SSLClient.h
Go to the documentation of this file.
/* Copyright 2019 OSU OPEnS Lab
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify,
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "Client.h"
#include "SSLClientImpl.h"
#include "SSLSession.h"
#include "SSLClientParameters.h"
#include "SSLObj.h"
#ifndef SSLClient_H_
#define SSLClient_H_
template <class C, size_t SessionCache = 1>
class SSLClient : public SSLClientImpl {
/*
* static checks
* I'm a java developer, so I want to ensure that my inheritance is safe.
* These checks ensure that all the functions we use on class C are
* actually present on class C. It does this by checking that the
* class inherits from Client.
*
* Additionally, I ran into a lot of memory issues with large sessions caches.
* Since each session contains at max 352 bytes of memory, they eat of the
* stack quite quickly and can cause overflows. As a result, I have added a
* warning here to discourage the use of more than 3 sessions at a time. Any
* amount past that will require special modification of this library, and
* assumes you know what you are doing.
*/
static_assert(SessionCache > 0 && SessionCache < 255, "There can be no less than one and no more than 255 sessions in the cache!");
static_assert(SessionCache <= 3, "You need to decrease the size of m_iobuf in order to have more than 3 sessions at once, otherwise memory issues will occur.");
public:
explicit 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)
: SSLClientImpl(trust_anchors, trust_anchors_num, analog_pin, debug)
, m_client(client)
, m_sessions{}
{
// set the timeout to a reasonable number (it can always be changes later)
// SSL Connections take a really long time so we don't want to time out a legitimate thing
setTimeout(30 * 1000);
}
//========================================
//= Functions implemented in SSLClientImpl
//========================================
int connect(IPAddress ip, uint16_t port) override { return connect_impl(ip, port); }
int connect(const char *host, uint16_t port) override { return connect_impl(host, port); }
size_t write(uint8_t b) override { return write_impl(&b, 1); }
size_t write(const uint8_t *buf, size_t size) override { return write_impl(buf, size); }
int available() override { return available_impl(); }
int read() override { uint8_t read_val; return read(&read_val, 1) > 0 ? read_val : -1; };
int read(uint8_t *buf, size_t size) override { return read_impl(buf, size); }
int peek() override { return peek_impl(); }
void flush() override { return flush_impl(); }
void stop() override { return stop_impl(); }
uint8_t connected() override { return connected_impl(); }
//========================================
//= Functions Not in the Client Interface
//========================================
void setMutualAuthParams(const SSLClientParameters* params) { return set_mutual_impl(params); }
SSLSession& getSession(const char* host, const IPAddress& addr) { return get_session_impl(host, addr); }
void removeSession(const char* host, const IPAddress& addr) { return remove_session_impl(host, addr); }
size_t getSessionCount() const override { return SessionCache; }
operator bool() { return connected() > 0; }
bool operator==(const bool value) { return bool() == value; }
bool operator!=(const bool value) { return bool() != value; }
bool operator==(const C& rhs) { return m_client == rhs; }
bool operator!=(const C& rhs) { return m_client != rhs; }
uint16_t localPort() override { return m_client.localPort(); }
IPAddress remoteIP() override { return m_client.remoteIP(); }
uint16_t remotePort() override { return m_client.remotePort(); }
C& getClient() { return m_client; }
protected:
Client& get_arduino_client() override { return m_client; }
const Client& get_arduino_client() const override { return m_client; }
SSLSession* get_session_array() override { return m_sessions; }
const SSLSession* get_session_array() const override { return m_sessions; }
private:
// create a copy of the client
C m_client;
// also store an array of SSLSessions, so we can resume communication with multiple websites
SSLSession m_sessions[SessionCache];
};
#endif
SSLClient::setMutualAuthParams
void setMutualAuthParams(const SSLClientParameters *params)
Add a client certificate and enable support for mutual auth.
Definition: SSLClient.h:300
SSLClientImpl::write_impl
size_t write_impl(const uint8_t *buf, size_t size)
Definition: SSLClientImpl.cpp:130
SSLClient::get_session_array
const SSLSession * get_session_array() const override
Definition: SSLClient.h:365
SSLClient::remoteIP
IPAddress remoteIP() override
Returns the remote IP, if C::remoteIP exists.
Definition: SSLClient.h:352
SSLClient::write
size_t write(uint8_t b) override
Definition: SSLClient.h:170
SSL_WARN
Definition: SSLClientImpl.h:66
SSLClientImpl::get_session_impl
SSLSession & get_session_impl(const char *host, const IPAddress &addr)
Definition: SSLClientImpl.cpp:286
SSLSession
This class stores values which allow SSLClient to save and resume SSL sessions.
Definition: SSLSession.h:52
SSLClient::operator!=
bool operator!=(const C &rhs)
Returns whether or not two SSLClient objects do not have the same underlying client object.
Definition: SSLClient.h:348
SSLClient::available
int available() override
Returns the number of bytes available to read from the data that has been received and decrypted.
Definition: SSLClient.h:214
SSLClient::getClient
C & getClient()
Returns a reference to the client object stored in this class. Take care not to break it.
Definition: SSLClient.h:357
SSLClientImpl::peek_impl
int peek_impl()
Definition: SSLClientImpl.cpp:209
SSLClientParameters
This struct stores data required for SSLClient to use mutual authentication.
Definition: SSLClientParameters.h:52
SSLClient::flush
void flush() override
Force writing the buffered bytes from SSLClient::write to the network.
Definition: SSLClient.h:261
SSLClient
The main SSLClient class. Check out README.md for more info.
Definition: SSLClient.h:36
SSLClient::operator!=
bool operator!=(const bool value)
Definition: SSLClient.h:344
SSLClient::stop
void stop() override
Close the connection.
Definition: SSLClient.h:271
SSLClient::write
size_t write(const uint8_t *buf, size_t size) override
Write some bytes to the SSL connection.
Definition: SSLClient.h:194
SSLClient::SSLClient
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.
Definition: SSLClient.h:72
SSLClient::peek
int peek() override
View the first byte of the buffer, without removing it from the SSLClient Buffer.
Definition: SSLClient.h:252
SSLClientImpl::available_impl
int available_impl()
Definition: SSLClientImpl.cpp:173
SSLClient::operator==
bool operator==(const C &rhs)
Returns whether or not two SSLClient objects have the same underlying client object.
Definition: SSLClient.h:346
SSLClientImpl::read_impl
int read_impl(uint8_t *buf, size_t size)
Definition: SSLClientImpl.cpp:194
SSLClient::get_session_array
SSLSession * get_session_array() override
Returns an instance of the session array that is on the stack.
Definition: SSLClient.h:364
SSLClientImpl::remove_session_impl
void remove_session_impl(const char *host, const IPAddress &addr)
Definition: SSLClientImpl.cpp:305
SSLClient::get_arduino_client
Client & get_arduino_client() override
Returns an instance of m_client that is polymorphic and can be used by SSLClientImpl.
Definition: SSLClient.h:361
SSLClient::localPort
uint16_t localPort() override
Returns the local port, if C::localPort exists.
Definition: SSLClient.h:350
SSLClientImpl.h
SSLClientImpl::set_mutual_impl
void set_mutual_impl(const SSLClientParameters *params)
Definition: SSLClientImpl.cpp:316
SSLClient::read
int read() override
Read a single byte, or -1 if none is available.
Definition: SSLClient.h:220
SSLClientParameters.h
SSLClient::connected
uint8_t connected() override
Check if the device is connected.
Definition: SSLClient.h:286
SSLSession.h
SSLClient::get_arduino_client
const Client & get_arduino_client() const override
Definition: SSLClient.h:362
SSLClient::connect
int connect(const char *host, uint16_t port) override
Connect over SSL to a host specified by a hostname.
Definition: SSLClient.h:167
SSLClient::operator==
bool operator==(const bool value)
Definition: SSLClient.h:342
SSLClient::remotePort
uint16_t remotePort() override
Returns the remote port, if C::remotePort exists. Else return 0.
Definition: SSLClient.h:354
SSLClientImpl::connect_impl
int connect_impl(IPAddress ip, uint16_t port)
Definition: SSLClientImpl.cpp:73
SSLClient::getSessionCount
size_t getSessionCount() const override
Get the maximum number of SSL sessions that can be stored at once.
Definition: SSLClient.h:333
SSLClientImpl::stop_impl
void stop_impl()
Definition: SSLClientImpl.cpp:227
SSLClientImpl::flush_impl
void flush_impl()
Definition: SSLClientImpl.cpp:221
SSLObj.h
SSLClientImpl
Implementation code to be inherited by SSLClient.
Definition: SSLClientImpl.h:72
SSLClient::removeSession
void removeSession(const char *host, const IPAddress &addr)
Clear the session corresponding to a host and IP.
Definition: SSLClient.h:326
SSLClientImpl::connected_impl
uint8_t connected_impl()
Definition: SSLClientImpl.cpp:255
SSLClient::getSession
SSLSession & getSession(const char *host, const IPAddress &addr)
Gets a session reference corresponding to a host and IP, or a reference to a empty session if none ex...
Definition: SSLClient.h:316
DebugLevel
DebugLevel
Level of verbosity used in logging for SSLClient.
Definition: SSLClientImpl.h:60
SSLClient::read
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 re...
Definition: SSLClient.h:242
SSLClient::connect
int connect(IPAddress ip, uint16_t port) override
Connect over SSL to a host specified by an IP address.
Definition: SSLClient.h:129