diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /security/nss/lib/ckfw/token.c | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'security/nss/lib/ckfw/token.c')
-rw-r--r-- | security/nss/lib/ckfw/token.c | 1791 |
1 files changed, 1791 insertions, 0 deletions
diff --git a/security/nss/lib/ckfw/token.c b/security/nss/lib/ckfw/token.c new file mode 100644 index 000000000..4483bb5c9 --- /dev/null +++ b/security/nss/lib/ckfw/token.c @@ -0,0 +1,1791 @@ +/* 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/. */ + +/* + * 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; + nssCKFWHash *mdMechanismHash; + + 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_RV +token_add_pointer( + const NSSCKFWToken *fwToken) +{ + return CKR_OK; +} + +static CK_RV +token_remove_pointer( + const NSSCKFWToken *fwToken) +{ + return CKR_OK; +} + +NSS_IMPLEMENT CK_RV +nssCKFWToken_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 (!arena) { + *pError = CKR_HOST_MEMORY; + goto loser; + } + + fwToken = nss_ZNEW(arena, NSSCKFWToken); + if (!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 (!fwToken->mutex) { + if (CKR_OK == *pError) { + *pError = CKR_GENERAL_ERROR; + } + goto loser; + } + + fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, arena, pError); + if (!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 (!fwToken->sessionObjectHash) { + if (CKR_OK == *pError) { + *pError = CKR_GENERAL_ERROR; + } + goto loser; + } + } + + fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance, + arena, pError); + if (!fwToken->mdObjectHash) { + if (CKR_OK == *pError) { + *pError = CKR_GENERAL_ERROR; + } + goto loser; + } + + fwToken->mdMechanismHash = nssCKFWHash_Create(fwToken->fwInstance, + arena, pError); + if (!fwToken->mdMechanismHash) { + if (CKR_OK == *pError) { + *pError = CKR_GENERAL_ERROR; + } + goto loser; + } + + /* More here */ + + if (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 (mdToken->Invalidate) { + mdToken->Invalidate(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance); + } + } + + if (arena) { + (void)NSSArena_Destroy(arena); + } + + return (NSSCKFWToken *)NULL; +} + +static void +nss_ckfwtoken_session_iterator( + const void *key, + void *value, + void *closure) +{ + /* + * Remember that the fwToken->mutex is locked + */ + NSSCKFWSession *fwSession = (NSSCKFWSession *)value; + (void)nssCKFWSession_Destroy(fwSession, CK_FALSE); + return; +} + +static void +nss_ckfwtoken_object_iterator( + const void *key, + void *value, + void *closure) +{ + /* + * Remember that the fwToken->mutex is locked + */ + NSSCKFWObject *fwObject = (NSSCKFWObject *)value; + (void)nssCKFWObject_Finalize(fwObject, CK_FALSE); + return; +} + +/* + * nssCKFWToken_Destroy + * + */ +NSS_IMPLEMENT CK_RV +nssCKFWToken_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 (fwToken->mdToken->Invalidate) { + fwToken->mdToken->Invalidate(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); + } + /* we can destroy the list without locking now because no one else is + * referencing us (or _Destroy was invalidly called!) + */ + nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, + (void *)NULL); + nssCKFWHash_Destroy(fwToken->sessions); + + /* session objects go away when their sessions are removed */ + if (fwToken->sessionObjectHash) { + nssCKFWHash_Destroy(fwToken->sessionObjectHash); + } + + /* free up the token objects */ + if (fwToken->mdObjectHash) { + nssCKFWHash_Iterate(fwToken->mdObjectHash, nss_ckfwtoken_object_iterator, + (void *)NULL); + nssCKFWHash_Destroy(fwToken->mdObjectHash); + } + if (fwToken->mdMechanismHash) { + nssCKFWHash_Destroy(fwToken->mdMechanismHash); + } + + 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 (!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_STATE +nssCKFWToken_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_RV +nssCKFWToken_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 (!fwToken->mdToken->InitToken) { + error = CKR_DEVICE_ERROR; + goto done; + } + + if (!pin) { + if (nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken)) { + ; /* okay */ + } else { + error = CKR_PIN_INCORRECT; + goto done; + } + } + + if (!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_RV +nssCKFWToken_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 (!fwToken->label) { + if (fwToken->mdToken->GetLabel) { + fwToken->label = fwToken->mdToken->GetLabel(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance, &error); + if ((!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_RV +nssCKFWToken_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 (!fwToken->manufacturerID) { + if (fwToken->mdToken->GetManufacturerID) { + fwToken->manufacturerID = fwToken->mdToken->GetManufacturerID(fwToken->mdToken, + fwToken, fwToken->mdInstance, fwToken->fwInstance, &error); + if ((!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; +} + +/* + * nssCKFWToken_GetModel + * + */ +NSS_IMPLEMENT CK_RV +nssCKFWToken_GetModel( + NSSCKFWToken *fwToken, + CK_CHAR model[16]) +{ + CK_RV error = CKR_OK; + +#ifdef NSSDEBUG + if ((CK_CHAR_PTR)NULL == model) { + 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 (!fwToken->model) { + if (fwToken->mdToken->GetModel) { + fwToken->model = fwToken->mdToken->GetModel(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance, &error); + if ((!fwToken->model) && (CKR_OK != error)) { + goto done; + } + } else { + fwToken->model = (NSSUTF8 *)""; + } + } + + (void)nssUTF8_CopyIntoFixedBuffer(fwToken->model, (char *)model, 16, ' '); + error = CKR_OK; + +done: + (void)nssCKFWMutex_Unlock(fwToken->mutex); + return error; +} + +/* + * nssCKFWToken_GetSerialNumber + * + */ +NSS_IMPLEMENT CK_RV +nssCKFWToken_GetSerialNumber( + NSSCKFWToken *fwToken, + CK_CHAR serialNumber[16]) +{ + CK_RV error = CKR_OK; + +#ifdef NSSDEBUG + if ((CK_CHAR_PTR)NULL == serialNumber) { + 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 (!fwToken->serialNumber) { + if (fwToken->mdToken->GetSerialNumber) { + fwToken->serialNumber = fwToken->mdToken->GetSerialNumber(fwToken->mdToken, + fwToken, fwToken->mdInstance, fwToken->fwInstance, &error); + if ((!fwToken->serialNumber) && (CKR_OK != error)) { + goto done; + } + } else { + fwToken->serialNumber = (NSSUTF8 *)""; + } + } + + (void)nssUTF8_CopyIntoFixedBuffer(fwToken->serialNumber, (char *)serialNumber, 16, ' '); + error = CKR_OK; + +done: + (void)nssCKFWMutex_Unlock(fwToken->mutex); + return error; +} + +/* + * nssCKFWToken_GetHasRNG + * + */ +NSS_IMPLEMENT CK_BBOOL +nssCKFWToken_GetHasRNG( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_FALSE; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetHasRNG) { + return CK_FALSE; + } + + return fwToken->mdToken->GetHasRNG(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetIsWriteProtected + * + */ +NSS_IMPLEMENT CK_BBOOL +nssCKFWToken_GetIsWriteProtected( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_FALSE; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetIsWriteProtected) { + return CK_FALSE; + } + + return fwToken->mdToken->GetIsWriteProtected(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetLoginRequired + * + */ +NSS_IMPLEMENT CK_BBOOL +nssCKFWToken_GetLoginRequired( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_FALSE; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetLoginRequired) { + return CK_FALSE; + } + + return fwToken->mdToken->GetLoginRequired(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetUserPinInitialized + * + */ +NSS_IMPLEMENT CK_BBOOL +nssCKFWToken_GetUserPinInitialized( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_FALSE; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetUserPinInitialized) { + return CK_FALSE; + } + + return fwToken->mdToken->GetUserPinInitialized(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetRestoreKeyNotNeeded + * + */ +NSS_IMPLEMENT CK_BBOOL +nssCKFWToken_GetRestoreKeyNotNeeded( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_FALSE; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetRestoreKeyNotNeeded) { + return CK_FALSE; + } + + return fwToken->mdToken->GetRestoreKeyNotNeeded(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetHasClockOnToken + * + */ +NSS_IMPLEMENT CK_BBOOL +nssCKFWToken_GetHasClockOnToken( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_FALSE; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetHasClockOnToken) { + return CK_FALSE; + } + + return fwToken->mdToken->GetHasClockOnToken(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetHasProtectedAuthenticationPath + * + */ +NSS_IMPLEMENT CK_BBOOL +nssCKFWToken_GetHasProtectedAuthenticationPath( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_FALSE; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetHasProtectedAuthenticationPath) { + return CK_FALSE; + } + + return fwToken->mdToken->GetHasProtectedAuthenticationPath(fwToken->mdToken, + fwToken, fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetSupportsDualCryptoOperations + * + */ +NSS_IMPLEMENT CK_BBOOL +nssCKFWToken_GetSupportsDualCryptoOperations( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_FALSE; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetSupportsDualCryptoOperations) { + return CK_FALSE; + } + + return fwToken->mdToken->GetSupportsDualCryptoOperations(fwToken->mdToken, + fwToken, fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetMaxSessionCount + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWToken_GetMaxSessionCount( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_UNAVAILABLE_INFORMATION; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetMaxSessionCount) { + return CK_UNAVAILABLE_INFORMATION; + } + + return fwToken->mdToken->GetMaxSessionCount(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetMaxRwSessionCount + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWToken_GetMaxRwSessionCount( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_UNAVAILABLE_INFORMATION; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetMaxRwSessionCount) { + return CK_UNAVAILABLE_INFORMATION; + } + + return fwToken->mdToken->GetMaxRwSessionCount(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetMaxPinLen + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWToken_GetMaxPinLen( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_UNAVAILABLE_INFORMATION; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetMaxPinLen) { + return CK_UNAVAILABLE_INFORMATION; + } + + return fwToken->mdToken->GetMaxPinLen(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetMinPinLen + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWToken_GetMinPinLen( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_UNAVAILABLE_INFORMATION; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetMinPinLen) { + return CK_UNAVAILABLE_INFORMATION; + } + + return fwToken->mdToken->GetMinPinLen(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetTotalPublicMemory + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWToken_GetTotalPublicMemory( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_UNAVAILABLE_INFORMATION; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetTotalPublicMemory) { + return CK_UNAVAILABLE_INFORMATION; + } + + return fwToken->mdToken->GetTotalPublicMemory(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetFreePublicMemory + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWToken_GetFreePublicMemory( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_UNAVAILABLE_INFORMATION; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetFreePublicMemory) { + return CK_UNAVAILABLE_INFORMATION; + } + + return fwToken->mdToken->GetFreePublicMemory(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetTotalPrivateMemory + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWToken_GetTotalPrivateMemory( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_UNAVAILABLE_INFORMATION; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetTotalPrivateMemory) { + return CK_UNAVAILABLE_INFORMATION; + } + + return fwToken->mdToken->GetTotalPrivateMemory(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetFreePrivateMemory + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWToken_GetFreePrivateMemory( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CK_UNAVAILABLE_INFORMATION; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetFreePrivateMemory) { + return CK_UNAVAILABLE_INFORMATION; + } + + return fwToken->mdToken->GetFreePrivateMemory(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetHardwareVersion + * + */ +NSS_IMPLEMENT CK_VERSION +nssCKFWToken_GetHardwareVersion( + NSSCKFWToken *fwToken) +{ + CK_VERSION rv; + +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + rv.major = rv.minor = 0; + return rv; + } +#endif /* NSSDEBUG */ + + if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) { + rv.major = rv.minor = 0; + return rv; + } + + if ((0 != fwToken->hardwareVersion.major) || + (0 != fwToken->hardwareVersion.minor)) { + rv = fwToken->hardwareVersion; + goto done; + } + + if (fwToken->mdToken->GetHardwareVersion) { + fwToken->hardwareVersion = fwToken->mdToken->GetHardwareVersion( + fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance); + } else { + fwToken->hardwareVersion.major = 0; + fwToken->hardwareVersion.minor = 1; + } + + rv = fwToken->hardwareVersion; + +done: + (void)nssCKFWMutex_Unlock(fwToken->mutex); + return rv; +} + +/* + * nssCKFWToken_GetFirmwareVersion + * + */ +NSS_IMPLEMENT CK_VERSION +nssCKFWToken_GetFirmwareVersion( + NSSCKFWToken *fwToken) +{ + CK_VERSION rv; + +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + rv.major = rv.minor = 0; + return rv; + } +#endif /* NSSDEBUG */ + + if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) { + rv.major = rv.minor = 0; + return rv; + } + + if ((0 != fwToken->firmwareVersion.major) || + (0 != fwToken->firmwareVersion.minor)) { + rv = fwToken->firmwareVersion; + goto done; + } + + if (fwToken->mdToken->GetFirmwareVersion) { + fwToken->firmwareVersion = fwToken->mdToken->GetFirmwareVersion( + fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance); + } else { + fwToken->firmwareVersion.major = 0; + fwToken->firmwareVersion.minor = 1; + } + + rv = fwToken->firmwareVersion; + +done: + (void)nssCKFWMutex_Unlock(fwToken->mutex); + return rv; +} + +/* + * nssCKFWToken_GetUTCTime + * + */ +NSS_IMPLEMENT CK_RV +nssCKFWToken_GetUTCTime( + NSSCKFWToken *fwToken, + CK_CHAR utcTime[16]) +{ + CK_RV error = CKR_OK; + +#ifdef NSSDEBUG + error = nssCKFWToken_verifyPointer(fwToken); + if (CKR_OK != error) { + return error; + } + + if ((CK_CHAR_PTR)NULL == utcTime) { + return CKR_ARGUMENTS_BAD; + } +#endif /* DEBUG */ + + if (CK_TRUE != nssCKFWToken_GetHasClockOnToken(fwToken)) { + /* return CKR_DEVICE_ERROR; */ + (void)nssUTF8_CopyIntoFixedBuffer((NSSUTF8 *)NULL, (char *)utcTime, 16, ' '); + return CKR_OK; + } + + if (!fwToken->mdToken->GetUTCTime) { + /* It said it had one! */ + return CKR_GENERAL_ERROR; + } + + error = fwToken->mdToken->GetUTCTime(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance, utcTime); + if (CKR_OK != error) { + return error; + } + + /* Sanity-check the data */ + { + /* Format is YYYYMMDDhhmmss00 */ + int i; + int Y, M, D, h, m, s; + static int dims[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + for (i = 0; i < 16; i++) { + if ((utcTime[i] < '0') || (utcTime[i] > '9')) { + goto badtime; + } + } + + Y = ((utcTime[0] - '0') * 1000) + ((utcTime[1] - '0') * 100) + + ((utcTime[2] - '0') * 10) + (utcTime[3] - '0'); + M = ((utcTime[4] - '0') * 10) + (utcTime[5] - '0'); + D = ((utcTime[6] - '0') * 10) + (utcTime[7] - '0'); + h = ((utcTime[8] - '0') * 10) + (utcTime[9] - '0'); + m = ((utcTime[10] - '0') * 10) + (utcTime[11] - '0'); + s = ((utcTime[12] - '0') * 10) + (utcTime[13] - '0'); + + if ((Y < 1990) || (Y > 3000)) + goto badtime; /* Y3K problem. heh heh heh */ + if ((M < 1) || (M > 12)) + goto badtime; + if ((D < 1) || (D > 31)) + goto badtime; + + if (D > dims[M - 1]) + goto badtime; /* per-month check */ + if ((2 == M) && (((Y % 4) || !(Y % 100)) && + (Y % 400)) && + (D > 28)) + goto badtime; /* leap years */ + + if ((h < 0) || (h > 23)) + goto badtime; + if ((m < 0) || (m > 60)) + goto badtime; + if ((s < 0) || (s > 61)) + goto badtime; + + /* 60m and 60 or 61s is only allowed for leap seconds. */ + if ((60 == m) || (s >= 60)) { + if ((23 != h) || (60 != m) || (s < 60)) + goto badtime; + /* leap seconds can only happen on June 30 or Dec 31.. I think */ + /* if( ((6 != M) || (30 != D)) && ((12 != M) || (31 != D)) ) goto badtime; */ + } + } + + return CKR_OK; + +badtime: + return CKR_GENERAL_ERROR; +} + +/* + * nssCKFWToken_OpenSession + * + */ +NSS_IMPLEMENT NSSCKFWSession * +nssCKFWToken_OpenSession( + NSSCKFWToken *fwToken, + CK_BBOOL rw, + CK_VOID_PTR pApplication, + CK_NOTIFY Notify, + CK_RV *pError) +{ + NSSCKFWSession *fwSession = (NSSCKFWSession *)NULL; + NSSCKMDSession *mdSession; + +#ifdef NSSDEBUG + if (!pError) { + return (NSSCKFWSession *)NULL; + } + + *pError = nssCKFWToken_verifyPointer(fwToken); + if (CKR_OK != *pError) { + return (NSSCKFWSession *)NULL; + } + + switch (rw) { + case CK_TRUE: + case CK_FALSE: + break; + default: + *pError = CKR_ARGUMENTS_BAD; + return (NSSCKFWSession *)NULL; + } +#endif /* NSSDEBUG */ + + *pError = nssCKFWMutex_Lock(fwToken->mutex); + if (CKR_OK != *pError) { + return (NSSCKFWSession *)NULL; + } + + if (CK_TRUE == rw) { + /* Read-write session desired */ + if (CK_TRUE == nssCKFWToken_GetIsWriteProtected(fwToken)) { + *pError = CKR_TOKEN_WRITE_PROTECTED; + goto done; + } + } else { + /* Read-only session desired */ + if (CKS_RW_SO_FUNCTIONS == nssCKFWToken_GetSessionState(fwToken)) { + *pError = CKR_SESSION_READ_WRITE_SO_EXISTS; + goto done; + } + } + + /* We could compare sesion counts to any limits we know of, I guess.. */ + + if (!fwToken->mdToken->OpenSession) { + /* + * I'm not sure that the Module actually needs to implement + * mdSessions -- the Framework can keep track of everything + * needed, really. But I'll sort out that detail later.. + */ + *pError = CKR_GENERAL_ERROR; + goto done; + } + + fwSession = nssCKFWSession_Create(fwToken, rw, pApplication, Notify, pError); + if (!fwSession) { + if (CKR_OK == *pError) { + *pError = CKR_GENERAL_ERROR; + } + goto done; + } + + mdSession = fwToken->mdToken->OpenSession(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance, fwSession, + rw, pError); + if (!mdSession) { + (void)nssCKFWSession_Destroy(fwSession, CK_FALSE); + if (CKR_OK == *pError) { + *pError = CKR_GENERAL_ERROR; + } + goto done; + } + + *pError = nssCKFWSession_SetMDSession(fwSession, mdSession); + if (CKR_OK != *pError) { + if (mdSession->Close) { + mdSession->Close(mdSession, fwSession, fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); + } + (void)nssCKFWSession_Destroy(fwSession, CK_FALSE); + goto done; + } + + *pError = nssCKFWHash_Add(fwToken->sessions, fwSession, fwSession); + if (CKR_OK != *pError) { + (void)nssCKFWSession_Destroy(fwSession, CK_FALSE); + fwSession = (NSSCKFWSession *)NULL; + goto done; + } + +done: + (void)nssCKFWMutex_Unlock(fwToken->mutex); + return fwSession; +} + +/* + * nssCKFWToken_GetMechanismCount + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWToken_GetMechanismCount( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return 0; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetMechanismCount) { + return 0; + } + + return fwToken->mdToken->GetMechanismCount(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +/* + * nssCKFWToken_GetMechanismTypes + * + */ +NSS_IMPLEMENT CK_RV +nssCKFWToken_GetMechanismTypes( + NSSCKFWToken *fwToken, + CK_MECHANISM_TYPE types[]) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CKR_ARGUMENTS_BAD; + } + + if (!types) { + return CKR_ARGUMENTS_BAD; + } +#endif /* NSSDEBUG */ + + if (!fwToken->mdToken->GetMechanismTypes) { + /* + * This should only be called with a sufficiently-large + * "types" array, which can only be done if GetMechanismCount + * is implemented. If that's implemented (and returns nonzero), + * then this should be too. So return an error. + */ + return CKR_GENERAL_ERROR; + } + + return fwToken->mdToken->GetMechanismTypes(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance, types); +} + +/* + * nssCKFWToken_GetMechanism + * + */ +NSS_IMPLEMENT NSSCKFWMechanism * +nssCKFWToken_GetMechanism( + NSSCKFWToken *fwToken, + CK_MECHANISM_TYPE which, + CK_RV *pError) +{ + NSSCKMDMechanism *mdMechanism; + if (!fwToken->mdMechanismHash) { + *pError = CKR_GENERAL_ERROR; + return (NSSCKFWMechanism *)NULL; + } + + if (!fwToken->mdToken->GetMechanism) { + /* + * If we don't implement any GetMechanism function, then we must + * not support any. + */ + *pError = CKR_MECHANISM_INVALID; + return (NSSCKFWMechanism *)NULL; + } + + /* lookup in hash table */ + mdMechanism = fwToken->mdToken->GetMechanism(fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance, which, pError); + if (!mdMechanism) { + return (NSSCKFWMechanism *)NULL; + } + /* store in hash table */ + return nssCKFWMechanism_Create(mdMechanism, fwToken->mdToken, fwToken, + fwToken->mdInstance, fwToken->fwInstance); +} + +NSS_IMPLEMENT CK_RV +nssCKFWToken_SetSessionState( + NSSCKFWToken *fwToken, + CK_STATE newState) +{ + CK_RV error = CKR_OK; + +#ifdef NSSDEBUG + error = nssCKFWToken_verifyPointer(fwToken); + if (CKR_OK != error) { + return error; + } + + switch (newState) { + case CKS_RO_PUBLIC_SESSION: + case CKS_RO_USER_FUNCTIONS: + case CKS_RW_PUBLIC_SESSION: + case CKS_RW_USER_FUNCTIONS: + case CKS_RW_SO_FUNCTIONS: + break; + default: + return CKR_ARGUMENTS_BAD; + } +#endif /* NSSDEBUG */ + + error = nssCKFWMutex_Lock(fwToken->mutex); + if (CKR_OK != error) { + return error; + } + + fwToken->state = newState; + (void)nssCKFWMutex_Unlock(fwToken->mutex); + return CKR_OK; +} + +/* + * nssCKFWToken_RemoveSession + * + */ +NSS_IMPLEMENT CK_RV +nssCKFWToken_RemoveSession( + NSSCKFWToken *fwToken, + NSSCKFWSession *fwSession) +{ + CK_RV error = CKR_OK; + +#ifdef NSSDEBUG + error = nssCKFWToken_verifyPointer(fwToken); + if (CKR_OK != error) { + return error; + } + + error = nssCKFWSession_verifyPointer(fwSession); + if (CKR_OK != error) { + return error; + } +#endif /* NSSDEBUG */ + + error = nssCKFWMutex_Lock(fwToken->mutex); + if (CKR_OK != error) { + return error; + } + + if (CK_TRUE != nssCKFWHash_Exists(fwToken->sessions, fwSession)) { + error = CKR_SESSION_HANDLE_INVALID; + goto done; + } + + nssCKFWHash_Remove(fwToken->sessions, fwSession); + fwToken->sessionCount--; + + if (nssCKFWSession_IsRWSession(fwSession)) { + fwToken->rwSessionCount--; + } + + if (0 == fwToken->sessionCount) { + fwToken->rwSessionCount = 0; /* sanity */ + fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */ + } + + error = CKR_OK; + +done: + (void)nssCKFWMutex_Unlock(fwToken->mutex); + return error; +} + +/* + * nssCKFWToken_CloseAllSessions + * + */ +NSS_IMPLEMENT CK_RV +nssCKFWToken_CloseAllSessions( + NSSCKFWToken *fwToken) +{ + CK_RV error = CKR_OK; + +#ifdef NSSDEBUG + error = nssCKFWToken_verifyPointer(fwToken); + if (CKR_OK != error) { + return error; + } +#endif /* NSSDEBUG */ + + error = nssCKFWMutex_Lock(fwToken->mutex); + if (CKR_OK != error) { + return error; + } + + nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, (void *)NULL); + + nssCKFWHash_Destroy(fwToken->sessions); + + fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, fwToken->arena, &error); + if (!fwToken->sessions) { + if (CKR_OK == error) { + error = CKR_GENERAL_ERROR; + } + goto done; + } + + fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */ + fwToken->sessionCount = 0; + fwToken->rwSessionCount = 0; + + error = CKR_OK; + +done: + (void)nssCKFWMutex_Unlock(fwToken->mutex); + return error; +} + +/* + * nssCKFWToken_GetSessionCount + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWToken_GetSessionCount( + NSSCKFWToken *fwToken) +{ + CK_ULONG rv; + +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return (CK_ULONG)0; + } +#endif /* NSSDEBUG */ + + if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) { + return (CK_ULONG)0; + } + + rv = fwToken->sessionCount; + (void)nssCKFWMutex_Unlock(fwToken->mutex); + return rv; +} + +/* + * nssCKFWToken_GetRwSessionCount + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWToken_GetRwSessionCount( + NSSCKFWToken *fwToken) +{ + CK_ULONG rv; + +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return (CK_ULONG)0; + } +#endif /* NSSDEBUG */ + + if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) { + return (CK_ULONG)0; + } + + rv = fwToken->rwSessionCount; + (void)nssCKFWMutex_Unlock(fwToken->mutex); + return rv; +} + +/* + * nssCKFWToken_GetRoSessionCount + * + */ +NSS_IMPLEMENT CK_ULONG +nssCKFWToken_GetRoSessionCount( + NSSCKFWToken *fwToken) +{ + CK_ULONG rv; + +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return (CK_ULONG)0; + } +#endif /* NSSDEBUG */ + + if (CKR_OK != nssCKFWMutex_Lock(fwToken->mutex)) { + return (CK_ULONG)0; + } + + rv = fwToken->sessionCount - fwToken->rwSessionCount; + (void)nssCKFWMutex_Unlock(fwToken->mutex); + return rv; +} + +/* + * nssCKFWToken_GetSessionObjectHash + * + */ +NSS_IMPLEMENT nssCKFWHash * +nssCKFWToken_GetSessionObjectHash( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return (nssCKFWHash *)NULL; + } +#endif /* NSSDEBUG */ + + return fwToken->sessionObjectHash; +} + +/* + * nssCKFWToken_GetMDObjectHash + * + */ +NSS_IMPLEMENT nssCKFWHash * +nssCKFWToken_GetMDObjectHash( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return (nssCKFWHash *)NULL; + } +#endif /* NSSDEBUG */ + + return fwToken->mdObjectHash; +} + +/* + * nssCKFWToken_GetObjectHandleHash + * + */ +NSS_IMPLEMENT nssCKFWHash * +nssCKFWToken_GetObjectHandleHash( + NSSCKFWToken *fwToken) +{ +#ifdef NSSDEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return (nssCKFWHash *)NULL; + } +#endif /* NSSDEBUG */ + + return fwToken->mdObjectHash; +} + +/* + * NSSCKFWToken_GetMDToken + * + */ + +NSS_IMPLEMENT NSSCKMDToken * +NSSCKFWToken_GetMDToken( + NSSCKFWToken *fwToken) +{ +#ifdef DEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return (NSSCKMDToken *)NULL; + } +#endif /* DEBUG */ + + return nssCKFWToken_GetMDToken(fwToken); +} + +/* + * NSSCKFWToken_GetArena + * + */ + +NSS_IMPLEMENT NSSArena * +NSSCKFWToken_GetArena( + NSSCKFWToken *fwToken, + CK_RV *pError) +{ +#ifdef DEBUG + if (!pError) { + return (NSSArena *)NULL; + } + + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + *pError = CKR_ARGUMENTS_BAD; + return (NSSArena *)NULL; + } +#endif /* DEBUG */ + + return nssCKFWToken_GetArena(fwToken, pError); +} + +/* + * NSSCKFWToken_GetFWSlot + * + */ + +NSS_IMPLEMENT NSSCKFWSlot * +NSSCKFWToken_GetFWSlot( + NSSCKFWToken *fwToken) +{ +#ifdef DEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return (NSSCKFWSlot *)NULL; + } +#endif /* DEBUG */ + + return nssCKFWToken_GetFWSlot(fwToken); +} + +/* + * NSSCKFWToken_GetMDSlot + * + */ + +NSS_IMPLEMENT NSSCKMDSlot * +NSSCKFWToken_GetMDSlot( + NSSCKFWToken *fwToken) +{ +#ifdef DEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return (NSSCKMDSlot *)NULL; + } +#endif /* DEBUG */ + + return nssCKFWToken_GetMDSlot(fwToken); +} + +/* + * NSSCKFWToken_GetSessionState + * + */ + +NSS_IMPLEMENT CK_STATE +NSSCKFWSession_GetSessionState( + NSSCKFWToken *fwToken) +{ +#ifdef DEBUG + if (CKR_OK != nssCKFWToken_verifyPointer(fwToken)) { + return CKS_RO_PUBLIC_SESSION; + } +#endif /* DEBUG */ + + return nssCKFWToken_GetSessionState(fwToken); +} |