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