Don't complain if function name doesn't match
[openssl.git] / apps / list.c
1 /*
2  * Copyright 1995-2019 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 #include <string.h>
11 #include <openssl/evp.h>
12 #include <openssl/err.h>
13 #include <openssl/provider.h>
14 #include <openssl/safestack.h>
15 #include "apps.h"
16 #include "progs.h"
17 #include "opt.h"
18
19 static void list_cipher_fn(const EVP_CIPHER *c,
20                            const char *from, const char *to, void *arg)
21 {
22     if (c != NULL) {
23         BIO_printf(arg, "  %s\n", EVP_CIPHER_name(c));
24     } else {
25         if (from == NULL)
26             from = "<undefined>";
27         if (to == NULL)
28             to = "<undefined>";
29         BIO_printf(arg, "  %s => %s\n", from, to);
30     }
31 }
32
33 DEFINE_STACK_OF(EVP_CIPHER)
34 static int cipher_cmp(const EVP_CIPHER * const *a,
35                       const EVP_CIPHER * const *b)
36 {
37     int ret = strcasecmp(EVP_CIPHER_name(*a), EVP_CIPHER_name(*b));
38
39     if (ret == 0)
40         ret = strcmp(OSSL_PROVIDER_name(EVP_CIPHER_provider(*a)),
41                      OSSL_PROVIDER_name(EVP_CIPHER_provider(*b)));
42
43     return ret;
44 }
45
46 static void collect_ciphers(EVP_CIPHER *cipher, void *stack)
47 {
48     STACK_OF(EVP_CIPHER) *cipher_stack = stack;
49
50     sk_EVP_CIPHER_push(cipher_stack, cipher);
51     EVP_CIPHER_up_ref(cipher);
52 }
53
54 static void list_ciphers(void)
55 {
56     STACK_OF(EVP_CIPHER) *ciphers = sk_EVP_CIPHER_new(cipher_cmp);
57     int i;
58
59     BIO_printf(bio_out, "Legacy:\n");
60     EVP_CIPHER_do_all_sorted(list_cipher_fn, bio_out);
61
62     BIO_printf(bio_out, "Provided:\n");
63     EVP_CIPHER_do_all_ex(NULL, collect_ciphers, ciphers);
64     sk_EVP_CIPHER_sort(ciphers);
65     for (i = 0; i < sk_EVP_CIPHER_num(ciphers); i++) {
66         const EVP_CIPHER *c = sk_EVP_CIPHER_value(ciphers, i);
67
68         BIO_printf(bio_out, "  %s", EVP_CIPHER_name(c));
69         BIO_printf(bio_out, " @ %s\n",
70                    OSSL_PROVIDER_name(EVP_CIPHER_provider(c)));
71     }
72     sk_EVP_CIPHER_pop_free(ciphers, EVP_CIPHER_meth_free);
73 }
74
75 static void list_md_fn(const EVP_MD *m,
76                        const char *from, const char *to, void *arg)
77 {
78     if (m != NULL) {
79         BIO_printf(arg, "  %s\n", EVP_MD_name(m));
80     } else {
81         if (from == NULL)
82             from = "<undefined>";
83         if (to == NULL)
84             to = "<undefined>";
85         BIO_printf((BIO *)arg, "  %s => %s\n", from, to);
86     }
87 }
88
89 DEFINE_STACK_OF(EVP_MD)
90 static int md_cmp(const EVP_MD * const *a, const EVP_MD * const *b)
91 {
92     int ret = strcasecmp(EVP_MD_name(*a), EVP_MD_name(*b));
93
94     if (ret == 0)
95         ret = strcmp(OSSL_PROVIDER_name(EVP_MD_provider(*a)),
96                      OSSL_PROVIDER_name(EVP_MD_provider(*b)));
97
98     return ret;
99 }
100
101 static void collect_digests(EVP_MD *md, void *stack)
102 {
103     STACK_OF(EVP_MD) *digest_stack = stack;
104
105     sk_EVP_MD_push(digest_stack, md);
106     EVP_MD_up_ref(md);
107 }
108
109 static void list_digests(void)
110 {
111     STACK_OF(EVP_MD) *digests = sk_EVP_MD_new(md_cmp);
112     int i;
113
114     BIO_printf(bio_out, "Legacy:\n");
115     EVP_MD_do_all_sorted(list_md_fn, bio_out);
116
117     BIO_printf(bio_out, "Provided:\n");
118     EVP_MD_do_all_ex(NULL, collect_digests, digests);
119     sk_EVP_MD_sort(digests);
120     for (i = 0; i < sk_EVP_MD_num(digests); i++) {
121         const EVP_MD *c = sk_EVP_MD_value(digests, i);
122
123         BIO_printf(bio_out, "  %s", EVP_MD_name(c));
124         BIO_printf(bio_out, " @ %s\n",
125                    OSSL_PROVIDER_name(EVP_MD_provider(c)));
126     }
127     sk_EVP_MD_pop_free(digests, EVP_MD_meth_free);
128 }
129
130 static void list_mac_fn(const EVP_MAC *m,
131                         const char *from, const char *to, void *arg)
132 {
133     if (m != NULL) {
134         BIO_printf(arg, "%s\n", EVP_MAC_name(m));
135     } else {
136         if (from == NULL)
137             from = "<undefined>";
138         if (to == NULL)
139             to = "<undefined>";
140         BIO_printf(arg, "%s => %s\n", from, to);
141     }
142 }
143
144 static void list_missing_help(void)
145 {
146     const FUNCTION *fp;
147     const OPTIONS *o;
148
149     for (fp = functions; fp->name != NULL; fp++) {
150         if ((o = fp->help) != NULL) {
151             /* If there is help, list what flags are not documented. */
152             for ( ; o->name != NULL; o++) {
153                 if (o->helpstr == NULL)
154                     BIO_printf(bio_out, "%s %s\n", fp->name, o->name);
155             }
156         } else if (fp->func != dgst_main) {
157             /* If not aliased to the dgst command, */
158             BIO_printf(bio_out, "%s *\n", fp->name);
159         }
160     }
161 }
162
163 static void list_objects(void)
164 {
165     int max_nid = OBJ_new_nid(0);
166     int i;
167     char *oid_buf = NULL;
168     int oid_size = 0;
169
170     /* Skip 0, since that's NID_undef */
171     for (i = 1; i < max_nid; i++) {
172         const ASN1_OBJECT *obj = OBJ_nid2obj(i);
173         const char *sn = OBJ_nid2sn(i);
174         const char *ln = OBJ_nid2ln(i);
175         int n = 0;
176
177         /*
178          * If one of the retrieved objects somehow generated an error,
179          * we ignore it.  The check for NID_undef below will detect the
180          * error and simply skip to the next NID.
181          */
182         ERR_clear_error();
183
184         if (OBJ_obj2nid(obj) == NID_undef)
185             continue;
186
187         if ((n = OBJ_obj2txt(NULL, 0, obj, 1)) == 0) {
188             BIO_printf(bio_out, "# None-OID object: %s, %s\n", sn, ln);
189             continue;
190         }
191         if (n < 0)
192             break;               /* Error */
193
194         if (n > oid_size) {
195             oid_buf = OPENSSL_realloc(oid_buf, n + 1);
196             if (oid_buf == NULL) {
197                 BIO_printf(bio_err, "ERROR: Memory allocation\n");
198                 break;           /* Error */
199             }
200             oid_size = n + 1;
201         }
202         if (OBJ_obj2txt(oid_buf, oid_size, obj, 1) < 0)
203             break;               /* Error */
204         if (ln == NULL || strcmp(sn, ln) == 0)
205             BIO_printf(bio_out, "%s = %s\n", sn, oid_buf);
206         else
207             BIO_printf(bio_out, "%s = %s, %s\n", sn, ln, oid_buf);
208     }
209
210     OPENSSL_free(oid_buf);
211 }
212
213 static void list_options_for_command(const char *command)
214 {
215     const FUNCTION *fp;
216     const OPTIONS *o;
217
218     for (fp = functions; fp->name != NULL; fp++)
219         if (strcmp(fp->name, command) == 0)
220             break;
221     if (fp->name == NULL) {
222         BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n",
223                 command);
224         return;
225     }
226
227     if ((o = fp->help) == NULL)
228         return;
229
230     for ( ; o->name != NULL; o++) {
231         if (o->name == OPT_HELP_STR
232                 || o->name == OPT_MORE_STR
233                 || o->name[0] == '\0')
234             continue;
235         BIO_printf(bio_out, "%s %c\n", o->name, o->valtype);
236     }
237 }
238
239 static void list_type(FUNC_TYPE ft, int one)
240 {
241     FUNCTION *fp;
242     int i = 0;
243     DISPLAY_COLUMNS dc;
244
245     memset(&dc, 0, sizeof(dc));
246     if (!one)
247         calculate_columns(functions, &dc);
248
249     for (fp = functions; fp->name != NULL; fp++) {
250         if (fp->type != ft)
251             continue;
252         if (one) {
253             BIO_printf(bio_out, "%s\n", fp->name);
254         } else {
255             if (i % dc.columns == 0 && i > 0)
256                 BIO_printf(bio_out, "\n");
257             BIO_printf(bio_out, "%-*s", dc.width, fp->name);
258             i++;
259         }
260     }
261     if (!one)
262         BIO_printf(bio_out, "\n\n");
263 }
264
265 static void list_pkey(void)
266 {
267     int i;
268
269     for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
270         const EVP_PKEY_ASN1_METHOD *ameth;
271         int pkey_id, pkey_base_id, pkey_flags;
272         const char *pinfo, *pem_str;
273         ameth = EVP_PKEY_asn1_get0(i);
274         EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags,
275                                 &pinfo, &pem_str, ameth);
276         if (pkey_flags & ASN1_PKEY_ALIAS) {
277             BIO_printf(bio_out, "Name: %s\n", OBJ_nid2ln(pkey_id));
278             BIO_printf(bio_out, "\tAlias for: %s\n",
279                        OBJ_nid2ln(pkey_base_id));
280         } else {
281             BIO_printf(bio_out, "Name: %s\n", pinfo);
282             BIO_printf(bio_out, "\tType: %s Algorithm\n",
283                        pkey_flags & ASN1_PKEY_DYNAMIC ?
284                        "External" : "Builtin");
285             BIO_printf(bio_out, "\tOID: %s\n", OBJ_nid2ln(pkey_id));
286             if (pem_str == NULL)
287                 pem_str = "(none)";
288             BIO_printf(bio_out, "\tPEM string: %s\n", pem_str);
289         }
290
291     }
292 }
293
294 static void list_pkey_meth(void)
295 {
296     size_t i;
297     size_t meth_count = EVP_PKEY_meth_get_count();
298
299     for (i = 0; i < meth_count; i++) {
300         const EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_get0(i);
301         int pkey_id, pkey_flags;
302
303         EVP_PKEY_meth_get0_info(&pkey_id, &pkey_flags, pmeth);
304         BIO_printf(bio_out, "%s\n", OBJ_nid2ln(pkey_id));
305         BIO_printf(bio_out, "\tType: %s Algorithm\n",
306                    pkey_flags & ASN1_PKEY_DYNAMIC ?  "External" : "Builtin");
307     }
308 }
309
310 static void list_engines(void)
311 {
312 #ifndef OPENSSL_NO_ENGINE
313     ENGINE *e;
314
315     BIO_puts(bio_out, "Engines:\n");
316     e = ENGINE_get_first();
317     while (e) {
318         BIO_printf(bio_out, "%s\n", ENGINE_get_id(e));
319         e = ENGINE_get_next(e);
320     }
321 #else
322     BIO_puts(bio_out, "Engine support is disabled.\n");
323 #endif
324 }
325
326 static void list_disabled(void)
327 {
328     BIO_puts(bio_out, "Disabled algorithms:\n");
329 #ifdef OPENSSL_NO_ARIA
330     BIO_puts(bio_out, "ARIA\n");
331 #endif
332 #ifdef OPENSSL_NO_BF
333     BIO_puts(bio_out, "BF\n");
334 #endif
335 #ifdef OPENSSL_NO_BLAKE2
336     BIO_puts(bio_out, "BLAKE2\n");
337 #endif
338 #ifdef OPENSSL_NO_CAMELLIA
339     BIO_puts(bio_out, "CAMELLIA\n");
340 #endif
341 #ifdef OPENSSL_NO_CAST
342     BIO_puts(bio_out, "CAST\n");
343 #endif
344 #ifdef OPENSSL_NO_CMAC
345     BIO_puts(bio_out, "CMAC\n");
346 #endif
347 #ifdef OPENSSL_NO_CMS
348     BIO_puts(bio_out, "CMS\n");
349 #endif
350 #ifdef OPENSSL_NO_COMP
351     BIO_puts(bio_out, "COMP\n");
352 #endif
353 #ifdef OPENSSL_NO_DES
354     BIO_puts(bio_out, "DES\n");
355 #endif
356 #ifdef OPENSSL_NO_DGRAM
357     BIO_puts(bio_out, "DGRAM\n");
358 #endif
359 #ifdef OPENSSL_NO_DH
360     BIO_puts(bio_out, "DH\n");
361 #endif
362 #ifdef OPENSSL_NO_DSA
363     BIO_puts(bio_out, "DSA\n");
364 #endif
365 #if defined(OPENSSL_NO_DTLS)
366     BIO_puts(bio_out, "DTLS\n");
367 #endif
368 #if defined(OPENSSL_NO_DTLS1)
369     BIO_puts(bio_out, "DTLS1\n");
370 #endif
371 #if defined(OPENSSL_NO_DTLS1_2)
372     BIO_puts(bio_out, "DTLS1_2\n");
373 #endif
374 #ifdef OPENSSL_NO_EC
375     BIO_puts(bio_out, "EC\n");
376 #endif
377 #ifdef OPENSSL_NO_EC2M
378     BIO_puts(bio_out, "EC2M\n");
379 #endif
380 #ifdef OPENSSL_NO_ENGINE
381     BIO_puts(bio_out, "ENGINE\n");
382 #endif
383 #ifdef OPENSSL_NO_GOST
384     BIO_puts(bio_out, "GOST\n");
385 #endif
386 #ifdef OPENSSL_NO_IDEA
387     BIO_puts(bio_out, "IDEA\n");
388 #endif
389 #ifdef OPENSSL_NO_MD2
390     BIO_puts(bio_out, "MD2\n");
391 #endif
392 #ifdef OPENSSL_NO_MD4
393     BIO_puts(bio_out, "MD4\n");
394 #endif
395 #ifdef OPENSSL_NO_MD5
396     BIO_puts(bio_out, "MD5\n");
397 #endif
398 #ifdef OPENSSL_NO_MDC2
399     BIO_puts(bio_out, "MDC2\n");
400 #endif
401 #ifdef OPENSSL_NO_OCB
402     BIO_puts(bio_out, "OCB\n");
403 #endif
404 #ifdef OPENSSL_NO_OCSP
405     BIO_puts(bio_out, "OCSP\n");
406 #endif
407 #ifdef OPENSSL_NO_PSK
408     BIO_puts(bio_out, "PSK\n");
409 #endif
410 #ifdef OPENSSL_NO_RC2
411     BIO_puts(bio_out, "RC2\n");
412 #endif
413 #ifdef OPENSSL_NO_RC4
414     BIO_puts(bio_out, "RC4\n");
415 #endif
416 #ifdef OPENSSL_NO_RC5
417     BIO_puts(bio_out, "RC5\n");
418 #endif
419 #ifdef OPENSSL_NO_RMD160
420     BIO_puts(bio_out, "RMD160\n");
421 #endif
422 #ifdef OPENSSL_NO_RSA
423     BIO_puts(bio_out, "RSA\n");
424 #endif
425 #ifdef OPENSSL_NO_SCRYPT
426     BIO_puts(bio_out, "SCRYPT\n");
427 #endif
428 #ifdef OPENSSL_NO_SCTP
429     BIO_puts(bio_out, "SCTP\n");
430 #endif
431 #ifdef OPENSSL_NO_SEED
432     BIO_puts(bio_out, "SEED\n");
433 #endif
434 #ifdef OPENSSL_NO_SM2
435     BIO_puts(bio_out, "SM2\n");
436 #endif
437 #ifdef OPENSSL_NO_SM3
438     BIO_puts(bio_out, "SM3\n");
439 #endif
440 #ifdef OPENSSL_NO_SM4
441     BIO_puts(bio_out, "SM4\n");
442 #endif
443 #ifdef OPENSSL_NO_SOCK
444     BIO_puts(bio_out, "SOCK\n");
445 #endif
446 #ifdef OPENSSL_NO_SRP
447     BIO_puts(bio_out, "SRP\n");
448 #endif
449 #ifdef OPENSSL_NO_SRTP
450     BIO_puts(bio_out, "SRTP\n");
451 #endif
452 #ifdef OPENSSL_NO_SSL3
453     BIO_puts(bio_out, "SSL3\n");
454 #endif
455 #ifdef OPENSSL_NO_TLS1
456     BIO_puts(bio_out, "TLS1\n");
457 #endif
458 #ifdef OPENSSL_NO_TLS1_1
459     BIO_puts(bio_out, "TLS1_1\n");
460 #endif
461 #ifdef OPENSSL_NO_TLS1_2
462     BIO_puts(bio_out, "TLS1_2\n");
463 #endif
464 #ifdef OPENSSL_NO_WHIRLPOOL
465     BIO_puts(bio_out, "WHIRLPOOL\n");
466 #endif
467 #ifndef ZLIB
468     BIO_puts(bio_out, "ZLIB\n");
469 #endif
470 }
471
472 /* Unified enum for help and list commands. */
473 typedef enum HELPLIST_CHOICE {
474     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ONE,
475     OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS,
476     OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
477     OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_ENGINES, OPT_DISABLED,
478     OPT_MISSING_HELP, OPT_OBJECTS
479 } HELPLIST_CHOICE;
480
481 const OPTIONS list_options[] = {
482     {"help", OPT_HELP, '-', "Display this summary"},
483     {"1", OPT_ONE, '-', "List in one column"},
484     {"commands", OPT_COMMANDS, '-', "List of standard commands"},
485     {"digest-commands", OPT_DIGEST_COMMANDS, '-',
486      "List of message digest commands"},
487     {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-',
488      "List of message digest algorithms"},
489     {"mac-algorithms", OPT_MAC_ALGORITHMS, '-',
490      "List of message authentication code algorithms"},
491     {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"},
492     {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-',
493      "List of cipher algorithms"},
494     {"public-key-algorithms", OPT_PK_ALGORITHMS, '-',
495      "List of public key algorithms"},
496     {"public-key-methods", OPT_PK_METHOD, '-',
497      "List of public key methods"},
498     {"engines", OPT_ENGINES, '-',
499      "List of loaded engines"},
500     {"disabled", OPT_DISABLED, '-',
501      "List of disabled features"},
502     {"missing-help", OPT_MISSING_HELP, '-',
503      "List missing detailed help strings"},
504     {"options", OPT_OPTIONS, 's',
505      "List options for specified command"},
506     {"objects", OPT_OBJECTS, '-',
507      "List built in objects (OID<->name mappings)"},
508     {NULL}
509 };
510
511 int list_main(int argc, char **argv)
512 {
513     char *prog;
514     HELPLIST_CHOICE o;
515     int one = 0, done = 0;
516
517     prog = opt_init(argc, argv, list_options);
518     while ((o = opt_next()) != OPT_EOF) {
519         switch (o) {
520         case OPT_EOF:  /* Never hit, but suppresses warning */
521         case OPT_ERR:
522 opthelp:
523             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
524             return 1;
525         case OPT_HELP:
526             opt_help(list_options);
527             break;
528         case OPT_ONE:
529             one = 1;
530             break;
531         case OPT_COMMANDS:
532             list_type(FT_general, one);
533             break;
534         case OPT_DIGEST_COMMANDS:
535             list_type(FT_md, one);
536             break;
537         case OPT_DIGEST_ALGORITHMS:
538             list_digests();
539             break;
540         case OPT_MAC_ALGORITHMS:
541             EVP_MAC_do_all_sorted(list_mac_fn, bio_out);
542             break;
543         case OPT_CIPHER_COMMANDS:
544             list_type(FT_cipher, one);
545             break;
546         case OPT_CIPHER_ALGORITHMS:
547             list_ciphers();
548             break;
549         case OPT_PK_ALGORITHMS:
550             list_pkey();
551             break;
552         case OPT_PK_METHOD:
553             list_pkey_meth();
554             break;
555         case OPT_ENGINES:
556             list_engines();
557             break;
558         case OPT_DISABLED:
559             list_disabled();
560             break;
561         case OPT_MISSING_HELP:
562             list_missing_help();
563             break;
564         case OPT_OBJECTS:
565             list_objects();
566             break;
567         case OPT_OPTIONS:
568             list_options_for_command(opt_arg());
569             break;
570         }
571         done = 1;
572     }
573     if (opt_num_rest() != 0) {
574         BIO_printf(bio_err, "Extra arguments given.\n");
575         goto opthelp;
576     }
577
578     if (!done)
579         goto opthelp;
580
581     return 0;
582 }