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