blob: cee56c97c6c2fad23c9a0dc0cf016dc140916eed [file] [log] [blame]
/* 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
* NSSCKFWInstance_DestroySessionHandle
* NSSCKFWInstance_FindSessionHandle
*
* -- implement public accessors --
* nssCKFWInstance_GetMDInstance
* nssCKFWInstance_GetArena
* nssCKFWInstance_MayCreatePthreads
* nssCKFWInstance_CreateMutex
* nssCKFWInstance_GetConfigurationData
* nssCKFWInstance_GetInitArgs
* nssCKFWInstance_DestroySessionHandle
* nssCKFWInstance_FindSessionHandle
*
* -- private accessors --
* nssCKFWInstance_CreateSessionHandle
* nssCKFWInstance_ResolveSessionHandle
* 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);
}
/*
* nssCKFWInstance_DestroySessionHandle
*
*/
NSS_IMPLEMENT void
NSSCKFWInstance_DestroySessionHandle(
NSSCKFWInstance *fwInstance,
CK_SESSION_HANDLE hSession)
{
nssCKFWInstance_DestroySessionHandle(fwInstance, hSession);
}
/*
* nssCKFWInstance_FindSessionHandle
*
*/
NSS_IMPLEMENT CK_SESSION_HANDLE
NSSCKFWInstance_FindSessionHandle(
NSSCKFWInstance *fwInstance,
NSSCKFWSession *fwSession)
{
return nssCKFWInstance_FindSessionHandle(fwInstance, fwSession);
}