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);
+}
+
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)