diff options
Diffstat (limited to 'p11-kit/iter.c')
-rw-r--r-- | p11-kit/iter.c | 983 |
1 files changed, 0 insertions, 983 deletions
diff --git a/p11-kit/iter.c b/p11-kit/iter.c deleted file mode 100644 index 4caf5d7..0000000 --- a/p11-kit/iter.c +++ /dev/null @@ -1,983 +0,0 @@ -/* - * Copyright (C) 2013 Red Hat Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above - * copyright notice, this list of conditions and the - * following disclaimer. - * * Redistributions in binary form must reproduce the - * above copyright notice, this list of conditions and - * the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * * The names of contributors to this software may not be - * used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * Author: Stef Walter <stefw@redhat.com> - */ - -#include "config.h" - -#include "array.h" -#include "attrs.h" -#include "debug.h" -#include "iter.h" -#include "pin.h" -#include "private.h" - -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -typedef struct _Callback { - p11_kit_iter_callback func; - void *callback_data; - p11_kit_destroyer destroyer; - struct _Callback *next; -} Callback; - -/** - * P11KitIter: - * - * Used to iterate over PKCS\#11 objects. - */ -struct p11_kit_iter { - - /* Iterator matching data */ - CK_INFO match_module; - CK_SLOT_INFO match_slot; - CK_TOKEN_INFO match_token; - CK_ATTRIBUTE *match_attrs; - CK_SLOT_ID match_slot_id; - Callback *callbacks; - - /* The input modules */ - p11_array *modules; - - /* The results of C_GetSlotList */ - CK_SLOT_ID *slots; - CK_ULONG num_slots; - CK_ULONG saw_slots; - - /* The results of C_FindObjects */ - CK_OBJECT_HANDLE *objects; - CK_ULONG max_objects; - CK_ULONG num_objects; - CK_ULONG saw_objects; - - /* The current iteration */ - CK_FUNCTION_LIST_PTR module; - CK_SLOT_ID slot; - CK_SESSION_HANDLE session; - CK_OBJECT_HANDLE object; - CK_SLOT_INFO slot_info; - CK_TOKEN_INFO token_info; - - /* And various flags */ - unsigned int searching : 1; - unsigned int searched : 1; - unsigned int iterating : 1; - unsigned int match_nothing : 1; - unsigned int keep_session : 1; - unsigned int preload_results : 1; - unsigned int want_writable : 1; -}; - -/** - * P11KitIterBehavior: - * @P11_KIT_ITER_BUSY_SESSIONS: Allow the iterator's sessions to be - * in a busy state when the iterator returns an object. - * @P11_KIT_ITER_WANT_WRITABLE: Try to open read-write sessions when - * iterating over obojects. - * - * Various flags controlling the behavior of the iterator. - */ - -/** - * p11_kit_iter_new: - * @uri: (allow-none): a PKCS\#11 URI to filter on, or %NULL - * @behavior: various behavior flags for iterator - * - * Create a new PKCS\#11 iterator for iterating over objects. Only - * objects that match the @uri will be returned by the iterator. - * Relevant information in @uri is copied, and you need not keep - * @uri around. - * - * If no @uri is specified then the iterator will iterate over all - * objects, unless otherwise filtered. - * - * Returns: (transfer full): a new iterator, which should be freed - * with p11_kit_iter_free() - */ -P11KitIter * -p11_kit_iter_new (P11KitUri *uri, - P11KitIterBehavior behavior) -{ - P11KitIter *iter; - - iter = calloc (1, sizeof (P11KitIter)); - return_val_if_fail (iter != NULL, NULL); - - iter->modules = p11_array_new (NULL); - return_val_if_fail (iter->modules != NULL, NULL); - - iter->want_writable = !!(behavior & P11_KIT_ITER_WANT_WRITABLE); - iter->preload_results = !(behavior & P11_KIT_ITER_BUSY_SESSIONS); - - p11_kit_iter_set_uri (iter, uri); - return iter; -} - -/** - * p11_kit_iter_set_uri: - * @iter: the iterator - * @uri: (allow-none): a PKCS\#11 URI to filter on, or %NULL - * - * Set the PKCS\#11 uri for iterator. Only - * objects that match the @uri will be returned by the iterator. - * Relevant information in @uri is copied, and you need not keep - * @uri around. - * - * If no @uri is specified then the iterator will iterate over all - * objects, unless otherwise filtered. - * - * This function should be called at most once, and should be - * called before iterating begins. - * - */ -void -p11_kit_iter_set_uri (P11KitIter *iter, - P11KitUri *uri) -{ - CK_ATTRIBUTE *attrs; - CK_TOKEN_INFO *tinfo; - CK_SLOT_INFO *sinfo; - CK_INFO *minfo; - CK_ULONG count; - - return_if_fail (iter != NULL); - - if (uri != NULL) { - - if (p11_kit_uri_any_unrecognized (uri)) { - iter->match_nothing = 1; - - } else { - attrs = p11_kit_uri_get_attributes (uri, &count); - iter->match_attrs = p11_attrs_buildn (NULL, attrs, count); - - iter->match_slot_id = p11_kit_uri_get_slot_id (uri); - - minfo = p11_kit_uri_get_module_info (uri); - if (minfo != NULL) - memcpy (&iter->match_module, minfo, sizeof (CK_INFO)); - - sinfo = p11_kit_uri_get_slot_info (uri); - if (sinfo != NULL) - memcpy (&iter->match_slot, sinfo, sizeof (CK_SLOT_INFO)); - - tinfo = p11_kit_uri_get_token_info (uri); - if (tinfo != NULL) - memcpy (&iter->match_token, tinfo, sizeof (CK_TOKEN_INFO)); - } - } else { - /* Match any module version number and slot ID */ - memset (&iter->match_module, 0, sizeof (iter->match_module)); - iter->match_module.libraryVersion.major = (CK_BYTE)-1; - iter->match_module.libraryVersion.minor = (CK_BYTE)-1; - iter->match_slot_id = (CK_SLOT_ID)-1; - } -} - -/** - * p11_kit_destroyer: - * @data: data to destroy - * - * A callback called to free a resource. - */ - -/** - * p11_kit_iter_callback: - * @iter: the iterator - * @matches: (out): whether to match the current object - * @data: callback data - * - * A callback setup with p11_kit_iter_add_callback(). This callback is - * called for each object iterated. - * - * If the callback sets @matches to CK_FALSE, then this object is - * skipped and not matched by p11_kit_iter_next(). If you return - * anything but CKR_OK, then the iteration is stopped, and - * p11_kit_iter_next() returns the result code. - * - * Returns: CKR_OK to continue iterating, CKR_CANCEL to stop, or - * anything else to fail - */ - -/** - * p11_kit_iter_add_callback: - * @iter: the iterator - * @callback: a function to call for each iteration - * @callback_data: (allow-none): data to pass to the function - * @callback_destroy: (allow-none): used to cleanup the data - * - * Adds a callback to the iterator which will be called each time - * that an object is iterated. - * - * These callbacks can also perform filtering. If any callback - * indicates through it's <literal>matches</literal> argument that - * the object should not match, then that object will not be iterated - * as far as p11_kit_iter_next() is concerned. - * - * The callbacks will be called with the <literal>matches</literal> - * set to <literal>CK_TRUE</literal> and it's up to filters to change - * it to <literal>CK_FALSE</literal> when necessary. - */ -void -p11_kit_iter_add_callback (P11KitIter *iter, - p11_kit_iter_callback callback, - void *callback_data, - p11_kit_destroyer callback_destroy) -{ - Callback *cb; - - return_if_fail (iter != NULL); - return_if_fail (callback != NULL); - - cb = calloc (1, sizeof (Callback)); - return_if_fail (cb != NULL); - - cb->func = callback; - cb->destroyer = callback_destroy; - cb->callback_data = callback_data; - cb->next = iter->callbacks; - iter->callbacks = cb; -} - -/** - * p11_kit_iter_add_filter: - * @iter: the iterator - * @matching: (array length=count): the attributes that the objects should match - * @count: the number of attributes - * - * Add a filter to limit the objects that the iterator iterates over. - * - * Only objects matching the passed in attributes will be iterated. - * This function can be called multiple times. - * - * The @matching attributes are copied. - */ -void -p11_kit_iter_add_filter (P11KitIter *iter, - CK_ATTRIBUTE *matching, - CK_ULONG count) -{ - return_if_fail (iter != NULL); - return_if_fail (!iter->iterating); - - iter->match_attrs = p11_attrs_buildn (iter->match_attrs, matching, count); - return_if_fail (iter->match_attrs != NULL); -} - -static void -finish_object (P11KitIter *iter) -{ - iter->object = 0; -} - -static void -finish_slot (P11KitIter *iter) -{ - if (iter->session && !iter->keep_session) { - assert (iter->module != NULL); - (iter->module->C_CloseSession) (iter->session); - } - - iter->keep_session = 0; - iter->session = 0; - iter->searched = 0; - iter->searching = 0; - iter->slot = 0; -} - -static void -finish_module (P11KitIter *iter) -{ - iter->num_slots = 0; - iter->saw_slots = 0; - iter->module = NULL; -} - -static CK_RV -finish_iterating (P11KitIter *iter, - CK_RV rv) -{ - finish_object (iter); - finish_slot (iter); - finish_module (iter); - p11_array_clear (iter->modules); - - iter->iterating = 0; - return rv; -} - -/** - * p11_kit_iter_begin: - * @iter: the iterator - * @modules: (array zero-terminated=1): null-terminated list of - * modules to iterate over - * - * Begin iterating PKCS\#11 objects in the given @modules. - * - * The @modules arguments should be a null-terminated list of - * pointers to the modules' PKCS\#11 function pointers. - * - * For each module, all initialized slots will be iterated over, - * having sessions opened for each of them in turn, and searched - * for objects matching the search criteria. - */ -void -p11_kit_iter_begin (P11KitIter *iter, - CK_FUNCTION_LIST_PTR *modules) -{ - int i; - - return_if_fail (modules != NULL); - - finish_iterating (iter, CKR_OK); - - /* Use this module */ - for (i = 0; modules[i] != NULL; i++) { - if (!p11_array_push (iter->modules, modules[i])) - return_if_reached (); - } - - iter->iterating = 1; - iter->searched = 1; -} - -/** - * p11_kit_iter_begin_with: - * @iter: the iterator - * @module: the module to iterate over - * @slot: (allow-none): the slot to iterate objects in, or zero - * @session: (allow-none): the session to search for objects on, or zero - * - * Begin iterating PKCS\#11 objects in the given @module. - * - * If @slot is non-zero then the iteration will be limited to that - * slot. - * - * If @session is non-zero then the iteration will be limited to - * objects visible through that session, which implies that they - * are also limited to the slot which the session was opened for. - */ -void -p11_kit_iter_begin_with (P11KitIter *iter, - CK_FUNCTION_LIST_PTR module, - CK_SLOT_ID slot, - CK_SESSION_HANDLE session) -{ - CK_SESSION_INFO info; - CK_RV rv; - - finish_iterating (iter, CKR_OK); - - return_if_fail (module != NULL); - - if (session != 0) { - /* - * A currently active session. Initialize as if we're ready - * to search using this session. - */ - - /* If we have a session, but no slot, then look it up */ - if (slot == 0) { - assert (module != NULL); - rv = (module->C_GetSessionInfo) (session, &info); - if (rv == CKR_OK) - slot = info.slotID; - } - - /* So initialize as if we're ready to search */ - iter->session = session; - iter->slot = slot; - iter->module = module; - iter->keep_session = 1; - - } else if (slot != 0) { - - /* - * Limit to this slot. Initialize as if we're ready to use the - * slot from the slots list. - */ - - iter->module = module; - iter->slots = realloc (iter->slots, sizeof (CK_SLOT_ID)); - return_if_fail (iter->slots != NULL); - iter->slots[0] = slot; - iter->num_slots = 1; - iter->searched = 1; - - } else { - - /* - * Limit to this module. Initialize as if we're ready to use - * the module from the modules array. - */ - - assert (module != NULL); - p11_array_push (iter->modules, module); - iter->session = 0; - iter->slot = 0; - iter->searched = 1; - } - - iter->iterating = 1; -} - -static CK_RV -call_all_filters (P11KitIter *iter, - CK_BBOOL *matches) -{ - Callback *cb; - CK_RV rv; - - *matches = CK_TRUE; - - for (cb = iter->callbacks; cb != NULL; cb = cb->next) { - rv = (cb->func) (iter, matches, cb->callback_data); - if (rv != CKR_OK || !*matches) - return rv; - } - - return CKR_OK; -} - -static CK_RV -move_next_session (P11KitIter *iter) -{ - CK_ULONG session_flags; - CK_ULONG num_slots; - CK_INFO minfo; - CK_RV rv; - - finish_slot (iter); - - /* If we have no more slots, then move to next module */ - while (iter->saw_slots >= iter->num_slots) { - finish_module (iter); - - /* Iter is finished */ - if (iter->modules->num == 0) - return finish_iterating (iter, CKR_CANCEL); - - iter->module = iter->modules->elem[0]; - p11_array_remove (iter->modules, 0); - - /* Skip module if it doesn't match uri */ - assert (iter->module != NULL); - rv = (iter->module->C_GetInfo) (&minfo); - if (rv != CKR_OK || !p11_match_uri_module_info (&iter->match_module, &minfo)) - continue; - - rv = (iter->module->C_GetSlotList) (CK_TRUE, NULL, &num_slots); - if (rv != CKR_OK) - return finish_iterating (iter, rv); - - iter->slots = realloc (iter->slots, sizeof (CK_SLOT_ID) * (num_slots + 1)); - return_val_if_fail (iter->slots != NULL, CKR_HOST_MEMORY); - - rv = (iter->module->C_GetSlotList) (CK_TRUE, iter->slots, &num_slots); - if (rv != CKR_OK) - return finish_iterating (iter, rv); - - iter->num_slots = num_slots; - assert (iter->saw_slots == 0); - } - - /* Move to the next slot, and open a session on it */ - while (iter->saw_slots < iter->num_slots) { - iter->slot = iter->slots[iter->saw_slots++]; - - assert (iter->module != NULL); - if (iter->match_slot_id != (CK_SLOT_ID)-1 && iter->slot != iter->match_slot_id) - continue; - rv = (iter->module->C_GetSlotInfo) (iter->slot, &iter->slot_info); - if (rv != CKR_OK || !p11_match_uri_slot_info (&iter->match_slot, &iter->slot_info)) - continue; - rv = (iter->module->C_GetTokenInfo) (iter->slot, &iter->token_info); - if (rv != CKR_OK || !p11_match_uri_token_info (&iter->match_token, &iter->token_info)) - continue; - - session_flags = CKF_SERIAL_SESSION; - - /* Skip if the read/write on a read-only token */ - if (iter->want_writable && (iter->token_info.flags & CKF_WRITE_PROTECTED) == 0) - session_flags |= CKF_RW_SESSION; - - rv = (iter->module->C_OpenSession) (iter->slot, session_flags, - NULL, NULL, &iter->session); - if (rv != CKR_OK) - return finish_iterating (iter, rv); - - if (iter->session != 0) - return CKR_OK; - } - - /* Otherwise try again */ - return move_next_session (iter); -} - -/** - * p11_kit_iter_next: - * @iter: the iterator - * - * Iterate to the next matching object. - * - * To access the object, session and so on, use the p11_kit_iter_get_object(), - * p11_kit_iter_get_session(), and p11_kit_iter_get_module() functions. - * - * This call must only be called after either p11_kit_iter_begin() - * or p11_kit_iter_begin_with() have been called. - * - * Objects which are skipped by callbacks will not be returned here - * as matching objects. - * - * Returns: CKR_OK if an object matched, CKR_CANCEL if no more objects, or another error - */ -CK_RV -p11_kit_iter_next (P11KitIter *iter) -{ - CK_ULONG batch; - CK_ULONG count; - CK_BBOOL matches; - CK_RV rv; - - return_val_if_fail (iter->iterating, CKR_OPERATION_NOT_INITIALIZED); - - iter->object = 0; - - if (iter->match_nothing) - return finish_iterating (iter, CKR_CANCEL); - - /* - * If we have outstanding objects, then iterate one through those - * Note that we pass each object through the filters, and only - * assume it's iterated if it matches - */ - while (iter->saw_objects < iter->num_objects) { - iter->object = iter->objects[iter->saw_objects++]; - - rv = call_all_filters (iter, &matches); - if (rv != CKR_OK) - return finish_iterating (iter, rv); - - if (matches) - return CKR_OK; - } - - /* If we have finished searching then move to next session */ - if (iter->searched) { - rv = move_next_session (iter); - if (rv != CKR_OK) - return finish_iterating (iter, rv); - } - - /* Ready to start searching */ - if (!iter->searching && !iter->searched) { - count = p11_attrs_count (iter->match_attrs); - rv = (iter->module->C_FindObjectsInit) (iter->session, iter->match_attrs, count); - if (rv != CKR_OK) - return finish_iterating (iter, rv); - iter->searching = 1; - iter->searched = 0; - } - - /* If we have searched on this session then try to continue */ - if (iter->searching) { - assert (iter->module != NULL); - assert (iter->session != 0); - iter->num_objects = 0; - iter->saw_objects = 0; - - for (;;) { - if (iter->max_objects - iter->num_objects == 0) { - iter->max_objects = iter->max_objects ? iter->max_objects * 2 : 64; - iter->objects = realloc (iter->objects, iter->max_objects * sizeof (CK_ULONG)); - return_val_if_fail (iter->objects != NULL, CKR_HOST_MEMORY); - } - - batch = iter->max_objects - iter->num_objects; - rv = (iter->module->C_FindObjects) (iter->session, - iter->objects + iter->num_objects, - batch, &count); - if (rv != CKR_OK) - return finish_iterating (iter, rv); - - iter->num_objects += count; - - /* - * Done searching on this session, although there are still - * objects outstanding, which will be returned on next - * iterations. - */ - if (batch != count) { - iter->searching = 0; - iter->searched = 1; - (iter->module->C_FindObjectsFinal) (iter->session); - break; - } - - if (!iter->preload_results) - break; - } - } - - /* Try again */ - return p11_kit_iter_next (iter); -} - -/** - * p11_kit_iter_get_module: - * @iter: the iterator - * - * Get the module function pointers for the current matching object. - * - * This can only be called after p11_kit_iter_next() succeeds. - * - * Returns: the module which the current matching object is in - */ -CK_FUNCTION_LIST_PTR -p11_kit_iter_get_module (P11KitIter *iter) -{ - return_val_if_fail (iter != NULL, NULL); - return_val_if_fail (iter->iterating, 0); - return iter->module; -} - -/** - * p11_kit_iter_get_slot: - * @iter: the iterator - * - * Get the slot which the current matching object is on. - * - * This can only be called after p11_kit_iter_next() succeeds. - * - * Returns: the slot of the current matching object - */ -CK_SLOT_ID -p11_kit_iter_get_slot (P11KitIter *iter) -{ - return_val_if_fail (iter != NULL, 0); - return_val_if_fail (iter->iterating, 0); - return iter->slot; -} - -/** - * p11_kit_iter_get_slot_info: - * @iter: the iterator - * - * Get the slot info for the slot which the current matching object is on. - * - * This can only be called after p11_kit_iter_next() succeeds. - * - * Returns: the slot of the current matching object. - */ -CK_SLOT_INFO * -p11_kit_iter_get_slot_info (P11KitIter *iter) -{ - return_val_if_fail (iter != NULL, NULL); - return &iter->slot_info; -} - -/** - * p11_kit_iter_get_token: - * @iter: the iterator - * - * Get the token info for the token which the current matching object is on. - * - * This can only be called after p11_kit_iter_next() succeeds. - * - * Returns: the slot of the current matching object. - */ -CK_TOKEN_INFO * -p11_kit_iter_get_token (P11KitIter *iter) -{ - return_val_if_fail (iter != NULL, NULL); - return &iter->token_info; -} - -/** - * p11_kit_iter_get_session: - * @iter: the iterator - * - * Get the session which the current matching object is acessible - * through. - * - * This can only be called after p11_kit_iter_next() succeeds. - * - * The session may be closed after the next p11_kit_iter_next() call - * unless p11_kit_iter_keep_session() is called. - * - * Returns: the session used to find the current matching object - */ -CK_SESSION_HANDLE -p11_kit_iter_get_session (P11KitIter *iter) -{ - return_val_if_fail (iter != NULL, 0); - return_val_if_fail (iter->iterating, 0); - return iter->session; -} - -/** - * p11_kit_iter_get_object: - * @iter: the iterator - * - * Get the current matching object. - * - * This can only be called after p11_kit_iter_next() succeeds. - * - * Returns: the current matching object - */ -CK_OBJECT_HANDLE -p11_kit_iter_get_object (P11KitIter *iter) -{ - return_val_if_fail (iter != NULL, 0); - return iter->object; -} - -/** - * p11_kit_iter_destroy_object: - * @iter: the iterator - * - * Destroy the current matching object. - * - * This can only be called after p11_kit_iter_next() succeeds. - * - * Returns: CKR_OK or a failure code - */ -CK_RV -p11_kit_iter_destroy_object (P11KitIter *iter) -{ - return_val_if_fail (iter != NULL, CKR_GENERAL_ERROR); - return_val_if_fail (iter->iterating, CKR_GENERAL_ERROR); - return (iter->module->C_DestroyObject) (iter->session, iter->object); -} - -/** - * p11_kit_iter_get_attributes: - * @iter: the iterator - * @template: (array length=count) (inout): the attributes to get - * @count: the number of attributes - * - * Get attributes for the current matching object. - * - * This calls <literal>C_GetAttributeValue</literal> for the object - * currently iterated to. Return value and attribute memory behavior - * is identical to the PKCS\#11 <literal>C_GetAttributeValue</literal> - * function. - * - * You might choose to use p11_kit_iter_load_attributes() for a more - * helpful variant. - * - * This can only be called after p11_kit_iter_next() succeeds. - * - * Returns: The result from <literal>C_GetAttributeValue</literal>. - */ -CK_RV -p11_kit_iter_get_attributes (P11KitIter *iter, - CK_ATTRIBUTE *template, - CK_ULONG count) -{ - return_val_if_fail (iter != NULL, CKR_GENERAL_ERROR); - return_val_if_fail (iter->iterating, CKR_GENERAL_ERROR); - return_val_if_fail (iter->module != NULL, CKR_GENERAL_ERROR); - return_val_if_fail (iter->session != 0, CKR_GENERAL_ERROR); - return_val_if_fail (iter->object != 0, CKR_GENERAL_ERROR); - - return (iter->module->C_GetAttributeValue) (iter->session, iter->object, - template, count); -} - -/** - * p11_kit_iter_load_attributes: - * @iter: the iterator - * @template: (array length=count) (inout): the attributes to load - * @count: the number of attributes - * - * Retrieve attributes for the current matching object. - * - * Each attribute in the array will be filled in with the value - * of that attribute retrieved from the object. After use the - * attribute value memory pointed to by the <literal>pValue</literal> - * of each attribute should be freed with the <literal>free<!-- -->()</literal> - * function. - * - * If the <literal>pValue</literal> of an attribute is not %NULL passed - * to this function, then it will be passed to - * <literal>realloc<!-- -->()</literal> to allocate the correct amount - * of space for the attribute value. - * - * If any attribute is not present on the object, or is sensitive and - * cannot be retrieved, then the <literal>pValue</literal> will be NULL. - * If <literal>pValue</literal> was not %NULL when passed to this function - * then it will be freed with <literal>free<!-- -->()</literal>. In these - * cases <literal>CKR_OK</literal> is returned. - * - * This can only be called after p11_kit_iter_next() succeeds. - * - * Returns: CKR_OK or a failure code - */ -CK_RV -p11_kit_iter_load_attributes (P11KitIter *iter, - CK_ATTRIBUTE *template, - CK_ULONG count) -{ - CK_ATTRIBUTE *original = NULL; - CK_ULONG i; - CK_RV rv; - - return_val_if_fail (iter != NULL, CKR_GENERAL_ERROR); - return_val_if_fail (iter->iterating, CKR_GENERAL_ERROR); - return_val_if_fail (iter->module != NULL, CKR_GENERAL_ERROR); - return_val_if_fail (iter->session != 0, CKR_GENERAL_ERROR); - return_val_if_fail (iter->object != 0, CKR_GENERAL_ERROR); - - if (count == 0) - return CKR_OK; - - original = memdup (template, count * sizeof (CK_ATTRIBUTE)); - return_val_if_fail (original != NULL, CKR_HOST_MEMORY); - - for (i = 0; i < count; i++) - template[i].pValue = NULL; - - rv = (iter->module->C_GetAttributeValue) (iter->session, iter->object, template, count); - - switch (rv) { - case CKR_OK: - case CKR_ATTRIBUTE_TYPE_INVALID: - case CKR_ATTRIBUTE_SENSITIVE: - case CKR_BUFFER_TOO_SMALL: - break; - default: - free (original); - return rv; - } - - for (i = 0; i < count; i++) { - if (template[i].ulValueLen == (CK_ULONG)-1 || - template[i].ulValueLen == 0) { - free (original[i].pValue); - - } else if (original[i].pValue != NULL && - template[i].ulValueLen == original[i].ulValueLen) { - template[i].pValue = original[i].pValue; - - } else { - template[i].pValue = realloc (original[i].pValue, template[i].ulValueLen); - return_val_if_fail (template[i].pValue != NULL, CKR_HOST_MEMORY); - } - } - - free (original); - - rv = (iter->module->C_GetAttributeValue) (iter->session, iter->object, template, count); - - switch (rv) { - case CKR_OK: - case CKR_ATTRIBUTE_TYPE_INVALID: - case CKR_ATTRIBUTE_SENSITIVE: - rv = CKR_OK; - break; - default: - return_val_if_fail (rv != CKR_BUFFER_TOO_SMALL, rv); - return rv; - } - - for (i = 0; i < count; i++) { - if (template[i].ulValueLen == (CK_ULONG)-1 || - template[i].ulValueLen == 0) { - free (template[i].pValue); - template[i].pValue = NULL; - } - } - - return rv; -} - -/** - * p11_kit_iter_keep_session: - * @iter: the iterator - * - * After calling this function the session open for iterating - * the current object will not be automatically closed by - * the iterator after later calls to p11_kit_iter_next() or - * p11_kit_iter_free(). - * - * It is the callers responsibility to close this session, - * after the iterator has been freed. The session may still be - * used by the iterator if further iterations are performed. - * - * This can only be called after p11_kit_iter_next() succeeds. - * - * Returns: the current session - */ -CK_SESSION_HANDLE -p11_kit_iter_keep_session (P11KitIter *iter) -{ - return_val_if_fail (iter != NULL, 0); - return_val_if_fail (iter->iterating, 0); - return_val_if_fail (iter->session != 0, 0); - - iter->keep_session = 1; - return iter->session; -} - -/** - * p11_kit_iter_free: - * @iter: the iterator - * - * Frees the iterator and all resources, such as sessions - * or callbacks held by the iterator. - */ -void -p11_kit_iter_free (P11KitIter *iter) -{ - Callback *cb, *next; - - if (iter == NULL) - return; - - finish_iterating (iter, CKR_OK); - p11_array_free (iter->modules); - p11_attrs_free (iter->match_attrs); - free (iter->objects); - free (iter->slots); - - for (cb = iter->callbacks; cb != NULL; cb = next) { - next = cb->next; - if (cb->destroyer) - (cb->destroyer) (cb->callback_data); - free (cb); - } - - free (iter); -} |