michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * find.c michael@0: * michael@0: * This file implements the nssCKFWFindObjects type and methods. michael@0: */ michael@0: michael@0: #ifndef CK_H michael@0: #include "ck.h" michael@0: #endif /* CK_H */ michael@0: michael@0: /* michael@0: * NSSCKFWFindObjects michael@0: * michael@0: * -- create/destroy -- michael@0: * nssCKFWFindObjects_Create michael@0: * nssCKFWFindObjects_Destroy michael@0: * michael@0: * -- public accessors -- michael@0: * NSSCKFWFindObjects_GetMDFindObjects michael@0: * michael@0: * -- implement public accessors -- michael@0: * nssCKFWFindObjects_GetMDFindObjects michael@0: * michael@0: * -- private accessors -- michael@0: * michael@0: * -- module fronts -- michael@0: * nssCKFWFindObjects_Next michael@0: */ michael@0: michael@0: struct NSSCKFWFindObjectsStr { michael@0: NSSCKFWMutex *mutex; /* merely to serialise the MDObject calls */ michael@0: NSSCKMDFindObjects *mdfo1; michael@0: NSSCKMDFindObjects *mdfo2; michael@0: NSSCKFWSession *fwSession; michael@0: NSSCKMDSession *mdSession; michael@0: NSSCKFWToken *fwToken; michael@0: NSSCKMDToken *mdToken; michael@0: NSSCKFWInstance *fwInstance; michael@0: NSSCKMDInstance *mdInstance; michael@0: michael@0: NSSCKMDFindObjects *mdFindObjects; /* varies */ michael@0: }; michael@0: michael@0: #ifdef DEBUG michael@0: /* michael@0: * But first, the pointer-tracking stuff. michael@0: * michael@0: * NOTE: the pointer-tracking support in NSS/base currently relies michael@0: * upon NSPR's CallOnce support. That, however, relies upon NSPR's michael@0: * locking, which is tied into the runtime. We need a pointer-tracker michael@0: * implementation that uses the locks supplied through C_Initialize. michael@0: * That support, however, can be filled in later. So for now, I'll michael@0: * just do these routines as no-ops. michael@0: */ michael@0: michael@0: static CK_RV michael@0: findObjects_add_pointer michael@0: ( michael@0: const NSSCKFWFindObjects *fwFindObjects michael@0: ) michael@0: { michael@0: return CKR_OK; michael@0: } michael@0: michael@0: static CK_RV michael@0: findObjects_remove_pointer michael@0: ( michael@0: const NSSCKFWFindObjects *fwFindObjects michael@0: ) michael@0: { michael@0: return CKR_OK; michael@0: } michael@0: michael@0: NSS_IMPLEMENT CK_RV michael@0: nssCKFWFindObjects_verifyPointer michael@0: ( michael@0: const NSSCKFWFindObjects *fwFindObjects michael@0: ) michael@0: { michael@0: return CKR_OK; michael@0: } michael@0: michael@0: #endif /* DEBUG */ michael@0: michael@0: /* michael@0: * nssCKFWFindObjects_Create michael@0: * michael@0: */ michael@0: NSS_EXTERN NSSCKFWFindObjects * michael@0: nssCKFWFindObjects_Create michael@0: ( michael@0: NSSCKFWSession *fwSession, michael@0: NSSCKFWToken *fwToken, michael@0: NSSCKFWInstance *fwInstance, michael@0: NSSCKMDFindObjects *mdFindObjects1, michael@0: NSSCKMDFindObjects *mdFindObjects2, michael@0: CK_RV *pError michael@0: ) michael@0: { michael@0: NSSCKFWFindObjects *fwFindObjects = NULL; michael@0: NSSCKMDSession *mdSession; michael@0: NSSCKMDToken *mdToken; michael@0: NSSCKMDInstance *mdInstance; michael@0: michael@0: mdSession = nssCKFWSession_GetMDSession(fwSession); michael@0: mdToken = nssCKFWToken_GetMDToken(fwToken); michael@0: mdInstance = nssCKFWInstance_GetMDInstance(fwInstance); michael@0: michael@0: fwFindObjects = nss_ZNEW(NULL, NSSCKFWFindObjects); michael@0: if (!fwFindObjects) { michael@0: *pError = CKR_HOST_MEMORY; michael@0: goto loser; michael@0: } michael@0: michael@0: fwFindObjects->mdfo1 = mdFindObjects1; michael@0: fwFindObjects->mdfo2 = mdFindObjects2; michael@0: fwFindObjects->fwSession = fwSession; michael@0: fwFindObjects->mdSession = mdSession; michael@0: fwFindObjects->fwToken = fwToken; michael@0: fwFindObjects->mdToken = mdToken; michael@0: fwFindObjects->fwInstance = fwInstance; michael@0: fwFindObjects->mdInstance = mdInstance; michael@0: michael@0: fwFindObjects->mutex = nssCKFWInstance_CreateMutex(fwInstance, NULL, pError); michael@0: if (!fwFindObjects->mutex) { michael@0: goto loser; michael@0: } michael@0: michael@0: #ifdef DEBUG michael@0: *pError = findObjects_add_pointer(fwFindObjects); michael@0: if( CKR_OK != *pError ) { michael@0: goto loser; michael@0: } michael@0: #endif /* DEBUG */ michael@0: michael@0: return fwFindObjects; michael@0: michael@0: loser: michael@0: if( fwFindObjects ) { michael@0: if( NULL != mdFindObjects1 ) { michael@0: if( NULL != mdFindObjects1->Final ) { michael@0: fwFindObjects->mdFindObjects = mdFindObjects1; michael@0: mdFindObjects1->Final(mdFindObjects1, fwFindObjects, mdSession, michael@0: fwSession, mdToken, fwToken, mdInstance, fwInstance); michael@0: } michael@0: } michael@0: michael@0: if( NULL != mdFindObjects2 ) { michael@0: if( NULL != mdFindObjects2->Final ) { michael@0: fwFindObjects->mdFindObjects = mdFindObjects2; michael@0: mdFindObjects2->Final(mdFindObjects2, fwFindObjects, mdSession, michael@0: fwSession, mdToken, fwToken, mdInstance, fwInstance); michael@0: } michael@0: } michael@0: michael@0: nss_ZFreeIf(fwFindObjects); michael@0: } michael@0: michael@0: if( CKR_OK == *pError ) { michael@0: *pError = CKR_GENERAL_ERROR; michael@0: } michael@0: michael@0: return (NSSCKFWFindObjects *)NULL; michael@0: } michael@0: michael@0: michael@0: /* michael@0: * nssCKFWFindObjects_Destroy michael@0: * michael@0: */ michael@0: NSS_EXTERN void michael@0: nssCKFWFindObjects_Destroy michael@0: ( michael@0: NSSCKFWFindObjects *fwFindObjects michael@0: ) michael@0: { michael@0: #ifdef NSSDEBUG michael@0: if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) { michael@0: return; michael@0: } michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: (void)nssCKFWMutex_Destroy(fwFindObjects->mutex); michael@0: michael@0: if (fwFindObjects->mdfo1) { michael@0: if (fwFindObjects->mdfo1->Final) { michael@0: fwFindObjects->mdFindObjects = fwFindObjects->mdfo1; michael@0: fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects, michael@0: fwFindObjects->mdSession, fwFindObjects->fwSession, michael@0: fwFindObjects->mdToken, fwFindObjects->fwToken, michael@0: fwFindObjects->mdInstance, fwFindObjects->fwInstance); michael@0: } michael@0: } michael@0: michael@0: if (fwFindObjects->mdfo2) { michael@0: if (fwFindObjects->mdfo2->Final) { michael@0: fwFindObjects->mdFindObjects = fwFindObjects->mdfo2; michael@0: fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects, michael@0: fwFindObjects->mdSession, fwFindObjects->fwSession, michael@0: fwFindObjects->mdToken, fwFindObjects->fwToken, michael@0: fwFindObjects->mdInstance, fwFindObjects->fwInstance); michael@0: } michael@0: } michael@0: michael@0: nss_ZFreeIf(fwFindObjects); michael@0: michael@0: #ifdef DEBUG michael@0: (void)findObjects_remove_pointer(fwFindObjects); michael@0: #endif /* DEBUG */ michael@0: michael@0: return; michael@0: } michael@0: michael@0: /* michael@0: * nssCKFWFindObjects_GetMDFindObjects michael@0: * michael@0: */ michael@0: NSS_EXTERN NSSCKMDFindObjects * michael@0: nssCKFWFindObjects_GetMDFindObjects michael@0: ( michael@0: NSSCKFWFindObjects *fwFindObjects michael@0: ) michael@0: { michael@0: #ifdef NSSDEBUG michael@0: if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) { michael@0: return (NSSCKMDFindObjects *)NULL; michael@0: } michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: return fwFindObjects->mdFindObjects; michael@0: } michael@0: michael@0: /* michael@0: * nssCKFWFindObjects_Next michael@0: * michael@0: */ michael@0: NSS_EXTERN NSSCKFWObject * michael@0: nssCKFWFindObjects_Next michael@0: ( michael@0: NSSCKFWFindObjects *fwFindObjects, michael@0: NSSArena *arenaOpt, michael@0: CK_RV *pError michael@0: ) michael@0: { michael@0: NSSCKMDObject *mdObject; michael@0: NSSCKFWObject *fwObject = (NSSCKFWObject *)NULL; michael@0: NSSArena *objArena; michael@0: michael@0: #ifdef NSSDEBUG michael@0: if (!pError) { michael@0: return (NSSCKFWObject *)NULL; michael@0: } michael@0: michael@0: *pError = nssCKFWFindObjects_verifyPointer(fwFindObjects); michael@0: if( CKR_OK != *pError ) { michael@0: return (NSSCKFWObject *)NULL; michael@0: } michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: *pError = nssCKFWMutex_Lock(fwFindObjects->mutex); michael@0: if( CKR_OK != *pError ) { michael@0: return (NSSCKFWObject *)NULL; michael@0: } michael@0: michael@0: if (fwFindObjects->mdfo1) { michael@0: if (fwFindObjects->mdfo1->Next) { michael@0: fwFindObjects->mdFindObjects = fwFindObjects->mdfo1; michael@0: mdObject = fwFindObjects->mdfo1->Next(fwFindObjects->mdfo1, michael@0: fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession, michael@0: fwFindObjects->mdToken, fwFindObjects->fwToken, michael@0: fwFindObjects->mdInstance, fwFindObjects->fwInstance, michael@0: arenaOpt, pError); michael@0: if (!mdObject) { michael@0: if( CKR_OK != *pError ) { michael@0: goto done; michael@0: } michael@0: michael@0: /* All done. */ michael@0: fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects, michael@0: fwFindObjects->mdSession, fwFindObjects->fwSession, michael@0: fwFindObjects->mdToken, fwFindObjects->fwToken, michael@0: fwFindObjects->mdInstance, fwFindObjects->fwInstance); michael@0: fwFindObjects->mdfo1 = (NSSCKMDFindObjects *)NULL; michael@0: } else { michael@0: goto wrap; michael@0: } michael@0: } michael@0: } michael@0: michael@0: if (fwFindObjects->mdfo2) { michael@0: if (fwFindObjects->mdfo2->Next) { michael@0: fwFindObjects->mdFindObjects = fwFindObjects->mdfo2; michael@0: mdObject = fwFindObjects->mdfo2->Next(fwFindObjects->mdfo2, michael@0: fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession, michael@0: fwFindObjects->mdToken, fwFindObjects->fwToken, michael@0: fwFindObjects->mdInstance, fwFindObjects->fwInstance, michael@0: arenaOpt, pError); michael@0: if (!mdObject) { michael@0: if( CKR_OK != *pError ) { michael@0: goto done; michael@0: } michael@0: michael@0: /* All done. */ michael@0: fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects, michael@0: fwFindObjects->mdSession, fwFindObjects->fwSession, michael@0: fwFindObjects->mdToken, fwFindObjects->fwToken, michael@0: fwFindObjects->mdInstance, fwFindObjects->fwInstance); michael@0: fwFindObjects->mdfo2 = (NSSCKMDFindObjects *)NULL; michael@0: } else { michael@0: goto wrap; michael@0: } michael@0: } michael@0: } michael@0: michael@0: /* No more objects */ michael@0: *pError = CKR_OK; michael@0: goto done; michael@0: michael@0: wrap: michael@0: /* michael@0: * This seems is less than ideal-- we should determine if it's a token michael@0: * object or a session object, and use the appropriate arena. michael@0: * But that duplicates logic in nssCKFWObject_IsTokenObject. michael@0: * Also we should lookup the real session the object was created on michael@0: * if the object was a session object... however this code is actually michael@0: * correct because nssCKFWObject_Create will return a cached version of michael@0: * the object from it's hash. This is necessary because 1) we don't want michael@0: * to create an arena style leak (where our arena grows with every search), michael@0: * and 2) we want the same object to always have the same ID. This means michael@0: * the only case the nssCKFWObject_Create() will need the objArena and the michael@0: * Session is in the case of token objects (session objects should already michael@0: * exist in the cache from their initial creation). So this code is correct, michael@0: * but it depends on nssCKFWObject_Create caching all objects. michael@0: */ michael@0: objArena = nssCKFWToken_GetArena(fwFindObjects->fwToken, pError); michael@0: if (!objArena) { michael@0: if( CKR_OK == *pError ) { michael@0: *pError = CKR_HOST_MEMORY; michael@0: } michael@0: goto done; michael@0: } michael@0: michael@0: fwObject = nssCKFWObject_Create(objArena, mdObject, michael@0: NULL, fwFindObjects->fwToken, michael@0: fwFindObjects->fwInstance, pError); michael@0: if (!fwObject) { michael@0: if( CKR_OK == *pError ) { michael@0: *pError = CKR_GENERAL_ERROR; michael@0: } michael@0: } michael@0: michael@0: done: michael@0: (void)nssCKFWMutex_Unlock(fwFindObjects->mutex); michael@0: return fwObject; michael@0: } michael@0: michael@0: /* michael@0: * NSSCKFWFindObjects_GetMDFindObjects michael@0: * michael@0: */ michael@0: michael@0: NSS_EXTERN NSSCKMDFindObjects * michael@0: NSSCKFWFindObjects_GetMDFindObjects michael@0: ( michael@0: NSSCKFWFindObjects *fwFindObjects michael@0: ) michael@0: { michael@0: #ifdef DEBUG michael@0: if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) { michael@0: return (NSSCKMDFindObjects *)NULL; michael@0: } michael@0: #endif /* DEBUG */ michael@0: michael@0: return nssCKFWFindObjects_GetMDFindObjects(fwFindObjects); michael@0: }