diff options
Diffstat (limited to 'lib/ckfw/sessobj.c')
-rw-r--r-- | lib/ckfw/sessobj.c | 1079 |
1 files changed, 1079 insertions, 0 deletions
diff --git a/lib/ckfw/sessobj.c b/lib/ckfw/sessobj.c new file mode 100644 index 000000000..d94ed7e87 --- /dev/null +++ b/lib/ckfw/sessobj.c @@ -0,0 +1,1079 @@ +/* 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/. */ + +#ifdef DEBUG +static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; +#endif /* DEBUG */ + +/* + * 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; +} |