Skip to content

Commit

Permalink
RFC 5077 TLS session tickets
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivan Kostoski committed Oct 10, 2019
1 parent 43b8c56 commit 7cb01b0
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/HTTPSConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace httpsserver {
HTTPSConnection::HTTPSConnection(ResourceResolver * resResolver):
HTTPConnection(resResolver) {
_ssl = NULL;
_TLSTickets = NULL;
}

HTTPSConnection::~HTTPSConnection() {
Expand All @@ -31,6 +32,7 @@ int HTTPSConnection::initialize(int serverSocketID, SSL_CTX * sslCtx, HTTPHeader
if (resSocket >= 0) {

_ssl = SSL_new(sslCtx);
if (_TLSTickets != NULL) _TLSTickets->enable(_ssl);

if (_ssl) {
// Bind SSL to the socket
Expand Down
2 changes: 2 additions & 0 deletions src/HTTPSConnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "ResourceNode.hpp"
#include "HTTPRequest.hpp"
#include "HTTPResponse.hpp"
#include "TLSTickets.hpp"

namespace httpsserver {

Expand Down Expand Up @@ -50,6 +51,7 @@ class HTTPSConnection : public HTTPConnection {
private:
// SSL context for this connection
SSL * _ssl;
TLSTickets * _TLSTickets;

};

Expand Down
5 changes: 5 additions & 0 deletions src/HTTPSServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ HTTPSServer::HTTPSServer(SSLCert * cert, const uint16_t port, const uint8_t maxC

// Configure runtime data
_sslctx = NULL;
_TLSTickets = NULL;
}

HTTPSServer::~HTTPSServer() {
Expand Down Expand Up @@ -45,6 +46,10 @@ uint8_t HTTPSServer::setupSocket() {
}
}

void HTTPSServer::enableTLSTickets(uint32_t liftimeSeconds, bool useHardwareRNG) {
_TLSTickets = new TLSTickets("esp32_https_server", liftimeSeconds, useHardwareRNG);
}

void HTTPSServer::teardownSocket() {

HTTPServer::teardownSocket();
Expand Down
5 changes: 5 additions & 0 deletions src/HTTPSServer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "ResolvedResource.hpp"
#include "HTTPSConnection.hpp"
#include "SSLCert.hpp"
#include "TLSTickets.hpp"

namespace httpsserver {

Expand All @@ -32,13 +33,17 @@ class HTTPSServer : public HTTPServer {
HTTPSServer(SSLCert * cert, const uint16_t portHTTPS = 443, const uint8_t maxConnections = 4, const in_addr_t bindAddress = 0);
virtual ~HTTPSServer();

// RFC 5077 TLS session tickets
void enableTLSTickets(uint32_t liftimeSeconds = 86400, bool useHardwareRNG = false);

private:
// Static configuration. Port, keys, etc. ====================
// Certificate that should be used (includes private key)
SSLCert * _cert;

//// Runtime data ============================================
SSL_CTX * _sslctx;
TLSTickets * _TLSTickets;
// Status of the server: Are we running, or not?

// Setup functions
Expand Down
91 changes: 91 additions & 0 deletions src/TLSTickets.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include "TLSTickets.hpp"
#include "HTTPSServerConstants.hpp"

#include "mbedtls/net_sockets.h"

// Low level SSL implementation on ESP32
// Copied from esp-idf/components/openssl/platform/ssl_pm.c
struct ssl_pm {
mbedtls_net_context fd;
mbedtls_net_context cl_fd;
mbedtls_ssl_config conf;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
mbedtls_entropy_context entropy;
};

namespace httpsserver {

int TLSTickets::hardware_random(void * p_rng, unsigned char * output, size_t output_len) {
esp_fill_random(output, output_len);
return 0;
}

TLSTickets::TLSTickets(const char* tag, uint32_t lifetimeSeconds, bool useHWRNG) {
_initOk = false;
_useHWRNG = useHWRNG;

// Setup TLS tickets context
int ret = -1;
if (_useHWRNG) {
mbedtls_ssl_ticket_init(&_ticketCtx);
ret = mbedtls_ssl_ticket_setup(
&_ticketCtx,
TLSTickets::hardware_random,
NULL,
MBEDTLS_CIPHER_AES_256_GCM,
lifetimeSeconds
);
} else {
mbedtls_entropy_init(&_entropy);
mbedtls_ctr_drbg_init(&_ctr_drbg);
mbedtls_ssl_ticket_init(&_ticketCtx);
ret = mbedtls_ctr_drbg_seed(
&_ctr_drbg,
mbedtls_entropy_func,
&_entropy,
(unsigned char*)tag,
strlen(tag)
);
if (ret == 0) {
ret = mbedtls_ssl_ticket_setup(
&_ticketCtx,
mbedtls_ctr_drbg_random,
&_ctr_drbg,
MBEDTLS_CIPHER_AES_256_GCM,
lifetimeSeconds
);
}
}
if (ret != 0) return;

_initOk = true;
HTTPS_LOGI("Using TLS session tickets");
}

TLSTickets::~TLSTickets() {
if (!_useHWRNG) {
mbedtls_ctr_drbg_free(&_ctr_drbg);
mbedtls_entropy_free(&_entropy);
}
mbedtls_ssl_ticket_free(&_ticketCtx);
}

bool TLSTickets::enable(SSL * ssl) {
bool res = false;
if (_initOk && ssl && ssl->ssl_pm) {
// Get handle of low-level mbedtls structures for the session
struct ssl_pm * ssl_pm = (struct ssl_pm *) ssl->ssl_pm;
// Configure TLS ticket callbacks using default MbedTLS implementation
mbedtls_ssl_conf_session_tickets_cb(
&ssl_pm->conf,
mbedtls_ssl_ticket_write,
mbedtls_ssl_ticket_parse,
&_ticketCtx
);
res = true;
}
return res;
}

} /* namespace httpsserver */
57 changes: 57 additions & 0 deletions src/TLSTickets.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#ifndef SRC_TLSTICKETS_HPP_
#define SRC_TLSTICKETS_HPP_

#include <cstdint>
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/ssl_ticket.h"
#include "openssl/ssl.h"

namespace httpsserver {

/**
* Enables handling of RFC 5077 TLS session tickets
*/
class TLSTickets {

public:
TLSTickets(const char* tag, uint32_t liftimeSecs, bool useHWRNG);
~TLSTickets();

/**
* Enables TLS ticket processing for SSL session
*/
bool enable(SSL * ssl);

protected:
bool _initOk;
bool _useHWRNG;

/**
* Holds TLS ticket keys
*/
mbedtls_ssl_ticket_context _ticketCtx;

/**
* mbedTLS random number generator state
*/
mbedtls_entropy_context _entropy;
mbedtls_ctr_drbg_context _ctr_drbg;

/**
* MbedTLS Random Number Generator using ESP32's hardware RNG
*
* NOTE: Radio (WiFi/Bluetooth) MUST be running for hardware
* entropy to be gathered. Otherwise this function is PRNG!
*
* See more details about esp_random(), here:
* https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/system.html
*
*/
static int hardware_random(void * p_rng, unsigned char * output, size_t output_len);

};

} /* namespace httpsserver */

#endif // SRC_TLSTICKETS_HPP_

0 comments on commit 7cb01b0

Please sign in to comment.