engine.c 16 KB

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