27RCSID(
"$Id: e7d456b3262f43bd238475e9b7962643a7ed0bab $")
 
   31#define LOG_PREFIX "tls" 
   37#include <openssl/conf.h> 
   38#include <openssl/provider.h> 
   40#include <freeradius-devel/server/base.h> 
   41#include <freeradius-devel/tls/attrs.h> 
   42#include <freeradius-devel/tls/base.h> 
   43#include <freeradius-devel/tls/engine.h> 
   44#include <freeradius-devel/util/atexit.h> 
   45#include <freeradius-devel/util/debug.h> 
   46#include <freeradius-devel/util/math.h> 
   47#include <freeradius-devel/util/syserror.h> 
   49static uint32_t openssl_instance_count = 0;
 
   53#define OPENSSL_ASYNC_STACK_SIZE        32768 
   57static size_t                   openssl_stack_size;
 
   63_Thread_local TALLOC_CTX        *ssl_talloc_ctx;
 
   68static _Thread_local 
bool       *async_pool_init;
 
   70static OSSL_PROVIDER *openssl_default_provider = NULL;
 
   71static OSSL_PROVIDER *openssl_legacy_provider = NULL;
 
   73static uint32_t tls_instance_count = 0;
 
   83        { .out = &
dict_tls, .proto = 
"tls" },
 
   84        { .out = &
dict_der, .proto = 
"der" },
 
  236int fr_tls_max_threads = 1;
 
  245        static char const *async_file;
 
  249                chunk = talloc_array(ssl_talloc_ctx, 
uint8_t, len);
 
  252                talloc_set_name(chunk, 
"fr_openssl_talloc");
 
  270                sep = strrchr(
file, 
'/');
 
  276                if (strcmp(sep, 
"async_posix.c") == 0) {
 
  281        } 
