]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ssl: Add 'show ssl providers' cli command and providers list in -vv option
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Thu, 21 Apr 2022 10:06:41 +0000 (12:06 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Thu, 21 Apr 2022 12:54:45 +0000 (14:54 +0200)
Starting from OpenSSLv3, providers are at the core of cryptography
functions. Depending on the provider used, the way the SSL
functionalities work could change. This new 'show ssl providers' CLI
command allows to show what providers were loaded by the SSL library.
This is required because the provider configuration is exclusively done
in the OpenSSL configuration file (/usr/local/ssl/openssl.cnf for
instance).
A new line is also added to the 'haproxy -vv' output containing the same
information.

doc/management.txt
include/haproxy/openssl-compat.h
src/ssl_sock.c

index f0fdcc009daa220e3e50c134c15e7e45576c6439..d21bc452ce46512a776ef10eca7bb328985dfbfa 100644 (file)
@@ -3359,6 +3359,18 @@ show ssl ocsp-response [<id>]
       Next Update: Oct 12 15:43:38 2048 GMT
       [...]
 
+show ssl providers
+  Display the names of the providers loaded by OpenSSL during init. Provider
+  loading can indeed be configured via the OpenSSL configuration file and this
+  option allows to check that the right providers were loaded. This command is
+  only available with OpenSSL v3.
+
+  Example :
+    $ echo "show ssl providers" | socat /var/run/haproxy.master -
+    Loaded providers :
+        - fips
+        - base
+
 show table
   Dump general information on all known stick-tables. Their name is returned
   (the name of the proxy which holds them), their type (currently zero, always
index f69139bb72c18e6de28f8b7241dda504d96ecf56..5aaa6c7e9751eb8c65ce040cc8d61659d22c5539 100644 (file)
@@ -28,6 +28,7 @@
 #include <openssl/core_names.h>
 #include <openssl/decoder.h>
 #include <openssl/param_build.h>
+#include <openssl/provider.h>
 #endif
 
 #if defined(LIBRESSL_VERSION_NUMBER)
@@ -92,6 +93,9 @@
 #define HASSL_DH EVP_PKEY
 #define HASSL_DH_free EVP_PKEY_free
 #define HASSL_DH_up_ref EVP_PKEY_up_ref
+
+#define HAVE_SSL_PROVIDERS
+
 #else /* HA_OPENSSL_VERSION_NUMBER >= 0x3000000fL */
 #define MAC_CTX HMAC_CTX
 #define HASSL_DH DH
index a7f232e4ffda93631a5419973d7ed4cbda3a3e2e..d823d92d3caba37bfd689f6f054e6da1c64aacda 100644 (file)
@@ -7576,6 +7576,84 @@ yield:
 #endif
 }
 
+#ifdef HAVE_SSL_PROVIDERS
+struct provider_name {
+       const char *name;
+       struct list list;
+};
+
+
+static int ssl_provider_get_name_cb(OSSL_PROVIDER *provider, void *cbdata)
+{
+       struct list *provider_names = cbdata;
+       struct provider_name *item = NULL;
+       const char *name = OSSL_PROVIDER_get0_name(provider);
+
+       if (!provider_names)
+               return 0;
+
+       item = calloc(1, sizeof(*item));
+
+       if (!item)
+               return 0;
+
+       item->name = name;
+       LIST_APPEND(provider_names, &item->list);
+
+       return 1;
+}
+
+static void ssl_provider_get_name_list(struct list *provider_names)
+{
+       if (!provider_names)
+               return;
+
+       OSSL_PROVIDER_do_all(NULL, ssl_provider_get_name_cb, provider_names);
+}
+
+static void ssl_provider_clear_name_list(struct list *provider_names)
+{
+       struct provider_name *item = NULL, *item_s = NULL;
+
+       if (provider_names) {
+               list_for_each_entry_safe(item, item_s, provider_names, list) {
+                       LIST_DELETE(&item->list);
+                       free(item);
+               }
+       }
+}
+
+static int cli_io_handler_show_providers(struct appctx *appctx)
+{
+       struct buffer *trash = get_trash_chunk();
+       struct conn_stream *cs = appctx->owner;
+       struct list provider_names;
+       struct provider_name *name;
+
+       LIST_INIT(&provider_names);
+
+       chunk_appendf(trash, "Loaded providers : \n");
+
+       ssl_provider_get_name_list(&provider_names);
+
+       list_for_each_entry(name, &provider_names, list) {
+               chunk_appendf(trash, "\t- %s\n", name->name);
+       }
+
+       ssl_provider_clear_name_list(&provider_names);
+
+       if (ci_putchk(cs_ic(cs), trash) == -1) {
+               cs_rx_room_blk(cs);
+               goto yield;
+       }
+
+       return 1;
+
+yield:
+       return 0;
+}
+#endif
+
 
 #if ((defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP) && !defined OPENSSL_IS_BORINGSSL)
 /*
@@ -7715,6 +7793,9 @@ static struct cli_kw_list cli_kws = {{ },{
        { { "set", "ssl", "ocsp-response", NULL }, "set ssl ocsp-response <resp|payload>    : update a certificate's OCSP Response from a base64-encode DER",      cli_parse_set_ocspresponse, NULL },
 
        { { "show", "ssl", "ocsp-response", NULL },"show ssl ocsp-response [id]             : display the IDs of the OCSP responses used in memory, or the details of a single OCSP response", cli_parse_show_ocspresponse, cli_io_handler_show_ocspresponse, NULL },
+#ifdef HAVE_SSL_PROVIDERS
+       { { "show", "ssl", "providers", NULL },    "show ssl providers                      : show loaded SSL providers", NULL, cli_io_handler_show_providers },
+#endif
        { { NULL }, NULL, NULL, NULL }
 }};
 
@@ -7998,6 +8079,23 @@ static void ssl_register_build_options()
                if (methodVersions[i].option)
                        memprintf(&ptr, "%s %s", ptr, methodVersions[i].name);
 
+#ifdef HAVE_SSL_PROVIDERS
+       {
+               struct list provider_names;
+               struct provider_name *name;
+               LIST_INIT(&provider_names);
+               ssl_provider_get_name_list(&provider_names);
+
+               memprintf(&ptr, "%s\nOpenSSL providers loaded :", ptr);
+
+               list_for_each_entry(name, &provider_names, list) {
+                       memprintf(&ptr, "%s %s", ptr, name->name);
+               }
+
+               ssl_provider_clear_name_list(&provider_names);
+       }
+#endif
+
        hap_register_build_opts(ptr, 1);
 }