fd018991e12c150c573c589414e241bbcb1224da
[openssl.git] / apps / list.c
1 /*
2  * Copyright 1995-2020 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/core_names.h>
22 #include "apps.h"
23 #include "app_params.h"
24 #include "progs.h"
25 #include "opt.h"
26 #include "names.h"
27
28 static int verbose = 0;
29
30 static void legacy_cipher_fn(const EVP_CIPHER *c,
31                              const char *from, const char *to, void *arg)
32 {
33     if (c != NULL) {
34         BIO_printf(arg, "  %s\n", EVP_CIPHER_name(c));
35     } else {
36         if (from == NULL)
37             from = "<undefined>";
38         if (to == NULL)
39             to = "<undefined>";
40         BIO_printf(arg, "  %s => %s\n", from, to);
41     }
42 }
43
44 DEFINE_STACK_OF(EVP_CIPHER)
45 static int cipher_cmp(const EVP_CIPHER * const *a,
46                       const EVP_CIPHER * const *b)
47 {
48     int ret = EVP_CIPHER_number(*a) - EVP_CIPHER_number(*b);
49
50     if (ret == 0)
51         ret = strcmp(OSSL_PROVIDER_name(EVP_CIPHER_provider(*a)),
52                      OSSL_PROVIDER_name(EVP_CIPHER_provider(*b)));
53
54     return ret;
55 }
56
57 static void collect_ciphers(EVP_CIPHER *cipher, void *stack)
58 {
59     STACK_OF(EVP_CIPHER) *cipher_stack = stack;
60
61     if (sk_EVP_CIPHER_push(cipher_stack, cipher) > 0)
62         EVP_CIPHER_up_ref(cipher);
63 }
64
65 static void list_ciphers(void)
66 {
67     STACK_OF(EVP_CIPHER) *ciphers = sk_EVP_CIPHER_new(cipher_cmp);
68     int i;
69
70     if (ciphers == NULL) {
71         BIO_printf(bio_err, "ERROR: Memory allocation\n");
72         return;
73     }
74     BIO_printf(bio_out, "Legacy:\n");
75     EVP_CIPHER_do_all_sorted(legacy_cipher_fn, bio_out);
76
77     BIO_printf(bio_out, "Provided:\n");
78     EVP_CIPHER_do_all_provided(NULL, collect_ciphers, ciphers);
79     sk_EVP_CIPHER_sort(ciphers);
80     for (i = 0; i < sk_EVP_CIPHER_num(ciphers); i++) {
81         const EVP_CIPHER *c = sk_EVP_CIPHER_value(ciphers, i);
82         STACK_OF(OPENSSL_CSTRING) *names =
83             sk_OPENSSL_CSTRING_new(name_cmp);
84
85         EVP_CIPHER_names_do_all(c, collect_names, names);
86
87         BIO_printf(bio_out, "  ");
88         print_names(bio_out, names);
89         BIO_printf(bio_out, " @ %s\n",
90                    OSSL_PROVIDER_name(EVP_CIPHER_provider(c)));
91
92         sk_OPENSSL_CSTRING_free(names);
93
94         if (verbose) {
95             print_param_types("retrievable algorithm parameters",
96                               EVP_CIPHER_gettable_params(c), 4);
97             print_param_types("retrievable operation parameters",
98                               EVP_CIPHER_gettable_ctx_params(c), 4);
99             print_param_types("settable operation parameters",
100                               EVP_CIPHER_settable_ctx_params(c), 4);
101         }
102     }
103     sk_EVP_CIPHER_pop_free(ciphers, EVP_CIPHER_free);
104 }
105
106 static void list_md_fn(const EVP_MD *m,
107                        const char *from, const char *to, void *arg)
108 {
109     if (m != NULL) {
110         BIO_printf(arg, "  %s\n", EVP_MD_name(m));
111     } else {
112         if (from == NULL)
113             from = "<undefined>";
114         if (to == NULL)
115             to = "<undefined>";
116         BIO_printf((BIO *)arg, "  %s => %s\n", from, to);
117     }
118 }
119
120 DEFINE_STACK_OF(EVP_MD)
121 static int md_cmp(const EVP_MD * const *a, const EVP_MD * const *b)
122 {
123     int ret = EVP_MD_number(*a) - EVP_MD_number(*b);
124
125     if (ret == 0)
126         ret = strcmp(OSSL_PROVIDER_name(EVP_MD_provider(*a)),
127                      OSSL_PROVIDER_name(EVP_MD_provider(*b)));
128
129     return ret;
130 }
131
132 static void collect_digests(EVP_MD *md, void *stack)
133 {
134     STACK_OF(EVP_MD) *digest_stack = stack;
135
136     if (sk_EVP_MD_push(digest_stack, md) > 0)
137         EVP_MD_up_ref(md);
138 }
139
140 static void list_digests(void)
141 {
142     STACK_OF(EVP_MD) *digests = sk_EVP_MD_new(md_cmp);
143     int i;
144
145     if (digests == NULL) {
146         BIO_printf(bio_err, "ERROR: Memory allocation\n");
147         return;
148     }
149     BIO_printf(bio_out, "Legacy:\n");
150     EVP_MD_do_all_sorted(list_md_fn, bio_out);
151
152     BIO_printf(bio_out, "Provided:\n");
153     EVP_MD_do_all_provided(NULL, collect_digests, digests);
154     sk_EVP_MD_sort(digests);
155     for (i = 0; i < sk_EVP_MD_num(digests); i++) {
156         const EVP_MD *m = sk_EVP_MD_value(digests, i);
157         STACK_OF(OPENSSL_CSTRING) *names =
158             sk_OPENSSL_CSTRING_new(name_cmp);
159
160         EVP_MD_names_do_all(m, collect_names, names);
161
162         BIO_printf(bio_out, "  ");
163         print_names(bio_out, names);
164         BIO_printf(bio_out, " @ %s\n",
165                    OSSL_PROVIDER_name(EVP_MD_provider(m)));
166
167         sk_OPENSSL_CSTRING_free(names);
168
169         if (verbose) {
170             print_param_types("retrievable algorithm parameters",
171                               EVP_MD_gettable_params(m), 4);
172             print_param_types("retrievable operation parameters",
173                               EVP_MD_gettable_ctx_params(m), 4);
174             print_param_types("settable operation parameters",
175                               EVP_MD_settable_ctx_params(m), 4);
176         }
177     }
178     sk_EVP_MD_pop_free(digests, EVP_MD_free);
179 }
180
181 DEFINE_STACK_OF(EVP_MAC)
182 static int mac_cmp(const EVP_MAC * const *a, const EVP_MAC * const *b)
183 {
184     int ret = EVP_MAC_number(*a) - EVP_MAC_number(*b);
185
186     if (ret == 0)
187         ret = strcmp(OSSL_PROVIDER_name(EVP_MAC_provider(*a)),
188                      OSSL_PROVIDER_name(EVP_MAC_provider(*b)));
189
190     return ret;
191 }
192
193 static void collect_macs(EVP_MAC *mac, void *stack)
194 {
195     STACK_OF(EVP_MAC) *mac_stack = stack;
196
197     if (sk_EVP_MAC_push(mac_stack, mac) > 0)
198         EVP_MAC_up_ref(mac);
199 }
200
201 static void list_macs(void)
202 {
203     STACK_OF(EVP_MAC) *macs = sk_EVP_MAC_new(mac_cmp);
204     int i;
205
206     if (macs == NULL) {
207         BIO_printf(bio_err, "ERROR: Memory allocation\n");
208         return;
209     }
210     BIO_printf(bio_out, "Provided MACs:\n");
211     EVP_MAC_do_all_provided(NULL, collect_macs, macs);
212     sk_EVP_MAC_sort(macs);
213     for (i = 0; i < sk_EVP_MAC_num(macs); i++) {
214         const EVP_MAC *m = sk_EVP_MAC_value(macs, i);
215         STACK_OF(OPENSSL_CSTRING) *names =
216             sk_OPENSSL_CSTRING_new(name_cmp);
217
218         EVP_MAC_names_do_all(m, collect_names, names);
219
220         BIO_printf(bio_out, "  ");
221         print_names(bio_out, names);
222         BIO_printf(bio_out, " @ %s\n",
223                    OSSL_PROVIDER_name(EVP_MAC_provider(m)));
224
225         sk_OPENSSL_CSTRING_free(names);
226
227         if (verbose) {
228             print_param_types("retrievable algorithm parameters",
229                               EVP_MAC_gettable_params(m), 4);
230             print_param_types("retrievable operation parameters",
231                               EVP_MAC_gettable_ctx_params(m), 4);
232             print_param_types("settable operation parameters",
233                               EVP_MAC_settable_ctx_params(m), 4);
234         }
235     }
236     sk_EVP_MAC_pop_free(macs, EVP_MAC_free);
237 }
238
239 /*
240  * KDFs and PRFs
241  */
242 DEFINE_STACK_OF(EVP_KDF)
243 static int kdf_cmp(const EVP_KDF * const *a, const EVP_KDF * const *b)
244 {
245     int ret = EVP_KDF_number(*a) - EVP_KDF_number(*b);
246
247     if (ret == 0)
248         ret = strcmp(OSSL_PROVIDER_name(EVP_KDF_provider(*a)),
249                      OSSL_PROVIDER_name(EVP_KDF_provider(*b)));
250
251     return ret;
252 }
253
254 static void collect_kdfs(EVP_KDF *kdf, void *stack)
255 {
256     STACK_OF(EVP_KDF) *kdf_stack = stack;
257
258     sk_EVP_KDF_push(kdf_stack, kdf);
259     EVP_KDF_up_ref(kdf);
260 }
261
262 static void list_kdfs(void)
263 {
264     STACK_OF(EVP_KDF) *kdfs = sk_EVP_KDF_new(kdf_cmp);
265     int i;
266
267     if (kdfs == NULL) {
268         BIO_printf(bio_err, "ERROR: Memory allocation\n");
269         return;
270     }
271     BIO_printf(bio_out, "Provided KDFs and PDFs:\n");
272     EVP_KDF_do_all_provided(NULL, collect_kdfs, kdfs);
273     sk_EVP_KDF_sort(kdfs);
274     for (i = 0; i < sk_EVP_KDF_num(kdfs); i++) {
275         const EVP_KDF *k = sk_EVP_KDF_value(kdfs, i);
276         STACK_OF(OPENSSL_CSTRING) *names =
277             sk_OPENSSL_CSTRING_new(name_cmp);
278
279         EVP_KDF_names_do_all(k, collect_names, names);
280
281         BIO_printf(bio_out, "  ");
282         print_names(bio_out, names);
283         BIO_printf(bio_out, " @ %s\n",
284                    OSSL_PROVIDER_name(EVP_KDF_provider(k)));
285
286         sk_OPENSSL_CSTRING_free(names);
287
288         if (verbose) {
289             print_param_types("retrievable algorithm parameters",
290                               EVP_KDF_gettable_params(k), 4);
291             print_param_types("retrievable operation parameters",
292                               EVP_KDF_gettable_ctx_params(k), 4);
293             print_param_types("settable operation parameters",
294                               EVP_KDF_settable_ctx_params(k), 4);
295         }
296     }
297     sk_EVP_KDF_pop_free(kdfs, EVP_KDF_free);
298 }
299
300 /*
301  * RANDs
302  */
303 DEFINE_STACK_OF(EVP_RAND)
304
305 static int rand_cmp(const EVP_RAND * const *a, const EVP_RAND * const *b)
306 {
307     int ret = strcasecmp(EVP_RAND_name(*a), EVP_RAND_name(*b));
308
309     if (ret == 0)
310         ret = strcmp(OSSL_PROVIDER_name(EVP_RAND_provider(*a)),
311                      OSSL_PROVIDER_name(EVP_RAND_provider(*b)));
312
313     return ret;
314 }
315
316 static void collect_rands(EVP_RAND *rand, void *stack)
317 {
318     STACK_OF(EVP_RAND) *rand_stack = stack;
319
320     sk_EVP_RAND_push(rand_stack, rand);
321     EVP_RAND_up_ref(rand);
322 }
323
324 static void list_random_generators(void)
325 {
326     STACK_OF(EVP_RAND) *rands = sk_EVP_RAND_new(rand_cmp);
327     int i;
328
329     if (rands == NULL) {
330         BIO_printf(bio_err, "ERROR: Memory allocation\n");
331         return;
332     }
333     BIO_printf(bio_out, "Provided RNGs and seed sources:\n");
334     EVP_RAND_do_all_provided(NULL, collect_rands, rands);
335     sk_EVP_RAND_sort(rands);
336     for (i = 0; i < sk_EVP_RAND_num(rands); i++) {
337         const EVP_RAND *m = sk_EVP_RAND_value(rands, i);
338
339         BIO_printf(bio_out, "  %s", EVP_RAND_name(m));
340         BIO_printf(bio_out, " @ %s\n",
341                    OSSL_PROVIDER_name(EVP_RAND_provider(m)));
342
343         if (verbose) {
344             print_param_types("retrievable algorithm parameters",
345                               EVP_RAND_gettable_params(m), 4);
346             print_param_types("retrievable operation parameters",
347                               EVP_RAND_gettable_ctx_params(m), 4);
348             print_param_types("settable operation parameters",
349                               EVP_RAND_settable_ctx_params(m), 4);
350         }
351     }
352     sk_EVP_RAND_pop_free(rands, EVP_RAND_free);
353 }
354
355 /*
356  * Encoders
357  */
358 DEFINE_STACK_OF(OSSL_ENCODER)
359 static int encoder_cmp(const OSSL_ENCODER * const *a,
360                        const OSSL_ENCODER * const *b)
361 {
362     int ret = OSSL_ENCODER_number(*a) - OSSL_ENCODER_number(*b);
363
364     if (ret == 0)
365         ret = strcmp(OSSL_PROVIDER_name(OSSL_ENCODER_provider(*a)),
366                      OSSL_PROVIDER_name(OSSL_ENCODER_provider(*b)));
367     return ret;
368 }
369
370 static void collect_encoders(OSSL_ENCODER *encoder, void *stack)
371 {
372     STACK_OF(OSSL_ENCODER) *encoder_stack = stack;
373
374     sk_OSSL_ENCODER_push(encoder_stack, encoder);
375     OSSL_ENCODER_up_ref(encoder);
376 }
377
378 static void list_encoders(void)
379 {
380     STACK_OF(OSSL_ENCODER) *encoders;
381     int i;
382
383     encoders = sk_OSSL_ENCODER_new(encoder_cmp);
384     if (encoders == NULL) {
385         BIO_printf(bio_err, "ERROR: Memory allocation\n");
386         return;
387     }
388     BIO_printf(bio_out, "Provided ENCODERs:\n");
389     OSSL_ENCODER_do_all_provided(NULL, collect_encoders, encoders);
390     sk_OSSL_ENCODER_sort(encoders);
391
392     for (i = 0; i < sk_OSSL_ENCODER_num(encoders); i++) {
393         OSSL_ENCODER *k = sk_OSSL_ENCODER_value(encoders, i);
394         STACK_OF(OPENSSL_CSTRING) *names =
395             sk_OPENSSL_CSTRING_new(name_cmp);
396
397         OSSL_ENCODER_names_do_all(k, collect_names, names);
398
399         BIO_printf(bio_out, "  ");
400         print_names(bio_out, names);
401         BIO_printf(bio_out, " @ %s (%s)\n",
402                    OSSL_PROVIDER_name(OSSL_ENCODER_provider(k)),
403                    OSSL_ENCODER_properties(k));
404
405         sk_OPENSSL_CSTRING_free(names);
406
407         if (verbose) {
408             print_param_types("settable operation parameters",
409                               OSSL_ENCODER_settable_ctx_params(k), 4);
410         }
411     }
412     sk_OSSL_ENCODER_pop_free(encoders, OSSL_ENCODER_free);
413 }
414
415 /*
416  * Decoders
417  */
418 DEFINE_STACK_OF(OSSL_DECODER)
419 static int decoder_cmp(const OSSL_DECODER * const *a,
420                        const OSSL_DECODER * const *b)
421 {
422     int ret = OSSL_DECODER_number(*a) - OSSL_DECODER_number(*b);
423
424     if (ret == 0)
425         ret = strcmp(OSSL_PROVIDER_name(OSSL_DECODER_provider(*a)),
426                      OSSL_PROVIDER_name(OSSL_DECODER_provider(*b)));
427     return ret;
428 }
429
430 static void collect_decoders(OSSL_DECODER *decoder, void *stack)
431 {
432     STACK_OF(OSSL_DECODER) *decoder_stack = stack;
433
434     sk_OSSL_DECODER_push(decoder_stack, decoder);
435     OSSL_DECODER_up_ref(decoder);
436 }
437
438 static void list_decoders(void)
439 {
440     STACK_OF(OSSL_DECODER) *decoders;
441     int i;
442
443     decoders = sk_OSSL_DECODER_new(decoder_cmp);
444     if (decoders == NULL) {
445         BIO_printf(bio_err, "ERROR: Memory allocation\n");
446         return;
447     }
448     BIO_printf(bio_out, "Provided DECODERs:\n");
449     OSSL_DECODER_do_all_provided(NULL, collect_decoders,
450                                  decoders);
451     sk_OSSL_DECODER_sort(decoders);
452
453     for (i = 0; i < sk_OSSL_DECODER_num(decoders); i++) {
454         OSSL_DECODER *k = sk_OSSL_DECODER_value(decoders, i);
455         STACK_OF(OPENSSL_CSTRING) *names =
456             sk_OPENSSL_CSTRING_new(name_cmp);
457
458         OSSL_DECODER_names_do_all(k, collect_names, names);
459
460         BIO_printf(bio_out, "  ");
461         print_names(bio_out, names);
462         BIO_printf(bio_out, " @ %s (%s)\n",
463                    OSSL_PROVIDER_name(OSSL_DECODER_provider(k)),
464                    OSSL_DECODER_properties(k));
465
466         sk_OPENSSL_CSTRING_free(names);
467
468         if (verbose) {
469             print_param_types("settable operation parameters",
470                               OSSL_DECODER_settable_ctx_params(k), 4);
471         }
472     }
473     sk_OSSL_DECODER_pop_free(decoders, OSSL_DECODER_free);
474 }
475
476 static void list_missing_help(void)
477 {
478     const FUNCTION *fp;
479     const OPTIONS *o;
480
481     for (fp = functions; fp->name != NULL; fp++) {
482         if ((o = fp->help) != NULL) {
483             /* If there is help, list what flags are not documented. */
484             for ( ; o->name != NULL; o++) {
485                 if (o->helpstr == NULL)
486                     BIO_printf(bio_out, "%s %s\n", fp->name, o->name);
487             }
488         } else if (fp->func != dgst_main) {
489             /* If not aliased to the dgst command, */
490             BIO_printf(bio_out, "%s *\n", fp->name);
491         }
492     }
493 }
494
495 static void list_objects(void)
496 {
497     int max_nid = OBJ_new_nid(0);
498     int i;
499     char *oid_buf = NULL;
500     int oid_size = 0;
501
502     /* Skip 0, since that's NID_undef */
503     for (i = 1; i < max_nid; i++) {
504         const ASN1_OBJECT *obj = OBJ_nid2obj(i);
505         const char *sn = OBJ_nid2sn(i);
506         const char *ln = OBJ_nid2ln(i);
507         int n = 0;
508
509         /*
510          * If one of the retrieved objects somehow generated an error,
511          * we ignore it.  The check for NID_undef below will detect the
512          * error and simply skip to the next NID.
513          */
514         ERR_clear_error();
515
516         if (OBJ_obj2nid(obj) == NID_undef)
517             continue;
518
519         if ((n = OBJ_obj2txt(NULL, 0, obj, 1)) == 0) {
520             BIO_printf(bio_out, "# None-OID object: %s, %s\n", sn, ln);
521             continue;
522         }
523         if (n < 0)
524             break;               /* Error */
525
526         if (n > oid_size) {
527             oid_buf = OPENSSL_realloc(oid_buf, n + 1);
528             if (oid_buf == NULL) {
529                 BIO_printf(bio_err, "ERROR: Memory allocation\n");
530                 break;           /* Error */
531             }
532             oid_size = n + 1;
533         }
534         if (OBJ_obj2txt(oid_buf, oid_size, obj, 1) < 0)
535             break;               /* Error */
536         if (ln == NULL || strcmp(sn, ln) == 0)
537             BIO_printf(bio_out, "%s = %s\n", sn, oid_buf);
538         else
539             BIO_printf(bio_out, "%s = %s, %s\n", sn, ln, oid_buf);
540     }
541
542     OPENSSL_free(oid_buf);
543 }
544
545 static void list_options_for_command(const char *command)
546 {
547     const FUNCTION *fp;
548     const OPTIONS *o;
549
550     for (fp = functions; fp->name != NULL; fp++)
551         if (strcmp(fp->name, command) == 0)
552             break;
553     if (fp->name == NULL) {
554         BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n",
555                    command);
556         return;
557     }
558
559     if ((o = fp->help) == NULL)
560         return;
561
562     for ( ; o->name != NULL; o++) {
563         char c = o->valtype;
564
565         if (o->name == OPT_PARAM_STR)
566             break;
567
568         if (o->name == OPT_HELP_STR
569                 || o->name == OPT_MORE_STR
570                 || o->name == OPT_SECTION_STR
571                 || o->name[0] == '\0')
572             continue;
573         BIO_printf(bio_out, "%s %c\n", o->name, c == '\0' ? '-' : c);
574     }
575     /* Always output the -- marker since it is sometimes documented. */
576     BIO_printf(bio_out, "- -\n");
577 }
578
579 static void list_type(FUNC_TYPE ft, int one)
580 {
581     FUNCTION *fp;
582     int i = 0;
583     DISPLAY_COLUMNS dc;
584
585     memset(&dc, 0, sizeof(dc));
586     if (!one)
587         calculate_columns(functions, &dc);
588
589     for (fp = functions; fp->name != NULL; fp++) {
590         if (fp->type != ft)
591             continue;
592         if (one) {
593             BIO_printf(bio_out, "%s\n", fp->name);
594         } else {
595             if (i % dc.columns == 0 && i > 0)
596                 BIO_printf(bio_out, "\n");
597             BIO_printf(bio_out, "%-*s", dc.width, fp->name);
598             i++;
599         }
600     }
601     if (!one)
602         BIO_printf(bio_out, "\n\n");
603 }
604
605 static void list_pkey(void)
606 {
607     int i;
608
609     for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
610         const EVP_PKEY_ASN1_METHOD *ameth;
611         int pkey_id, pkey_base_id, pkey_flags;
612         const char *pinfo, *pem_str;
613         ameth = EVP_PKEY_asn1_get0(i);
614         EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags,
615                                 &pinfo, &pem_str, ameth);
616         if (pkey_flags & ASN1_PKEY_ALIAS) {
617             BIO_printf(bio_out, "Name: %s\n", OBJ_nid2ln(pkey_id));
618             BIO_printf(bio_out, "\tAlias for: %s\n",
619                        OBJ_nid2ln(pkey_base_id));
620         } else {
621             BIO_printf(bio_out, "Name: %s\n", pinfo);
622             BIO_printf(bio_out, "\tType: %s Algorithm\n",
623                        pkey_flags & ASN1_PKEY_DYNAMIC ?
624                        "External" : "Builtin");
625             BIO_printf(bio_out, "\tOID: %s\n", OBJ_nid2ln(pkey_id));
626             if (pem_str == NULL)
627                 pem_str = "(none)";
628             BIO_printf(bio_out, "\tPEM string: %s\n", pem_str);
629         }
630
631     }
632 }
633
634 #ifndef OPENSSL_NO_DEPRECATED_3_0
635 static void list_pkey_meth(void)
636 {
637     size_t i;
638     size_t meth_count = EVP_PKEY_meth_get_count();
639
640     for (i = 0; i < meth_count; i++) {
641         const EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_get0(i);
642         int pkey_id, pkey_flags;
643
644         EVP_PKEY_meth_get0_info(&pkey_id, &pkey_flags, pmeth);
645         BIO_printf(bio_out, "%s\n", OBJ_nid2ln(pkey_id));
646         BIO_printf(bio_out, "\tType: %s Algorithm\n",
647                    pkey_flags & ASN1_PKEY_DYNAMIC ?  "External" : "Builtin");
648     }
649 }
650 #endif
651
652 #ifndef OPENSSL_NO_DEPRECATED_3_0
653 static void list_engines(void)
654 {
655 # ifndef OPENSSL_NO_ENGINE
656     ENGINE *e;
657
658     BIO_puts(bio_out, "Engines:\n");
659     e = ENGINE_get_first();
660     while (e) {
661         BIO_printf(bio_out, "%s\n", ENGINE_get_id(e));
662         e = ENGINE_get_next(e);
663     }
664 # else
665     BIO_puts(bio_out, "Engine support is disabled.\n");
666 # endif
667 }
668 #endif
669
670 static void list_disabled(void)
671 {
672     BIO_puts(bio_out, "Disabled algorithms:\n");
673 #ifdef OPENSSL_NO_ARIA
674     BIO_puts(bio_out, "ARIA\n");
675 #endif
676 #ifdef OPENSSL_NO_BF
677     BIO_puts(bio_out, "BF\n");
678 #endif
679 #ifdef OPENSSL_NO_BLAKE2
680     BIO_puts(bio_out, "BLAKE2\n");
681 #endif
682 #ifdef OPENSSL_NO_CAMELLIA
683     BIO_puts(bio_out, "CAMELLIA\n");
684 #endif
685 #ifdef OPENSSL_NO_CAST
686     BIO_puts(bio_out, "CAST\n");
687 #endif
688 #ifdef OPENSSL_NO_CMAC
689     BIO_puts(bio_out, "CMAC\n");
690 #endif
691 #ifdef OPENSSL_NO_CMS
692     BIO_puts(bio_out, "CMS\n");
693 #endif
694 #ifdef OPENSSL_NO_COMP
695     BIO_puts(bio_out, "COMP\n");
696 #endif
697 #ifdef OPENSSL_NO_DES
698     BIO_puts(bio_out, "DES\n");
699 #endif
700 #ifdef OPENSSL_NO_DGRAM
701     BIO_puts(bio_out, "DGRAM\n");
702 #endif
703 #ifdef OPENSSL_NO_DH
704     BIO_puts(bio_out, "DH\n");
705 #endif
706 #ifdef OPENSSL_NO_DSA
707     BIO_puts(bio_out, "DSA\n");
708 #endif
709 #if defined(OPENSSL_NO_DTLS)
710     BIO_puts(bio_out, "DTLS\n");
711 #endif
712 #if defined(OPENSSL_NO_DTLS1)
713     BIO_puts(bio_out, "DTLS1\n");
714 #endif
715 #if defined(OPENSSL_NO_DTLS1_2)
716     BIO_puts(bio_out, "DTLS1_2\n");
717 #endif
718 #ifdef OPENSSL_NO_EC
719     BIO_puts(bio_out, "EC\n");
720 #endif
721 #ifdef OPENSSL_NO_EC2M
722     BIO_puts(bio_out, "EC2M\n");
723 #endif
724 #if defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0)
725     BIO_puts(bio_out, "ENGINE\n");
726 #endif
727 #ifdef OPENSSL_NO_GOST
728     BIO_puts(bio_out, "GOST\n");
729 #endif
730 #ifdef OPENSSL_NO_IDEA
731     BIO_puts(bio_out, "IDEA\n");
732 #endif
733 #ifdef OPENSSL_NO_MD2
734     BIO_puts(bio_out, "MD2\n");
735 #endif
736 #ifdef OPENSSL_NO_MD4
737     BIO_puts(bio_out, "MD4\n");
738 #endif
739 #ifdef OPENSSL_NO_MD5
740     BIO_puts(bio_out, "MD5\n");
741 #endif
742 #ifdef OPENSSL_NO_MDC2
743     BIO_puts(bio_out, "MDC2\n");
744 #endif
745 #ifdef OPENSSL_NO_OCB
746     BIO_puts(bio_out, "OCB\n");
747 #endif
748 #ifdef OPENSSL_NO_OCSP
749     BIO_puts(bio_out, "OCSP\n");
750 #endif
751 #ifdef OPENSSL_NO_PSK
752     BIO_puts(bio_out, "PSK\n");
753 #endif
754 #ifdef OPENSSL_NO_RC2
755     BIO_puts(bio_out, "RC2\n");
756 #endif
757 #ifdef OPENSSL_NO_RC4
758     BIO_puts(bio_out, "RC4\n");
759 #endif
760 #ifdef OPENSSL_NO_RC5
761     BIO_puts(bio_out, "RC5\n");
762 #endif
763 #ifdef OPENSSL_NO_RMD160
764     BIO_puts(bio_out, "RMD160\n");
765 #endif
766 #ifdef OPENSSL_NO_RSA
767     BIO_puts(bio_out, "RSA\n");
768 #endif
769 #ifdef OPENSSL_NO_SCRYPT
770     BIO_puts(bio_out, "SCRYPT\n");
771 #endif
772 #ifdef OPENSSL_NO_SCTP
773     BIO_puts(bio_out, "SCTP\n");
774 #endif
775 #ifdef OPENSSL_NO_SEED
776     BIO_puts(bio_out, "SEED\n");
777 #endif
778 #ifdef OPENSSL_NO_SM2
779     BIO_puts(bio_out, "SM2\n");
780 #endif
781 #ifdef OPENSSL_NO_SM3
782     BIO_puts(bio_out, "SM3\n");
783 #endif
784 #ifdef OPENSSL_NO_SM4
785     BIO_puts(bio_out, "SM4\n");
786 #endif
787 #ifdef OPENSSL_NO_SOCK
788     BIO_puts(bio_out, "SOCK\n");
789 #endif
790 #ifdef OPENSSL_NO_SRP
791     BIO_puts(bio_out, "SRP\n");
792 #endif
793 #ifdef OPENSSL_NO_SRTP
794     BIO_puts(bio_out, "SRTP\n");
795 #endif
796 #ifdef OPENSSL_NO_SSL3
797     BIO_puts(bio_out, "SSL3\n");
798 #endif
799 #ifdef OPENSSL_NO_TLS1
800     BIO_puts(bio_out, "TLS1\n");
801 #endif
802 #ifdef OPENSSL_NO_TLS1_1
803     BIO_puts(bio_out, "TLS1_1\n");
804 #endif
805 #ifdef OPENSSL_NO_TLS1_2
806     BIO_puts(bio_out, "TLS1_2\n");
807 #endif
808 #ifdef OPENSSL_NO_WHIRLPOOL
809     BIO_puts(bio_out, "WHIRLPOOL\n");
810 #endif
811 #ifndef ZLIB
812     BIO_puts(bio_out, "ZLIB\n");
813 #endif
814 }
815
816 /* Unified enum for help and list commands. */
817 typedef enum HELPLIST_CHOICE {
818     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ONE, OPT_VERBOSE,
819     OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS,
820     OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
821     OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED,
822     OPT_KDF_ALGORITHMS, OPT_RANDOM_GENERATORS, OPT_ENCODERS,
823     OPT_DECODERS,
824     OPT_MISSING_HELP, OPT_OBJECTS,
825 #ifndef OPENSSL_NO_DEPRECATED_3_0
826     OPT_ENGINES, 
827 #endif
828     OPT_PROV_ENUM
829 } HELPLIST_CHOICE;
830
831 const OPTIONS list_options[] = {
832
833     OPT_SECTION("General"),
834     {"help", OPT_HELP, '-', "Display this summary"},
835
836     OPT_SECTION("Output"),
837     {"1", OPT_ONE, '-', "List in one column"},
838     {"verbose", OPT_VERBOSE, '-', "Verbose listing"},
839     {"commands", OPT_COMMANDS, '-', "List of standard commands"},
840     {"standard-commands", OPT_COMMANDS, '-', "List of standard commands"},
841     {"digest-commands", OPT_DIGEST_COMMANDS, '-',
842      "List of message digest commands"},
843     {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-',
844      "List of message digest algorithms"},
845     {"kdf-algorithms", OPT_KDF_ALGORITHMS, '-',
846      "List of key derivation and pseudo random function algorithms"},
847     {"random-generators", OPT_RANDOM_GENERATORS, '-',
848      "List of random number generators"},
849     {"mac-algorithms", OPT_MAC_ALGORITHMS, '-',
850      "List of message authentication code algorithms"},
851     {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"},
852     {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-',
853      "List of cipher algorithms"},
854     {"encoders", OPT_ENCODERS, '-', "List of encoding methods" },
855     {"decoders", OPT_DECODERS, '-', "List of decoding methods" },
856     {"public-key-algorithms", OPT_PK_ALGORITHMS, '-',
857      "List of public key algorithms"},
858 #ifndef OPENSSL_NO_DEPRECATED_3_0
859     {"public-key-methods", OPT_PK_METHOD, '-',
860      "List of public key methods"},
861     {"engines", OPT_ENGINES, '-',
862      "List of loaded engines"},
863 #endif
864     {"disabled", OPT_DISABLED, '-', "List of disabled features"},
865     {"missing-help", OPT_MISSING_HELP, '-',
866      "List missing detailed help strings"},
867     {"options", OPT_OPTIONS, 's',
868      "List options for specified command"},
869     {"objects", OPT_OBJECTS, '-',
870      "List built in objects (OID<->name mappings)"},
871
872     OPT_PROV_OPTIONS,
873     {NULL}
874 };
875
876 int list_main(int argc, char **argv)
877 {
878     char *prog;
879     HELPLIST_CHOICE o;
880     int one = 0, done = 0;
881     struct {
882         unsigned int commands:1;
883         unsigned int random_generators:1;
884         unsigned int digest_commands:1;
885         unsigned int digest_algorithms:1;
886         unsigned int kdf_algorithms:1;
887         unsigned int mac_algorithms:1;
888         unsigned int cipher_commands:1;
889         unsigned int cipher_algorithms:1;
890         unsigned int encoder_algorithms:1;
891         unsigned int decoder_algorithms:1;
892         unsigned int pk_algorithms:1;
893         unsigned int pk_method:1;
894 #ifndef OPENSSL_NO_DEPRECATED_3_0
895         unsigned int engines:1;
896 #endif
897         unsigned int disabled:1;
898         unsigned int missing_help:1;
899         unsigned int objects:1;
900         unsigned int options:1;
901     } todo = { 0, };
902
903     verbose = 0;                 /* Clear a possible previous call */
904
905     prog = opt_init(argc, argv, list_options);
906     while ((o = opt_next()) != OPT_EOF) {
907         switch (o) {
908         case OPT_EOF:  /* Never hit, but suppresses warning */
909         case OPT_ERR:
910 opthelp:
911             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
912             return 1;
913         case OPT_HELP:
914             opt_help(list_options);
915             break;
916         case OPT_ONE:
917             one = 1;
918             break;
919         case OPT_COMMANDS:
920             todo.commands = 1;
921             break;
922         case OPT_DIGEST_COMMANDS:
923             todo.digest_commands = 1;
924             break;
925         case OPT_DIGEST_ALGORITHMS:
926             todo.digest_algorithms = 1;
927             break;
928         case OPT_KDF_ALGORITHMS:
929             todo.kdf_algorithms = 1;
930             break;
931         case OPT_RANDOM_GENERATORS:
932             todo.random_generators = 1;
933             break;
934         case OPT_MAC_ALGORITHMS:
935             todo.mac_algorithms = 1;
936             break;
937         case OPT_CIPHER_COMMANDS:
938             todo.cipher_commands = 1;
939             break;
940         case OPT_CIPHER_ALGORITHMS:
941             todo.cipher_algorithms = 1;
942             break;
943         case OPT_ENCODERS:
944             todo.encoder_algorithms = 1;
945             break;
946         case OPT_DECODERS:
947             todo.decoder_algorithms = 1;
948             break;
949         case OPT_PK_ALGORITHMS:
950             todo.pk_algorithms = 1;
951             break;
952         case OPT_PK_METHOD:
953             todo.pk_method = 1;
954             break;
955 #ifndef OPENSSL_NO_DEPRECATED_3_0
956         case OPT_ENGINES:
957             todo.engines = 1;
958             break;
959 #endif
960         case OPT_DISABLED:
961             todo.disabled = 1;
962             break;
963         case OPT_MISSING_HELP:
964             todo.missing_help = 1;
965             break;
966         case OPT_OBJECTS:
967             todo.objects = 1;
968             break;
969         case OPT_OPTIONS:
970             list_options_for_command(opt_arg());
971             break;
972         case OPT_VERBOSE:
973             verbose = 1;
974             break;
975         case OPT_PROV_CASES:
976             if (!opt_provider(o))
977                 return 1;
978             break;
979         }
980         done = 1;
981     }
982     if (opt_num_rest() != 0) {
983         BIO_printf(bio_err, "Extra arguments given.\n");
984         goto opthelp;
985     }
986
987     if (todo.commands)
988         list_type(FT_general, one);
989     if (todo.random_generators)
990         list_random_generators();
991     if (todo.digest_commands)
992         list_type(FT_md, one);
993     if (todo.digest_algorithms)
994         list_digests();
995     if (todo.kdf_algorithms)
996         list_kdfs();
997     if (todo.mac_algorithms)
998         list_macs();
999     if (todo.cipher_commands)
1000         list_type(FT_cipher, one);
1001     if (todo.cipher_algorithms)
1002         list_ciphers();
1003     if (todo.encoder_algorithms)
1004         list_encoders();
1005     if (todo.decoder_algorithms)
1006         list_decoders();
1007     if (todo.pk_algorithms)
1008         list_pkey();
1009 #ifndef OPENSSL_NO_DEPRECATED_3_0
1010     if (todo.pk_method)
1011         list_pkey_meth();
1012     if (todo.engines)
1013         list_engines();
1014 #endif
1015     if (todo.disabled)
1016         list_disabled();
1017     if (todo.missing_help)
1018         list_missing_help();
1019     if (todo.objects)
1020         list_objects();
1021
1022     if (!done)
1023         goto opthelp;
1024
1025     return 0;
1026 }