|
2 | 2 | WiFiClientSecure.cpp - Client Secure class for ESP32
|
3 | 3 | Copyright (c) 2016 Hristo Gochkov All right reserved.
|
4 | 4 | Additions Copyright (C) 2017 Evandro Luis Copercini.
|
| 5 | + Rewrite for SSLClient Copyright (c) 2021 Stanislav Galabov. |
5 | 6 |
|
6 | 7 | This library is free software; you can redistribute it and/or
|
7 | 8 | modify it under the terms of the GNU Lesser General Public
|
|
19 | 20 | */
|
20 | 21 |
|
21 | 22 | #include "WiFiClientSecure.h"
|
22 |
| -#include <lwip/sockets.h> |
23 |
| -#include <lwip/netdb.h> |
24 |
| -#include <errno.h> |
25 | 23 |
|
26 |
| -#undef connect |
27 |
| -#undef write |
28 |
| -#undef read |
29 |
| - |
30 |
| - |
31 |
| -WiFiClientSecure::WiFiClientSecure() |
| 24 | +WiFiClientSecure::WiFiClientSecure() : SSLClient() |
32 | 25 | {
|
33 |
| - _connected = false; |
34 |
| - |
35 |
| - sslclient = new sslclient_context; |
36 |
| - ssl_init(sslclient); |
37 |
| - sslclient->socket = -1; |
38 |
| - sslclient->handshake_timeout = 120000; |
39 |
| - _use_insecure = false; |
40 |
| - _CA_cert = NULL; |
41 |
| - _cert = NULL; |
42 |
| - _private_key = NULL; |
43 |
| - _pskIdent = NULL; |
44 |
| - _psKey = NULL; |
45 |
| - next = NULL; |
46 |
| - _alpn_protos = NULL; |
| 26 | + sslclient->client = new WiFiClient; |
47 | 27 | }
|
48 | 28 |
|
49 |
| - |
50 |
| -WiFiClientSecure::WiFiClientSecure(int sock) |
| 29 | +WiFiClientSecure::WiFiClientSecure(int fd) : SSLClient() |
51 | 30 | {
|
52 |
| - _connected = false; |
53 |
| - _timeout = 0; |
54 |
| - |
55 |
| - sslclient = new sslclient_context; |
56 |
| - ssl_init(sslclient); |
57 |
| - sslclient->socket = sock; |
58 |
| - sslclient->handshake_timeout = 120000; |
59 |
| - |
60 |
| - if (sock >= 0) { |
61 |
| - _connected = true; |
62 |
| - } |
63 |
| - |
64 |
| - _CA_cert = NULL; |
65 |
| - _cert = NULL; |
66 |
| - _private_key = NULL; |
67 |
| - _pskIdent = NULL; |
68 |
| - _psKey = NULL; |
69 |
| - next = NULL; |
70 |
| - _alpn_protos = NULL; |
| 31 | + sslclient->client = new WiFiClient(fd); |
71 | 32 | }
|
72 | 33 |
|
73 | 34 | WiFiClientSecure::~WiFiClientSecure()
|
74 | 35 | {
|
75 | 36 | stop();
|
76 |
| - delete sslclient; |
77 |
| -} |
78 |
| - |
79 |
| -WiFiClientSecure &WiFiClientSecure::operator=(const WiFiClientSecure &other) |
80 |
| -{ |
81 |
| - stop(); |
82 |
| - sslclient->socket = other.sslclient->socket; |
83 |
| - _connected = other._connected; |
84 |
| - return *this; |
85 |
| -} |
86 |
| - |
87 |
| -void WiFiClientSecure::stop() |
88 |
| -{ |
89 |
| - if (sslclient->socket >= 0) { |
90 |
| - close(sslclient->socket); |
91 |
| - sslclient->socket = -1; |
92 |
| - _connected = false; |
93 |
| - _peek = -1; |
94 |
| - } |
95 |
| - stop_ssl_socket(sslclient, _CA_cert, _cert, _private_key); |
96 |
| -} |
97 |
| - |
98 |
| -int WiFiClientSecure::connect(IPAddress ip, uint16_t port) |
99 |
| -{ |
100 |
| - if (_pskIdent && _psKey) |
101 |
| - return connect(ip, port, _pskIdent, _psKey); |
102 |
| - return connect(ip, port, _CA_cert, _cert, _private_key); |
103 |
| -} |
104 |
| - |
105 |
| -int WiFiClientSecure::connect(IPAddress ip, uint16_t port, int32_t timeout){ |
106 |
| - _timeout = timeout; |
107 |
| - return connect(ip, port); |
108 |
| -} |
109 |
| - |
110 |
| -int WiFiClientSecure::connect(const char *host, uint16_t port) |
111 |
| -{ |
112 |
| - if (_pskIdent && _psKey) |
113 |
| - return connect(host, port, _pskIdent, _psKey); |
114 |
| - return connect(host, port, _CA_cert, _cert, _private_key); |
115 |
| -} |
116 |
| - |
117 |
| -int WiFiClientSecure::connect(const char *host, uint16_t port, int32_t timeout){ |
118 |
| - _timeout = timeout; |
119 |
| - return connect(host, port); |
120 |
| -} |
121 |
| - |
122 |
| -int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *CA_cert, const char *cert, const char *private_key) |
123 |
| -{ |
124 |
| - return connect(ip.toString().c_str(), port, CA_cert, cert, private_key); |
125 |
| -} |
126 |
| - |
127 |
| -int WiFiClientSecure::connect(const char *host, uint16_t port, const char *CA_cert, const char *cert, const char *private_key) |
128 |
| -{ |
129 |
| - if(_timeout > 0){ |
130 |
| - sslclient->handshake_timeout = _timeout; |
131 |
| - } |
132 |
| - int ret = start_ssl_client(sslclient, host, port, _timeout, CA_cert, cert, private_key, NULL, NULL, _use_insecure, _alpn_protos); |
133 |
| - _lastError = ret; |
134 |
| - if (ret < 0) { |
135 |
| - log_e("start_ssl_client: %d", ret); |
136 |
| - stop(); |
137 |
| - return 0; |
138 |
| - } |
139 |
| - _connected = true; |
140 |
| - return 1; |
141 |
| -} |
142 |
| - |
143 |
| -int WiFiClientSecure::connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psKey) { |
144 |
| - return connect(ip.toString().c_str(), port, pskIdent, psKey); |
145 |
| -} |
146 |
| - |
147 |
| -int WiFiClientSecure::connect(const char *host, uint16_t port, const char *pskIdent, const char *psKey) { |
148 |
| - log_v("start_ssl_client with PSK"); |
149 |
| - if(_timeout > 0){ |
150 |
| - sslclient->handshake_timeout = _timeout; |
151 |
| - } |
152 |
| - int ret = start_ssl_client(sslclient, host, port, _timeout, NULL, NULL, NULL, pskIdent, psKey, _use_insecure, _alpn_protos); |
153 |
| - _lastError = ret; |
154 |
| - if (ret < 0) { |
155 |
| - log_e("start_ssl_client: %d", ret); |
156 |
| - stop(); |
157 |
| - return 0; |
158 |
| - } |
159 |
| - _connected = true; |
160 |
| - return 1; |
161 |
| -} |
162 |
| - |
163 |
| -int WiFiClientSecure::peek(){ |
164 |
| - if(_peek >= 0){ |
165 |
| - return _peek; |
166 |
| - } |
167 |
| - _peek = timedRead(); |
168 |
| - return _peek; |
169 |
| -} |
170 |
| - |
171 |
| -size_t WiFiClientSecure::write(uint8_t data) |
172 |
| -{ |
173 |
| - return write(&data, 1); |
174 |
| -} |
175 |
| - |
176 |
| -int WiFiClientSecure::read() |
177 |
| -{ |
178 |
| - uint8_t data = -1; |
179 |
| - int res = read(&data, 1); |
180 |
| - if (res < 0) { |
181 |
| - return res; |
182 |
| - } |
183 |
| - return data; |
184 |
| -} |
185 |
| - |
186 |
| -size_t WiFiClientSecure::write(const uint8_t *buf, size_t size) |
187 |
| -{ |
188 |
| - if (!_connected) { |
189 |
| - return 0; |
190 |
| - } |
191 |
| - int res = send_ssl_data(sslclient, buf, size); |
192 |
| - if (res < 0) { |
193 |
| - stop(); |
194 |
| - res = 0; |
195 |
| - } |
196 |
| - return res; |
197 |
| -} |
198 |
| - |
199 |
| -int WiFiClientSecure::read(uint8_t *buf, size_t size) |
200 |
| -{ |
201 |
| - int peeked = 0; |
202 |
| - int avail = available(); |
203 |
| - if ((!buf && size) || avail <= 0) { |
204 |
| - return -1; |
205 |
| - } |
206 |
| - if(!size){ |
207 |
| - return 0; |
208 |
| - } |
209 |
| - if(_peek >= 0){ |
210 |
| - buf[0] = _peek; |
211 |
| - _peek = -1; |
212 |
| - size--; |
213 |
| - avail--; |
214 |
| - if(!size || !avail){ |
215 |
| - return 1; |
216 |
| - } |
217 |
| - buf++; |
218 |
| - peeked = 1; |
219 |
| - } |
220 |
| - |
221 |
| - int res = get_ssl_receive(sslclient, buf, size); |
222 |
| - if (res < 0) { |
223 |
| - stop(); |
224 |
| - return peeked?peeked:res; |
225 |
| - } |
226 |
| - return res + peeked; |
227 |
| -} |
228 |
| - |
229 |
| -int WiFiClientSecure::available() |
230 |
| -{ |
231 |
| - int peeked = (_peek >= 0); |
232 |
| - if (!_connected) { |
233 |
| - return peeked; |
234 |
| - } |
235 |
| - int res = data_to_read(sslclient); |
236 |
| - if (res < 0) { |
237 |
| - stop(); |
238 |
| - return peeked?peeked:res; |
239 |
| - } |
240 |
| - return res+peeked; |
241 |
| -} |
242 |
| - |
243 |
| -uint8_t WiFiClientSecure::connected() |
244 |
| -{ |
245 |
| - uint8_t dummy = 0; |
246 |
| - read(&dummy, 0); |
247 |
| - |
248 |
| - return _connected; |
249 |
| -} |
250 |
| - |
251 |
| -void WiFiClientSecure::setInsecure() |
252 |
| -{ |
253 |
| - _CA_cert = NULL; |
254 |
| - _cert = NULL; |
255 |
| - _private_key = NULL; |
256 |
| - _pskIdent = NULL; |
257 |
| - _psKey = NULL; |
258 |
| - _use_insecure = true; |
259 |
| -} |
260 |
| - |
261 |
| -void WiFiClientSecure::setCACert (const char *rootCA) |
262 |
| -{ |
263 |
| - _CA_cert = rootCA; |
264 |
| -} |
265 |
| - |
266 |
| -void WiFiClientSecure::setCertificate (const char *client_ca) |
267 |
| -{ |
268 |
| - _cert = client_ca; |
269 |
| -} |
270 |
| - |
271 |
| -void WiFiClientSecure::setPrivateKey (const char *private_key) |
272 |
| -{ |
273 |
| - _private_key = private_key; |
274 |
| -} |
275 |
| - |
276 |
| -void WiFiClientSecure::setPreSharedKey(const char *pskIdent, const char *psKey) { |
277 |
| - _pskIdent = pskIdent; |
278 |
| - _psKey = psKey; |
279 |
| -} |
280 |
| - |
281 |
| -bool WiFiClientSecure::verify(const char* fp, const char* domain_name) |
282 |
| -{ |
283 |
| - if (!sslclient) |
284 |
| - return false; |
285 |
| - |
286 |
| - return verify_ssl_fingerprint(sslclient, fp, domain_name); |
287 |
| -} |
288 |
| - |
289 |
| -char *WiFiClientSecure::_streamLoad(Stream& stream, size_t size) { |
290 |
| - char *dest = (char*)malloc(size+1); |
291 |
| - if (!dest) { |
292 |
| - return nullptr; |
293 |
| - } |
294 |
| - if (size != stream.readBytes(dest, size)) { |
295 |
| - free(dest); |
296 |
| - dest = nullptr; |
297 |
| - return nullptr; |
298 |
| - } |
299 |
| - dest[size] = '\0'; |
300 |
| - return dest; |
301 |
| -} |
302 |
| - |
303 |
| -bool WiFiClientSecure::loadCACert(Stream& stream, size_t size) { |
304 |
| - char *dest = _streamLoad(stream, size); |
305 |
| - bool ret = false; |
306 |
| - if (dest) { |
307 |
| - setCACert(dest); |
308 |
| - ret = true; |
309 |
| - } |
310 |
| - return ret; |
311 |
| -} |
312 |
| - |
313 |
| -bool WiFiClientSecure::loadCertificate(Stream& stream, size_t size) { |
314 |
| - char *dest = _streamLoad(stream, size); |
315 |
| - bool ret = false; |
316 |
| - if (dest) { |
317 |
| - setCertificate(dest); |
318 |
| - ret = true; |
319 |
| - } |
320 |
| - return ret; |
321 |
| -} |
322 |
| - |
323 |
| -bool WiFiClientSecure::loadPrivateKey(Stream& stream, size_t size) { |
324 |
| - char *dest = _streamLoad(stream, size); |
325 |
| - bool ret = false; |
326 |
| - if (dest) { |
327 |
| - setPrivateKey(dest); |
328 |
| - ret = true; |
329 |
| - } |
330 |
| - return ret; |
331 |
| -} |
332 |
| - |
333 |
| -int WiFiClientSecure::lastError(char *buf, const size_t size) |
334 |
| -{ |
335 |
| - if (!_lastError) { |
336 |
| - return 0; |
337 |
| - } |
338 |
| - mbedtls_strerror(_lastError, buf, size); |
339 |
| - return _lastError; |
340 |
| -} |
341 |
| - |
342 |
| -void WiFiClientSecure::setHandshakeTimeout(unsigned long handshake_timeout) |
343 |
| -{ |
344 |
| - sslclient->handshake_timeout = handshake_timeout * 1000; |
345 |
| -} |
346 |
| - |
347 |
| -void WiFiClientSecure::setAlpnProtocols(const char **alpn_protos) |
348 |
| -{ |
349 |
| - _alpn_protos = alpn_protos; |
| 37 | + if (sslclient->client != nullptr) |
| 38 | + delete sslclient->client; |
350 | 39 | }
|
0 commit comments