27 RCSID(
"$Id: dd951b942c4694a9f3ece3dcf25bc4b7518fb7cd $")
31 #define LOG_PREFIX "tls"
36 #include <openssl/conf.h>
37 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
38 # include <openssl/provider.h>
41 #include <freeradius-devel/server/base.h>
42 #include <freeradius-devel/tls/attrs.h>
43 #include <freeradius-devel/tls/base.h>
44 #include <freeradius-devel/tls/engine.h>
45 #include <freeradius-devel/util/atexit.h>
46 #include <freeradius-devel/util/debug.h>
48 static uint32_t openssl_instance_count = 0;
54 _Thread_local TALLOC_CTX *ssl_talloc_ctx;
59 static _Thread_local
bool *async_pool_init;
61 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
62 static OSSL_PROVIDER *openssl_default_provider = NULL;
63 static OSSL_PROVIDER *openssl_legacy_provider = NULL;
66 static uint32_t tls_instance_count = 0;
76 { .out = &
dict_tls, .proto =
"tls" },
202 int fr_tls_max_threads = 1;
211 static char const *async_file;
215 chunk = talloc_array(ssl_talloc_ctx,
uint8_t, len);
218 talloc_set_name(chunk,
"fr_openssl_talloc");
236 sep = strrchr(
file,
'/');
242 if (strcmp(sep,
"async_posix.c") == 0) {
247 }
else if (
file == async_file)
goto alloc_stack;
249 chunk = talloc_array(ssl_talloc_ctx,
uint8_t, len);
251 talloc_set_name(chunk,
"%s:%u",
file,
line);
266 chunk = talloc_realloc_size(ssl_talloc_ctx, old, len);
268 talloc_set_name(chunk,
"%s:%u",
file,
line);
282 static void fr_openssl_talloc_free(
void *to_free,
char const *
file,
UNUSED int line)
284 (void)_talloc_free(to_free,
file);
287 static void fr_openssl_talloc_free(
void *to_free,
char const *
file,
int line)
292 (void)_talloc_free(to_free,
buffer);
299 static int _openssl_thread_free(
void *
init)
301 ASYNC_cleanup_thread();
317 int fr_openssl_thread_init(
size_t async_pool_size_init,
size_t async_pool_size_max)
322 if (!async_pool_init) {
323 bool *
init = talloc_zero(NULL,
bool);
325 if (ASYNC_init_thread(async_pool_size_max, async_pool_size_init) != 1) {
326 fr_tls_log(NULL,
"Failed initialising OpenSSL async context pool");
343 void fr_openssl_free(
void)
345 if (--openssl_instance_count > 0)
return;
352 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
353 static void _openssl_provider_free(
void)
355 if (openssl_default_provider && !OSSL_PROVIDER_unload(openssl_default_provider)) {
356 fr_tls_log(NULL,
"Failed unloading default provider");
358 openssl_default_provider = NULL;
360 if (openssl_legacy_provider && !OSSL_PROVIDER_unload(openssl_legacy_provider)) {
361 fr_tls_log(NULL,
"Failed unloading legacy provider");
363 openssl_legacy_provider = NULL;
367 #if OPENSSL_VERSION_NUMBER < 0x30000000L
368 static void _openssl_engine_free(
void)
370 fr_tls_engine_free_all();
374 static int fr_openssl_cleanup(
UNUSED void *uctx)
385 int fr_openssl_init(
void)
387 if (openssl_instance_count > 0) {
388 openssl_instance_count++;
396 if (CRYPTO_set_mem_functions(fr_openssl_talloc, fr_openssl_talloc_realloc, fr_openssl_talloc_free) != 1) {
397 fr_tls_log(NULL,
"Failed to set OpenSSL memory allocation functions. fr_openssl_init() called too late");
409 if (OPENSSL_init_ssl(OPENSSL_INIT_NO_ATEXIT | OPENSSL_INIT_LOAD_CONFIG, NULL) != 1) {
410 fr_tls_log(NULL,
"Failed calling OPENSSL_init_crypto()");
414 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
418 openssl_default_provider = OSSL_PROVIDER_load(NULL,
"default");
419 if (!openssl_default_provider) {
420 fr_tls_log(NULL,
"Failed loading default provider");
429 openssl_legacy_provider = OSSL_PROVIDER_load(NULL,
"legacy");
430 if (!openssl_legacy_provider) {
431 fr_tls_log(NULL,
"Failed loading legacy provider");
441 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
442 OPENSSL_atexit(_openssl_provider_free);
445 #if OPENSSL_VERSION_NUMBER < 0x30000000L
446 OPENSSL_atexit(_openssl_engine_free);
454 EVP_add_digest(EVP_sha256());
460 #if OPENSSL_VERSION_NUMBER < 0x30000000L
461 fr_tls_engine_load_builtin();
478 openssl_instance_count++;
490 int fr_openssl_fips_mode(
bool enabled)
492 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
493 if (!EVP_set_default_properties(NULL, enabled ?
"fips=yes" :
"fips=no")) {
494 fr_tls_log(NULL,
"Failed %s OpenSSL FIPS mode", enabled ?
"enabling" :
"disabling");
498 if (!FIPS_mode_set(enabled ? 1 : 0)) {
499 fr_tls_log(NULL,
"Failed %s OpenSSL FIPS mode", enabled ?
"enabling" :
"disabling");
516 int fr_tls_dict_init(
void)
518 if (tls_instance_count > 0) {
519 tls_instance_count++;
523 tls_instance_count++;
526 PERROR(
"Failed initialising protocol library");
528 tls_instance_count--;
534 PERROR(
"Failed resolving attributes");
539 PERROR(
"Failed resolving enums");
546 void fr_tls_dict_free(
void)
548 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)
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.
fr_dict_attr_t const * attr_tls_certificate
Attribute definitions for lib curl.
fr_dict_t const * dict_freeradius
fr_dict_t const * dict_radius
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_t const * dict_tls
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_attr_t const * attr_tls_certificate_subject_alt_name_dns
HIDDEN fr_dict_attr_t const * attr_tls_session_ttl
HIDDEN fr_dict_attr_t const * attr_framed_mtu
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_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
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_packet_type_notfound
HIDDEN fr_dict_attr_t const * attr_tls_certificate_signature
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_subject_alt_name_email
HIDDEN fr_dict_attr_t const * attr_allow_session_resumption
@ 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)
init
Enter the EAP-IDENTITY state.