security/nss/lib/ckfw/token.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * token.c
     7  *
     8  * This file implements the NSSCKFWToken type and methods.
     9  */
    11 #ifndef CK_T
    12 #include "ck.h"
    13 #endif /* CK_T */
    15 /*
    16  * NSSCKFWToken
    17  *
    18  *  -- create/destroy --
    19  *  nssCKFWToken_Create
    20  *  nssCKFWToken_Destroy
    21  *
    22  *  -- public accessors --
    23  *  NSSCKFWToken_GetMDToken
    24  *  NSSCKFWToken_GetFWSlot
    25  *  NSSCKFWToken_GetMDSlot
    26  *  NSSCKFWToken_GetSessionState
    27  *
    28  *  -- implement public accessors --
    29  *  nssCKFWToken_GetMDToken
    30  *  nssCKFWToken_GetFWSlot
    31  *  nssCKFWToken_GetMDSlot
    32  *  nssCKFWToken_GetSessionState
    33  *  nssCKFWToken_SetSessionState
    34  *
    35  *  -- private accessors --
    36  *  nssCKFWToken_SetSessionState
    37  *  nssCKFWToken_RemoveSession
    38  *  nssCKFWToken_CloseAllSessions
    39  *  nssCKFWToken_GetSessionCount
    40  *  nssCKFWToken_GetRwSessionCount
    41  *  nssCKFWToken_GetRoSessionCount
    42  *  nssCKFWToken_GetSessionObjectHash
    43  *  nssCKFWToken_GetMDObjectHash
    44  *  nssCKFWToken_GetObjectHandleHash
    45  *
    46  *  -- module fronts --
    47  *  nssCKFWToken_InitToken
    48  *  nssCKFWToken_GetLabel
    49  *  nssCKFWToken_GetManufacturerID
    50  *  nssCKFWToken_GetModel
    51  *  nssCKFWToken_GetSerialNumber
    52  *  nssCKFWToken_GetHasRNG
    53  *  nssCKFWToken_GetIsWriteProtected
    54  *  nssCKFWToken_GetLoginRequired
    55  *  nssCKFWToken_GetUserPinInitialized
    56  *  nssCKFWToken_GetRestoreKeyNotNeeded
    57  *  nssCKFWToken_GetHasClockOnToken
    58  *  nssCKFWToken_GetHasProtectedAuthenticationPath
    59  *  nssCKFWToken_GetSupportsDualCryptoOperations
    60  *  nssCKFWToken_GetMaxSessionCount
    61  *  nssCKFWToken_GetMaxRwSessionCount
    62  *  nssCKFWToken_GetMaxPinLen
    63  *  nssCKFWToken_GetMinPinLen
    64  *  nssCKFWToken_GetTotalPublicMemory
    65  *  nssCKFWToken_GetFreePublicMemory
    66  *  nssCKFWToken_GetTotalPrivateMemory
    67  *  nssCKFWToken_GetFreePrivateMemory
    68  *  nssCKFWToken_GetHardwareVersion
    69  *  nssCKFWToken_GetFirmwareVersion
    70  *  nssCKFWToken_GetUTCTime
    71  *  nssCKFWToken_OpenSession
    72  *  nssCKFWToken_GetMechanismCount
    73  *  nssCKFWToken_GetMechanismTypes
    74  *  nssCKFWToken_GetMechanism
    75  */
    77 struct NSSCKFWTokenStr {
    78   NSSCKFWMutex *mutex;
    79   NSSArena *arena;
    80   NSSCKMDToken *mdToken;
    81   NSSCKFWSlot *fwSlot;
    82   NSSCKMDSlot *mdSlot;
    83   NSSCKFWInstance *fwInstance;
    84   NSSCKMDInstance *mdInstance;
    86   /*
    87    * Everything above is set at creation time, and then not modified.
    88    * The invariants the mutex protects are:
    89    *
    90    * 1) Each of the cached descriptions (versions, etc.) are in an
    91    *    internally consistant state.
    92    *
    93    * 2) The session counts and hashes are consistant.
    94    *
    95    * 3) The object hashes are consistant.
    96    *
    97    * Note that the calls accessing the cached descriptions will call
    98    * the NSSCKMDToken methods with the mutex locked.  Those methods
    99    * may then call the public NSSCKFWToken routines.  Those public
   100    * routines only access the constant data above and the atomic
   101    * CK_STATE session state variable below, so there's no problem.
   102    * But be careful if you add to this object; mutexes are in
   103    * general not reentrant, so don't create deadlock situations.
   104    */
   106   NSSUTF8 *label;
   107   NSSUTF8 *manufacturerID;
   108   NSSUTF8 *model;
   109   NSSUTF8 *serialNumber;
   110   CK_VERSION hardwareVersion;
   111   CK_VERSION firmwareVersion;
   113   CK_ULONG sessionCount;
   114   CK_ULONG rwSessionCount;
   115   nssCKFWHash *sessions;
   116   nssCKFWHash *sessionObjectHash;
   117   nssCKFWHash *mdObjectHash;
   118   nssCKFWHash *mdMechanismHash;
   120   CK_STATE state;
   121 };
   123 #ifdef DEBUG
   124 /*
   125  * But first, the pointer-tracking stuff.
   126  *
   127  * NOTE: the pointer-tracking support in NSS/base currently relies
   128  * upon NSPR's CallOnce support.  That, however, relies upon NSPR's
   129  * locking, which is tied into the runtime.  We need a pointer-tracker
   130  * implementation that uses the locks supplied through C_Initialize.
   131  * That support, however, can be filled in later.  So for now, I'll
   132  * just do this routines as no-ops.
   133  */
   135 static CK_RV
   136 token_add_pointer
   137 (
   138   const NSSCKFWToken *fwToken
   139 )
   140 {
   141   return CKR_OK;
   142 }
   144 static CK_RV
   145 token_remove_pointer
   146 (
   147   const NSSCKFWToken *fwToken
   148 )
   149 {
   150   return CKR_OK;
   151 }
   153 NSS_IMPLEMENT CK_RV
   154 nssCKFWToken_verifyPointer
   155 (
   156   const NSSCKFWToken *fwToken
   157 )
   158 {
   159   return CKR_OK;
   160 }
   162 #endif /* DEBUG */
   164 /*
   165  * nssCKFWToken_Create
   166  *
   167  */
   168 NSS_IMPLEMENT NSSCKFWToken *
   169 nssCKFWToken_Create
   170 (
   171   NSSCKFWSlot *fwSlot,
   172   NSSCKMDToken *mdToken,
   173   CK_RV *pError
   174 )
   175 {
   176   NSSArena *arena = (NSSArena *)NULL;
   177   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
   178   CK_BBOOL called_setup = CK_FALSE;
   180   /*
   181    * We have already verified the arguments in nssCKFWSlot_GetToken.
   182    */
   184   arena = NSSArena_Create();
   185   if (!arena) {
   186     *pError = CKR_HOST_MEMORY;
   187     goto loser;
   188   }
   190   fwToken = nss_ZNEW(arena, NSSCKFWToken);
   191   if (!fwToken) {
   192     *pError = CKR_HOST_MEMORY;
   193     goto loser;
   194   }    
   196   fwToken->arena = arena;
   197   fwToken->mdToken = mdToken;
   198   fwToken->fwSlot = fwSlot;
   199   fwToken->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);
   200   fwToken->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);
   201   fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
   202   fwToken->sessionCount = 0;
   203   fwToken->rwSessionCount = 0;
   205   fwToken->mutex = nssCKFWInstance_CreateMutex(fwToken->fwInstance, arena, pError);
   206   if (!fwToken->mutex) {
   207     if( CKR_OK == *pError ) {
   208       *pError = CKR_GENERAL_ERROR;
   209     }
   210     goto loser;
   211   }
   213   fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, arena, pError);
   214   if (!fwToken->sessions) {
   215     if( CKR_OK == *pError ) {
   216       *pError = CKR_GENERAL_ERROR;
   217     }
   218     goto loser;
   219   }
   221   if( CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects(
   222                    fwToken->fwInstance) ) {
   223     fwToken->sessionObjectHash = nssCKFWHash_Create(fwToken->fwInstance, 
   224                                    arena, pError);
   225     if (!fwToken->sessionObjectHash) {
   226       if( CKR_OK == *pError ) {
   227         *pError = CKR_GENERAL_ERROR;
   228       }
   229       goto loser;
   230     }
   231   }
   233   fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance, 
   234                             arena, pError);
   235   if (!fwToken->mdObjectHash) {
   236     if( CKR_OK == *pError ) {
   237       *pError = CKR_GENERAL_ERROR;
   238     }
   239     goto loser;
   240   }
   242   fwToken->mdMechanismHash = nssCKFWHash_Create(fwToken->fwInstance, 
   243                             arena, pError);
   244   if (!fwToken->mdMechanismHash) {
   245     if( CKR_OK == *pError ) {
   246       *pError = CKR_GENERAL_ERROR;
   247     }
   248     goto loser;
   249   }
   251   /* More here */
   253   if (mdToken->Setup) {
   254     *pError = mdToken->Setup(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
   255     if( CKR_OK != *pError ) {
   256       goto loser;
   257     }
   258   }
   260   called_setup = CK_TRUE;
   262 #ifdef DEBUG
   263   *pError = token_add_pointer(fwToken);
   264   if( CKR_OK != *pError ) {
   265     goto loser;
   266   }
   267 #endif /* DEBUG */
   269   *pError = CKR_OK;
   270   return fwToken;
   272  loser:
   274   if( CK_TRUE == called_setup ) {
   275     if (mdToken->Invalidate) {
   276       mdToken->Invalidate(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
   277     }
   278   }
   280   if (arena) {
   281     (void)NSSArena_Destroy(arena);
   282   }
   284   return (NSSCKFWToken *)NULL;
   285 }
   287 static void
   288 nss_ckfwtoken_session_iterator
   289 (
   290   const void *key,
   291   void *value,
   292   void *closure
   293 )
   294 {
   295   /*
   296    * Remember that the fwToken->mutex is locked
   297    */
   298   NSSCKFWSession *fwSession = (NSSCKFWSession *)value;
   299   (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
   300   return;
   301 }
   303 static void
   304 nss_ckfwtoken_object_iterator
   305 (
   306   const void *key,
   307   void *value,
   308   void *closure
   309 )
   310 {
   311   /*
   312    * Remember that the fwToken->mutex is locked
   313    */
   314   NSSCKFWObject *fwObject = (NSSCKFWObject *)value;
   315   (void)nssCKFWObject_Finalize(fwObject, CK_FALSE);
   316   return;
   317 }
   319 /*
   320  * nssCKFWToken_Destroy
   321  *
   322  */
   323 NSS_IMPLEMENT CK_RV
   324 nssCKFWToken_Destroy
   325 (
   326   NSSCKFWToken *fwToken
   327 )
   328 {
   329   CK_RV error = CKR_OK;
   331 #ifdef NSSDEBUG
   332   error = nssCKFWToken_verifyPointer(fwToken);
   333   if( CKR_OK != error ) {
   334     return error;
   335   }
   336 #endif /* NSSDEBUG */
   338   (void)nssCKFWMutex_Destroy(fwToken->mutex);
   340   if (fwToken->mdToken->Invalidate) {
   341     fwToken->mdToken->Invalidate(fwToken->mdToken, fwToken,
   342       fwToken->mdInstance, fwToken->fwInstance);
   343   }
   344   /* we can destroy the list without locking now because no one else is 
   345    * referencing us (or _Destroy was invalidly called!)
   346    */
   347   nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, 
   348                                                                 (void *)NULL);
   349   nssCKFWHash_Destroy(fwToken->sessions);
   351   /* session objects go away when their sessions are removed */
   352   if (fwToken->sessionObjectHash) {
   353     nssCKFWHash_Destroy(fwToken->sessionObjectHash);
   354   }
   356   /* free up the token objects */
   357   if (fwToken->mdObjectHash) {
   358     nssCKFWHash_Iterate(fwToken->mdObjectHash, nss_ckfwtoken_object_iterator, 
   359                                                                 (void *)NULL);
   360     nssCKFWHash_Destroy(fwToken->mdObjectHash);
   361   }
   362   if (fwToken->mdMechanismHash) {
   363     nssCKFWHash_Destroy(fwToken->mdMechanismHash);
   364   }
   366   nssCKFWSlot_ClearToken(fwToken->fwSlot);
   368 #ifdef DEBUG
   369   error = token_remove_pointer(fwToken);
   370 #endif /* DEBUG */
   372   (void)NSSArena_Destroy(fwToken->arena);
   373   return error;
   374 }
   376 /*
   377  * nssCKFWToken_GetMDToken
   378  *
   379  */
   380 NSS_IMPLEMENT NSSCKMDToken *
   381 nssCKFWToken_GetMDToken
   382 (
   383   NSSCKFWToken *fwToken
   384 )
   385 {
   386 #ifdef NSSDEBUG
   387   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   388     return (NSSCKMDToken *)NULL;
   389   }
   390 #endif /* NSSDEBUG */
   392   return fwToken->mdToken;
   393 }
   395 /*
   396  * nssCKFWToken_GetArena
   397  *
   398  */
   399 NSS_IMPLEMENT NSSArena *
   400 nssCKFWToken_GetArena
   401 (
   402   NSSCKFWToken *fwToken,
   403   CK_RV *pError
   404 )
   405 {
   406 #ifdef NSSDEBUG
   407   if (!pError) {
   408     return (NSSArena *)NULL;
   409   }
   411   *pError = nssCKFWToken_verifyPointer(fwToken);
   412   if( CKR_OK != *pError ) {
   413     return (NSSArena *)NULL;
   414   }
   415 #endif /* NSSDEBUG */
   417   return fwToken->arena;
   418 }
   420 /*
   421  * nssCKFWToken_GetFWSlot
   422  *
   423  */
   424 NSS_IMPLEMENT NSSCKFWSlot *
   425 nssCKFWToken_GetFWSlot
   426 (
   427   NSSCKFWToken *fwToken
   428 )
   429 {
   430 #ifdef NSSDEBUG
   431   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   432     return (NSSCKFWSlot *)NULL;
   433   }
   434 #endif /* NSSDEBUG */
   436   return fwToken->fwSlot;
   437 }
   439 /*
   440  * nssCKFWToken_GetMDSlot
   441  *
   442  */
   443 NSS_IMPLEMENT NSSCKMDSlot *
   444 nssCKFWToken_GetMDSlot
   445 (
   446   NSSCKFWToken *fwToken
   447 )
   448 {
   449 #ifdef NSSDEBUG
   450   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   451     return (NSSCKMDSlot *)NULL;
   452   }
   453 #endif /* NSSDEBUG */
   455   return fwToken->mdSlot;
   456 }
   458 /*
   459  * nssCKFWToken_GetSessionState
   460  *
   461  */
   462 NSS_IMPLEMENT CK_STATE
   463 nssCKFWToken_GetSessionState
   464 (
   465   NSSCKFWToken *fwToken
   466 )
   467 {
   468 #ifdef NSSDEBUG
   469   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   470     return CKS_RO_PUBLIC_SESSION; /* whatever */
   471   }
   472 #endif /* NSSDEBUG */
   474   /*
   475    * BTW, do not lock the token in this method.
   476    */
   478   /*
   479    * Theoretically, there is no state if there aren't any
   480    * sessions open.  But then we'd need to worry about
   481    * reporting an error, etc.  What the heck-- let's just
   482    * revert to CKR_RO_PUBLIC_SESSION as the "default."
   483    */
   485   return fwToken->state;
   486 }
   488 /*
   489  * nssCKFWToken_InitToken
   490  *
   491  */
   492 NSS_IMPLEMENT CK_RV
   493 nssCKFWToken_InitToken
   494 (
   495   NSSCKFWToken *fwToken,
   496   NSSItem *pin,
   497   NSSUTF8 *label
   498 )
   499 {
   500   CK_RV error;
   502 #ifdef NSSDEBUG
   503   error = nssCKFWToken_verifyPointer(fwToken);
   504   if( CKR_OK != error ) {
   505     return CKR_ARGUMENTS_BAD;
   506   }
   507 #endif /* NSSDEBUG */
   509   error = nssCKFWMutex_Lock(fwToken->mutex);
   510   if( CKR_OK != error ) {
   511     return error;
   512   }
   514   if( fwToken->sessionCount > 0 ) {
   515     error = CKR_SESSION_EXISTS;
   516     goto done;
   517   }
   519   if (!fwToken->mdToken->InitToken) {
   520     error = CKR_DEVICE_ERROR;
   521     goto done;
   522   }
   524   if (!pin) {
   525     if( nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken) ) {
   526       ; /* okay */
   527     } else {
   528       error = CKR_PIN_INCORRECT;
   529       goto done;
   530     }
   531   }
   533   if (!label) {
   534     label = (NSSUTF8 *) "";
   535   }
   537   error = fwToken->mdToken->InitToken(fwToken->mdToken, fwToken,
   538             fwToken->mdInstance, fwToken->fwInstance, pin, label);
   540  done:
   541   (void)nssCKFWMutex_Unlock(fwToken->mutex);
   542   return error;
   543 }
   545 /*
   546  * nssCKFWToken_GetLabel
   547  *
   548  */
   549 NSS_IMPLEMENT CK_RV
   550 nssCKFWToken_GetLabel
   551 (
   552   NSSCKFWToken *fwToken,
   553   CK_CHAR label[32]
   554 )
   555 {
   556   CK_RV error = CKR_OK;
   558 #ifdef NSSDEBUG
   559   if( (CK_CHAR_PTR)NULL == label ) {
   560     return CKR_ARGUMENTS_BAD;
   561   }
   563   error = nssCKFWToken_verifyPointer(fwToken);
   564   if( CKR_OK != error ) {
   565     return error;
   566   }
   567 #endif /* NSSDEBUG */
   569   error = nssCKFWMutex_Lock(fwToken->mutex);
   570   if( CKR_OK != error ) {
   571     return error;
   572   }
   574   if (!fwToken->label) {
   575     if (fwToken->mdToken->GetLabel) {
   576       fwToken->label = fwToken->mdToken->GetLabel(fwToken->mdToken, fwToken,
   577         fwToken->mdInstance, fwToken->fwInstance, &error);
   578       if ((!fwToken->label) && (CKR_OK != error)) {
   579         goto done;
   580       }
   581     } else {
   582       fwToken->label = (NSSUTF8 *) "";
   583     }
   584   }
   586   (void)nssUTF8_CopyIntoFixedBuffer(fwToken->label, (char *)label, 32, ' ');
   587   error = CKR_OK;
   589  done:
   590   (void)nssCKFWMutex_Unlock(fwToken->mutex);
   591   return error;
   592 }
   594 /*
   595  * nssCKFWToken_GetManufacturerID
   596  *
   597  */
   598 NSS_IMPLEMENT CK_RV
   599 nssCKFWToken_GetManufacturerID
   600 (
   601   NSSCKFWToken *fwToken,
   602   CK_CHAR manufacturerID[32]
   603 )
   604 {
   605   CK_RV error = CKR_OK;
   607 #ifdef NSSDEBUG
   608   if( (CK_CHAR_PTR)NULL == manufacturerID ) {
   609     return CKR_ARGUMENTS_BAD;
   610   }
   612   error = nssCKFWToken_verifyPointer(fwToken);
   613   if( CKR_OK != error ) {
   614     return error;
   615   }
   616 #endif /* NSSDEBUG */
   618   error = nssCKFWMutex_Lock(fwToken->mutex);
   619   if( CKR_OK != error ) {
   620     return error;
   621   }
   623   if (!fwToken->manufacturerID) {
   624     if (fwToken->mdToken->GetManufacturerID) {
   625       fwToken->manufacturerID = fwToken->mdToken->GetManufacturerID(fwToken->mdToken,
   626         fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
   627       if ((!fwToken->manufacturerID) && (CKR_OK != error)) {
   628         goto done;
   629       }
   630     } else {
   631       fwToken->manufacturerID = (NSSUTF8 *)"";
   632     }
   633   }
   635   (void)nssUTF8_CopyIntoFixedBuffer(fwToken->manufacturerID, (char *)manufacturerID, 32, ' ');
   636   error = CKR_OK;
   638  done:
   639   (void)nssCKFWMutex_Unlock(fwToken->mutex);
   640   return error;
   641 }
   643 /*
   644  * nssCKFWToken_GetModel
   645  *
   646  */
   647 NSS_IMPLEMENT CK_RV
   648 nssCKFWToken_GetModel
   649 (
   650   NSSCKFWToken *fwToken,
   651   CK_CHAR model[16]
   652 )
   653 {
   654   CK_RV error = CKR_OK;
   656 #ifdef NSSDEBUG
   657   if( (CK_CHAR_PTR)NULL == model ) {
   658     return CKR_ARGUMENTS_BAD;
   659   }
   661   error = nssCKFWToken_verifyPointer(fwToken);
   662   if( CKR_OK != error ) {
   663     return error;
   664   }
   665 #endif /* NSSDEBUG */
   667   error = nssCKFWMutex_Lock(fwToken->mutex);
   668   if( CKR_OK != error ) {
   669     return error;
   670   }
   672   if (!fwToken->model) {
   673     if (fwToken->mdToken->GetModel) {
   674       fwToken->model = fwToken->mdToken->GetModel(fwToken->mdToken, fwToken,
   675         fwToken->mdInstance, fwToken->fwInstance, &error);
   676       if ((!fwToken->model) && (CKR_OK != error)) {
   677         goto done;
   678       }
   679     } else {
   680       fwToken->model = (NSSUTF8 *)"";
   681     }
   682   }
   684   (void)nssUTF8_CopyIntoFixedBuffer(fwToken->model, (char *)model, 16, ' ');
   685   error = CKR_OK;
   687  done:
   688   (void)nssCKFWMutex_Unlock(fwToken->mutex);
   689   return error;
   690 }
   692 /*
   693  * nssCKFWToken_GetSerialNumber
   694  *
   695  */
   696 NSS_IMPLEMENT CK_RV
   697 nssCKFWToken_GetSerialNumber
   698 (
   699   NSSCKFWToken *fwToken,
   700   CK_CHAR serialNumber[16]
   701 )
   702 {
   703   CK_RV error = CKR_OK;
   705 #ifdef NSSDEBUG
   706   if( (CK_CHAR_PTR)NULL == serialNumber ) {
   707     return CKR_ARGUMENTS_BAD;
   708   }
   710   error = nssCKFWToken_verifyPointer(fwToken);
   711   if( CKR_OK != error ) {
   712     return error;
   713   }
   714 #endif /* NSSDEBUG */
   716   error = nssCKFWMutex_Lock(fwToken->mutex);
   717   if( CKR_OK != error ) {
   718     return error;
   719   }
   721   if (!fwToken->serialNumber) {
   722     if (fwToken->mdToken->GetSerialNumber) {
   723       fwToken->serialNumber = fwToken->mdToken->GetSerialNumber(fwToken->mdToken, 
   724         fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
   725       if ((!fwToken->serialNumber) && (CKR_OK != error)) {
   726         goto done;
   727       }
   728     } else {
   729       fwToken->serialNumber = (NSSUTF8 *)"";
   730     }
   731   }
   733   (void)nssUTF8_CopyIntoFixedBuffer(fwToken->serialNumber, (char *)serialNumber, 16, ' ');
   734   error = CKR_OK;
   736  done:
   737   (void)nssCKFWMutex_Unlock(fwToken->mutex);
   738   return error;
   739 }
   742 /*
   743  * nssCKFWToken_GetHasRNG
   744  *
   745  */
   746 NSS_IMPLEMENT CK_BBOOL
   747 nssCKFWToken_GetHasRNG
   748 (
   749   NSSCKFWToken *fwToken
   750 )
   751 {
   752 #ifdef NSSDEBUG
   753   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   754     return CK_FALSE;
   755   }
   756 #endif /* NSSDEBUG */
   758   if (!fwToken->mdToken->GetHasRNG) {
   759     return CK_FALSE;
   760   }
   762   return fwToken->mdToken->GetHasRNG(fwToken->mdToken, fwToken, 
   763     fwToken->mdInstance, fwToken->fwInstance);
   764 }
   766 /*
   767  * nssCKFWToken_GetIsWriteProtected
   768  *
   769  */
   770 NSS_IMPLEMENT CK_BBOOL
   771 nssCKFWToken_GetIsWriteProtected
   772 (
   773   NSSCKFWToken *fwToken
   774 )
   775 {
   776 #ifdef NSSDEBUG
   777   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   778     return CK_FALSE;
   779   }
   780 #endif /* NSSDEBUG */
   782   if (!fwToken->mdToken->GetIsWriteProtected) {
   783     return CK_FALSE;
   784   }
   786   return fwToken->mdToken->GetIsWriteProtected(fwToken->mdToken, fwToken, 
   787     fwToken->mdInstance, fwToken->fwInstance);
   788 }
   790 /*
   791  * nssCKFWToken_GetLoginRequired
   792  *
   793  */
   794 NSS_IMPLEMENT CK_BBOOL
   795 nssCKFWToken_GetLoginRequired
   796 (
   797   NSSCKFWToken *fwToken
   798 )
   799 {
   800 #ifdef NSSDEBUG
   801   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   802     return CK_FALSE;
   803   }
   804 #endif /* NSSDEBUG */
   806   if (!fwToken->mdToken->GetLoginRequired) {
   807     return CK_FALSE;
   808   }
   810   return fwToken->mdToken->GetLoginRequired(fwToken->mdToken, fwToken, 
   811     fwToken->mdInstance, fwToken->fwInstance);
   812 }
   814 /*
   815  * nssCKFWToken_GetUserPinInitialized
   816  *
   817  */
   818 NSS_IMPLEMENT CK_BBOOL
   819 nssCKFWToken_GetUserPinInitialized
   820 (
   821   NSSCKFWToken *fwToken
   822 )
   823 {
   824 #ifdef NSSDEBUG
   825   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   826     return CK_FALSE;
   827   }
   828 #endif /* NSSDEBUG */
   830   if (!fwToken->mdToken->GetUserPinInitialized) {
   831     return CK_FALSE;
   832   }
   834   return fwToken->mdToken->GetUserPinInitialized(fwToken->mdToken, fwToken, 
   835     fwToken->mdInstance, fwToken->fwInstance);
   836 }
   838 /*
   839  * nssCKFWToken_GetRestoreKeyNotNeeded
   840  *
   841  */
   842 NSS_IMPLEMENT CK_BBOOL
   843 nssCKFWToken_GetRestoreKeyNotNeeded
   844 (
   845   NSSCKFWToken *fwToken
   846 )
   847 {
   848 #ifdef NSSDEBUG
   849   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   850     return CK_FALSE;
   851   }
   852 #endif /* NSSDEBUG */
   854   if (!fwToken->mdToken->GetRestoreKeyNotNeeded) {
   855     return CK_FALSE;
   856   }
   858   return fwToken->mdToken->GetRestoreKeyNotNeeded(fwToken->mdToken, fwToken, 
   859     fwToken->mdInstance, fwToken->fwInstance);
   860 }
   862 /*
   863  * nssCKFWToken_GetHasClockOnToken
   864  *
   865  */
   866 NSS_IMPLEMENT CK_BBOOL
   867 nssCKFWToken_GetHasClockOnToken
   868 (
   869   NSSCKFWToken *fwToken
   870 )
   871 {
   872 #ifdef NSSDEBUG
   873   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   874     return CK_FALSE;
   875   }
   876 #endif /* NSSDEBUG */
   878   if (!fwToken->mdToken->GetHasClockOnToken) {
   879     return CK_FALSE;
   880   }
   882   return fwToken->mdToken->GetHasClockOnToken(fwToken->mdToken, fwToken, 
   883     fwToken->mdInstance, fwToken->fwInstance);
   884 }
   886 /*
   887  * nssCKFWToken_GetHasProtectedAuthenticationPath
   888  *
   889  */
   890 NSS_IMPLEMENT CK_BBOOL
   891 nssCKFWToken_GetHasProtectedAuthenticationPath
   892 (
   893   NSSCKFWToken *fwToken
   894 )
   895 {
   896 #ifdef NSSDEBUG
   897   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   898     return CK_FALSE;
   899   }
   900 #endif /* NSSDEBUG */
   902   if (!fwToken->mdToken->GetHasProtectedAuthenticationPath) {
   903     return CK_FALSE;
   904   }
   906   return fwToken->mdToken->GetHasProtectedAuthenticationPath(fwToken->mdToken, 
   907     fwToken, fwToken->mdInstance, fwToken->fwInstance);
   908 }
   910 /*
   911  * nssCKFWToken_GetSupportsDualCryptoOperations
   912  *
   913  */
   914 NSS_IMPLEMENT CK_BBOOL
   915 nssCKFWToken_GetSupportsDualCryptoOperations
   916 (
   917   NSSCKFWToken *fwToken
   918 )
   919 {
   920 #ifdef NSSDEBUG
   921   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   922     return CK_FALSE;
   923   }
   924 #endif /* NSSDEBUG */
   926   if (!fwToken->mdToken->GetSupportsDualCryptoOperations) {
   927     return CK_FALSE;
   928   }
   930   return fwToken->mdToken->GetSupportsDualCryptoOperations(fwToken->mdToken, 
   931     fwToken, fwToken->mdInstance, fwToken->fwInstance);
   932 }
   934 /*
   935  * nssCKFWToken_GetMaxSessionCount
   936  *
   937  */
   938 NSS_IMPLEMENT CK_ULONG
   939 nssCKFWToken_GetMaxSessionCount
   940 (
   941   NSSCKFWToken *fwToken
   942 )
   943 {
   944 #ifdef NSSDEBUG
   945   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   946     return CK_UNAVAILABLE_INFORMATION;
   947   }
   948 #endif /* NSSDEBUG */
   950   if (!fwToken->mdToken->GetMaxSessionCount) {
   951     return CK_UNAVAILABLE_INFORMATION;
   952   }
   954   return fwToken->mdToken->GetMaxSessionCount(fwToken->mdToken, fwToken, 
   955     fwToken->mdInstance, fwToken->fwInstance);
   956 }
   958 /*
   959  * nssCKFWToken_GetMaxRwSessionCount
   960  *
   961  */
   962 NSS_IMPLEMENT CK_ULONG
   963 nssCKFWToken_GetMaxRwSessionCount
   964 (
   965   NSSCKFWToken *fwToken
   966 )
   967 {
   968 #ifdef NSSDEBUG
   969   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   970     return CK_UNAVAILABLE_INFORMATION;
   971   }
   972 #endif /* NSSDEBUG */
   974   if (!fwToken->mdToken->GetMaxRwSessionCount) {
   975     return CK_UNAVAILABLE_INFORMATION;
   976   }
   978   return fwToken->mdToken->GetMaxRwSessionCount(fwToken->mdToken, fwToken, 
   979     fwToken->mdInstance, fwToken->fwInstance);
   980 }
   982 /*
   983  * nssCKFWToken_GetMaxPinLen
   984  *
   985  */
   986 NSS_IMPLEMENT CK_ULONG
   987 nssCKFWToken_GetMaxPinLen
   988 (
   989   NSSCKFWToken *fwToken
   990 )
   991 {
   992 #ifdef NSSDEBUG
   993   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
   994     return CK_UNAVAILABLE_INFORMATION;
   995   }
   996 #endif /* NSSDEBUG */
   998   if (!fwToken->mdToken->GetMaxPinLen) {
   999     return CK_UNAVAILABLE_INFORMATION;
  1002   return fwToken->mdToken->GetMaxPinLen(fwToken->mdToken, fwToken, 
  1003     fwToken->mdInstance, fwToken->fwInstance);
  1006 /*
  1007  * nssCKFWToken_GetMinPinLen
  1009  */
  1010 NSS_IMPLEMENT CK_ULONG
  1011 nssCKFWToken_GetMinPinLen
  1013   NSSCKFWToken *fwToken
  1016 #ifdef NSSDEBUG
  1017   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1018     return CK_UNAVAILABLE_INFORMATION;
  1020 #endif /* NSSDEBUG */
  1022   if (!fwToken->mdToken->GetMinPinLen) {
  1023     return CK_UNAVAILABLE_INFORMATION;
  1026   return fwToken->mdToken->GetMinPinLen(fwToken->mdToken, fwToken, 
  1027     fwToken->mdInstance, fwToken->fwInstance);
  1030 /*
  1031  * nssCKFWToken_GetTotalPublicMemory
  1033  */
  1034 NSS_IMPLEMENT CK_ULONG
  1035 nssCKFWToken_GetTotalPublicMemory
  1037   NSSCKFWToken *fwToken
  1040 #ifdef NSSDEBUG
  1041   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1042     return CK_UNAVAILABLE_INFORMATION;
  1044 #endif /* NSSDEBUG */
  1046   if (!fwToken->mdToken->GetTotalPublicMemory) {
  1047     return CK_UNAVAILABLE_INFORMATION;
  1050   return fwToken->mdToken->GetTotalPublicMemory(fwToken->mdToken, fwToken, 
  1051     fwToken->mdInstance, fwToken->fwInstance);
  1054 /*
  1055  * nssCKFWToken_GetFreePublicMemory
  1057  */
  1058 NSS_IMPLEMENT CK_ULONG
  1059 nssCKFWToken_GetFreePublicMemory
  1061   NSSCKFWToken *fwToken
  1064 #ifdef NSSDEBUG
  1065   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1066     return CK_UNAVAILABLE_INFORMATION;
  1068 #endif /* NSSDEBUG */
  1070   if (!fwToken->mdToken->GetFreePublicMemory) {
  1071     return CK_UNAVAILABLE_INFORMATION;
  1074   return fwToken->mdToken->GetFreePublicMemory(fwToken->mdToken, fwToken, 
  1075     fwToken->mdInstance, fwToken->fwInstance);
  1078 /*
  1079  * nssCKFWToken_GetTotalPrivateMemory
  1081  */
  1082 NSS_IMPLEMENT CK_ULONG
  1083 nssCKFWToken_GetTotalPrivateMemory
  1085   NSSCKFWToken *fwToken
  1088 #ifdef NSSDEBUG
  1089   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1090     return CK_UNAVAILABLE_INFORMATION;
  1092 #endif /* NSSDEBUG */
  1094   if (!fwToken->mdToken->GetTotalPrivateMemory) {
  1095     return CK_UNAVAILABLE_INFORMATION;
  1098   return fwToken->mdToken->GetTotalPrivateMemory(fwToken->mdToken, fwToken, 
  1099     fwToken->mdInstance, fwToken->fwInstance);
  1102 /*
  1103  * nssCKFWToken_GetFreePrivateMemory
  1105  */
  1106 NSS_IMPLEMENT CK_ULONG
  1107 nssCKFWToken_GetFreePrivateMemory
  1109   NSSCKFWToken *fwToken
  1112 #ifdef NSSDEBUG
  1113   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1114     return CK_UNAVAILABLE_INFORMATION;
  1116 #endif /* NSSDEBUG */
  1118   if (!fwToken->mdToken->GetFreePrivateMemory) {
  1119     return CK_UNAVAILABLE_INFORMATION;
  1122   return fwToken->mdToken->GetFreePrivateMemory(fwToken->mdToken, fwToken, 
  1123     fwToken->mdInstance, fwToken->fwInstance);
  1126 /*
  1127  * nssCKFWToken_GetHardwareVersion
  1129  */
  1130 NSS_IMPLEMENT CK_VERSION
  1131 nssCKFWToken_GetHardwareVersion
  1133   NSSCKFWToken *fwToken
  1136   CK_VERSION rv;
  1138 #ifdef NSSDEBUG
  1139   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1140     rv.major = rv.minor = 0;
  1141     return rv;
  1143 #endif /* NSSDEBUG */
  1145   if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1146     rv.major = rv.minor = 0;
  1147     return rv;
  1150   if( (0 != fwToken->hardwareVersion.major) ||
  1151       (0 != fwToken->hardwareVersion.minor) ) {
  1152     rv = fwToken->hardwareVersion;
  1153     goto done;
  1156   if (fwToken->mdToken->GetHardwareVersion) {
  1157     fwToken->hardwareVersion = fwToken->mdToken->GetHardwareVersion(
  1158       fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
  1159   } else {
  1160     fwToken->hardwareVersion.major = 0;
  1161     fwToken->hardwareVersion.minor = 1;
  1164   rv = fwToken->hardwareVersion;
  1166  done:
  1167   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1168   return rv;
  1171 /*
  1172  * nssCKFWToken_GetFirmwareVersion
  1174  */
  1175 NSS_IMPLEMENT CK_VERSION
  1176 nssCKFWToken_GetFirmwareVersion
  1178   NSSCKFWToken *fwToken
  1181   CK_VERSION rv;
  1183 #ifdef NSSDEBUG
  1184   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1185     rv.major = rv.minor = 0;
  1186     return rv;
  1188 #endif /* NSSDEBUG */
  1190   if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1191     rv.major = rv.minor = 0;
  1192     return rv;
  1195   if( (0 != fwToken->firmwareVersion.major) ||
  1196       (0 != fwToken->firmwareVersion.minor) ) {
  1197     rv = fwToken->firmwareVersion;
  1198     goto done;
  1201   if (fwToken->mdToken->GetFirmwareVersion) {
  1202     fwToken->firmwareVersion = fwToken->mdToken->GetFirmwareVersion(
  1203       fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
  1204   } else {
  1205     fwToken->firmwareVersion.major = 0;
  1206     fwToken->firmwareVersion.minor = 1;
  1209   rv = fwToken->firmwareVersion;
  1211  done:
  1212   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1213   return rv;
  1216 /*
  1217  * nssCKFWToken_GetUTCTime
  1219  */
  1220 NSS_IMPLEMENT CK_RV
  1221 nssCKFWToken_GetUTCTime
  1223   NSSCKFWToken *fwToken,
  1224   CK_CHAR utcTime[16]
  1227   CK_RV error = CKR_OK;
  1229 #ifdef NSSDEBUG
  1230   error = nssCKFWToken_verifyPointer(fwToken);
  1231   if( CKR_OK != error ) {
  1232     return error;
  1235   if( (CK_CHAR_PTR)NULL == utcTime ) {
  1236     return CKR_ARGUMENTS_BAD;
  1238 #endif /* DEBUG */
  1240   if( CK_TRUE != nssCKFWToken_GetHasClockOnToken(fwToken) ) {
  1241     /* return CKR_DEVICE_ERROR; */
  1242     (void)nssUTF8_CopyIntoFixedBuffer((NSSUTF8 *)NULL, (char *)utcTime, 16, ' ');
  1243     return CKR_OK;
  1246   if (!fwToken->mdToken->GetUTCTime) {
  1247     /* It said it had one! */
  1248     return CKR_GENERAL_ERROR;
  1251   error = fwToken->mdToken->GetUTCTime(fwToken->mdToken, fwToken, 
  1252             fwToken->mdInstance, fwToken->fwInstance, utcTime);
  1253   if( CKR_OK != error ) {
  1254     return error;
  1257   /* Sanity-check the data */
  1259     /* Format is YYYYMMDDhhmmss00 */
  1260     int i;
  1261     int Y, M, D, h, m, s, z;
  1262     static int dims[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  1264     for( i = 0; i < 16; i++ ) {
  1265       if( (utcTime[i] < '0') || (utcTime[i] > '9') ) {
  1266         goto badtime;
  1270     Y = ((utcTime[ 0] - '0') * 1000) + ((utcTime[1] - '0') * 100) +
  1271         ((utcTime[ 2] - '0') * 10) + (utcTime[ 3] - '0');
  1272     M = ((utcTime[ 4] - '0') * 10) + (utcTime[ 5] - '0');
  1273     D = ((utcTime[ 6] - '0') * 10) + (utcTime[ 7] - '0');
  1274     h = ((utcTime[ 8] - '0') * 10) + (utcTime[ 9] - '0');
  1275     m = ((utcTime[10] - '0') * 10) + (utcTime[11] - '0');
  1276     s = ((utcTime[12] - '0') * 10) + (utcTime[13] - '0');
  1277     z = ((utcTime[14] - '0') * 10) + (utcTime[15] - '0');
  1279     if( (Y < 1990) || (Y > 3000) ) goto badtime; /* Y3K problem.  heh heh heh */
  1280     if( (M < 1) || (M > 12) ) goto badtime;
  1281     if( (D < 1) || (D > 31) ) goto badtime;
  1283     if( D > dims[M-1] ) goto badtime; /* per-month check */
  1284     if( (2 == M) && (((Y%4)||!(Y%100))&&(Y%400)) && (D > 28) ) goto badtime; /* leap years */
  1286     if( (h < 0) || (h > 23) ) goto badtime;
  1287     if( (m < 0) || (m > 60) ) goto badtime;
  1288     if( (s < 0) || (s > 61) ) goto badtime;
  1290     /* 60m and 60 or 61s is only allowed for leap seconds. */
  1291     if( (60 == m) || (s >= 60) ) {
  1292       if( (23 != h) || (60 != m) || (s < 60) ) goto badtime;
  1293       /* leap seconds can only happen on June 30 or Dec 31.. I think */
  1294       /* if( ((6 != M) || (30 != D)) && ((12 != M) || (31 != D)) ) goto badtime; */
  1298   return CKR_OK;
  1300  badtime:
  1301   return CKR_GENERAL_ERROR;
  1304 /*
  1305  * nssCKFWToken_OpenSession
  1307  */
  1308 NSS_IMPLEMENT NSSCKFWSession *
  1309 nssCKFWToken_OpenSession
  1311   NSSCKFWToken *fwToken,
  1312   CK_BBOOL rw,
  1313   CK_VOID_PTR pApplication,
  1314   CK_NOTIFY Notify,
  1315   CK_RV *pError
  1318   NSSCKFWSession *fwSession = (NSSCKFWSession *)NULL;
  1319   NSSCKMDSession *mdSession;
  1321 #ifdef NSSDEBUG
  1322   if (!pError) {
  1323     return (NSSCKFWSession *)NULL;
  1326   *pError = nssCKFWToken_verifyPointer(fwToken);
  1327   if( CKR_OK != *pError ) {
  1328     return (NSSCKFWSession *)NULL;
  1331   switch( rw ) {
  1332   case CK_TRUE:
  1333   case CK_FALSE:
  1334     break;
  1335   default:
  1336     *pError = CKR_ARGUMENTS_BAD;
  1337     return (NSSCKFWSession *)NULL;
  1339 #endif /* NSSDEBUG */
  1341   *pError = nssCKFWMutex_Lock(fwToken->mutex);
  1342   if( CKR_OK != *pError ) {
  1343     return (NSSCKFWSession *)NULL;
  1346   if( CK_TRUE == rw ) {
  1347     /* Read-write session desired */
  1348     if( CK_TRUE == nssCKFWToken_GetIsWriteProtected(fwToken) ) {
  1349       *pError = CKR_TOKEN_WRITE_PROTECTED;
  1350       goto done;
  1352   } else {
  1353     /* Read-only session desired */
  1354     if( CKS_RW_SO_FUNCTIONS == nssCKFWToken_GetSessionState(fwToken) ) {
  1355       *pError = CKR_SESSION_READ_WRITE_SO_EXISTS;
  1356       goto done;
  1360   /* We could compare sesion counts to any limits we know of, I guess.. */
  1362   if (!fwToken->mdToken->OpenSession) {
  1363     /*
  1364      * I'm not sure that the Module actually needs to implement
  1365      * mdSessions -- the Framework can keep track of everything 
  1366      * needed, really.  But I'll sort out that detail later..
  1367      */
  1368     *pError = CKR_GENERAL_ERROR;
  1369     goto done;
  1372   fwSession = nssCKFWSession_Create(fwToken, rw, pApplication, Notify, pError);
  1373   if (!fwSession) {
  1374     if( CKR_OK == *pError ) {
  1375       *pError = CKR_GENERAL_ERROR;
  1377     goto done;
  1380   mdSession = fwToken->mdToken->OpenSession(fwToken->mdToken, fwToken,
  1381                 fwToken->mdInstance, fwToken->fwInstance, fwSession,
  1382                 rw, pError);
  1383   if (!mdSession) {
  1384     (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  1385     if( CKR_OK == *pError ) {
  1386       *pError = CKR_GENERAL_ERROR;
  1388     goto done;
  1391   *pError = nssCKFWSession_SetMDSession(fwSession, mdSession);
  1392   if( CKR_OK != *pError ) {
  1393     if (mdSession->Close) {
  1394       mdSession->Close(mdSession, fwSession, fwToken->mdToken, fwToken,
  1395       fwToken->mdInstance, fwToken->fwInstance);
  1397     (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  1398     goto done;
  1401   *pError = nssCKFWHash_Add(fwToken->sessions, fwSession, fwSession);
  1402   if( CKR_OK != *pError ) {
  1403     (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  1404     fwSession = (NSSCKFWSession *)NULL;
  1405     goto done;
  1408  done:
  1409   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1410   return fwSession;
  1413 /*
  1414  * nssCKFWToken_GetMechanismCount
  1416  */
  1417 NSS_IMPLEMENT CK_ULONG
  1418 nssCKFWToken_GetMechanismCount
  1420   NSSCKFWToken *fwToken
  1423 #ifdef NSSDEBUG
  1424   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1425     return 0;
  1427 #endif /* NSSDEBUG */
  1429   if (!fwToken->mdToken->GetMechanismCount) {
  1430     return 0;
  1433   return fwToken->mdToken->GetMechanismCount(fwToken->mdToken, fwToken,
  1434     fwToken->mdInstance, fwToken->fwInstance);
  1437 /*
  1438  * nssCKFWToken_GetMechanismTypes
  1440  */
  1441 NSS_IMPLEMENT CK_RV
  1442 nssCKFWToken_GetMechanismTypes
  1444   NSSCKFWToken *fwToken,
  1445   CK_MECHANISM_TYPE types[]
  1448 #ifdef NSSDEBUG
  1449   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1450     return CKR_ARGUMENTS_BAD;
  1453   if (!types) {
  1454     return CKR_ARGUMENTS_BAD;
  1456 #endif /* NSSDEBUG */
  1458   if (!fwToken->mdToken->GetMechanismTypes) {
  1459     /*
  1460      * This should only be called with a sufficiently-large
  1461      * "types" array, which can only be done if GetMechanismCount
  1462      * is implemented.  If that's implemented (and returns nonzero),
  1463      * then this should be too.  So return an error.
  1464      */
  1465     return CKR_GENERAL_ERROR;
  1468   return fwToken->mdToken->GetMechanismTypes(fwToken->mdToken, fwToken,
  1469     fwToken->mdInstance, fwToken->fwInstance, types);
  1473 /*
  1474  * nssCKFWToken_GetMechanism
  1476  */
  1477 NSS_IMPLEMENT NSSCKFWMechanism *
  1478 nssCKFWToken_GetMechanism
  1480   NSSCKFWToken *fwToken,
  1481   CK_MECHANISM_TYPE which,
  1482   CK_RV *pError
  1485   NSSCKMDMechanism *mdMechanism;
  1486   if (!fwToken->mdMechanismHash) {
  1487     *pError = CKR_GENERAL_ERROR;
  1488     return (NSSCKFWMechanism *)NULL;
  1491   if (!fwToken->mdToken->GetMechanism) {
  1492     /*
  1493      * If we don't implement any GetMechanism function, then we must
  1494      * not support any.
  1495      */
  1496     *pError = CKR_MECHANISM_INVALID;
  1497     return (NSSCKFWMechanism *)NULL;
  1500   /* lookup in hash table */
  1501   mdMechanism = fwToken->mdToken->GetMechanism(fwToken->mdToken, fwToken,
  1502     fwToken->mdInstance, fwToken->fwInstance, which, pError);
  1503   if (!mdMechanism) {
  1504     return (NSSCKFWMechanism *) NULL;
  1506   /* store in hash table */
  1507   return nssCKFWMechanism_Create(mdMechanism, fwToken->mdToken, fwToken,
  1508     fwToken->mdInstance, fwToken->fwInstance);
  1511 NSS_IMPLEMENT CK_RV
  1512 nssCKFWToken_SetSessionState
  1514   NSSCKFWToken *fwToken,
  1515   CK_STATE newState
  1518   CK_RV error = CKR_OK;
  1520 #ifdef NSSDEBUG
  1521   error = nssCKFWToken_verifyPointer(fwToken);
  1522   if( CKR_OK != error ) {
  1523     return error;
  1526   switch( newState ) {
  1527   case CKS_RO_PUBLIC_SESSION:
  1528   case CKS_RO_USER_FUNCTIONS:
  1529   case CKS_RW_PUBLIC_SESSION:
  1530   case CKS_RW_USER_FUNCTIONS:
  1531   case CKS_RW_SO_FUNCTIONS:
  1532     break;
  1533   default:
  1534     return CKR_ARGUMENTS_BAD;
  1536 #endif /* NSSDEBUG */
  1538   error = nssCKFWMutex_Lock(fwToken->mutex);
  1539   if( CKR_OK != error ) {
  1540     return error;
  1543   fwToken->state = newState;
  1544   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1545   return CKR_OK;
  1548 /*
  1549  * nssCKFWToken_RemoveSession
  1551  */
  1552 NSS_IMPLEMENT CK_RV
  1553 nssCKFWToken_RemoveSession
  1555   NSSCKFWToken *fwToken,
  1556   NSSCKFWSession *fwSession
  1559   CK_RV error = CKR_OK;
  1561 #ifdef NSSDEBUG
  1562   error = nssCKFWToken_verifyPointer(fwToken);
  1563   if( CKR_OK != error ) {
  1564     return error;
  1567   error = nssCKFWSession_verifyPointer(fwSession);
  1568   if( CKR_OK != error ) {
  1569     return error;
  1571 #endif /* NSSDEBUG */
  1573   error = nssCKFWMutex_Lock(fwToken->mutex);
  1574   if( CKR_OK != error ) {
  1575     return error;
  1578   if( CK_TRUE != nssCKFWHash_Exists(fwToken->sessions, fwSession) ) {
  1579     error = CKR_SESSION_HANDLE_INVALID;
  1580     goto done;
  1583   nssCKFWHash_Remove(fwToken->sessions, fwSession);
  1584   fwToken->sessionCount--;
  1586   if( nssCKFWSession_IsRWSession(fwSession) ) {
  1587     fwToken->rwSessionCount--;
  1590   if( 0 == fwToken->sessionCount ) {
  1591     fwToken->rwSessionCount = 0; /* sanity */
  1592     fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
  1595   error = CKR_OK;
  1597  done:
  1598   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1599   return error;
  1603 /*
  1604  * nssCKFWToken_CloseAllSessions
  1606  */
  1607 NSS_IMPLEMENT CK_RV
  1608 nssCKFWToken_CloseAllSessions
  1610   NSSCKFWToken *fwToken
  1613   CK_RV error = CKR_OK;
  1615 #ifdef NSSDEBUG
  1616   error = nssCKFWToken_verifyPointer(fwToken);
  1617   if( CKR_OK != error ) {
  1618     return error;
  1620 #endif /* NSSDEBUG */
  1622   error = nssCKFWMutex_Lock(fwToken->mutex);
  1623   if( CKR_OK != error ) {
  1624     return error;
  1627   nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, (void *)NULL);
  1629   nssCKFWHash_Destroy(fwToken->sessions);
  1631   fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, fwToken->arena, &error);
  1632   if (!fwToken->sessions) {
  1633     if( CKR_OK == error ) {
  1634       error = CKR_GENERAL_ERROR;
  1636     goto done;
  1639   fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
  1640   fwToken->sessionCount = 0;
  1641   fwToken->rwSessionCount = 0;
  1643   error = CKR_OK;
  1645  done:
  1646   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1647   return error;
  1650 /*
  1651  * nssCKFWToken_GetSessionCount
  1653  */
  1654 NSS_IMPLEMENT CK_ULONG
  1655 nssCKFWToken_GetSessionCount
  1657   NSSCKFWToken *fwToken
  1660   CK_ULONG rv;
  1662 #ifdef NSSDEBUG
  1663   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1664     return (CK_ULONG)0;
  1666 #endif /* NSSDEBUG */
  1668   if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1669     return (CK_ULONG)0;
  1672   rv = fwToken->sessionCount;
  1673   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1674   return rv;
  1677 /*
  1678  * nssCKFWToken_GetRwSessionCount
  1680  */
  1681 NSS_IMPLEMENT CK_ULONG
  1682 nssCKFWToken_GetRwSessionCount
  1684   NSSCKFWToken *fwToken
  1687   CK_ULONG rv;
  1689 #ifdef NSSDEBUG
  1690   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1691     return (CK_ULONG)0;
  1693 #endif /* NSSDEBUG */
  1695   if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1696     return (CK_ULONG)0;
  1699   rv = fwToken->rwSessionCount;
  1700   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1701   return rv;
  1704 /*
  1705  * nssCKFWToken_GetRoSessionCount
  1707  */
  1708 NSS_IMPLEMENT CK_ULONG
  1709 nssCKFWToken_GetRoSessionCount
  1711   NSSCKFWToken *fwToken
  1714   CK_ULONG rv;
  1716 #ifdef NSSDEBUG
  1717   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1718     return (CK_ULONG)0;
  1720 #endif /* NSSDEBUG */
  1722   if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1723     return (CK_ULONG)0;
  1726   rv = fwToken->sessionCount - fwToken->rwSessionCount;
  1727   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1728   return rv;
  1731 /*
  1732  * nssCKFWToken_GetSessionObjectHash
  1734  */
  1735 NSS_IMPLEMENT nssCKFWHash *
  1736 nssCKFWToken_GetSessionObjectHash
  1738   NSSCKFWToken *fwToken
  1741 #ifdef NSSDEBUG
  1742   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1743     return (nssCKFWHash *)NULL;
  1745 #endif /* NSSDEBUG */
  1747   return fwToken->sessionObjectHash;
  1750 /*
  1751  * nssCKFWToken_GetMDObjectHash
  1753  */
  1754 NSS_IMPLEMENT nssCKFWHash *
  1755 nssCKFWToken_GetMDObjectHash
  1757   NSSCKFWToken *fwToken
  1760 #ifdef NSSDEBUG
  1761   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1762     return (nssCKFWHash *)NULL;
  1764 #endif /* NSSDEBUG */
  1766   return fwToken->mdObjectHash;
  1769 /*
  1770  * nssCKFWToken_GetObjectHandleHash
  1772  */
  1773 NSS_IMPLEMENT nssCKFWHash *
  1774 nssCKFWToken_GetObjectHandleHash
  1776   NSSCKFWToken *fwToken
  1779 #ifdef NSSDEBUG
  1780   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1781     return (nssCKFWHash *)NULL;
  1783 #endif /* NSSDEBUG */
  1785   return fwToken->mdObjectHash;
  1788 /*
  1789  * NSSCKFWToken_GetMDToken
  1791  */
  1793 NSS_IMPLEMENT NSSCKMDToken *
  1794 NSSCKFWToken_GetMDToken
  1796   NSSCKFWToken *fwToken
  1799 #ifdef DEBUG
  1800   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1801     return (NSSCKMDToken *)NULL;
  1803 #endif /* DEBUG */
  1805   return nssCKFWToken_GetMDToken(fwToken);
  1808 /*
  1809  * NSSCKFWToken_GetArena
  1811  */
  1813 NSS_IMPLEMENT NSSArena *
  1814 NSSCKFWToken_GetArena
  1816   NSSCKFWToken *fwToken,
  1817   CK_RV *pError
  1820 #ifdef DEBUG
  1821   if (!pError) {
  1822     return (NSSArena *)NULL;
  1825   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1826     *pError = CKR_ARGUMENTS_BAD;
  1827     return (NSSArena *)NULL;
  1829 #endif /* DEBUG */
  1831   return nssCKFWToken_GetArena(fwToken, pError);
  1834 /*
  1835  * NSSCKFWToken_GetFWSlot
  1837  */
  1839 NSS_IMPLEMENT NSSCKFWSlot *
  1840 NSSCKFWToken_GetFWSlot
  1842   NSSCKFWToken *fwToken
  1845 #ifdef DEBUG
  1846   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1847     return (NSSCKFWSlot *)NULL;
  1849 #endif /* DEBUG */
  1851   return nssCKFWToken_GetFWSlot(fwToken);
  1854 /*
  1855  * NSSCKFWToken_GetMDSlot
  1857  */
  1859 NSS_IMPLEMENT NSSCKMDSlot *
  1860 NSSCKFWToken_GetMDSlot
  1862   NSSCKFWToken *fwToken
  1865 #ifdef DEBUG
  1866   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1867     return (NSSCKMDSlot *)NULL;
  1869 #endif /* DEBUG */
  1871   return nssCKFWToken_GetMDSlot(fwToken);
  1874 /*
  1875  * NSSCKFWToken_GetSessionState
  1877  */
  1879 NSS_IMPLEMENT CK_STATE
  1880 NSSCKFWSession_GetSessionState
  1882   NSSCKFWToken *fwToken
  1885 #ifdef DEBUG
  1886   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1887     return CKS_RO_PUBLIC_SESSION;
  1889 #endif /* DEBUG */
  1891   return nssCKFWToken_GetSessionState(fwToken);

mercurial