SSLClient  v1.6.11
SSLClient.h
Go to the documentation of this file.
1 /* Copyright 2019 OSU OPEnS Lab
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy of this
4  * software and associated documentation files (the "Software"), to deal in the Software
5  * without restriction, including without limitation the rights to use, copy, modify,
6  * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
7  * permit persons to whom the Software is furnished to do so, subject to the following
8  * conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in all
11  * copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15  * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
16  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
21 #include "Client.h"
22 #include "SSLSession.h"
23 #include "SSLClientParameters.h"
24 #include <vector>
25 
26 #ifndef SSLClient_H_
27 #define SSLClient_H_
28 
34 class SSLClient : public Client {
35 public:
44  enum Error {
45  SSL_OK = 0,
58  };
59 
66  enum DebugLevel {
68  SSL_NONE = 0,
70  SSL_ERROR = 1,
72  SSL_WARN = 2,
74  SSL_INFO = 3,
76  SSL_DUMP = 4,
77  };
78 
96  explicit SSLClient( Client& client,
97  const br_x509_trust_anchor *trust_anchors,
98  const size_t trust_anchors_num,
99  const int analog_pin,
100  const size_t max_sessions = 1,
101  const DebugLevel debug = SSL_WARN);
102 
103  //========================================
104  //= Functions implemented in SSLClient.cpp
105  //========================================
106 
146  int connect(IPAddress ip, uint16_t port) override;
147 
184  int connect(const char *host, uint16_t port) override;
185 
209  size_t write(const uint8_t *buf, size_t size) override;
211  size_t write(uint8_t b) override { return write(&b, 1); }
212 
231  int available() override;
232 
254  int read(uint8_t *buf, size_t size) override;
259  int read() override { uint8_t read_val; return read(&read_val, 1) > 0 ? read_val : -1; };
260 
269  int peek() override;
270 
278  void flush() override;
279 
288  void stop() override;
289 
303  uint8_t connected() override;
304 
305  //========================================
306  //= Functions Not in the Client Interface
307  //========================================
308 
317  void setMutualAuthParams(const SSLClientParameters& params);
318 
333  SSLSession* getSession(const char* host);
334 
343  void removeSession(const char* host);
344 
350  size_t getSessionCount() const { return m_sessions.size(); }
351 
357  operator bool() { return connected() > 0; }
358 
360  Client& getClient() { return m_client; }
361 
366  void setTimeout(unsigned int t) { m_timeout = t; }
367 
372  unsigned int getTimeout() const { return m_timeout; }
373 
385  void setVerificationTime(uint32_t days, uint32_t seconds);
386 
387 private:
389  Client& get_arduino_client() { return m_client; }
390  const Client& get_arduino_client() const { return m_client; }
391 
393  bool m_soft_connected(const char* func_name);
395  int m_start_ssl(const char* host = nullptr, SSLSession* ssl_ses = nullptr);
397  int m_run_until(const unsigned target);
399  unsigned m_update_engine();
401  int m_get_session_index(const char* host) const;
402 
404  void m_print_prefix(const char* func_name, const DebugLevel level) const;
405 
407  void m_print_ssl_error(const int ssl_error, const DebugLevel level) const;
408 
410  void m_print_br_error(const unsigned br_error_code, const DebugLevel level) const;
411 
413  void m_print_br_state(const unsigned br_state, const DebugLevel level) const;
414 
416  template<typename T>
417  void m_print(const T str, const char* func_name, const DebugLevel level) const {
418  // check the current debug level and serial status
419  if (level > m_debug || !Serial) return;
420  // print prefix
421  m_print_prefix(func_name, level);
422  // print the message
423  Serial.println(str);
424  }
425 
427  template<typename T>
428  void m_info(const T str, const char* func_name) const { m_print(str, func_name, SSL_INFO); }
429 
430  template<typename T>
431  void m_warn(const T str, const char* func_name) const { m_print(str, func_name, SSL_WARN); }
432 
433  template<typename T>
434  void m_error(const T str, const char* func_name) const { m_print(str, func_name, SSL_ERROR); }
435 
436  //============================================
437  //= Data Members
438  //============================================
439  // create a reference the client
440  Client& m_client;
441  // also store an array of SSLSessions, so we can resume communication with multiple websites
442  std::vector<SSLSession> m_sessions;
443  // as well as the maximmum number of sessions we can store
444  const size_t m_max_sessions;
445  // store the pin to fetch an RNG see from
446  const int m_analog_pin;
447  // store whether to enable debug logging
448  const DebugLevel m_debug;
449  // store if we are connected in bearssl or not
450  bool m_is_connected;
451  // store the timeout for SSL internals
452  unsigned int m_timeout;
453  // store the context values required for SSL
454  br_ssl_client_context m_sslctx;
455  br_x509_minimal_context m_x509ctx;
456  // use a mono-directional buffer by default to cut memory in half
457  // can expand to a bi-directional buffer with maximum of BR_SSL_BUFSIZE_BIDI
458  // or shrink to below BR_SSL_BUFSIZE_MONO, and bearSSL will adapt automatically
459  // simply edit this value to change the buffer size to the desired value
460  // additionally, we need to correct buffer size based off of how many sessions we decide to cache
461  // since SSL takes so much memory if we don't it will cause the stack and heap to collide
469  unsigned char m_iobuf[2048];
470  // store the index of where we are writing in the buffer
471  // so we can send our records all at once to prevent
472  // weird timing issues
473  size_t m_write_idx;
474  // store the last BearSSL state so we can print changes to the console
475  unsigned m_br_last_state;
476 };
477 
478 #endif
The main SSLClient class. Check out README.md for more info.
Definition: SSLClient.h:34
size_t write(const uint8_t *buf, size_t size) override
Write some bytes to the SSL connection.
Definition: SSLClient.cpp:93
int peek() override
View the first byte of the buffer, without removing it from the SSLClient Buffer.
Definition: SSLClient.cpp:179
int available() override
Returns the number of bytes available to read from the data that has been received and decrypted.
Definition: SSLClient.cpp:143
unsigned int getTimeout() const
Get the timeout when waiting for an SSL response.
Definition: SSLClient.h:372
SSLSession * getSession(const char *host)
Gets a session reference corresponding to a host and IP, or a reference to a empty session if none ex...
Definition: SSLClient.cpp:263
Error
Static constants defining the possible errors encountered.
Definition: SSLClient.h:44
@ SSL_OUT_OF_MEMORY
Definition: SSLClient.h:57
@ SSL_OK
Definition: SSLClient.h:45
@ SSL_BR_WRITE_ERROR
Definition: SSLClient.h:53
@ SSL_BR_CONNECT_FAIL
Definition: SSLClient.h:49
@ SSL_CLIENT_CONNECT_FAIL
Definition: SSLClient.h:47
@ SSL_CLIENT_WRTIE_ERROR
Definition: SSLClient.h:51
@ SSL_INTERNAL_ERROR
Definition: SSLClient.h:55
uint8_t connected() override
Check if the device is connected.
Definition: SSLClient.cpp:232
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.
Definition: SSLClient.cpp:24
size_t write(uint8_t b) override
Definition: SSLClient.h:211
void setTimeout(unsigned int t)
Set the timeout when waiting for an SSL response.
Definition: SSLClient.h:366
Client & getClient()
Returns a reference to the client object stored in this class. Take care not to break it.
Definition: SSLClient.h:360
void flush() override
Force writing the buffered bytes from SSLClient::write to the network.
Definition: SSLClient.cpp:191
void setVerificationTime(uint32_t days, uint32_t seconds)
Change the time used during x509 verification to a different value.
Definition: SSLClient.cpp:309
int connect(IPAddress ip, uint16_t port) override
Connect over SSL to a host specified by an IP address.
Definition: SSLClient.cpp:52
void removeSession(const char *host)
Clear the session corresponding to a host and IP.
Definition: SSLClient.cpp:276
void stop() override
Close the connection.
Definition: SSLClient.cpp:205
size_t getSessionCount() const
Get the maximum number of SSL sessions that can be stored at once.
Definition: SSLClient.h:350
void setMutualAuthParams(const SSLClientParameters &params)
Add a client certificate and enable support for mutual auth.
Definition: SSLClient.cpp:287
int read() override
Read a single byte, or -1 if none is available.
Definition: SSLClient.h:259
DebugLevel
Level of verbosity used in logging for SSLClient.
Definition: SSLClient.h:66
@ SSL_ERROR
Definition: SSLClient.h:70
@ SSL_NONE
Definition: SSLClient.h:68
@ SSL_WARN
Definition: SSLClient.h:72
@ SSL_INFO
Definition: SSLClient.h:74
@ SSL_DUMP
Definition: SSLClient.h:76
This class stores data required for SSLClient to use mutual authentication.
Definition: SSLClientParameters.h:52
This class stores values which allow SSLClient to save and resume SSL sessions.
Definition: SSLSession.h:51