token.c

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

C
1,865
字号
/*  * 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: token.c,v $ $Revision: 1.4 $ $Date: 2000/09/06 22:23:57 $ $Name: NSS_3_1_1_RTM $";#endif /* DEBUG *//* * token.c * * This file implements the NSSCKFWToken type and methods. */#ifndef CK_T#include "ck.h"#endif /* CK_T *//* * NSSCKFWToken * *  -- create/destroy -- *  nssCKFWToken_Create *  nssCKFWToken_Destroy * *  -- public accessors -- *  NSSCKFWToken_GetMDToken *  NSSCKFWToken_GetFWSlot *  NSSCKFWToken_GetMDSlot *  NSSCKFWToken_GetSessionState * *  -- implement public accessors -- *  nssCKFWToken_GetMDToken *  nssCKFWToken_GetFWSlot *  nssCKFWToken_GetMDSlot *  nssCKFWToken_GetSessionState *  nssCKFWToken_SetSessionState * *  -- private accessors -- *  nssCKFWToken_SetSessionState *  nssCKFWToken_RemoveSession *  nssCKFWToken_CloseAllSessions *  nssCKFWToken_GetSessionCount *  nssCKFWToken_GetRwSessionCount *  nssCKFWToken_GetRoSessionCount *  nssCKFWToken_GetSessionObjectHash *  nssCKFWToken_GetMDObjectHash *  nssCKFWToken_GetObjectHandleHash * *  -- module fronts -- *  nssCKFWToken_InitToken *  nssCKFWToken_GetLabel *  nssCKFWToken_GetManufacturerID *  nssCKFWToken_GetModel *  nssCKFWToken_GetSerialNumber *  nssCKFWToken_GetHasRNG *  nssCKFWToken_GetIsWriteProtected *  nssCKFWToken_GetLoginRequired *  nssCKFWToken_GetUserPinInitialized *  nssCKFWToken_GetRestoreKeyNotNeeded *  nssCKFWToken_GetHasClockOnToken *  nssCKFWToken_GetHasProtectedAuthenticationPath *  nssCKFWToken_GetSupportsDualCryptoOperations *  nssCKFWToken_GetMaxSessionCount *  nssCKFWToken_GetMaxRwSessionCount *  nssCKFWToken_GetMaxPinLen *  nssCKFWToken_GetMinPinLen *  nssCKFWToken_GetTotalPublicMemory *  nssCKFWToken_GetFreePublicMemory *  nssCKFWToken_GetTotalPrivateMemory *  nssCKFWToken_GetFreePrivateMemory *  nssCKFWToken_GetHardwareVersion *  nssCKFWToken_GetFirmwareVersion *  nssCKFWToken_GetUTCTime *  nssCKFWToken_OpenSession *  nssCKFWToken_GetMechanismCount *  nssCKFWToken_GetMechanismTypes *  nssCKFWToken_GetMechanism */struct NSSCKFWTokenStr {  NSSCKFWMutex *mutex;  NSSArena *arena;  NSSCKMDToken *mdToken;  NSSCKFWSlot *fwSlot;  NSSCKMDSlot *mdSlot;  NSSCKFWInstance *fwInstance;  NSSCKMDInstance *mdInstance;  /*   * 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 counts and hashes are consistant.   *   * 3) The object hashes are consistant.   *   * Note that the calls accessing the cached descriptions will call   * the NSSCKMDToken methods with the mutex locked.  Those methods   * may then call the public NSSCKFWToken routines.  Those public   * routines only access the constant data above and the atomic   * CK_STATE session state variable below, 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.   */  NSSUTF8 *label;  NSSUTF8 *manufacturerID;  NSSUTF8 *model;  NSSUTF8 *serialNumber;  CK_VERSION hardwareVersion;  CK_VERSION firmwareVersion;  CK_ULONG sessionCount;  CK_ULONG rwSessionCount;  nssCKFWHash *sessions;  nssCKFWHash *sessionObjectHash;  nssCKFWHash *mdObjectHash;  CK_STATE state;};#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_RVtoken_add_pointer(  const NSSCKFWToken *fwToken){  return CKR_OK;}static CK_RVtoken_remove_pointer(  const NSSCKFWToken *fwToken){  return CKR_OK;}NSS_IMPLEMENT CK_RVnssCKFWToken_verifyPointer(  const NSSCKFWToken *fwToken){  return CKR_OK;}#endif /* DEBUG *//* * nssCKFWToken_Create * */NSS_IMPLEMENT NSSCKFWToken *nssCKFWToken_Create(  NSSCKFWSlot *fwSlot,  NSSCKMDToken *mdToken,  CK_RV *pError){  NSSArena *arena = (NSSArena *)NULL;  NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;  CK_BBOOL called_setup = CK_FALSE;  /*   * We have already verified the arguments in nssCKFWSlot_GetToken.   */  arena = NSSArena_Create();  if( (NSSArena *)NULL == arena ) {    *pError = CKR_HOST_MEMORY;    goto loser;  }  fwToken = nss_ZNEW(arena, NSSCKFWToken);  if( (NSSCKFWToken *)NULL == fwToken ) {    *pError = CKR_HOST_MEMORY;    goto loser;  }      fwToken->arena = arena;  fwToken->mdToken = mdToken;  fwToken->fwSlot = fwSlot;  fwToken->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);  fwToken->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);  fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */  fwToken->sessionCount = 0;  fwToken->rwSessionCount = 0;  fwToken->mutex = nssCKFWInstance_CreateMutex(fwToken->fwInstance, arena, pError);  if( (NSSCKFWMutex *)NULL == fwToken->mutex ) {    if( CKR_OK == *pError ) {      *pError = CKR_GENERAL_ERROR;    }    goto loser;  }  fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, arena, pError);  if( (nssCKFWHash *)NULL == fwToken->sessions ) {    if( CKR_OK == *pError ) {      *pError = CKR_GENERAL_ERROR;    }    goto loser;  }  if( CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects(                   fwToken->fwInstance) ) {    fwToken->sessionObjectHash = nssCKFWHash_Create(fwToken->fwInstance,                                    arena, pError);    if( (nssCKFWHash *)NULL == fwToken->sessionObjectHash ) {      if( CKR_OK == *pError ) {        *pError = CKR_GENERAL_ERROR;      }      goto loser;    }  }  fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance,                             arena, pError);  if( (nssCKFWHash *)NULL == fwToken->mdObjectHash ) {    if( CKR_OK == *pError ) {      *pError = CKR_GENERAL_ERROR;    }    goto loser;  }  fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance,                                 arena, pError);  if( (nssCKFWHash *)NULL == fwToken->mdObjectHash ) {    if( CKR_OK == *pError ) {      *pError = CKR_GENERAL_ERROR;    }    goto loser;  }  /* More here */  if( (void *)NULL != (void *)mdToken->Setup ) {    *pError = mdToken->Setup(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);    if( CKR_OK != *pError ) {      goto loser;    }  }  called_setup = CK_TRUE;#ifdef DEBUG  *pError = token_add_pointer(fwToken);  if( CKR_OK != *pError ) {    goto loser;  }#endif /* DEBUG */  *pError = CKR_OK;  return fwToken; loser:  if( CK_TRUE == called_setup ) {    if( (void *)NULL != (void *)mdToken->Invalidate ) {      mdToken->Invalidate(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);    }  }  if( (NSSArena *)NULL != arena ) {    (void)NSSArena_Destroy(arena);  }  return (NSSCKFWToken *)NULL;}/* * nssCKFWToken_Destroy * */NSS_IMPLEMENT CK_RVnssCKFWToken_Destroy(  NSSCKFWToken *fwToken){  CK_RV error = CKR_OK;#ifdef NSSDEBUG  error = nssCKFWToken_verifyPointer(fwToken);  if( CKR_OK != error ) {    return error;  }#endif /* NSSDEBUG */  (void)nssCKFWMutex_Destroy(fwToken->mutex);    if( (void *)NULL != (void *)fwToken->mdToken->Invalidate ) {    fwToken->mdToken->Invalidate(fwToken->mdToken, fwToken,      fwToken->mdInstance, fwToken->fwInstance);  }  nssCKFWSlot_ClearToken(fwToken->fwSlot);  #ifdef DEBUG  error = token_remove_pointer(fwToken);#endif /* DEBUG */  (void)NSSArena_Destroy(fwToken->arena);  return error;}/* * nssCKFWToken_GetMDToken * */NSS_IMPLEMENT NSSCKMDToken *nssCKFWToken_GetMDToken(  NSSCKFWToken *fwToken){#ifdef NSSDEBUG  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {    return (NSSCKMDToken *)NULL;  }#endif /* NSSDEBUG */  return fwToken->mdToken;}/* * nssCKFWToken_GetArena * */NSS_IMPLEMENT NSSArena *nssCKFWToken_GetArena(  NSSCKFWToken *fwToken,  CK_RV *pError){#ifdef NSSDEBUG  if( (CK_RV *)NULL == pError ) {    return (NSSArena *)NULL;  }  *pError = nssCKFWToken_verifyPointer(fwToken);  if( CKR_OK != *pError ) {    return (NSSArena *)NULL;  }#endif /* NSSDEBUG */  return fwToken->arena;}/* * nssCKFWToken_GetFWSlot * */NSS_IMPLEMENT NSSCKFWSlot *nssCKFWToken_GetFWSlot(  NSSCKFWToken *fwToken){#ifdef NSSDEBUG  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {    return (NSSCKFWSlot *)NULL;  }#endif /* NSSDEBUG */  return fwToken->fwSlot;}/* * nssCKFWToken_GetMDSlot * */NSS_IMPLEMENT NSSCKMDSlot *nssCKFWToken_GetMDSlot(  NSSCKFWToken *fwToken){#ifdef NSSDEBUG  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {    return (NSSCKMDSlot *)NULL;  }#endif /* NSSDEBUG */  return fwToken->mdSlot;}/* * nssCKFWToken_GetSessionState * */NSS_IMPLEMENT CK_STATEnssCKFWToken_GetSessionState(  NSSCKFWToken *fwToken){#ifdef NSSDEBUG  if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {    return CKS_RO_PUBLIC_SESSION; /* whatever */  }#endif /* NSSDEBUG */  /*   * BTW, do not lock the token in this method.   */  /*   * Theoretically, there is no state if there aren't any   * sessions open.  But then we'd need to worry about   * reporting an error, etc.  What the heck-- let's just   * revert to CKR_RO_PUBLIC_SESSION as the "default."   */  return fwToken->state;}/* * nssCKFWToken_InitToken * */NSS_IMPLEMENT CK_RVnssCKFWToken_InitToken(  NSSCKFWToken *fwToken,  NSSItem *pin,  NSSUTF8 *label){  CK_RV error;#ifdef NSSDEBUG  error = nssCKFWToken_verifyPointer(fwToken);  if( CKR_OK != error ) {    return CKR_ARGUMENTS_BAD;  }#endif /* NSSDEBUG */  error = nssCKFWMutex_Lock(fwToken->mutex);  if( CKR_OK != error ) {    return error;  }  if( fwToken->sessionCount > 0 ) {    error = CKR_SESSION_EXISTS;    goto done;  }  if( (void *)NULL == (void *)fwToken->mdToken->InitToken ) {    error = CKR_DEVICE_ERROR;    goto done;  }  if( (NSSItem *)NULL == pin ) {    if( nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken) ) {      ; /* okay */    } else {      error = CKR_PIN_INCORRECT;      goto done;    }  }  if( (NSSUTF8 *)NULL == label ) {    label = (NSSUTF8 *) "";  }  error = fwToken->mdToken->InitToken(fwToken->mdToken, fwToken,            fwToken->mdInstance, fwToken->fwInstance, pin, label); done:  (void)nssCKFWMutex_Unlock(fwToken->mutex);  return error;}/* * nssCKFWToken_GetLabel * */NSS_IMPLEMENT CK_RVnssCKFWToken_GetLabel(  NSSCKFWToken *fwToken,  CK_CHAR label[32]){  CK_RV error = CKR_OK;#ifdef NSSDEBUG  if( (CK_CHAR_PTR)NULL == label ) {    return CKR_ARGUMENTS_BAD;  }  error = nssCKFWToken_verifyPointer(fwToken);  if( CKR_OK != error ) {    return error;  }#endif /* NSSDEBUG */  error = nssCKFWMutex_Lock(fwToken->mutex);  if( CKR_OK != error ) {    return error;  }  if( (NSSUTF8 *)NULL == fwToken->label ) {    if( (void *)NULL != (void *)fwToken->mdToken->GetLabel ) {      fwToken->label = fwToken->mdToken->GetLabel(fwToken->mdToken, fwToken,        fwToken->mdInstance, fwToken->fwInstance, &error);      if( ((NSSUTF8 *)NULL == fwToken->label) && (CKR_OK != error) ) {        goto done;      }    } else {      fwToken->label = (NSSUTF8 *) "";    }  }  (void)nssUTF8_CopyIntoFixedBuffer(fwToken->label, (char *)label, 32, ' ');  error = CKR_OK; done:  (void)nssCKFWMutex_Unlock(fwToken->mutex);  return error;}/* * nssCKFWToken_GetManufacturerID * */NSS_IMPLEMENT CK_RVnssCKFWToken_GetManufacturerID(  NSSCKFWToken *fwToken,  CK_CHAR manufacturerID[32]){  CK_RV error = CKR_OK;#ifdef NSSDEBUG  if( (CK_CHAR_PTR)NULL == manufacturerID ) {    return CKR_ARGUMENTS_BAD;  }  error = nssCKFWToken_verifyPointer(fwToken);  if( CKR_OK != error ) {    return error;  }#endif /* NSSDEBUG */  error = nssCKFWMutex_Lock(fwToken->mutex);  if( CKR_OK != error ) {    return error;  }  if( (NSSUTF8 *)NULL == fwToken->manufacturerID ) {    if( (void *)NULL != (void *)fwToken->mdToken->GetManufacturerID ) {      fwToken->manufacturerID = fwToken->mdToken->GetManufacturerID(fwToken->mdToken,        fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);      if( ((NSSUTF8 *)NULL == fwToken->manufacturerID) && (CKR_OK != error) ) {        goto done;      }    } else {      fwToken->manufacturerID = (NSSUTF8 *)"";    }  }  (void)nssUTF8_CopyIntoFixedBuffer(fwToken->manufacturerID, (char *)manufacturerID, 32, ' ');  error = CKR_OK; done:  (void)nssCKFWMutex_Unlock(fwToken->mutex);  return error;}/*

⌨️ 快捷键说明

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