Source code

Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* sessobj.c
*
* This file contains an NSSCKMDObject implementation for session
* objects. The framework uses this implementation to manage
* session objects when a Module doesn't wish to be bothered.
*/
#ifndef CK_T
#include "ck.h"
#endif /* CK_T */
/*
* nssCKMDSessionObject
*
* -- create --
* nssCKMDSessionObject_Create
*
* -- EPV calls --
* nss_ckmdSessionObject_Finalize
* nss_ckmdSessionObject_IsTokenObject
* nss_ckmdSessionObject_GetAttributeCount
* nss_ckmdSessionObject_GetAttributeTypes
* nss_ckmdSessionObject_GetAttributeSize
* nss_ckmdSessionObject_GetAttribute
* nss_ckmdSessionObject_SetAttribute
* nss_ckmdSessionObject_GetObjectSize
*/
struct nssCKMDSessionObjectStr {
CK_ULONG n;
NSSArena *arena;
NSSItem *attributes;
CK_ATTRIBUTE_TYPE_PTR types;
nssCKFWHash *hash;
};
typedef struct nssCKMDSessionObjectStr nssCKMDSessionObject;
#ifdef DEBUG
/*
* But first, the pointer-tracking stuff.
*
* NOTE: the pointer-tracking support in NSS/base currently relies
* upon NSPR's CallOnce support. That, however, relies upon NSPR's
* locking, which is tied into the runtime. We need a pointer-tracker
* implementation that uses the locks supplied through C_Initialize.
* That support, however, can be filled in later. So for now, I'll
* just do this routines as no-ops.
*/
static CK_RV
nss_ckmdSessionObject_add_pointer(
const NSSCKMDObject *mdObject)
{
return CKR_OK;
}
static CK_RV
nss_ckmdSessionObject_remove_pointer(
const NSSCKMDObject *mdObject)
{
return CKR_OK;
}
#ifdef NSS_DEBUG
static CK_RV
nss_ckmdSessionObject_verifyPointer(
const NSSCKMDObject *mdObject)
{
return CKR_OK;
}
#endif
#endif /* DEBUG */
/*
* We must forward-declare these routines
*/
static void
nss_ckmdSessionObject_Finalize(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance);
static CK_RV
nss_ckmdSessionObject_Destroy(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance);
static CK_BBOOL
nss_ckmdSessionObject_IsTokenObject(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance);
static CK_ULONG
nss_ckmdSessionObject_GetAttributeCount(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
CK_RV *pError);
static CK_RV
nss_ckmdSessionObject_GetAttributeTypes(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
CK_ATTRIBUTE_TYPE_PTR typeArray,
CK_ULONG ulCount);
static CK_ULONG
nss_ckmdSessionObject_GetAttributeSize(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
CK_ATTRIBUTE_TYPE attribute,
CK_RV *pError);
static NSSCKFWItem
nss_ckmdSessionObject_GetAttribute(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
CK_ATTRIBUTE_TYPE attribute,
CK_RV *pError);
static CK_RV
nss_ckmdSessionObject_SetAttribute(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
CK_ATTRIBUTE_TYPE attribute,
NSSItem *value);
static CK_ULONG
nss_ckmdSessionObject_GetObjectSize(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
CK_RV *pError);
/*
* nssCKMDSessionObject_Create
*
*/
NSS_IMPLEMENT NSSCKMDObject *
nssCKMDSessionObject_Create(
NSSCKFWToken *fwToken,
NSSArena *arena,
CK_ATTRIBUTE_PTR attributes,
CK_ULONG ulCount,
CK_RV *pError)
{
NSSCKMDObject *mdObject = (NSSCKMDObject *)NULL;
nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)NULL;
CK_ULONG i;
nssCKFWHash *hash;
*pError = CKR_OK;
mdso = nss_ZNEW(arena, nssCKMDSessionObject);
if (!mdso) {
goto loser;
}
mdso->arena = arena;
mdso->n = ulCount;
mdso->attributes = nss_ZNEWARRAY(arena, NSSItem, ulCount);
if (!mdso->attributes) {
goto loser;
}
mdso->types = nss_ZNEWARRAY(arena, CK_ATTRIBUTE_TYPE, ulCount);
if (!mdso->types) {
goto loser;
}
for (i = 0; i < ulCount; i++) {
mdso->types[i] = attributes[i].type;
mdso->attributes[i].size = attributes[i].ulValueLen;
mdso->attributes[i].data = nss_ZAlloc(arena, attributes[i].ulValueLen);
if (!mdso->attributes[i].data) {
goto loser;
}
(void)nsslibc_memcpy(mdso->attributes[i].data, attributes[i].pValue,
attributes[i].ulValueLen);
}
mdObject = nss_ZNEW(arena, NSSCKMDObject);
if (!mdObject) {
goto loser;
}
mdObject->etc = (void *)mdso;
mdObject->Finalize = nss_ckmdSessionObject_Finalize;
mdObject->Destroy = nss_ckmdSessionObject_Destroy;
mdObject->IsTokenObject = nss_ckmdSessionObject_IsTokenObject;
mdObject->GetAttributeCount = nss_ckmdSessionObject_GetAttributeCount;
mdObject->GetAttributeTypes = nss_ckmdSessionObject_GetAttributeTypes;
mdObject->GetAttributeSize = nss_ckmdSessionObject_GetAttributeSize;
mdObject->GetAttribute = nss_ckmdSessionObject_GetAttribute;
mdObject->SetAttribute = nss_ckmdSessionObject_SetAttribute;
mdObject->GetObjectSize = nss_ckmdSessionObject_GetObjectSize;
hash = nssCKFWToken_GetSessionObjectHash(fwToken);
if (!hash) {
*pError = CKR_GENERAL_ERROR;
goto loser;
}
mdso->hash = hash;
*pError = nssCKFWHash_Add(hash, mdObject, mdObject);
if (CKR_OK != *pError) {
goto loser;
}
#ifdef DEBUG
if ((*pError = nss_ckmdSessionObject_add_pointer(mdObject)) != CKR_OK) {
goto loser;
}
#endif /* DEBUG */
return mdObject;
loser:
if (mdso) {
if (mdso->attributes) {
for (i = 0; i < ulCount; i++) {
nss_ZFreeIf(mdso->attributes[i].data);
}
nss_ZFreeIf(mdso->attributes);
}
nss_ZFreeIf(mdso->types);
nss_ZFreeIf(mdso);
}
nss_ZFreeIf(mdObject);
if (*pError == CKR_OK) {
*pError = CKR_HOST_MEMORY;
}
return (NSSCKMDObject *)NULL;
}
/*
* nss_ckmdSessionObject_Finalize
*
*/
static void
nss_ckmdSessionObject_Finalize(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance)
{
/* This shouldn't ever be called */
return;
}
/*
* nss_ckmdSessionObject_Destroy
*
*/
static CK_RV
nss_ckmdSessionObject_Destroy(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance)
{
#ifdef NSSDEBUG
CK_RV error = CKR_OK;
#endif /* NSSDEBUG */
nssCKMDSessionObject *mdso;
CK_ULONG i;
#ifdef NSSDEBUG
error = nss_ckmdSessionObject_verifyPointer(mdObject);
if (CKR_OK != error) {
return error;
}
#endif /* NSSDEBUG */
mdso = (nssCKMDSessionObject *)mdObject->etc;
nssCKFWHash_Remove(mdso->hash, mdObject);
for (i = 0; i < mdso->n; i++) {
nss_ZFreeIf(mdso->attributes[i].data);
}
nss_ZFreeIf(mdso->attributes);
nss_ZFreeIf(mdso->types);
nss_ZFreeIf(mdso);
nss_ZFreeIf(mdObject);
#ifdef DEBUG
(void)nss_ckmdSessionObject_remove_pointer(mdObject);
#endif /* DEBUG */
return CKR_OK;
}
/*
* nss_ckmdSessionObject_IsTokenObject
*
*/
static CK_BBOOL
nss_ckmdSessionObject_IsTokenObject(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance)
{
#ifdef NSSDEBUG
if (CKR_OK != nss_ckmdSessionObject_verifyPointer(mdObject)) {
return CK_FALSE;
}
#endif /* NSSDEBUG */
/*
* This implementation is only ever used for session objects.
*/
return CK_FALSE;
}
/*
* nss_ckmdSessionObject_GetAttributeCount
*
*/
static CK_ULONG
nss_ckmdSessionObject_GetAttributeCount(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
CK_RV *pError)
{
nssCKMDSessionObject *obj;
#ifdef NSSDEBUG
if (!pError) {
return 0;
}
*pError = nss_ckmdSessionObject_verifyPointer(mdObject);
if (CKR_OK != *pError) {
return 0;
}
/* We could even check all the other arguments, for sanity. */
#endif /* NSSDEBUG */
obj = (nssCKMDSessionObject *)mdObject->etc;
return obj->n;
}
/*
* nss_ckmdSessionObject_GetAttributeTypes
*
*/
static CK_RV
nss_ckmdSessionObject_GetAttributeTypes(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
CK_ATTRIBUTE_TYPE_PTR typeArray,
CK_ULONG ulCount)
{
#ifdef NSSDEBUG
CK_RV error = CKR_OK;
#endif /* NSSDEBUG */
nssCKMDSessionObject *obj;
#ifdef NSSDEBUG
error = nss_ckmdSessionObject_verifyPointer(mdObject);
if (CKR_OK != error) {
return error;
}
/* We could even check all the other arguments, for sanity. */
#endif /* NSSDEBUG */
obj = (nssCKMDSessionObject *)mdObject->etc;
if (ulCount < obj->n) {
return CKR_BUFFER_TOO_SMALL;
}
(void)nsslibc_memcpy(typeArray, obj->types,
sizeof(CK_ATTRIBUTE_TYPE) *
obj->n);
return CKR_OK;
}
/*
* nss_ckmdSessionObject_GetAttributeSize
*
*/
static CK_ULONG
nss_ckmdSessionObject_GetAttributeSize(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
CK_ATTRIBUTE_TYPE attribute,
CK_RV *pError)
{
nssCKMDSessionObject *obj;
CK_ULONG i;
#ifdef NSSDEBUG
if (!pError) {
return 0;
}
*pError = nss_ckmdSessionObject_verifyPointer(mdObject);
if (CKR_OK != *pError) {
return 0;
}
/* We could even check all the other arguments, for sanity. */
#endif /* NSSDEBUG */
obj = (nssCKMDSessionObject *)mdObject->etc;
for (i = 0; i < obj->n; i++) {
if (attribute == obj->types[i]) {
return (CK_ULONG)(obj->attributes[i].size);
}
}
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
return 0;
}
/*
* nss_ckmdSessionObject_GetAttribute
*
*/
static NSSCKFWItem
nss_ckmdSessionObject_GetAttribute(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
CK_ATTRIBUTE_TYPE attribute,
CK_RV *pError)
{
NSSCKFWItem item;
nssCKMDSessionObject *obj;
CK_ULONG i;
item.needsFreeing = PR_FALSE;
item.item = NULL;
#ifdef NSSDEBUG
if (!pError) {
return item;
}
*pError = nss_ckmdSessionObject_verifyPointer(mdObject);
if (CKR_OK != *pError) {
return item;
}
/* We could even check all the other arguments, for sanity. */
#endif /* NSSDEBUG */
obj = (nssCKMDSessionObject *)mdObject->etc;
for (i = 0; i < obj->n; i++) {
if (attribute == obj->types[i]) {
item.item = &obj->attributes[i];
return item;
}
}
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
return item;
}
/*
* nss_ckmdSessionObject_SetAttribute
*
*/
/*
* Okay, so this implementation sucks. It doesn't support removing
* an attribute (if value == NULL), and could be more graceful about
* memory. It should allow "blank" slots in the arrays, with some
* invalid attribute type, and then it could support removal much
* more easily. Do this later.
*/
static CK_RV
nss_ckmdSessionObject_SetAttribute(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
CK_ATTRIBUTE_TYPE attribute,
NSSItem *value)
{
nssCKMDSessionObject *obj;
CK_ULONG i;
NSSItem n;
NSSItem *ra;
CK_ATTRIBUTE_TYPE_PTR rt;
#ifdef NSSDEBUG
CK_RV error;
#endif /* NSSDEBUG */
#ifdef NSSDEBUG
error = nss_ckmdSessionObject_verifyPointer(mdObject);
if (CKR_OK != error) {
return 0;
}
/* We could even check all the other arguments, for sanity. */
#endif /* NSSDEBUG */
obj = (nssCKMDSessionObject *)mdObject->etc;
n.size = value->size;
n.data = nss_ZAlloc(obj->arena, n.size);
if (!n.data) {
return CKR_HOST_MEMORY;
}
(void)nsslibc_memcpy(n.data, value->data, n.size);
for (i = 0; i < obj->n; i++) {
if (attribute == obj->types[i]) {
nss_ZFreeIf(obj->attributes[i].data);
obj->attributes[i] = n;
return CKR_OK;
}
}
/*
* It's new.
*/
ra = (NSSItem *)nss_ZRealloc(obj->attributes, sizeof(NSSItem) * (obj->n + 1));
if (!ra) {
nss_ZFreeIf(n.data);
return CKR_HOST_MEMORY;
}
obj->attributes = ra;
rt = (CK_ATTRIBUTE_TYPE_PTR)nss_ZRealloc(obj->types,
sizeof(CK_ATTRIBUTE_TYPE) * (obj->n + 1));
if (!rt) {
nss_ZFreeIf(n.data);
return CKR_HOST_MEMORY;
}
obj->types = rt;
obj->attributes[obj->n] = n;
obj->types[obj->n] = attribute;
obj->n++;
return CKR_OK;
}
/*
* nss_ckmdSessionObject_GetObjectSize
*
*/
static CK_ULONG
nss_ckmdSessionObject_GetObjectSize(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
CK_RV *pError)
{
nssCKMDSessionObject *obj;
CK_ULONG i;
CK_ULONG rv = (CK_ULONG)0;
#ifdef NSSDEBUG
if (!pError) {
return 0;
}
*pError = nss_ckmdSessionObject_verifyPointer(mdObject);
if (CKR_OK != *pError) {
return 0;
}
/* We could even check all the other arguments, for sanity. */
#endif /* NSSDEBUG */
obj = (nssCKMDSessionObject *)mdObject->etc;
for (i = 0; i < obj->n; i++) {
rv += obj->attributes[i].size;
}
rv += sizeof(NSSItem) * obj->n;
rv += sizeof(CK_ATTRIBUTE_TYPE) * obj->n;
rv += sizeof(nssCKMDSessionObject);
return rv;
}
/*
* nssCKMDFindSessionObjects
*
* -- create --
* nssCKMDFindSessionObjects_Create
*
* -- EPV calls --
* nss_ckmdFindSessionObjects_Final
* nss_ckmdFindSessionObjects_Next
*/
struct nodeStr {
struct nodeStr *next;
NSSCKMDObject *mdObject;
};
struct nssCKMDFindSessionObjectsStr {
NSSArena *arena;
CK_RV error;
CK_ATTRIBUTE_PTR pTemplate;
CK_ULONG ulCount;
struct nodeStr *list;
nssCKFWHash *hash;
};
typedef struct nssCKMDFindSessionObjectsStr nssCKMDFindSessionObjects;
#ifdef DEBUG
/*
* But first, the pointer-tracking stuff.
*
* NOTE: the pointer-tracking support in NSS/base currently relies
* upon NSPR's CallOnce support. That, however, relies upon NSPR's
* locking, which is tied into the runtime. We need a pointer-tracker
* implementation that uses the locks supplied through C_Initialize.
* That support, however, can be filled in later. So for now, I'll
* just do this routines as no-ops.
*/
static CK_RV
nss_ckmdFindSessionObjects_add_pointer(
const NSSCKMDFindObjects *mdFindObjects)
{
return CKR_OK;
}
static CK_RV
nss_ckmdFindSessionObjects_remove_pointer(
const NSSCKMDFindObjects *mdFindObjects)
{
return CKR_OK;
}
#ifdef NSS_DEBUG
static CK_RV
nss_ckmdFindSessionObjects_verifyPointer(
const NSSCKMDFindObjects *mdFindObjects)
{
return CKR_OK;
}
#endif
#endif /* DEBUG */
/*
* We must forward-declare these routines.
*/
static void
nss_ckmdFindSessionObjects_Final(
NSSCKMDFindObjects *mdFindObjects,
NSSCKFWFindObjects *fwFindObjects,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance);
static NSSCKMDObject *
nss_ckmdFindSessionObjects_Next(
NSSCKMDFindObjects *mdFindObjects,
NSSCKFWFindObjects *fwFindObjects,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
NSSArena *arena,
CK_RV *pError);
static CK_BBOOL
items_match(
NSSItem *a,
CK_VOID_PTR pValue,
CK_ULONG ulValueLen)
{
if (a->size != ulValueLen) {
return CK_FALSE;
}
if (PR_TRUE == nsslibc_memequal(a->data, pValue, ulValueLen, (PRStatus *)NULL)) {
return CK_TRUE;
} else {
return CK_FALSE;
}
}
/*
* Our hashtable iterator
*/
static void
findfcn(
const void *key,
void *value,
void *closure)
{
NSSCKMDObject *mdObject = (NSSCKMDObject *)value;
nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)mdObject->etc;
nssCKMDFindSessionObjects *mdfso = (nssCKMDFindSessionObjects *)closure;
CK_ULONG i, j;
struct nodeStr *node;
if (CKR_OK != mdfso->error) {
return;
}
for (i = 0; i < mdfso->ulCount; i++) {
CK_ATTRIBUTE_PTR p = &mdfso->pTemplate[i];
for (j = 0; j < mdso->n; j++) {
if (mdso->types[j] == p->type) {
if (!items_match(&mdso->attributes[j], p->pValue, p->ulValueLen)) {
return;
} else {
break;
}
}
}
if (j == mdso->n) {
/* Attribute not found */
return;
}
}
/* Matches */
node = nss_ZNEW(mdfso->arena, struct nodeStr);
if ((struct nodeStr *)NULL == node) {
mdfso->error = CKR_HOST_MEMORY;
return;
}
node->mdObject = mdObject;
node->next = mdfso->list;
mdfso->list = node;
return;
}
/*
* nssCKMDFindSessionObjects_Create
*
*/
NSS_IMPLEMENT NSSCKMDFindObjects *
nssCKMDFindSessionObjects_Create(
NSSCKFWToken *fwToken,
CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount,
CK_RV *pError)
{
NSSArena *arena;
nssCKMDFindSessionObjects *mdfso;
nssCKFWHash *hash;
NSSCKMDFindObjects *rv;
#ifdef NSSDEBUG
if (!pError) {
return (NSSCKMDFindObjects *)NULL;
}
*pError = nssCKFWToken_verifyPointer(fwToken);
if (CKR_OK != *pError) {
return (NSSCKMDFindObjects *)NULL;
}
if ((CK_ATTRIBUTE_PTR)NULL == pTemplate) {
*pError = CKR_ARGUMENTS_BAD;
return (NSSCKMDFindObjects *)NULL;
}
#endif /* NSSDEBUG */
*pError = CKR_OK;
hash = nssCKFWToken_GetSessionObjectHash(fwToken);
if (!hash) {
*pError = CKR_GENERAL_ERROR;
return (NSSCKMDFindObjects *)NULL;
}
arena = NSSArena_Create();
if (!arena) {
*pError = CKR_HOST_MEMORY;
return (NSSCKMDFindObjects *)NULL;
}
mdfso = nss_ZNEW(arena, nssCKMDFindSessionObjects);
if (!mdfso) {
goto loser;
}
rv = nss_ZNEW(arena, NSSCKMDFindObjects);
if (rv == NULL) {
goto loser;
}
mdfso->error = CKR_OK;
mdfso->pTemplate = pTemplate;
mdfso->ulCount = ulCount;
mdfso->hash = hash;
nssCKFWHash_Iterate(hash, findfcn, mdfso);
if (CKR_OK != mdfso->error) {
goto loser;
}
rv->etc = (void *)mdfso;
rv->Final = nss_ckmdFindSessionObjects_Final;
rv->Next = nss_ckmdFindSessionObjects_Next;
#ifdef DEBUG
if ((*pError = nss_ckmdFindSessionObjects_add_pointer(rv)) != CKR_OK) {
goto loser;
}
#endif /* DEBUG */
mdfso->arena = arena;
return rv;
loser:
if (arena) {
NSSArena_Destroy(arena);
}
if (*pError == CKR_OK) {
*pError = CKR_HOST_MEMORY;
}
return NULL;
}
static void
nss_ckmdFindSessionObjects_Final(
NSSCKMDFindObjects *mdFindObjects,
NSSCKFWFindObjects *fwFindObjects,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance)
{
nssCKMDFindSessionObjects *mdfso;
#ifdef NSSDEBUG
if (CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects)) {
return;
}
#endif /* NSSDEBUG */
mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
if (mdfso->arena)
NSSArena_Destroy(mdfso->arena);
#ifdef DEBUG
(void)nss_ckmdFindSessionObjects_remove_pointer(mdFindObjects);
#endif /* DEBUG */
return;
}
static NSSCKMDObject *
nss_ckmdFindSessionObjects_Next(
NSSCKMDFindObjects *mdFindObjects,
NSSCKFWFindObjects *fwFindObjects,
NSSCKMDSession *mdSession,
NSSCKFWSession *fwSession,
NSSCKMDToken *mdToken,
NSSCKFWToken *fwToken,
NSSCKMDInstance *mdInstance,
NSSCKFWInstance *fwInstance,
NSSArena *arena,
CK_RV *pError)
{
nssCKMDFindSessionObjects *mdfso;
NSSCKMDObject *rv = (NSSCKMDObject *)NULL;
#ifdef NSSDEBUG
if (CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects)) {
return (NSSCKMDObject *)NULL;
}
#endif /* NSSDEBUG */
mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
while (!rv) {
if ((struct nodeStr *)NULL == mdfso->list) {
*pError = CKR_OK;
return (NSSCKMDObject *)NULL;
}
if (nssCKFWHash_Exists(mdfso->hash, mdfso->list->mdObject)) {
rv = mdfso->list->mdObject;
}
mdfso->list = mdfso->list->next;
}
return rv;
}