diff --git a/doc/tools/pkcs11-tool.1.xml b/doc/tools/pkcs11-tool.1.xml
index 45757311..bb8bce37 100644
--- a/doc/tools/pkcs11-tool.1.xml
+++ b/doc/tools/pkcs11-tool.1.xml
@@ -219,6 +219,13 @@
List slots with tokens.
+
+
+
+
+ List interfaces of PKCS #11 3.0 library.
+
+
,
diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c
index 53861898..fbeb0c9d 100644
--- a/src/tools/pkcs11-tool.c
+++ b/src/tools/pkcs11-tool.c
@@ -161,7 +161,8 @@ enum {
OPT_ALWAYS_AUTH,
OPT_ALLOWED_MECHANISMS,
OPT_OBJECT_INDEX,
- OPT_ALLOW_SW
+ OPT_ALLOW_SW,
+ OPT_LIST_INTERFACES
};
static const struct option options[] = {
@@ -171,6 +172,7 @@ static const struct option options[] = {
{ "list-token-slots", 0, NULL, 'T' },
{ "list-mechanisms", 0, NULL, 'M' },
{ "list-objects", 0, NULL, 'O' },
+ { "list-interfaces", 0, NULL, OPT_LIST_INTERFACES },
{ "sign", 0, NULL, 's' },
{ "verify", 0, NULL, OPT_VERIFY },
@@ -248,6 +250,7 @@ static const char *option_help[] = {
"List slots with tokens",
"List mechanisms supported by the token",
"Show objects on token",
+ "List interfaces of PKCS #11 3.0 library",
"Sign some data",
"Verify a signature of some data",
@@ -373,7 +376,7 @@ static int opt_always_auth = 0;
static CK_FLAGS opt_allow_sw = CKF_HW;
static void *module = NULL;
-static CK_FUNCTION_LIST_PTR p11 = NULL;
+static CK_FUNCTION_LIST_3_0_PTR p11 = NULL;
static CK_SLOT_ID_PTR p11_slots = NULL;
static CK_ULONG p11_num_slots = 0;
static int suppress_warn = 0;
@@ -424,6 +427,7 @@ static void list_slots(int, int, int);
static void show_token(CK_SLOT_ID);
static void list_mechs(CK_SLOT_ID);
static void list_objects(CK_SESSION_HANDLE, CK_OBJECT_CLASS);
+static void list_interfaces(void);
static int login(CK_SESSION_HANDLE, int);
static void init_token(CK_SLOT_ID);
static void init_pin(CK_SLOT_ID, CK_SESSION_HANDLE);
@@ -577,6 +581,7 @@ int main(int argc, char * argv[])
int list_token_slots = 0;
int do_list_mechs = 0;
int do_list_objects = 0;
+ int do_list_interfaces = 0;
int do_sign = 0;
int do_verify = 0;
int do_decrypt = 0;
@@ -950,6 +955,10 @@ int main(int argc, char * argv[])
s = strtok(NULL, ",");
}
break;
+ case OPT_LIST_INTERFACES:
+ do_list_interfaces = 1;
+ action_count++;
+ break;
default:
util_print_usage_and_die(app_name, options, option_help, NULL);
}
@@ -974,11 +983,15 @@ int main(int argc, char * argv[])
else
#endif
{
- module = C_LoadModule(opt_module, &p11);
+ module = C_LoadModule(opt_module, (CK_FUNCTION_LIST_PTR_PTR)&p11);
if (module == NULL)
util_fatal("Failed to load pkcs11 module");
}
+ /* This can be done even before initialization */
+ if (do_list_interfaces)
+ list_interfaces();
+
rv = p11->C_Initialize(NULL);
if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED)
fprintf(stderr, "\n*** Cryptoki library has already been initialized ***\n");
@@ -1258,6 +1271,41 @@ static void show_cryptoki_info(void)
info.libraryVersion.minor);
}
+static void list_interfaces(void)
+{
+ CK_ULONG count = 0, i;
+ CK_INTERFACE_PTR interfaces = NULL;
+ CK_RV rv;
+
+ if (p11->version.major < 3) {
+ fprintf(stderr, "Interfaces are supported only in PKCS #11 3.0 and newer\n");
+ exit(1);
+ }
+
+ rv = p11->C_GetInterfaceList(NULL, &count);
+ if (rv != CKR_OK) {
+ p11_fatal("C_GetInterfaceList(size inquire)", rv);
+ }
+
+ interfaces = malloc(count * sizeof(CK_INTERFACE));
+ if (interfaces == NULL) {
+ perror("malloc failed");
+ exit(1);
+ }
+ rv = p11->C_GetInterfaceList(interfaces, &count);
+ if (rv != CKR_OK) {
+ p11_fatal("C_GetInterfaceList", rv);
+ }
+ for (i = 0; i < count; i++) {
+ printf("Interface '%s'\n version: %d.%d\n funcs=%p\n flags=0x%lu\n",
+ interfaces[i].pInterfaceName,
+ ((CK_VERSION *)interfaces[i].pFunctionList)->major,
+ ((CK_VERSION *)interfaces[i].pFunctionList)->minor,
+ interfaces[i].pFunctionList,
+ interfaces[i].flags);
+ }
+
+}
static void list_slots(int tokens, int refresh, int print)
{
CK_SLOT_INFO info;
@@ -6207,7 +6255,7 @@ static CK_SESSION_HANDLE test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE
printf("\n*** Loading the pkcs11 lib, opening a session and logging in ***\n");
- module = C_LoadModule(opt_module, &p11);
+ module = C_LoadModule(opt_module, (CK_FUNCTION_LIST_PTR_PTR)&p11);
if (module == NULL)
util_fatal("Failed to load pkcs11 module");