Restore makedepend capabilities for Windows and VMS
[openssl.git] / apps / engine.c
1 /*
2  * Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 #ifdef OPENSSL_NO_ENGINE
12 NON_EMPTY_TRANSLATION_UNIT
13 #else
14
15 # include "apps.h"
16 # include <stdio.h>
17 # include <stdlib.h>
18 # include <string.h>
19 # include <openssl/err.h>
20 # include <openssl/engine.h>
21 # include <openssl/ssl.h>
22 # include <openssl/store.h>
23
24 typedef enum OPTION_choice {
25     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
26     OPT_C, OPT_T, OPT_TT, OPT_PRE, OPT_POST,
27     OPT_V = 100, OPT_VV, OPT_VVV, OPT_VVVV
28 } OPTION_CHOICE;
29
30 const OPTIONS engine_options[] = {
31     {OPT_HELP_STR, 1, '-', "Usage: %s [options] engine...\n"},
32     {OPT_HELP_STR, 1, '-',
33         "  engine... Engines to load\n"},
34     {"help", OPT_HELP, '-', "Display this summary"},
35     {"v", OPT_V, '-', "List 'control commands' For each specified engine"},
36     {"vv", OPT_VV, '-', "Also display each command's description"},
37     {"vvv", OPT_VVV, '-', "Also add the input flags for each command"},
38     {"vvvv", OPT_VVVV, '-', "Also show internal input flags"},
39     {"c", OPT_C, '-', "List the capabilities of specified engine"},
40     {"t", OPT_T, '-', "Check that specified engine is available"},
41     {"tt", OPT_TT, '-', "Display error trace for unavailable engines"},
42     {"pre", OPT_PRE, 's', "Run command against the ENGINE before loading it"},
43     {"post", OPT_POST, 's', "Run command against the ENGINE after loading it"},
44     {OPT_MORE_STR, OPT_EOF, 1,
45      "Commands are like \"SO_PATH:/lib/libdriver.so\""},
46     {NULL}
47 };
48
49 static int append_buf(char **buf, int *size, const char *s)
50 {
51     const int expand = 256;
52     int len = strlen(s) + 1;
53     char *p = *buf;
54
55     if (p == NULL) {
56         *size = ((len + expand - 1) / expand) * expand;
57         p = *buf = app_malloc(*size, "engine buffer");
58     } else {
59         const int blen = strlen(p);
60
61         if (blen > 0)
62             len += 2 + blen;
63
64         if (len > *size) {
65             *size = ((len + expand - 1) / expand) * expand;
66             p = OPENSSL_realloc(p, *size);
67             if (p == NULL) {
68                 OPENSSL_free(*buf);
69                 *buf = NULL;
70                 return 0;
71             }
72             *buf = p;
73         }
74
75         if (blen > 0) {
76             p += blen;
77             *p++ = ',';
78             *p++ = ' ';
79         }
80     }
81
82     strcpy(p, s);
83     return 1;
84 }
85
86 static int util_flags(BIO *out, unsigned int flags, const char *indent)
87 {
88     int started = 0, err = 0;
89     /* Indent before displaying input flags */
90     BIO_printf(out, "%s%s(input flags): ", indent, indent);
91     if (flags == 0) {
92         BIO_printf(out, "<no flags>\n");
93         return 1;
94     }
95     /*
96      * If the object is internal, mark it in a way that shows instead of
97      * having it part of all the other flags, even if it really is.
98      */
99     if (flags & ENGINE_CMD_FLAG_INTERNAL) {
100         BIO_printf(out, "[Internal] ");
101     }
102
103     if (flags & ENGINE_CMD_FLAG_NUMERIC) {
104         BIO_printf(out, "NUMERIC");
105         started = 1;
106     }
107     /*
108      * Now we check that no combinations of the mutually exclusive NUMERIC,
109      * STRING, and NO_INPUT flags have been used. Future flags that can be
110      * OR'd together with these would need to added after these to preserve
111      * the testing logic.
112      */
113     if (flags & ENGINE_CMD_FLAG_STRING) {
114         if (started) {
115             BIO_printf(out, "|");
116             err = 1;
117         }
118         BIO_printf(out, "STRING");
119         started = 1;
120     }
121     if (flags & ENGINE_CMD_FLAG_NO_INPUT) {
122         if (started) {
123             BIO_printf(out, "|");
124             err = 1;
125         }
126         BIO_printf(out, "NO_INPUT");
127         started = 1;
128     }
129     /* Check for unknown flags */
130     flags = flags & ~ENGINE_CMD_FLAG_NUMERIC &
131         ~ENGINE_CMD_FLAG_STRING &
132         ~ENGINE_CMD_FLAG_NO_INPUT & ~ENGINE_CMD_FLAG_INTERNAL;
133     if (flags) {
134         if (started)
135             BIO_printf(out, "|");
136         BIO_printf(out, "<0x%04X>", flags);
137     }
138     if (err)
139         BIO_printf(out, "  <illegal flags!>");
140     BIO_printf(out, "\n");
141     return 1;
142 }
143
144 static int util_verbose(ENGINE *e, int verbose, BIO *out, const char *indent)
145 {
146     static const int line_wrap = 78;
147     int num;
148     int ret = 0;
149     char *name = NULL;
150     char *desc = NULL;
151     int flags;
152     int xpos = 0;
153     STACK_OF(OPENSSL_STRING) *cmds = NULL;
154     if (!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL) ||
155         ((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_FIRST_CMD_TYPE,
156                             0, NULL, NULL)) <= 0)) {
157         return 1;
158     }
159
160     cmds = sk_OPENSSL_STRING_new_null();
161     if (cmds == NULL)
162         goto err;
163
164     do {
165         int len;
166         /* Get the command input flags */
167         if ((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num,
168                                  NULL, NULL)) < 0)
169             goto err;
170         if (!(flags & ENGINE_CMD_FLAG_INTERNAL) || verbose >= 4) {
171             /* Get the command name */
172             if ((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_LEN_FROM_CMD, num,
173                                    NULL, NULL)) <= 0)
174                 goto err;
175             name = app_malloc(len + 1, "name buffer");
176             if (ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_FROM_CMD, num, name,
177                             NULL) <= 0)
178                 goto err;
179             /* Get the command description */
180             if ((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_LEN_FROM_CMD, num,
181                                    NULL, NULL)) < 0)
182                 goto err;
183             if (len > 0) {
184                 desc = app_malloc(len + 1, "description buffer");
185                 if (ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_FROM_CMD, num, desc,
186                                 NULL) <= 0)
187                     goto err;
188             }
189             /* Now decide on the output */
190             if (xpos == 0)
191                 /* Do an indent */
192                 xpos = BIO_puts(out, indent);
193             else
194                 /* Otherwise prepend a ", " */
195                 xpos += BIO_printf(out, ", ");
196             if (verbose == 1) {
197                 /*
198                  * We're just listing names, comma-delimited
199                  */
200                 if ((xpos > (int)strlen(indent)) &&
201                     (xpos + (int)strlen(name) > line_wrap)) {
202                     BIO_printf(out, "\n");
203                     xpos = BIO_puts(out, indent);
204                 }
205                 xpos += BIO_printf(out, "%s", name);
206             } else {
207                 /* We're listing names plus descriptions */
208                 BIO_printf(out, "%s: %s\n", name,
209                            (desc == NULL) ? "<no description>" : desc);
210                 /* ... and sometimes input flags */
211                 if ((verbose >= 3) && !util_flags(out, flags, indent))
212                     goto err;
213                 xpos = 0;
214             }
215         }
216         OPENSSL_free(name);
217         name = NULL;
218         OPENSSL_free(desc);
219         desc = NULL;
220         /* Move to the next command */
221         num = ENGINE_ctrl(e, ENGINE_CTRL_GET_NEXT_CMD_TYPE, num, NULL, NULL);
222     } while (num > 0);
223     if (xpos > 0)
224         BIO_printf(out, "\n");
225     ret = 1;
226  err:
227     sk_OPENSSL_STRING_free(cmds);
228     OPENSSL_free(name);
229     OPENSSL_free(desc);
230     return ret;
231 }
232
233 static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds,
234                          BIO *out, const char *indent)
235 {
236     int loop, res, num = sk_OPENSSL_STRING_num(cmds);
237
238     if (num < 0) {
239         BIO_printf(out, "[Error]: internal stack error\n");
240         return;
241     }
242     for (loop = 0; loop < num; loop++) {
243         char buf[256];
244         const char *cmd, *arg;
245         cmd = sk_OPENSSL_STRING_value(cmds, loop);
246         res = 1;                /* assume success */
247         /* Check if this command has no ":arg" */
248         if ((arg = strstr(cmd, ":")) == NULL) {
249             if (!ENGINE_ctrl_cmd_string(e, cmd, NULL, 0))
250                 res = 0;
251         } else {
252             if ((int)(arg - cmd) > 254) {
253                 BIO_printf(out, "[Error]: command name too long\n");
254                 return;
255             }
256             memcpy(buf, cmd, (int)(arg - cmd));
257             buf[arg - cmd] = '\0';
258             arg++;              /* Move past the ":" */
259             /* Call the command with the argument */
260             if (!ENGINE_ctrl_cmd_string(e, buf, arg, 0))
261                 res = 0;
262         }
263         if (res) {
264             BIO_printf(out, "[Success]: %s\n", cmd);
265         } else {
266             BIO_printf(out, "[Failure]: %s\n", cmd);
267             ERR_print_errors(out);
268         }
269     }
270 }
271
272 struct util_store_cap_data {
273     ENGINE *engine;
274     char **cap_buf;
275     int *cap_size;
276     int ok;
277 };
278 static void util_store_cap(const OSSL_STORE_LOADER *loader, void *arg)
279 {
280     struct util_store_cap_data *ctx = arg;
281
282     if (OSSL_STORE_LOADER_get0_engine(loader) == ctx->engine) {
283         char buf[256];
284         BIO_snprintf(buf, sizeof(buf), "STORE(%s)",
285                      OSSL_STORE_LOADER_get0_scheme(loader));
286         if (!append_buf(ctx->cap_buf, ctx->cap_size, buf))
287             ctx->ok = 0;
288     }
289 }
290
291 int engine_main(int argc, char **argv)
292 {
293     int ret = 1, i;
294     int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0;
295     ENGINE *e;
296     STACK_OF(OPENSSL_CSTRING) *engines = sk_OPENSSL_CSTRING_new_null();
297     STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
298     STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();
299     BIO *out;
300     const char *indent = "     ";
301     OPTION_CHOICE o;
302     char *prog;
303     char *argv1;
304
305     out = dup_bio_out(FORMAT_TEXT);
306     if (engines == NULL || pre_cmds == NULL || post_cmds == NULL)
307         goto end;
308
309     /* Remember the original command name, parse/skip any leading engine
310      * names, and then setup to parse the rest of the line as flags. */
311     prog = argv[0];
312     while ((argv1 = argv[1]) != NULL && *argv1 != '-') {
313         sk_OPENSSL_CSTRING_push(engines, argv1);
314         argc--;
315         argv++;
316     }
317     argv[0] = prog;
318     opt_init(argc, argv, engine_options);
319
320     while ((o = opt_next()) != OPT_EOF) {
321         switch (o) {
322         case OPT_EOF:
323         case OPT_ERR:
324             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
325             goto end;
326         case OPT_HELP:
327             opt_help(engine_options);
328             ret = 0;
329             goto end;
330         case OPT_VVVV:
331         case OPT_VVV:
332         case OPT_VV:
333         case OPT_V:
334             /* Convert to an integer from one to four. */
335             i = (int)(o - OPT_V) + 1;
336             if (verbose < i)
337                 verbose = i;
338             break;
339         case OPT_C:
340             list_cap = 1;
341             break;
342         case OPT_TT:
343             test_avail_noise++;
344             /* fall thru */
345         case OPT_T:
346             test_avail++;
347             break;
348         case OPT_PRE:
349             sk_OPENSSL_STRING_push(pre_cmds, opt_arg());
350             break;
351         case OPT_POST:
352             sk_OPENSSL_STRING_push(post_cmds, opt_arg());
353             break;
354         }
355     }
356
357     /* Allow any trailing parameters as engine names. */
358     argc = opt_num_rest();
359     argv = opt_rest();
360     for ( ; *argv; argv++) {
361         if (**argv == '-') {
362             BIO_printf(bio_err, "%s: Cannot mix flags and engine names.\n",
363                        prog);
364             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
365             goto end;
366         }
367         sk_OPENSSL_CSTRING_push(engines, *argv);
368     }
369
370     if (sk_OPENSSL_CSTRING_num(engines) == 0) {
371         for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) {
372             sk_OPENSSL_CSTRING_push(engines, ENGINE_get_id(e));
373         }
374     }
375
376     ret = 0;
377     for (i = 0; i < sk_OPENSSL_CSTRING_num(engines); i++) {
378         const char *id = sk_OPENSSL_CSTRING_value(engines, i);
379         if ((e = ENGINE_by_id(id)) != NULL) {
380             const char *name = ENGINE_get_name(e);
381             /*
382              * Do "id" first, then "name". Easier to auto-parse.
383              */
384             BIO_printf(out, "(%s) %s\n", id, name);
385             util_do_cmds(e, pre_cmds, out, indent);
386             if (strcmp(ENGINE_get_id(e), id) != 0) {
387                 BIO_printf(out, "Loaded: (%s) %s\n",
388                            ENGINE_get_id(e), ENGINE_get_name(e));
389             }
390             if (list_cap) {
391                 int cap_size = 256;
392                 char *cap_buf = NULL;
393                 int k, n;
394                 const int *nids;
395                 ENGINE_CIPHERS_PTR fn_c;
396                 ENGINE_DIGESTS_PTR fn_d;
397                 ENGINE_PKEY_METHS_PTR fn_pk;
398
399                 if (ENGINE_get_RSA(e) != NULL
400                     && !append_buf(&cap_buf, &cap_size, "RSA"))
401                     goto end;
402                 if (ENGINE_get_DSA(e) != NULL
403                     && !append_buf(&cap_buf, &cap_size, "DSA"))
404                     goto end;
405                 if (ENGINE_get_DH(e) != NULL
406                     && !append_buf(&cap_buf, &cap_size, "DH"))
407                     goto end;
408                 if (ENGINE_get_RAND(e) != NULL
409                     && !append_buf(&cap_buf, &cap_size, "RAND"))
410                     goto end;
411
412                 fn_c = ENGINE_get_ciphers(e);
413                 if (fn_c == NULL)
414                     goto skip_ciphers;
415                 n = fn_c(e, NULL, &nids, 0);
416                 for (k = 0; k < n; ++k)
417                     if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k])))
418                         goto end;
419
420  skip_ciphers:
421                 fn_d = ENGINE_get_digests(e);
422                 if (fn_d == NULL)
423                     goto skip_digests;
424                 n = fn_d(e, NULL, &nids, 0);
425                 for (k = 0; k < n; ++k)
426                     if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k])))
427                         goto end;
428
429  skip_digests:
430                 fn_pk = ENGINE_get_pkey_meths(e);
431                 if (fn_pk == NULL)
432                     goto skip_pmeths;
433                 n = fn_pk(e, NULL, &nids, 0);
434                 for (k = 0; k < n; ++k)
435                     if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k])))
436                         goto end;
437  skip_pmeths:
438                 {
439                     struct util_store_cap_data store_ctx;
440
441                     store_ctx.engine = e;
442                     store_ctx.cap_buf = &cap_buf;
443                     store_ctx.cap_size = &cap_size;
444                     store_ctx.ok = 1;
445
446                     OSSL_STORE_do_all_loaders(util_store_cap, &store_ctx);
447                     if (!store_ctx.ok)
448                         goto end;
449                 }
450                 if (cap_buf != NULL && (*cap_buf != '\0'))
451                     BIO_printf(out, " [%s]\n", cap_buf);
452
453                 OPENSSL_free(cap_buf);
454             }
455             if (test_avail) {
456                 BIO_printf(out, "%s", indent);
457                 if (ENGINE_init(e)) {
458                     BIO_printf(out, "[ available ]\n");
459                     util_do_cmds(e, post_cmds, out, indent);
460                     ENGINE_finish(e);
461                 } else {
462                     BIO_printf(out, "[ unavailable ]\n");
463                     if (test_avail_noise)
464                         ERR_print_errors_fp(stdout);
465                     ERR_clear_error();
466                 }
467             }
468             if ((verbose > 0) && !util_verbose(e, verbose, out, indent))
469                 goto end;
470             ENGINE_free(e);
471         } else {
472             ERR_print_errors(bio_err);
473             /* because exit codes above 127 have special meaning on Unix */
474             if (++ret > 127)
475                 ret = 127;
476         }
477     }
478
479  end:
480
481     ERR_print_errors(bio_err);
482     sk_OPENSSL_CSTRING_free(engines);
483     sk_OPENSSL_STRING_free(pre_cmds);
484     sk_OPENSSL_STRING_free(post_cmds);
485     BIO_free_all(out);
486     return ret;
487 }
488 #endif