- ssl-default-server-options
- ssl-dh-param-file
- ssl-propquery
+ - ssl-provider
- ssl-server-verify
- ssl-skip-self-issued-ca
- unix-bind
foo provider by default, and to fallback on the default provider's one if it
was not found.
+ssl-provider <name>
+ This setting is only available when support for OpenSSL was built in and when
+ OpenSSL's version is at least 3.0. It allows to load a provider during init.
+ If loading is successful, any capabilities provided by the loaded provider
+ might be used by HAProxy. Multiple 'ssl-provider' options can be specified in
+ a configuration file. The providers will be loaded in their order of
+ appearance.
+ Please note that loading a provider explicitely prevents OpenSSL from loading
+ the 'default' provider automatically. OpenSSL also allows to define the
+ providers that should be loaded directly in its configuration file
+ (openssl.cnf for instance) so it is not necessary to use this 'ssl-provider'
+ option to load providers. The "show ssl providers" CLI command can be used to
+ show all the providers that were successfully loaded.
+ The default search path of OpenSSL provider can be found in the output of the
+ "openssl version -a" command. If the provider is in another directory, you
+ can set the OPENSSL_MODULES environment variable, which takes the directory
+ where your provider can be found.
+ See also "ssl-propquery".
+
ssl-load-extra-del-ext
This setting allows to configure the way HAProxy does the lookup for the
extra SSL files. By default HAProxy adds a new extension to the filename.
extern int ssl_client_sni_index;
extern struct pool_head *pool_head_ssl_keylog;
extern struct pool_head *pool_head_ssl_keylog_str;
+extern struct list openssl_providers;
int ssl_sock_prep_ctx_and_inst(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
SSL_CTX *ctx, struct ckch_inst *ckch_inst, char **err);
void ssl_free_dh(void);
#endif
void ssl_free_engines(void);
+#ifdef HAVE_SSL_PROVIDERS
+void ssl_unload_providers(void);
+#endif
#ifdef HAVE_SSL_CLIENT_HELLO_CB
int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv);
#ifdef OPENSSL_IS_BORINGSSL
int ssl_initialize_random(void);
int ssl_sock_load_cert_list_file(char *file, int dir, struct bind_conf *bind_conf, struct proxy *curproxy, char **err);
int ssl_init_single_engine(const char *engine_id, const char *def_algorithms);
+#ifdef HAVE_SSL_PROVIDERS
+int ssl_init_provider(const char *provider_name);
+#endif
#if ((defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP) && !defined OPENSSL_IS_BORINGSSL)
int ssl_get_ocspresponse_detail(unsigned char *ocsp_certid, struct buffer *out);
int ssl_ocsp_response_print(struct buffer *ocsp_response, struct buffer *out);
return ret;
}
+
+/* parse the "ssl-provider" keyword in global section.
+ * Returns <0 on alert, >0 on warning, 0 on success.
+ */
+static int ssl_parse_global_ssl_provider(char **args, int section_type, struct proxy *curpx,
+ const struct proxy *defpx, const char *file, int line,
+ char **err)
+{
+ int ret = -1;
+
+ if (*(args[1]) == 0) {
+ memprintf(err, "global statement '%s' expects a valid engine provider name as an argument.", args[0]);
+ return ret;
+ }
+
+ if (ssl_init_provider(args[1]) == 0)
+ ret = 0;
+
+ return ret;
+}
#endif
/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
#endif
#ifdef HAVE_SSL_PROVIDERS
{ CFG_GLOBAL, "ssl-propquery", ssl_parse_global_ssl_propquery },
+ { CFG_GLOBAL, "ssl-provider", ssl_parse_global_ssl_provider },
#endif
{ CFG_GLOBAL, "ssl-skip-self-issued-ca", ssl_parse_skip_self_issued_ca },
{ CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
};
#endif
+#ifdef HAVE_SSL_PROVIDERS
+struct list openssl_providers = LIST_HEAD_INIT(openssl_providers);
+struct ssl_provider_list {
+ struct list list;
+ OSSL_PROVIDER *provider;
+};
+#endif
+
#ifndef OPENSSL_NO_DH
static int ssl_dh_ptr_index = -1;
static HASSL_DH *global_dh = NULL;
}
#endif
+#ifdef HAVE_SSL_PROVIDERS
+int ssl_init_provider(const char *provider_name)
+{
+ int err_code = ERR_ABORT;
+ struct ssl_provider_list *prov = NULL;
+
+ prov = calloc(1, sizeof(*prov));
+ if (!prov) {
+ ha_alert("ssl-provider %s: memory allocation failure\n", provider_name);
+ goto error;
+ }
+
+ if ((prov->provider = OSSL_PROVIDER_load(NULL, provider_name)) == NULL) {
+ ha_alert("ssl-provider %s: unknown provider\n", provider_name);
+ goto error;
+ }
+
+ LIST_INSERT(&openssl_providers, &prov->list);
+
+ return 0;
+
+error:
+ ha_free(&prov);
+ return err_code;
+}
+#endif /* HAVE_SSL_PROVIDERS */
+
#ifdef SSL_MODE_ASYNC
/*
* openssl async fd handler
#if defined(USE_ENGINE) && !defined(OPENSSL_NO_ENGINE)
hap_register_post_deinit(ssl_free_engines);
#endif
+#ifdef HAVE_SSL_PROVIDERS
+ hap_register_post_deinit(ssl_unload_providers);
+#endif
#if HA_OPENSSL_VERSION_NUMBER < 0x3000000fL
/* Load SSL string for the verbose & debug mode. */
ERR_load_SSL_strings();
}
#endif
+#ifdef HAVE_SSL_PROVIDERS
+void ssl_unload_providers(void) {
+ struct ssl_provider_list *prov, *provb;
+ list_for_each_entry_safe(prov, provb, &openssl_providers, list) {
+ OSSL_PROVIDER_unload(prov->provider);
+ LIST_DELETE(&prov->list);
+ free(prov);
+ }
+}
+#endif
+
#ifndef OPENSSL_NO_DH
void ssl_free_dh(void) {
if (local_dh_1024) {