Skip to content

Commit eba412b

Browse files
committed
Add axTLS, first draft of WiFiClientSecure (#43)
1 parent 9f2f2f4 commit eba412b

File tree

7 files changed

+850
-11
lines changed

7 files changed

+850
-11
lines changed

hardware/esp8266com/esp8266/cores/esp8266/libc_replacements.c

+27-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
/*
1+
/*
22
libc_replacements.c - replaces libc functions with functions
33
from Espressif SDK
44
55
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
66
This file is part of the esp8266 core for Arduino environment.
7-
7+
88
This library is free software; you can redistribute it and/or
99
modify it under the terms of the GNU Lesser General Public
1010
License as published by the Free Software Foundation; either
@@ -83,6 +83,10 @@ int snprintf(char* buffer, size_t size, const char* format, ...) {
8383
return ret;
8484
}
8585

86+
int vprintf(const char * format, va_list arg) {
87+
return ets_vprintf(format, arg);
88+
}
89+
8690
int vsnprintf(char * buffer, size_t size, const char * format, va_list arg) {
8791
return ets_vsnprintf(buffer, size, format, arg);
8892
}
@@ -144,7 +148,7 @@ char* ICACHE_FLASH_ATTR strtok_r(char* s, const char* delim, char** last) {
144148
}
145149

146150

147-
// Skip (span) leading delimiters
151+
// Skip (span) leading delimiters
148152
//
149153
cont:
150154
c = *s++;
@@ -164,7 +168,7 @@ char* ICACHE_FLASH_ATTR strtok_r(char* s, const char* delim, char** last) {
164168
tok = s - 1;
165169

166170

167-
// Scan token
171+
// Scan token
168172
// Note that delim must have one NUL; we stop if we see that, too.
169173
//
170174
for (;;) {
@@ -384,14 +388,31 @@ int isblank(int c) {
384388
static int errno_var = 0;
385389

386390
int* ICACHE_FLASH_ATTR __errno(void) {
387-
DEBUGV("__errno is called last error: %d (not current)\n", errno_var);
391+
// DEBUGV("__errno is called last error: %d (not current)\n", errno_var);
388392
return &errno_var;
389393
}
390394

391395

396+
char * ctime(const time_t *clock) {
397+
return 0;
398+
}
399+
400+
time_t time(time_t * t) {
401+
return 0;
402+
}
403+
404+
int gettimeofday(void *tp, void *tzp) {
405+
return 0;
406+
}
407+
408+
time_t mktime(struct tm *timp) {
409+
return 0;
410+
}
411+
412+
392413
/*
393414
* begin newlib/string/strlcpy.c
394-
*
415+
*
395416
* Copyright (c) 1998 Todd C. Miller <[email protected]>
396417
* All rights reserved.
397418
*

hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
#ifndef wificlient_h
2323
#define wificlient_h
24-
#include "Arduino.h"
24+
#include "Arduino.h"
2525
#include "Print.h"
2626
#include "Client.h"
2727
#include "IPAddress.h"
@@ -74,7 +74,7 @@ class WiFiClient : public Client, public SList<WiFiClient> {
7474
size_t doneLen = 0;
7575
size_t sentLen;
7676
int i;
77-
77+
7878
while (src.available() > WIFICLIENT_MAX_PACKET_SIZE){
7979
src.read(obuf, WIFICLIENT_MAX_PACKET_SIZE);
8080
sentLen = write(obuf, WIFICLIENT_MAX_PACKET_SIZE);
@@ -83,7 +83,7 @@ class WiFiClient : public Client, public SList<WiFiClient> {
8383
return doneLen;
8484
}
8585
}
86-
86+
8787
uint16_t leftLen = src.available();
8888
src.read(obuf, leftLen);
8989
sentLen = write(obuf, leftLen);
@@ -98,7 +98,7 @@ class WiFiClient : public Client, public SList<WiFiClient> {
9898
static void stopAll();
9999
static void stopAllExcept(WiFiClient * c);
100100

101-
private:
101+
protected:
102102

103103
static int8_t _s_connected(void* arg, void* tpcb, int8_t err);
104104
static void _s_err(void* arg, int8_t err);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
/*
2+
WiFiClientSecure.cpp - Variant of WiFiClient with TLS support
3+
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
4+
This file is part of the esp8266 core for Arduino environment.
5+
6+
7+
This library is free software; you can redistribute it and/or
8+
modify it under the terms of the GNU Lesser General Public
9+
License as published by the Free Software Foundation; either
10+
version 2.1 of the License, or (at your option) any later version.
11+
12+
This library is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
Lesser General Public License for more details.
16+
17+
You should have received a copy of the GNU Lesser General Public
18+
License along with this library; if not, write to the Free Software
19+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20+
21+
*/
22+
23+
#define LWIP_INTERNAL
24+
25+
extern "C"
26+
{
27+
#include "osapi.h"
28+
#include "ets_sys.h"
29+
}
30+
#include <errno.h>
31+
#include "debug.h"
32+
#include "ESP8266WiFi.h"
33+
#include "WiFiClientSecure.h"
34+
#include "WiFiClient.h"
35+
#include "lwip/opt.h"
36+
#include "lwip/ip.h"
37+
#include "lwip/tcp.h"
38+
#include "lwip/inet.h"
39+
#include "lwip/netif.h"
40+
#include "cbuf.h"
41+
#include "include/ClientContext.h"
42+
#include "c_types.h"
43+
44+
45+
class SSLContext {
46+
public:
47+
SSLContext() {
48+
if (_ssl_ctx_refcnt == 0) {
49+
_ssl_ctx = ssl_ctx_new(SSL_SERVER_VERIFY_LATER | SSL_DISPLAY_STATES, 0);
50+
}
51+
++_ssl_ctx_refcnt;
52+
53+
}
54+
55+
~SSLContext() {
56+
if (_ssl) {
57+
ssl_free(_ssl);
58+
_ssl = nullptr;
59+
}
60+
61+
--_ssl_ctx_refcnt;
62+
if (_ssl_ctx_refcnt == 0) {
63+
ssl_ctx_free(_ssl_ctx);
64+
}
65+
}
66+
67+
void ref() {
68+
++_refcnt;
69+
}
70+
71+
void unref() {
72+
if (--_refcnt == 0) {
73+
delete this;
74+
}
75+
}
76+
77+
void connect(ClientContext* ctx) {
78+
_ssl = ssl_client_new(_ssl_ctx, reinterpret_cast<int>(ctx), nullptr, 0);
79+
}
80+
81+
operator SSL*() {
82+
return _ssl;
83+
}
84+
85+
protected:
86+
static SSL_CTX* _ssl_ctx;
87+
static int _ssl_ctx_refcnt;
88+
SSL* _ssl = nullptr;
89+
int _refcnt = 0;
90+
};
91+
92+
SSL_CTX* SSLContext::_ssl_ctx = nullptr;
93+
int SSLContext::_ssl_ctx_refcnt = 0;
94+
95+
96+
WiFiClientSecure::WiFiClientSecure()
97+
{
98+
}
99+
100+
WiFiClientSecure::~WiFiClientSecure()
101+
{
102+
if (_ssl) {
103+
_ssl->unref();
104+
}
105+
}
106+
107+
WiFiClientSecure::WiFiClientSecure(const WiFiClientSecure& other)
108+
: WiFiClient(static_cast<const WiFiClient&>(other))
109+
{
110+
_ssl = other._ssl;
111+
if (_ssl) {
112+
_ssl->ref();
113+
}
114+
}
115+
116+
WiFiClientSecure& WiFiClientSecure::operator=(const WiFiClientSecure& rhs) {
117+
(WiFiClient&) *this = rhs;
118+
_ssl = rhs._ssl;
119+
if (_ssl) {
120+
_ssl->ref();
121+
}
122+
return *this;
123+
}
124+
125+
int WiFiClientSecure::connect(IPAddress ip, uint16_t port) {
126+
if (!WiFiClient::connect(ip, port))
127+
return 0;
128+
129+
return _connectSSL();
130+
}
131+
132+
int WiFiClientSecure::connect(const char* name, uint16_t port) {
133+
if (!WiFiClient::connect(name, port))
134+
return 0;
135+
return 1;
136+
}
137+
138+
int WiFiClientSecure::_connectSSL() {
139+
if (_ssl) {
140+
_ssl->unref();
141+
_ssl = nullptr;
142+
}
143+
144+
_ssl = new SSLContext;
145+
_ssl->ref();
146+
_ssl->connect(_client);
147+
148+
auto status = ssl_handshake_status(*_ssl);
149+
if (status != SSL_OK) {
150+
_ssl->unref();
151+
_ssl = nullptr;
152+
return 0;
153+
}
154+
155+
return 1;
156+
}
157+
158+
size_t WiFiClientSecure::write(const uint8_t *buf, size_t size) {
159+
int rc = ssl_write(*_ssl, buf, size);
160+
if (rc >= 0)
161+
return rc;
162+
163+
return 0;
164+
}
165+
166+
int WiFiClientSecure::read(uint8_t *buf, size_t size) {
167+
168+
uint8_t* data;
169+
int rc = ssl_read(*_ssl, &data);
170+
if (rc <= 0)
171+
return 0;
172+
173+
memcpy(buf, data, rc);
174+
return rc;
175+
}
176+
177+
void WiFiClientSecure::stop() {
178+
if (_ssl) {
179+
_ssl->unref();
180+
_ssl = nullptr;
181+
}
182+
return WiFiClient::stop();
183+
}
184+
185+
extern "C" int ax_port_read(int fd, uint8_t* buffer, size_t count) {
186+
ClientContext* _client = reinterpret_cast<ClientContext*>(fd);
187+
if (_client->state() != ESTABLISHED && !_client->getSize()) {
188+
return -1;
189+
errno = EIO;
190+
}
191+
size_t cb = _client->read((char*) buffer, count);
192+
if (cb != count) {
193+
errno = EAGAIN;
194+
}
195+
if (cb == 0) {
196+
yield();
197+
return -1;
198+
}
199+
return cb;
200+
}
201+
202+
extern "C" int ax_port_write(int fd, uint8_t* buffer, size_t count) {
203+
ClientContext* _client = reinterpret_cast<ClientContext*>(fd);
204+
if (_client->state() != ESTABLISHED) {
205+
errno = EIO;
206+
return -1;
207+
}
208+
size_t cb = _client->write((const char*) buffer, count);
209+
if (cb != count) {
210+
errno = EAGAIN;
211+
}
212+
return cb;
213+
}
214+
215+
extern "C" int ax_get_file(const char *filename, uint8_t **buf) {
216+
*buf = 0;
217+
return 0;
218+
}
219+
220+
#ifdef DEBUG_TLS_MEM
221+
#define DEBUG_TLS_MEM_PRINT(...) DEBUGV(__VA_ARGS__)
222+
#else
223+
#define DEBUG_TLS_MEM_PRINT(...)
224+
#endif
225+
226+
227+
extern "C" void* ax_port_malloc(size_t size, const char* file, int line) {
228+
void* result = malloc(size);
229+
230+
if (result == nullptr) {
231+
DEBUG_TLS_MEM_PRINT("%s:%d malloc %d failed, left %d\r\n", file, line, size, ESP.getFreeHeap());
232+
233+
while(true){}
234+
}
235+
if (size >= 1024)
236+
DEBUG_TLS_MEM_PRINT("%s:%d malloc %d, left %d\r\n", file, line, size, ESP.getFreeHeap());
237+
return result;
238+
}
239+
240+
extern "C" void* ax_port_calloc(size_t size, size_t count, const char* file, int line) {
241+
void* result = ax_port_malloc(size * count, file, line);
242+
memset(result, 0, size * count);
243+
return result;
244+
}
245+
246+
extern "C" void* ax_port_realloc(void* ptr, size_t size, const char* file, int line) {
247+
void* result = realloc(ptr, size);
248+
if (result == nullptr) {
249+
DEBUG_TLS_MEM_PRINT("%s:%d realloc %d failed, left %d\r\n", file, line, size, ESP.getFreeHeap());
250+
while(true){}
251+
}
252+
if (size >= 1024)
253+
DEBUG_TLS_MEM_PRINT("%s:%d realloc %d, left %d\r\n", file, line, size, ESP.getFreeHeap());
254+
return result;
255+
}
256+
257+
258+
extern "C" void ax_port_free(void* ptr) {
259+
free(ptr);
260+
uint32_t *p = (uint32_t*) ptr;
261+
size_t size = p[-3];
262+
if (size >= 1024)
263+
DEBUG_TLS_MEM_PRINT("free %d, left %d\r\n", p[-3], ESP.getFreeHeap());
264+
}

0 commit comments

Comments
 (0)