else if (
file == async_file) 
goto alloc_stack;
 
  283        chunk = talloc_array(ssl_talloc_ctx, 
uint8_t, len);
 
  285        talloc_set_name(chunk, 
"%s:%d", 
file, 
line);
 
  300        chunk = talloc_realloc_size(ssl_talloc_ctx, old, len);
 
  302        talloc_set_name(chunk, 
"%s:%d", 
file, 
line);
 
  316static void fr_openssl_talloc_free(
void *to_free, 
char const *
file, 
UNUSED int line)
 
  318        (void)_talloc_free(to_free, 
file);
 
  321static void fr_openssl_talloc_free(
void *to_free, 
char const *
file, 
int line)
 
  326        (void)_talloc_free(to_free, 
buffer);
 
  333static int _openssl_thread_free(
void *
init)
 
  335        ASYNC_cleanup_thread();
 
  351int fr_openssl_thread_init(
size_t async_pool_size_init, 
size_t async_pool_size_max)
 
  356        if (!async_pool_init) {
 
  357                bool *
init = talloc_zero(NULL, 
bool);
 
  359                if (ASYNC_init_thread(async_pool_size_max, async_pool_size_init) != 1) {
 
  360                        fr_tls_log(NULL, 
"Failed initialising OpenSSL async context pool");
 
  377void fr_openssl_free(
void)
 
  379        if (--openssl_instance_count > 0) 
return;
 
  386static void _openssl_provider_free(
void)
 
  388        if (openssl_default_provider && !OSSL_PROVIDER_unload(openssl_default_provider)) {
 
  389                fr_tls_log(NULL, 
"Failed unloading default provider");
 
  391        openssl_default_provider = NULL;
 
  393        if (openssl_legacy_provider && !OSSL_PROVIDER_unload(openssl_legacy_provider)) {
 
  394                fr_tls_log(NULL, 
"Failed unloading legacy provider");
 
  396        openssl_legacy_provider = NULL;
 
  399static int fr_openssl_cleanup(
UNUSED void *uctx)
 
  405#if OPENSSL_VERSION_NUMBER >= 0x30400000L 
  407static void *fr_openssl_stack_alloc(
size_t *len)
 
  414#if defined(__linux__) || defined(__FreeBSD__) 
  415        stack = mmap(NULL, openssl_stack_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_STACK, -1, 0);
 
  417        stack = mmap(NULL, openssl_stack_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
 
  419        if (
stack == MAP_FAILED) {
 
  420                fr_tls_log(NULL, 
"Failed allocating OpenSSL stack: %s", 
fr_syserror(errno));
 
  423        *len = openssl_stack_size;
 
  428static void fr_openssl_stack_free(
void *
stack)
 
  430        munmap(
stack, openssl_stack_size);
 
  439int fr_openssl_init(
void)
 
  441        pthread_attr_t tattr;
 
  443        if (openssl_instance_count > 0) {
 
  444                openssl_instance_count++;
 
  448        pthread_attr_init(&tattr);
 
  449        if (pthread_attr_getstacksize(&tattr, &openssl_stack_size) != 0) {
 
  450                fr_tls_log(NULL, 
"Failed getting stack size");
 
  458        if (CRYPTO_set_mem_functions(fr_openssl_talloc, fr_openssl_talloc_realloc, fr_openssl_talloc_free) != 1) {
 
  459                fr_tls_log(NULL, 
"Failed to set OpenSSL memory allocation functions.  fr_openssl_init() called too late");
 
  467#if OPENSSL_VERSION_NUMBER >= 0x30400000L 
  468        if (ASYNC_set_mem_functions(fr_openssl_stack_alloc, fr_openssl_stack_free) != 1) {
 
  469                fr_tls_log(NULL, 
"Failed to set OpenSSL async stack allocation functions");
 
  482        if (OPENSSL_init_ssl(OPENSSL_INIT_NO_ATEXIT | OPENSSL_INIT_LOAD_CONFIG, NULL) != 1) {
 
  483                fr_tls_log(NULL, 
"Failed calling OPENSSL_init_crypto()");
 
  490        openssl_default_provider = OSSL_PROVIDER_load(NULL, 
"default");
 
  491        if (!openssl_default_provider) {
 
  492                fr_tls_log(NULL, 
"Failed loading default provider");
 
  501        openssl_legacy_provider = OSSL_PROVIDER_load(NULL, 
"legacy");
 
  502        if (!openssl_legacy_provider) {
 
  503                fr_tls_log(NULL, 
"Failed loading legacy provider");
 
  512        OPENSSL_atexit(_openssl_provider_free);
 
  519        EVP_add_digest(EVP_sha256());
 
  535        openssl_instance_count++;
 
  547int fr_openssl_fips_mode(
bool enabled)
 
  549        if (!EVP_set_default_properties(NULL, enabled ? 
"fips=yes" : 
"-fips")) {
 
  550                fr_tls_log(NULL, 
"Failed %s OpenSSL FIPS mode", enabled ? 
"enabling" : 
"disabling");
 
  566int fr_tls_dict_init(
void)
 
  568        if (tls_instance_count > 0) {
 
  569                tls_instance_count++;
 
  573        tls_instance_count++;
 
  576                PERROR(
"Failed initialising protocol library");
 
  578                tls_instance_count--;
 
  584                PERROR(
"Failed resolving attributes");
 
  589                PERROR(
"Failed resolving enums");
 
  596void fr_tls_dict_free(
void)
 
  598        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.
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
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_certificate_x509v3_basic_constraints
fr_value_box_t const  * enum_tls_packet_type_success
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_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
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_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
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_psk_identity
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_der_certificate
HIDDEN fr_dict_attr_t const  * attr_tls_certificate_signature
HIDDEN fr_dict_attr_t const  * attr_tls_session_resume_type
HIDDEN fr_dict_attr_t const  * attr_tls_ocsp_next_update
fr_value_box_t const  * enum_tls_packet_type_verify_certificate
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_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_BOOL
A truth value.
@ FR_TYPE_OCTETS
Raw octets.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.