diff options
author | Martin Willi <martin@revosec.ch> | 2010-07-15 12:22:36 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-08-04 09:26:20 +0200 |
commit | 36c852a08be2b4373bd62d7cfb1862d28e818505 (patch) | |
tree | 0ea437131fabb04662c3c45efb4031ea15265205 /src | |
parent | fe876b24d9ddd34194d35dff9f8ea5290e93ee5a (diff) | |
download | strongswan-36c852a08be2b4373bd62d7cfb1862d28e818505.tar.bz2 strongswan-36c852a08be2b4373bd62d7cfb1862d28e818505.tar.xz |
Added enumerator for PKCS#11 tokens
Diffstat (limited to 'src')
-rw-r--r-- | src/libstrongswan/plugins/pkcs11/pkcs11_creds.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs11/pkcs11_manager.c | 134 | ||||
-rw-r--r-- | src/libstrongswan/plugins/pkcs11/pkcs11_manager.h | 19 |
3 files changed, 140 insertions, 15 deletions
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c b/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c index 5f79775b9..978bb8103 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c @@ -279,7 +279,7 @@ pkcs11_creds_t *pkcs11_creds_create(pkcs11_library_t *p11, CK_SLOT_ID slot) if (!load_certificates(this)) { - free(this); + destroy(this); return NULL; } diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c index 2c2ebbdf1..2428b39de 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c @@ -58,8 +58,6 @@ struct private_pkcs11_manager_t { typedef struct { /* back reference to this */ private_pkcs11_manager_t *this; - /* friendly name */ - char *name; /* associated library path */ char *path; /* loaded library */ @@ -178,14 +176,14 @@ static void handle_slot(lib_entry_t *entry, CK_SLOT_ID slot) if (info.flags & CKF_TOKEN_PRESENT) { 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); entry->this->cb(entry->this->data, entry->lib, slot, TRUE); } else { 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); } } @@ -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) { DBG1(DBG_CFG, "module '%s' does not support hot-plugging, cancelled", - entry->name); + entry->lib->get_name(entry->lib)); return JOB_REQUEUE_NONE; } if (rv == CKR_CRYPTOKI_NOT_INITIALIZED) @@ -230,33 +228,130 @@ static void end_dispatch(lib_entry_t *entry) } /** + * 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 */ static void query_slots(lib_entry_t *entry) { - CK_ULONG token_count; + CK_ULONG count; CK_SLOT_ID_PTR slots; 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); - if (entry->lib->f->C_GetSlotList(TRUE, slots, &token_count) == CKR_OK) + for (i = 0; i < count; i++) { - for (i = 0; i < token_count; i++) - { - handle_slot(entry, slots[i]); - } + handle_slot(entry, slots[i]); } 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, private_pkcs11_manager_t *this) { this->libs->destroy_function(this->libs, (void*)lib_entry_destroy); free(this); + singleton = NULL; } /** @@ -272,6 +367,7 @@ pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb, INIT(this, .public = { + .create_token_enumerator = _create_token_enumerator, .destroy = _destroy, }, .libs = linked_list_create(), @@ -285,7 +381,6 @@ pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb, { INIT(entry, .this = this, - .name = module, ); 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); } enumerator->destroy(enumerator); + + singleton = this; + return &this->public; } + +/** + * See header + */ +pkcs11_manager_t *pkcs11_manager_get() +{ + return (pkcs11_manager_t*)singleton; +} diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.h b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.h index c0208234e..b80d67324 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.h +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.h @@ -45,6 +45,13 @@ typedef void (*pkcs11_manager_token_event_t)(void *data, pkcs11_library_t *p11, 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. */ void (*destroy)(pkcs11_manager_t *this); @@ -52,8 +59,20 @@ struct pkcs11_manager_t { /** * 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, 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_ @}*/ |