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