/* 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; }