Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(760)

Unified Diff: nss/mozilla/security/nss/lib/ckfw/token.c

Issue 7530005: Add all NSS files to allow using a complete NSS in the future. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/
Patch Set: Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « nss/mozilla/security/nss/lib/ckfw/slot.c ('k') | nss/mozilla/security/nss/lib/ckfw/wrap.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « nss/mozilla/security/nss/lib/ckfw/slot.c ('k') | nss/mozilla/security/nss/lib/ckfw/wrap.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698