Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Esp tls #169

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/ConnectionContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
#include <IPAddress.h>

// Required for SSL
#include "openssl/ssl.h"
#undef read

//#include "openssl/ssl.h"
//#undef read
#include <esp_tls.h>
namespace httpsserver {

class WebsocketHandler;
Expand Down
2 changes: 1 addition & 1 deletion src/HTTPConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,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;
Expand Down
2 changes: 1 addition & 1 deletion src/HTTPConnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include <string>
#include <mbedtls/base64.h>
#include <hwcrypto/sha.h>
#include <mbedtls/sha1.h>
#include <functional>

// Required for sockets
Expand Down
3 changes: 2 additions & 1 deletion src/HTTPResponse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
#undef write
#include <vector>

#include <openssl/ssl.h>
//#include <openssl/ssl.h>
#include <esp_tls.h>

#include "util.hpp"

Expand Down
54 changes: 18 additions & 36 deletions src/HTTPSConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace httpsserver {

HTTPSConnection::HTTPSConnection(ResourceResolver * resResolver):
HTTPConnection(resResolver) {
_ssl = NULL;
_ssl = esp_tls_init();
}

HTTPSConnection::~HTTPSConnection() {
Expand All @@ -22,42 +22,32 @@ 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) {
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_set_fd failed. Aborting handshake. FID=%d", resSocket);
HTTPS_LOGE("SSL_accept failed. Aborting handshake. FID=%d", resSocket);
}
} else {
HTTPS_LOGE("SSL_new failed. Aborting handshake. FID=%d", resSocket);
HTTPS_LOGE("SSL_new failed. Aborting handshake. Error=%d", res);
}

} else {
HTTPS_LOGE("Could not accept() new connection. FID=%d", resSocket);
}

_connectionState = STATE_ERROR;
_clientState = CSTATE_ACTIVE;

// This will only be called if the connection could not be established and cleanup
// variables like _ssl etc.
closeConnection();
Expand All @@ -84,18 +74,10 @@ void HTTPSConnection::closeConnection() {

// 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
Expand All @@ -105,19 +87,19 @@ 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);// SSL_write(_ssl, buffer, length);
}

size_t HTTPSConnection::readBytesToBuffer(byte* buffer, size_t length) {
return SSL_read(_ssl, buffer, length);
return esp_tls_conn_read(_ssl, buffer, 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 */
11 changes: 6 additions & 5 deletions src/HTTPSConnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
#include <string>

// Required for SSL
#include "openssl/ssl.h"
#undef read
//#include "openssl/ssl.h"
//#undef read
#include <esp_tls.h>

// Required for sockets
#include "lwip/netdb.h"
Expand All @@ -34,7 +35,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();

Expand All @@ -49,8 +50,8 @@ class HTTPSConnection : public HTTPConnection {

private:
// SSL context for this connection
SSL * _ssl;

esp_tls_t * _ssl;
esp_tls_cfg_server_t * _cfg;
};

} /* namespace httpsserver */
Expand Down
71 changes: 20 additions & 51 deletions src/HTTPSServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,40 @@

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);
}

/**
* This method starts the server and begins to listen on the port
*/
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 {
Serial.println("setupSockets failed");
SSL_CTX_free(_sslctx);
_sslctx = NULL;
return 0;
}
} else {
Expand All @@ -49,30 +47,12 @@ 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);
}

/**
Expand All @@ -81,22 +61,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()
);
}

return ret;
_cfg->servercert_buf= _cert->getCertData();
_cfg->servercert_bytes = _cert->getCertLength();
_cfg->serverkey_buf= _cert->getPKData();
_cfg->serverkey_bytes= _cert->getPKLength();
return 1;
}

} /* namespace httpsserver */
10 changes: 5 additions & 5 deletions src/HTTPSServer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
#include <Arduino.h>

// Required for SSL
#include "openssl/ssl.h"
#undef read
//#include "openssl/ssl.h"
#include <esp_tls.h>
//#undef read

// Internal includes
#include "HTTPServer.hpp"
Expand All @@ -31,20 +32,19 @@ 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
virtual uint8_t setupSocket();
virtual void teardownSocket();
uint8_t setupSSLCTX();
uint8_t setupCert();

// Helper functions
Expand Down
6 changes: 4 additions & 2 deletions src/WebsocketHandler.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "WebsocketHandler.hpp"

#ifndef TAG
#define TAG "ARDUINO"
#endif
namespace httpsserver {

/**
Expand All @@ -17,7 +19,7 @@ static void dumpFrame(WebsocketFrame frame) {
case WebsocketHandler::OPCODE_TEXT: opcode = std::string("TEXT"); break;
}
ESP_LOGI(
TAG,
"",
"Fin: %d, OpCode: %d (%s), Mask: %d, Len: %d",
(int)frame.fin,
(int)frame.opCode,
Expand Down