26RCSID(
"$Id: b6d1caa2bc507f44a7cdb60e47e3c0bfd894eb31 $")
30#define LOG_PREFIX "tls"
33#include <freeradius-devel/internal/internal.h>
34#include <freeradius-devel/server/pair.h>
35#include <freeradius-devel/server/module_rlm.h>
36#include <freeradius-devel/unlang/function.h>
37#include <freeradius-devel/unlang/subrequest.h>
38#include <freeradius-devel/util/debug.h>
40#include <freeradius-devel/protocol/tls/freeradius.h>
49#include <openssl/ssl.h>
79 id = SSL_SESSION_get_id(sess, &
len);
96void tls_session_id_cache(fr_tls_session_t *tls_session, SSL_SESSION *sess)
100 if (tls_ticket_id_to_box(tls_session, &tls_session->session_id, sess) < 0)
return;
105 if (tls_session->cache) tls_session->cache->session_id = &tls_session->session_id;
131 vp->vp_uint32 = packet_type;
156 fr_dbuff_uctx_talloc_t tctx;
163 RDEBUG2(
"(TLS) Session ID %pV - Adding session-state[*] to data", session_id);
184 RPERROR(
"(TLS) Session ID %pV - Failed serialising session-state list", session_id);
200 fr_tls_log_perror(
request,
"Session ID %pV - Failed setting application data", session_id);
218 if (SSL_SESSION_get0_ticket_appdata(sess, (
void **)&
data, &data_len) != 1) {
219 fr_tls_log_perror(
request,
"Session ID %pV - Failed retrieving application data", session_id);
224 fr_tls_log_perror(
request,
"Session ID %pV - Got NULL session application data", session_id);
243 RPEDEBUG(
"(TLS) Session-ID %pV - Failed decoding session-state", session_id);
244 fr_tls_session_error_add(
request, FR_ERROR_VALUE_SESSION_DATA_DECODE_FAILED);
250 RDEBUG2(
"(TLS) Session-ID %pV - Restoring session-state[*]", session_id);
280 fr_tls_conf_t
const *
conf, SSL_SESSION *sess)
282 time_t timeout = SSL_get_timeout(sess);
286 if (lifetime && (lifetime < timeout)) timeout = lifetime;
288 if (timeout > FR_TLS_MAX_SESSION_LIFETIME) {
289 RWDEBUG(
"(TLS) Session ID %pV - Session lifetime %pV is longer than the maximum of %pV, limiting it",
293 timeout = FR_TLS_MAX_SESSION_LIFETIME;
296#if OPENSSL_VERSION_NUMBER >= 0x30400000L
297 expires =
fr_time_from_sec((time_t)(SSL_SESSION_get_time_ex(sess) + timeout));
319 fr_tls_conf_t
const *
conf, SSL_SESSION *sess)
326 RDEBUG2(
"(TLS) Session ID %pV - %pV left is less than min_lifetime of %pV",
345int fr_tls_ticket_disable_cb(SSL *ssl,
int is_forward_secure)
349 fr_tls_session_t *tls_session;
352 tls_session = fr_tls_session(ssl);
353 request = fr_tls_session_request(tls_session->ssl);
364 conf = talloc_get_type_abort(SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_CONF), fr_tls_conf_t);
365 if (
conf->cache.require_extms && (SSL_get_extms_support(tls_session->ssl) == 0)) {
366 RDEBUG2(
"(TLS) Client does not support the Extended Master Secret extension, "
367 "denying session resumption");
371 if (
conf->cache.require_pfs && !is_forward_secure) {
372 RDEBUG2(
"(TLS) Cipher suite is not forward secure, denying session resumption");
386 if (!tls_session->allow_session_resumption) {
387 RDEBUG2(
"(TLS) Session resumption not enabled for this TLS session, denying session resumption");
392 if (
vp && (
vp->vp_uint32 == 0)) {
393 RDEBUG2(
"(TLS) control.Allow-Session-Resumption == no, denying session resumption");
395 SSL_CTX_remove_session(tls_session->ctx, tls_session->session);
396 tls_session->allow_session_resumption =
false;
400 RDEBUG2(
"(TLS) Allowing future session-resumption");
413int fr_tls_ticket_ctx_init(SSL_CTX *ctx, fr_tls_ticket_conf_t
const *cache_conf,
bool client)
415 switch (cache_conf->mode) {
416 case FR_TLS_TICKET_DISABLED:
417 fr_tls_ticket_stateless_disable(ctx,
false);
418 fr_tls_ticket_stateful_disable(ctx);
421 case FR_TLS_TICKET_AUTO:
422 case FR_TLS_TICKET_STATEFUL:
423 fr_tls_ticket_stateful_ctx_init(ctx, cache_conf, client);
428 if (!(cache_conf->mode & FR_TLS_TICKET_STATELESS)) {
429 fr_tls_ticket_stateless_disable(ctx,
true);
434 case FR_TLS_TICKET_STATELESS:
449 if (!(cache_conf->mode & FR_TLS_TICKET_STATEFUL)) {
451 fr_tls_ticket_stateful_disable(ctx);
453 fr_tls_ticket_stateful_ctx_init(ctx, cache_conf, client);
457 if (fr_tls_ticket_stateless_ctx_init(ctx, cache_conf) < 0)
return -1;
462 SSL_CTX_set_not_resumable_session_callback(ctx, fr_tls_ticket_disable_cb);
463 SSL_CTX_set_quiet_shutdown(ctx, 1);
static uint8_t request[4]
#define USES_APPLE_DEPRECATED_API
#define FALL_THROUGH
clang 10 doesn't recognised the FALL-THROUGH comment anymore
#define fr_dbuff_used(_dbuff_or_marker)
Return the number of bytes remaining between the start of the dbuff or marker and the current positio...
static void fr_dbuff_free_talloc(fr_dbuff_t *dbuff)
Free the talloc buffer associated with a dbuff.
#define fr_dbuff_len(_dbuff_or_marker)
The length of the underlying buffer.
#define fr_dbuff_init(_out, _start, _len_or_end)
Initialise an dbuff for encoding or decoding.
#define fr_dbuff_start(_dbuff_or_marker)
Return the 'start' position of a dbuff or marker.
#define fr_dbuff_remaining(_dbuff_or_marker)
Return the number of bytes remaining between the dbuff or marker and the end of the buffer.
static fr_dbuff_t * fr_dbuff_init_talloc(TALLOC_CTX *ctx, fr_dbuff_t *dbuff, fr_dbuff_uctx_talloc_t *tctx, size_t init, size_t max)
Initialise a special dbuff which automatically extends as additional data is written.
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
static void * fr_dcursor_current(fr_dcursor_t *cursor)
Return the item the cursor current points to.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
bool unlang_request_is_cancelled(request_t const *request)
Return whether a request has been cancelled.
void log_request_pair_list(fr_log_lvl_t lvl, request_t *request, fr_pair_t const *parent, fr_pair_list_t const *vps, char const *prefix)
Print a fr_pair_list_t.
#define REXDENT()
Exdent (unindent) R* messages by one level.
#define RHEXDUMP4(_data, _len, _fmt,...)
#define RPEDEBUG(fmt,...)
#define RINDENT()
Indent R* messages by one level.
HIDDEN fr_dict_attr_t const * attr_tls_packet_type
HIDDEN fr_dict_attr_t const * attr_tls_session_id
HIDDEN fr_dict_attr_t const * attr_allow_session_resumption
@ L_DBG_LVL_2
2nd highest priority debug messages (-xx | -X).
int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Copy data into an "octets" data type.
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
ssize_t fr_internal_decode_pair_dbuff(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, fr_dbuff_t *dbuff, void *decode_ctx)
ssize_t fr_internal_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *encode_ctx)
Encode a data structure into an internal attribute.
#define RDEBUG_ENABLED2()
#define pair_append_request(_attr, _da)
Allocate and append a fr_pair_t to the request list.
#define pair_prepend_request(_attr, _da)
Allocate and prepend a fr_pair_t to the request list.
Stores an attribute, a value and various bits of other data.
request_t * unlang_subrequest_alloc(request_t *parent, fr_dict_t const *namespace)
Allocate a subrequest to run through a virtual server at some point in the future.
#define fr_time_delta_lt(_a, _b)
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
#define fr_time_delta_ispos(_a)
static int64_t fr_time_delta_to_sec(fr_time_delta_t delta)
static fr_time_t fr_time_from_sec(time_t when)
Convert a time_t (wallclock time) to a fr_time_t (internal time)
#define fr_time_sub(_a, _b)
Subtract one time from another.
A time delta, a difference in time measured in nanoseconds.
static fr_dict_t const * dict_tls
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
void fr_pair_list_append(fr_pair_list_t *dst, fr_pair_list_t *src)
Appends a list of fr_pair_t from a temporary list to a destination list.
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
#define fr_type_is_null(_x)
int fr_value_box_memdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, uint8_t const *src, size_t len, bool tainted)
Copy a buffer to a fr_value_box_t.
static fr_sbuff_err_t char ** out
static fr_sbuff_err_t char size_t * len
#define fr_box_time_delta(_val)