diff options
Diffstat (limited to 'security/nss/lib/ckfw/find.c')
-rw-r--r-- | security/nss/lib/ckfw/find.c | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/security/nss/lib/ckfw/find.c b/security/nss/lib/ckfw/find.c new file mode 100644 index 000000000..55732e626 --- /dev/null +++ b/security/nss/lib/ckfw/find.c @@ -0,0 +1,362 @@ +/* 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); +} |