instance.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,311 行 · 第 1/2 页

C
1,311
字号
/*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape security libraries. *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#ifdef DEBUGstatic const char CVS_ID[] = "@(#) $RCSfile: instance.c,v $ $Revision: 1.3 $ $Date: 2000/09/06 22:23:55 $ $Name: NSS_3_1_1_RTM $";#endif /* DEBUG *//* * 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 * *  -- implement public accessors -- *  nssCKFWInstance_GetMDInstance *  nssCKFWInstance_GetArena *  nssCKFWInstance_MayCreatePthreads *  nssCKFWInstance_CreateMutex *  nssCKFWInstance_GetConfigurationData * *  -- 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_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_RVinstance_add_pointer(  const NSSCKFWInstance *fwInstance){  return CKR_OK;}static CK_RVinstance_remove_pointer(  const NSSCKFWInstance *fwInstance){  return CKR_OK;}NSS_IMPLEMENT CK_RVnssCKFWInstance_verifyPointer(  const NSSCKFWInstance *fwInstance){  return CKR_OK;}#endif /* DEBUG *//* * nssCKFWInstance_Create * */NSS_IMPLEMENT NSSCKFWInstance *nssCKFWInstance_Create(  CK_C_INITIALIZE_ARGS_PTR pInitArgs,  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( (NSSCKMDInstance *)NULL == mdInstance ) {    *pError = CKR_ARGUMENTS_BAD;    return (NSSCKFWInstance *)NULL;  }#endif /* NSSDEBUG */  arena = NSSArena_Create();  if( (NSSArena *)NULL == arena ) {    *pError = CKR_HOST_MEMORY;    return (NSSCKFWInstance *)NULL;  }  fwInstance = nss_ZNEW(arena, NSSCKFWInstance);  if( (NSSCKFWInstance *)NULL == fwInstance ) {    goto nomem;  }  fwInstance->arena = arena;  fwInstance->mdInstance = mdInstance;  fwInstance->pInitArgs = pInitArgs;  if( (CK_C_INITIALIZE_ARGS_PTR)NULL != pInitArgs ) {    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, arena, pError);  if( (NSSCKFWMutex *)NULL == fwInstance->mutex ) {    if( CKR_OK == *pError ) {      *pError = CKR_GENERAL_ERROR;    }    goto loser;  }  if( (void *)NULL != (void *)mdInstance->Initialize ) {    *pError = mdInstance->Initialize(mdInstance, fwInstance, fwInstance->configurationData);    if( CKR_OK != *pError ) {      goto loser;    }    called_Initialize = CK_TRUE;  }  if( (void *)NULL != (void *)mdInstance->ModuleHandlesSessionObjects ) {    fwInstance->moduleHandlesSessionObjects =       mdInstance->ModuleHandlesSessionObjects(mdInstance, fwInstance);  } else {    fwInstance->moduleHandlesSessionObjects = CK_FALSE;  }  if( (void *)NULL == (void *)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( (nssCKFWHash *)NULL == fwInstance->sessionHandleHash ) {    goto loser;  }  fwInstance->objectHandleHash = nssCKFWHash_Create(fwInstance,    fwInstance->arena, pError);  if( (nssCKFWHash *)NULL == fwInstance->objectHandleHash ) {    goto loser;  }  if( (void *)NULL == (void *)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( (NSSCKMDSlot *)NULL == 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( (void *)NULL != (void *)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( (void *)NULL != (void *)mdInstance->Finalize ) {      mdInstance->Finalize(mdInstance, fwInstance);    }  }  (void)NSSArena_Destroy(arena);  return (NSSCKFWInstance *)NULL;}/* * nssCKFWInstance_Destroy * */NSS_IMPLEMENT CK_RVnssCKFWInstance_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( (void *)NULL != (void *)fwInstance->mdInstance->Finalize ) {    fwInstance->mdInstance->Finalize(fwInstance->mdInstance, fwInstance);  }#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( (CK_RV *)NULL == 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_BBOOLnssCKFWInstance_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( (CK_RV *)NULL == pError ) {    return (NSSCKFWMutex *)NULL;  }  *pError = nssCKFWInstance_verifyPointer(fwInstance);  if( CKR_OK != *pError ) {    return (NSSCKFWMutex *)NULL;  }#endif /* NSSDEBUG */  if( (NSSArena *)NULL == arena ) {    arena = fwInstance->arena;  }  mutex = nssCKFWMutex_Create(fwInstance->pInitArgs, arena, pError);  if( (NSSCKFWMutex *)NULL == 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_CreateSessionHandle * */NSS_IMPLEMENT CK_SESSION_HANDLEnssCKFWInstance_CreateSessionHandle(  NSSCKFWInstance *fwInstance,  NSSCKFWSession *fwSession,  CK_RV *pError){  CK_SESSION_HANDLE hSession;#ifdef NSSDEBUG  if( (CK_RV *)NULL == 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 voidnssCKFWInstance_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);  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_HANDLEnssCKFWInstance_FindSessionHandle(  NSSCKFWInstance *fwInstance,  NSSCKFWSession *fwSession){#ifdef NSSDEBUG

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?