Rename <openssl/core_numbers.h> -> <openssl/core_dispatch.h>
[oweals/openssl.git] / apps / provider.c
1 /*
2  * Copyright 2019-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 #include <openssl/opensslconf.h>
11
12 #include "apps.h"
13 #include "app_params.h"
14 #include "progs.h"
15 #include "names.h"
16 #include <openssl/err.h>
17 #include <openssl/evp.h>
18 #include <openssl/safestack.h>
19 #include <openssl/provider.h>
20 #include <openssl/core.h>
21 #include <openssl/core_dispatch.h>
22
23 DEFINE_STACK_OF_CSTRING()
24
25 typedef enum OPTION_choice {
26     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
27     OPT_V = 100, OPT_VV, OPT_VVV
28 } OPTION_CHOICE;
29
30 const OPTIONS provider_options[] = {
31     {OPT_HELP_STR, 1, '-', "Usage: %s [options] [provider...]\n"},
32
33     OPT_SECTION("General"),
34     {"help", OPT_HELP, '-', "Display this summary"},
35
36     OPT_SECTION("Output"),
37     {"v", OPT_V, '-', "List the algorithm names of specified provider"},
38     {"vv", OPT_VV, '-', "List the algorithm names of specified providers,"},
39     {OPT_MORE_STR, 0, '-', "categorised by operation type"},
40     {"vvv", OPT_VVV, '-', "List the algorithm names of specified provider"},
41     {OPT_MORE_STR, 0, '-', "one at a time, and list all known parameters"},
42
43     OPT_PARAMETERS(),
44     {"provider", 0, 0, "Provider(s) to load"},
45     {NULL}
46 };
47
48 typedef struct info_st INFO;
49 typedef struct meta_st META;
50
51 struct info_st {
52     void (*collect_names_fn)(void *method, STACK_OF(OPENSSL_CSTRING) *names);
53     void *method;
54     const OSSL_PARAM *gettable_params;
55     const OSSL_PARAM *gettable_ctx_params;
56     const OSSL_PARAM *settable_ctx_params;
57 };
58
59 struct meta_st {
60     int first;                   /* For prints */
61     int total;
62     int indent;
63     int subindent;
64     int verbose;
65     const char *label;
66     OSSL_PROVIDER *prov;
67     void (*fn)(META *meta, INFO *info);
68 };
69
70 static void collect_cipher_names(void *method,
71                                  STACK_OF(OPENSSL_CSTRING) *names)
72 {
73     EVP_CIPHER_names_do_all(method, collect_names, names);
74 }
75
76 static void collect_digest_names(void *method,
77                                  STACK_OF(OPENSSL_CSTRING) *names)
78 {
79     EVP_MD_names_do_all(method, collect_names, names);
80 }
81
82 static void collect_mac_names(void *method,
83                               STACK_OF(OPENSSL_CSTRING) *names)
84 {
85     EVP_MAC_names_do_all(method, collect_names, names);
86 }
87
88 static void collect_keymgmt_names(void *method,
89                                   STACK_OF(OPENSSL_CSTRING) *names)
90 {
91     EVP_KEYMGMT_names_do_all(method, collect_names, names);
92 }
93
94 static void collect_keyexch_names(void *method,
95                                   STACK_OF(OPENSSL_CSTRING) *names)
96 {
97     EVP_KEYEXCH_names_do_all(method, collect_names, names);
98 }
99
100 static void collect_signature_names(void *method,
101                                   STACK_OF(OPENSSL_CSTRING) *names)
102 {
103     EVP_SIGNATURE_names_do_all(method, collect_names, names);
104 }
105
106 static void print_method_names(BIO *out, INFO *info)
107 {
108     STACK_OF(OPENSSL_CSTRING) *names = sk_OPENSSL_CSTRING_new(name_cmp);
109
110     info->collect_names_fn(info->method, names);
111     print_names(out, names);
112     sk_OPENSSL_CSTRING_free(names);
113 }
114
115 static void print_caps(META *meta, INFO *info)
116 {
117     switch (meta->verbose) {
118     case 1:
119         if (!meta->first)
120             BIO_printf(bio_out, "; ");
121         print_method_names(bio_out, info);
122         break;
123     case 2:
124         if (meta->first) {
125             if (meta->total > 0)
126                 BIO_printf(bio_out, "\n");
127             BIO_printf(bio_out, "%*s%ss:", meta->indent, "", meta->label);
128         }
129         BIO_printf(bio_out, " ");
130         print_method_names(bio_out, info);
131         break;
132     case 3:
133     default:
134         BIO_printf(bio_out, "%*s%s ", meta->indent, "", meta->label);
135         print_method_names(bio_out, info);
136         BIO_printf(bio_out, "\n");
137         print_param_types("retrievable algorithm parameters",
138                           info->gettable_params, meta->subindent);
139         print_param_types("retrievable operation parameters",
140                           info->gettable_ctx_params, meta->subindent);
141         print_param_types("settable operation parameters",
142                           info->settable_ctx_params, meta->subindent);
143         break;
144     }
145     meta->first = 0;
146 }
147
148 static void do_method(void *method,
149                       void (*collect_names_fn)(void *method,
150                                                STACK_OF(OPENSSL_CSTRING) *names),
151                       const OSSL_PARAM *gettable_params,
152                       const OSSL_PARAM *gettable_ctx_params,
153                       const OSSL_PARAM *settable_ctx_params,
154                       META *meta)
155 {
156     INFO info;
157
158     info.collect_names_fn = collect_names_fn;
159     info.method = method;
160     info.gettable_params = gettable_params;
161     info.gettable_ctx_params = gettable_ctx_params;
162     info.settable_ctx_params = settable_ctx_params;
163     meta->fn(meta, &info);
164     meta->total++;
165 }
166
167 static void do_cipher(EVP_CIPHER *cipher, void *meta)
168 {
169     do_method(cipher, collect_cipher_names,
170               EVP_CIPHER_gettable_params(cipher),
171               EVP_CIPHER_gettable_ctx_params(cipher),
172               EVP_CIPHER_settable_ctx_params(cipher),
173               meta);
174 }
175
176 static void do_digest(EVP_MD *digest, void *meta)
177 {
178     do_method(digest, collect_digest_names,
179               EVP_MD_gettable_params(digest),
180               EVP_MD_gettable_ctx_params(digest),
181               EVP_MD_settable_ctx_params(digest),
182               meta);
183 }
184
185 static void do_mac(EVP_MAC *mac, void *meta)
186 {
187     do_method(mac, collect_mac_names,
188               EVP_MAC_gettable_params(mac),
189               EVP_MAC_gettable_ctx_params(mac),
190               EVP_MAC_settable_ctx_params(mac),
191               meta);
192 }
193
194 static void do_keymgmt(EVP_KEYMGMT *keymgmt, void *meta)
195 {
196     do_method(keymgmt, collect_keymgmt_names,
197 /*
198  * TODO(3.0) Enable when KEYMGMT and KEYEXCH have gettables and settables
199  */
200 #if 0
201               EVP_KEYMGMT_gettable_params(keymgmt),
202               EVP_KEYMGMT_gettable_ctx_params(keymgmt),
203               EVP_KEYMGMT_settable_ctx_params(keymgmt),
204 #else
205               NULL, NULL, NULL,
206 #endif
207               meta);
208 }
209
210 static void do_keyexch(EVP_KEYEXCH *keyexch, void *meta)
211 {
212     do_method(keyexch, collect_keyexch_names,
213 /*
214  * TODO(3.0) Enable when KEYMGMT and KEYEXCH have gettables and settables
215  */
216 #if 0
217               EVP_KEYEXCH_gettable_params(keyexch),
218               EVP_KEYEXCH_gettable_ctx_params(keyexch),
219               EVP_KEYEXCH_settable_ctx_params(keyexch),
220 #else
221               NULL, NULL, NULL,
222 #endif
223               meta);
224 }
225
226 static void do_signature(EVP_SIGNATURE *signature, void *meta)
227 {
228     do_method(signature, collect_signature_names,
229 /*
230  * TODO(3.0) Enable when KEYMGMT and SIGNATURE have gettables and settables
231  */
232 #if 0
233               EVP_SIGNATURE_gettable_params(signature),
234               EVP_SIGNATURE_gettable_ctx_params(signature),
235               EVP_SIGNATURE_settable_ctx_params(signature),
236 #else
237               NULL, NULL, NULL,
238 #endif
239               meta);
240 }
241
242 int provider_main(int argc, char **argv)
243 {
244     int ret = 1, i;
245     int verbose = 0;
246     STACK_OF(OPENSSL_CSTRING) *providers = sk_OPENSSL_CSTRING_new_null();
247     OPTION_CHOICE o;
248     char *prog;
249
250     prog = opt_init(argc, argv, provider_options);
251     while ((o = opt_next()) != OPT_EOF) {
252         switch (o) {
253         default: /* Catching OPT_ERR & covering OPT_EOF which isn't possible */
254             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
255             goto end;
256         case OPT_HELP:
257             opt_help(provider_options);
258             ret = 0;
259             goto end;
260         case OPT_VVV:
261         case OPT_VV:
262         case OPT_V:
263             /* Convert to an integer from one to four. */
264             i = (int)(o - OPT_V) + 1;
265             if (verbose < i)
266                 verbose = i;
267             break;
268         }
269     }
270
271     /* Allow any trailing parameters as provider names. */
272     argc = opt_num_rest();
273     argv = opt_rest();
274     for ( ; *argv; argv++) {
275         /* This isn't necessary since -- is supported. */
276         if (**argv == '-') {
277             BIO_printf(bio_err, "%s: Cannot mix flags and provider names.\n",
278                        prog);
279             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
280             goto end;
281         }
282         sk_OPENSSL_CSTRING_push(providers, *argv);
283     }
284
285     ret = 0;
286     for (i = 0; i < sk_OPENSSL_CSTRING_num(providers); i++) {
287         const char *name = sk_OPENSSL_CSTRING_value(providers, i);
288         OSSL_PROVIDER *prov = OSSL_PROVIDER_load(NULL, name);
289
290         if (prov != NULL) {
291             BIO_printf(bio_out, verbose == 0 ? "%s\n" :  "[ %s ]\n", name);
292
293             if (verbose > 0) {
294                 META data;
295
296                 data.total = 0;
297                 data.first = 1;
298                 data.verbose = verbose;
299                 data.prov = prov;
300                 data.fn = print_caps;
301
302                 switch (verbose) {
303                 case 1:
304                     BIO_printf(bio_out, "    ");
305                     break;
306                 case 2:
307                     data.indent = 4;
308                     break;
309                 case 3:
310                 default:
311                     data.indent = 4;
312                     data.subindent = 10;
313                     break;
314                 }
315
316                 if (verbose > 1) {
317                     data.first = 1;
318                     data.label = "Cipher";
319                 }
320                 EVP_CIPHER_do_all_provided(NULL, do_cipher, &data);
321                 if (verbose > 1) {
322                     data.first = 1;
323                     data.label = "Digest";
324                 }
325                 EVP_MD_do_all_provided(NULL, do_digest, &data);
326                 if (verbose > 1) {
327                     data.first = 1;
328                     data.label = "MAC";
329                 }
330                 EVP_MAC_do_all_provided(NULL, do_mac, &data);
331
332                 if (verbose > 1) {
333                     data.first = 1;
334                     data.label = "Key manager";
335                 }
336                 EVP_KEYMGMT_do_all_provided(NULL, do_keymgmt, &data);
337                 if (verbose > 1) {
338                     data.first = 1;
339                     data.label = "Key exchange";
340                 }
341                 EVP_KEYEXCH_do_all_provided(NULL, do_keyexch, &data);
342                 if (verbose > 1) {
343                     data.first = 1;
344                     data.label = "Signature";
345                 }
346                 EVP_SIGNATURE_do_all_provided(NULL, do_signature, &data);
347
348                 switch (verbose) {
349                 default:
350                     break;
351                 case 2:
352                 case 1:
353                     BIO_printf(bio_out, "\n");
354                     break;
355                 }
356             }
357             OSSL_PROVIDER_unload(prov);
358         } else {
359             ERR_print_errors(bio_err);
360             ret = 1;
361             /*
362              * Just because one provider module failed, there's no reason to
363              * stop, if there are more to try.
364              */
365         }
366     }
367
368  end:
369
370     ERR_print_errors(bio_err);
371     sk_OPENSSL_CSTRING_free(providers);
372     return ret;
373 }