| Index: nss/mozilla/security/nss/lib/ckfw/token.c
|
| ===================================================================
|
| --- nss/mozilla/security/nss/lib/ckfw/token.c (revision 0)
|
| +++ nss/mozilla/security/nss/lib/ckfw/token.c (revision 0)
|
| @@ -0,0 +1,1928 @@
|
| +/* ***** BEGIN LICENSE BLOCK *****
|
| + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
| + *
|
| + * 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 the Initial Developer are Copyright (C) 1994-2000
|
| + * the Initial Developer. All Rights Reserved.
|
| + *
|
| + * Contributor(s):
|
| + *
|
| + * Alternatively, the contents of this file may be used under the terms of
|
| + * either the GNU General Public License Version 2 or later (the "GPL"), or
|
| + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
| + * in which case the provisions of the GPL or the LGPL are applicable instead
|
| + * of those above. If you wish to allow use of your version of this file only
|
| + * under the terms of either the GPL or the LGPL, and not to allow others to
|
| + * use your version of this file under the terms of the MPL, indicate your
|
| + * decision by deleting the provisions above and replace them with the notice
|
| + * and other provisions required by the GPL or the LGPL. If you do not delete
|
| + * the provisions above, a recipient may use your version of this file under
|
| + * the terms of any one of the MPL, the GPL or the LGPL.
|
| + *
|
| + * ***** END LICENSE BLOCK ***** */
|
| +
|
| +#ifdef DEBUG
|
| +static const char CVS_ID[] = "@(#) $RCSfile: token.c,v $ $Revision: 1.16 $ $Date: 2010/03/15 06:07:56 $";
|
| +#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;
|
| + 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, z;
|
| + 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');
|
| + z = ((utcTime[14] - '0') * 10) + (utcTime[15] - '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);
|
| +}
|
|
|
| Property changes on: nss/mozilla/security/nss/lib/ckfw/token.c
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|