From b8441adb593392e224eccc95495e9a7451d04821 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Sat, 13 Jul 2019 07:04:01 +0200 Subject: [PATCH] Re-implement the cipher and digest listings for 'openssl list' They now display both legacy and provided algorithms. Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/9356) --- apps/list.c | 97 ++++++++++++++++++++++++++++++++++++++++++++--- doc/man1/list.pod | 4 ++ 2 files changed, 95 insertions(+), 6 deletions(-) diff --git a/apps/list.c b/apps/list.c index 8e4f00585a..5f05fb980b 100644 --- a/apps/list.c +++ b/apps/list.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include "apps.h" #include "progs.h" #include "opt.h" @@ -18,28 +20,111 @@ static void list_cipher_fn(const EVP_CIPHER *c, const char *from, const char *to, void *arg) { if (c != NULL) { - BIO_printf(arg, "%s\n", EVP_CIPHER_name(c)); + BIO_printf(arg, " %s\n", EVP_CIPHER_name(c)); } else { if (from == NULL) from = ""; if (to == NULL) to = ""; - BIO_printf(arg, "%s => %s\n", from, to); + BIO_printf(arg, " %s => %s\n", from, to); + } +} + +DEFINE_STACK_OF(EVP_CIPHER) +static int cipher_cmp(const EVP_CIPHER * const *a, + const EVP_CIPHER * const *b) +{ + int ret = strcasecmp(EVP_CIPHER_name(*a), EVP_CIPHER_name(*b)); + + if (ret == 0) + ret = strcmp(OSSL_PROVIDER_name(EVP_CIPHER_provider(*a)), + OSSL_PROVIDER_name(EVP_CIPHER_provider(*b))); + + return ret; +} + +static void collect_ciphers(EVP_CIPHER *cipher, void *stack) +{ + STACK_OF(EVP_CIPHER) *cipher_stack = stack; + + sk_EVP_CIPHER_push(cipher_stack, cipher); + EVP_CIPHER_up_ref(cipher); +} + +static void list_ciphers(void) +{ + STACK_OF(EVP_CIPHER) *ciphers = sk_EVP_CIPHER_new(cipher_cmp); + int i; + + BIO_printf(bio_out, "Legacy:\n"); + EVP_CIPHER_do_all_sorted(list_cipher_fn, bio_out); + + BIO_printf(bio_out, "Provided:\n"); + EVP_CIPHER_do_all_ex(NULL, collect_ciphers, ciphers); + sk_EVP_CIPHER_sort(ciphers); + for (i = 0; i < sk_EVP_CIPHER_num(ciphers); i++) { + const EVP_CIPHER *c = sk_EVP_CIPHER_value(ciphers, i); + + BIO_printf(bio_out, " %s", EVP_CIPHER_name(c)); + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_name(EVP_CIPHER_provider(c))); } + sk_EVP_CIPHER_pop_free(ciphers, EVP_CIPHER_meth_free); } static void list_md_fn(const EVP_MD *m, const char *from, const char *to, void *arg) { if (m != NULL) { - BIO_printf(arg, "%s\n", EVP_MD_name(m)); + BIO_printf(arg, " %s\n", EVP_MD_name(m)); } else { if (from == NULL) from = ""; if (to == NULL) to = ""; - BIO_printf((BIO *)arg, "%s => %s\n", from, to); + BIO_printf((BIO *)arg, " %s => %s\n", from, to); + } +} + +DEFINE_STACK_OF(EVP_MD) +static int md_cmp(const EVP_MD * const *a, const EVP_MD * const *b) +{ + int ret = strcasecmp(EVP_MD_name(*a), EVP_MD_name(*b)); + + if (ret == 0) + ret = strcmp(OSSL_PROVIDER_name(EVP_MD_provider(*a)), + OSSL_PROVIDER_name(EVP_MD_provider(*b))); + + return ret; +} + +static void collect_digests(EVP_MD *md, void *stack) +{ + STACK_OF(EVP_MD) *digest_stack = stack; + + sk_EVP_MD_push(digest_stack, md); + EVP_MD_up_ref(md); +} + +static void list_digests(void) +{ + STACK_OF(EVP_MD) *digests = sk_EVP_MD_new(md_cmp); + int i; + + BIO_printf(bio_out, "Legacy:\n"); + EVP_MD_do_all_sorted(list_md_fn, bio_out); + + BIO_printf(bio_out, "Provided:\n"); + EVP_MD_do_all_ex(NULL, collect_digests, digests); + sk_EVP_MD_sort(digests); + for (i = 0; i < sk_EVP_MD_num(digests); i++) { + const EVP_MD *c = sk_EVP_MD_value(digests, i); + + BIO_printf(bio_out, " %s", EVP_MD_name(c)); + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_name(EVP_MD_provider(c))); } + sk_EVP_MD_pop_free(digests, EVP_MD_meth_free); } static void list_mac_fn(const EVP_MAC *m, @@ -450,7 +535,7 @@ opthelp: list_type(FT_md, one); break; case OPT_DIGEST_ALGORITHMS: - EVP_MD_do_all_sorted(list_md_fn, bio_out); + list_digests(); break; case OPT_MAC_ALGORITHMS: EVP_MAC_do_all_sorted(list_mac_fn, bio_out); @@ -459,7 +544,7 @@ opthelp: list_type(FT_cipher, one); break; case OPT_CIPHER_ALGORITHMS: - EVP_CIPHER_do_all_sorted(list_cipher_fn, bio_out); + list_ciphers(); break; case OPT_PK_ALGORITHMS: list_pkey(); diff --git a/doc/man1/list.pod b/doc/man1/list.pod index 901a2668dd..1e4d7cdd0a 100644 --- a/doc/man1/list.pod +++ b/doc/man1/list.pod @@ -53,6 +53,8 @@ as input to the L or L commands. Display a list of message digest algorithms. If a line is of the form C bar> then B is an alias for the official algorithm name, B. +If a line is of the form C, then B is provided by the provider +B. =item B<-mac-algorithms> @@ -70,6 +72,8 @@ to the L or L commands. Display a list of cipher algorithms. If a line is of the form C bar> then B is an alias for the official algorithm name, B. +If a line is of the form C, then B is provided by the provider +B. =item B<-public-key-algorithms> -- 2.25.1