Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,7 @@ AS_IF([test "x$with_openssl" = "xyes"],[
openssl/engine.h \
openssl/txt_db.h \
openssl/pem.h \
openssl/provider.h \
)

# User may have provided a custom location for OpenSSL. Otherwise...
Expand Down
1 change: 1 addition & 0 deletions src/SquidConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ class SquidConfig
struct {
int unclean_shutdown;
char *ssl_engine;
char *ssl_provider;
int session_ttl;
size_t sessionCacheSize;
char *certSignHash;
Expand Down
13 changes: 13 additions & 0 deletions src/cf.data.pre
Original file line number Diff line number Diff line change
Expand Up @@ -3150,6 +3150,19 @@ DOC_START
Not supported in builds with OpenSSL 3.0 or newer.
DOC_END

NAME: ssl_provider
IFDEF: USE_OPENSSL&&OPENSSL_VERSION_MAJOR>=3
TYPE: string
LOC: Config.SSL.ssl_provider
DEFAULT: none
DOC_START
The OpenSSL provider to use.

When configured, Squid will only uses this named provider with
no additional parameters. Provider settings configured in
openssl.conf are ignored.
DOC_END

NAME: sslproxy_session_ttl
IFDEF: USE_OPENSSL
DEFAULT: 300
Expand Down
1 change: 1 addition & 0 deletions src/cf_gen_defines
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ BEGIN {
define["USE_ICMP"]="--enable-icmp"
define["USE_LOADABLE_MODULES"]="--enable-shared"
define["USE_OPENSSL"]="--with-openssl"
define["USE_OPENSSL&&OPENSSL_VERSION_MAJOR>=3"]="--with-openssl (v3.0 or newer)"
define["USE_QOS_TOS"]="--enable-zph-qos"
define["USE_SQUID_EUI"]="--enable-eui"
define["USE_SSL_CRTD"]="--enable-ssl-crtd"
Expand Down
88 changes: 88 additions & 0 deletions src/ssl/support.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
#include "anyp/Host.h"
#include "anyp/PortCfg.h"
#include "anyp/Uri.h"
#include "base/Raw.h"
#include "fatal.h"
#include "fd.h"
#include "fde.h"
#include "globals.h"
#include "ip/Address.h"
#include "ipc/MemMap.h"
#include "sbuf/Stream.h"
#include "security/CertError.h"
#include "security/Certificate.h"
#include "security/ErrorDetail.h"
Expand All @@ -38,6 +40,10 @@

#include <cerrno>

#if HAVE_OPENSSL_PROVIDER_H
#include <openssl/provider.h>
#endif

// TODO: Move ssl_ex_index_* global variables from global.cc here.
static int ssl_ex_index_verify_callback_parameters = -1;

Expand Down Expand Up @@ -743,6 +749,77 @@ ssl_free_VerifyCallbackParameters(void *, void *ptr, CRYPTO_EX_DATA *,
delete static_cast<Ssl::VerifyCallbackParameters*>(ptr);
}

#if OPENSSL_VERSION_MAJOR >= 3
static int
DisplayProviderInfo(OSSL_PROVIDER *provider, void *)
{
SBufStream out;
const auto params = OSSL_PROVIDER_gettable_params(provider);
for (int i = 0; params[i].key; ++i) {
out << (i > 0 ? "," : "");

OSSL_PARAM detail[2] = {OSSL_PARAM_END, OSSL_PARAM_END};
switch (params[i].data_type)
{
case OSSL_PARAM_INTEGER: {
int value = 0;
detail[0] = OSSL_PARAM_construct_int(params[i].key, &value);
if (OSSL_PROVIDER_get_params(provider, detail))
out << ' ' << detail[0].key << '=' << value;
}
break;
case OSSL_PARAM_UNSIGNED_INTEGER: {
unsigned int value = 0;
detail[0] = OSSL_PARAM_construct_uint(params[i].key, &value);
if (OSSL_PROVIDER_get_params(provider, detail))
out << ' ' << detail[0].key << '=' << value;
}
break;
case OSSL_PARAM_REAL: {
double value = 0.0;
detail[0] = OSSL_PARAM_construct_double(params[i].key, &value);
if (OSSL_PROVIDER_get_params(provider, detail))
out << ' ' << detail[0].key << '=' << value;
}
break;
case OSSL_PARAM_UTF8_STRING: {
char *value = nullptr;
detail[0] = OSSL_PARAM_construct_utf8_string(params[i].key, value, 0);
if (OSSL_PROVIDER_get_params(provider, detail))
out << Raw(detail[0].key, value, detail[0].return_size);
}
break;
case OSSL_PARAM_OCTET_STRING: {
char *value = nullptr;
detail[0] = OSSL_PARAM_construct_octet_string(params[i].key, static_cast<void*>(value), 0);
if (OSSL_PROVIDER_get_params(provider, detail))
out << Raw(detail[0].key, value, detail[0].return_size).hex();
}
break;
case OSSL_PARAM_UTF8_PTR: {
char *value = nullptr;
detail[0] = OSSL_PARAM_construct_utf8_ptr(params[i].key, &value, 0);
OSSL_PARAM_set_all_unmodified(detail);
if (OSSL_PROVIDER_get_params(provider, detail))
out << Raw(detail[0].key, value, detail[0].return_size);
}
break;
case OSSL_PARAM_OCTET_PTR: {
char *value = nullptr;
detail[0] = OSSL_PARAM_construct_octet_ptr(params[i].key, reinterpret_cast<void**>(&value), 0);
if (OSSL_PROVIDER_get_params(provider, detail))
out << Raw(detail[0].key, value, detail[0].return_size).hex();
}
break;
}
}

const auto name = OSSL_PROVIDER_get0_name(provider);
debugs(83, DBG_PARSE_NOTE(3), "Provider: " << name << '(' << out.buf() << " )");
return 1;
}
#endif /* OPENSSL_VERSION_MAJOR >= 3 */

void
Ssl::Initialize(void)
{
Expand Down Expand Up @@ -777,6 +854,17 @@ Ssl::Initialize(void)
#endif
}

#if OPENSSL_VERSION_MAJOR >= 3
if (::Config.SSL.ssl_provider) {
if (!OSSL_PROVIDER_load(nullptr, ::Config.SSL.ssl_provider)) {
const auto ssl_error = ERR_get_error();
fatalf("Failed to load SSL provider: %s\n", Security::ErrorString(ssl_error));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not call fatalf() when reacting to a configuration application failure. Throw an exception instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately this function is not only called during startup. It can be delayed and called later in Squid operation after a reconfigure. The exception handlers for that case are not yet reliable.

FWIW, I planned to fix the above situation with the project moving init things into runners. But that work got stalled.

}
}
const auto debugResult = OSSL_PROVIDER_do_all(nullptr, &DisplayProviderInfo, nullptr);
assert(debugResult == 1); // paranoid check that DisplayProviderInfo() returns 1
#endif /* OPENSSL_VERSION_MAJOR >= 3 */

const char *defName = ::Config.SSL.certSignHash ? ::Config.SSL.certSignHash : SQUID_SSL_SIGN_HASH_IF_NONE;
Ssl::DefaultSignHash = EVP_get_digestbyname(defName);
if (!Ssl::DefaultSignHash)
Expand Down
Loading