Skip to content

Commit d37e476

Browse files
committed
Commit fhessel#169 for ESP TLS IDFv5
1 parent 4df47fd commit d37e476

9 files changed

+72
-107
lines changed

Diff for: src/ConnectionContext.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
#include <Arduino.h>
55
#include <IPAddress.h>
66

7+
/* Openssl removed from IDF V5, move to esp_tls.h
78
// Required for SSL
89
#include "openssl/ssl.h"
910
#undef read
11+
*/
12+
#include <esp_tls.h>
1013

1114
namespace httpsserver {
1215

Diff for: src/HTTPConnection.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ void handleWebsocketHandshake(HTTPRequest * req, HTTPResponse * res) {
675675
std::string websocketKeyResponseHash(std::string const &key) {
676676
std::string newKey = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
677677
uint8_t shaData[HTTPS_SHA1_LENGTH];
678-
esp_sha(SHA1, (uint8_t*)newKey.data(), newKey.length(), shaData);
678+
mbedtls_sha1_ret((uint8_t*)newKey.data(), newKey.length(), shaData);
679679

680680
// Get output size required for base64 representation
681681
size_t b64BufferSize = 0;

Diff for: src/HTTPConnection.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//#include <hwcrypto/sha.h>
1010
#include <sha/sha_parallel_engine.h> // For use with IDF4.4
1111
//#include <esp32/sha.h> // Deprecated
12+
//#include <mbedtls/sha1.h> //TODO Use instead of sha/sha_parallel_engine.h ?
1213

1314
#include <functional>
1415

Diff for: src/HTTPResponse.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
#undef write
1010
#include <vector>
1111

12-
#include <openssl/ssl.h>
12+
// #include <openssl/ssl.h> //Deprecated w.e.f IDF v5
13+
#include <esp_tls.h>
1314

1415
#include "util.hpp"
1516

Diff for: src/HTTPSConnection.cpp

+25-43
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace httpsserver {
55

66
HTTPSConnection::HTTPSConnection(ResourceResolver * resResolver):
77
HTTPConnection(resResolver) {
8-
_ssl = NULL;
8+
_ssl = esp_tls_init();
99
}
1010

1111
HTTPSConnection::~HTTPSConnection() {
@@ -22,36 +22,30 @@ bool HTTPSConnection::isSecure() {
2222
*
2323
* The call WILL BLOCK if accept(serverSocketID) blocks. So use select() to check for that in advance.
2424
*/
25-
int HTTPSConnection::initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeaders *defaultHeaders) {
25+
int HTTPSConnection::initialize(int serverSocketID, esp_tls_cfg_server_t * cfgSrv, HTTPHeaders *defaultHeaders) {
2626
if (_connectionState == STATE_UNDEFINED) {
2727
// Let the base class connect the plain tcp socket
2828
int resSocket = HTTPConnection::initialize(serverSocketID, defaultHeaders);
29-
29+
HTTPS_LOGI("Cert len:%d, apn:%s\n",cfgSrv->servercert_bytes,cfgSrv->alpn_protos[0]);
3030
// Build up SSL Connection context if the socket has been created successfully
3131
if (resSocket >= 0) {
32-
33-
_ssl = SSL_new(sslCtx);
34-
35-
if (_ssl) {
32+
int res=esp_tls_server_session_create(cfgSrv,resSocket,_ssl);
33+
if (0==res) {
34+
esp_tls_cfg_server_session_tickets_init(cfgSrv);
35+
_cfg = cfgSrv;
3636
// Bind SSL to the socket
37-
int success = SSL_set_fd(_ssl, resSocket);
38-
if (success) {
39-
40-
// Perform the handshake
41-
success = SSL_accept(_ssl);
42-
if (success) {
43-
return resSocket;
44-
} else {
45-
HTTPS_LOGE("SSL_accept failed. Aborting handshake. FID=%d", resSocket);
46-
}
47-
} else {
48-
HTTPS_LOGE("SSL_set_fd failed. Aborting handshake. FID=%d", resSocket);
37+
if (ESP_OK == esp_tls_get_conn_sockfd(_ssl,&resSocket)) {
38+
return resSocket;
39+
}
40+
else {
41+
HTTPS_LOGE("SSL_accept failed. Aborting handshake. FID=%d", resSocket);
4942
}
50-
} else {
51-
HTTPS_LOGE("SSL_new failed. Aborting handshake. FID=%d", resSocket);
43+
}
44+
else {
45+
HTTPS_LOGE("SSL_new failed. Aborting handshake. Error=%d", res);
5246
}
53-
54-
} else {
47+
}
48+
else {
5549
HTTPS_LOGE("Could not accept() new connection. FID=%d", resSocket);
5650
}
5751

@@ -66,9 +60,7 @@ int HTTPSConnection::initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeader
6660
return -1;
6761
}
6862

69-
7063
void HTTPSConnection::closeConnection() {
71-
7264
// FIXME: Copy from HTTPConnection, could be done better probably
7365
if (_connectionState != STATE_ERROR && _connectionState != STATE_CLOSED) {
7466

@@ -81,47 +73,37 @@ void HTTPSConnection::closeConnection() {
8173
// correctly
8274
_connectionState = STATE_CLOSING;
8375
}
84-
8576
// Try to tear down SSL while we are in the _shutdownTS timeout period or if an error occurred
8677
if (_ssl) {
87-
if(_connectionState == STATE_ERROR || SSL_shutdown(_ssl) == 0) {
88-
// SSL_shutdown will return 1 as soon as the client answered with close notify
89-
// This means we are safe to close the socket
90-
SSL_free(_ssl);
91-
_ssl = NULL;
92-
} else if (_shutdownTS + HTTPS_SHUTDOWN_TIMEOUT < millis()) {
93-
// The timeout has been hit, we force SSL shutdown now by freeing the context
94-
SSL_free(_ssl);
95-
_ssl = NULL;
96-
HTTPS_LOGW("SSL_shutdown did not receive close notification from the client");
97-
_connectionState = STATE_ERROR;
98-
}
78+
esp_tls_cfg_server_session_tickets_free(_cfg);
79+
esp_tls_server_session_delete(_ssl);
80+
_ssl = NULL;
81+
_connectionState = STATE_ERROR;
9982
}
100-
10183
// If SSL has been brought down, close the socket
10284
if (!_ssl) {
10385
HTTPConnection::closeConnection();
10486
}
10587
}
10688

10789
size_t HTTPSConnection::writeBuffer(byte* buffer, size_t length) {
108-
return SSL_write(_ssl, buffer, length);
90+
return esp_tls_conn_write(_ssl,buffer,length);
10991
}
11092

11193
size_t HTTPSConnection::readBytesToBuffer(byte* buffer, size_t length) {
112-
int ret = SSL_read(_ssl, buffer, length);
94+
int ret = esp_tls_conn_read(_ssl, buffer, length);
11395
if (ret < 0) {
11496
HTTPS_LOGD("SSL_read error: %d", SSL_get_error(_ssl, ret));
11597
}
11698
return ret;
11799
}
118100

119101
size_t HTTPSConnection::pendingByteCount() {
120-
return SSL_pending(_ssl);
102+
return esp_tls_get_bytes_avail(_ssl);
121103
}
122104

123105
bool HTTPSConnection::canReadData() {
124-
return HTTPConnection::canReadData() || (SSL_pending(_ssl) > 0);
106+
return HTTPConnection::canReadData() || (esp_tls_get_bytes_avail(_ssl) > 0);
125107
}
126108

127109
} /* namespace httpsserver */

Diff for: src/HTTPSConnection.hpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55

66
#include <string>
77

8+
/* OpenSSL Depracation in IDF v5
89
// Required for SSL
910
#include "openssl/ssl.h"
1011
#undef read
12+
*/
13+
#include <esp_tls.h>
1114

1215
// Required for sockets
1316
#include "lwip/netdb.h"
@@ -34,7 +37,7 @@ class HTTPSConnection : public HTTPConnection {
3437
HTTPSConnection(ResourceResolver * resResolver);
3538
virtual ~HTTPSConnection();
3639

37-
virtual int initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeaders *defaultHeaders);
40+
virtual int initialize(int serverSocketID,esp_tls_cfg_server_t * cfgSrv, HTTPHeaders *defaultHeaders);
3841
virtual void closeConnection();
3942
virtual bool isSecure();
4043

@@ -49,7 +52,8 @@ class HTTPSConnection : public HTTPConnection {
4952

5053
private:
5154
// SSL context for this connection
52-
SSL * _ssl;
55+
esp_tls_t * _ssl;
56+
esp_tls_cfg_server_t * _cfg;
5357

5458
};
5559

Diff for: src/HTTPSServer.cpp

+24-56
Original file line numberDiff line numberDiff line change
@@ -2,77 +2,56 @@
22

33
namespace httpsserver {
44

5+
constexpr const char * alpn_protos[] = { "http/1.1", NULL } ;
56

67
HTTPSServer::HTTPSServer(SSLCert * cert, const uint16_t port, const uint8_t maxConnections, const in_addr_t bindAddress):
78
HTTPServer(port, maxConnections, bindAddress),
89
_cert(cert) {
9-
1010
// Configure runtime data
11-
_sslctx = NULL;
11+
_cfg = new esp_tls_cfg_server();
12+
_cfg->alpn_protos = (const char **)alpn_protos;
13+
_cfg->cacert_buf = NULL;
14+
_cfg->cacert_bytes = 0;
15+
_cfg->servercert_buf =cert->getCertData();
16+
_cfg->servercert_bytes = cert->getCertLength();
17+
_cfg->serverkey_buf= cert->getPKData();
18+
_cfg->serverkey_bytes= cert->getPKLength();
1219
}
1320

1421
HTTPSServer::~HTTPSServer() {
15-
22+
free(_cfg);
1623
}
1724

1825
/**
1926
* This method starts the server and begins to listen on the port
2027
*/
2128
uint8_t HTTPSServer::setupSocket() {
2229
if (!isRunning()) {
23-
if (!setupSSLCTX()) {
24-
Serial.println("setupSSLCTX failed");
25-
return 0;
26-
}
27-
28-
if (!setupCert()) {
29-
Serial.println("setupCert failed");
30-
SSL_CTX_free(_sslctx);
31-
_sslctx = NULL;
32-
return 0;
33-
}
34-
30+
_cfg->servercert_buf= _cert->getCertData();
31+
_cfg->servercert_bytes = _cert->getCertLength();
32+
_cfg->serverkey_buf= _cert->getPKData();
33+
_cfg->serverkey_bytes= _cert->getPKLength();
3534
if (HTTPServer::setupSocket()) {
3635
return 1;
37-
} else {
36+
}
37+
else {
3838
Serial.println("setupSockets failed");
39-
SSL_CTX_free(_sslctx);
40-
_sslctx = NULL;
4139
return 0;
4240
}
43-
} else {
41+
}
42+
else {
4443
return 1;
4544
}
4645
}
4746

4847
void HTTPSServer::teardownSocket() {
49-
5048
HTTPServer::teardownSocket();
51-
52-
// Tear down the SSL context
53-
SSL_CTX_free(_sslctx);
54-
_sslctx = NULL;
5549
}
5650

5751
int HTTPSServer::createConnection(int idx) {
5852
HTTPSConnection * newConnection = new HTTPSConnection(this);
5953
_connections[idx] = newConnection;
60-
return newConnection->initialize(_socket, _sslctx, &_defaultHeaders);
61-
}
62-
63-
/**
64-
* This method configures the ssl context that is used for the server
65-
*/
66-
uint8_t HTTPSServer::setupSSLCTX() {
67-
_sslctx = SSL_CTX_new(TLSv1_2_server_method());
68-
if (_sslctx) {
69-
// Set SSL Timeout to 5 minutes
70-
SSL_CTX_set_timeout(_sslctx, 300);
71-
return 1;
72-
} else {
73-
_sslctx = NULL;
74-
return 0;
75-
}
54+
return newConnection->initialize(_socket, _cfg, &_defaultHeaders);
7655
}
7756

7857
/**
@@ -81,22 +60,11 @@ uint8_t HTTPSServer::setupSSLCTX() {
8160
*/
8261
uint8_t HTTPSServer::setupCert() {
8362
// Configure the certificate first
84-
uint8_t ret = SSL_CTX_use_certificate_ASN1(
85-
_sslctx,
86-
_cert->getCertLength(),
87-
_cert->getCertData()
88-
);
89-
90-
// Then set the private key accordingly
91-
if (ret) {
92-
ret = SSL_CTX_use_RSAPrivateKey_ASN1(
93-
_sslctx,
94-
_cert->getPKData(),
95-
_cert->getPKLength()
96-
);
63+
_cfg->servercert_buf= _cert->getCertData();
64+
_cfg->servercert_bytes = _cert->getCertLength();
65+
_cfg->serverkey_buf= _cert->getPKData();
66+
_cfg->serverkey_bytes= _cert->getPKLength();
67+
return 1;
9768
}
9869

99-
return ret;
100-
}
101-
10270
} /* namespace httpsserver */

Diff for: src/HTTPSServer.hpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77
// Arduino stuff
88
#include <Arduino.h>
99

10+
/* OpenSSL wrapper depracated in IDF v5
1011
// Required for SSL
1112
#include "openssl/ssl.h"
1213
#undef read
14+
*/
15+
#include <esp_tls.h>
1316

1417
// Internal includes
1518
#include "HTTPServer.hpp"
@@ -31,14 +34,14 @@ class HTTPSServer : public HTTPServer {
3134
public:
3235
HTTPSServer(SSLCert * cert, const uint16_t portHTTPS = 443, const uint8_t maxConnections = 4, const in_addr_t bindAddress = 0);
3336
virtual ~HTTPSServer();
34-
37+
virtual esp_tls_cfg_server_t *getConfig() {return _cfg;}
3538
private:
3639
// Static configuration. Port, keys, etc. ====================
3740
// Certificate that should be used (includes private key)
3841
SSLCert * _cert;
3942

4043
//// Runtime data ============================================
41-
SSL_CTX * _sslctx;
44+
esp_tls_cfg_server_t * _cfg;
4245
// Status of the server: Are we running, or not?
4346

4447
// Setup functions

Diff for: src/WebsocketHandler.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#include "WebsocketHandler.hpp"
22

3+
#ifndef TAG
4+
static const char *TAG = "WebsocketHandler";
5+
#endif
6+
37
namespace httpsserver {
48

59
/**
@@ -16,7 +20,7 @@ static void dumpFrame(WebsocketFrame frame) {
1620
case WebsocketHandler::OPCODE_PONG: opcode = std::string("PONG"); break;
1721
case WebsocketHandler::OPCODE_TEXT: opcode = std::string("TEXT"); break;
1822
}
19-
/* Commenting logging function to resolve compilation
23+
Commenting logging function to resolve compilation
2024
ESP_LOGI(
2125
TAG,
2226
"Fin: %d, OpCode: %d (%s), Mask: %d, Len: %d",
@@ -26,7 +30,6 @@ static void dumpFrame(WebsocketFrame frame) {
2630
(int)frame.mask,
2731
(int)frame.len
2832
);
29-
*/
3033
}
3134

3235
WebsocketHandler::WebsocketHandler() {

0 commit comments

Comments
 (0)