SSLClient  v1.1.1
Add TLS 1.2 functionality to any network library.
SSLClientImpl.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 "bearssl.h"
22 #include "Arduino.h"
23 #include "Client.h"
24 #include "SSLSession.h"
25 
26 #ifndef SSLClientImpl_H_
27 #define SSLClientImpl_H_
28 
37 enum Error {
38  SSL_OK = 0,
51 };
52 
59 enum DebugLevel {
61  SSL_NONE = 0,
63  SSL_ERROR = 1,
65  SSL_WARN = 2,
67  SSL_INFO = 3,
68 };
69 
71 class SSLClientImpl : public Client {
72 public:
74  explicit SSLClientImpl(const br_x509_trust_anchor *trust_anchors,
75  const size_t trust_anchors_num, const int analog_pin, const DebugLevel debug);
76 
77  //============================================
78  //= Functions implemented in SSLClientImpl.cpp
79  //============================================
80 
82  int connect_impl(IPAddress ip, uint16_t port);
84  int connect_impl(const char *host, uint16_t port);
86  size_t write_impl(const uint8_t *buf, size_t size);
88  int available_impl();
90  int read_impl(uint8_t *buf, size_t size);
92  int peek_impl();
94  void flush_impl();
96  void stop_impl();
98  uint8_t connected_impl();
100  SSLSession& get_session_impl(const char* host, const IPAddress& addr);
102  void remove_session_impl(const char* host, const IPAddress& addr);
103 
104  //============================================
105  //= Functions implemented in SSLClient.h
106  //============================================
108  virtual uint16_t localPort() = 0;
110  virtual IPAddress remoteIP() = 0;
112  virtual uint16_t remotePort() = 0;
114  virtual size_t getSessionCount() const = 0;
115 
116 protected:
118  virtual Client& get_arduino_client() = 0;
119  virtual const Client& get_arduino_client() const = 0;
121  virtual SSLSession* get_session_array() = 0;
122  virtual const SSLSession* get_session_array() const = 0;
123 
124  //============================================
125  //= Functions implemented in SSLClientImpl.cpp
126  //============================================
127 
129  void m_print_prefix(const char* func_name, const DebugLevel level) const;
130 
132  void m_print_ssl_error(const int ssl_error, const DebugLevel level) const;
133 
135  void m_print_br_error(const unsigned br_error_code, const DebugLevel level) const;
136 
138  template<typename T>
139  void m_print(const T str, const char* func_name, const DebugLevel level) const {
140  // check the current debug level and serial status
141  if (level > m_debug || !Serial) return;
142  // print prefix
143  m_print_prefix(func_name, level);
144  // print the message
145  Serial.println(str);
146  }
147 
149  template<typename T>
150  void m_info(const T str, const char* func_name) const { m_print(str, func_name, SSL_INFO); }
151 
152  template<typename T>
153  void m_warn(const T str, const char* func_name) const { m_print(str, func_name, SSL_WARN); }
154 
155  template<typename T>
156  void m_error(const T str, const char* func_name) const { m_print(str, func_name, SSL_ERROR); }
157 
158 private:
160  bool m_soft_connected(const char* func_name);
162  int m_start_ssl(const char* host, SSLSession& ssl_ses);
164  int m_run_until(const unsigned target);
166  unsigned m_update_engine();
168  int m_get_session_index(const char* host, const IPAddress& addr) const;
169 
170  //============================================
171  //= Data Members
172  //============================================
173 
174  // store pointers to the trust anchors
175  // should not be computed at runtime
176  const br_x509_trust_anchor *m_trust_anchors;
177  const size_t m_trust_anchors_num;
178  // store the pin to fetch an RNG see from
179  const int m_analog_pin;
180  // store an index of where a new session can be placed if we don't have any corresponding sessions
181  size_t m_session_index;
182  // store whether to enable debug logging
183  const DebugLevel m_debug;
184  // store if we are connected in bearssl or not
185  bool m_is_connected;
186  // store the context values required for SSL
187  br_ssl_client_context m_sslctx;
188  br_x509_minimal_context m_x509ctx;
189  // use a mono-directional buffer by default to cut memory in half
190  // can expand to a bi-directional buffer with maximum of BR_SSL_BUFSIZE_BIDI
191  // or shrink to below BR_SSL_BUFSIZE_MONO, and bearSSL will adapt automatically
192  // simply edit this value to change the buffer size to the desired value
193  // additionally, we need to correct buffer size based off of how many sessions we decide to cache
194  // since SSL takes so much memory if we don't it will cause the stack and heap to collide
202  unsigned char m_iobuf[BR_SSL_BUFSIZE_MONO / 8];
203  static_assert(sizeof m_iobuf <= BR_SSL_BUFSIZE_BIDI, "m_iobuf must be below maximum buffer size");
204  // store the index of where we are writing in the buffer
205  // so we can send our records all at once to prevent
206  // weird timing issues
207  size_t m_write_idx;
208 };
209 
210 #endif /* SSLClientImpl_H_ */
size_t write_impl(const uint8_t *buf, size_t size)
Definition: SSLClientImpl.cpp:132
virtual uint16_t remotePort()=0
void m_print(const T str, const char *func_name, const DebugLevel level) const
debugging print function, only prints if m_debug is true
Definition: SSLClientImpl.h:139
Definition: SSLClientImpl.h:65
virtual IPAddress remoteIP()=0
SSLSession & get_session_impl(const char *host, const IPAddress &addr)
Definition: SSLClientImpl.cpp:294
This class stores values which allow SSLClient to save and resume SSL sessions.
Definition: SSLSession.h:52
void m_info(const T str, const char *func_name) const
Prints a info message to serial, if info messages are enabled.
Definition: SSLClientImpl.h:150
SSLClientImpl(const br_x509_trust_anchor *trust_anchors, const size_t trust_anchors_num, const int analog_pin, const DebugLevel debug)
Definition: SSLClientImpl.cpp:53
void m_error(const T str, const char *func_name) const
Definition: SSLClientImpl.h:156
int peek_impl()
Definition: SSLClientImpl.cpp:211
Definition: SSLClientImpl.h:67
Definition: SSLClientImpl.h:63
Definition: SSLClientImpl.h:48
virtual size_t getSessionCount() const =0
virtual SSLSession * get_session_array()=0
Definition: SSLClientImpl.h:46
Definition: SSLClientImpl.h:38
void m_print_ssl_error(const int ssl_error, const DebugLevel level) const
Prints the string associated with a write error.
Definition: SSLClientImpl.cpp:657
int available_impl()
Definition: SSLClientImpl.cpp:175
Error
Static constants defining the possible errors encountered.
Definition: SSLClientImpl.h:37
Definition: SSLClientImpl.h:42
int read_impl(uint8_t *buf, size_t size)
Definition: SSLClientImpl.cpp:196
void remove_session_impl(const char *host, const IPAddress &addr)
Definition: SSLClientImpl.cpp:313
Definition: SSLClientImpl.h:44
virtual Client & get_arduino_client()=0
Definition: SSLClientImpl.h:40
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.
Definition: SSLClientImpl.cpp:639
Definition: SSLClientImpl.h:61
void m_print_br_error(const unsigned br_error_code, const DebugLevel level) const
Print the text string associated with a BearSSL error code.
Definition: SSLClientImpl.cpp:672
void m_warn(const T str, const char *func_name) const
Definition: SSLClientImpl.h:153
int connect_impl(IPAddress ip, uint16_t port)
Definition: SSLClientImpl.cpp:75
Definition: SSLClientImpl.h:50
void stop_impl()
Definition: SSLClientImpl.cpp:231
void flush_impl()
Definition: SSLClientImpl.cpp:223
Implementation code to be inherited by SSLClient.
Definition: SSLClientImpl.h:71
virtual uint16_t localPort()=0
uint8_t connected_impl()
Definition: SSLClientImpl.cpp:263
DebugLevel
Level of verbosity used in logging for SSLClient.
Definition: SSLClientImpl.h:59