Skip to content

Commit 7cb01b0

Browse files
author
Ivan Kostoski
committed
RFC 5077 TLS session tickets
1 parent 43b8c56 commit 7cb01b0

6 files changed

+162
-0
lines changed

src/HTTPSConnection.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace httpsserver {
66
HTTPSConnection::HTTPSConnection(ResourceResolver * resResolver):
77
HTTPConnection(resResolver) {
88
_ssl = NULL;
9+
_TLSTickets = NULL;
910
}
1011

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

3334
_ssl = SSL_new(sslCtx);
35+
if (_TLSTickets != NULL) _TLSTickets->enable(_ssl);
3436

3537
if (_ssl) {
3638
// Bind SSL to the socket

src/HTTPSConnection.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "ResourceNode.hpp"
2424
#include "HTTPRequest.hpp"
2525
#include "HTTPResponse.hpp"
26+
#include "TLSTickets.hpp"
2627

2728
namespace httpsserver {
2829

@@ -50,6 +51,7 @@ class HTTPSConnection : public HTTPConnection {
5051
private:
5152
// SSL context for this connection
5253
SSL * _ssl;
54+
TLSTickets * _TLSTickets;
5355

5456
};
5557

src/HTTPSServer.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ HTTPSServer::HTTPSServer(SSLCert * cert, const uint16_t port, const uint8_t maxC
99

1010
// Configure runtime data
1111
_sslctx = NULL;
12+
_TLSTickets = NULL;
1213
}
1314

1415
HTTPSServer::~HTTPSServer() {
@@ -45,6 +46,10 @@ uint8_t HTTPSServer::setupSocket() {
4546
}
4647
}
4748

49+
void HTTPSServer::enableTLSTickets(uint32_t liftimeSeconds, bool useHardwareRNG) {
50+
_TLSTickets = new TLSTickets("esp32_https_server", liftimeSeconds, useHardwareRNG);
51+
}
52+
4853
void HTTPSServer::teardownSocket() {
4954

5055
HTTPServer::teardownSocket();

src/HTTPSServer.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "ResolvedResource.hpp"
2222
#include "HTTPSConnection.hpp"
2323
#include "SSLCert.hpp"
24+
#include "TLSTickets.hpp"
2425

2526
namespace httpsserver {
2627

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

36+
// RFC 5077 TLS session tickets
37+
void enableTLSTickets(uint32_t liftimeSeconds = 86400, bool useHardwareRNG = false);
38+
3539
private:
3640
// Static configuration. Port, keys, etc. ====================
3741
// Certificate that should be used (includes private key)
3842
SSLCert * _cert;
3943

4044
//// Runtime data ============================================
4145
SSL_CTX * _sslctx;
46+
TLSTickets * _TLSTickets;
4247
// Status of the server: Are we running, or not?
4348

4449
// Setup functions

src/TLSTickets.cpp

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include "TLSTickets.hpp"
2+
#include "HTTPSServerConstants.hpp"
3+
4+
#include "mbedtls/net_sockets.h"
5+
6+
// Low level SSL implementation on ESP32
7+
// Copied from esp-idf/components/openssl/platform/ssl_pm.c
8+
struct ssl_pm {
9+
mbedtls_net_context fd;
10+
mbedtls_net_context cl_fd;
11+
mbedtls_ssl_config conf;
12+
mbedtls_ctr_drbg_context ctr_drbg;
13+
mbedtls_ssl_context ssl;
14+
mbedtls_entropy_context entropy;
15+
};
16+
17+
namespace httpsserver {
18+
19+
int TLSTickets::hardware_random(void * p_rng, unsigned char * output, size_t output_len) {
20+
esp_fill_random(output, output_len);
21+
return 0;
22+
}
23+
24+
TLSTickets::TLSTickets(const char* tag, uint32_t lifetimeSeconds, bool useHWRNG) {
25+
_initOk = false;
26+
_useHWRNG = useHWRNG;
27+
28+
// Setup TLS tickets context
29+
int ret = -1;
30+
if (_useHWRNG) {
31+
mbedtls_ssl_ticket_init(&_ticketCtx);
32+
ret = mbedtls_ssl_ticket_setup(
33+
&_ticketCtx,
34+
TLSTickets::hardware_random,
35+
NULL,
36+
MBEDTLS_CIPHER_AES_256_GCM,
37+
lifetimeSeconds
38+
);
39+
} else {
40+
mbedtls_entropy_init(&_entropy);
41+
mbedtls_ctr_drbg_init(&_ctr_drbg);
42+
mbedtls_ssl_ticket_init(&_ticketCtx);
43+
ret = mbedtls_ctr_drbg_seed(
44+
&_ctr_drbg,
45+
mbedtls_entropy_func,
46+
&_entropy,
47+
(unsigned char*)tag,
48+
strlen(tag)
49+
);
50+
if (ret == 0) {
51+
ret = mbedtls_ssl_ticket_setup(
52+
&_ticketCtx,
53+
mbedtls_ctr_drbg_random,
54+
&_ctr_drbg,
55+
MBEDTLS_CIPHER_AES_256_GCM,
56+
lifetimeSeconds
57+
);
58+
}
59+
}
60+
if (ret != 0) return;
61+
62+
_initOk = true;
63+
HTTPS_LOGI("Using TLS session tickets");
64+
}
65+
66+
TLSTickets::~TLSTickets() {
67+
if (!_useHWRNG) {
68+
mbedtls_ctr_drbg_free(&_ctr_drbg);
69+
mbedtls_entropy_free(&_entropy);
70+
}
71+
mbedtls_ssl_ticket_free(&_ticketCtx);
72+
}
73+
74+
bool TLSTickets::enable(SSL * ssl) {
75+
bool res = false;
76+
if (_initOk && ssl && ssl->ssl_pm) {
77+
// Get handle of low-level mbedtls structures for the session
78+
struct ssl_pm * ssl_pm = (struct ssl_pm *) ssl->ssl_pm;
79+
// Configure TLS ticket callbacks using default MbedTLS implementation
80+
mbedtls_ssl_conf_session_tickets_cb(
81+
&ssl_pm->conf,
82+
mbedtls_ssl_ticket_write,
83+
mbedtls_ssl_ticket_parse,
84+
&_ticketCtx
85+
);
86+
res = true;
87+
}
88+
return res;
89+
}
90+
91+
} /* namespace httpsserver */

src/TLSTickets.hpp

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#ifndef SRC_TLSTICKETS_HPP_
2+
#define SRC_TLSTICKETS_HPP_
3+
4+
#include <cstdint>
5+
#include "mbedtls/entropy.h"
6+
#include "mbedtls/ctr_drbg.h"
7+
#include "mbedtls/ssl_ticket.h"
8+
#include "openssl/ssl.h"
9+
10+
namespace httpsserver {
11+
12+
/**
13+
* Enables handling of RFC 5077 TLS session tickets
14+
*/
15+
class TLSTickets {
16+
17+
public:
18+
TLSTickets(const char* tag, uint32_t liftimeSecs, bool useHWRNG);
19+
~TLSTickets();
20+
21+
/**
22+
* Enables TLS ticket processing for SSL session
23+
*/
24+
bool enable(SSL * ssl);
25+
26+
protected:
27+
bool _initOk;
28+
bool _useHWRNG;
29+
30+
/**
31+
* Holds TLS ticket keys
32+
*/
33+
mbedtls_ssl_ticket_context _ticketCtx;
34+
35+
/**
36+
* mbedTLS random number generator state
37+
*/
38+
mbedtls_entropy_context _entropy;
39+
mbedtls_ctr_drbg_context _ctr_drbg;
40+
41+
/**
42+
* MbedTLS Random Number Generator using ESP32's hardware RNG
43+
*
44+
* NOTE: Radio (WiFi/Bluetooth) MUST be running for hardware
45+
* entropy to be gathered. Otherwise this function is PRNG!
46+
*
47+
* See more details about esp_random(), here:
48+
* https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/system.html
49+
*
50+
*/
51+
static int hardware_random(void * p_rng, unsigned char * output, size_t output_len);
52+
53+
};
54+
55+
} /* namespace httpsserver */
56+
57+
#endif // SRC_TLSTICKETS_HPP_

0 commit comments

Comments
 (0)