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     * If OK - result is the index of inserted data
1214     * Error - result is -1 or 0
1215     */
1216    return sk_OSSL_PROVIDER_push(provider_stack, provider) > 0 ? 1 : 0;
1217}
1218
1219static void list_provider_info(void)
1220{
1221    STACK_OF(OSSL_PROVIDER) *providers = sk_OSSL_PROVIDER_new(provider_cmp);
1222    OSSL_PARAM params[5];
1223    char *name, *version, *buildinfo;
1224    int status;
1225    int i;
1226
1227    if (providers == NULL) {
1228        BIO_printf(bio_err, "ERROR: Memory allocation\n");
1229        return;
1230    }
1231
1232    if (OSSL_PROVIDER_do_all(NULL, &collect_providers, providers) != 1) {
1233        BIO_printf(bio_err, "ERROR: Memory allocation\n");
1234        return;
1235    }
1236
1237    BIO_printf(bio_out, "Providers:\n");
1238    sk_OSSL_PROVIDER_sort(providers);
1239    for (i = 0; i < sk_OSSL_PROVIDER_num(providers); i++) {
1240        const OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(providers, i);
1241        const char *provname = OSSL_PROVIDER_get0_name(prov);
1242
1243        BIO_printf(bio_out, "  %s\n", provname);
1244
1245        /* Query the "known" information parameters, the order matches below */
1246        params[0] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_NAME,
1247                                                  &name, 0);
1248        params[1] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_VERSION,
1249                                                  &version, 0);
1250        params[2] = OSSL_PARAM_construct_int(OSSL_PROV_PARAM_STATUS, &status);
1251        params[3] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_BUILDINFO,
1252                                                  &buildinfo, 0);
1253        params[4] = OSSL_PARAM_construct_end();
1254        OSSL_PARAM_set_all_unmodified(params);
1255        if (!OSSL_PROVIDER_get_params(prov, params)) {
1256            BIO_printf(bio_err,
1257                       "WARNING: Unable to query provider parameters for %s\n",
1258                       provname);
1259        } else {
1260            /* Print out the provider information, the params order matches above */
1261            if (OSSL_PARAM_modified(params))
1262                BIO_printf(bio_out, "    name: %s\n", name);
1263            if (OSSL_PARAM_modified(params + 1))
1264                BIO_printf(bio_out, "    version: %s\n", version);
1265            if (OSSL_PARAM_modified(params + 2))
1266                BIO_printf(bio_out, "    status: %sactive\n", status ? "" : "in");
1267            if (verbose) {
1268                if (OSSL_PARAM_modified(params + 3))
1269                    BIO_printf(bio_out, "    build info: %s\n", buildinfo);
1270                print_param_types("gettable provider parameters",
1271                                  OSSL_PROVIDER_gettable_params(prov), 4);
1272            }
1273        }
1274    }
1275    sk_OSSL_PROVIDER_free(providers);
1276}
1277
1278#ifndef OPENSSL_NO_DEPRECATED_3_0
1279static void list_engines(void)
1280{
1281# ifndef OPENSSL_NO_ENGINE
1282    ENGINE *e;
1283
1284    BIO_puts(bio_out, "Engines:\n");
1285    e = ENGINE_get_first();
1286    while (e) {
1287        BIO_printf(bio_out, "%s\n", ENGINE_get_id(e));
1288        e = ENGINE_get_next(e);
1289    }
1290# else
1291    BIO_puts(bio_out, "Engine support is disabled.\n");
1292# endif
1293}
1294#endif
1295
1296static void list_disabled(void)
1297{
1298    BIO_puts(bio_out, "Disabled algorithms:\n");
1299#ifdef OPENSSL_NO_ARIA
1300    BIO_puts(bio_out, "ARIA\n");
1301#endif
1302#ifdef OPENSSL_NO_BF
1303    BIO_puts(bio_out, "BF\n");
1304#endif
1305#ifdef OPENSSL_NO_BLAKE2
1306    BIO_puts(bio_out, "BLAKE2\n");
1307#endif
1308#ifdef OPENSSL_NO_CAMELLIA
1309    BIO_puts(bio_out, "CAMELLIA\n");
1310#endif
1311#ifdef OPENSSL_NO_CAST
1312    BIO_puts(bio_out, "CAST\n");
1313#endif
1314#ifdef OPENSSL_NO_CMAC
1315    BIO_puts(bio_out, "CMAC\n");
1316#endif
1317#ifdef OPENSSL_NO_CMS
1318    BIO_puts(bio_out, "CMS\n");
1319#endif
1320#ifdef OPENSSL_NO_COMP
1321    BIO_puts(bio_out, "COMP\n");
1322#endif
1323#ifdef OPENSSL_NO_DES
1324    BIO_puts(bio_out, "DES\n");
1325#endif
1326#ifdef OPENSSL_NO_DGRAM
1327    BIO_puts(bio_out, "DGRAM\n");
1328#endif
1329#ifdef OPENSSL_NO_DH
1330    BIO_puts(bio_out, "DH\n");
1331#endif
1332#ifdef OPENSSL_NO_DSA
1333    BIO_puts(bio_out, "DSA\n");
1334#endif
1335#if defined(OPENSSL_NO_DTLS)
1336    BIO_puts(bio_out, "DTLS\n");
1337#endif
1338#if defined(OPENSSL_NO_DTLS1)
1339    BIO_puts(bio_out, "DTLS1\n");
1340#endif
1341#if defined(OPENSSL_NO_DTLS1_2)
1342    BIO_puts(bio_out, "DTLS1_2\n");
1343#endif
1344#ifdef OPENSSL_NO_EC
1345    BIO_puts(bio_out, "EC\n");
1346#endif
1347#ifdef OPENSSL_NO_EC2M
1348    BIO_puts(bio_out, "EC2M\n");
1349#endif
1350#if defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
1351    BIO_puts(bio_out, "ENGINE\n");
1352#endif
1353#ifdef OPENSSL_NO_GOST
1354    BIO_puts(bio_out, "GOST\n");
1355#endif
1356#ifdef OPENSSL_NO_IDEA
1357    BIO_puts(bio_out, "IDEA\n");
1358#endif
1359#ifdef OPENSSL_NO_MD2
1360    BIO_puts(bio_out, "MD2\n");
1361#endif
1362#ifdef OPENSSL_NO_MD4
1363    BIO_puts(bio_out, "MD4\n");
1364#endif
1365#ifdef OPENSSL_NO_MD5
1366    BIO_puts(bio_out, "MD5\n");
1367#endif
1368#ifdef OPENSSL_NO_MDC2
1369    BIO_puts(bio_out, "MDC2\n");
1370#endif
1371#ifdef OPENSSL_NO_OCB
1372    BIO_puts(bio_out, "OCB\n");
1373#endif
1374#ifdef OPENSSL_NO_OCSP
1375    BIO_puts(bio_out, "OCSP\n");
1376#endif
1377#ifdef OPENSSL_NO_PSK
1378    BIO_puts(bio_out, "PSK\n");
1379#endif
1380#ifdef OPENSSL_NO_RC2
1381    BIO_puts(bio_out, "RC2\n");
1382#endif
1383#ifdef OPENSSL_NO_RC4
1384    BIO_puts(bio_out, "RC4\n");
1385#endif
1386#ifdef OPENSSL_NO_RC5
1387    BIO_puts(bio_out, "RC5\n");
1388#endif
1389#ifdef OPENSSL_NO_RMD160
1390    BIO_puts(bio_out, "RMD160\n");
1391#endif
1392#ifdef OPENSSL_NO_SCRYPT
1393    BIO_puts(bio_out, "SCRYPT\n");
1394#endif
1395#ifdef OPENSSL_NO_SCTP
1396    BIO_puts(bio_out, "SCTP\n");
1397#endif
1398#ifdef OPENSSL_NO_SEED
1399    BIO_puts(bio_out, "SEED\n");
1400#endif
1401#ifdef OPENSSL_NO_SM2
1402    BIO_puts(bio_out, "SM2\n");
1403#endif
1404#ifdef OPENSSL_NO_SM3
1405    BIO_puts(bio_out, "SM3\n");
1406#endif
1407#ifdef OPENSSL_NO_SM4
1408    BIO_puts(bio_out, "SM4\n");
1409#endif
1410#ifdef OPENSSL_NO_SOCK
1411    BIO_puts(bio_out, "SOCK\n");
1412#endif
1413#ifdef OPENSSL_NO_SRP
1414    BIO_puts(bio_out, "SRP\n");
1415#endif
1416#ifdef OPENSSL_NO_SRTP
1417    BIO_puts(bio_out, "SRTP\n");
1418#endif
1419#ifdef OPENSSL_NO_SSL3
1420    BIO_puts(bio_out, "SSL3\n");
1421#endif
1422#ifdef OPENSSL_NO_TLS1
1423    BIO_puts(bio_out, "TLS1\n");
1424#endif
1425#ifdef OPENSSL_NO_TLS1_1
1426    BIO_puts(bio_out, "TLS1_1\n");
1427#endif
1428#ifdef OPENSSL_NO_TLS1_2
1429    BIO_puts(bio_out, "TLS1_2\n");
1430#endif
1431#ifdef OPENSSL_NO_WHIRLPOOL
1432    BIO_puts(bio_out, "WHIRLPOOL\n");
1433#endif
1434#ifndef ZLIB
1435    BIO_puts(bio_out, "ZLIB\n");
1436#endif
1437}
1438
1439/* Unified enum for help and list commands. */
1440typedef enum HELPLIST_CHOICE {
1441    OPT_COMMON,
1442    OPT_ONE, OPT_VERBOSE,
1443    OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS,
1444    OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
1445    OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED,
1446    OPT_KDF_ALGORITHMS, OPT_RANDOM_INSTANCES, OPT_RANDOM_GENERATORS,
1447    OPT_ENCODERS, OPT_DECODERS, OPT_KEYMANAGERS, OPT_KEYEXCHANGE_ALGORITHMS,
1448    OPT_KEM_ALGORITHMS, OPT_SIGNATURE_ALGORITHMS, OPT_ASYM_CIPHER_ALGORITHMS,
1449    OPT_STORE_LOADERS, OPT_PROVIDER_INFO,
1450    OPT_OBJECTS, OPT_SELECT_NAME,
1451#ifndef OPENSSL_NO_DEPRECATED_3_0
1452    OPT_ENGINES,
1453#endif
1454    OPT_PROV_ENUM
1455} HELPLIST_CHOICE;
1456
1457const OPTIONS list_options[] = {
1458
1459    OPT_SECTION("General"),
1460    {"help", OPT_HELP, '-', "Display this summary"},
1461
1462    OPT_SECTION("Output"),
1463    {"1", OPT_ONE, '-', "List in one column"},
1464    {"verbose", OPT_VERBOSE, '-', "Verbose listing"},
1465    {"select", OPT_SELECT_NAME, 's', "Select a single algorithm"},
1466    {"commands", OPT_COMMANDS, '-', "List of standard commands"},
1467    {"standard-commands", OPT_COMMANDS, '-', "List of standard commands"},
1468#ifndef OPENSSL_NO_DEPRECATED_3_0
1469    {"digest-commands", OPT_DIGEST_COMMANDS, '-',
1470     "List of message digest commands (deprecated)"},
1471#endif
1472    {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-',
1473     "List of message digest algorithms"},
1474    {"kdf-algorithms", OPT_KDF_ALGORITHMS, '-',
1475     "List of key derivation and pseudo random function algorithms"},
1476    {"random-instances", OPT_RANDOM_INSTANCES, '-',
1477     "List the primary, public and private random number generator details"},
1478    {"random-generators", OPT_RANDOM_GENERATORS, '-',
1479     "List of random number generators"},
1480    {"mac-algorithms", OPT_MAC_ALGORITHMS, '-',
1481     "List of message authentication code algorithms"},
1482#ifndef OPENSSL_NO_DEPRECATED_3_0
1483    {"cipher-commands", OPT_CIPHER_COMMANDS, '-',
1484    "List of cipher commands (deprecated)"},
1485#endif
1486    {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-',
1487     "List of symmetric cipher algorithms"},
1488    {"encoders", OPT_ENCODERS, '-', "List of encoding methods" },
1489    {"decoders", OPT_DECODERS, '-', "List of decoding methods" },
1490    {"key-managers", OPT_KEYMANAGERS, '-', "List of key managers" },
1491    {"key-exchange-algorithms", OPT_KEYEXCHANGE_ALGORITHMS, '-',
1492     "List of key exchange algorithms" },
1493    {"kem-algorithms", OPT_KEM_ALGORITHMS, '-',
1494     "List of key encapsulation mechanism algorithms" },
1495    {"signature-algorithms", OPT_SIGNATURE_ALGORITHMS, '-',
1496     "List of signature algorithms" },
1497    {"asymcipher-algorithms", OPT_ASYM_CIPHER_ALGORITHMS, '-',
1498      "List of asymmetric cipher algorithms" },
1499    {"public-key-algorithms", OPT_PK_ALGORITHMS, '-',
1500     "List of public key algorithms"},
1501    {"public-key-methods", OPT_PK_METHOD, '-',
1502     "List of public key methods"},
1503    {"store-loaders", OPT_STORE_LOADERS, '-',
1504     "List of store loaders"},
1505    {"providers", OPT_PROVIDER_INFO, '-',
1506     "List of provider information"},
1507#ifndef OPENSSL_NO_DEPRECATED_3_0
1508    {"engines", OPT_ENGINES, '-',
1509     "List of loaded engines"},
1510#endif
1511    {"disabled", OPT_DISABLED, '-', "List of disabled features"},
1512    {"options", OPT_OPTIONS, 's',
1513     "List options for specified command"},
1514    {"objects", OPT_OBJECTS, '-',
1515     "List built in objects (OID<->name mappings)"},
1516
1517    OPT_PROV_OPTIONS,
1518    {NULL}
1519};
1520
1521int list_main(int argc, char **argv)
1522{
1523    char *prog;
1524    HELPLIST_CHOICE o;
1525    int one = 0, done = 0;
1526    struct {
1527        unsigned int commands:1;
1528        unsigned int random_instances:1;
1529        unsigned int random_generators:1;
1530        unsigned int digest_commands:1;
1531        unsigned int digest_algorithms:1;
1532        unsigned int kdf_algorithms:1;
1533        unsigned int mac_algorithms:1;
1534        unsigned int cipher_commands:1;
1535        unsigned int cipher_algorithms:1;
1536        unsigned int encoder_algorithms:1;
1537        unsigned int decoder_algorithms:1;
1538        unsigned int keymanager_algorithms:1;
1539        unsigned int signature_algorithms:1;
1540        unsigned int keyexchange_algorithms:1;
1541        unsigned int kem_algorithms:1;
1542        unsigned int asym_cipher_algorithms:1;
1543        unsigned int pk_algorithms:1;
1544        unsigned int pk_method:1;
1545        unsigned int store_loaders:1;
1546        unsigned int provider_info:1;
1547#ifndef OPENSSL_NO_DEPRECATED_3_0
1548        unsigned int engines:1;
1549#endif
1550        unsigned int disabled:1;
1551        unsigned int objects:1;
1552        unsigned int options:1;
1553    } todo = { 0, };
1554
1555    verbose = 0;                 /* Clear a possible previous call */
1556
1557    prog = opt_init(argc, argv, list_options);
1558    while ((o = opt_next()) != OPT_EOF) {
1559        switch (o) {
1560        case OPT_EOF:  /* Never hit, but suppresses warning */
1561        case OPT_ERR:
1562opthelp:
1563            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
1564            return 1;
1565        case OPT_HELP:
1566            opt_help(list_options);
1567            return 0;
1568        case OPT_ONE:
1569            one = 1;
1570            break;
1571        case OPT_COMMANDS:
1572            todo.commands = 1;
1573            break;
1574        case OPT_DIGEST_COMMANDS:
1575            todo.digest_commands = 1;
1576            break;
1577        case OPT_DIGEST_ALGORITHMS:
1578            todo.digest_algorithms = 1;
1579            break;
1580        case OPT_KDF_ALGORITHMS:
1581            todo.kdf_algorithms = 1;
1582            break;
1583        case OPT_RANDOM_INSTANCES:
1584            todo.random_instances = 1;
1585            break;
1586        case OPT_RANDOM_GENERATORS:
1587            todo.random_generators = 1;
1588            break;
1589        case OPT_MAC_ALGORITHMS:
1590            todo.mac_algorithms = 1;
1591            break;
1592        case OPT_CIPHER_COMMANDS:
1593            todo.cipher_commands = 1;
1594            break;
1595        case OPT_CIPHER_ALGORITHMS:
1596            todo.cipher_algorithms = 1;
1597            break;
1598        case OPT_ENCODERS:
1599            todo.encoder_algorithms = 1;
1600            break;
1601        case OPT_DECODERS:
1602            todo.decoder_algorithms = 1;
1603            break;
1604        case OPT_KEYMANAGERS:
1605            todo.keymanager_algorithms = 1;
1606            break;
1607        case OPT_SIGNATURE_ALGORITHMS:
1608            todo.signature_algorithms = 1;
1609            break;
1610        case OPT_KEYEXCHANGE_ALGORITHMS:
1611            todo.keyexchange_algorithms = 1;
1612            break;
1613        case OPT_KEM_ALGORITHMS:
1614            todo.kem_algorithms = 1;
1615            break;
1616        case OPT_ASYM_CIPHER_ALGORITHMS:
1617            todo.asym_cipher_algorithms = 1;
1618            break;
1619        case OPT_PK_ALGORITHMS:
1620            todo.pk_algorithms = 1;
1621            break;
1622        case OPT_PK_METHOD:
1623            todo.pk_method = 1;
1624            break;
1625        case OPT_STORE_LOADERS:
1626            todo.store_loaders = 1;
1627            break;
1628        case OPT_PROVIDER_INFO:
1629            todo.provider_info = 1;
1630            break;
1631#ifndef OPENSSL_NO_DEPRECATED_3_0
1632        case OPT_ENGINES:
1633            todo.engines = 1;
1634            break;
1635#endif
1636        case OPT_DISABLED:
1637            todo.disabled = 1;
1638            break;
1639        case OPT_OBJECTS:
1640            todo.objects = 1;
1641            break;
1642        case OPT_OPTIONS:
1643            list_options_for_command(opt_arg());
1644            break;
1645        case OPT_VERBOSE:
1646            verbose = 1;
1647            break;
1648        case OPT_SELECT_NAME:
1649            select_name = opt_arg();
1650            break;
1651        case OPT_PROV_CASES:
1652            if (!opt_provider(o))
1653                return 1;
1654            break;
1655        }
1656        done = 1;
1657    }
1658
1659    /* No extra arguments. */
1660    if (opt_num_rest() != 0)
1661        goto opthelp;
1662
1663    if (todo.commands)
1664        list_type(FT_general, one);
1665    if (todo.random_instances)
1666        list_random_instances();
1667    if (todo.random_generators)
1668        list_random_generators();
1669    if (todo.digest_commands)
1670        list_type(FT_md, one);
1671    if (todo.digest_algorithms)
1672        list_digests();
1673    if (todo.kdf_algorithms)
1674        list_kdfs();
1675    if (todo.mac_algorithms)
1676        list_macs();
1677    if (todo.cipher_commands)
1678        list_type(FT_cipher, one);
1679    if (todo.cipher_algorithms)
1680        list_ciphers();
1681    if (todo.encoder_algorithms)
1682        list_encoders();
1683    if (todo.decoder_algorithms)
1684        list_decoders();
1685    if (todo.keymanager_algorithms)
1686        list_keymanagers();
1687    if (todo.signature_algorithms)
1688        list_signatures();
1689    if (todo.asym_cipher_algorithms)
1690        list_asymciphers();
1691    if (todo.keyexchange_algorithms)
1692        list_keyexchanges();
1693    if (todo.kem_algorithms)
1694        list_kems();
1695    if (todo.pk_algorithms)
1696        list_pkey();
1697    if (todo.pk_method)
1698        list_pkey_meth();
1699    if (todo.store_loaders)
1700        list_store_loaders();
1701    if (todo.provider_info)
1702        list_provider_info();
1703#ifndef OPENSSL_NO_DEPRECATED_3_0
1704    if (todo.engines)
1705        list_engines();
1706#endif
1707    if (todo.disabled)
1708        list_disabled();
1709    if (todo.objects)
1710        list_objects();
1711
1712    if (!done)
1713        goto opthelp;
1714
1715    return 0;
1716}
1717