Re-implement the cipher and digest listings for 'openssl list'

They now display both legacy and provided algorithms.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9356)
This commit is contained in:
Richard Levitte 2019-07-13 07:04:01 +02:00
parent c540f00f38
commit b8441adb59
2 changed files with 95 additions and 6 deletions

View File

@ -10,6 +10,8 @@
#include <string.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/provider.h>
#include <openssl/safestack.h>
#include "apps.h"
#include "progs.h"
#include "opt.h"
@ -18,30 +20,113 @@ 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 = "<undefined>";
if (to == NULL)
to = "<undefined>";
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 = "<undefined>";
if (to == NULL)
to = "<undefined>";
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,
const char *from, const char *to, void *arg)
{
@ -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();

View File

@ -53,6 +53,8 @@ as input to the L<dgst(1)> or L<speed(1)> commands.
Display a list of message digest algorithms.
If a line is of the form C<foo =E<gt> bar> then B<foo> is an alias for the
official algorithm name, B<bar>.
If a line is of the form C<foo @ bar>, then B<foo> is provided by the provider
B<bar>.
=item B<-mac-algorithms>
@ -70,6 +72,8 @@ to the L<dgst(1)> or L<speed(1)> commands.
Display a list of cipher algorithms.
If a line is of the form C<foo =E<gt> bar> then B<foo> is an alias for the
official algorithm name, B<bar>.
If a line is of the form C<foo @ bar>, then B<foo> is provided by the provider
B<bar>.
=item B<-public-key-algorithms>