diff --git a/src/ConnectionContext.hpp b/src/ConnectionContext.hpp index da88964..807981c 100644 --- a/src/ConnectionContext.hpp +++ b/src/ConnectionContext.hpp @@ -4,9 +4,12 @@ #include #include +/* Openssl removed from IDF V5, move to esp_tls.h // Required for SSL #include "openssl/ssl.h" #undef read +*/ +#include namespace httpsserver { diff --git a/src/HTTPConnection.cpp b/src/HTTPConnection.cpp index 17452e0..1fb585c 100644 --- a/src/HTTPConnection.cpp +++ b/src/HTTPConnection.cpp @@ -675,7 +675,7 @@ void handleWebsocketHandshake(HTTPRequest * req, HTTPResponse * res) { std::string websocketKeyResponseHash(std::string const &key) { std::string newKey = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; uint8_t shaData[HTTPS_SHA1_LENGTH]; - esp_sha(SHA1, (uint8_t*)newKey.data(), newKey.length(), shaData); + mbedtls_sha1_ret((uint8_t*)newKey.data(), newKey.length(), shaData); // Get output size required for base64 representation size_t b64BufferSize = 0; diff --git a/src/HTTPConnection.hpp b/src/HTTPConnection.hpp index d59c082..e4bb98d 100644 --- a/src/HTTPConnection.hpp +++ b/src/HTTPConnection.hpp @@ -9,6 +9,7 @@ //#include #include // For use with IDF4.4 //#include // Deprecated +//#include //TODO Use instead of sha/sha_parallel_engine.h ? #include diff --git a/src/HTTPResponse.hpp b/src/HTTPResponse.hpp index 7bd1758..58211c9 100644 --- a/src/HTTPResponse.hpp +++ b/src/HTTPResponse.hpp @@ -9,7 +9,8 @@ #undef write #include -#include +// #include //Deprecated w.e.f IDF v5 +#include #include "util.hpp" diff --git a/src/HTTPSConnection.cpp b/src/HTTPSConnection.cpp index 5169ee6..356e22a 100644 --- a/src/HTTPSConnection.cpp +++ b/src/HTTPSConnection.cpp @@ -5,7 +5,7 @@ namespace httpsserver { HTTPSConnection::HTTPSConnection(ResourceResolver * resResolver): HTTPConnection(resResolver) { - _ssl = NULL; + _ssl = esp_tls_init(); } HTTPSConnection::~HTTPSConnection() { @@ -22,36 +22,30 @@ bool HTTPSConnection::isSecure() { * * The call WILL BLOCK if accept(serverSocketID) blocks. So use select() to check for that in advance. */ -int HTTPSConnection::initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeaders *defaultHeaders) { +int HTTPSConnection::initialize(int serverSocketID, esp_tls_cfg_server_t * cfgSrv, HTTPHeaders *defaultHeaders) { if (_connectionState == STATE_UNDEFINED) { // Let the base class connect the plain tcp socket int resSocket = HTTPConnection::initialize(serverSocketID, defaultHeaders); - + HTTPS_LOGI("Cert len:%d, apn:%s\n",cfgSrv->servercert_bytes,cfgSrv->alpn_protos[0]); // Build up SSL Connection context if the socket has been created successfully if (resSocket >= 0) { - - _ssl = SSL_new(sslCtx); - - if (_ssl) { + int res=esp_tls_server_session_create(cfgSrv,resSocket,_ssl); + if (0==res) { + esp_tls_cfg_server_session_tickets_init(cfgSrv); + _cfg = cfgSrv; // Bind SSL to the socket - int success = SSL_set_fd(_ssl, resSocket); - if (success) { - - // Perform the handshake - success = SSL_accept(_ssl); - if (success) { - return resSocket; - } else { - HTTPS_LOGE("SSL_accept failed. Aborting handshake. FID=%d", resSocket); - } - } else { - HTTPS_LOGE("SSL_set_fd failed. Aborting handshake. FID=%d", resSocket); + if (ESP_OK == esp_tls_get_conn_sockfd(_ssl,&resSocket)) { + return resSocket; + } + else { + HTTPS_LOGE("SSL_accept failed. Aborting handshake. FID=%d", resSocket); } - } else { - HTTPS_LOGE("SSL_new failed. Aborting handshake. FID=%d", resSocket); + } + else { + HTTPS_LOGE("SSL_new failed. Aborting handshake. Error=%d", res); } - - } else { + } + else { HTTPS_LOGE("Could not accept() new connection. FID=%d", resSocket); } @@ -66,9 +60,7 @@ int HTTPSConnection::initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeader return -1; } - void HTTPSConnection::closeConnection() { - // FIXME: Copy from HTTPConnection, could be done better probably if (_connectionState != STATE_ERROR && _connectionState != STATE_CLOSED) { @@ -81,23 +73,13 @@ void HTTPSConnection::closeConnection() { // correctly _connectionState = STATE_CLOSING; } - // Try to tear down SSL while we are in the _shutdownTS timeout period or if an error occurred if (_ssl) { - if(_connectionState == STATE_ERROR || SSL_shutdown(_ssl) == 0) { - // SSL_shutdown will return 1 as soon as the client answered with close notify - // This means we are safe to close the socket - SSL_free(_ssl); - _ssl = NULL; - } else if (_shutdownTS + HTTPS_SHUTDOWN_TIMEOUT < millis()) { - // The timeout has been hit, we force SSL shutdown now by freeing the context - SSL_free(_ssl); - _ssl = NULL; - HTTPS_LOGW("SSL_shutdown did not receive close notification from the client"); - _connectionState = STATE_ERROR; - } + esp_tls_cfg_server_session_tickets_free(_cfg); + esp_tls_server_session_delete(_ssl); + _ssl = NULL; + _connectionState = STATE_ERROR; } - // If SSL has been brought down, close the socket if (!_ssl) { HTTPConnection::closeConnection(); @@ -105,11 +87,11 @@ void HTTPSConnection::closeConnection() { } size_t HTTPSConnection::writeBuffer(byte* buffer, size_t length) { - return SSL_write(_ssl, buffer, length); + return esp_tls_conn_write(_ssl,buffer,length); } size_t HTTPSConnection::readBytesToBuffer(byte* buffer, size_t length) { - int ret = SSL_read(_ssl, buffer, length); + int ret = esp_tls_conn_read(_ssl, buffer, length); if (ret < 0) { HTTPS_LOGD("SSL_read error: %d", SSL_get_error(_ssl, ret)); } @@ -117,11 +99,11 @@ size_t HTTPSConnection::readBytesToBuffer(byte* buffer, size_t length) { } size_t HTTPSConnection::pendingByteCount() { - return SSL_pending(_ssl); + return esp_tls_get_bytes_avail(_ssl); } bool HTTPSConnection::canReadData() { - return HTTPConnection::canReadData() || (SSL_pending(_ssl) > 0); + return HTTPConnection::canReadData() || (esp_tls_get_bytes_avail(_ssl) > 0); } } /* namespace httpsserver */ diff --git a/src/HTTPSConnection.hpp b/src/HTTPSConnection.hpp index 8adbce5..abf085f 100644 --- a/src/HTTPSConnection.hpp +++ b/src/HTTPSConnection.hpp @@ -5,9 +5,12 @@ #include +/* OpenSSL Depracation in IDF v5 // Required for SSL #include "openssl/ssl.h" #undef read +*/ +#include // Required for sockets #include "lwip/netdb.h" @@ -34,7 +37,7 @@ class HTTPSConnection : public HTTPConnection { HTTPSConnection(ResourceResolver * resResolver); virtual ~HTTPSConnection(); - virtual int initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeaders *defaultHeaders); + virtual int initialize(int serverSocketID,esp_tls_cfg_server_t * cfgSrv, HTTPHeaders *defaultHeaders); virtual void closeConnection(); virtual bool isSecure(); @@ -49,7 +52,8 @@ class HTTPSConnection : public HTTPConnection { private: // SSL context for this connection - SSL * _ssl; + esp_tls_t * _ssl; + esp_tls_cfg_server_t * _cfg; }; diff --git a/src/HTTPSServer.cpp b/src/HTTPSServer.cpp index 4d8352d..e065303 100644 --- a/src/HTTPSServer.cpp +++ b/src/HTTPSServer.cpp @@ -2,17 +2,24 @@ namespace httpsserver { +constexpr const char * alpn_protos[] = { "http/1.1", NULL } ; HTTPSServer::HTTPSServer(SSLCert * cert, const uint16_t port, const uint8_t maxConnections, const in_addr_t bindAddress): HTTPServer(port, maxConnections, bindAddress), _cert(cert) { - // Configure runtime data - _sslctx = NULL; + _cfg = new esp_tls_cfg_server(); + _cfg->alpn_protos = (const char **)alpn_protos; + _cfg->cacert_buf = NULL; + _cfg->cacert_bytes = 0; + _cfg->servercert_buf =cert->getCertData(); + _cfg->servercert_bytes = cert->getCertLength(); + _cfg->serverkey_buf= cert->getPKData(); + _cfg->serverkey_bytes= cert->getPKLength(); } HTTPSServer::~HTTPSServer() { - + free(_cfg); } /** @@ -20,59 +27,31 @@ HTTPSServer::~HTTPSServer() { */ uint8_t HTTPSServer::setupSocket() { if (!isRunning()) { - if (!setupSSLCTX()) { - Serial.println("setupSSLCTX failed"); - return 0; - } - - if (!setupCert()) { - Serial.println("setupCert failed"); - SSL_CTX_free(_sslctx); - _sslctx = NULL; - return 0; - } - + _cfg->servercert_buf= _cert->getCertData(); + _cfg->servercert_bytes = _cert->getCertLength(); + _cfg->serverkey_buf= _cert->getPKData(); + _cfg->serverkey_bytes= _cert->getPKLength(); if (HTTPServer::setupSocket()) { return 1; - } else { + } + else { Serial.println("setupSockets failed"); - SSL_CTX_free(_sslctx); - _sslctx = NULL; return 0; } - } else { + } + else { return 1; } } void HTTPSServer::teardownSocket() { - HTTPServer::teardownSocket(); - - // Tear down the SSL context - SSL_CTX_free(_sslctx); - _sslctx = NULL; } int HTTPSServer::createConnection(int idx) { HTTPSConnection * newConnection = new HTTPSConnection(this); _connections[idx] = newConnection; - return newConnection->initialize(_socket, _sslctx, &_defaultHeaders); -} - -/** - * This method configures the ssl context that is used for the server - */ -uint8_t HTTPSServer::setupSSLCTX() { - _sslctx = SSL_CTX_new(TLSv1_2_server_method()); - if (_sslctx) { - // Set SSL Timeout to 5 minutes - SSL_CTX_set_timeout(_sslctx, 300); - return 1; - } else { - _sslctx = NULL; - return 0; - } + return newConnection->initialize(_socket, _cfg, &_defaultHeaders); } /** @@ -81,22 +60,11 @@ uint8_t HTTPSServer::setupSSLCTX() { */ uint8_t HTTPSServer::setupCert() { // Configure the certificate first - uint8_t ret = SSL_CTX_use_certificate_ASN1( - _sslctx, - _cert->getCertLength(), - _cert->getCertData() - ); - - // Then set the private key accordingly - if (ret) { - ret = SSL_CTX_use_RSAPrivateKey_ASN1( - _sslctx, - _cert->getPKData(), - _cert->getPKLength() - ); + _cfg->servercert_buf= _cert->getCertData(); + _cfg->servercert_bytes = _cert->getCertLength(); + _cfg->serverkey_buf= _cert->getPKData(); + _cfg->serverkey_bytes= _cert->getPKLength(); + return 1; } - return ret; -} - } /* namespace httpsserver */ diff --git a/src/HTTPSServer.hpp b/src/HTTPSServer.hpp index 68596bf..96c5efc 100644 --- a/src/HTTPSServer.hpp +++ b/src/HTTPSServer.hpp @@ -7,9 +7,12 @@ // Arduino stuff #include +/* OpenSSL wrapper depracated in IDF v5 // Required for SSL #include "openssl/ssl.h" #undef read +*/ +#include // Internal includes #include "HTTPServer.hpp" @@ -31,14 +34,14 @@ class HTTPSServer : public HTTPServer { public: HTTPSServer(SSLCert * cert, const uint16_t portHTTPS = 443, const uint8_t maxConnections = 4, const in_addr_t bindAddress = 0); virtual ~HTTPSServer(); - + virtual esp_tls_cfg_server_t *getConfig() {return _cfg;} private: // Static configuration. Port, keys, etc. ==================== // Certificate that should be used (includes private key) SSLCert * _cert; //// Runtime data ============================================ - SSL_CTX * _sslctx; + esp_tls_cfg_server_t * _cfg; // Status of the server: Are we running, or not? // Setup functions diff --git a/src/WebsocketHandler.cpp b/src/WebsocketHandler.cpp index ab85fa7..aa69c9d 100644 --- a/src/WebsocketHandler.cpp +++ b/src/WebsocketHandler.cpp @@ -1,5 +1,9 @@ #include "WebsocketHandler.hpp" +#ifndef TAG +static const char *TAG = "WebsocketHandler"; +#endif + namespace httpsserver { /** @@ -16,7 +20,7 @@ static void dumpFrame(WebsocketFrame frame) { case WebsocketHandler::OPCODE_PONG: opcode = std::string("PONG"); break; case WebsocketHandler::OPCODE_TEXT: opcode = std::string("TEXT"); break; } -/* Commenting logging function to resolve compilation + Commenting logging function to resolve compilation ESP_LOGI( TAG, "Fin: %d, OpCode: %d (%s), Mask: %d, Len: %d", @@ -26,7 +30,6 @@ static void dumpFrame(WebsocketFrame frame) { (int)frame.mask, (int)frame.len ); -*/ } WebsocketHandler::WebsocketHandler() {