diff --git a/stunnel-5.72-speed-up-loading-client-CA-list.patch b/stunnel-5.72-speed-up-loading-client-CA-list.patch new file mode 100644 index 0000000..7c16aa8 --- /dev/null +++ b/stunnel-5.72-speed-up-loading-client-CA-list.patch @@ -0,0 +1,107 @@ +From 5f0b818f62720d5bd8b8c9c631604ddb4c992be7 Mon Sep 17 00:00:00 2001 +From: Clemens Lang +Date: Wed, 31 Jul 2024 15:35:24 +0200 +Subject: [PATCH] src/verify.c: Speed up loading client CA list + +Do not attempt to load and print all trusted CAs unless we need them to +invoke SSL_CTX_set_client_CA_list(3). Loading all trusted CAs can be +slow, especially if there are many. The CAdir format allows OpenSSL to +only load them on demand, avoiding this overhead. + +Additionally, SSL_CTX_load_verify_locations(3) supports file formats +that SSL_load_client_CA_file(3) and SSL_add_*_cert_subjects_to_stack(3) +do not support, for example certificates in the BEGIN TRUSTED +CERTIFICATE format. Valid configurations with older stunnel versions +that point to such a file would otherwise needlessly start failing. + +Additionally, use SSL_load_client_CA_file(3) to load certificates from +a file rather than SSL_add_file_cert_subjects_to_stack(3), since the +former uses a hashtable for deduplication, but the latter relies on +a sorted STACK_OF(X509_NAME). The sorting is exceptionally slow in +OpenSSL, because the comparison function for X509_NAMEs converts them to +DER involving a memory allocation, which is already expensive, but even +more expensive when used with stunnel's custom allocator functions. + +An upstream PR openssl/openssl#25056 will eventually fix this, but it +will take quite a while for this to arrive on users' systems, and it +will likely not be backported into older affected versions of OpenSSL or +their forks. + +Related: RHEL-50154 +Related: RHEL-46411 +Signed-off-by: Clemens Lang +--- + src/verify.c | 42 ++++++++++++++++++++++++++++-------------- + 1 file changed, 28 insertions(+), 14 deletions(-) + +diff --git a/src/verify.c b/src/verify.c +index 56ab130..d1d3849 100644 +--- a/src/verify.c ++++ b/src/verify.c +@@ -95,10 +95,35 @@ NOEXPORT int init_ca(SERVICE_OPTIONS *section) { + if(!SSL_CTX_load_verify_locations(section->ctx, + section->ca_file, section->ca_dir)) { + sslerror("SSL_CTX_load_verify_locations"); ++ return 1; /* FAILED */ + } + } + +- ca_dn=sk_X509_NAME_new_null(); ++ /* Do not attempt to load and print all trusted CAs unless we need them to ++ invoke SSL_CTX_set_client_CA_list(3). Loading all trusted CAs can be ++ slow, especially if there are many. The CAdir format allows OpenSSL to ++ only load them on demand. ++ Additionally, SSL_CTX_load_verify_locations(3) supports file formats ++ that SSL_load_client_CA_file(3) and SSL_add_*_cert_subjects_to_stack(3) ++ do not support, for example certificates in the BEGIN TRUSTED ++ CERTIFICATE format. Valid configurations with older stunnel versions ++ that point to such a file would otherwise needlessly start failing. */ ++ if(section->option.client) ++ return 0; /* OK */ ++ ++ if(section->ca_file) ++ /* SSL_load_client_CA_file is a lot faster than ++ SSL_add_file_cert_subjects_to_stack(). Use it for ca_file if ++ specified, then add the rest of the certificates to this stack. */ ++ ca_dn=SSL_load_client_CA_file(section->ca_file); ++ ++ if (!ca_dn) ++ /* ca_file not set, or SSL_load_client_CA_file(3) failed. */ ++ ca_dn=sk_X509_NAME_new_null(); ++ ++ /* client CA list initialization from directory */ ++ if(section->ca_dir) ++ SSL_add_dir_cert_subjects_to_stack(ca_dn, section->ca_dir); + + #ifndef OPENSSL_NO_ENGINE + /* CA and client CA list initialization with the engine */ +@@ -115,24 +140,13 @@ NOEXPORT int init_ca(SERVICE_OPTIONS *section) { + } + #endif + +- /* client CA list initialization with the file and/or directory */ +- if(section->ca_file) +- SSL_add_file_cert_subjects_to_stack(ca_dn, section->ca_file); +- if(section->ca_dir) +- SSL_add_dir_cert_subjects_to_stack(ca_dn, section->ca_dir); +- + if(!sk_X509_NAME_num(ca_dn)) { + sk_X509_NAME_pop_free(ca_dn, X509_NAME_free); + return 1; /* FAILED */ + } + +- if(section->option.client) { +- print_CA_list("Configured trusted server CA", ca_dn); +- sk_X509_NAME_pop_free(ca_dn, X509_NAME_free); +- } else { /* only set the client CA list on the server */ +- print_CA_list("Configured trusted client CA", ca_dn); +- SSL_CTX_set_client_CA_list(section->ctx, ca_dn); +- } ++ print_CA_list("Configured trusted client CA", ca_dn); ++ SSL_CTX_set_client_CA_list(section->ctx, ca_dn); + + return 0; /* OK */ + } +-- +2.45.2 + diff --git a/stunnel.spec b/stunnel.spec index 1597e04..b698e34 100644 --- a/stunnel.spec +++ b/stunnel.spec @@ -32,6 +32,7 @@ Patch3: stunnel-5.69-system-ciphers.patch Patch5: stunnel-5.69-default-tls-version.patch Patch6: stunnel-5.56-curves-doc-update.patch Patch7: stunnel-5.71-Preserve-NO_TLSv1.-123-option-compatibility.patch +Patch8: stunnel-5.72-speed-up-loading-client-CA-list.patch # util-linux is needed for rename BuildRequires: make BuildRequires: gcc @@ -64,6 +65,7 @@ conjunction with imapd to create a TLS secure IMAP server. %patch5 -p1 -b .default-tls-version %patch6 -p1 -b .curves-doc-update %patch7 -p1 -b .preserve-no-tlsv1-123-option-compatibility +%patch8 -p1 -b .speed-up-loading-client-CA-list # Fix the stack protector flag sed -i 's/-fstack-protector/-fstack-protector-strong/' configure @@ -142,6 +144,12 @@ fi %systemd_postun_with_restart %{name}.service %changelog +* Wed Aug 07 2024 Clemens Lang - 5.71-2 +- Speed up loading client CA list from CAfile + Resolves: RHEL-46411 +- Do not load all CAs in client mode to allow continued use of BEGIN TRUSTED CERTIFICATE format + Resolves: RHEL-50154 + * Thu Oct 19 2023 Clemens Lang - 5.71-2 - Restore support for the NO_TLSv1.[123] values for the option directive Resolves: RHEL-2340