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