25RCSID(
"$Id: 1b6cf4ca7f583d137ce887e5a259b6505f19330e $")
29#define LOG_PREFIX "tls"
36#include <openssl/conf.h>
37#include <openssl/provider.h>
39#include <freeradius-devel/server/base.h>
40#include <freeradius-devel/tls/attrs.h>
41#include <freeradius-devel/tls/base.h>
42#include <freeradius-devel/util/atexit.h>
43#include <freeradius-devel/util/debug.h>
44#include <freeradius-devel/util/math.h>
45#include <freeradius-devel/util/syserror.h>
46#include <freeradius-devel/util/md5.h>
47#include <freeradius-devel/util/md4.h>
49static uint32_t openssl_instance_count = 0;
53static size_t openssl_stack_size;
66static OSSL_PROVIDER *openssl_default_provider = NULL;
67static OSSL_PROVIDER *openssl_legacy_provider = NULL;
69static uint32_t tls_instance_count = 0;
79 { .out = &
dict_tls, .proto =
"tls" },
80 { .out = &
dict_der, .proto =
"der" },
269int fr_tls_max_threads = 1;
278 static char const *async_file;
282 chunk = talloc_array(ssl_talloc_ctx,
uint8_t,
len);
285 talloc_set_name(chunk,
"fr_openssl_talloc");
303 sep = strrchr(file,
'/');
309 if (strcmp(sep,
"async_posix.c") == 0) {
314 }
else if (file == async_file)
goto alloc_stack;
316 chunk = talloc_array(ssl_talloc_ctx,
uint8_t,
len);
318 talloc_set_name(chunk,
"%s:%d", file,
line);
333 chunk = talloc_realloc_size(ssl_talloc_ctx, old,
len);
335 talloc_set_name(chunk,
"%s:%d", file,
line);
349static void fr_openssl_talloc_free(
void *to_free,
char const *file,
UNUSED int line)
351 (void)_talloc_free(to_free, file);
354static void fr_openssl_talloc_free(
void *to_free,
char const *file,
int line)
359 (void)_talloc_free(to_free,
buffer);
366static int _openssl_thread_free(
void *
init)
368 ASYNC_cleanup_thread();
384int fr_openssl_thread_init(
size_t async_pool_size_init,
size_t async_pool_size_max)
389 if (!async_pool_init) {
390 bool *
init = talloc_zero(NULL,
bool);
392 if (ASYNC_init_thread(async_pool_size_max, async_pool_size_init) != 1) {
393 fr_openssl_log_perror(NULL,
"Failed initialising OpenSSL async context pool");
410void fr_openssl_free(
void)
412 if (--openssl_instance_count > 0)
return;
418 fr_md5_openssl_free();
419 fr_md4_openssl_free();
422static void _openssl_provider_free(
void)
424 if (openssl_default_provider && !OSSL_PROVIDER_unload(openssl_default_provider)) {
425 fr_openssl_log_perror(NULL,
"Failed unloading default provider");
427 openssl_default_provider = NULL;
429 if (openssl_legacy_provider && !OSSL_PROVIDER_unload(openssl_legacy_provider)) {
430 fr_openssl_log_perror(NULL,
"Failed unloading legacy provider");
432 openssl_legacy_provider = NULL;
435static int fr_openssl_cleanup(
UNUSED void *uctx)
441#ifdef HAVE_ASYNC_SET_MEM_FUNCTIONS
443static void *fr_openssl_stack_alloc(
size_t *
len)
450#if defined(__linux__) || defined(__FreeBSD__)
451 stack = mmap(NULL, openssl_stack_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_STACK, -1, 0);
453 stack = mmap(NULL, openssl_stack_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
455 if (
stack == MAP_FAILED) {
456 fr_openssl_log_perror(NULL,
"Failed allocating OpenSSL stack: %s",
fr_syserror(errno));
459 *
len = openssl_stack_size;
464static void fr_openssl_stack_free(
void *
stack)
466 munmap(
stack, openssl_stack_size);
475int fr_tls_session_ex_index = -1;
477int fr_openssl_init(
void)
480 pthread_attr_t tattr;
482 if (openssl_instance_count > 0) {
483 openssl_instance_count++;
487 pthread_attr_init(&tattr);
488 rcode = pthread_attr_getstacksize(&tattr, &openssl_stack_size);
489 pthread_attr_destroy(&tattr);
492 fr_openssl_log_perror(NULL,
"Failed getting stack size");
500 if (CRYPTO_set_mem_functions(fr_openssl_talloc, fr_openssl_talloc_realloc, fr_openssl_talloc_free) != 1) {
501 fr_openssl_log_perror(NULL,
"Failed to set OpenSSL memory allocation functions. fr_openssl_init() called too late");
509#ifdef HAVE_ASYNC_SET_MEM_FUNCTIONS
510 if (ASYNC_set_mem_functions(fr_openssl_stack_alloc, fr_openssl_stack_free) != 1) {
511 fr_openssl_log_perror(NULL,
"Failed to set OpenSSL async stack allocation functions");
524 if (OPENSSL_init_ssl(OPENSSL_INIT_NO_ATEXIT | OPENSSL_INIT_LOAD_CONFIG, NULL) != 1) {
525 fr_openssl_log_perror(NULL,
"Failed calling OPENSSL_init_crypto()");
532 openssl_default_provider = OSSL_PROVIDER_load(NULL,
"default");
533 if (!openssl_default_provider) {
534 fr_openssl_log_perror(NULL,
"Failed loading default provider");
543 openssl_legacy_provider = OSSL_PROVIDER_load(NULL,
"legacy");
544 if (!openssl_legacy_provider) {
545 fr_openssl_log_perror(NULL,
"Failed loading legacy provider");
554 OPENSSL_atexit(_openssl_provider_free);
561 EVP_add_digest(EVP_sha256());
572 fr_tls_session_ex_index = SSL_SESSION_get_ex_new_index(0, NULL, NULL, NULL, NULL);
573 if (fr_tls_session_ex_index < 0) {
574 fr_openssl_log_perror(NULL,
"Failed allocating an SSL_SESSION ex_data index");
586 if (fr_dtls_cookie_init() < 0) {
587 fr_openssl_log_perror(NULL,
"Failed generating the DTLS cookie key");
591 fr_md5_openssl_init();
592 fr_md4_openssl_init();
604 openssl_instance_count++;
616int fr_openssl_fips_mode(
bool enabled)
618 if (!EVP_set_default_properties(NULL, enabled ?
"fips=yes" :
"-fips")) {
619 fr_openssl_log_perror(NULL,
"Failed %s OpenSSL FIPS mode", enabled ?
"enabling" :
"disabling");
627 fr_md5_openssl_init();
628 fr_md4_openssl_init();
630 fr_md5_openssl_free();
631 fr_md4_openssl_free();
646int fr_tls_dict_init(
void)
648 if (tls_instance_count > 0) {
649 tls_instance_count++;
653 tls_instance_count++;
656 PERROR(
"Failed initialising protocol library");
658 tls_instance_count--;
664 PERROR(
"Failed resolving attributes");
669 PERROR(
"Failed resolving enums");
676void fr_tls_dict_free(
void)
678 if (--tls_instance_count > 0)
return;
static int const char char buffer[256]
#define fr_atexit_global(_func, _uctx)
Add a free function to the global free list.
#define fr_atexit_thread_local(_name, _free, _uctx)
#define USES_APPLE_DEPRECATED_API
int fr_dict_enum_autoload(fr_dict_enum_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
#define fr_dict_autofree(_to_free)
fr_value_box_t const ** out
Enumeration value.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
#define fr_dict_autoload(_to_load)
#define DICT_AUTOLOAD_TERMINATOR
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
Specifies a value which must be present for the module to function.
static fr_dict_t const * dict_freeradius
fr_dict_attr_t const * attr_tls_certificate
Attribute definitions for lib curl.
static fr_dict_t const * dict_tls
fr_dict_t const * dict_radius
static fr_dict_attr_t const * attr_module_failure_message
fr_value_box_t const * enum_tls_packet_type_store_session
fr_value_box_t const * enum_tls_packet_type_load_psk
HIDDEN fr_dict_attr_t const * attr_tls_certificate_subject
HIDDEN fr_dict_attr_t const * attr_tls_certificate_x509v3_extended_key_usage
HIDDEN fr_dict_attr_t const * attr_tls_packet_type
HIDDEN fr_dict_attr_t const * attr_tls_certificate_x509v3_authority_key_identifier
HIDDEN fr_dict_attr_t const * attr_session_resumed
fr_value_box_t const * enum_tls_packet_type_failure
HIDDEN fr_dict_attr_t const * attr_tls_session_resumed
HIDDEN fr_dict_attr_t const * attr_tls_session_version
HIDDEN fr_dict_attr_t const * attr_tls_ocsp_cert_valid
HIDDEN fr_dict_attr_t const * attr_tls_alert_level
HIDDEN fr_dict_attr_t const * attr_tls_client_hello
HIDDEN fr_dict_attr_t const * attr_tls_client_hello_psk_key_mode
HIDDEN fr_dict_attr_t const * attr_tls_certificate_x509v3_basic_constraints
fr_value_box_t const * enum_tls_packet_type_success
HIDDEN fr_dict_attr_t const * attr_tls_psk_key
HIDDEN fr_dict_attr_t const * attr_tls_certificate_serial
HIDDEN fr_dict_attr_t const * attr_tls_session_require_client_cert
HIDDEN fr_dict_t const * dict_der
HIDDEN fr_dict_attr_t const * attr_tls_certificate_subject_alt_name_dns
HIDDEN fr_dict_attr_t const * attr_tls_client_hello_supported_group
HIDDEN fr_dict_attr_t const * attr_tls_session_ttl
fr_value_box_t const * enum_tls_session_resumed_stateful
HIDDEN fr_dict_attr_t const * attr_tls_session_data
HIDDEN fr_dict_attr_t const * attr_tls_certificate_not_after
HIDDEN fr_dict_attr_t const * attr_tls_certificate_not_before
HIDDEN fr_dict_attr_t const * attr_tls_alpn
fr_value_box_t const * enum_tls_packet_type_new_session
HIDDEN fr_dict_attr_t const * attr_tls_certificate_signature_algorithm
HIDDEN fr_dict_attr_t const * attr_tls_client_error_code
fr_value_box_t const * enum_tls_packet_type_load_session
fr_value_box_t const * enum_tls_packet_type_establish_session
HIDDEN fr_dict_attr_t const * attr_tls_error
HIDDEN fr_dict_attr_t const * attr_tls_certificate_subject_alt_name_upn
HIDDEN fr_dict_attr_t const * attr_tls_ocsp_response
HIDDEN fr_dict_attr_t const * attr_tls_session_id
fr_value_box_t const * enum_tls_packet_type_fail_session
HIDDEN fr_dict_attr_t const * attr_tls_client_hello_sig_algo
HIDDEN fr_dict_attr_t const * attr_tls_certificate_ocsp_uri
HIDDEN fr_dict_attr_t const * attr_tls_certificate_x509v3_subject_key_identifier
fr_value_box_t const * enum_tls_packet_type_clear_session
HIDDEN fr_dict_attr_t const * attr_tls_session_cipher_suite
HIDDEN fr_dict_attr_t const * attr_tls_certificate_common_name
HIDDEN fr_dict_attr_t const * attr_tls_certificate_ocsp_cert_id
HIDDEN fr_dict_attr_t const * attr_tls_psk_identity
HIDDEN fr_dict_attr_t const * attr_tls_alert_description
HIDDEN fr_dict_attr_t const * attr_tls_certificate_issuer
fr_value_box_t const * enum_tls_session_resumed_stateless
HIDDEN fr_dict_attr_t const * attr_tls_certificate_x509v3_crl_distribution_points
fr_value_box_t const * enum_tls_packet_type_notfound
HIDDEN fr_dict_attr_t const * attr_tls_client_hello_ec_point_format
HIDDEN fr_dict_attr_t const * attr_der_certificate
HIDDEN fr_dict_attr_t const * attr_tls_certificate_signature
HIDDEN fr_dict_attr_t const * attr_tls_alert
fr_value_box_t const * enum_tls_packet_type_decode_session
HIDDEN fr_dict_attr_t const * attr_tls_ocsp_next_update
fr_value_box_t const * enum_tls_packet_type_encode_session
HIDDEN fr_dict_attr_t const * attr_tls_client_hello_tls_version
fr_value_box_t const * enum_tls_packet_type_verify_certificate
HIDDEN fr_dict_attr_t const * attr_tls_client_hello_cipher
HIDDEN fr_dict_attr_t const * attr_tls_session_cert_file
HIDDEN fr_dict_attr_t const * attr_tls_certificate_chain_depth
HIDDEN fr_dict_attr_t const * attr_tls_certificate_subject_alt_name_email
HIDDEN fr_dict_attr_t const * attr_allow_session_resumption
static char * stack[MAX_STACK]
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_DATE
Unix time stamp, always has value >2^31.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_OCTETS
Raw octets.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
init
Enter the EAP-IDENTITY state.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
static fr_sbuff_err_t char size_t * len