From 8c746ded0b14d30d5319dcd94b94a18215e0bcbf Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Sun, 1 Oct 2023 06:18:19 +0900 Subject: [PATCH] p11-kit list-tokens: New subcommand This adds a new subcommand "list-tokens" to the p11-kit command, which is similar to "list-modules" but only prints tokens. This would make scripting tasks easier. Signed-off-by: Daiki Ueno --- doc/manual/p11-kit.xml | 19 +++++ p11-kit/Makefile.am | 4 + p11-kit/list-tokens.c | 165 ++++++++++++++++++++++++++++++++++++ p11-kit/lists.c | 9 +- p11-kit/meson.build | 4 + p11-kit/p11-kit.c | 4 + p11-kit/test-list-tokens.sh | 82 ++++++++++++++++++ 7 files changed, 285 insertions(+), 2 deletions(-) create mode 100644 p11-kit/list-tokens.c create mode 100755 p11-kit/test-list-tokens.sh diff --git a/doc/manual/p11-kit.xml b/doc/manual/p11-kit.xml index bb27640f..90c1ec69 100644 --- a/doc/manual/p11-kit.xml +++ b/doc/manual/p11-kit.xml @@ -32,6 +32,9 @@ p11-kit list-modules + + p11-kit list-tokens ... + p11-kit list-objects ... @@ -105,6 +108,22 @@ $ p11-kit list-modules + + List Tokens + + List all tokens available in system configured PKCS#11 modules. + + +$ p11-kit list-tokens pkcs11:token +$ p11-kit list-tokens --only-uris pkcs11:token + + + This retrieves all tokens and displays some of their + common attributes. If is given, + only the matching token URIs are printed. + + + List Objects diff --git a/p11-kit/Makefile.am b/p11-kit/Makefile.am index 47f9ed26..1eb29e1e 100644 --- a/p11-kit/Makefile.am +++ b/p11-kit/Makefile.am @@ -271,6 +271,7 @@ p11_kit_p11_kit_SOURCES = \ p11-kit/list-objects.c \ p11-kit/list-profiles.c \ p11-kit/list-mechanisms.c \ + p11-kit/list-tokens.c \ p11-kit/lists.c \ p11-kit/p11-kit.c \ p11-kit/print-config.c \ @@ -303,6 +304,7 @@ p11_kit_p11_kit_testable_SOURCES = \ p11-kit/list-objects.c \ p11-kit/list-profiles.c \ p11-kit/list-mechanisms.c \ + p11-kit/list-tokens.c \ p11-kit/lists.c \ p11-kit/p11-kit.c \ p11-kit/print-config.c \ @@ -428,6 +430,7 @@ sh_tests += \ p11-kit/test-lists.sh \ p11-kit/test-server.sh \ p11-kit/test-list-mechanisms.sh \ + p11-kit/test-list-tokens.sh \ $(NULL) if WITH_ASN1 @@ -620,6 +623,7 @@ EXTRA_DIST += \ p11-kit/test-lists.sh \ p11-kit/test-messages.sh \ p11-kit/test-server.sh \ + p11-kit/test-list-tokens.sh \ p11-kit/test-export-public.sh \ p11-kit/test-list-mechanisms.sh \ $(NULL) diff --git a/p11-kit/list-tokens.c b/p11-kit/list-tokens.c new file mode 100644 index 00000000..b2b06c14 --- /dev/null +++ b/p11-kit/list-tokens.c @@ -0,0 +1,165 @@ +#include "config.h" + +#include "attrs.h" +#include "buffer.h" +#include "constants.h" +#define P11_DEBUG_FLAG P11_DEBUG_TOOL +#include "debug.h" +#include "iter.h" +#include "message.h" +#include "print.h" +#include "tool.h" + +#include +#include +#include +#include +#include + +#ifdef ENABLE_NLS +#include +#define _(x) dgettext(PACKAGE_NAME, x) +#else +#define _(x) (x) +#endif + +void print_token_info (p11_list_printer *printer, + CK_TOKEN_INFO *info); + +char *format_token_uri (CK_TOKEN_INFO *info); + +int p11_kit_list_tokens (int argc, + char *argv[]); + +static int +print_tokens (p11_list_printer *printer, + const char *token_str, + bool only_uris) +{ + int ret = 1; + CK_FUNCTION_LIST **modules = NULL; + P11KitUri *uri = NULL; + P11KitIter *iter = NULL; + + uri = p11_kit_uri_new (); + if (uri == NULL) { + p11_message (_("failed to allocate memory")); + goto cleanup; + } + + if (p11_kit_uri_parse (token_str, P11_KIT_URI_FOR_TOKEN, uri) != P11_KIT_URI_OK) { + p11_message (_("failed to parse URI")); + goto cleanup; + } + + modules = p11_kit_modules_load_and_initialize (0); + if (modules == NULL) { + p11_message (_("failed to load and initialize modules")); + goto cleanup; + } + + iter = p11_kit_iter_new (uri, P11_KIT_ITER_WITH_TOKENS | + P11_KIT_ITER_WITHOUT_OBJECTS); + if (iter == NULL) { + p11_debug ("failed to initialize iterator"); + goto cleanup; + } + + p11_kit_iter_begin (iter, modules); + while (p11_kit_iter_next (iter) == CKR_OK) { + CK_TOKEN_INFO *info = p11_kit_iter_get_token (iter); + char *value; + + if (only_uris) { + value = format_token_uri (info); + if (value) + printf ("%s\n", value); + free (value); + } else { + value = p11_kit_space_strdup (info->label, sizeof (info->label)); + p11_list_printer_start_section (printer, "token", "%s", value); + free (value); + + print_token_info (printer, info); + p11_list_printer_end_section (printer); + } + } + + ret = 0; + +cleanup: + p11_kit_iter_free (iter); + p11_kit_uri_free (uri); + if (modules != NULL) + p11_kit_modules_finalize_and_release (modules); + + return ret; +} + +int +p11_kit_list_tokens (int argc, + char *argv[]) +{ + int opt; + bool only_uris = false; + p11_list_printer printer; + + enum { + opt_verbose = 'v', + opt_quiet = 'q', + opt_help = 'h', + }; + + struct option options[] = { + { "verbose", no_argument, NULL, opt_verbose }, + { "quiet", no_argument, NULL, opt_quiet }, + { "only-uris", no_argument, NULL, CHAR_MAX + 1 }, + { "help", no_argument, NULL, opt_help }, + { 0 }, + }; + + p11_tool_desc usages[] = { + { 0, "usage: p11-kit list-tokens" }, + { opt_verbose, "show verbose debug output", }, + { opt_quiet, "suppress command output", }, + { CHAR_MAX + 1, "only print token URIs", }, + { 0 }, + }; + + while ((opt = p11_tool_getopt (argc, argv, options)) != -1) { + switch (opt) { + + case opt_verbose: + p11_kit_be_loud (); + break; + + case opt_quiet: + p11_kit_be_quiet (); + break; + + case CHAR_MAX + 1: /* --only-uris */ + only_uris = true; + break; + + case opt_help: + p11_tool_usage (usages, options); + return 0; + case '?': + return 2; + default: + assert_not_reached (); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc != 1) { + p11_tool_usage (usages, options); + return 2; + } + + p11_list_printer_init (&printer, stdout, 0); + return print_tokens (&printer, *argv, only_uris); +} diff --git a/p11-kit/lists.c b/p11-kit/lists.c index 52aaa697..df58beb3 100644 --- a/p11-kit/lists.c +++ b/p11-kit/lists.c @@ -80,7 +80,12 @@ is_ascii_string (const unsigned char *data, return true; } -static char * +char *format_token_uri (CK_TOKEN_INFO *info); + +void print_token_info (p11_list_printer *printer, + CK_TOKEN_INFO *info); + +char * format_token_uri (CK_TOKEN_INFO *info) { char *value; @@ -105,7 +110,7 @@ format_token_uri (CK_TOKEN_INFO *info) return value; } -static void +void print_token_info (p11_list_printer *printer, CK_TOKEN_INFO *info) { diff --git a/p11-kit/meson.build b/p11-kit/meson.build index 6aa69675..bdc50290 100644 --- a/p11-kit/meson.build +++ b/p11-kit/meson.build @@ -218,6 +218,7 @@ p11_kit_sources = [ 'list-objects.c', 'list-profiles.c', 'list-mechanisms.c', + 'list-tokens.c', 'lists.c', 'p11-kit.c', 'print-config.c' @@ -405,6 +406,9 @@ if get_option('test') test('test-list-mechanisms.sh', find_program('test-list-mechanisms.sh'), + + test('test-list-tokens.sh', + find_program('test-list-tokens.sh'), env: p11_kit_tests_env) endif diff --git a/p11-kit/p11-kit.c b/p11-kit/p11-kit.c index 04a55f1e..eed453d8 100644 --- a/p11-kit/p11-kit.c +++ b/p11-kit/p11-kit.c @@ -62,6 +62,9 @@ int p11_kit_list_modules (int argc, char *argv[]); +int p11_kit_list_tokens (int argc, + char *argv[]); + int p11_kit_list_objects (int argc, char *argv[]); @@ -97,6 +100,7 @@ int p11_kit_external (int argc, static const p11_tool_command commands[] = { { "list-modules", p11_kit_list_modules, N_("List modules and tokens") }, + { "list-tokens", p11_kit_list_tokens, N_("List tokens") }, { "list-objects", p11_kit_list_objects, N_("List objects of a token") }, { "export-object", p11_kit_export_object, N_("Export object matching PKCS#11 URI") }, { "delete-object", p11_kit_delete_object, N_("Delete objects matching PKCS#11 URI") }, diff --git a/p11-kit/test-list-tokens.sh b/p11-kit/test-list-tokens.sh new file mode 100755 index 00000000..f61e241d --- /dev/null +++ b/p11-kit/test-list-tokens.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +# Test public key export from mock-twelve.so (mock-module-ep10.c). + +test "${abs_top_builddir+set}" = set || { + echo "set abs_top_builddir" 1>&2 + exit 1 +} + +. "$abs_top_builddir/common/test-init.sh" + +setup() { + testdir=$PWD/test-objects-$$ + test -d "$testdir" || mkdir "$testdir" + cd "$testdir" +} + +teardown() { + rm -rf "$testdir" +} + +test_list_tokens_without_uri() { + cat > list.exp <&1 > list.out; then + assert_fail "p11-kit list-tokens succeeded without token URI" + fi + + : ${DIFF=diff} + if ! ${DIFF} list.exp list.out > list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains incorrect result" + fi +} + +test_list_tokens() { + cat > list.exp < list.out; then + assert_fail "unable to run: p11-kit list-tokens" + fi + + : ${DIFF=diff} + if ! ${DIFF} list.exp list.out > list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains incorrect result" + fi +} + +test_list_tokens_only_uris() { + cat > list.exp < list.out; then + assert_fail "unable to run: p11-kit list-tokens --only-uris" + fi + + : ${DIFF=diff} + if ! ${DIFF} list.exp list.out > list.diff; then + sed 's/^/# /' list.diff + assert_fail "output contains incorrect result" + fi +} + +run test_list_tokens_without_uri test_list_tokens test_list_tokens_only_uris