| /* 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/. */ |
| |
| /* |
| * find.c |
| * |
| * This file implements the nssCKFWFindObjects type and methods. |
| */ |
| |
| #ifndef CK_H |
| #include "ck.h" |
| #endif /* CK_H */ |
| |
| /* |
| * NSSCKFWFindObjects |
| * |
| * -- create/destroy -- |
| * nssCKFWFindObjects_Create |
| * nssCKFWFindObjects_Destroy |
| * |
| * -- public accessors -- |
| * NSSCKFWFindObjects_GetMDFindObjects |
| * |
| * -- implement public accessors -- |
| * nssCKFWFindObjects_GetMDFindObjects |
| * |
| * -- private accessors -- |
| * |
| * -- module fronts -- |
| * nssCKFWFindObjects_Next |
| */ |
| |
| struct NSSCKFWFindObjectsStr { |
| NSSCKFWMutex *mutex; /* merely to serialise the MDObject calls */ |
| NSSCKMDFindObjects *mdfo1; |
| NSSCKMDFindObjects *mdfo2; |
| NSSCKFWSession *fwSession; |
| NSSCKMDSession *mdSession; |
| NSSCKFWToken *fwToken; |
| NSSCKMDToken *mdToken; |
| NSSCKFWInstance *fwInstance; |
| NSSCKMDInstance *mdInstance; |
| |
| NSSCKMDFindObjects *mdFindObjects; /* varies */ |
| }; |
| |
| #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 these routines as no-ops. |
| */ |
| |
| static CK_RV |
| findObjects_add_pointer( |
| const NSSCKFWFindObjects *fwFindObjects) |
| { |
| return CKR_OK; |
| } |
| |
| static CK_RV |
| findObjects_remove_pointer( |
| const NSSCKFWFindObjects *fwFindObjects) |
| { |
| return CKR_OK; |
| } |
| |
| NSS_IMPLEMENT CK_RV |
| nssCKFWFindObjects_verifyPointer( |
| const NSSCKFWFindObjects *fwFindObjects) |
| { |
| return CKR_OK; |
| } |
| |
| #endif /* DEBUG */ |
| |
| /* |
| * nssCKFWFindObjects_Create |
| * |
| */ |
| NSS_EXTERN NSSCKFWFindObjects * |
| nssCKFWFindObjects_Create( |
| NSSCKFWSession *fwSession, |
| NSSCKFWToken *fwToken, |
| NSSCKFWInstance *fwInstance, |
| NSSCKMDFindObjects *mdFindObjects1, |
| NSSCKMDFindObjects *mdFindObjects2, |
| CK_RV *pError) |
| { |
| NSSCKFWFindObjects *fwFindObjects = NULL; |
| NSSCKMDSession *mdSession; |
| NSSCKMDToken *mdToken; |
| NSSCKMDInstance *mdInstance; |
| |
| mdSession = nssCKFWSession_GetMDSession(fwSession); |
| mdToken = nssCKFWToken_GetMDToken(fwToken); |
| mdInstance = nssCKFWInstance_GetMDInstance(fwInstance); |
| |
| fwFindObjects = nss_ZNEW(NULL, NSSCKFWFindObjects); |
| if (!fwFindObjects) { |
| *pError = CKR_HOST_MEMORY; |
| goto loser; |
| } |
| |
| fwFindObjects->mdfo1 = mdFindObjects1; |
| fwFindObjects->mdfo2 = mdFindObjects2; |
| fwFindObjects->fwSession = fwSession; |
| fwFindObjects->mdSession = mdSession; |
| fwFindObjects->fwToken = fwToken; |
| fwFindObjects->mdToken = mdToken; |
| fwFindObjects->fwInstance = fwInstance; |
| fwFindObjects->mdInstance = mdInstance; |
| |
| fwFindObjects->mutex = nssCKFWInstance_CreateMutex(fwInstance, NULL, pError); |
| if (!fwFindObjects->mutex) { |
| goto loser; |
| } |
| |
| #ifdef DEBUG |
| *pError = findObjects_add_pointer(fwFindObjects); |
| if (CKR_OK != *pError) { |
| goto loser; |
| } |
| #endif /* DEBUG */ |
| |
| return fwFindObjects; |
| |
| loser: |
| if (fwFindObjects) { |
| if (NULL != mdFindObjects1) { |
| if (NULL != mdFindObjects1->Final) { |
| fwFindObjects->mdFindObjects = mdFindObjects1; |
| mdFindObjects1->Final(mdFindObjects1, fwFindObjects, mdSession, |
| fwSession, mdToken, fwToken, mdInstance, fwInstance); |
| } |
| } |
| |
| if (NULL != mdFindObjects2) { |
| if (NULL != mdFindObjects2->Final) { |
| fwFindObjects->mdFindObjects = mdFindObjects2; |
| mdFindObjects2->Final(mdFindObjects2, fwFindObjects, mdSession, |
| fwSession, mdToken, fwToken, mdInstance, fwInstance); |
| } |
| } |
| |
| nss_ZFreeIf(fwFindObjects); |
| } |
| |
| if (CKR_OK == *pError) { |
| *pError = CKR_GENERAL_ERROR; |
| } |
| |
| return (NSSCKFWFindObjects *)NULL; |
| } |
| |
| /* |
| * nssCKFWFindObjects_Destroy |
| * |
| */ |
| NSS_EXTERN void |
| nssCKFWFindObjects_Destroy( |
| NSSCKFWFindObjects *fwFindObjects) |
| { |
| #ifdef NSSDEBUG |
| if (CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects)) { |
| return; |
| } |
| #endif /* NSSDEBUG */ |
| |
| (void)nssCKFWMutex_Destroy(fwFindObjects->mutex); |
| |
| if (fwFindObjects->mdfo1) { |
| if (fwFindObjects->mdfo1->Final) { |
| fwFindObjects->mdFindObjects = fwFindObjects->mdfo1; |
| fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects, |
| fwFindObjects->mdSession, fwFindObjects->fwSession, |
| fwFindObjects->mdToken, fwFindObjects->fwToken, |
| fwFindObjects->mdInstance, fwFindObjects->fwInstance); |
| } |
| } |
| |
| if (fwFindObjects->mdfo2) { |
| if (fwFindObjects->mdfo2->Final) { |
| fwFindObjects->mdFindObjects = fwFindObjects->mdfo2; |
| fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects, |
| fwFindObjects->mdSession, fwFindObjects->fwSession, |
| fwFindObjects->mdToken, fwFindObjects->fwToken, |
| fwFindObjects->mdInstance, fwFindObjects->fwInstance); |
| } |
| } |
| |
| nss_ZFreeIf(fwFindObjects); |
| |
| #ifdef DEBUG |
| (void)findObjects_remove_pointer(fwFindObjects); |
| #endif /* DEBUG */ |
| |
| return; |
| } |
| |
| /* |
| * nssCKFWFindObjects_GetMDFindObjects |
| * |
| */ |
| NSS_EXTERN NSSCKMDFindObjects * |
| nssCKFWFindObjects_GetMDFindObjects( |
| NSSCKFWFindObjects *fwFindObjects) |
| { |
| #ifdef NSSDEBUG |
| if (CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects)) { |
| return (NSSCKMDFindObjects *)NULL; |
| } |
| #endif /* NSSDEBUG */ |
| |
| return fwFindObjects->mdFindObjects; |
| } |
| |
| /* |
| * nssCKFWFindObjects_Next |
| * |
| */ |
| NSS_EXTERN NSSCKFWObject * |
| nssCKFWFindObjects_Next( |
| NSSCKFWFindObjects *fwFindObjects, |
| NSSArena *arenaOpt, |
| CK_RV *pError) |
| { |
| NSSCKMDObject *mdObject; |
| NSSCKFWObject *fwObject = (NSSCKFWObject *)NULL; |
| NSSArena *objArena; |
| |
| #ifdef NSSDEBUG |
| if (!pError) { |
| return (NSSCKFWObject *)NULL; |
| } |
| |
| *pError = nssCKFWFindObjects_verifyPointer(fwFindObjects); |
| if (CKR_OK != *pError) { |
| return (NSSCKFWObject *)NULL; |
| } |
| #endif /* NSSDEBUG */ |
| |
| *pError = nssCKFWMutex_Lock(fwFindObjects->mutex); |
| if (CKR_OK != *pError) { |
| return (NSSCKFWObject *)NULL; |
| } |
| |
| if (fwFindObjects->mdfo1) { |
| if (fwFindObjects->mdfo1->Next) { |
| fwFindObjects->mdFindObjects = fwFindObjects->mdfo1; |
| mdObject = fwFindObjects->mdfo1->Next(fwFindObjects->mdfo1, |
| fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession, |
| fwFindObjects->mdToken, fwFindObjects->fwToken, |
| fwFindObjects->mdInstance, fwFindObjects->fwInstance, |
| arenaOpt, pError); |
| if (!mdObject) { |
| if (CKR_OK != *pError) { |
| goto done; |
| } |
| |
| /* All done. */ |
| fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects, |
| fwFindObjects->mdSession, fwFindObjects->fwSession, |
| fwFindObjects->mdToken, fwFindObjects->fwToken, |
| fwFindObjects->mdInstance, fwFindObjects->fwInstance); |
| fwFindObjects->mdfo1 = (NSSCKMDFindObjects *)NULL; |
| } else { |
| goto wrap; |
| } |
| } |
| } |
| |
| if (fwFindObjects->mdfo2) { |
| if (fwFindObjects->mdfo2->Next) { |
| fwFindObjects->mdFindObjects = fwFindObjects->mdfo2; |
| mdObject = fwFindObjects->mdfo2->Next(fwFindObjects->mdfo2, |
| fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession, |
| fwFindObjects->mdToken, fwFindObjects->fwToken, |
| fwFindObjects->mdInstance, fwFindObjects->fwInstance, |
| arenaOpt, pError); |
| if (!mdObject) { |
| if (CKR_OK != *pError) { |
| goto done; |
| } |
| |
| /* All done. */ |
| fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects, |
| fwFindObjects->mdSession, fwFindObjects->fwSession, |
| fwFindObjects->mdToken, fwFindObjects->fwToken, |
| fwFindObjects->mdInstance, fwFindObjects->fwInstance); |
| fwFindObjects->mdfo2 = (NSSCKMDFindObjects *)NULL; |
| } else { |
| goto wrap; |
| } |
| } |
| } |
| |
| /* No more objects */ |
| *pError = CKR_OK; |
| goto done; |
| |
| wrap: |
| /* |
| * This seems is less than ideal-- we should determine if it's a token |
| * object or a session object, and use the appropriate arena. |
| * But that duplicates logic in nssCKFWObject_IsTokenObject. |
| * Also we should lookup the real session the object was created on |
| * if the object was a session object... however this code is actually |
| * correct because nssCKFWObject_Create will return a cached version of |
| * the object from it's hash. This is necessary because 1) we don't want |
| * to create an arena style leak (where our arena grows with every search), |
| * and 2) we want the same object to always have the same ID. This means |
| * the only case the nssCKFWObject_Create() will need the objArena and the |
| * Session is in the case of token objects (session objects should already |
| * exist in the cache from their initial creation). So this code is correct, |
| * but it depends on nssCKFWObject_Create caching all objects. |
| */ |
| objArena = nssCKFWToken_GetArena(fwFindObjects->fwToken, pError); |
| if (!objArena) { |
| if (CKR_OK == *pError) { |
| *pError = CKR_HOST_MEMORY; |
| } |
| goto done; |
| } |
| |
| fwObject = nssCKFWObject_Create(objArena, mdObject, |
| NULL, fwFindObjects->fwToken, |
| fwFindObjects->fwInstance, pError); |
| if (!fwObject) { |
| if (CKR_OK == *pError) { |
| *pError = CKR_GENERAL_ERROR; |
| } |
| } |
| |
| done: |
| (void)nssCKFWMutex_Unlock(fwFindObjects->mutex); |
| return fwObject; |
| } |
| |
| /* |
| * NSSCKFWFindObjects_GetMDFindObjects |
| * |
| */ |
| |
| NSS_EXTERN NSSCKMDFindObjects * |
| NSSCKFWFindObjects_GetMDFindObjects( |
| NSSCKFWFindObjects *fwFindObjects) |
| { |
| #ifdef DEBUG |
| if (CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects)) { |
| return (NSSCKMDFindObjects *)NULL; |
| } |
| #endif /* DEBUG */ |
| |
| return nssCKFWFindObjects_GetMDFindObjects(fwFindObjects); |
| } |