|
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