summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2013-03-06 19:16:09 +0100
committerStef Walter <stefw@gnome.org>2013-03-15 17:25:17 +0100
commit0e75a5ba8261955d4d75a38a528f79ff4edd5c21 (patch)
treee06a9dd5a59b2a92704fc23d19f21f7873d0bccc
parentd2128c263ea77e4f99bccc6ac46964ad419ec2d1 (diff)
downloadp11-kit-0e75a5ba8261955d4d75a38a528f79ff4edd5c21.tar.gz
trust: Make each configured path its own token
* Each source directory or file configured into the module or passed in as an initialization argument becomes its own token. Previously there was one token that contained certificates from all the configured paths. * These tokens are clearly labeled in the token info as to the directory or file that they represent. * Update PKCS#11 module logic to deal with multiple tokens, validate the slot ids and so on. * The order in which the paths are configured will become the order of trust priority. This is the same order in which they are listed through 'p11-kit list-modules' and C_GetSlotList. * Update the frob-token internal tool to only play with one path * Adjust tests where necessary to reflect the new state of things and add tests for modified trust module code https://bugs.freedesktop.org/show_bug.cgi?id=61499
-rw-r--r--trust/module.c202
-rw-r--r--trust/tests/frob-token.c4
-rw-r--r--trust/tests/test-module.c283
-rw-r--r--trust/tests/test-session.c2
-rw-r--r--trust/tests/test-token.c33
-rw-r--r--trust/token.c64
-rw-r--r--trust/token.h8
7 files changed, 460 insertions, 136 deletions
diff --git a/trust/module.c b/trust/module.c
index 5ac018e..a39c204 100644
--- a/trust/module.c
+++ b/trust/module.c
@@ -36,12 +36,14 @@
#define CRYPTOKI_EXPORTS
+#include "array.h"
#include "attrs.h"
#define P11_DEBUG_FLAG P11_DEBUG_TRUST
#include "debug.h"
#include "dict.h"
#include "library.h"
#include "module.h"
+#include "parser.h"
#include "pkcs11.h"
#include "session.h"
#include "token.h"
@@ -53,17 +55,16 @@
#define MANUFACTURER_ID "PKCS#11 Kit "
#define LIBRARY_DESCRIPTION "PKCS#11 Kit Trust Module "
-#define SLOT_DESCRIPTION "System Certificates, Trust Anchors, and Black Lists "
#define TOKEN_LABEL "System Trust Anchors and Policy "
#define TOKEN_MODEL "PKCS#11 Kit "
#define TOKEN_SERIAL_NUMBER "1 "
-/* Arbitrary non-zero and non-one choice */
-#define SYSTEM_SLOT_ID 18UL
+/* Initial slot id: non-zero and non-one */
+#define BASE_SLOT_ID 18UL
static struct _Shared {
p11_dict *sessions;
- p11_token *token;
+ p11_array *tokens;
char *paths;
} gl = { NULL, NULL };
@@ -103,6 +104,80 @@ lookup_session (CK_SESSION_HANDLE handle,
return CKR_OK;
}
+static CK_RV
+lookup_slot_inlock (CK_SLOT_ID id,
+ p11_token **token)
+{
+ /*
+ * These are invalid inputs, that well behaved callers should
+ * not produce, so have them fail precondations
+ */
+
+ return_val_if_fail (gl.tokens != NULL,
+ CKR_CRYPTOKI_NOT_INITIALIZED);
+
+ return_val_if_fail (id >= BASE_SLOT_ID && id - BASE_SLOT_ID < gl.tokens->num,
+ CKR_SLOT_ID_INVALID);
+
+ if (token)
+ *token = gl.tokens->elem[id - BASE_SLOT_ID];
+ return CKR_OK;
+}
+
+static bool
+check_slot (CK_SLOT_ID id)
+{
+ bool ret;
+
+ p11_lock ();
+ ret = lookup_slot_inlock (id, NULL) == CKR_OK;
+ p11_unlock ();
+
+ return ret;
+}
+
+static bool
+create_tokens_inlock (p11_array *tokens,
+ const char *paths)
+{
+ p11_token *token;
+ p11_token *check;
+ CK_SLOT_ID slot;
+ const char *path;
+ char *remaining;
+ char *pos;
+
+ p11_debug ("using paths: %s", paths);
+
+ remaining = strdup (paths);
+ return_val_if_fail (remaining != NULL, false);
+
+ while (remaining) {
+ path = remaining;
+ pos = strchr (remaining, ':');
+ if (pos == NULL) {
+ remaining = NULL;
+ } else {
+ pos[0] = '\0';
+ remaining = pos + 1;
+ }
+
+ if (path[0] != '\0') {
+ slot = BASE_SLOT_ID + tokens->num;
+ token = p11_token_new (slot, path);
+ return_val_if_fail (token != NULL, false);
+
+ if (!p11_array_push (tokens, token))
+ return_val_if_reached (false);
+
+ assert (lookup_slot_inlock (slot, &check) == CKR_OK && check == token);
+ }
+ }
+
+ free (remaining);
+ return true;
+}
+
static void
parse_argument (char *arg)
{
@@ -220,8 +295,8 @@ sys_C_Finalize (CK_VOID_PTR reserved)
p11_dict_free (gl.sessions);
gl.sessions = NULL;
- p11_token_free (gl.token);
- gl.token = NULL;
+ p11_array_free (gl.tokens);
+ gl.tokens = NULL;
rv = CKR_OK;
}
@@ -284,9 +359,11 @@ sys_C_Initialize (CK_VOID_PTR init_args)
p11_dict_ulongptr_equal,
NULL, p11_session_free);
- gl.token = p11_token_new (gl.paths ? gl.paths : TRUST_PATHS);
+ gl.tokens = p11_array_new ((p11_destroyer)p11_token_free);
+ if (gl.tokens && !create_tokens_inlock (gl.tokens, gl.paths ? gl.paths : TRUST_PATHS))
+ gl.tokens = NULL;
- if (gl.sessions == NULL || gl.token == NULL) {
+ if (gl.sessions == NULL || gl.tokens == NULL) {
warn_if_reached ();
rv = CKR_GENERAL_ERROR;
}
@@ -351,6 +428,7 @@ sys_C_GetSlotList (CK_BBOOL token_present,
CK_ULONG_PTR count)
{
CK_RV rv = CKR_OK;
+ int i;
return_val_if_fail (count != NULL, CKR_ARGUMENTS_BAD);
@@ -367,16 +445,17 @@ sys_C_GetSlotList (CK_BBOOL token_present,
/* already failed */
} else if (!slot_list) {
- *count = 1;
+ *count = gl.tokens->num;
rv = CKR_OK;
- } else if (*count < 1) {
- *count = 1;
+ } else if (*count < gl.tokens->num) {
+ *count = gl.tokens->num;
rv = CKR_BUFFER_TOO_SMALL;
} else {
- slot_list[0] = SYSTEM_SLOT_ID;
- *count = 1;
+ for (i = 0; i < gl.tokens->num; i++)
+ slot_list[i] = BASE_SLOT_ID + i;
+ *count = gl.tokens->num;
rv = CKR_OK;
}
@@ -390,19 +469,16 @@ sys_C_GetSlotInfo (CK_SLOT_ID id,
CK_SLOT_INFO_PTR info)
{
CK_RV rv = CKR_OK;
+ p11_token *token;
+ const char *path;
+ size_t length;
- return_val_if_fail (id == SYSTEM_SLOT_ID, CKR_SLOT_ID_INVALID);
return_val_if_fail (info != NULL, CKR_ARGUMENTS_BAD);
p11_debug ("in");
-
p11_lock ();
- if (!gl.sessions)
- rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-
- p11_unlock ();
-
+ rv = lookup_slot_inlock (id, &token);
if (rv == CKR_OK) {
memset (info, 0, sizeof (*info));
info->firmwareVersion.major = 0;
@@ -411,9 +487,17 @@ sys_C_GetSlotInfo (CK_SLOT_ID id,
info->hardwareVersion.minor = 0;
info->flags = CKF_TOKEN_PRESENT;
strncpy ((char*)info->manufacturerID, MANUFACTURER_ID, 32);
- strncpy ((char*)info->slotDescription, SLOT_DESCRIPTION, 64);
+
+ /* If too long, copy the first 64 characters into buffer */
+ path = p11_token_get_path (token);
+ length = strlen (path);
+ if (length > sizeof (info->slotDescription))
+ length = sizeof (info->slotDescription);
+ memset (info->slotDescription, ' ', sizeof (info->slotDescription));
+ memcpy (info->slotDescription, path, length);
}
+ p11_unlock ();
p11_debug ("out: 0x%lx", rv);
return rv;
@@ -424,19 +508,17 @@ sys_C_GetTokenInfo (CK_SLOT_ID id,
CK_TOKEN_INFO_PTR info)
{
CK_RV rv = CKR_OK;
+ p11_token *token;
+ const char *path;
+ size_t length;
- return_val_if_fail (id == SYSTEM_SLOT_ID, CKR_SLOT_ID_INVALID);
return_val_if_fail (info != NULL, CKR_ARGUMENTS_BAD);
p11_debug ("in");
p11_lock ();
- if (!gl.sessions)
- rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-
- p11_unlock ();
-
+ rv = lookup_slot_inlock (id, &token);
if (rv == CKR_OK) {
memset (info, 0, sizeof (*info));
info->firmwareVersion.major = 0;
@@ -445,7 +527,6 @@ sys_C_GetTokenInfo (CK_SLOT_ID id,
info->hardwareVersion.minor = 0;
info->flags = CKF_TOKEN_INITIALIZED | CKF_WRITE_PROTECTED;
strncpy ((char*)info->manufacturerID, MANUFACTURER_ID, 32);
- strncpy ((char*)info->label, TOKEN_LABEL, 32);
strncpy ((char*)info->model, TOKEN_MODEL, 16);
strncpy ((char*)info->serialNumber, TOKEN_SERIAL_NUMBER, 16);
info->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
@@ -458,8 +539,17 @@ sys_C_GetTokenInfo (CK_SLOT_ID id,
info->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
info->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
info->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
+
+ /* If too long, copy the last 32 characters into buffer */
+ path = basename (p11_token_get_path (token));
+ length = strlen (path);
+ if (length > sizeof (info->label))
+ length = sizeof (info->label);
+ memset (info->label, ' ', sizeof (info->label));
+ memcpy (info->label, path, length);
}
+ p11_unlock ();
p11_debug ("out: 0x%lx", rv);
return rv;
@@ -487,8 +577,8 @@ sys_C_GetMechanismInfo (CK_SLOT_ID id,
CK_MECHANISM_TYPE type,
CK_MECHANISM_INFO_PTR info)
{
- return_val_if_fail (id == SYSTEM_SLOT_ID, CKR_SLOT_ID_INVALID);
return_val_if_fail (info != NULL, CKR_ARGUMENTS_BAD);
+ return_val_if_fail (check_slot (id), CKR_SLOT_ID_INVALID);
return_val_if_reached (CKR_MECHANISM_INVALID);
}
@@ -498,7 +588,7 @@ sys_C_InitToken (CK_SLOT_ID id,
CK_ULONG pin_len,
CK_UTF8CHAR_PTR label)
{
- return_val_if_fail (id == SYSTEM_SLOT_ID, CKR_SLOT_ID_INVALID);
+ return_val_if_fail (check_slot (id), CKR_SLOT_ID_INVALID);
return_val_if_reached (CKR_TOKEN_WRITE_PROTECTED);
}
@@ -519,17 +609,19 @@ sys_C_OpenSession (CK_SLOT_ID id,
CK_SESSION_HANDLE_PTR handle)
{
p11_session *session;
+ p11_token *token;
CK_RV rv = CKR_OK;
- return_val_if_fail (id == SYSTEM_SLOT_ID, CKR_SLOT_ID_INVALID);
+ return_val_if_fail (check_slot (id), CKR_SLOT_ID_INVALID);
return_val_if_fail (handle != NULL, CKR_ARGUMENTS_BAD);
p11_debug ("in");
p11_lock ();
- if (!gl.sessions) {
- rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+ rv = lookup_slot_inlock (id, &token);
+ if (rv != CKR_OK) {
+ /* fail below */;
} else if (!(flags & CKF_SERIAL_SESSION)) {
rv = CKR_SESSION_PARALLEL_NOT_SUPPORTED;
@@ -538,7 +630,7 @@ sys_C_OpenSession (CK_SLOT_ID id,
rv = CKR_TOKEN_WRITE_PROTECTED;
} else {
- session = p11_session_new (gl.token);
+ session = p11_session_new (token);
if (p11_dict_set (gl.sessions, &session->handle, session)) {
rv = CKR_OK;
*handle = session->handle;
@@ -585,20 +677,23 @@ sys_C_CloseSession (CK_SESSION_HANDLE handle)
static CK_RV
sys_C_CloseAllSessions (CK_SLOT_ID id)
{
- CK_RV rv = CKR_OK;
-
- return_val_if_fail (id == SYSTEM_SLOT_ID, CKR_SLOT_ID_INVALID);
+ CK_SESSION_HANDLE *handle;
+ p11_session *session;
+ p11_token *token;
+ p11_dictiter iter;
+ CK_RV rv;
p11_debug ("in");
p11_lock ();
- if (!gl.sessions) {
- rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-
- } else {
- p11_dict_clear (gl.sessions);
- rv = CKR_OK;
+ rv = lookup_slot_inlock (id, &token);
+ if (rv == CKR_OK) {
+ p11_dict_iterate (gl.sessions, &iter);
+ while (p11_dict_next (&iter, (void **)&handle, (void **)&session)) {
+ if (session->token == token)
+ p11_dict_remove (gl.sessions, handle);
+ }
}
p11_unlock ();
@@ -624,6 +719,7 @@ static CK_RV
sys_C_GetSessionInfo (CK_SESSION_HANDLE handle,
CK_SESSION_INFO_PTR info)
{
+ p11_session *session;
CK_RV rv;
return_val_if_fail (info != NULL, CKR_ARGUMENTS_BAD);
@@ -632,17 +728,17 @@ sys_C_GetSessionInfo (CK_SESSION_HANDLE handle,
p11_lock ();
- rv = lookup_session (handle, NULL);
+ rv = lookup_session (handle, &session);
+ if (rv == CKR_OK) {
+ info->flags = CKF_SERIAL_SESSION;
+ info->state = CKS_RO_PUBLIC_SESSION;
+ info->slotID = p11_token_get_slot (session->token);
+ info->ulDeviceError = 0;
+ }
+
p11_unlock ();
- if (rv == CKR_OK) {
- info->flags = CKF_SERIAL_SESSION;
- info->slotID = SYSTEM_SLOT_ID;
- info->state = CKS_RO_PUBLIC_SESSION;
- info->ulDeviceError = 0;
- }
-
p11_debug ("out: 0x%lx", rv);
return rv;
@@ -951,11 +1047,11 @@ sys_C_FindObjectsInit (CK_SESSION_HANDLE handle,
/* Refresh from disk if this session hasn't yet */
if (rv == CKR_OK && want_token_objects && !session->loaded) {
session->loaded = CK_TRUE;
- p11_token_load (gl.token);
+ p11_token_load (session->token);
}
if (rv == CKR_OK) {
- objects = p11_token_objects (gl.token);
+ objects = p11_token_objects (session->token);
find = calloc (1, sizeof (FindObjects));
warn_if_fail (find != NULL);
diff --git a/trust/tests/frob-token.c b/trust/tests/frob-token.c
index 23856cf..976fb2b 100644
--- a/trust/tests/frob-token.c
+++ b/trust/tests/frob-token.c
@@ -48,11 +48,11 @@ main (int argc,
int count;
if (argc != 2) {
- fprintf (stderr, "usage: frob-token anchor:paths\n");
+ fprintf (stderr, "usage: frob-token path\n");
return 2;
}
- token = p11_token_new (argv[1]);
+ token = p11_token_new (1, argv[1]);
count = p11_token_load (token);
printf ("%d files loaded\n", count);
diff --git a/trust/tests/test-module.c b/trust/tests/test-module.c
index 52fbe03..d811f1d 100644
--- a/trust/tests/test-module.c
+++ b/trust/tests/test-module.c
@@ -49,10 +49,19 @@
#include "test-data.h"
#include "token.h"
+#include <assert.h>
+
+/*
+ * This is the number of input paths. Should match the
+ * paths below near :
+ *
+ * paths='%s'
+ */
+#define NUM_SLOTS 3
+
struct {
CK_FUNCTION_LIST *module;
- CK_SLOT_ID slot;
- CK_SESSION_HANDLE session;
+ CK_SLOT_ID slots[NUM_SLOTS];
} test;
static void
@@ -71,7 +80,7 @@ setup (CuTest *cu)
CuAssertTrue (cu, rv == CKR_OK);
memset (&args, 0, sizeof (args));
- paths = SRCDIR "/input:" SRCDIR "/files/cacert-ca.der";
+ paths = SRCDIR "/input:" SRCDIR "/files/cacert-ca.der:" SRCDIR "/files/testing-server.der";
if (asprintf (&arguments, "paths='%s'", paths) < 0)
CuAssertTrue (cu, false && "not reached");
args.pReserved = arguments;
@@ -82,13 +91,10 @@ setup (CuTest *cu)
free (arguments);
- count = 1;
- rv = test.module->C_GetSlotList (CK_TRUE, &test.slot, &count);
- CuAssertTrue (cu, rv == CKR_OK);
- CuAssertTrue (cu, count == 1);
-
- rv = test.module->C_OpenSession (test.slot, CKF_SERIAL_SESSION, NULL, NULL, &test.session);
+ count = NUM_SLOTS;
+ rv = test.module->C_GetSlotList (CK_TRUE, test.slots, &count);
CuAssertTrue (cu, rv == CKR_OK);
+ CuAssertTrue (cu, count == NUM_SLOTS);
}
static void
@@ -96,38 +102,238 @@ teardown (CuTest *cu)
{
CK_RV rv;
- rv = test.module->C_CloseSession (test.session);
- CuAssertTrue (cu, rv == CKR_OK);
-
rv = test.module->C_Finalize (NULL);
CuAssertTrue (cu, rv == CKR_OK);
memset (&test, 0, sizeof (test));
}
+static void
+test_get_slot_list (CuTest *cu)
+{
+ CK_SLOT_ID slots[NUM_SLOTS];
+ CK_ULONG count;
+ CK_RV rv;
+ int i;
+
+ setup (cu);
+
+ rv = test.module->C_GetSlotList (TRUE, NULL, &count);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+ CuAssertIntEquals (cu, NUM_SLOTS, count);
+
+ count = 1;
+ rv = test.module->C_GetSlotList (TRUE, slots, &count);
+ CuAssertIntEquals (cu, CKR_BUFFER_TOO_SMALL, rv);
+ CuAssertIntEquals (cu, NUM_SLOTS, count);
+
+ count = NUM_SLOTS;
+ memset (slots, 0, sizeof (slots));
+ rv = test.module->C_GetSlotList (TRUE, slots, &count);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+ CuAssertIntEquals (cu, NUM_SLOTS, count);
+
+ for (i = 0; i < NUM_SLOTS; i++)
+ CuAssertTrue (cu, slots[i] != 0);
+
+ teardown (cu);
+}
+
+static void
+test_get_slot_info (CuTest *cu)
+{
+ CK_SLOT_ID slots[NUM_SLOTS];
+ CK_SLOT_INFO info;
+ char description[64];
+ CK_ULONG count;
+ CK_RV rv;
+ int i;
+
+ /* These are the paths passed in in setup() */
+ const char *paths[] = {
+ SRCDIR "/input",
+ SRCDIR "/files/cacert-ca.der",
+ SRCDIR "/files/testing-server.der"
+ };
+
+ setup (cu);
+
+ count = NUM_SLOTS;
+ rv = test.module->C_GetSlotList (TRUE, slots, &count);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+ CuAssertIntEquals (cu, NUM_SLOTS, count);
+
+ for (i = 0; i < NUM_SLOTS; i++) {
+ rv = test.module->C_GetSlotInfo (slots[i], &info);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+
+ memset (description, ' ', sizeof (description));
+ assert (strlen (paths[i]) <= sizeof (description));
+ memcpy (description, paths[i], strlen (paths[i]));
+ CuAssertTrue (cu, memcmp (info.slotDescription, description, sizeof (description)) == 0);
+ }
+
+ teardown (cu);
+}
+
+static void
+test_get_token_info (CuTest *cu)
+{
+ CK_SLOT_ID slots[NUM_SLOTS];
+ CK_TOKEN_INFO info;
+ char label[32];
+ CK_ULONG count;
+ CK_RV rv;
+ int i;
+
+ /* These are the paths passed in in setup() */
+ const char *labels[] = {
+ "input",
+ "cacert-ca.der",
+ "testing-server.der"
+ };
+
+ setup (cu);
+
+ count = NUM_SLOTS;
+ rv = test.module->C_GetSlotList (TRUE, slots, &count);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+ CuAssertIntEquals (cu, NUM_SLOTS, count);
+
+ for (i = 0; i < NUM_SLOTS; i++) {
+ rv = test.module->C_GetTokenInfo (slots[i], &info);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+
+ memset (label, ' ', sizeof (label));
+ memcpy (label, labels[i], strlen (labels[i]));
+ CuAssertTrue (cu, memcmp (info.label, label, sizeof (label)) == 0);
+ }
+
+ teardown (cu);
+}
+
+static void
+test_get_session_info (CuTest *cu)
+{
+ CK_SLOT_ID slots[NUM_SLOTS];
+ CK_SESSION_HANDLE sessions[NUM_SLOTS];
+ CK_SESSION_INFO info;
+ CK_ULONG count;
+ CK_RV rv;
+ int i;
+
+ setup (cu);
+
+ count = NUM_SLOTS;
+ rv = test.module->C_GetSlotList (TRUE, slots, &count);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+ CuAssertIntEquals (cu, NUM_SLOTS, count);
+
+ /* Open two sessions with each token */
+ for (i = 0; i < NUM_SLOTS; i++) {
+ rv = test.module->C_OpenSession (slots[i], CKF_SERIAL_SESSION, NULL, NULL, &sessions[i]);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+
+ rv = test.module->C_GetSessionInfo (sessions[i], &info);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+
+ CuAssertIntEquals (cu, slots[i], info.slotID);
+ CuAssertIntEquals (cu, CKF_SERIAL_SESSION, info.flags);
+ }
+
+ teardown (cu);
+}
+
+static void
+test_close_all_sessions (CuTest *cu)
+{
+ CK_SLOT_ID slots[NUM_SLOTS];
+ CK_SESSION_HANDLE sessions[NUM_SLOTS][2];
+ CK_SESSION_INFO info;
+ CK_ULONG count;
+ CK_RV rv;
+ int i;
+
+ setup (cu);
+
+ count = NUM_SLOTS;
+ rv = test.module->C_GetSlotList (TRUE, slots, &count);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+ CuAssertIntEquals (cu, NUM_SLOTS, count);
+
+ /* Open two sessions with each token */
+ for (i = 0; i < NUM_SLOTS; i++) {
+ rv = test.module->C_OpenSession (slots[i], CKF_SERIAL_SESSION, NULL, NULL, &sessions[i][0]);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+
+ rv = test.module->C_GetSessionInfo (sessions[i][0], &info);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+
+ rv = test.module->C_OpenSession (slots[i], CKF_SERIAL_SESSION, NULL, NULL, &sessions[i][1]);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+
+ rv = test.module->C_GetSessionInfo (sessions[i][0], &info);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+ }
+
+ /* Close all the sessions on the first token */
+ rv = test.module->C_CloseAllSessions (slots[0]);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+
+ /* Those sessions should be closed */
+ rv = test.module->C_GetSessionInfo (sessions[0][0], &info);
+ CuAssertIntEquals (cu, CKR_SESSION_HANDLE_INVALID, rv);
+ rv = test.module->C_GetSessionInfo (sessions[0][1], &info);
+ CuAssertIntEquals (cu, CKR_SESSION_HANDLE_INVALID, rv);
+
+ /* Other sessions should still be open */
+ for (i = 1; i < NUM_SLOTS; i++) {
+ rv = test.module->C_GetSessionInfo (sessions[i][0], &info);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+ rv = test.module->C_GetSessionInfo (sessions[i][0], &info);
+ CuAssertIntEquals (cu, CKR_OK, rv);
+ }
+
+ teardown (cu);
+}
+
static CK_ULONG
find_objects (CuTest *cu,
CK_ATTRIBUTE *match,
+ CK_OBJECT_HANDLE *sessions,
CK_OBJECT_HANDLE *objects,
- CK_ULONG num_objects)
+ CK_ULONG max_objects)
{
+ CK_SESSION_HANDLE session;
CK_RV rv;
+ CK_ULONG found;
CK_ULONG count;
+ int i, j;
- count = p11_attrs_count (match);
+ found = 0;
+ for (i = 0; i < NUM_SLOTS; i++) {
+ rv = test.module->C_OpenSession (test.slots[i], CKF_SERIAL_SESSION, NULL, NULL, &session);
+ CuAssertTrue (cu, rv == CKR_OK);
- rv = test.module->C_FindObjectsInit (test.session, match, count);
- CuAssertTrue (cu, rv == CKR_OK);
- rv = test.module->C_FindObjects (test.session, objects, num_objects, &num_objects);
- CuAssertTrue (cu, rv == CKR_OK);
- rv = test.module->C_FindObjectsFinal (test.session);
- CuAssertTrue (cu, rv == CKR_OK);
+ rv = test.module->C_FindObjectsInit (session, match, p11_attrs_count (match));
+ CuAssertTrue (cu, rv == CKR_OK);
+ rv = test.module->C_FindObjects (session, objects + found, max_objects - found, &count);
+ CuAssertTrue (cu, rv == CKR_OK);
+ rv = test.module->C_FindObjectsFinal (session);
+ CuAssertTrue (cu, rv == CKR_OK);
- return num_objects;
+ for (j = found ; j < found + count; j++)
+ sessions[j] = session;
+ found += count;
+ }
+
+ assert (found < max_objects);
+ return found;
}
static void
check_trust_object_equiv (CuTest *cu,
+ CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE trust,
CK_ATTRIBUTE *cert)
{
@@ -150,7 +356,7 @@ check_trust_object_equiv (CuTest *cu,
{ CKA_INVALID, },
};
- rv = test.module->C_GetAttributeValue (test.session, trust, equiv, 6);
+ rv = test.module->C_GetAttributeValue (session, trust, equiv, 6);
CuAssertTrue (cu, rv == CKR_OK);
test_check_attrs (cu, equiv, cert);
@@ -158,6 +364,7 @@ check_trust_object_equiv (CuTest *cu,
static void
check_trust_object_hashes (CuTest *cu,
+ CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE trust,
CK_ATTRIBUTE *cert)
{
@@ -173,7 +380,7 @@ check_trust_object_hashes (CuTest *cu,
{ CKA_INVALID, },
};
- rv = test.module->C_GetAttributeValue (test.session, trust, hashes, 2);
+ rv = test.module->C_GetAttributeValue (session, trust, hashes, 2);
CuAssertTrue (cu, rv == CKR_OK);
value = p11_attrs_find (cert, CKA_VALUE);
@@ -193,6 +400,7 @@ check_has_trust_object (CuTest *cu,
CK_OBJECT_CLASS trust_object = CKO_NSS_TRUST;
CK_ATTRIBUTE klass = { CKA_CLASS, &trust_object, sizeof (trust_object) };
CK_OBJECT_HANDLE objects[2];
+ CK_SESSION_HANDLE sessions[2];
CK_ATTRIBUTE *match;
CK_ATTRIBUTE *attr;
CK_ULONG count;
@@ -201,15 +409,16 @@ check_has_trust_object (CuTest *cu,
CuAssertPtrNotNull (cu, attr);
match = p11_attrs_build (NULL, &klass, attr, NULL);
- count = find_objects (cu, match, objects, 2);
+ count = find_objects (cu, match, sessions, objects, 2);
CuAssertIntEquals (cu, 1, count);
- check_trust_object_equiv (cu, objects[0], cert);
- check_trust_object_hashes (cu, objects[0], cert);
+ check_trust_object_equiv (cu, sessions[0], objects[0], cert);
+ check_trust_object_hashes (cu, sessions[0], objects[0], cert);
}
static void
check_certificate (CuTest *cu,
+ CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE handle)
{
unsigned char label[4096]= { 0, };
@@ -249,7 +458,7 @@ check_certificate (CuTest *cu,
};
/* Note that we don't pass the CKA_INVALID attribute in */
- rv = test.module->C_GetAttributeValue (test.session, handle, attrs, 15);
+ rv = test.module->C_GetAttributeValue (session, handle, attrs, 15);
CuAssertTrue (cu, rv == CKR_OK);
/* If this is the cacert3 certificate, check its values */
@@ -270,7 +479,7 @@ check_certificate (CuTest *cu,
test_check_cacert3_ca (cu, attrs, NULL);
/* Get anchor specific attributes */
- rv = test.module->C_GetAttributeValue (test.session, handle, anchor, 1);
+ rv = test.module->C_GetAttributeValue (session, handle, anchor, 1);
CuAssertTrue (cu, rv == CKR_OK);
/* It lives in the trusted directory */
@@ -295,16 +504,17 @@ test_find_certificates (CuTest *cu)
};
CK_OBJECT_HANDLE objects[16];
+ CK_SESSION_HANDLE sessions[16];
CK_ULONG count;
CK_ULONG i;
setup (cu);
- count = find_objects (cu, match, objects, 16);
- CuAssertIntEquals (cu, 6, count);
+ count = find_objects (cu, match, sessions, objects, 16);
+ CuAssertIntEquals (cu, 7, count);
for (i = 0; i < count; i++)
- check_certificate (cu, objects[i]);
+ check_certificate (cu, sessions[i], objects[i]);
teardown (cu);
}
@@ -325,12 +535,14 @@ test_find_builtin (CuTest *cu)
};
CK_OBJECT_HANDLE objects[16];
+ CK_SESSION_HANDLE sessions[16];
CK_ULONG count;
setup (cu);
- count = find_objects (cu, match, objects, 16);
- CuAssertIntEquals (cu, 1, count);
+ /* One per token */
+ count = find_objects (cu, match, sessions, objects, 16);
+ CuAssertIntEquals (cu, NUM_SLOTS, count);
teardown (cu);
}
@@ -346,6 +558,11 @@ main (void)
p11_library_init ();
p11_debug_init ();
+ SUITE_ADD_TEST (suite, test_get_slot_list);
+ SUITE_ADD_TEST (suite, test_get_slot_info);
+ SUITE_ADD_TEST (suite, test_get_token_info);
+ SUITE_ADD_TEST (suite, test_get_session_info);
+ SUITE_ADD_TEST (suite, test_close_all_sessions);
SUITE_ADD_TEST (suite, test_find_certificates);
SUITE_ADD_TEST (suite, test_find_builtin);
diff --git a/trust/tests/test-session.c b/trust/tests/test-session.c
index e9031f2..6183e7c 100644
--- a/trust/tests/test-session.c
+++ b/trust/tests/test-session.c
@@ -53,7 +53,7 @@ struct {
static void
setup (CuTest *cu)
{
- test.token = p11_token_new ("");
+ test.token = p11_token_new (1, "/nonexistant");
CuAssertPtrNotNull (cu, test.token);
test.session = p11_session_new (test.token);
diff --git a/trust/tests/test-token.c b/trust/tests/test-token.c
index c566406..96f7a6c 100644
--- a/trust/tests/test-token.c
+++ b/trust/tests/test-token.c
@@ -51,9 +51,10 @@ struct {
} test;
static void
-setup (CuTest *cu)
+setup (CuTest *cu,
+ const char *path)
{
- test.token = p11_token_new (SRCDIR "/input:" SRCDIR "/files/self-server.der:" SRCDIR "/files/cacert-ca.der");
+ test.token = p11_token_new (333, path);
CuAssertPtrNotNull (cu, test.token);
}
@@ -70,10 +71,10 @@ test_token_load (CuTest *cu)
p11_dict *objects;
int count;
- setup (cu);
+ setup (cu, SRCDIR "/input");
count = p11_token_load (test.token);
- CuAssertIntEquals (cu, 7, count);
+ CuAssertIntEquals (cu, 6, count);
/* A certificate and trust object for each parsed object + builtin */
objects = p11_token_objects (test.token);
@@ -183,7 +184,7 @@ test_token_flags (CuTest *cu)
{ CKA_INVALID },
};
- setup (cu);
+ setup (cu, SRCDIR "/input");
if (p11_token_load (test.token) < 0)
CuFail (cu, "should not be reached");
@@ -197,6 +198,26 @@ test_token_flags (CuTest *cu)
teardown (cu);
}
+static void
+test_token_path (CuTest *cu)
+{
+ setup (cu, "/wheee");
+
+ CuAssertStrEquals (cu, "/wheee", p11_token_get_path (test.token));
+
+ teardown (cu);
+}
+
+static void
+test_token_slot (CuTest *cu)
+{
+ setup (cu, "/unneeded");
+
+ CuAssertIntEquals (cu, 333, p11_token_get_slot (test.token));
+
+ teardown (cu);
+}
+
int
main (void)
{
@@ -211,6 +232,8 @@ main (void)
SUITE_ADD_TEST (suite, test_token_load);
SUITE_ADD_TEST (suite, test_token_flags);
+ SUITE_ADD_TEST (suite, test_token_path);
+ SUITE_ADD_TEST (suite, test_token_slot);
CuSuiteRun (suite);
CuSuiteSummary (suite, output);
diff --git a/trust/token.c b/trust/token.c
index f96d865..39bca04 100644
--- a/trust/token.c
+++ b/trust/token.c
@@ -59,7 +59,8 @@
struct _p11_token {
p11_parser *parser;
p11_dict *objects;
- const char *paths;
+ const char *path;
+ CK_SLOT_ID slot;
int loaded;
};
@@ -209,43 +210,6 @@ loader_load_path (p11_token *token,
}
static int
-loader_load_paths (p11_token *token,
- const char *paths)
-{
- const char *pos;
- int total = 0;
- char *path;
- int ret;
-
- p11_debug ("loading paths: %s", paths);
-
- while (paths) {
- pos = strchr (paths, ':');
- if (pos == NULL) {
- path = strdup (paths);
- paths = NULL;
- } else {
- path = strndup (paths, pos - paths);
- paths = pos + 1;
- }
-
- return_val_if_fail (path != NULL, -1);
-
- if (path[0] != '\0') {
- /* We don't expect this to fail except for in strange circumstances */
- ret = loader_load_path (token, path);
- if (ret < 0)
- return_val_if_reached (-1);
- total += ret;
- }
-
- free (path);
- }
-
- return total;
-}
-
-static int
load_builtin_objects (p11_token *token)
{
CK_OBJECT_CLASS builtin = CKO_NSS_BUILTIN_ROOT_LIST;
@@ -425,7 +389,7 @@ p11_token_load (p11_token *token)
builtins = load_builtin_objects (token);
- count = loader_load_paths (token, token->paths);
+ count = loader_load_path (token, token->path);
return_val_if_fail (count >= 0, count);
return count + builtins;
@@ -449,7 +413,8 @@ p11_token_free (p11_token *token)
}
p11_token *
-p11_token_new (const char *paths)
+p11_token_new (CK_SLOT_ID slot,
+ const char *path)
{
p11_token *token;
@@ -464,8 +429,25 @@ p11_token_new (const char *paths)
free, p11_attrs_free);
return_val_if_fail (token->objects != NULL, NULL);
- token->paths = paths;
+ token->path = strdup (path);
+ return_val_if_fail (token->path != NULL, NULL);
+
+ token->slot = slot;
token->loaded = 0;
return token;
}
+
+const char *
+p11_token_get_path (p11_token *token)
+{
+ return_val_if_fail (token != NULL, NULL);
+ return token->path;
+}
+
+CK_SLOT_ID
+p11_token_get_slot (p11_token *token)
+{
+ return_val_if_fail (token != NULL, 0);
+ return token->slot;
+}
diff --git a/trust/token.h b/trust/token.h
index 0c53d32..599e982 100644
--- a/trust/token.h
+++ b/trust/token.h
@@ -36,10 +36,12 @@
#define P11_TOKEN_H_
#include "dict.h"
+#include "pkcs11.h"
typedef struct _p11_token p11_token;
-p11_token * p11_token_new (const char *paths);
+p11_token * p11_token_new (CK_SLOT_ID slot,
+ const char *path);
void p11_token_free (p11_token *token);
@@ -47,4 +49,8 @@ int p11_token_load (p11_token *token);
p11_dict * p11_token_objects (p11_token *token);
+const char * p11_token_get_path (p11_token *token);
+
+CK_SLOT_ID p11_token_get_slot (p11_token *token);
+
#endif /* P11_TOKEN_H_ */