xref: /third_party/openssl/apps/list.c (revision e1051a39)
1/*
2 * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License").  You may not use
5 * this file except in compliance with the License.  You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10/* We need to use some deprecated APIs */
11#define OPENSSL_SUPPRESS_DEPRECATED
12
13#include <string.h>
14#include <openssl/evp.h>
15#include <openssl/err.h>
16#include <openssl/provider.h>
17#include <openssl/safestack.h>
18#include <openssl/kdf.h>
19#include <openssl/encoder.h>
20#include <openssl/decoder.h>
21#include <openssl/store.h>
22#include <openssl/core_names.h>
23#include <openssl/rand.h>
24#include "apps.h"
25#include "app_params.h"
26#include "progs.h"
27#include "opt.h"
28#include "names.h"
29
30static int verbose = 0;
31static const char *select_name = NULL;
32
33/* Checks to see if algorithms are fetchable */
34#define IS_FETCHABLE(type, TYPE)                                \
35    static int is_ ## type ## _fetchable(const TYPE *alg)       \
36    {                                                           \
37        TYPE *impl;                                             \
38        const char *propq = app_get0_propq();                   \
39        OSSL_LIB_CTX *libctx = app_get0_libctx();               \
40        const char *name = TYPE ## _get0_name(alg);             \
41                                                                \
42        ERR_set_mark();                                         \
43        impl = TYPE ## _fetch(libctx, name, propq);             \
44        ERR_pop_to_mark();                                      \
45        if (impl == NULL)                                       \
46            return 0;                                           \
47        TYPE ## _free(impl);                                    \
48        return 1;                                               \
49    }
50IS_FETCHABLE(cipher, EVP_CIPHER)
51IS_FETCHABLE(digest, EVP_MD)
52IS_FETCHABLE(mac, EVP_MAC)
53IS_FETCHABLE(kdf, EVP_KDF)
54IS_FETCHABLE(rand, EVP_RAND)
55IS_FETCHABLE(keymgmt, EVP_KEYMGMT)
56IS_FETCHABLE(signature, EVP_SIGNATURE)
57IS_FETCHABLE(kem, EVP_KEM)
58IS_FETCHABLE(asym_cipher, EVP_ASYM_CIPHER)
59IS_FETCHABLE(keyexch, EVP_KEYEXCH)
60IS_FETCHABLE(decoder, OSSL_DECODER)
61IS_FETCHABLE(encoder, OSSL_ENCODER)
62
63#ifndef OPENSSL_NO_DEPRECATED_3_0
64static int include_legacy(void)
65{
66    return app_get0_propq() == NULL;
67}
68
69static void legacy_cipher_fn(const EVP_CIPHER *c,
70                             const char *from, const char *to, void *arg)
71{
72    if (select_name != NULL
73        && (c == NULL
74            || OPENSSL_strcasecmp(select_name,  EVP_CIPHER_get0_name(c)) != 0))
75        return;
76    if (c != NULL) {
77        BIO_printf(arg, "  %s\n", EVP_CIPHER_get0_name(c));
78    } else {
79        if (from == NULL)
80            from = "<undefined>";
81        if (to == NULL)
82            to = "<undefined>";
83        BIO_printf(arg, "  %s => %s\n", from, to);
84    }
85}
86#endif
87
88DEFINE_STACK_OF(EVP_CIPHER)
89static int cipher_cmp(const EVP_CIPHER * const *a,
90                      const EVP_CIPHER * const *b)
91{
92    return strcmp(OSSL_PROVIDER_get0_name(EVP_CIPHER_get0_provider(*a)),
93                  OSSL_PROVIDER_get0_name(EVP_CIPHER_get0_provider(*b)));
94}
95
96static void collect_ciphers(EVP_CIPHER *cipher, void *stack)
97{
98    STACK_OF(EVP_CIPHER) *cipher_stack = stack;
99
100    if (is_cipher_fetchable(cipher)
101            && sk_EVP_CIPHER_push(cipher_stack, cipher) > 0)
102        EVP_CIPHER_up_ref(cipher);
103}
104
105static void list_ciphers(void)
106{
107    STACK_OF(EVP_CIPHER) *ciphers = sk_EVP_CIPHER_new(cipher_cmp);
108    int i;
109
110    if (ciphers == NULL) {
111        BIO_printf(bio_err, "ERROR: Memory allocation\n");
112        return;
113    }
114#ifndef OPENSSL_NO_DEPRECATED_3_0
115    if (include_legacy()) {
116        BIO_printf(bio_out, "Legacy:\n");
117        EVP_CIPHER_do_all_sorted(legacy_cipher_fn, bio_out);
118    }
119#endif
120
121    BIO_printf(bio_out, "Provided:\n");
122    EVP_CIPHER_do_all_provided(app_get0_libctx(), collect_ciphers, ciphers);
123    sk_EVP_CIPHER_sort(ciphers);
124    for (i = 0; i < sk_EVP_CIPHER_num(ciphers); i++) {
125        const EVP_CIPHER *c = sk_EVP_CIPHER_value(ciphers, i);
126        STACK_OF(OPENSSL_CSTRING) *names = NULL;
127
128        if (select_name != NULL && !EVP_CIPHER_is_a(c, select_name))
129            continue;
130
131        names = sk_OPENSSL_CSTRING_new(name_cmp);
132        if (names != NULL && EVP_CIPHER_names_do_all(c, collect_names, names)) {
133            BIO_printf(bio_out, "  ");
134            print_names(bio_out, names);
135
136            BIO_printf(bio_out, " @ %s\n",
137                       OSSL_PROVIDER_get0_name(EVP_CIPHER_get0_provider(c)));
138
139            if (verbose) {
140                const char *desc = EVP_CIPHER_get0_description(c);
141
142                if (desc != NULL)
143                    BIO_printf(bio_out, "    description: %s\n", desc);
144                print_param_types("retrievable algorithm parameters",
145                                  EVP_CIPHER_gettable_params(c), 4);
146                print_param_types("retrievable operation parameters",
147                                  EVP_CIPHER_gettable_ctx_params(c), 4);
148                print_param_types("settable operation parameters",
149                                  EVP_CIPHER_settable_ctx_params(c), 4);
150            }
151        }
152        sk_OPENSSL_CSTRING_free(names);
153    }
154    sk_EVP_CIPHER_pop_free(ciphers, EVP_CIPHER_free);
155}
156
157#ifndef OPENSSL_NO_DEPRECATED_3_0
158static void legacy_md_fn(const EVP_MD *m,
159                       const char *from, const char *to, void *arg)
160{
161    if (m != NULL) {
162        BIO_printf(arg, "  %s\n", EVP_MD_get0_name(m));
163    } else {
164        if (from == NULL)
165            from = "<undefined>";
166        if (to == NULL)
167            to = "<undefined>";
168        BIO_printf((BIO *)arg, "  %s => %s\n", from, to);
169    }
170}
171#endif
172
173DEFINE_STACK_OF(EVP_MD)
174static int md_cmp(const EVP_MD * const *a, const EVP_MD * const *b)
175{
176    return strcmp(OSSL_PROVIDER_get0_name(EVP_MD_get0_provider(*a)),
177                  OSSL_PROVIDER_get0_name(EVP_MD_get0_provider(*b)));
178}
179
180static void collect_digests(EVP_MD *digest, void *stack)
181{
182    STACK_OF(EVP_MD) *digest_stack = stack;
183
184    if (is_digest_fetchable(digest)
185            && sk_EVP_MD_push(digest_stack, digest) > 0)
186        EVP_MD_up_ref(digest);
187}
188
189static void list_digests(void)
190{
191    STACK_OF(EVP_MD) *digests = sk_EVP_MD_new(md_cmp);
192    int i;
193
194    if (digests == NULL) {
195        BIO_printf(bio_err, "ERROR: Memory allocation\n");
196        return;
197    }
198#ifndef OPENSSL_NO_DEPRECATED_3_0
199    if (include_legacy()) {
200        BIO_printf(bio_out, "Legacy:\n");
201        EVP_MD_do_all_sorted(legacy_md_fn, bio_out);
202    }
203#endif
204
205    BIO_printf(bio_out, "Provided:\n");
206    EVP_MD_do_all_provided(app_get0_libctx(), collect_digests, digests);
207    sk_EVP_MD_sort(digests);
208    for (i = 0; i < sk_EVP_MD_num(digests); i++) {
209        const EVP_MD *m = sk_EVP_MD_value(digests, i);
210        STACK_OF(OPENSSL_CSTRING) *names = NULL;
211
212        if (select_name != NULL && !EVP_MD_is_a(m, select_name))
213            continue;
214
215        names = sk_OPENSSL_CSTRING_new(name_cmp);
216        if (names != NULL && EVP_MD_names_do_all(m, collect_names, names)) {
217            BIO_printf(bio_out, "  ");
218            print_names(bio_out, names);
219
220            BIO_printf(bio_out, " @ %s\n",
221                       OSSL_PROVIDER_get0_name(EVP_MD_get0_provider(m)));
222
223            if (verbose) {
224                const char *desc = EVP_MD_get0_description(m);
225
226                if (desc != NULL)
227                    BIO_printf(bio_out, "    description: %s\n", desc);
228                print_param_types("retrievable algorithm parameters",
229                                EVP_MD_gettable_params(m), 4);
230                print_param_types("retrievable operation parameters",
231                                EVP_MD_gettable_ctx_params(m), 4);
232                print_param_types("settable operation parameters",
233                                EVP_MD_settable_ctx_params(m), 4);
234            }
235        }
236        sk_OPENSSL_CSTRING_free(names);
237    }
238    sk_EVP_MD_pop_free(digests, EVP_MD_free);
239}
240
241DEFINE_STACK_OF(EVP_MAC)
242static int mac_cmp(const EVP_MAC * const *a, const EVP_MAC * const *b)
243{
244    return strcmp(OSSL_PROVIDER_get0_name(EVP_MAC_get0_provider(*a)),
245                  OSSL_PROVIDER_get0_name(EVP_MAC_get0_provider(*b)));
246}
247
248static void collect_macs(EVP_MAC *mac, void *stack)
249{
250    STACK_OF(EVP_MAC) *mac_stack = stack;
251
252    if (is_mac_fetchable(mac)
253            && sk_EVP_MAC_push(mac_stack, mac) > 0)
254        EVP_MAC_up_ref(mac);
255}
256
257static void list_macs(void)
258{
259    STACK_OF(EVP_MAC) *macs = sk_EVP_MAC_new(mac_cmp);
260    int i;
261
262    if (macs == NULL) {
263        BIO_printf(bio_err, "ERROR: Memory allocation\n");
264        return;
265    }
266    BIO_printf(bio_out, "Provided MACs:\n");
267    EVP_MAC_do_all_provided(app_get0_libctx(), collect_macs, macs);
268    sk_EVP_MAC_sort(macs);
269    for (i = 0; i < sk_EVP_MAC_num(macs); i++) {
270        const EVP_MAC *m = sk_EVP_MAC_value(macs, i);
271        STACK_OF(OPENSSL_CSTRING) *names = NULL;
272
273        if (select_name != NULL && !EVP_MAC_is_a(m, select_name))
274            continue;
275
276        names = sk_OPENSSL_CSTRING_new(name_cmp);
277        if (names != NULL && EVP_MAC_names_do_all(m, collect_names, names)) {
278            BIO_printf(bio_out, "  ");
279            print_names(bio_out, names);
280
281            BIO_printf(bio_out, " @ %s\n",
282                       OSSL_PROVIDER_get0_name(EVP_MAC_get0_provider(m)));
283
284            if (verbose) {
285                const char *desc = EVP_MAC_get0_description(m);
286
287                if (desc != NULL)
288                    BIO_printf(bio_out, "    description: %s\n", desc);
289                print_param_types("retrievable algorithm parameters",
290                                EVP_MAC_gettable_params(m), 4);
291                print_param_types("retrievable operation parameters",
292                                EVP_MAC_gettable_ctx_params(m), 4);
293                print_param_types("settable operation parameters",
294                                EVP_MAC_settable_ctx_params(m), 4);
295            }
296        }
297        sk_OPENSSL_CSTRING_free(names);
298    }
299    sk_EVP_MAC_pop_free(macs, EVP_MAC_free);
300}
301
302/*
303 * KDFs and PRFs
304 */
305DEFINE_STACK_OF(EVP_KDF)
306static int kdf_cmp(const EVP_KDF * const *a, const EVP_KDF * const *b)
307{
308    return strcmp(OSSL_PROVIDER_get0_name(EVP_KDF_get0_provider(*a)),
309                  OSSL_PROVIDER_get0_name(EVP_KDF_get0_provider(*b)));
310}
311
312static void collect_kdfs(EVP_KDF *kdf, void *stack)
313{
314    STACK_OF(EVP_KDF) *kdf_stack = stack;
315
316    if (is_kdf_fetchable(kdf)
317            && sk_EVP_KDF_push(kdf_stack, kdf) > 0)
318        EVP_KDF_up_ref(kdf);
319}
320
321static void list_kdfs(void)
322{
323    STACK_OF(EVP_KDF) *kdfs = sk_EVP_KDF_new(kdf_cmp);
324    int i;
325
326    if (kdfs == NULL) {
327        BIO_printf(bio_err, "ERROR: Memory allocation\n");
328        return;
329    }
330    BIO_printf(bio_out, "Provided KDFs and PDFs:\n");
331    EVP_KDF_do_all_provided(app_get0_libctx(), collect_kdfs, kdfs);
332    sk_EVP_KDF_sort(kdfs);
333    for (i = 0; i < sk_EVP_KDF_num(kdfs); i++) {
334        const EVP_KDF *k = sk_EVP_KDF_value(kdfs, i);
335        STACK_OF(OPENSSL_CSTRING) *names = NULL;
336
337        if (select_name != NULL && !EVP_KDF_is_a(k, select_name))
338            continue;
339
340        names = sk_OPENSSL_CSTRING_new(name_cmp);
341        if (names != NULL && EVP_KDF_names_do_all(k, collect_names, names)) {
342            BIO_printf(bio_out, "  ");
343            print_names(bio_out, names);
344
345            BIO_printf(bio_out, " @ %s\n",
346                       OSSL_PROVIDER_get0_name(EVP_KDF_get0_provider(k)));
347
348            if (verbose) {
349                const char *desc = EVP_KDF_get0_description(k);
350
351                if (desc != NULL)
352                    BIO_printf(bio_out, "    description: %s\n", desc);
353                print_param_types("retrievable algorithm parameters",
354                                EVP_KDF_gettable_params(k), 4);
355                print_param_types("retrievable operation parameters",
356                                EVP_KDF_gettable_ctx_params(k), 4);
357                print_param_types("settable operation parameters",
358                                EVP_KDF_settable_ctx_params(k), 4);
359            }
360        }
361        sk_OPENSSL_CSTRING_free(names);
362    }
363    sk_EVP_KDF_pop_free(kdfs, EVP_KDF_free);
364}
365
366/*
367 * RANDs
368 */
369DEFINE_STACK_OF(EVP_RAND)
370
371static int rand_cmp(const EVP_RAND * const *a, const EVP_RAND * const *b)
372{
373    int ret = OPENSSL_strcasecmp(EVP_RAND_get0_name(*a), EVP_RAND_get0_name(*b));
374
375    if (ret == 0)
376        ret = strcmp(OSSL_PROVIDER_get0_name(EVP_RAND_get0_provider(*a)),
377                     OSSL_PROVIDER_get0_name(EVP_RAND_get0_provider(*b)));
378
379    return ret;
380}
381
382static void collect_rands(EVP_RAND *rand, void *stack)
383{
384    STACK_OF(EVP_RAND) *rand_stack = stack;
385
386    if (is_rand_fetchable(rand)
387            && sk_EVP_RAND_push(rand_stack, rand) > 0)
388        EVP_RAND_up_ref(rand);
389}
390
391static void list_random_generators(void)
392{
393    STACK_OF(EVP_RAND) *rands = sk_EVP_RAND_new(rand_cmp);
394    int i;
395
396    if (rands == NULL) {
397        BIO_printf(bio_err, "ERROR: Memory allocation\n");
398        return;
399    }
400    BIO_printf(bio_out, "Provided RNGs and seed sources:\n");
401    EVP_RAND_do_all_provided(app_get0_libctx(), collect_rands, rands);
402    sk_EVP_RAND_sort(rands);
403    for (i = 0; i < sk_EVP_RAND_num(rands); i++) {
404        const EVP_RAND *m = sk_EVP_RAND_value(rands, i);
405
406        if (select_name != NULL
407            && OPENSSL_strcasecmp(EVP_RAND_get0_name(m), select_name) != 0)
408            continue;
409        BIO_printf(bio_out, "  %s", EVP_RAND_get0_name(m));
410        BIO_printf(bio_out, " @ %s\n",
411                   OSSL_PROVIDER_get0_name(EVP_RAND_get0_provider(m)));
412
413        if (verbose) {
414            const char *desc = EVP_RAND_get0_description(m);
415
416            if (desc != NULL)
417                BIO_printf(bio_out, "    description: %s\n", desc);
418            print_param_types("retrievable algorithm parameters",
419                              EVP_RAND_gettable_params(m), 4);
420            print_param_types("retrievable operation parameters",
421                              EVP_RAND_gettable_ctx_params(m), 4);
422            print_param_types("settable operation parameters",
423                              EVP_RAND_settable_ctx_params(m), 4);
424        }
425    }
426    sk_EVP_RAND_pop_free(rands, EVP_RAND_free);
427}
428
429static void display_random(const char *name, EVP_RAND_CTX *drbg)
430{
431    EVP_RAND *rand;
432    uint64_t u;
433    const char *p;
434    const OSSL_PARAM *gettables;
435    OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
436    unsigned char buf[1000];
437
438    BIO_printf(bio_out, "%s:\n", name);
439    if (drbg != NULL) {
440        rand = EVP_RAND_CTX_get0_rand(drbg);
441
442        BIO_printf(bio_out, "  %s", EVP_RAND_get0_name(rand));
443        BIO_printf(bio_out, " @ %s\n",
444                   OSSL_PROVIDER_get0_name(EVP_RAND_get0_provider(rand)));
445
446        switch (EVP_RAND_get_state(drbg)) {
447        case EVP_RAND_STATE_UNINITIALISED:
448            p = "uninitialised";
449            break;
450        case EVP_RAND_STATE_READY:
451            p = "ready";
452            break;
453        case EVP_RAND_STATE_ERROR:
454            p = "error";
455            break;
456        default:
457            p = "unknown";
458            break;
459        }
460        BIO_printf(bio_out, "  state = %s\n", p);
461
462        gettables = EVP_RAND_gettable_ctx_params(rand);
463        if (gettables != NULL)
464            for (; gettables->key != NULL; gettables++) {
465                /* State has been dealt with already, so ignore */
466                if (OPENSSL_strcasecmp(gettables->key, OSSL_RAND_PARAM_STATE) == 0)
467                    continue;
468                /* Outside of verbose mode, we skip non-string values */
469                if (gettables->data_type != OSSL_PARAM_UTF8_STRING
470                        && gettables->data_type != OSSL_PARAM_UTF8_PTR
471                        && !verbose)
472                    continue;
473                params->key = gettables->key;
474                params->data_type = gettables->data_type;
475                if (gettables->data_type == OSSL_PARAM_UNSIGNED_INTEGER
476                        || gettables->data_type == OSSL_PARAM_INTEGER) {
477                    params->data = &u;
478                    params->data_size = sizeof(u);
479                } else {
480                    params->data = buf;
481                    params->data_size = sizeof(buf);
482                }
483                params->return_size = 0;
484                if (EVP_RAND_CTX_get_params(drbg, params))
485                    print_param_value(params, 2);
486            }
487    }
488}
489
490static void list_random_instances(void)
491{
492    display_random("primary", RAND_get0_primary(NULL));
493    display_random("public", RAND_get0_public(NULL));
494    display_random("private", RAND_get0_private(NULL));
495}
496
497/*
498 * Encoders
499 */
500DEFINE_STACK_OF(OSSL_ENCODER)
501static int encoder_cmp(const OSSL_ENCODER * const *a,
502                       const OSSL_ENCODER * const *b)
503{
504    return strcmp(OSSL_PROVIDER_get0_name(OSSL_ENCODER_get0_provider(*a)),
505                  OSSL_PROVIDER_get0_name(OSSL_ENCODER_get0_provider(*b)));
506}
507
508static void collect_encoders(OSSL_ENCODER *encoder, void *stack)
509{
510    STACK_OF(OSSL_ENCODER) *encoder_stack = stack;
511
512    if (is_encoder_fetchable(encoder)
513            && sk_OSSL_ENCODER_push(encoder_stack, encoder) > 0)
514        OSSL_ENCODER_up_ref(encoder);
515}
516
517static void list_encoders(void)
518{
519    STACK_OF(OSSL_ENCODER) *encoders;
520    int i;
521
522    encoders = sk_OSSL_ENCODER_new(encoder_cmp);
523    if (encoders == NULL) {
524        BIO_printf(bio_err, "ERROR: Memory allocation\n");
525        return;
526    }
527    BIO_printf(bio_out, "Provided ENCODERs:\n");
528    OSSL_ENCODER_do_all_provided(app_get0_libctx(), collect_encoders,
529                                 encoders);
530    sk_OSSL_ENCODER_sort(encoders);
531
532    for (i = 0; i < sk_OSSL_ENCODER_num(encoders); i++) {
533        OSSL_ENCODER *k = sk_OSSL_ENCODER_value(encoders, i);
534        STACK_OF(OPENSSL_CSTRING) *names = NULL;
535
536        if (select_name != NULL && !OSSL_ENCODER_is_a(k, select_name))
537            continue;
538
539        names = sk_OPENSSL_CSTRING_new(name_cmp);
540        if (names != NULL && OSSL_ENCODER_names_do_all(k, collect_names, names)) {
541            BIO_printf(bio_out, "  ");
542            print_names(bio_out, names);
543
544            BIO_printf(bio_out, " @ %s (%s)\n",
545                    OSSL_PROVIDER_get0_name(OSSL_ENCODER_get0_provider(k)),
546                    OSSL_ENCODER_get0_properties(k));
547
548            if (verbose) {
549                const char *desc = OSSL_ENCODER_get0_description(k);
550
551                if (desc != NULL)
552                    BIO_printf(bio_out, "    description: %s\n", desc);
553                print_param_types("settable operation parameters",
554                                OSSL_ENCODER_settable_ctx_params(k), 4);
555            }
556        }
557        sk_OPENSSL_CSTRING_free(names);
558    }
559    sk_OSSL_ENCODER_pop_free(encoders, OSSL_ENCODER_free);
560}
561
562/*
563 * Decoders
564 */
565DEFINE_STACK_OF(OSSL_DECODER)
566static int decoder_cmp(const OSSL_DECODER * const *a,
567                       const OSSL_DECODER * const *b)
568{
569    return strcmp(OSSL_PROVIDER_get0_name(OSSL_DECODER_get0_provider(*a)),
570                  OSSL_PROVIDER_get0_name(OSSL_DECODER_get0_provider(*b)));
571}
572
573static void collect_decoders(OSSL_DECODER *decoder, void *stack)
574{
575    STACK_OF(OSSL_DECODER) *decoder_stack = stack;
576
577    if (is_decoder_fetchable(decoder)
578            && sk_OSSL_DECODER_push(decoder_stack, decoder) > 0)
579        OSSL_DECODER_up_ref(decoder);
580}
581
582static void list_decoders(void)
583{
584    STACK_OF(OSSL_DECODER) *decoders;
585    int i;
586
587    decoders = sk_OSSL_DECODER_new(decoder_cmp);
588    if (decoders == NULL) {
589        BIO_printf(bio_err, "ERROR: Memory allocation\n");
590        return;
591    }
592    BIO_printf(bio_out, "Provided DECODERs:\n");
593    OSSL_DECODER_do_all_provided(app_get0_libctx(), collect_decoders,
594                                 decoders);
595    sk_OSSL_DECODER_sort(decoders);
596
597    for (i = 0; i < sk_OSSL_DECODER_num(decoders); i++) {
598        OSSL_DECODER *k = sk_OSSL_DECODER_value(decoders, i);
599        STACK_OF(OPENSSL_CSTRING) *names = NULL;
600
601        if (select_name != NULL && !OSSL_DECODER_is_a(k, select_name))
602            continue;
603
604        names = sk_OPENSSL_CSTRING_new(name_cmp);
605        if (names != NULL && OSSL_DECODER_names_do_all(k, collect_names, names)) {
606            BIO_printf(bio_out, "  ");
607            print_names(bio_out, names);
608
609            BIO_printf(bio_out, " @ %s (%s)\n",
610                       OSSL_PROVIDER_get0_name(OSSL_DECODER_get0_provider(k)),
611                       OSSL_DECODER_get0_properties(k));
612
613            if (verbose) {
614                const char *desc = OSSL_DECODER_get0_description(k);
615
616                if (desc != NULL)
617                    BIO_printf(bio_out, "    description: %s\n", desc);
618                print_param_types("settable operation parameters",
619                                OSSL_DECODER_settable_ctx_params(k), 4);
620            }
621        }
622        sk_OPENSSL_CSTRING_free(names);
623    }
624    sk_OSSL_DECODER_pop_free(decoders, OSSL_DECODER_free);
625}
626
627DEFINE_STACK_OF(EVP_KEYMGMT)
628static int keymanager_cmp(const EVP_KEYMGMT * const *a,
629                          const EVP_KEYMGMT * const *b)
630{
631    return strcmp(OSSL_PROVIDER_get0_name(EVP_KEYMGMT_get0_provider(*a)),
632                  OSSL_PROVIDER_get0_name(EVP_KEYMGMT_get0_provider(*b)));
633}
634
635static void collect_keymanagers(EVP_KEYMGMT *km, void *stack)
636{
637    STACK_OF(EVP_KEYMGMT) *km_stack = stack;
638
639    if (is_keymgmt_fetchable(km)
640            && sk_EVP_KEYMGMT_push(km_stack, km) > 0)
641        EVP_KEYMGMT_up_ref(km);
642}
643
644static void list_keymanagers(void)
645{
646    int i;
647    STACK_OF(EVP_KEYMGMT) *km_stack = sk_EVP_KEYMGMT_new(keymanager_cmp);
648
649    EVP_KEYMGMT_do_all_provided(app_get0_libctx(), collect_keymanagers,
650                                km_stack);
651    sk_EVP_KEYMGMT_sort(km_stack);
652
653    for (i = 0; i < sk_EVP_KEYMGMT_num(km_stack); i++) {
654        EVP_KEYMGMT *k = sk_EVP_KEYMGMT_value(km_stack, i);
655        STACK_OF(OPENSSL_CSTRING) *names = NULL;
656
657        if (select_name != NULL && !EVP_KEYMGMT_is_a(k, select_name))
658            continue;
659
660        names = sk_OPENSSL_CSTRING_new(name_cmp);
661        if (names != NULL && EVP_KEYMGMT_names_do_all(k, collect_names, names)) {
662            const char *desc = EVP_KEYMGMT_get0_description(k);
663
664            BIO_printf(bio_out, "  Name: ");
665            if (desc != NULL)
666                BIO_printf(bio_out, "%s", desc);
667            else
668                BIO_printf(bio_out, "%s", sk_OPENSSL_CSTRING_value(names, 0));
669            BIO_printf(bio_out, "\n");
670            BIO_printf(bio_out, "    Type: Provider Algorithm\n");
671            BIO_printf(bio_out, "    IDs: ");
672            print_names(bio_out, names);
673            BIO_printf(bio_out, " @ %s\n",
674                    OSSL_PROVIDER_get0_name(EVP_KEYMGMT_get0_provider(k)));
675
676            if (verbose) {
677                print_param_types("settable key generation parameters",
678                                EVP_KEYMGMT_gen_settable_params(k), 4);
679                print_param_types("settable operation parameters",
680                                EVP_KEYMGMT_settable_params(k), 4);
681                print_param_types("retrievable operation parameters",
682                                EVP_KEYMGMT_gettable_params(k), 4);
683            }
684        }
685        sk_OPENSSL_CSTRING_free(names);
686    }
687    sk_EVP_KEYMGMT_pop_free(km_stack, EVP_KEYMGMT_free);
688}
689
690DEFINE_STACK_OF(EVP_SIGNATURE)
691static int signature_cmp(const EVP_SIGNATURE * const *a,
692                         const EVP_SIGNATURE * const *b)
693{
694    return strcmp(OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*a)),
695                  OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(*b)));
696}
697
698static void collect_signatures(EVP_SIGNATURE *sig, void *stack)
699{
700    STACK_OF(EVP_SIGNATURE) *sig_stack = stack;
701
702    if (is_signature_fetchable(sig)
703            && sk_EVP_SIGNATURE_push(sig_stack, sig) > 0)
704        EVP_SIGNATURE_up_ref(sig);
705}
706
707static void list_signatures(void)
708{
709    int i, count = 0;
710    STACK_OF(EVP_SIGNATURE) *sig_stack = sk_EVP_SIGNATURE_new(signature_cmp);
711
712    EVP_SIGNATURE_do_all_provided(app_get0_libctx(), collect_signatures,
713                                  sig_stack);
714    sk_EVP_SIGNATURE_sort(sig_stack);
715
716    for (i = 0; i < sk_EVP_SIGNATURE_num(sig_stack); i++) {
717        EVP_SIGNATURE *k = sk_EVP_SIGNATURE_value(sig_stack, i);
718        STACK_OF(OPENSSL_CSTRING) *names = NULL;
719
720        if (select_name != NULL && !EVP_SIGNATURE_is_a(k, select_name))
721            continue;
722
723        names = sk_OPENSSL_CSTRING_new(name_cmp);
724        if (names != NULL && EVP_SIGNATURE_names_do_all(k, collect_names, names)) {
725            count++;
726            BIO_printf(bio_out, "  ");
727            print_names(bio_out, names);
728
729            BIO_printf(bio_out, " @ %s\n",
730                    OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(k)));
731
732            if (verbose) {
733                const char *desc = EVP_SIGNATURE_get0_description(k);
734
735                if (desc != NULL)
736                    BIO_printf(bio_out, "    description: %s\n", desc);
737                print_param_types("settable operation parameters",
738                                EVP_SIGNATURE_settable_ctx_params(k), 4);
739                print_param_types("retrievable operation parameters",
740                                EVP_SIGNATURE_gettable_ctx_params(k), 4);
741            }
742        }
743        sk_OPENSSL_CSTRING_free(names);
744    }
745    sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free);
746    if (count == 0)
747        BIO_printf(bio_out, " -\n");
748}
749
750DEFINE_STACK_OF(EVP_KEM)
751static int kem_cmp(const EVP_KEM * const *a,
752                   const EVP_KEM * const *b)
753{
754    return strcmp(OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*a)),
755                  OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(*b)));
756}
757
758static void collect_kem(EVP_KEM *kem, void *stack)
759{
760    STACK_OF(EVP_KEM) *kem_stack = stack;
761
762    if (is_kem_fetchable(kem)
763            && sk_EVP_KEM_push(kem_stack, kem) > 0)
764        EVP_KEM_up_ref(kem);
765}
766
767static void list_kems(void)
768{
769    int i, count = 0;
770    STACK_OF(EVP_KEM) *kem_stack = sk_EVP_KEM_new(kem_cmp);
771
772    EVP_KEM_do_all_provided(app_get0_libctx(), collect_kem, kem_stack);
773    sk_EVP_KEM_sort(kem_stack);
774
775    for (i = 0; i < sk_EVP_KEM_num(kem_stack); i++) {
776        EVP_KEM *k = sk_EVP_KEM_value(kem_stack, i);
777        STACK_OF(OPENSSL_CSTRING) *names = NULL;
778
779        if (select_name != NULL && !EVP_KEM_is_a(k, select_name))
780            continue;
781
782        names = sk_OPENSSL_CSTRING_new(name_cmp);
783        if (names != NULL && EVP_KEM_names_do_all(k, collect_names, names)) {
784            count++;
785            BIO_printf(bio_out, "  ");
786            print_names(bio_out, names);
787
788            BIO_printf(bio_out, " @ %s\n",
789                       OSSL_PROVIDER_get0_name(EVP_KEM_get0_provider(k)));
790
791            if (verbose) {
792                const char *desc = EVP_KEM_get0_description(k);
793
794                if (desc != NULL)
795                    BIO_printf(bio_out, "    description: %s\n", desc);
796                print_param_types("settable operation parameters",
797                                EVP_KEM_settable_ctx_params(k), 4);
798                print_param_types("retrievable operation parameters",
799                                EVP_KEM_gettable_ctx_params(k), 4);
800            }
801        }
802        sk_OPENSSL_CSTRING_free(names);
803    }
804    sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free);
805    if (count == 0)
806        BIO_printf(bio_out, " -\n");
807}
808
809DEFINE_STACK_OF(EVP_ASYM_CIPHER)
810static int asymcipher_cmp(const EVP_ASYM_CIPHER * const *a,
811                          const EVP_ASYM_CIPHER * const *b)
812{
813    return strcmp(OSSL_PROVIDER_get0_name(EVP_ASYM_CIPHER_get0_provider(*a)),
814                  OSSL_PROVIDER_get0_name(EVP_ASYM_CIPHER_get0_provider(*b)));
815}
816
817static void collect_asymciph(EVP_ASYM_CIPHER *asym_cipher, void *stack)
818{
819    STACK_OF(EVP_ASYM_CIPHER) *asym_cipher_stack = stack;
820
821    if (is_asym_cipher_fetchable(asym_cipher)
822            && sk_EVP_ASYM_CIPHER_push(asym_cipher_stack, asym_cipher) > 0)
823        EVP_ASYM_CIPHER_up_ref(asym_cipher);
824}
825
826static void list_asymciphers(void)
827{
828    int i, count = 0;
829    STACK_OF(EVP_ASYM_CIPHER) *asymciph_stack =
830        sk_EVP_ASYM_CIPHER_new(asymcipher_cmp);
831
832    EVP_ASYM_CIPHER_do_all_provided(app_get0_libctx(), collect_asymciph,
833                                    asymciph_stack);
834    sk_EVP_ASYM_CIPHER_sort(asymciph_stack);
835
836    for (i = 0; i < sk_EVP_ASYM_CIPHER_num(asymciph_stack); i++) {
837        EVP_ASYM_CIPHER *k = sk_EVP_ASYM_CIPHER_value(asymciph_stack, i);
838        STACK_OF(OPENSSL_CSTRING) *names = NULL;
839
840        if (select_name != NULL && !EVP_ASYM_CIPHER_is_a(k, select_name))
841            continue;
842
843        names = sk_OPENSSL_CSTRING_new(name_cmp);
844        if (names != NULL
845                && EVP_ASYM_CIPHER_names_do_all(k, collect_names, names)) {
846            count++;
847            BIO_printf(bio_out, "  ");
848            print_names(bio_out, names);
849
850            BIO_printf(bio_out, " @ %s\n",
851                    OSSL_PROVIDER_get0_name(EVP_ASYM_CIPHER_get0_provider(k)));
852
853            if (verbose) {
854                const char *desc = EVP_ASYM_CIPHER_get0_description(k);
855
856                if (desc != NULL)
857                    BIO_printf(bio_out, "    description: %s\n", desc);
858                print_param_types("settable operation parameters",
859                                EVP_ASYM_CIPHER_settable_ctx_params(k), 4);
860                print_param_types("retrievable operation parameters",
861                                EVP_ASYM_CIPHER_gettable_ctx_params(k), 4);
862            }
863        }
864        sk_OPENSSL_CSTRING_free(names);
865    }
866    sk_EVP_ASYM_CIPHER_pop_free(asymciph_stack, EVP_ASYM_CIPHER_free);
867    if (count == 0)
868        BIO_printf(bio_out, " -\n");
869}
870
871DEFINE_STACK_OF(EVP_KEYEXCH)
872static int kex_cmp(const EVP_KEYEXCH * const *a,
873                   const EVP_KEYEXCH * const *b)
874{
875    return strcmp(OSSL_PROVIDER_get0_name(EVP_KEYEXCH_get0_provider(*a)),
876                  OSSL_PROVIDER_get0_name(EVP_KEYEXCH_get0_provider(*b)));
877}
878
879static void collect_kex(EVP_KEYEXCH *kex, void *stack)
880{
881    STACK_OF(EVP_KEYEXCH) *kex_stack = stack;
882
883    if (is_keyexch_fetchable(kex)
884            && sk_EVP_KEYEXCH_push(kex_stack, kex) > 0)
885        EVP_KEYEXCH_up_ref(kex);
886}
887
888static void list_keyexchanges(void)
889{
890    int i, count = 0;
891    STACK_OF(EVP_KEYEXCH) *kex_stack = sk_EVP_KEYEXCH_new(kex_cmp);
892
893    EVP_KEYEXCH_do_all_provided(app_get0_libctx(), collect_kex, kex_stack);
894    sk_EVP_KEYEXCH_sort(kex_stack);
895
896    for (i = 0; i < sk_EVP_KEYEXCH_num(kex_stack); i++) {
897        EVP_KEYEXCH *k = sk_EVP_KEYEXCH_value(kex_stack, i);
898        STACK_OF(OPENSSL_CSTRING) *names = NULL;
899
900        if (select_name != NULL && !EVP_KEYEXCH_is_a(k, select_name))
901            continue;
902
903        names = sk_OPENSSL_CSTRING_new(name_cmp);
904        if (names != NULL && EVP_KEYEXCH_names_do_all(k, collect_names, names)) {
905            count++;
906            BIO_printf(bio_out, "  ");
907            print_names(bio_out, names);
908
909            BIO_printf(bio_out, " @ %s\n",
910                    OSSL_PROVIDER_get0_name(EVP_KEYEXCH_get0_provider(k)));
911
912            if (verbose) {
913                const char *desc = EVP_KEYEXCH_get0_description(k);
914
915                if (desc != NULL)
916                    BIO_printf(bio_out, "    description: %s\n", desc);
917                print_param_types("settable operation parameters",
918                                EVP_KEYEXCH_settable_ctx_params(k), 4);
919                print_param_types("retrievable operation parameters",
920                                EVP_KEYEXCH_gettable_ctx_params(k), 4);
921            }
922        }
923        sk_OPENSSL_CSTRING_free(names);
924    }
925    sk_EVP_KEYEXCH_pop_free(kex_stack, EVP_KEYEXCH_free);
926    if (count == 0)
927        BIO_printf(bio_out, " -\n");
928}
929
930static void list_objects(void)
931{
932    int max_nid = OBJ_new_nid(0);
933    int i;
934    char *oid_buf = NULL;
935    int oid_size = 0;
936
937    /* Skip 0, since that's NID_undef */
938    for (i = 1; i < max_nid; i++) {
939        const ASN1_OBJECT *obj = OBJ_nid2obj(i);
940        const char *sn = OBJ_nid2sn(i);
941        const char *ln = OBJ_nid2ln(i);
942        int n = 0;
943
944        /*
945         * If one of the retrieved objects somehow generated an error,
946         * we ignore it.  The check for NID_undef below will detect the
947         * error and simply skip to the next NID.
948         */
949        ERR_clear_error();
950
951        if (OBJ_obj2nid(obj) == NID_undef)
952            continue;
953
954        if ((n = OBJ_obj2txt(NULL, 0, obj, 1)) == 0) {
955            BIO_printf(bio_out, "# None-OID object: %s, %s\n", sn, ln);
956            continue;
957        }
958        if (n < 0)
959            break;               /* Error */
960
961        if (n > oid_size) {
962            oid_buf = OPENSSL_realloc(oid_buf, n + 1);
963            if (oid_buf == NULL) {
964                BIO_printf(bio_err, "ERROR: Memory allocation\n");
965                break;           /* Error */
966            }
967            oid_size = n + 1;
968        }
969        if (OBJ_obj2txt(oid_buf, oid_size, obj, 1) < 0)
970            break;               /* Error */
971        if (ln == NULL || strcmp(sn, ln) == 0)
972            BIO_printf(bio_out, "%s = %s\n", sn, oid_buf);
973        else
974            BIO_printf(bio_out, "%s = %s, %s\n", sn, ln, oid_buf);
975    }
976
977    OPENSSL_free(oid_buf);
978}
979
980static void list_options_for_command(const char *command)
981{
982    const FUNCTION *fp;
983    const OPTIONS *o;
984
985    for (fp = functions; fp->name != NULL; fp++)
986        if (strcmp(fp->name, command) == 0)
987            break;
988    if (fp->name == NULL) {
989        BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n",
990                   command);
991        return;
992    }
993
994    if ((o = fp->help) == NULL)
995        return;
996
997    for ( ; o->name != NULL; o++) {
998        char c = o->valtype;
999
1000        if (o->name == OPT_PARAM_STR)
1001            break;
1002
1003        if (o->name == OPT_HELP_STR
1004                || o->name == OPT_MORE_STR
1005                || o->name == OPT_SECTION_STR
1006                || o->name[0] == '\0')
1007            continue;
1008        BIO_printf(bio_out, "%s %c\n", o->name, c == '\0' ? '-' : c);
1009    }
1010    /* Always output the -- marker since it is sometimes documented. */
1011    BIO_printf(bio_out, "- -\n");
1012}
1013
1014static int is_md_available(const char *name)
1015{
1016    EVP_MD *md;
1017    const char *propq = app_get0_propq();
1018
1019    /* Look through providers' digests */
1020    ERR_set_mark();
1021    md = EVP_MD_fetch(app_get0_libctx(), name, propq);
1022    ERR_pop_to_mark();
1023    if (md != NULL) {
1024        EVP_MD_free(md);
1025        return 1;
1026    }
1027
1028    return propq != NULL || get_digest_from_engine(name) == NULL ? 0 : 1;
1029}
1030
1031static int is_cipher_available(const char *name)
1032{
1033    EVP_CIPHER *cipher;
1034    const char *propq = app_get0_propq();
1035
1036    /* Look through providers' ciphers */
1037    ERR_set_mark();
1038    cipher = EVP_CIPHER_fetch(app_get0_libctx(), name, propq);
1039    ERR_pop_to_mark();
1040    if (cipher != NULL) {
1041        EVP_CIPHER_free(cipher);
1042        return 1;
1043    }
1044
1045    return propq != NULL || get_cipher_from_engine(name) == NULL ? 0 : 1;
1046}
1047
1048static void list_type(FUNC_TYPE ft, int one)
1049{
1050    FUNCTION *fp;
1051    int i = 0;
1052    DISPLAY_COLUMNS dc;
1053
1054    memset(&dc, 0, sizeof(dc));
1055    if (!one)
1056        calculate_columns(functions, &dc);
1057
1058    for (fp = functions; fp->name != NULL; fp++) {
1059        if (fp->type != ft)
1060            continue;
1061        switch (ft) {
1062        case FT_cipher:
1063            if (!is_cipher_available(fp->name))
1064                continue;
1065            break;
1066        case FT_md:
1067            if (!is_md_available(fp->name))
1068                continue;
1069            break;
1070        default:
1071            break;
1072        }
1073        if (one) {
1074            BIO_printf(bio_out, "%s\n", fp->name);
1075        } else {
1076            if (i % dc.columns == 0 && i > 0)
1077                BIO_printf(bio_out, "\n");
1078            BIO_printf(bio_out, "%-*s", dc.width, fp->name);
1079            i++;
1080        }
1081    }
1082    if (!one)
1083        BIO_printf(bio_out, "\n\n");
1084}
1085
1086static void list_pkey(void)
1087{
1088#ifndef OPENSSL_NO_DEPRECATED_3_0
1089    int i;
1090
1091    if (select_name == NULL && include_legacy()) {
1092        BIO_printf(bio_out, "Legacy:\n");
1093        for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
1094            const EVP_PKEY_ASN1_METHOD *ameth;
1095            int pkey_id, pkey_base_id, pkey_flags;
1096            const char *pinfo, *pem_str;
1097            ameth = EVP_PKEY_asn1_get0(i);
1098            EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags,
1099                                    &pinfo, &pem_str, ameth);
1100            if (pkey_flags & ASN1_PKEY_ALIAS) {
1101                BIO_printf(bio_out, " Name: %s\n", OBJ_nid2ln(pkey_id));
1102                BIO_printf(bio_out, "\tAlias for: %s\n",
1103                           OBJ_nid2ln(pkey_base_id));
1104            } else {
1105                BIO_printf(bio_out, " Name: %s\n", pinfo);
1106                BIO_printf(bio_out, "\tType: %s Algorithm\n",
1107                           pkey_flags & ASN1_PKEY_DYNAMIC ?
1108                           "External" : "Builtin");
1109                BIO_printf(bio_out, "\tOID: %s\n", OBJ_nid2ln(pkey_id));
1110                if (pem_str == NULL)
1111                    pem_str = "(none)";
1112                BIO_printf(bio_out, "\tPEM string: %s\n", pem_str);
1113            }
1114        }
1115    }
1116#endif
1117    BIO_printf(bio_out, "Provided:\n");
1118    BIO_printf(bio_out, " Key Managers:\n");
1119    list_keymanagers();
1120}
1121
1122static void list_pkey_meth(void)
1123{
1124#ifndef OPENSSL_NO_DEPRECATED_3_0
1125    size_t i;
1126    size_t meth_count = EVP_PKEY_meth_get_count();
1127
1128    if (select_name == NULL && include_legacy()) {
1129        BIO_printf(bio_out, "Legacy:\n");
1130        for (i = 0; i < meth_count; i++) {
1131            const EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_get0(i);
1132            int pkey_id, pkey_flags;
1133
1134            EVP_PKEY_meth_get0_info(&pkey_id, &pkey_flags, pmeth);
1135            BIO_printf(bio_out, " %s\n", OBJ_nid2ln(pkey_id));
1136            BIO_printf(bio_out, "\tType: %s Algorithm\n",
1137                       pkey_flags & ASN1_PKEY_DYNAMIC ?  "External" : "Builtin");
1138        }
1139    }
1140#endif
1141    BIO_printf(bio_out, "Provided:\n");
1142    BIO_printf(bio_out, " Encryption:\n");
1143    list_asymciphers();
1144    BIO_printf(bio_out, " Key Exchange:\n");
1145    list_keyexchanges();
1146    BIO_printf(bio_out, " Signatures:\n");
1147    list_signatures();
1148    BIO_printf(bio_out, " Key encapsulation:\n");
1149    list_kems();
1150}
1151
1152DEFINE_STACK_OF(OSSL_STORE_LOADER)
1153static int store_cmp(const OSSL_STORE_LOADER * const *a,
1154                     const OSSL_STORE_LOADER * const *b)
1155{
1156    return strcmp(OSSL_PROVIDER_get0_name(OSSL_STORE_LOADER_get0_provider(*a)),
1157                  OSSL_PROVIDER_get0_name(OSSL_STORE_LOADER_get0_provider(*b)));
1158}
1159
1160static void collect_store_loaders(OSSL_STORE_LOADER *store, void *stack)
1161{
1162    STACK_OF(OSSL_STORE_LOADER) *store_stack = stack;
1163
1164    if (sk_OSSL_STORE_LOADER_push(store_stack, store) > 0)
1165        OSSL_STORE_LOADER_up_ref(store);
1166}
1167
1168static void list_store_loaders(void)
1169{
1170    STACK_OF(OSSL_STORE_LOADER) *stores = sk_OSSL_STORE_LOADER_new(store_cmp);
1171    int i;
1172
1173    if (stores == NULL) {
1174        BIO_printf(bio_err, "ERROR: Memory allocation\n");
1175        return;
1176    }
1177    BIO_printf(bio_out, "Provided STORE LOADERs:\n");
1178    OSSL_STORE_LOADER_do_all_provided(app_get0_libctx(), collect_store_loaders,
1179                                      stores);
1180    sk_OSSL_STORE_LOADER_sort(stores);
1181    for (i = 0; i < sk_OSSL_STORE_LOADER_num(stores); i++) {
1182        const OSSL_STORE_LOADER *m = sk_OSSL_STORE_LOADER_value(stores, i);
1183        STACK_OF(OPENSSL_CSTRING) *names = NULL;
1184
1185        if (select_name != NULL && !OSSL_STORE_LOADER_is_a(m, select_name))
1186            continue;
1187
1188        names = sk_OPENSSL_CSTRING_new(name_cmp);
1189        if (names != NULL && OSSL_STORE_LOADER_names_do_all(m, collect_names,
1190                                                            names)) {
1191            BIO_printf(bio_out, "  ");
1192            print_names(bio_out, names);
1193
1194            BIO_printf(bio_out, " @ %s\n",
1195                       OSSL_PROVIDER_get0_name(OSSL_STORE_LOADER_get0_provider(m)));
1196        }
1197        sk_OPENSSL_CSTRING_free(names);
1198    }
1199    sk_OSSL_STORE_LOADER_pop_free(stores, OSSL_STORE_LOADER_free);
1200}
1201
1202DEFINE_STACK_OF(OSSL_PROVIDER)
1203static int provider_cmp(const OSSL_PROVIDER * const *a,
1204                        const OSSL_PROVIDER * const *b)
1205{
1206    return strcmp(OSSL_PROVIDER_get0_name(*a), OSSL_PROVIDER_get0_name(*b));
1207}
1208
1209static int collect_providers(OSSL_PROVIDER *provider, void *stack)
1210{
1211    STACK_OF(OSSL_PROVIDER) *provider_stack = stack;
1212
1213    sk_OSSL_PROVIDER_push(provider_stack, provider);
1214    return 1;
1215}
1216
1217static void list_provider_info(void)
1218{
1219    STACK_OF(OSSL_PROVIDER) *providers = sk_OSSL_PROVIDER_new(provider_cmp);
1220    OSSL_PARAM params[5];
1221    char *name, *version, *buildinfo;
1222    int status;
1223    int i;
1224
1225    if (providers == NULL) {
1226        BIO_printf(bio_err, "ERROR: Memory allocation\n");
1227        return;
1228    }
1229    BIO_printf(bio_out, "Providers:\n");
1230    OSSL_PROVIDER_do_all(NULL, &collect_providers, providers);
1231    sk_OSSL_PROVIDER_sort(providers);
1232    for (i = 0; i < sk_OSSL_PROVIDER_num(providers); i++) {
1233        const OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(providers, i);
1234
1235        /* Query the "known" information parameters, the order matches below */
1236        params[0] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_NAME,
1237                                                  &name, 0);
1238        params[1] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_VERSION,
1239                                                  &version, 0);
1240        params[2] = OSSL_PARAM_construct_int(OSSL_PROV_PARAM_STATUS, &status);
1241        params[3] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_BUILDINFO,
1242                                                  &buildinfo, 0);
1243        params[4] = OSSL_PARAM_construct_end();
1244        OSSL_PARAM_set_all_unmodified(params);
1245        if (!OSSL_PROVIDER_get_params(prov, params)) {
1246            BIO_printf(bio_err, "ERROR: Unable to query provider parameters\n");
1247            return;
1248        }
1249
1250        /* Print out the provider information, the params order matches above */
1251        BIO_printf(bio_out, "  %s\n", OSSL_PROVIDER_get0_name(prov));
1252        if (OSSL_PARAM_modified(params))
1253            BIO_printf(bio_out, "    name: %s\n", name);
1254        if (OSSL_PARAM_modified(params + 1))
1255            BIO_printf(bio_out, "    version: %s\n", version);
1256        if (OSSL_PARAM_modified(params + 2))
1257            BIO_printf(bio_out, "    status: %sactive\n", status ? "" : "in");
1258        if (verbose) {
1259            if (OSSL_PARAM_modified(params + 3))
1260                BIO_printf(bio_out, "    build info: %s\n", buildinfo);
1261            print_param_types("gettable provider parameters",
1262                              OSSL_PROVIDER_gettable_params(prov), 4);
1263        }
1264    }
1265    sk_OSSL_PROVIDER_free(providers);
1266}
1267
1268#ifndef OPENSSL_NO_DEPRECATED_3_0
1269static void list_engines(void)
1270{
1271# ifndef OPENSSL_NO_ENGINE
1272    ENGINE *e;
1273
1274    BIO_puts(bio_out, "Engines:\n");
1275    e = ENGINE_get_first();
1276    while (e) {
1277        BIO_printf(bio_out, "%s\n", ENGINE_get_id(e));
1278        e = ENGINE_get_next(e);
1279    }
1280# else
1281    BIO_puts(bio_out, "Engine support is disabled.\n");
1282# endif
1283}
1284#endif
1285
1286static void list_disabled(void)
1287{
1288    BIO_puts(bio_out, "Disabled algorithms:\n");
1289#ifdef OPENSSL_NO_ARIA
1290    BIO_puts(bio_out, "ARIA\n");
1291#endif
1292#ifdef OPENSSL_NO_BF
1293    BIO_puts(bio_out, "BF\n");
1294#endif
1295#ifdef OPENSSL_NO_BLAKE2
1296    BIO_puts(bio_out, "BLAKE2\n");
1297#endif
1298#ifdef OPENSSL_NO_CAMELLIA
1299    BIO_puts(bio_out, "CAMELLIA\n");
1300#endif
1301#ifdef OPENSSL_NO_CAST
1302    BIO_puts(bio_out, "CAST\n");
1303#endif
1304#ifdef OPENSSL_NO_CMAC
1305    BIO_puts(bio_out, "CMAC\n");
1306#endif
1307#ifdef OPENSSL_NO_CMS
1308    BIO_puts(bio_out, "CMS\n");
1309#endif
1310#ifdef OPENSSL_NO_COMP
1311    BIO_puts(bio_out, "COMP\n");
1312#endif
1313#ifdef OPENSSL_NO_DES
1314    BIO_puts(bio_out, "DES\n");
1315#endif
1316#ifdef OPENSSL_NO_DGRAM
1317    BIO_puts(bio_out, "DGRAM\n");
1318#endif
1319#ifdef OPENSSL_NO_DH
1320    BIO_puts(bio_out, "DH\n");
1321#endif
1322#ifdef OPENSSL_NO_DSA
1323    BIO_puts(bio_out, "DSA\n");
1324#endif
1325#if defined(OPENSSL_NO_DTLS)
1326    BIO_puts(bio_out, "DTLS\n");
1327#endif
1328#if defined(OPENSSL_NO_DTLS1)
1329    BIO_puts(bio_out, "DTLS1\n");
1330#endif
1331#if defined(OPENSSL_NO_DTLS1_2)
1332    BIO_puts(bio_out, "DTLS1_2\n");
1333#endif
1334#ifdef OPENSSL_NO_EC
1335    BIO_puts(bio_out, "EC\n");
1336#endif
1337#ifdef OPENSSL_NO_EC2M
1338    BIO_puts(bio_out, "EC2M\n");
1339#endif
1340#if defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
1341    BIO_puts(bio_out, "ENGINE\n");
1342#endif
1343#ifdef OPENSSL_NO_GOST
1344    BIO_puts(bio_out, "GOST\n");
1345#endif
1346#ifdef OPENSSL_NO_IDEA
1347    BIO_puts(bio_out, "IDEA\n");
1348#endif
1349#ifdef OPENSSL_NO_MD2
1350    BIO_puts(bio_out, "MD2\n");
1351#endif
1352#ifdef OPENSSL_NO_MD4
1353    BIO_puts(bio_out, "MD4\n");
1354#endif
1355#ifdef OPENSSL_NO_MD5
1356    BIO_puts(bio_out, "MD5\n");
1357#endif
1358#ifdef OPENSSL_NO_MDC2
1359    BIO_puts(bio_out, "MDC2\n");
1360#endif
1361#ifdef OPENSSL_NO_OCB
1362    BIO_puts(bio_out, "OCB\n");
1363#endif
1364#ifdef OPENSSL_NO_OCSP
1365    BIO_puts(bio_out, "OCSP\n");
1366#endif
1367#ifdef OPENSSL_NO_PSK
1368    BIO_puts(bio_out, "PSK\n");
1369#endif
1370#ifdef OPENSSL_NO_RC2
1371    BIO_puts(bio_out, "RC2\n");
1372#endif
1373#ifdef OPENSSL_NO_RC4
1374    BIO_puts(bio_out, "RC4\n");
1375#endif
1376#ifdef OPENSSL_NO_RC5
1377    BIO_puts(bio_out, "RC5\n");
1378#endif
1379#ifdef OPENSSL_NO_RMD160
1380    BIO_puts(bio_out, "RMD160\n");
1381#endif
1382#ifdef OPENSSL_NO_SCRYPT
1383    BIO_puts(bio_out, "SCRYPT\n");
1384#endif
1385#ifdef OPENSSL_NO_SCTP
1386    BIO_puts(bio_out, "SCTP\n");
1387#endif
1388#ifdef OPENSSL_NO_SEED
1389    BIO_puts(bio_out, "SEED\n");
1390#endif
1391#ifdef OPENSSL_NO_SM2
1392    BIO_puts(bio_out, "SM2\n");
1393#endif
1394#ifdef OPENSSL_NO_SM3
1395    BIO_puts(bio_out, "SM3\n");
1396#endif
1397#ifdef OPENSSL_NO_SM4
1398    BIO_puts(bio_out, "SM4\n");
1399#endif
1400#ifdef OPENSSL_NO_SOCK
1401    BIO_puts(bio_out, "SOCK\n");
1402#endif
1403#ifdef OPENSSL_NO_SRP
1404    BIO_puts(bio_out, "SRP\n");
1405#endif
1406#ifdef OPENSSL_NO_SRTP
1407    BIO_puts(bio_out, "SRTP\n");
1408#endif
1409#ifdef OPENSSL_NO_SSL3
1410    BIO_puts(bio_out, "SSL3\n");
1411#endif
1412#ifdef OPENSSL_NO_TLS1
1413    BIO_puts(bio_out, "TLS1\n");
1414#endif
1415#ifdef OPENSSL_NO_TLS1_1
1416    BIO_puts(bio_out, "TLS1_1\n");
1417#endif
1418#ifdef OPENSSL_NO_TLS1_2
1419    BIO_puts(bio_out, "TLS1_2\n");
1420#endif
1421#ifdef OPENSSL_NO_WHIRLPOOL
1422    BIO_puts(bio_out, "WHIRLPOOL\n");
1423#endif
1424#ifndef ZLIB
1425    BIO_puts(bio_out, "ZLIB\n");
1426#endif
1427}
1428
1429/* Unified enum for help and list commands. */
1430typedef enum HELPLIST_CHOICE {
1431    OPT_COMMON,
1432    OPT_ONE, OPT_VERBOSE,
1433    OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS,
1434    OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
1435    OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED,
1436    OPT_KDF_ALGORITHMS, OPT_RANDOM_INSTANCES, OPT_RANDOM_GENERATORS,
1437    OPT_ENCODERS, OPT_DECODERS, OPT_KEYMANAGERS, OPT_KEYEXCHANGE_ALGORITHMS,
1438    OPT_KEM_ALGORITHMS, OPT_SIGNATURE_ALGORITHMS, OPT_ASYM_CIPHER_ALGORITHMS,
1439    OPT_STORE_LOADERS, OPT_PROVIDER_INFO,
1440    OPT_OBJECTS, OPT_SELECT_NAME,
1441#ifndef OPENSSL_NO_DEPRECATED_3_0
1442    OPT_ENGINES,
1443#endif
1444    OPT_PROV_ENUM
1445} HELPLIST_CHOICE;
1446
1447const OPTIONS list_options[] = {
1448
1449    OPT_SECTION("General"),
1450    {"help", OPT_HELP, '-', "Display this summary"},
1451
1452    OPT_SECTION("Output"),
1453    {"1", OPT_ONE, '-', "List in one column"},
1454    {"verbose", OPT_VERBOSE, '-', "Verbose listing"},
1455    {"select", OPT_SELECT_NAME, 's', "Select a single algorithm"},
1456    {"commands", OPT_COMMANDS, '-', "List of standard commands"},
1457    {"standard-commands", OPT_COMMANDS, '-', "List of standard commands"},
1458#ifndef OPENSSL_NO_DEPRECATED_3_0
1459    {"digest-commands", OPT_DIGEST_COMMANDS, '-',
1460     "List of message digest commands (deprecated)"},
1461#endif
1462    {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-',
1463     "List of message digest algorithms"},
1464    {"kdf-algorithms", OPT_KDF_ALGORITHMS, '-',
1465     "List of key derivation and pseudo random function algorithms"},
1466    {"random-instances", OPT_RANDOM_INSTANCES, '-',
1467     "List the primary, public and private random number generator details"},
1468    {"random-generators", OPT_RANDOM_GENERATORS, '-',
1469     "List of random number generators"},
1470    {"mac-algorithms", OPT_MAC_ALGORITHMS, '-',
1471     "List of message authentication code algorithms"},
1472#ifndef OPENSSL_NO_DEPRECATED_3_0
1473    {"cipher-commands", OPT_CIPHER_COMMANDS, '-',
1474    "List of cipher commands (deprecated)"},
1475#endif
1476    {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-',
1477     "List of symmetric cipher algorithms"},
1478    {"encoders", OPT_ENCODERS, '-', "List of encoding methods" },
1479    {"decoders", OPT_DECODERS, '-', "List of decoding methods" },
1480    {"key-managers", OPT_KEYMANAGERS, '-', "List of key managers" },
1481    {"key-exchange-algorithms", OPT_KEYEXCHANGE_ALGORITHMS, '-',
1482     "List of key exchange algorithms" },
1483    {"kem-algorithms", OPT_KEM_ALGORITHMS, '-',
1484     "List of key encapsulation mechanism algorithms" },
1485    {"signature-algorithms", OPT_SIGNATURE_ALGORITHMS, '-',
1486     "List of signature algorithms" },
1487    {"asymcipher-algorithms", OPT_ASYM_CIPHER_ALGORITHMS, '-',
1488      "List of asymmetric cipher algorithms" },
1489    {"public-key-algorithms", OPT_PK_ALGORITHMS, '-',
1490     "List of public key algorithms"},
1491    {"public-key-methods", OPT_PK_METHOD, '-',
1492     "List of public key methods"},
1493    {"store-loaders", OPT_STORE_LOADERS, '-',
1494     "List of store loaders"},
1495    {"providers", OPT_PROVIDER_INFO, '-',
1496     "List of provider information"},
1497#ifndef OPENSSL_NO_DEPRECATED_3_0
1498    {"engines", OPT_ENGINES, '-',
1499     "List of loaded engines"},
1500#endif
1501    {"disabled", OPT_DISABLED, '-', "List of disabled features"},
1502    {"options", OPT_OPTIONS, 's',
1503     "List options for specified command"},
1504    {"objects", OPT_OBJECTS, '-',
1505     "List built in objects (OID<->name mappings)"},
1506
1507    OPT_PROV_OPTIONS,
1508    {NULL}
1509};
1510
1511int list_main(int argc, char **argv)
1512{
1513    char *prog;
1514    HELPLIST_CHOICE o;
1515    int one = 0, done = 0;
1516    struct {
1517        unsigned int commands:1;
1518        unsigned int random_instances:1;
1519        unsigned int random_generators:1;
1520        unsigned int digest_commands:1;
1521        unsigned int digest_algorithms:1;
1522        unsigned int kdf_algorithms:1;
1523        unsigned int mac_algorithms:1;
1524        unsigned int cipher_commands:1;
1525        unsigned int cipher_algorithms:1;
1526        unsigned int encoder_algorithms:1;
1527        unsigned int decoder_algorithms:1;
1528        unsigned int keymanager_algorithms:1;
1529        unsigned int signature_algorithms:1;
1530        unsigned int keyexchange_algorithms:1;
1531        unsigned int kem_algorithms:1;
1532        unsigned int asym_cipher_algorithms:1;
1533        unsigned int pk_algorithms:1;
1534        unsigned int pk_method:1;
1535        unsigned int store_loaders:1;
1536        unsigned int provider_info:1;
1537#ifndef OPENSSL_NO_DEPRECATED_3_0
1538        unsigned int engines:1;
1539#endif
1540        unsigned int disabled:1;
1541        unsigned int objects:1;
1542        unsigned int options:1;
1543    } todo = { 0, };
1544
1545    verbose = 0;                 /* Clear a possible previous call */
1546
1547    prog = opt_init(argc, argv, list_options);
1548    while ((o = opt_next()) != OPT_EOF) {
1549        switch (o) {
1550        case OPT_EOF:  /* Never hit, but suppresses warning */
1551        case OPT_ERR:
1552opthelp:
1553            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
1554            return 1;
1555        case OPT_HELP:
1556            opt_help(list_options);
1557            return 0;
1558        case OPT_ONE:
1559            one = 1;
1560            break;
1561        case OPT_COMMANDS:
1562            todo.commands = 1;
1563            break;
1564        case OPT_DIGEST_COMMANDS:
1565            todo.digest_commands = 1;
1566            break;
1567        case OPT_DIGEST_ALGORITHMS:
1568            todo.digest_algorithms = 1;
1569            break;
1570        case OPT_KDF_ALGORITHMS:
1571            todo.kdf_algorithms = 1;
1572            break;
1573        case OPT_RANDOM_INSTANCES:
1574            todo.random_instances = 1;
1575            break;
1576        case OPT_RANDOM_GENERATORS:
1577            todo.random_generators = 1;
1578            break;
1579        case OPT_MAC_ALGORITHMS:
1580            todo.mac_algorithms = 1;
1581            break;
1582        case OPT_CIPHER_COMMANDS:
1583            todo.cipher_commands = 1;
1584            break;
1585        case OPT_CIPHER_ALGORITHMS:
1586            todo.cipher_algorithms = 1;
1587            break;
1588        case OPT_ENCODERS:
1589            todo.encoder_algorithms = 1;
1590            break;
1591        case OPT_DECODERS:
1592            todo.decoder_algorithms = 1;
1593            break;
1594        case OPT_KEYMANAGERS:
1595            todo.keymanager_algorithms = 1;
1596            break;
1597        case OPT_SIGNATURE_ALGORITHMS:
1598            todo.signature_algorithms = 1;
1599            break;
1600        case OPT_KEYEXCHANGE_ALGORITHMS:
1601            todo.keyexchange_algorithms = 1;
1602            break;
1603        case OPT_KEM_ALGORITHMS:
1604            todo.kem_algorithms = 1;
1605            break;
1606        case OPT_ASYM_CIPHER_ALGORITHMS:
1607            todo.asym_cipher_algorithms = 1;
1608            break;
1609        case OPT_PK_ALGORITHMS:
1610            todo.pk_algorithms = 1;
1611            break;
1612        case OPT_PK_METHOD:
1613            todo.pk_method = 1;
1614            break;
1615        case OPT_STORE_LOADERS:
1616            todo.store_loaders = 1;
1617            break;
1618        case OPT_PROVIDER_INFO:
1619            todo.provider_info = 1;
1620            break;
1621#ifndef OPENSSL_NO_DEPRECATED_3_0
1622        case OPT_ENGINES:
1623            todo.engines = 1;
1624            break;
1625#endif
1626        case OPT_DISABLED:
1627            todo.disabled = 1;
1628            break;
1629        case OPT_OBJECTS:
1630            todo.objects = 1;
1631            break;
1632        case OPT_OPTIONS:
1633            list_options_for_command(opt_arg());
1634            break;
1635        case OPT_VERBOSE:
1636            verbose = 1;
1637            break;
1638        case OPT_SELECT_NAME:
1639            select_name = opt_arg();
1640            break;
1641        case OPT_PROV_CASES:
1642            if (!opt_provider(o))
1643                return 1;
1644            break;
1645        }
1646        done = 1;
1647    }
1648
1649    /* No extra arguments. */
1650    if (opt_num_rest() != 0)
1651        goto opthelp;
1652
1653    if (todo.commands)
1654        list_type(FT_general, one);
1655    if (todo.random_instances)
1656        list_random_instances();
1657    if (todo.random_generators)
1658        list_random_generators();
1659    if (todo.digest_commands)
1660        list_type(FT_md, one);
1661    if (todo.digest_algorithms)
1662        list_digests();
1663    if (todo.kdf_algorithms)
1664        list_kdfs();
1665    if (todo.mac_algorithms)
1666        list_macs();
1667    if (todo.cipher_commands)
1668        list_type(FT_cipher, one);
1669    if (todo.cipher_algorithms)
1670        list_ciphers();
1671    if (todo.encoder_algorithms)
1672        list_encoders();
1673    if (todo.decoder_algorithms)
1674        list_decoders();
1675    if (todo.keymanager_algorithms)
1676        list_keymanagers();
1677    if (todo.signature_algorithms)
1678        list_signatures();
1679    if (todo.asym_cipher_algorithms)
1680        list_asymciphers();
1681    if (todo.keyexchange_algorithms)
1682        list_keyexchanges();
1683    if (todo.kem_algorithms)
1684        list_kems();
1685    if (todo.pk_algorithms)
1686        list_pkey();
1687    if (todo.pk_method)
1688        list_pkey_meth();
1689    if (todo.store_loaders)
1690        list_store_loaders();
1691    if (todo.provider_info)
1692        list_provider_info();
1693#ifndef OPENSSL_NO_DEPRECATED_3_0
1694    if (todo.engines)
1695        list_engines();
1696#endif
1697    if (todo.disabled)
1698        list_disabled();
1699    if (todo.objects)
1700        list_objects();
1701
1702    if (!done)
1703        goto opthelp;
1704
1705    return 0;
1706}
1707