Iterate over all slots, not just the first/selected one.

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17591 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2006-05-29 09:24:47 +00:00
parent 7f6b59890e
commit a99e6303d5

View File

@@ -38,24 +38,24 @@ RCSID("$Id$");
#include "pkcs11u.h"
#include "pkcs11.h"
struct p11_slot {
int flags;
#define P11_SESSION 1
#define P11_LOGIN_REQ 2
#define P11_LOGIN_DONE 4
CK_SLOT_ID id;
CK_BBOOL token;
char *name;
hx509_certs certs;
char *pin;
};
struct p11_module {
void *dl_handle;
CK_FUNCTION_LIST_PTR funcs;
CK_ULONG num_slots;
CK_ULONG selected_slot;
unsigned int refcount;
/* slot info */
struct p11_slot {
int flags;
#define P11_SESSION 1
#define P11_LOGIN_REQ 2
#define P11_LOGIN_DONE 4
CK_SLOT_ID id;
CK_BBOOL token;
char *name;
hx509_certs certs;
char *pin;
} slot;
struct p11_slot *slot;
};
#define P11FUNC(module,f,args) (*(module)->funcs->C_##f)args
@@ -69,6 +69,13 @@ static int p11_put_session(struct p11_module *,
CK_SESSION_HANDLE);
static void p11_release_module(struct p11_module *);
static int p11_list_keys(hx509_context,
struct p11_module *,
struct p11_slot *,
CK_SESSION_HANDLE,
hx509_lock,
hx509_certs *);
/*
*
*/
@@ -218,17 +225,28 @@ static const RSA_METHOD rsa_pkcs1_method = {
*/
static int
p11_init_slot(struct p11_module *p, CK_SLOT_ID id, struct p11_slot *slot)
p11_init_slot(hx509_context context,
struct p11_module *p,
hx509_lock lock,
CK_SLOT_ID id,
int num,
struct p11_slot *slot)
{
CK_SESSION_HANDLE session;
CK_SLOT_INFO slot_info;
CK_TOKEN_INFO token_info;
int ret, i;
slot->certs = NULL;
slot->id = id;
ret = P11FUNC(p, GetSlotInfo, (slot->id, &slot_info));
if (ret)
return ret;
if (ret) {
hx509_set_error_string(context, 0, EINVAL,
"Failed to init PKCS11 slot %d",
num);
return EINVAL;
}
for (i = sizeof(slot_info.slotDescription) - 1; i > 0; i--) {
char c = slot_info.slotDescription[i];
@@ -246,13 +264,27 @@ p11_init_slot(struct p11_module *p, CK_SLOT_ID id, struct p11_slot *slot)
}
ret = P11FUNC(p, GetTokenInfo, (slot->id, &token_info));
if (ret)
return ret;
if (ret) {
hx509_set_error_string(context, 0, EINVAL,
"Failed to init PKCS11 slot %d",
num);
return EINVAL;
}
if (token_info.flags & CKF_LOGIN_REQUIRED)
slot->flags |= P11_LOGIN_REQ;
return 0;
ret = p11_get_session(p, slot, lock, &session);
if (ret) {
hx509_set_error_string(context, 0, ret,
"Failed to get session PKCS11 slot %d",
num);
return ret;
}
ret = p11_list_keys(context, p, slot, session, lock, &slot->certs);
p11_put_session(p, slot, session);
return ret;
}
static int
@@ -669,7 +701,6 @@ p11_init(hx509_context context,
return ENOMEM;
}
p->selected_slot = 0;
p->refcount = 1;
str = strchr(list, ',');
@@ -680,8 +711,10 @@ p11_init(hx509_context context,
strnext = strchr(str, ',');
if (strnext)
*strnext++ = '\0';
#if 0
if (strncasecmp(str, "slot=", 5) == 0)
p->selected_slot = atoi(str + 5);
#endif
str = strnext;
}
@@ -727,18 +760,17 @@ p11_init(hx509_context context,
goto out;
}
if (p->selected_slot >= p->num_slots) {
if (p->num_slots == 0) {
hx509_set_error_string(context, 0, EINVAL,
"Selected PKCS11 slot (%d) larger "
"then maximum slot (%d)",
p->selected_slot, p->num_slots);
"Select PKCS11 module have no slots");
ret = EINVAL;
goto out;
}
}
{
CK_SESSION_HANDLE session;
CK_SLOT_ID_PTR slot_ids;
int i;
slot_ids = malloc(p->num_slots * sizeof(*slot_ids));
if (slot_ids == NULL) {
@@ -757,25 +789,24 @@ p11_init(hx509_context context,
goto out;
}
ret = p11_init_slot(p, slot_ids[p->selected_slot], &p->slot);
p->slot = calloc(p->num_slots, sizeof(p->slot[0]));
if (p->slot == NULL) {
free(slot_ids);
hx509_set_error_string(context, 0, ENOMEM,
"Failed to get memory for slot-list");
ret = ENOMEM;
goto out;
}
for (i = 0; i < p->num_slots; i++) {
ret = p11_init_slot(context, p, lock, slot_ids[i], i, &p->slot[i]);
if (ret)
break;
}
free(slot_ids);
if (ret) {
hx509_set_error_string(context, 0, ret,
"Failed to init PKCS11 slot %d",
p->selected_slot);
goto out;
}
ret = p11_get_session(p, &p->slot, lock, &session);
if (ret) {
hx509_set_error_string(context, 0, ret,
"Failed to get session PKCS11 slot %d",
p->selected_slot);
goto out;
}
ret = p11_list_keys(context, p, &p->slot, session,
NULL, &p->slot.certs);
p11_put_session(p, &p->slot, session);
}
*data = p;
@@ -789,6 +820,7 @@ p11_init(hx509_context context,
static void
p11_release_module(struct p11_module *p)
{
int i;
if (p->refcount == 0)
_hx509_abort("pkcs11 refcount to low");
if (--p->refcount > 0)
@@ -796,11 +828,17 @@ p11_release_module(struct p11_module *p)
if (p->dl_handle)
dlclose(p->dl_handle);
if (p->slot.name)
free(p->slot.name);
if (p->slot.pin) {
memset(p->slot.pin, 0, strlen(p->slot.pin));
free(p->slot.pin);
for (i = 0; i < p->num_slots; i++) {
if (p->slot[i].certs)
hx509_certs_free(&p->slot[i].certs);
if (p->slot[i].name)
free(p->slot[i].name);
if (p->slot[i].pin) {
memset(p->slot[i].pin, 0, strlen(p->slot[i].pin));
free(p->slot[i].pin);
}
free(p->slot);
}
memset(p, 0, sizeof(*p));
free(p);
@@ -813,28 +851,68 @@ p11_free(hx509_certs certs, void *data)
return 0;
}
struct p11_cursor {
hx509_certs certs;
void *cursor;
};
static int
p11_iter_start(hx509_context context,
hx509_certs certs, void *data, void **cursor)
{
struct p11_module *p = data;
return hx509_certs_start_seq(context, p->slot.certs, cursor);
struct p11_cursor *c;
int ret, i;
c = malloc(sizeof(*c));
if (c == NULL) {
hx509_clear_error_string(context);
return ENOMEM;
}
ret = hx509_certs_init(context, "MEMORY:pkcs11-iter", 0, NULL, &c->certs);
if (ret) {
free(c);
return ret;
}
for (i = 0 ; i < p->num_slots; i++) {
ret = hx509_certs_merge(context, c->certs, p->slot[i].certs);
if (ret) {
hx509_certs_free(&c->certs);
free(c);
return ret;
}
}
ret = hx509_certs_start_seq(context, c->certs, &c->cursor);
if (ret) {
hx509_certs_free(&c->certs);
free(c);
return 0;
}
*cursor = c;
return 0;
}
static int
p11_iter(hx509_context context,
hx509_certs certs, void *data, void *cursor, hx509_cert *cert)
{
struct p11_module *p = data;
return hx509_certs_next_cert(context, p->slot.certs, cursor, cert);
struct p11_cursor *c = cursor;
return hx509_certs_next_cert(context, c->certs, c->cursor, cert);
}
static int
p11_iter_end(hx509_context context,
hx509_certs certs, void *data, void *cursor)
{
struct p11_module *p = data;
return hx509_certs_end_seq(context, p->slot.certs, cursor);
struct p11_cursor *c = cursor;
int ret;
ret = hx509_certs_end_seq(context, c->certs, c->cursor);
hx509_certs_free(&c->certs);
free(c);
return ret;
}
static struct hx509_keyset_ops keyset_pkcs11 = {