Added enumerator for PKCS#11 tokens
This commit is contained in:
@@ -279,7 +279,7 @@ pkcs11_creds_t *pkcs11_creds_create(pkcs11_library_t *p11, CK_SLOT_ID slot)
|
|||||||
|
|
||||||
if (!load_certificates(this))
|
if (!load_certificates(this))
|
||||||
{
|
{
|
||||||
free(this);
|
destroy(this);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,8 +58,6 @@ struct private_pkcs11_manager_t {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
/* back reference to this */
|
/* back reference to this */
|
||||||
private_pkcs11_manager_t *this;
|
private_pkcs11_manager_t *this;
|
||||||
/* friendly name */
|
|
||||||
char *name;
|
|
||||||
/* associated library path */
|
/* associated library path */
|
||||||
char *path;
|
char *path;
|
||||||
/* loaded library */
|
/* loaded library */
|
||||||
@@ -178,14 +176,14 @@ static void handle_slot(lib_entry_t *entry, CK_SLOT_ID slot)
|
|||||||
if (info.flags & CKF_TOKEN_PRESENT)
|
if (info.flags & CKF_TOKEN_PRESENT)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, " found token in slot '%s':%lu (%s)",
|
DBG1(DBG_CFG, " found token in slot '%s':%lu (%s)",
|
||||||
entry->name, slot, info.slotDescription);
|
entry->lib->get_name(entry->lib), slot, info.slotDescription);
|
||||||
handle_token(entry, slot);
|
handle_token(entry, slot);
|
||||||
entry->this->cb(entry->this->data, entry->lib, slot, TRUE);
|
entry->this->cb(entry->this->data, entry->lib, slot, TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "token removed from slot '%s':%lu (%s)",
|
DBG1(DBG_CFG, "token removed from slot '%s':%lu (%s)",
|
||||||
entry->name, slot, info.slotDescription);
|
entry->lib->get_name(entry->lib), slot, info.slotDescription);
|
||||||
entry->this->cb(entry->this->data, entry->lib, slot, FALSE);
|
entry->this->cb(entry->this->data, entry->lib, slot, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -205,7 +203,7 @@ static job_requeue_t dispatch_slot_events(lib_entry_t *entry)
|
|||||||
if (rv == CKR_FUNCTION_NOT_SUPPORTED || rv == CKR_NO_EVENT)
|
if (rv == CKR_FUNCTION_NOT_SUPPORTED || rv == CKR_NO_EVENT)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "module '%s' does not support hot-plugging, cancelled",
|
DBG1(DBG_CFG, "module '%s' does not support hot-plugging, cancelled",
|
||||||
entry->name);
|
entry->lib->get_name(entry->lib));
|
||||||
return JOB_REQUEUE_NONE;
|
return JOB_REQUEUE_NONE;
|
||||||
}
|
}
|
||||||
if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
|
if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
|
||||||
@@ -229,34 +227,131 @@ static void end_dispatch(lib_entry_t *entry)
|
|||||||
entry->job = NULL;
|
entry->job = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the slot list of a library
|
||||||
|
*/
|
||||||
|
static CK_SLOT_ID_PTR get_slot_list(pkcs11_library_t *p11, CK_ULONG *out)
|
||||||
|
{
|
||||||
|
CK_SLOT_ID_PTR slots;
|
||||||
|
CK_ULONG count;
|
||||||
|
CK_RV rv;
|
||||||
|
|
||||||
|
rv = p11->f->C_GetSlotList(TRUE, NULL, &count);
|
||||||
|
if (rv != CKR_OK)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "C_GetSlotList() failed: %N", ck_rv_names, rv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
slots = malloc(sizeof(CK_SLOT_ID) * count);
|
||||||
|
rv = p11->f->C_GetSlotList(TRUE, slots, &count);
|
||||||
|
if (rv != CKR_OK)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "C_GetSlotList() failed: %N", ck_rv_names, rv);
|
||||||
|
free(slots);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
*out = count;
|
||||||
|
return slots;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query the slots for tokens
|
* Query the slots for tokens
|
||||||
*/
|
*/
|
||||||
static void query_slots(lib_entry_t *entry)
|
static void query_slots(lib_entry_t *entry)
|
||||||
{
|
{
|
||||||
CK_ULONG token_count;
|
CK_ULONG count;
|
||||||
CK_SLOT_ID_PTR slots;
|
CK_SLOT_ID_PTR slots;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (entry->lib->f->C_GetSlotList(TRUE, NULL, &token_count) == CKR_OK)
|
slots = get_slot_list(entry->lib, &count);
|
||||||
|
if (slots)
|
||||||
{
|
{
|
||||||
slots = malloc(sizeof(CK_SLOT_ID) * token_count);
|
for (i = 0; i < count; i++)
|
||||||
if (entry->lib->f->C_GetSlotList(TRUE, slots, &token_count) == CKR_OK)
|
|
||||||
{
|
{
|
||||||
for (i = 0; i < token_count; i++)
|
handle_slot(entry, slots[i]);
|
||||||
{
|
|
||||||
handle_slot(entry, slots[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
free(slots);
|
free(slots);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token enumerator
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/* implements enumerator */
|
||||||
|
enumerator_t public;
|
||||||
|
/* inner enumerator over PKCS#11 libraries */
|
||||||
|
enumerator_t *inner;
|
||||||
|
/* active library entry */
|
||||||
|
lib_entry_t *entry;
|
||||||
|
/* slot list with tokens */
|
||||||
|
CK_SLOT_ID_PTR slots;
|
||||||
|
/* number of slots */
|
||||||
|
CK_ULONG count;
|
||||||
|
/* current slot */
|
||||||
|
int current;
|
||||||
|
} token_enumerator_t;
|
||||||
|
|
||||||
|
METHOD(enumerator_t, enumerate_token, bool,
|
||||||
|
token_enumerator_t *this, pkcs11_library_t **out, CK_SLOT_ID *slot)
|
||||||
|
{
|
||||||
|
if (this->current >= this->count)
|
||||||
|
{
|
||||||
|
free(this->slots);
|
||||||
|
this->slots = NULL;
|
||||||
|
this->current = 0;
|
||||||
|
}
|
||||||
|
while (!this->slots)
|
||||||
|
{
|
||||||
|
if (!this->inner->enumerate(this->inner, &this->entry))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
this->slots = get_slot_list(this->entry->lib, &this->count);
|
||||||
|
}
|
||||||
|
*out = this->entry->lib;
|
||||||
|
*slot = this->slots[this->current++];
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(enumerator_t, destroy_token, void,
|
||||||
|
token_enumerator_t *this)
|
||||||
|
{
|
||||||
|
this->inner->destroy(this->inner);
|
||||||
|
free(this->slots);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pkcs11_manager_t, create_token_enumerator, enumerator_t*,
|
||||||
|
private_pkcs11_manager_t *this)
|
||||||
|
{
|
||||||
|
token_enumerator_t *enumerator;
|
||||||
|
|
||||||
|
INIT(enumerator,
|
||||||
|
.public = {
|
||||||
|
.enumerate = (void*)_enumerate_token,
|
||||||
|
.destroy = _destroy_token,
|
||||||
|
},
|
||||||
|
.inner = this->libs->create_enumerator(this->libs),
|
||||||
|
);
|
||||||
|
return &enumerator->public;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singleton instance
|
||||||
|
*/
|
||||||
|
static private_pkcs11_manager_t *singleton = NULL;
|
||||||
|
|
||||||
METHOD(pkcs11_manager_t, destroy, void,
|
METHOD(pkcs11_manager_t, destroy, void,
|
||||||
private_pkcs11_manager_t *this)
|
private_pkcs11_manager_t *this)
|
||||||
{
|
{
|
||||||
this->libs->destroy_function(this->libs, (void*)lib_entry_destroy);
|
this->libs->destroy_function(this->libs, (void*)lib_entry_destroy);
|
||||||
free(this);
|
free(this);
|
||||||
|
singleton = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -272,6 +367,7 @@ pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb,
|
|||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
|
.create_token_enumerator = _create_token_enumerator,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.libs = linked_list_create(),
|
.libs = linked_list_create(),
|
||||||
@@ -285,7 +381,6 @@ pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb,
|
|||||||
{
|
{
|
||||||
INIT(entry,
|
INIT(entry,
|
||||||
.this = this,
|
.this = this,
|
||||||
.name = module,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
entry->path = lib->settings->get_str(lib->settings,
|
entry->path = lib->settings->get_str(lib->settings,
|
||||||
@@ -310,5 +405,16 @@ pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb,
|
|||||||
charon->processor->queue_job(charon->processor, (job_t*)entry->job);
|
charon->processor->queue_job(charon->processor, (job_t*)entry->job);
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
singleton = this;
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header
|
||||||
|
*/
|
||||||
|
pkcs11_manager_t *pkcs11_manager_get()
|
||||||
|
{
|
||||||
|
return (pkcs11_manager_t*)singleton;
|
||||||
|
}
|
||||||
|
|||||||
@@ -44,6 +44,13 @@ typedef void (*pkcs11_manager_token_event_t)(void *data, pkcs11_library_t *p11,
|
|||||||
*/
|
*/
|
||||||
struct pkcs11_manager_t {
|
struct pkcs11_manager_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an enumerator over all tokens.
|
||||||
|
*
|
||||||
|
* @return enumerator over (pkcs11_library_t*,CK_SLOT_ID)
|
||||||
|
*/
|
||||||
|
enumerator_t* (*create_token_enumerator)(pkcs11_manager_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a pkcs11_manager_t.
|
* Destroy a pkcs11_manager_t.
|
||||||
*/
|
*/
|
||||||
@@ -52,8 +59,20 @@ struct pkcs11_manager_t {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a pkcs11_manager instance.
|
* Create a pkcs11_manager instance.
|
||||||
|
*
|
||||||
|
* @param cb token event callback function
|
||||||
|
* @param data user data to pass to token event callback
|
||||||
|
* @return instance
|
||||||
*/
|
*/
|
||||||
pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb,
|
pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the singleton instance of the manager
|
||||||
|
*
|
||||||
|
* @return instance, NULL if none available
|
||||||
|
*/
|
||||||
|
pkcs11_manager_t *pkcs11_manager_get();
|
||||||
|
|
||||||
#endif /** PKCS11_MANAGER_H_ @}*/
|
#endif /** PKCS11_MANAGER_H_ @}*/
|
||||||
|
|||||||
Reference in New Issue
Block a user