Mercurial > trustbridge > nss-cmake-static
diff nss/lib/ckfw/instance.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nss/lib/ckfw/instance.c Mon Jul 28 10:47:06 2014 +0200 @@ -0,0 +1,1340 @@ +/* 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/. */ + +/* + * instance.c + * + * This file implements the NSSCKFWInstance type and methods. + */ + +#ifndef CK_T +#include "ck.h" +#endif /* CK_T */ + +/* + * NSSCKFWInstance + * + * -- create/destroy -- + * nssCKFWInstance_Create + * nssCKFWInstance_Destroy + * + * -- public accessors -- + * NSSCKFWInstance_GetMDInstance + * NSSCKFWInstance_GetArena + * NSSCKFWInstance_MayCreatePthreads + * NSSCKFWInstance_CreateMutex + * NSSCKFWInstance_GetConfigurationData + * NSSCKFWInstance_GetInitArgs + * + * -- implement public accessors -- + * nssCKFWInstance_GetMDInstance + * nssCKFWInstance_GetArena + * nssCKFWInstance_MayCreatePthreads + * nssCKFWInstance_CreateMutex + * nssCKFWInstance_GetConfigurationData + * nssCKFWInstance_GetInitArgs + * + * -- private accessors -- + * nssCKFWInstance_CreateSessionHandle + * nssCKFWInstance_ResolveSessionHandle + * nssCKFWInstance_DestroySessionHandle + * nssCKFWInstance_FindSessionHandle + * nssCKFWInstance_CreateObjectHandle + * nssCKFWInstance_ResolveObjectHandle + * nssCKFWInstance_DestroyObjectHandle + * + * -- module fronts -- + * nssCKFWInstance_GetNSlots + * nssCKFWInstance_GetCryptokiVersion + * nssCKFWInstance_GetManufacturerID + * nssCKFWInstance_GetFlags + * nssCKFWInstance_GetLibraryDescription + * nssCKFWInstance_GetLibraryVersion + * nssCKFWInstance_GetModuleHandlesSessionObjects + * nssCKFWInstance_GetSlots + * nssCKFWInstance_WaitForSlotEvent + * + * -- debugging versions only -- + * nssCKFWInstance_verifyPointer + */ + +struct NSSCKFWInstanceStr { + NSSCKFWMutex *mutex; + NSSArena *arena; + NSSCKMDInstance *mdInstance; + CK_C_INITIALIZE_ARGS_PTR pInitArgs; + CK_C_INITIALIZE_ARGS initArgs; + CryptokiLockingState LockingState; + CK_BBOOL mayCreatePthreads; + NSSUTF8 *configurationData; + CK_ULONG nSlots; + NSSCKFWSlot **fwSlotList; + NSSCKMDSlot **mdSlotList; + CK_BBOOL moduleHandlesSessionObjects; + + /* + * Everything above is set at creation time, and then not modified. + * The invariants the mutex protects are: + * + * 1) Each of the cached descriptions (versions, etc.) are in an + * internally consistant state. + * + * 2) The session handle hashes and count are consistant + * + * 3) The object handle hashes and count are consistant. + * + * I could use multiple locks, but let's wait to see if that's + * really necessary. + * + * Note that the calls accessing the cached descriptions will + * call the NSSCKMDInstance methods with the mutex locked. Those + * methods may then call the public NSSCKFWInstance routines. + * Those public routines only access the constant data above, so + * there's no problem. But be careful if you add to this object; + * mutexes are in general not reentrant, so don't create deadlock + * situations. + */ + + CK_VERSION cryptokiVersion; + NSSUTF8 *manufacturerID; + NSSUTF8 *libraryDescription; + CK_VERSION libraryVersion; + + CK_ULONG lastSessionHandle; + nssCKFWHash *sessionHandleHash; + + CK_ULONG lastObjectHandle; + nssCKFWHash *objectHandleHash; +}; + +#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 +instance_add_pointer +( + const NSSCKFWInstance *fwInstance +) +{ + return CKR_OK; +} + +static CK_RV +instance_remove_pointer +( + const NSSCKFWInstance *fwInstance +) +{ + return CKR_OK; +} + +NSS_IMPLEMENT CK_RV +nssCKFWInstance_verifyPointer +( + const NSSCKFWInstance *fwInstance +) +{ + return CKR_OK; +} + +#endif /* DEBUG */ + +/* + * nssCKFWInstance_Create + * + */ +NSS_IMPLEMENT NSSCKFWInstance * +nssCKFWInstance_Create +( + CK_C_INITIALIZE_ARGS_PTR pInitArgs, + CryptokiLockingState LockingState, + NSSCKMDInstance *mdInstance, + CK_RV *pError +) +{ + NSSCKFWInstance *fwInstance; + NSSArena *arena = (NSSArena *)NULL; + CK_ULONG i; + CK_BBOOL called_Initialize = CK_FALSE; + +#ifdef NSSDEBUG + if( (CK_RV)NULL == pError ) { + return (NSSCKFWInstance *)NULL; + } + + if (!mdInstance) { + *pError = CKR_ARGUMENTS_BAD; + return (NSSCKFWInstance *)NULL; + } +#endif /* NSSDEBUG */ + + arena = NSSArena_Create(); + if (!arena) { + *pError = CKR_HOST_MEMORY; + return (NSSCKFWInstance *)NULL; + } + + fwInstance = nss_ZNEW(arena, NSSCKFWInstance); + if (!fwInstance) { + goto nomem; + } + + fwInstance->arena = arena; + fwInstance->mdInstance = mdInstance; + + fwInstance->LockingState = LockingState; + if( (CK_C_INITIALIZE_ARGS_PTR)NULL != pInitArgs ) { + fwInstance->initArgs = *pInitArgs; + fwInstance->pInitArgs = &fwInstance->initArgs; + if( pInitArgs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS ) { + fwInstance->mayCreatePthreads = CK_FALSE; + } else { + fwInstance->mayCreatePthreads = CK_TRUE; + } + fwInstance->configurationData = (NSSUTF8 *)(pInitArgs->pReserved); + } else { + fwInstance->mayCreatePthreads = CK_TRUE; + } + + fwInstance->mutex = nssCKFWMutex_Create(pInitArgs, LockingState, arena, + pError); + if (!fwInstance->mutex) { + if( CKR_OK == *pError ) { + *pError = CKR_GENERAL_ERROR; + } + goto loser; + } + + if (mdInstance->Initialize) { + *pError = mdInstance->Initialize(mdInstance, fwInstance, fwInstance->configurationData); + if( CKR_OK != *pError ) { + goto loser; + } + + called_Initialize = CK_TRUE; + } + + if (mdInstance->ModuleHandlesSessionObjects) { + fwInstance->moduleHandlesSessionObjects = + mdInstance->ModuleHandlesSessionObjects(mdInstance, fwInstance); + } else { + fwInstance->moduleHandlesSessionObjects = CK_FALSE; + } + + if (!mdInstance->GetNSlots) { + /* That routine is required */ + *pError = CKR_GENERAL_ERROR; + goto loser; + } + + fwInstance->nSlots = mdInstance->GetNSlots(mdInstance, fwInstance, pError); + if( (CK_ULONG)0 == fwInstance->nSlots ) { + if( CKR_OK == *pError ) { + /* Zero is not a legitimate answer */ + *pError = CKR_GENERAL_ERROR; + } + goto loser; + } + + fwInstance->fwSlotList = nss_ZNEWARRAY(arena, NSSCKFWSlot *, fwInstance->nSlots); + if( (NSSCKFWSlot **)NULL == fwInstance->fwSlotList ) { + goto nomem; + } + + fwInstance->mdSlotList = nss_ZNEWARRAY(arena, NSSCKMDSlot *, fwInstance->nSlots); + if( (NSSCKMDSlot **)NULL == fwInstance->mdSlotList ) { + goto nomem; + } + + fwInstance->sessionHandleHash = nssCKFWHash_Create(fwInstance, + fwInstance->arena, pError); + if (!fwInstance->sessionHandleHash) { + goto loser; + } + + fwInstance->objectHandleHash = nssCKFWHash_Create(fwInstance, + fwInstance->arena, pError); + if (!fwInstance->objectHandleHash) { + goto loser; + } + + if (!mdInstance->GetSlots) { + /* That routine is required */ + *pError = CKR_GENERAL_ERROR; + goto loser; + } + + *pError = mdInstance->GetSlots(mdInstance, fwInstance, fwInstance->mdSlotList); + if( CKR_OK != *pError ) { + goto loser; + } + + for( i = 0; i < fwInstance->nSlots; i++ ) { + NSSCKMDSlot *mdSlot = fwInstance->mdSlotList[i]; + + if (!mdSlot) { + *pError = CKR_GENERAL_ERROR; + goto loser; + } + + fwInstance->fwSlotList[i] = nssCKFWSlot_Create(fwInstance, mdSlot, i, pError); + if( CKR_OK != *pError ) { + CK_ULONG j; + + for( j = 0; j < i; j++ ) { + (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[j]); + } + + for( j = i; j < fwInstance->nSlots; j++ ) { + NSSCKMDSlot *mds = fwInstance->mdSlotList[j]; + if (mds->Destroy) { + mds->Destroy(mds, (NSSCKFWSlot *)NULL, mdInstance, fwInstance); + } + } + + goto loser; + } + } + +#ifdef DEBUG + *pError = instance_add_pointer(fwInstance); + if( CKR_OK != *pError ) { + for( i = 0; i < fwInstance->nSlots; i++ ) { + (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]); + } + + goto loser; + } +#endif /* DEBUG */ + + *pError = CKR_OK; + return fwInstance; + + nomem: + *pError = CKR_HOST_MEMORY; + /*FALLTHROUGH*/ + loser: + + if( CK_TRUE == called_Initialize ) { + if (mdInstance->Finalize) { + mdInstance->Finalize(mdInstance, fwInstance); + } + } + + if (fwInstance && fwInstance->mutex) { + nssCKFWMutex_Destroy(fwInstance->mutex); + } + + if (arena) { + (void)NSSArena_Destroy(arena); + } + return (NSSCKFWInstance *)NULL; +} + +/* + * nssCKFWInstance_Destroy + * + */ +NSS_IMPLEMENT CK_RV +nssCKFWInstance_Destroy +( + NSSCKFWInstance *fwInstance +) +{ +#ifdef NSSDEBUG + CK_RV error = CKR_OK; +#endif /* NSSDEBUG */ + CK_ULONG i; + +#ifdef NSSDEBUG + error = nssCKFWInstance_verifyPointer(fwInstance); + if( CKR_OK != error ) { + return error; + } +#endif /* NSSDEBUG */ + + nssCKFWMutex_Destroy(fwInstance->mutex); + + for( i = 0; i < fwInstance->nSlots; i++ ) { + (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]); + } + + if (fwInstance->mdInstance->Finalize) { + fwInstance->mdInstance->Finalize(fwInstance->mdInstance, fwInstance); + } + + if (fwInstance->sessionHandleHash) { + nssCKFWHash_Destroy(fwInstance->sessionHandleHash); + } + + if (fwInstance->objectHandleHash) { + nssCKFWHash_Destroy(fwInstance->objectHandleHash); + } + +#ifdef DEBUG + (void)instance_remove_pointer(fwInstance); +#endif /* DEBUG */ + + (void)NSSArena_Destroy(fwInstance->arena); + return CKR_OK; +} + +/* + * nssCKFWInstance_GetMDInstance + * + */ +NSS_IMPLEMENT NSSCKMDInstance * +nssCKFWInstance_GetMDInstance +( + NSSCKFWInstance *fwInstance +) +{ +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return (NSSCKMDInstance *)NULL; + } +#endif /* NSSDEBUG */ + + return fwInstance->mdInstance; +} + +/* + * nssCKFWInstance_GetArena + * + */ +NSS_IMPLEMENT NSSArena * +nssCKFWInstance_GetArena +( + NSSCKFWInstance *fwInstance, + CK_RV *pError +) +{ +#ifdef NSSDEBUG + if (!pError) { + return (NSSArena *)NULL; + } + + *pError = nssCKFWInstance_verifyPointer(fwInstance); + if( CKR_OK != *pError ) { + return (NSSArena *)NULL; + } +#endif /* NSSDEBUG */ + + *pError = CKR_OK; + return fwInstance->arena; +} + +/* + * nssCKFWInstance_MayCreatePthreads + * + */ +NSS_IMPLEMENT CK_BBOOL +nssCKFWInstance_MayCreatePthreads +( + NSSCKFWInstance *fwInstance +) +{ +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return CK_FALSE; + } +#endif /* NSSDEBUG */ + + return fwInstance->mayCreatePthreads; +} + +/* + * nssCKFWInstance_CreateMutex + * + */ +NSS_IMPLEMENT NSSCKFWMutex * +nssCKFWInstance_CreateMutex +( + NSSCKFWInstance *fwInstance, + NSSArena *arena, + CK_RV *pError +) +{ + NSSCKFWMutex *mutex; + +#ifdef NSSDEBUG + if (!pError) { + return (NSSCKFWMutex *)NULL; + } + + *pError = nssCKFWInstance_verifyPointer(fwInstance); + if( CKR_OK != *pError ) { + return (NSSCKFWMutex *)NULL; + } +#endif /* NSSDEBUG */ + + mutex = nssCKFWMutex_Create(fwInstance->pInitArgs, fwInstance->LockingState, + arena, pError); + if (!mutex) { + if( CKR_OK == *pError ) { + *pError = CKR_GENERAL_ERROR; + } + + return (NSSCKFWMutex *)NULL; + } + + return mutex; +} + +/* + * nssCKFWInstance_GetConfigurationData + * + */ +NSS_IMPLEMENT NSSUTF8 * +nssCKFWInstance_GetConfigurationData +( + NSSCKFWInstance *fwInstance +) +{ +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return (NSSUTF8 *)NULL; + } +#endif /* NSSDEBUG */ + + return fwInstance->configurationData; +} + +/* + * nssCKFWInstance_GetInitArgs + * + */ +CK_C_INITIALIZE_ARGS_PTR +nssCKFWInstance_GetInitArgs +( + NSSCKFWInstance *fwInstance +) +{ +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return (CK_C_INITIALIZE_ARGS_PTR)NULL; + } +#endif /* NSSDEBUG */ + + return fwInstance->pInitArgs; +} + +/* + * nssCKFWInstance_CreateSessionHandle + * + */ +NSS_IMPLEMENT CK_SESSION_HANDLE +nssCKFWInstance_CreateSessionHandle +( + NSSCKFWInstance *fwInstance, + NSSCKFWSession *fwSession, + CK_RV *pError +) +{ + CK_SESSION_HANDLE hSession; + +#ifdef NSSDEBUG + if (!pError) { + return (CK_SESSION_HANDLE)0; + } + + *pError = nssCKFWInstance_verifyPointer(fwInstance); + if( CKR_OK != *pError ) { + return (CK_SESSION_HANDLE)0; + } +#endif /* NSSDEBUG */ + + *pError = nssCKFWMutex_Lock(fwInstance->mutex); + if( CKR_OK != *pError ) { + return (CK_SESSION_HANDLE)0; + } + + hSession = ++(fwInstance->lastSessionHandle); + + /* Alan would say I should unlock for this call. */ + + *pError = nssCKFWSession_SetHandle(fwSession, hSession); + if( CKR_OK != *pError ) { + goto done; + } + + *pError = nssCKFWHash_Add(fwInstance->sessionHandleHash, + (const void *)hSession, (const void *)fwSession); + if( CKR_OK != *pError ) { + hSession = (CK_SESSION_HANDLE)0; + goto done; + } + + done: + nssCKFWMutex_Unlock(fwInstance->mutex); + return hSession; +} + +/* + * nssCKFWInstance_ResolveSessionHandle + * + */ +NSS_IMPLEMENT NSSCKFWSession * +nssCKFWInstance_ResolveSessionHandle +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession +) +{ + NSSCKFWSession *fwSession; + +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return (NSSCKFWSession *)NULL; + } +#endif /* NSSDEBUG */ + + if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) { + return (NSSCKFWSession *)NULL; + } + + fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup( + fwInstance->sessionHandleHash, (const void *)hSession); + + /* Assert(hSession == nssCKFWSession_GetHandle(fwSession)) */ + + (void)nssCKFWMutex_Unlock(fwInstance->mutex); + + return fwSession; +} + +/* + * nssCKFWInstance_DestroySessionHandle + * + */ +NSS_IMPLEMENT void +nssCKFWInstance_DestroySessionHandle +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession +) +{ + NSSCKFWSession *fwSession; + +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return; + } +#endif /* NSSDEBUG */ + + if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) { + return; + } + + fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup( + fwInstance->sessionHandleHash, (const void *)hSession); + if (fwSession) { + nssCKFWHash_Remove(fwInstance->sessionHandleHash, (const void *)hSession); + nssCKFWSession_SetHandle(fwSession, (CK_SESSION_HANDLE)0); + } + + (void)nssCKFWMutex_Unlock(fwInstance->mutex); + + return; +} + +/* + * nssCKFWInstance_FindSessionHandle + * + */ +NSS_IMPLEMENT CK_SESSION_HANDLE +nssCKFWInstance_FindSessionHandle +( + NSSCKFWInstance *fwInstance, + NSSCKFWSession *fwSession +) +{ +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return (CK_SESSION_HANDLE)0; + } + + if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) { + return (CK_SESSION_HANDLE)0; + } +#endif /* NSSDEBUG */ + + return nssCKFWSession_GetHandle(fwSession); + /* look it up and assert? */ +} + +/* + * nssCKFWInstance_CreateObjectHandle + * + */ +NSS_IMPLEMENT CK_OBJECT_HANDLE +nssCKFWInstance_CreateObjectHandle +( + NSSCKFWInstance *fwInstance, + NSSCKFWObject *fwObject, + CK_RV *pError +) +{ + CK_OBJECT_HANDLE hObject; + +#ifdef NSSDEBUG + if (!pError) { + return (CK_OBJECT_HANDLE)0; + } + + *pError = nssCKFWInstance_verifyPointer(fwInstance); + if( CKR_OK != *pError ) { + return (CK_OBJECT_HANDLE)0; + } +#endif /* NSSDEBUG */ + + *pError = nssCKFWMutex_Lock(fwInstance->mutex); + if( CKR_OK != *pError ) { + return (CK_OBJECT_HANDLE)0; + } + + hObject = ++(fwInstance->lastObjectHandle); + + *pError = nssCKFWObject_SetHandle(fwObject, hObject); + if( CKR_OK != *pError ) { + hObject = (CK_OBJECT_HANDLE)0; + goto done; + } + + *pError = nssCKFWHash_Add(fwInstance->objectHandleHash, + (const void *)hObject, (const void *)fwObject); + if( CKR_OK != *pError ) { + hObject = (CK_OBJECT_HANDLE)0; + goto done; + } + + done: + (void)nssCKFWMutex_Unlock(fwInstance->mutex); + return hObject; +} + +/* + * nssCKFWInstance_ResolveObjectHandle + * + */ +NSS_IMPLEMENT NSSCKFWObject * +nssCKFWInstance_ResolveObjectHandle +( + NSSCKFWInstance *fwInstance, + CK_OBJECT_HANDLE hObject +) +{ + NSSCKFWObject *fwObject; + +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return (NSSCKFWObject *)NULL; + } +#endif /* NSSDEBUG */ + + if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) { + return (NSSCKFWObject *)NULL; + } + + fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup( + fwInstance->objectHandleHash, (const void *)hObject); + + /* Assert(hObject == nssCKFWObject_GetHandle(fwObject)) */ + + (void)nssCKFWMutex_Unlock(fwInstance->mutex); + return fwObject; +} + +/* + * nssCKFWInstance_ReassignObjectHandle + * + */ +NSS_IMPLEMENT CK_RV +nssCKFWInstance_ReassignObjectHandle +( + NSSCKFWInstance *fwInstance, + CK_OBJECT_HANDLE hObject, + NSSCKFWObject *fwObject +) +{ + CK_RV error = CKR_OK; + NSSCKFWObject *oldObject; + +#ifdef NSSDEBUG + error = nssCKFWInstance_verifyPointer(fwInstance); + if( CKR_OK != error ) { + return error; + } +#endif /* NSSDEBUG */ + + error = nssCKFWMutex_Lock(fwInstance->mutex); + if( CKR_OK != error ) { + return error; + } + + oldObject = (NSSCKFWObject *)nssCKFWHash_Lookup( + fwInstance->objectHandleHash, (const void *)hObject); + if(oldObject) { + /* Assert(hObject == nssCKFWObject_GetHandle(oldObject) */ + (void)nssCKFWObject_SetHandle(oldObject, (CK_SESSION_HANDLE)0); + nssCKFWHash_Remove(fwInstance->objectHandleHash, (const void *)hObject); + } + + error = nssCKFWObject_SetHandle(fwObject, hObject); + if( CKR_OK != error ) { + goto done; + } + error = nssCKFWHash_Add(fwInstance->objectHandleHash, + (const void *)hObject, (const void *)fwObject); + + done: + (void)nssCKFWMutex_Unlock(fwInstance->mutex); + return error; +} + +/* + * nssCKFWInstance_DestroyObjectHandle + * + */ +NSS_IMPLEMENT void +nssCKFWInstance_DestroyObjectHandle +( + NSSCKFWInstance *fwInstance, + CK_OBJECT_HANDLE hObject +) +{ + NSSCKFWObject *fwObject; + +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return; + } +#endif /* NSSDEBUG */ + + if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) { + return; + } + + fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup( + fwInstance->objectHandleHash, (const void *)hObject); + if (fwObject) { + /* Assert(hObject = nssCKFWObject_GetHandle(fwObject)) */ + nssCKFWHash_Remove(fwInstance->objectHandleHash, (const void *)hObject); + (void)nssCKFWObject_SetHandle(fwObject, (CK_SESSION_HANDLE)0); + } + + (void)nssCKFWMutex_Unlock(fwInstance->mutex); + return; +} + +/* + * nssCKFWInstance_FindObjectHandle + * + */ +NSS_IMPLEMENT CK_OBJECT_HANDLE +nssCKFWInstance_FindObjectHandle +( + NSSCKFWInstance *fwInstance, + NSSCKFWObject *fwObject +) +{ +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return (CK_OBJECT_HANDLE)0; + } + + if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { + return (CK_OBJECT_HANDLE)0; + } +#endif /* NSSDEBUG */ + + return nssCKFWObject_GetHandle(fwObject); +} + +/* + * nssCKFWInstance_GetNSlots + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWInstance_GetNSlots +( + NSSCKFWInstance *fwInstance, + CK_RV *pError +) +{ +#ifdef NSSDEBUG + if (!pError) { + return (CK_ULONG)0; + } + + *pError = nssCKFWInstance_verifyPointer(fwInstance); + if( CKR_OK != *pError ) { + return (CK_ULONG)0; + } +#endif /* NSSDEBUG */ + + *pError = CKR_OK; + return fwInstance->nSlots; +} + +/* + * nssCKFWInstance_GetCryptokiVersion + * + */ +NSS_IMPLEMENT CK_VERSION +nssCKFWInstance_GetCryptokiVersion +( + NSSCKFWInstance *fwInstance +) +{ + CK_VERSION rv; + +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + rv.major = rv.minor = 0; + return rv; + } +#endif /* NSSDEBUG */ + + if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) { + rv.major = rv.minor = 0; + return rv; + } + + if( (0 != fwInstance->cryptokiVersion.major) || + (0 != fwInstance->cryptokiVersion.minor) ) { + rv = fwInstance->cryptokiVersion; + goto done; + } + + if (fwInstance->mdInstance->GetCryptokiVersion) { + fwInstance->cryptokiVersion = fwInstance->mdInstance->GetCryptokiVersion( + fwInstance->mdInstance, fwInstance); + } else { + fwInstance->cryptokiVersion.major = 2; + fwInstance->cryptokiVersion.minor = 1; + } + + rv = fwInstance->cryptokiVersion; + + done: + (void)nssCKFWMutex_Unlock(fwInstance->mutex); + return rv; +} + +/* + * nssCKFWInstance_GetManufacturerID + * + */ +NSS_IMPLEMENT CK_RV +nssCKFWInstance_GetManufacturerID +( + NSSCKFWInstance *fwInstance, + CK_CHAR manufacturerID[32] +) +{ + CK_RV error = CKR_OK; + +#ifdef NSSDEBUG + if( (CK_CHAR_PTR)NULL == manufacturerID ) { + return CKR_ARGUMENTS_BAD; + } + + error = nssCKFWInstance_verifyPointer(fwInstance); + if( CKR_OK != error ) { + return error; + } +#endif /* NSSDEBUG */ + + error = nssCKFWMutex_Lock(fwInstance->mutex); + if( CKR_OK != error ) { + return error; + } + + if (!fwInstance->manufacturerID) { + if (fwInstance->mdInstance->GetManufacturerID) { + fwInstance->manufacturerID = fwInstance->mdInstance->GetManufacturerID( + fwInstance->mdInstance, fwInstance, &error); + if ((!fwInstance->manufacturerID) && (CKR_OK != error)) { + goto done; + } + } else { + fwInstance->manufacturerID = (NSSUTF8 *) ""; + } + } + + (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->manufacturerID, (char *)manufacturerID, 32, ' '); + error = CKR_OK; + + done: + (void)nssCKFWMutex_Unlock(fwInstance->mutex); + return error; +} + +/* + * nssCKFWInstance_GetFlags + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWInstance_GetFlags +( + NSSCKFWInstance *fwInstance +) +{ +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return (CK_ULONG)0; + } +#endif /* NSSDEBUG */ + + /* No "instance flags" are yet defined by Cryptoki. */ + return (CK_ULONG)0; +} + +/* + * nssCKFWInstance_GetLibraryDescription + * + */ +NSS_IMPLEMENT CK_RV +nssCKFWInstance_GetLibraryDescription +( + NSSCKFWInstance *fwInstance, + CK_CHAR libraryDescription[32] +) +{ + CK_RV error = CKR_OK; + +#ifdef NSSDEBUG + if( (CK_CHAR_PTR)NULL == libraryDescription ) { + return CKR_ARGUMENTS_BAD; + } + + error = nssCKFWInstance_verifyPointer(fwInstance); + if( CKR_OK != error ) { + return error; + } +#endif /* NSSDEBUG */ + + error = nssCKFWMutex_Lock(fwInstance->mutex); + if( CKR_OK != error ) { + return error; + } + + if (!fwInstance->libraryDescription) { + if (fwInstance->mdInstance->GetLibraryDescription) { + fwInstance->libraryDescription = fwInstance->mdInstance->GetLibraryDescription( + fwInstance->mdInstance, fwInstance, &error); + if ((!fwInstance->libraryDescription) && (CKR_OK != error)) { + goto done; + } + } else { + fwInstance->libraryDescription = (NSSUTF8 *) ""; + } + } + + (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->libraryDescription, (char *)libraryDescription, 32, ' '); + error = CKR_OK; + + done: + (void)nssCKFWMutex_Unlock(fwInstance->mutex); + return error; +} + +/* + * nssCKFWInstance_GetLibraryVersion + * + */ +NSS_IMPLEMENT CK_VERSION +nssCKFWInstance_GetLibraryVersion +( + NSSCKFWInstance *fwInstance +) +{ + CK_VERSION rv; + +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + rv.major = rv.minor = 0; + return rv; + } +#endif /* NSSDEBUG */ + + if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) { + rv.major = rv.minor = 0; + return rv; + } + + if( (0 != fwInstance->libraryVersion.major) || + (0 != fwInstance->libraryVersion.minor) ) { + rv = fwInstance->libraryVersion; + goto done; + } + + if (fwInstance->mdInstance->GetLibraryVersion) { + fwInstance->libraryVersion = fwInstance->mdInstance->GetLibraryVersion( + fwInstance->mdInstance, fwInstance); + } else { + fwInstance->libraryVersion.major = 0; + fwInstance->libraryVersion.minor = 3; + } + + rv = fwInstance->libraryVersion; + done: + (void)nssCKFWMutex_Unlock(fwInstance->mutex); + return rv; +} + +/* + * nssCKFWInstance_GetModuleHandlesSessionObjects + * + */ +NSS_IMPLEMENT CK_BBOOL +nssCKFWInstance_GetModuleHandlesSessionObjects +( + NSSCKFWInstance *fwInstance +) +{ +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return CK_FALSE; + } +#endif /* NSSDEBUG */ + + return fwInstance->moduleHandlesSessionObjects; +} + +/* + * nssCKFWInstance_GetSlots + * + */ +NSS_IMPLEMENT NSSCKFWSlot ** +nssCKFWInstance_GetSlots +( + NSSCKFWInstance *fwInstance, + CK_RV *pError +) +{ +#ifdef NSSDEBUG + if (!pError) { + return (NSSCKFWSlot **)NULL; + } + + *pError = nssCKFWInstance_verifyPointer(fwInstance); + if( CKR_OK != *pError ) { + return (NSSCKFWSlot **)NULL; + } +#endif /* NSSDEBUG */ + + return fwInstance->fwSlotList; +} + +/* + * nssCKFWInstance_WaitForSlotEvent + * + */ +NSS_IMPLEMENT NSSCKFWSlot * +nssCKFWInstance_WaitForSlotEvent +( + NSSCKFWInstance *fwInstance, + CK_BBOOL block, + CK_RV *pError +) +{ + NSSCKFWSlot *fwSlot = (NSSCKFWSlot *)NULL; + NSSCKMDSlot *mdSlot; + CK_ULONG i, n; + +#ifdef NSSDEBUG + if (!pError) { + return (NSSCKFWSlot *)NULL; + } + + *pError = nssCKFWInstance_verifyPointer(fwInstance); + if( CKR_OK != *pError ) { + return (NSSCKFWSlot *)NULL; + } + + switch( block ) { + case CK_TRUE: + case CK_FALSE: + break; + default: + *pError = CKR_ARGUMENTS_BAD; + return (NSSCKFWSlot *)NULL; + } +#endif /* NSSDEBUG */ + + if (!fwInstance->mdInstance->WaitForSlotEvent) { + *pError = CKR_NO_EVENT; + return (NSSCKFWSlot *)NULL; + } + + mdSlot = fwInstance->mdInstance->WaitForSlotEvent( + fwInstance->mdInstance, + fwInstance, + block, + pError + ); + + if (!mdSlot) { + return (NSSCKFWSlot *)NULL; + } + + n = nssCKFWInstance_GetNSlots(fwInstance, pError); + if( ((CK_ULONG)0 == n) && (CKR_OK != *pError) ) { + return (NSSCKFWSlot *)NULL; + } + + for( i = 0; i < n; i++ ) { + if( fwInstance->mdSlotList[i] == mdSlot ) { + fwSlot = fwInstance->fwSlotList[i]; + break; + } + } + + if (!fwSlot) { + /* Internal error */ + *pError = CKR_GENERAL_ERROR; + return (NSSCKFWSlot *)NULL; + } + + return fwSlot; +} + +/* + * NSSCKFWInstance_GetMDInstance + * + */ +NSS_IMPLEMENT NSSCKMDInstance * +NSSCKFWInstance_GetMDInstance +( + NSSCKFWInstance *fwInstance +) +{ +#ifdef DEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return (NSSCKMDInstance *)NULL; + } +#endif /* DEBUG */ + + return nssCKFWInstance_GetMDInstance(fwInstance); +} + +/* + * NSSCKFWInstance_GetArena + * + */ +NSS_IMPLEMENT NSSArena * +NSSCKFWInstance_GetArena +( + NSSCKFWInstance *fwInstance, + CK_RV *pError +) +{ +#ifdef DEBUG + if (!pError) { + return (NSSArena *)NULL; + } + + *pError = nssCKFWInstance_verifyPointer(fwInstance); + if( CKR_OK != *pError ) { + return (NSSArena *)NULL; + } +#endif /* DEBUG */ + + return nssCKFWInstance_GetArena(fwInstance, pError); +} + +/* + * NSSCKFWInstance_MayCreatePthreads + * + */ +NSS_IMPLEMENT CK_BBOOL +NSSCKFWInstance_MayCreatePthreads +( + NSSCKFWInstance *fwInstance +) +{ +#ifdef DEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return CK_FALSE; + } +#endif /* DEBUG */ + + return nssCKFWInstance_MayCreatePthreads(fwInstance); +} + +/* + * NSSCKFWInstance_CreateMutex + * + */ +NSS_IMPLEMENT NSSCKFWMutex * +NSSCKFWInstance_CreateMutex +( + NSSCKFWInstance *fwInstance, + NSSArena *arena, + CK_RV *pError +) +{ +#ifdef DEBUG + if (!pError) { + return (NSSCKFWMutex *)NULL; + } + + *pError = nssCKFWInstance_verifyPointer(fwInstance); + if( CKR_OK != *pError ) { + return (NSSCKFWMutex *)NULL; + } +#endif /* DEBUG */ + + return nssCKFWInstance_CreateMutex(fwInstance, arena, pError); +} + +/* + * NSSCKFWInstance_GetConfigurationData + * + */ +NSS_IMPLEMENT NSSUTF8 * +NSSCKFWInstance_GetConfigurationData +( + NSSCKFWInstance *fwInstance +) +{ +#ifdef DEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return (NSSUTF8 *)NULL; + } +#endif /* DEBUG */ + + return nssCKFWInstance_GetConfigurationData(fwInstance); +} + +/* + * NSSCKFWInstance_GetInitArgs + * + */ +NSS_IMPLEMENT CK_C_INITIALIZE_ARGS_PTR +NSSCKFWInstance_GetInitArgs +( + NSSCKFWInstance *fwInstance +) +{ +#ifdef DEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return (CK_C_INITIALIZE_ARGS_PTR)NULL; + } +#endif /* DEBUG */ + + return nssCKFWInstance_GetInitArgs(fwInstance); +} +