From fb43ddceda79f0af5fca88b47c794337f207666e Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Mon, 4 Sep 2017 15:42:01 +0200 Subject: Add a recursive option to 'openssl storeutl' Simply put, any NAME type OSS_STORE_INTO is a new object that can be looked into, and potentially lead to a whole tree of data to dive into. The recursive option allows someone to view the whole tree and its data in one go. Reviewed-by: Andy Polyakov (Merged from https://github.com/openssl/openssl/pull/4336) --- apps/storeutl.c | 73 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 17 deletions(-) (limited to 'apps/storeutl.c') diff --git a/apps/storeutl.c b/apps/storeutl.c index dd2f60b5ef..77f0f3f0f5 100644 --- a/apps/storeutl.c +++ b/apps/storeutl.c @@ -14,9 +14,12 @@ #include #include +static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, + int text, int noout, int recursive, int indent, BIO *out); + typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE, OPT_OUT, OPT_PASSIN, - OPT_NOOUT, OPT_TEXT + OPT_NOOUT, OPT_TEXT, OPT_RECURSIVE } OPTION_CHOICE; const OPTIONS storeutl_options[] = { @@ -29,13 +32,13 @@ const OPTIONS storeutl_options[] = { #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif + {"r", OPT_RECURSIVE, '-', "Recurse through names"}, {NULL} }; int storeutl_main(int argc, char *argv[]) { - OSSL_STORE_CTX *store_ctx = NULL; - int ret = 1, noout = 0, text = 0, items = 0; + int ret = 1, noout = 0, text = 0, recursive = 0; char *outfile = NULL, *passin = NULL, *passinarg = NULL; BIO *out = NULL; ENGINE *e = NULL; @@ -66,6 +69,9 @@ int storeutl_main(int argc, char *argv[]) case OPT_TEXT: text = 1; break; + case OPT_RECURSIVE: + recursive = 1; + break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; @@ -94,11 +100,40 @@ int storeutl_main(int argc, char *argv[]) if (out == NULL) goto end; - if ((store_ctx = OSSL_STORE_open(argv[0], get_ui_method(), &pw_cb_data, - NULL, NULL)) == NULL) { - BIO_printf(bio_err, "Couldn't open file or uri %s\n", argv[0]); + ret = process(argv[0], get_ui_method(), &pw_cb_data, text, noout, recursive, + 0, out); + + end: + BIO_free_all(out); + OPENSSL_free(passin); + release_engine(e); + return ret; +} + +static int indent_printf(int indent, BIO *bio, const char *format, ...) +{ + va_list args; + int ret; + + va_start(args, format); + + ret = BIO_printf(bio, "%*s", indent, "") + BIO_vprintf(bio, format, args); + + va_end(args); + return ret; +} + +static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, + int text, int noout, int recursive, int indent, BIO *out) +{ + OSSL_STORE_CTX *store_ctx = NULL; + int ret = 1, items = 0; + + if ((store_ctx = OSSL_STORE_open(uri, uimeth, uidata, NULL, NULL)) + == NULL) { + BIO_printf(bio_err, "Couldn't open file or uri %s\n", uri); ERR_print_errors(bio_err); - goto end; + return ret; } /* From here on, we count errors, and we'll return the count at the end */ @@ -115,7 +150,10 @@ int storeutl_main(int argc, char *argv[]) break; if (OSSL_STORE_error(store_ctx)) { - ERR_print_errors(bio_err); + if (recursive) + ERR_clear_error(); + else + ERR_print_errors(bio_err); ret++; continue; } @@ -132,11 +170,12 @@ int storeutl_main(int argc, char *argv[]) if (type == OSSL_STORE_INFO_NAME) { const char *name = OSSL_STORE_INFO_get0_NAME(info); const char *desc = OSSL_STORE_INFO_get0_NAME_description(info); - BIO_printf(bio_out, "%d: %s: %s\n", items, infostr, name); + indent_printf(indent, bio_out, "%d: %s: %s\n", items, infostr, + name); if (desc != NULL) - BIO_printf(bio_out, "%s\n", desc); + indent_printf(indent, bio_out, "%s\n", desc); } else { - BIO_printf(bio_out, "%d: %s\n", items, infostr); + indent_printf(indent, bio_out, "%d: %s\n", items, infostr); } /* @@ -146,6 +185,11 @@ int storeutl_main(int argc, char *argv[]) */ switch (type) { case OSSL_STORE_INFO_NAME: + if (recursive) { + const char *suburi = OSSL_STORE_INFO_get0_NAME(info); + ret += process(suburi, uimeth, uidata, text, noout, recursive, + indent + 2, out); + } break; case OSSL_STORE_INFO_PARAMS: if (text) @@ -183,17 +227,12 @@ int storeutl_main(int argc, char *argv[]) items++; OSSL_STORE_INFO_free(info); } - BIO_printf(out, "Total found: %d\n", items); + indent_printf(indent, out, "Total found: %d\n", items); if (!OSSL_STORE_close(store_ctx)) { ERR_print_errors(bio_err); ret++; - goto end; } - end: - BIO_free_all(out); - OPENSSL_free(passin); - release_engine(e); return ret; } -- cgit v1.2.3