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 + -
显示快捷键?