token.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:39k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /* 
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. #ifdef DEBUG
  34. static const char CVS_ID[] = "@(#) $RCSfile: token.c,v $ $Revision: 1.4 $ $Date: 2000/09/06 22:23:57 $ $Name: NSS_3_1_1_RTM $";
  35. #endif /* DEBUG */
  36. /*
  37.  * token.c
  38.  *
  39.  * This file implements the NSSCKFWToken type and methods.
  40.  */
  41. #ifndef CK_T
  42. #include "ck.h"
  43. #endif /* CK_T */
  44. /*
  45.  * NSSCKFWToken
  46.  *
  47.  *  -- create/destroy --
  48.  *  nssCKFWToken_Create
  49.  *  nssCKFWToken_Destroy
  50.  *
  51.  *  -- public accessors --
  52.  *  NSSCKFWToken_GetMDToken
  53.  *  NSSCKFWToken_GetFWSlot
  54.  *  NSSCKFWToken_GetMDSlot
  55.  *  NSSCKFWToken_GetSessionState
  56.  *
  57.  *  -- implement public accessors --
  58.  *  nssCKFWToken_GetMDToken
  59.  *  nssCKFWToken_GetFWSlot
  60.  *  nssCKFWToken_GetMDSlot
  61.  *  nssCKFWToken_GetSessionState
  62.  *  nssCKFWToken_SetSessionState
  63.  *
  64.  *  -- private accessors --
  65.  *  nssCKFWToken_SetSessionState
  66.  *  nssCKFWToken_RemoveSession
  67.  *  nssCKFWToken_CloseAllSessions
  68.  *  nssCKFWToken_GetSessionCount
  69.  *  nssCKFWToken_GetRwSessionCount
  70.  *  nssCKFWToken_GetRoSessionCount
  71.  *  nssCKFWToken_GetSessionObjectHash
  72.  *  nssCKFWToken_GetMDObjectHash
  73.  *  nssCKFWToken_GetObjectHandleHash
  74.  *
  75.  *  -- module fronts --
  76.  *  nssCKFWToken_InitToken
  77.  *  nssCKFWToken_GetLabel
  78.  *  nssCKFWToken_GetManufacturerID
  79.  *  nssCKFWToken_GetModel
  80.  *  nssCKFWToken_GetSerialNumber
  81.  *  nssCKFWToken_GetHasRNG
  82.  *  nssCKFWToken_GetIsWriteProtected
  83.  *  nssCKFWToken_GetLoginRequired
  84.  *  nssCKFWToken_GetUserPinInitialized
  85.  *  nssCKFWToken_GetRestoreKeyNotNeeded
  86.  *  nssCKFWToken_GetHasClockOnToken
  87.  *  nssCKFWToken_GetHasProtectedAuthenticationPath
  88.  *  nssCKFWToken_GetSupportsDualCryptoOperations
  89.  *  nssCKFWToken_GetMaxSessionCount
  90.  *  nssCKFWToken_GetMaxRwSessionCount
  91.  *  nssCKFWToken_GetMaxPinLen
  92.  *  nssCKFWToken_GetMinPinLen
  93.  *  nssCKFWToken_GetTotalPublicMemory
  94.  *  nssCKFWToken_GetFreePublicMemory
  95.  *  nssCKFWToken_GetTotalPrivateMemory
  96.  *  nssCKFWToken_GetFreePrivateMemory
  97.  *  nssCKFWToken_GetHardwareVersion
  98.  *  nssCKFWToken_GetFirmwareVersion
  99.  *  nssCKFWToken_GetUTCTime
  100.  *  nssCKFWToken_OpenSession
  101.  *  nssCKFWToken_GetMechanismCount
  102.  *  nssCKFWToken_GetMechanismTypes
  103.  *  nssCKFWToken_GetMechanism
  104.  */
  105. struct NSSCKFWTokenStr {
  106.   NSSCKFWMutex *mutex;
  107.   NSSArena *arena;
  108.   NSSCKMDToken *mdToken;
  109.   NSSCKFWSlot *fwSlot;
  110.   NSSCKMDSlot *mdSlot;
  111.   NSSCKFWInstance *fwInstance;
  112.   NSSCKMDInstance *mdInstance;
  113.   /*
  114.    * Everything above is set at creation time, and then not modified.
  115.    * The invariants the mutex protects are:
  116.    *
  117.    * 1) Each of the cached descriptions (versions, etc.) are in an
  118.    *    internally consistant state.
  119.    *
  120.    * 2) The session counts and hashes are consistant.
  121.    *
  122.    * 3) The object hashes are consistant.
  123.    *
  124.    * Note that the calls accessing the cached descriptions will call
  125.    * the NSSCKMDToken methods with the mutex locked.  Those methods
  126.    * may then call the public NSSCKFWToken routines.  Those public
  127.    * routines only access the constant data above and the atomic
  128.    * CK_STATE session state variable below, so there's no problem.
  129.    * But be careful if you add to this object; mutexes are in
  130.    * general not reentrant, so don't create deadlock situations.
  131.    */
  132.   NSSUTF8 *label;
  133.   NSSUTF8 *manufacturerID;
  134.   NSSUTF8 *model;
  135.   NSSUTF8 *serialNumber;
  136.   CK_VERSION hardwareVersion;
  137.   CK_VERSION firmwareVersion;
  138.   CK_ULONG sessionCount;
  139.   CK_ULONG rwSessionCount;
  140.   nssCKFWHash *sessions;
  141.   nssCKFWHash *sessionObjectHash;
  142.   nssCKFWHash *mdObjectHash;
  143.   CK_STATE state;
  144. };
  145. #ifdef DEBUG
  146. /*
  147.  * But first, the pointer-tracking stuff.
  148.  *
  149.  * NOTE: the pointer-tracking support in NSS/base currently relies
  150.  * upon NSPR's CallOnce support.  That, however, relies upon NSPR's
  151.  * locking, which is tied into the runtime.  We need a pointer-tracker
  152.  * implementation that uses the locks supplied through C_Initialize.
  153.  * That support, however, can be filled in later.  So for now, I'll
  154.  * just do this routines as no-ops.
  155.  */
  156. static CK_RV
  157. token_add_pointer
  158. (
  159.   const NSSCKFWToken *fwToken
  160. )
  161. {
  162.   return CKR_OK;
  163. }
  164. static CK_RV
  165. token_remove_pointer
  166. (
  167.   const NSSCKFWToken *fwToken
  168. )
  169. {
  170.   return CKR_OK;
  171. }
  172. NSS_IMPLEMENT CK_RV
  173. nssCKFWToken_verifyPointer
  174. (
  175.   const NSSCKFWToken *fwToken
  176. )
  177. {
  178.   return CKR_OK;
  179. }
  180. #endif /* DEBUG */
  181. /*
  182.  * nssCKFWToken_Create
  183.  *
  184.  */
  185. NSS_IMPLEMENT NSSCKFWToken *
  186. nssCKFWToken_Create
  187. (
  188.   NSSCKFWSlot *fwSlot,
  189.   NSSCKMDToken *mdToken,
  190.   CK_RV *pError
  191. )
  192. {
  193.   NSSArena *arena = (NSSArena *)NULL;
  194.   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
  195.   CK_BBOOL called_setup = CK_FALSE;
  196.   /*
  197.    * We have already verified the arguments in nssCKFWSlot_GetToken.
  198.    */
  199.   arena = NSSArena_Create();
  200.   if( (NSSArena *)NULL == arena ) {
  201.     *pError = CKR_HOST_MEMORY;
  202.     goto loser;
  203.   }
  204.   fwToken = nss_ZNEW(arena, NSSCKFWToken);
  205.   if( (NSSCKFWToken *)NULL == fwToken ) {
  206.     *pError = CKR_HOST_MEMORY;
  207.     goto loser;
  208.   }    
  209.   fwToken->arena = arena;
  210.   fwToken->mdToken = mdToken;
  211.   fwToken->fwSlot = fwSlot;
  212.   fwToken->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);
  213.   fwToken->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);
  214.   fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
  215.   fwToken->sessionCount = 0;
  216.   fwToken->rwSessionCount = 0;
  217.   fwToken->mutex = nssCKFWInstance_CreateMutex(fwToken->fwInstance, arena, pError);
  218.   if( (NSSCKFWMutex *)NULL == fwToken->mutex ) {
  219.     if( CKR_OK == *pError ) {
  220.       *pError = CKR_GENERAL_ERROR;
  221.     }
  222.     goto loser;
  223.   }
  224.   fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, arena, pError);
  225.   if( (nssCKFWHash *)NULL == fwToken->sessions ) {
  226.     if( CKR_OK == *pError ) {
  227.       *pError = CKR_GENERAL_ERROR;
  228.     }
  229.     goto loser;
  230.   }
  231.   if( CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects(
  232.                    fwToken->fwInstance) ) {
  233.     fwToken->sessionObjectHash = nssCKFWHash_Create(fwToken->fwInstance, 
  234.                                    arena, pError);
  235.     if( (nssCKFWHash *)NULL == fwToken->sessionObjectHash ) {
  236.       if( CKR_OK == *pError ) {
  237.         *pError = CKR_GENERAL_ERROR;
  238.       }
  239.       goto loser;
  240.     }
  241.   }
  242.   fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance, 
  243.                             arena, pError);
  244.   if( (nssCKFWHash *)NULL == fwToken->mdObjectHash ) {
  245.     if( CKR_OK == *pError ) {
  246.       *pError = CKR_GENERAL_ERROR;
  247.     }
  248.     goto loser;
  249.   }
  250.   fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance, 
  251.                                 arena, pError);
  252.   if( (nssCKFWHash *)NULL == fwToken->mdObjectHash ) {
  253.     if( CKR_OK == *pError ) {
  254.       *pError = CKR_GENERAL_ERROR;
  255.     }
  256.     goto loser;
  257.   }
  258.   /* More here */
  259.   if( (void *)NULL != (void *)mdToken->Setup ) {
  260.     *pError = mdToken->Setup(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
  261.     if( CKR_OK != *pError ) {
  262.       goto loser;
  263.     }
  264.   }
  265.   called_setup = CK_TRUE;
  266. #ifdef DEBUG
  267.   *pError = token_add_pointer(fwToken);
  268.   if( CKR_OK != *pError ) {
  269.     goto loser;
  270.   }
  271. #endif /* DEBUG */
  272.   *pError = CKR_OK;
  273.   return fwToken;
  274.  loser:
  275.   if( CK_TRUE == called_setup ) {
  276.     if( (void *)NULL != (void *)mdToken->Invalidate ) {
  277.       mdToken->Invalidate(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
  278.     }
  279.   }
  280.   if( (NSSArena *)NULL != arena ) {
  281.     (void)NSSArena_Destroy(arena);
  282.   }
  283.   return (NSSCKFWToken *)NULL;
  284. }
  285. /*
  286.  * nssCKFWToken_Destroy
  287.  *
  288.  */
  289. NSS_IMPLEMENT CK_RV
  290. nssCKFWToken_Destroy
  291. (
  292.   NSSCKFWToken *fwToken
  293. )
  294. {
  295.   CK_RV error = CKR_OK;
  296. #ifdef NSSDEBUG
  297.   error = nssCKFWToken_verifyPointer(fwToken);
  298.   if( CKR_OK != error ) {
  299.     return error;
  300.   }
  301. #endif /* NSSDEBUG */
  302.   (void)nssCKFWMutex_Destroy(fwToken->mutex);
  303.   
  304.   if( (void *)NULL != (void *)fwToken->mdToken->Invalidate ) {
  305.     fwToken->mdToken->Invalidate(fwToken->mdToken, fwToken,
  306.       fwToken->mdInstance, fwToken->fwInstance);
  307.   }
  308.   nssCKFWSlot_ClearToken(fwToken->fwSlot);
  309.   
  310. #ifdef DEBUG
  311.   error = token_remove_pointer(fwToken);
  312. #endif /* DEBUG */
  313.   (void)NSSArena_Destroy(fwToken->arena);
  314.   return error;
  315. }
  316. /*
  317.  * nssCKFWToken_GetMDToken
  318.  *
  319.  */
  320. NSS_IMPLEMENT NSSCKMDToken *
  321. nssCKFWToken_GetMDToken
  322. (
  323.   NSSCKFWToken *fwToken
  324. )
  325. {
  326. #ifdef NSSDEBUG
  327.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  328.     return (NSSCKMDToken *)NULL;
  329.   }
  330. #endif /* NSSDEBUG */
  331.   return fwToken->mdToken;
  332. }
  333. /*
  334.  * nssCKFWToken_GetArena
  335.  *
  336.  */
  337. NSS_IMPLEMENT NSSArena *
  338. nssCKFWToken_GetArena
  339. (
  340.   NSSCKFWToken *fwToken,
  341.   CK_RV *pError
  342. )
  343. {
  344. #ifdef NSSDEBUG
  345.   if( (CK_RV *)NULL == pError ) {
  346.     return (NSSArena *)NULL;
  347.   }
  348.   *pError = nssCKFWToken_verifyPointer(fwToken);
  349.   if( CKR_OK != *pError ) {
  350.     return (NSSArena *)NULL;
  351.   }
  352. #endif /* NSSDEBUG */
  353.   return fwToken->arena;
  354. }
  355. /*
  356.  * nssCKFWToken_GetFWSlot
  357.  *
  358.  */
  359. NSS_IMPLEMENT NSSCKFWSlot *
  360. nssCKFWToken_GetFWSlot
  361. (
  362.   NSSCKFWToken *fwToken
  363. )
  364. {
  365. #ifdef NSSDEBUG
  366.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  367.     return (NSSCKFWSlot *)NULL;
  368.   }
  369. #endif /* NSSDEBUG */
  370.   return fwToken->fwSlot;
  371. }
  372. /*
  373.  * nssCKFWToken_GetMDSlot
  374.  *
  375.  */
  376. NSS_IMPLEMENT NSSCKMDSlot *
  377. nssCKFWToken_GetMDSlot
  378. (
  379.   NSSCKFWToken *fwToken
  380. )
  381. {
  382. #ifdef NSSDEBUG
  383.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  384.     return (NSSCKMDSlot *)NULL;
  385.   }
  386. #endif /* NSSDEBUG */
  387.   return fwToken->mdSlot;
  388. }
  389. /*
  390.  * nssCKFWToken_GetSessionState
  391.  *
  392.  */
  393. NSS_IMPLEMENT CK_STATE
  394. nssCKFWToken_GetSessionState
  395. (
  396.   NSSCKFWToken *fwToken
  397. )
  398. {
  399. #ifdef NSSDEBUG
  400.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  401.     return CKS_RO_PUBLIC_SESSION; /* whatever */
  402.   }
  403. #endif /* NSSDEBUG */
  404.   /*
  405.    * BTW, do not lock the token in this method.
  406.    */
  407.   /*
  408.    * Theoretically, there is no state if there aren't any
  409.    * sessions open.  But then we'd need to worry about
  410.    * reporting an error, etc.  What the heck-- let's just
  411.    * revert to CKR_RO_PUBLIC_SESSION as the "default."
  412.    */
  413.   return fwToken->state;
  414. }
  415. /*
  416.  * nssCKFWToken_InitToken
  417.  *
  418.  */
  419. NSS_IMPLEMENT CK_RV
  420. nssCKFWToken_InitToken
  421. (
  422.   NSSCKFWToken *fwToken,
  423.   NSSItem *pin,
  424.   NSSUTF8 *label
  425. )
  426. {
  427.   CK_RV error;
  428. #ifdef NSSDEBUG
  429.   error = nssCKFWToken_verifyPointer(fwToken);
  430.   if( CKR_OK != error ) {
  431.     return CKR_ARGUMENTS_BAD;
  432.   }
  433. #endif /* NSSDEBUG */
  434.   error = nssCKFWMutex_Lock(fwToken->mutex);
  435.   if( CKR_OK != error ) {
  436.     return error;
  437.   }
  438.   if( fwToken->sessionCount > 0 ) {
  439.     error = CKR_SESSION_EXISTS;
  440.     goto done;
  441.   }
  442.   if( (void *)NULL == (void *)fwToken->mdToken->InitToken ) {
  443.     error = CKR_DEVICE_ERROR;
  444.     goto done;
  445.   }
  446.   if( (NSSItem *)NULL == pin ) {
  447.     if( nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken) ) {
  448.       ; /* okay */
  449.     } else {
  450.       error = CKR_PIN_INCORRECT;
  451.       goto done;
  452.     }
  453.   }
  454.   if( (NSSUTF8 *)NULL == label ) {
  455.     label = (NSSUTF8 *) "";
  456.   }
  457.   error = fwToken->mdToken->InitToken(fwToken->mdToken, fwToken,
  458.             fwToken->mdInstance, fwToken->fwInstance, pin, label);
  459.  done:
  460.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  461.   return error;
  462. }
  463. /*
  464.  * nssCKFWToken_GetLabel
  465.  *
  466.  */
  467. NSS_IMPLEMENT CK_RV
  468. nssCKFWToken_GetLabel
  469. (
  470.   NSSCKFWToken *fwToken,
  471.   CK_CHAR label[32]
  472. )
  473. {
  474.   CK_RV error = CKR_OK;
  475. #ifdef NSSDEBUG
  476.   if( (CK_CHAR_PTR)NULL == label ) {
  477.     return CKR_ARGUMENTS_BAD;
  478.   }
  479.   error = nssCKFWToken_verifyPointer(fwToken);
  480.   if( CKR_OK != error ) {
  481.     return error;
  482.   }
  483. #endif /* NSSDEBUG */
  484.   error = nssCKFWMutex_Lock(fwToken->mutex);
  485.   if( CKR_OK != error ) {
  486.     return error;
  487.   }
  488.   if( (NSSUTF8 *)NULL == fwToken->label ) {
  489.     if( (void *)NULL != (void *)fwToken->mdToken->GetLabel ) {
  490.       fwToken->label = fwToken->mdToken->GetLabel(fwToken->mdToken, fwToken,
  491.         fwToken->mdInstance, fwToken->fwInstance, &error);
  492.       if( ((NSSUTF8 *)NULL == fwToken->label) && (CKR_OK != error) ) {
  493.         goto done;
  494.       }
  495.     } else {
  496.       fwToken->label = (NSSUTF8 *) "";
  497.     }
  498.   }
  499.   (void)nssUTF8_CopyIntoFixedBuffer(fwToken->label, (char *)label, 32, ' ');
  500.   error = CKR_OK;
  501.  done:
  502.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  503.   return error;
  504. }
  505. /*
  506.  * nssCKFWToken_GetManufacturerID
  507.  *
  508.  */
  509. NSS_IMPLEMENT CK_RV
  510. nssCKFWToken_GetManufacturerID
  511. (
  512.   NSSCKFWToken *fwToken,
  513.   CK_CHAR manufacturerID[32]
  514. )
  515. {
  516.   CK_RV error = CKR_OK;
  517. #ifdef NSSDEBUG
  518.   if( (CK_CHAR_PTR)NULL == manufacturerID ) {
  519.     return CKR_ARGUMENTS_BAD;
  520.   }
  521.   error = nssCKFWToken_verifyPointer(fwToken);
  522.   if( CKR_OK != error ) {
  523.     return error;
  524.   }
  525. #endif /* NSSDEBUG */
  526.   error = nssCKFWMutex_Lock(fwToken->mutex);
  527.   if( CKR_OK != error ) {
  528.     return error;
  529.   }
  530.   if( (NSSUTF8 *)NULL == fwToken->manufacturerID ) {
  531.     if( (void *)NULL != (void *)fwToken->mdToken->GetManufacturerID ) {
  532.       fwToken->manufacturerID = fwToken->mdToken->GetManufacturerID(fwToken->mdToken,
  533.         fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
  534.       if( ((NSSUTF8 *)NULL == fwToken->manufacturerID) && (CKR_OK != error) ) {
  535.         goto done;
  536.       }
  537.     } else {
  538.       fwToken->manufacturerID = (NSSUTF8 *)"";
  539.     }
  540.   }
  541.   (void)nssUTF8_CopyIntoFixedBuffer(fwToken->manufacturerID, (char *)manufacturerID, 32, ' ');
  542.   error = CKR_OK;
  543.  done:
  544.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  545.   return error;
  546. }
  547. /*
  548.  * nssCKFWToken_GetModel
  549.  *
  550.  */
  551. NSS_IMPLEMENT CK_RV
  552. nssCKFWToken_GetModel
  553. (
  554.   NSSCKFWToken *fwToken,
  555.   CK_CHAR model[16]
  556. )
  557. {
  558.   CK_RV error = CKR_OK;
  559. #ifdef NSSDEBUG
  560.   if( (CK_CHAR_PTR)NULL == model ) {
  561.     return CKR_ARGUMENTS_BAD;
  562.   }
  563.   error = nssCKFWToken_verifyPointer(fwToken);
  564.   if( CKR_OK != error ) {
  565.     return error;
  566.   }
  567. #endif /* NSSDEBUG */
  568.   error = nssCKFWMutex_Lock(fwToken->mutex);
  569.   if( CKR_OK != error ) {
  570.     return error;
  571.   }
  572.   if( (NSSUTF8 *)NULL == fwToken->model ) {
  573.     if( (void *)NULL != (void *)fwToken->mdToken->GetModel ) {
  574.       fwToken->model = fwToken->mdToken->GetModel(fwToken->mdToken, fwToken,
  575.         fwToken->mdInstance, fwToken->fwInstance, &error);
  576.       if( ((NSSUTF8 *)NULL == fwToken->model) && (CKR_OK != error) ) {
  577.         goto done;
  578.       }
  579.     } else {
  580.       fwToken->model = (NSSUTF8 *)"";
  581.     }
  582.   }
  583.   (void)nssUTF8_CopyIntoFixedBuffer(fwToken->model, (char *)model, 16, ' ');
  584.   error = CKR_OK;
  585.  done:
  586.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  587.   return error;
  588. }
  589. /*
  590.  * nssCKFWToken_GetSerialNumber
  591.  *
  592.  */
  593. NSS_IMPLEMENT CK_RV
  594. nssCKFWToken_GetSerialNumber
  595. (
  596.   NSSCKFWToken *fwToken,
  597.   CK_CHAR serialNumber[16]
  598. )
  599. {
  600.   CK_RV error = CKR_OK;
  601. #ifdef NSSDEBUG
  602.   if( (CK_CHAR_PTR)NULL == serialNumber ) {
  603.     return CKR_ARGUMENTS_BAD;
  604.   }
  605.   error = nssCKFWToken_verifyPointer(fwToken);
  606.   if( CKR_OK != error ) {
  607.     return error;
  608.   }
  609. #endif /* NSSDEBUG */
  610.   error = nssCKFWMutex_Lock(fwToken->mutex);
  611.   if( CKR_OK != error ) {
  612.     return error;
  613.   }
  614.   if( (NSSUTF8 *)NULL == fwToken->serialNumber ) {
  615.     if( (void *)NULL != (void *)fwToken->mdToken->GetSerialNumber ) {
  616.       fwToken->serialNumber = fwToken->mdToken->GetSerialNumber(fwToken->mdToken, 
  617.         fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
  618.       if( ((NSSUTF8 *)NULL == fwToken->serialNumber) && (CKR_OK != error) ) {
  619.         goto done;
  620.       }
  621.     } else {
  622.       fwToken->serialNumber = (NSSUTF8 *)"";
  623.     }
  624.   }
  625.   (void)nssUTF8_CopyIntoFixedBuffer(fwToken->serialNumber, (char *)serialNumber, 16, ' ');
  626.   error = CKR_OK;
  627.  done:
  628.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  629.   return error;
  630. }
  631. /*
  632.  * nssCKFWToken_GetHasRNG
  633.  *
  634.  */
  635. NSS_IMPLEMENT CK_BBOOL
  636. nssCKFWToken_GetHasRNG
  637. (
  638.   NSSCKFWToken *fwToken
  639. )
  640. {
  641. #ifdef NSSDEBUG
  642.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  643.     return CK_FALSE;
  644.   }
  645. #endif /* NSSDEBUG */
  646.   if( (void *)NULL == (void *)fwToken->mdToken->GetHasRNG ) {
  647.     return CK_FALSE;
  648.   }
  649.   return fwToken->mdToken->GetHasRNG(fwToken->mdToken, fwToken, 
  650.     fwToken->mdInstance, fwToken->fwInstance);
  651. }
  652. /*
  653.  * nssCKFWToken_GetIsWriteProtected
  654.  *
  655.  */
  656. NSS_IMPLEMENT CK_BBOOL
  657. nssCKFWToken_GetIsWriteProtected
  658. (
  659.   NSSCKFWToken *fwToken
  660. )
  661. {
  662. #ifdef NSSDEBUG
  663.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  664.     return CK_FALSE;
  665.   }
  666. #endif /* NSSDEBUG */
  667.   if( (void *)NULL == (void *)fwToken->mdToken->GetIsWriteProtected ) {
  668.     return CK_FALSE;
  669.   }
  670.   return fwToken->mdToken->GetIsWriteProtected(fwToken->mdToken, fwToken, 
  671.     fwToken->mdInstance, fwToken->fwInstance);
  672. }
  673. /*
  674.  * nssCKFWToken_GetLoginRequired
  675.  *
  676.  */
  677. NSS_IMPLEMENT CK_BBOOL
  678. nssCKFWToken_GetLoginRequired
  679. (
  680.   NSSCKFWToken *fwToken
  681. )
  682. {
  683. #ifdef NSSDEBUG
  684.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  685.     return CK_FALSE;
  686.   }
  687. #endif /* NSSDEBUG */
  688.   if( (void *)NULL == (void *)fwToken->mdToken->GetLoginRequired ) {
  689.     return CK_FALSE;
  690.   }
  691.   return fwToken->mdToken->GetLoginRequired(fwToken->mdToken, fwToken, 
  692.     fwToken->mdInstance, fwToken->fwInstance);
  693. }
  694. /*
  695.  * nssCKFWToken_GetUserPinInitialized
  696.  *
  697.  */
  698. NSS_IMPLEMENT CK_BBOOL
  699. nssCKFWToken_GetUserPinInitialized
  700. (
  701.   NSSCKFWToken *fwToken
  702. )
  703. {
  704. #ifdef NSSDEBUG
  705.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  706.     return CK_FALSE;
  707.   }
  708. #endif /* NSSDEBUG */
  709.   if( (void *)NULL == (void *)fwToken->mdToken->GetUserPinInitialized ) {
  710.     return CK_FALSE;
  711.   }
  712.   return fwToken->mdToken->GetUserPinInitialized(fwToken->mdToken, fwToken, 
  713.     fwToken->mdInstance, fwToken->fwInstance);
  714. }
  715. /*
  716.  * nssCKFWToken_GetRestoreKeyNotNeeded
  717.  *
  718.  */
  719. NSS_IMPLEMENT CK_BBOOL
  720. nssCKFWToken_GetRestoreKeyNotNeeded
  721. (
  722.   NSSCKFWToken *fwToken
  723. )
  724. {
  725. #ifdef NSSDEBUG
  726.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  727.     return CK_FALSE;
  728.   }
  729. #endif /* NSSDEBUG */
  730.   if( (void *)NULL == (void *)fwToken->mdToken->GetRestoreKeyNotNeeded ) {
  731.     return CK_FALSE;
  732.   }
  733.   return fwToken->mdToken->GetRestoreKeyNotNeeded(fwToken->mdToken, fwToken, 
  734.     fwToken->mdInstance, fwToken->fwInstance);
  735. }
  736. /*
  737.  * nssCKFWToken_GetHasClockOnToken
  738.  *
  739.  */
  740. NSS_IMPLEMENT CK_BBOOL
  741. nssCKFWToken_GetHasClockOnToken
  742. (
  743.   NSSCKFWToken *fwToken
  744. )
  745. {
  746. #ifdef NSSDEBUG
  747.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  748.     return CK_FALSE;
  749.   }
  750. #endif /* NSSDEBUG */
  751.   if( (void *)NULL == (void *)fwToken->mdToken->GetHasClockOnToken ) {
  752.     return CK_FALSE;
  753.   }
  754.   return fwToken->mdToken->GetHasClockOnToken(fwToken->mdToken, fwToken, 
  755.     fwToken->mdInstance, fwToken->fwInstance);
  756. }
  757. /*
  758.  * nssCKFWToken_GetHasProtectedAuthenticationPath
  759.  *
  760.  */
  761. NSS_IMPLEMENT CK_BBOOL
  762. nssCKFWToken_GetHasProtectedAuthenticationPath
  763. (
  764.   NSSCKFWToken *fwToken
  765. )
  766. {
  767. #ifdef NSSDEBUG
  768.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  769.     return CK_FALSE;
  770.   }
  771. #endif /* NSSDEBUG */
  772.   if( (void *)NULL == (void *)fwToken->mdToken->GetHasProtectedAuthenticationPath ) {
  773.     return CK_FALSE;
  774.   }
  775.   return fwToken->mdToken->GetHasProtectedAuthenticationPath(fwToken->mdToken, 
  776.     fwToken, fwToken->mdInstance, fwToken->fwInstance);
  777. }
  778. /*
  779.  * nssCKFWToken_GetSupportsDualCryptoOperations
  780.  *
  781.  */
  782. NSS_IMPLEMENT CK_BBOOL
  783. nssCKFWToken_GetSupportsDualCryptoOperations
  784. (
  785.   NSSCKFWToken *fwToken
  786. )
  787. {
  788. #ifdef NSSDEBUG
  789.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  790.     return CK_FALSE;
  791.   }
  792. #endif /* NSSDEBUG */
  793.   if( (void *)NULL == (void *)fwToken->mdToken->GetSupportsDualCryptoOperations ) {
  794.     return CK_FALSE;
  795.   }
  796.   return fwToken->mdToken->GetSupportsDualCryptoOperations(fwToken->mdToken, 
  797.     fwToken, fwToken->mdInstance, fwToken->fwInstance);
  798. }
  799. /*
  800.  * nssCKFWToken_GetMaxSessionCount
  801.  *
  802.  */
  803. NSS_IMPLEMENT CK_ULONG
  804. nssCKFWToken_GetMaxSessionCount
  805. (
  806.   NSSCKFWToken *fwToken
  807. )
  808. {
  809. #ifdef NSSDEBUG
  810.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  811.     return CK_UNAVAILABLE_INFORMATION;
  812.   }
  813. #endif /* NSSDEBUG */
  814.   if( (void *)NULL == (void *)fwToken->mdToken->GetMaxSessionCount ) {
  815.     return CK_UNAVAILABLE_INFORMATION;
  816.   }
  817.   return fwToken->mdToken->GetMaxSessionCount(fwToken->mdToken, fwToken, 
  818.     fwToken->mdInstance, fwToken->fwInstance);
  819. }
  820. /*
  821.  * nssCKFWToken_GetMaxRwSessionCount
  822.  *
  823.  */
  824. NSS_IMPLEMENT CK_ULONG
  825. nssCKFWToken_GetMaxRwSessionCount
  826. (
  827.   NSSCKFWToken *fwToken
  828. )
  829. {
  830. #ifdef NSSDEBUG
  831.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  832.     return CK_UNAVAILABLE_INFORMATION;
  833.   }
  834. #endif /* NSSDEBUG */
  835.   if( (void *)NULL == (void *)fwToken->mdToken->GetMaxRwSessionCount ) {
  836.     return CK_UNAVAILABLE_INFORMATION;
  837.   }
  838.   return fwToken->mdToken->GetMaxRwSessionCount(fwToken->mdToken, fwToken, 
  839.     fwToken->mdInstance, fwToken->fwInstance);
  840. }
  841. /*
  842.  * nssCKFWToken_GetMaxPinLen
  843.  *
  844.  */
  845. NSS_IMPLEMENT CK_ULONG
  846. nssCKFWToken_GetMaxPinLen
  847. (
  848.   NSSCKFWToken *fwToken
  849. )
  850. {
  851. #ifdef NSSDEBUG
  852.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  853.     return CK_UNAVAILABLE_INFORMATION;
  854.   }
  855. #endif /* NSSDEBUG */
  856.   if( (void *)NULL == (void *)fwToken->mdToken->GetMaxPinLen ) {
  857.     return CK_UNAVAILABLE_INFORMATION;
  858.   }
  859.   return fwToken->mdToken->GetMaxPinLen(fwToken->mdToken, fwToken, 
  860.     fwToken->mdInstance, fwToken->fwInstance);
  861. }
  862. /*
  863.  * nssCKFWToken_GetMinPinLen
  864.  *
  865.  */
  866. NSS_IMPLEMENT CK_ULONG
  867. nssCKFWToken_GetMinPinLen
  868. (
  869.   NSSCKFWToken *fwToken
  870. )
  871. {
  872. #ifdef NSSDEBUG
  873.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  874.     return CK_UNAVAILABLE_INFORMATION;
  875.   }
  876. #endif /* NSSDEBUG */
  877.   if( (void *)NULL == (void *)fwToken->mdToken->GetMinPinLen ) {
  878.     return CK_UNAVAILABLE_INFORMATION;
  879.   }
  880.   return fwToken->mdToken->GetMinPinLen(fwToken->mdToken, fwToken, 
  881.     fwToken->mdInstance, fwToken->fwInstance);
  882. }
  883. /*
  884.  * nssCKFWToken_GetTotalPublicMemory
  885.  *
  886.  */
  887. NSS_IMPLEMENT CK_ULONG
  888. nssCKFWToken_GetTotalPublicMemory
  889. (
  890.   NSSCKFWToken *fwToken
  891. )
  892. {
  893. #ifdef NSSDEBUG
  894.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  895.     return CK_UNAVAILABLE_INFORMATION;
  896.   }
  897. #endif /* NSSDEBUG */
  898.   if( (void *)NULL == (void *)fwToken->mdToken->GetTotalPublicMemory ) {
  899.     return CK_UNAVAILABLE_INFORMATION;
  900.   }
  901.   return fwToken->mdToken->GetTotalPublicMemory(fwToken->mdToken, fwToken, 
  902.     fwToken->mdInstance, fwToken->fwInstance);
  903. }
  904. /*
  905.  * nssCKFWToken_GetFreePublicMemory
  906.  *
  907.  */
  908. NSS_IMPLEMENT CK_ULONG
  909. nssCKFWToken_GetFreePublicMemory
  910. (
  911.   NSSCKFWToken *fwToken
  912. )
  913. {
  914. #ifdef NSSDEBUG
  915.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  916.     return CK_UNAVAILABLE_INFORMATION;
  917.   }
  918. #endif /* NSSDEBUG */
  919.   if( (void *)NULL == (void *)fwToken->mdToken->GetFreePublicMemory ) {
  920.     return CK_UNAVAILABLE_INFORMATION;
  921.   }
  922.   return fwToken->mdToken->GetFreePublicMemory(fwToken->mdToken, fwToken, 
  923.     fwToken->mdInstance, fwToken->fwInstance);
  924. }
  925. /*
  926.  * nssCKFWToken_GetTotalPrivateMemory
  927.  *
  928.  */
  929. NSS_IMPLEMENT CK_ULONG
  930. nssCKFWToken_GetTotalPrivateMemory
  931. (
  932.   NSSCKFWToken *fwToken
  933. )
  934. {
  935. #ifdef NSSDEBUG
  936.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  937.     return CK_UNAVAILABLE_INFORMATION;
  938.   }
  939. #endif /* NSSDEBUG */
  940.   if( (void *)NULL == (void *)fwToken->mdToken->GetTotalPrivateMemory ) {
  941.     return CK_UNAVAILABLE_INFORMATION;
  942.   }
  943.   return fwToken->mdToken->GetTotalPrivateMemory(fwToken->mdToken, fwToken, 
  944.     fwToken->mdInstance, fwToken->fwInstance);
  945. }
  946. /*
  947.  * nssCKFWToken_GetFreePrivateMemory
  948.  *
  949.  */
  950. NSS_IMPLEMENT CK_ULONG
  951. nssCKFWToken_GetFreePrivateMemory
  952. (
  953.   NSSCKFWToken *fwToken
  954. )
  955. {
  956. #ifdef NSSDEBUG
  957.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  958.     return CK_UNAVAILABLE_INFORMATION;
  959.   }
  960. #endif /* NSSDEBUG */
  961.   if( (void *)NULL == (void *)fwToken->mdToken->GetFreePrivateMemory ) {
  962.     return CK_UNAVAILABLE_INFORMATION;
  963.   }
  964.   return fwToken->mdToken->GetFreePrivateMemory(fwToken->mdToken, fwToken, 
  965.     fwToken->mdInstance, fwToken->fwInstance);
  966. }
  967. /*
  968.  * nssCKFWToken_GetHardwareVersion
  969.  *
  970.  */
  971. NSS_IMPLEMENT CK_VERSION
  972. nssCKFWToken_GetHardwareVersion
  973. (
  974.   NSSCKFWToken *fwToken
  975. )
  976. {
  977.   CK_VERSION rv;
  978. #ifdef NSSDEBUG
  979.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  980.     rv.major = rv.minor = 0;
  981.     return rv;
  982.   }
  983. #endif /* NSSDEBUG */
  984.   if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  985.     rv.major = rv.minor = 0;
  986.     return rv;
  987.   }
  988.   if( (0 != fwToken->hardwareVersion.major) ||
  989.       (0 != fwToken->hardwareVersion.minor) ) {
  990.     rv = fwToken->hardwareVersion;
  991.     goto done;
  992.   }
  993.   if( (void *)NULL != (void *)fwToken->mdToken->GetHardwareVersion ) {
  994.     fwToken->hardwareVersion = fwToken->mdToken->GetHardwareVersion(
  995.       fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
  996.   } else {
  997.     fwToken->hardwareVersion.major = 0;
  998.     fwToken->hardwareVersion.minor = 1;
  999.   }
  1000.   rv = fwToken->hardwareVersion;
  1001.  done:
  1002.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1003.   return rv;
  1004. }
  1005. /*
  1006.  * nssCKFWToken_GetFirmwareVersion
  1007.  *
  1008.  */
  1009. NSS_IMPLEMENT CK_VERSION
  1010. nssCKFWToken_GetFirmwareVersion
  1011. (
  1012.   NSSCKFWToken *fwToken
  1013. )
  1014. {
  1015.   CK_VERSION rv;
  1016. #ifdef NSSDEBUG
  1017.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1018.     rv.major = rv.minor = 0;
  1019.     return rv;
  1020.   }
  1021. #endif /* NSSDEBUG */
  1022.   if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1023.     rv.major = rv.minor = 0;
  1024.     return rv;
  1025.   }
  1026.   if( (0 != fwToken->firmwareVersion.major) ||
  1027.       (0 != fwToken->firmwareVersion.minor) ) {
  1028.     rv = fwToken->firmwareVersion;
  1029.     goto done;
  1030.   }
  1031.   if( (void *)NULL != (void *)fwToken->mdToken->GetFirmwareVersion ) {
  1032.     fwToken->firmwareVersion = fwToken->mdToken->GetFirmwareVersion(
  1033.       fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
  1034.   } else {
  1035.     fwToken->firmwareVersion.major = 0;
  1036.     fwToken->firmwareVersion.minor = 1;
  1037.   }
  1038.   rv = fwToken->firmwareVersion;
  1039.  done:
  1040.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1041.   return rv;
  1042. }
  1043. /*
  1044.  * nssCKFWToken_GetUTCTime
  1045.  *
  1046.  */
  1047. NSS_IMPLEMENT CK_RV
  1048. nssCKFWToken_GetUTCTime
  1049. (
  1050.   NSSCKFWToken *fwToken,
  1051.   CK_CHAR utcTime[16]
  1052. )
  1053. {
  1054.   CK_RV error = CKR_OK;
  1055. #ifdef NSSDEBUG
  1056.   error = nssCKFWToken_verifyPointer(fwToken);
  1057.   if( CKR_OK != error ) {
  1058.     return error;
  1059.   }
  1060.   if( (CK_CHAR_PTR)NULL == utcTime ) {
  1061.     return CKR_ARGUMENTS_BAD;
  1062.   }
  1063. #endif /* DEBUG */
  1064.   if( CK_TRUE != nssCKFWToken_GetHasClockOnToken(fwToken) ) {
  1065.     /* return CKR_DEVICE_ERROR; */
  1066.     (void)nssUTF8_CopyIntoFixedBuffer((NSSUTF8 *)NULL, (char *)utcTime, 16, ' ');
  1067.     return CKR_OK;
  1068.   }
  1069.   if( (void *)NULL == (void *)fwToken->mdToken->GetUTCTime ) {
  1070.     /* It said it had one! */
  1071.     return CKR_GENERAL_ERROR;
  1072.   }
  1073.   error = fwToken->mdToken->GetUTCTime(fwToken->mdToken, fwToken, 
  1074.             fwToken->mdInstance, fwToken->fwInstance, utcTime);
  1075.   if( CKR_OK != error ) {
  1076.     return error;
  1077.   }
  1078.   /* Sanity-check the data */
  1079.   {
  1080.     /* Format is YYYYMMDDhhmmss00 */
  1081.     int i;
  1082.     int Y, M, D, h, m, s, z;
  1083.     static int dims[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  1084.     for( i = 0; i < 16; i++ ) {
  1085.       if( (utcTime[i] < '0') || (utcTime[i] > '9') ) {
  1086.         goto badtime;
  1087.       }
  1088.     }
  1089.     Y = ((utcTime[ 0] - '0') * 1000) + ((utcTime[1] - '0') * 100) +
  1090.         ((utcTime[ 2] - '0') * 10) + (utcTime[ 3] - '0');
  1091.     M = ((utcTime[ 4] - '0') * 10) + (utcTime[ 5] - '0');
  1092.     D = ((utcTime[ 6] - '0') * 10) + (utcTime[ 7] - '0');
  1093.     h = ((utcTime[ 8] - '0') * 10) + (utcTime[ 9] - '0');
  1094.     m = ((utcTime[10] - '0') * 10) + (utcTime[11] - '0');
  1095.     s = ((utcTime[12] - '0') * 10) + (utcTime[13] - '0');
  1096.     z = ((utcTime[14] - '0') * 10) + (utcTime[15] - '0');
  1097.     if( (Y < 1990) || (Y > 3000) ) goto badtime; /* Y3K problem.  heh heh heh */
  1098.     if( (M < 1) || (M > 12) ) goto badtime;
  1099.     if( (D < 1) || (D > 31) ) goto badtime;
  1100.     if( D > dims[M-1] ) goto badtime; /* per-month check */
  1101.     if( (2 == M) && (((Y%4)||!(Y%100))&&(Y%400)) && (D > 28) ) goto badtime; /* leap years */
  1102.     if( (h < 0) || (h > 23) ) goto badtime;
  1103.     if( (m < 0) || (m > 60) ) goto badtime;
  1104.     if( (s < 0) || (s > 61) ) goto badtime;
  1105.     /* 60m and 60 or 61s is only allowed for leap seconds. */
  1106.     if( (60 == m) || (s >= 60) ) {
  1107.       if( (23 != h) || (60 != m) || (s < 60) ) goto badtime;
  1108.       /* leap seconds can only happen on June 30 or Dec 31.. I think */
  1109.       /* if( ((6 != M) || (30 != D)) && ((12 != M) || (31 != D)) ) goto badtime; */
  1110.     }
  1111.   }
  1112.   return CKR_OK;
  1113.  badtime:
  1114.   return CKR_GENERAL_ERROR;
  1115. }
  1116. /*
  1117.  * nssCKFWToken_OpenSession
  1118.  *
  1119.  */
  1120. NSS_IMPLEMENT NSSCKFWSession *
  1121. nssCKFWToken_OpenSession
  1122. (
  1123.   NSSCKFWToken *fwToken,
  1124.   CK_BBOOL rw,
  1125.   CK_VOID_PTR pApplication,
  1126.   CK_NOTIFY Notify,
  1127.   CK_RV *pError
  1128. )
  1129. {
  1130.   NSSCKFWSession *fwSession = (NSSCKFWSession *)NULL;
  1131.   NSSCKMDSession *mdSession;
  1132. #ifdef NSSDEBUG
  1133.   if( (CK_RV *)NULL == pError ) {
  1134.     return (NSSCKFWSession *)NULL;
  1135.   }
  1136.   *pError = nssCKFWToken_verifyPointer(fwToken);
  1137.   if( CKR_OK != *pError ) {
  1138.     return (NSSCKFWSession *)NULL;
  1139.   }
  1140.   switch( rw ) {
  1141.   case CK_TRUE:
  1142.   case CK_FALSE:
  1143.     break;
  1144.   default:
  1145.     *pError = CKR_ARGUMENTS_BAD;
  1146.     return (NSSCKFWSession *)NULL;
  1147.   }
  1148. #endif /* NSSDEBUG */
  1149.   *pError = nssCKFWMutex_Lock(fwToken->mutex);
  1150.   if( CKR_OK != *pError ) {
  1151.     return (NSSCKFWSession *)NULL;
  1152.   }
  1153.   if( CK_TRUE == rw ) {
  1154.     /* Read-write session desired */
  1155.     if( CK_TRUE != nssCKFWToken_GetIsWriteProtected(fwToken) ) {
  1156.       *pError = CKR_TOKEN_WRITE_PROTECTED;
  1157.       goto done;
  1158.     }
  1159.   } else {
  1160.     /* Read-only session desired */
  1161.     if( CKS_RW_SO_FUNCTIONS == nssCKFWToken_GetSessionState(fwToken) ) {
  1162.       *pError = CKR_SESSION_READ_WRITE_SO_EXISTS;
  1163.       goto done;
  1164.     }
  1165.   }
  1166.   /* We could compare sesion counts to any limits we know of, I guess.. */
  1167.   if( (void *)NULL == (void *)fwToken->mdToken->OpenSession ) {
  1168.     /*
  1169.      * I'm not sure that the Module actually needs to implement
  1170.      * mdSessions -- the Framework can keep track of everything 
  1171.      * needed, really.  But I'll sort out that detail later..
  1172.      */
  1173.     *pError = CKR_GENERAL_ERROR;
  1174.     goto done;
  1175.   }
  1176.   fwSession = nssCKFWSession_Create(fwToken, rw, pApplication, Notify, pError);
  1177.   if( (NSSCKFWSession *)NULL == fwSession ) {
  1178.     if( CKR_OK == *pError ) {
  1179.       *pError = CKR_GENERAL_ERROR;
  1180.     }
  1181.     goto done;
  1182.   }
  1183.   mdSession = fwToken->mdToken->OpenSession(fwToken->mdToken, fwToken,
  1184.                 fwToken->mdInstance, fwToken->fwInstance, fwSession,
  1185.                 rw, pError);
  1186.   if( (NSSCKMDSession *)NULL == mdSession ) {
  1187.     (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  1188.     if( CKR_OK == *pError ) {
  1189.       *pError = CKR_GENERAL_ERROR;
  1190.     }
  1191.     goto done;
  1192.   }
  1193.   *pError = nssCKFWSession_SetMDSession(fwSession, mdSession);
  1194.   if( CKR_OK != *pError ) {
  1195.     if( (void *)NULL != (void *)mdSession->Close ) {
  1196.       mdSession->Close(mdSession, fwSession, fwToken->mdToken, fwToken,
  1197.       fwToken->mdInstance, fwToken->fwInstance);
  1198.     }
  1199.     (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  1200.     goto done;
  1201.   }
  1202.   *pError = nssCKFWHash_Add(fwToken->sessions, fwSession, fwSession);
  1203.   if( CKR_OK != *pError ) {
  1204.     (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  1205.     fwSession = (NSSCKFWSession *)NULL;
  1206.     goto done;
  1207.   }
  1208.  done:
  1209.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1210.   return fwSession;
  1211. }
  1212. /*
  1213.  * nssCKFWToken_GetMechanismCount
  1214.  *
  1215.  */
  1216. NSS_IMPLEMENT CK_ULONG
  1217. nssCKFWToken_GetMechanismCount
  1218. (
  1219.   NSSCKFWToken *fwToken
  1220. )
  1221. {
  1222. #ifdef NSSDEBUG
  1223.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1224.     return 0;
  1225.   }
  1226. #endif /* NSSDEBUG */
  1227.   if( (void *)NULL == fwToken->mdToken->GetMechanismCount ) {
  1228.     return 0;
  1229.   }
  1230.   return fwToken->mdToken->GetMechanismCount(fwToken->mdToken, fwToken,
  1231.     fwToken->mdInstance, fwToken->fwInstance);
  1232. }
  1233. /*
  1234.  * nssCKFWToken_GetMechanismTypes
  1235.  *
  1236.  */
  1237. NSS_IMPLEMENT CK_RV
  1238. nssCKFWToken_GetMechanismTypes
  1239. (
  1240.   NSSCKFWToken *fwToken,
  1241.   CK_MECHANISM_TYPE types[]
  1242. )
  1243. {
  1244. #ifdef NSSDEBUG
  1245.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1246.     return CKR_ARGUMENTS_BAD;
  1247.   }
  1248.   if( (CK_MECHANISM_TYPE *)NULL == types ) {
  1249.     return CKR_ARGUMENTS_BAD;
  1250.   }
  1251. #endif /* NSSDEBUG */
  1252.   if( (void *)NULL == fwToken->mdToken->GetMechanismTypes ) {
  1253.     /*
  1254.      * This should only be called with a sufficiently-large
  1255.      * "types" array, which can only be done if GetMechanismCount
  1256.      * is implemented.  If that's implemented (and returns nonzero),
  1257.      * then this should be too.  So return an error.
  1258.      */
  1259.     return CKR_GENERAL_ERROR;
  1260.   }
  1261.   return fwToken->mdToken->GetMechanismTypes(fwToken->mdToken, fwToken,
  1262.     fwToken->mdInstance, fwToken->fwInstance, types);
  1263. }
  1264. /*
  1265.  * nssCKFWToken_GetMechanism
  1266.  *
  1267.  */
  1268. NSS_IMPLEMENT NSSCKFWMechanism *
  1269. nssCKFWToken_GetMechanism
  1270. (
  1271.   NSSCKFWToken *fwToken,
  1272.   CK_MECHANISM_TYPE which,
  1273.   CK_RV *pError
  1274. )
  1275. {
  1276.   /* XXX fgmr */
  1277.   return (NSSCKFWMechanism *)NULL;
  1278. }
  1279. NSS_IMPLEMENT CK_RV
  1280. nssCKFWToken_SetSessionState
  1281. (
  1282.   NSSCKFWToken *fwToken,
  1283.   CK_STATE newState
  1284. )
  1285. {
  1286.   CK_RV error = CKR_OK;
  1287. #ifdef NSSDEBUG
  1288.   error = nssCKFWToken_verifyPointer(fwToken);
  1289.   if( CKR_OK != error ) {
  1290.     return error;
  1291.   }
  1292.   switch( newState ) {
  1293.   case CKS_RO_PUBLIC_SESSION:
  1294.   case CKS_RO_USER_FUNCTIONS:
  1295.   case CKS_RW_PUBLIC_SESSION:
  1296.   case CKS_RW_USER_FUNCTIONS:
  1297.   case CKS_RW_SO_FUNCTIONS:
  1298.     break;
  1299.   default:
  1300.     return CKR_ARGUMENTS_BAD;
  1301.   }
  1302. #endif /* NSSDEBUG */
  1303.   error = nssCKFWMutex_Lock(fwToken->mutex);
  1304.   if( CKR_OK != error ) {
  1305.     return error;
  1306.   }
  1307.   fwToken->state = newState;
  1308.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1309.   return CKR_OK;
  1310. }
  1311. /*
  1312.  * nssCKFWToken_RemoveSession
  1313.  *
  1314.  */
  1315. NSS_IMPLEMENT CK_RV
  1316. nssCKFWToken_RemoveSession
  1317. (
  1318.   NSSCKFWToken *fwToken,
  1319.   NSSCKFWSession *fwSession
  1320. )
  1321. {
  1322.   CK_RV error = CKR_OK;
  1323. #ifdef NSSDEBUG
  1324.   error = nssCKFWToken_verifyPointer(fwToken);
  1325.   if( CKR_OK != error ) {
  1326.     return error;
  1327.   }
  1328.   error = nssCKFWSession_verifyPointer(fwSession);
  1329.   if( CKR_OK != error ) {
  1330.     return error;
  1331.   }
  1332. #endif /* NSSDEBUG */
  1333.   error = nssCKFWMutex_Lock(fwToken->mutex);
  1334.   if( CKR_OK != error ) {
  1335.     return error;
  1336.   }
  1337.   if( CK_TRUE != nssCKFWHash_Exists(fwToken->sessions, fwSession) ) {
  1338.     error = CKR_SESSION_HANDLE_INVALID;
  1339.     goto done;
  1340.   }
  1341.   nssCKFWHash_Remove(fwToken->sessions, fwSession);
  1342.   fwToken->sessionCount--;
  1343.   if( nssCKFWSession_IsRWSession(fwSession) ) {
  1344.     fwToken->rwSessionCount--;
  1345.   }
  1346.   if( 0 == fwToken->sessionCount ) {
  1347.     fwToken->rwSessionCount = 0; /* sanity */
  1348.     fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
  1349.   }
  1350.   error = CKR_OK;
  1351.  done:
  1352.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1353.   return error;
  1354. }
  1355. static void
  1356. nss_ckfwtoken_session_iterator
  1357. (
  1358.   const void *key,
  1359.   void *value,
  1360.   void *closure
  1361. )
  1362. {
  1363.   /*
  1364.    * Remember that the fwToken->mutex is locked
  1365.    */
  1366.   NSSCKFWSession *fwSession = (NSSCKFWSession *)value;
  1367.   (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
  1368.   return;
  1369. }
  1370. /*
  1371.  * nssCKFWToken_CloseAllSessions
  1372.  *
  1373.  */
  1374. NSS_IMPLEMENT CK_RV
  1375. nssCKFWToken_CloseAllSessions
  1376. (
  1377.   NSSCKFWToken *fwToken
  1378. )
  1379. {
  1380.   CK_RV error = CKR_OK;
  1381. #ifdef NSSDEBUG
  1382.   error = nssCKFWToken_verifyPointer(fwToken);
  1383.   if( CKR_OK != error ) {
  1384.     return error;
  1385.   }
  1386. #endif /* NSSDEBUG */
  1387.   error = nssCKFWMutex_Lock(fwToken->mutex);
  1388.   if( CKR_OK != error ) {
  1389.     return error;
  1390.   }
  1391.   nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, (void *)NULL);
  1392.   nssCKFWHash_Destroy(fwToken->sessions);
  1393.   fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, fwToken->arena, &error);
  1394.   if( (nssCKFWHash *)NULL == fwToken->sessions ) {
  1395.     if( CKR_OK == error ) {
  1396.       error = CKR_GENERAL_ERROR;
  1397.     }
  1398.     goto done;
  1399.   }
  1400.   fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
  1401.   fwToken->sessionCount = 0;
  1402.   fwToken->rwSessionCount = 0;
  1403.   error = CKR_OK;
  1404.  done:
  1405.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1406.   return error;
  1407. }
  1408. /*
  1409.  * nssCKFWToken_GetSessionCount
  1410.  *
  1411.  */
  1412. NSS_IMPLEMENT CK_ULONG
  1413. nssCKFWToken_GetSessionCount
  1414. (
  1415.   NSSCKFWToken *fwToken
  1416. )
  1417. {
  1418.   CK_ULONG rv;
  1419. #ifdef NSSDEBUG
  1420.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1421.     return (CK_ULONG)0;
  1422.   }
  1423. #endif /* NSSDEBUG */
  1424.   if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1425.     return (CK_ULONG)0;
  1426.   }
  1427.   rv = fwToken->sessionCount;
  1428.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1429.   return rv;
  1430. }
  1431. /*
  1432.  * nssCKFWToken_GetRwSessionCount
  1433.  *
  1434.  */
  1435. NSS_IMPLEMENT CK_ULONG
  1436. nssCKFWToken_GetRwSessionCount
  1437. (
  1438.   NSSCKFWToken *fwToken
  1439. )
  1440. {
  1441.   CK_ULONG rv;
  1442. #ifdef NSSDEBUG
  1443.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1444.     return (CK_ULONG)0;
  1445.   }
  1446. #endif /* NSSDEBUG */
  1447.   if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1448.     return (CK_ULONG)0;
  1449.   }
  1450.   rv = fwToken->rwSessionCount;
  1451.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1452.   return rv;
  1453. }
  1454. /*
  1455.  * nssCKFWToken_GetRoSessionCount
  1456.  *
  1457.  */
  1458. NSS_IMPLEMENT CK_ULONG
  1459. nssCKFWToken_GetRoSessionCount
  1460. (
  1461.   NSSCKFWToken *fwToken
  1462. )
  1463. {
  1464.   CK_ULONG rv;
  1465. #ifdef NSSDEBUG
  1466.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1467.     return (CK_ULONG)0;
  1468.   }
  1469. #endif /* NSSDEBUG */
  1470.   if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
  1471.     return (CK_ULONG)0;
  1472.   }
  1473.   rv = fwToken->sessionCount - fwToken->rwSessionCount;
  1474.   (void)nssCKFWMutex_Unlock(fwToken->mutex);
  1475.   return rv;
  1476. }
  1477. /*
  1478.  * nssCKFWToken_GetSessionObjectHash
  1479.  *
  1480.  */
  1481. NSS_IMPLEMENT nssCKFWHash *
  1482. nssCKFWToken_GetSessionObjectHash
  1483. (
  1484.   NSSCKFWToken *fwToken
  1485. )
  1486. {
  1487. #ifdef NSSDEBUG
  1488.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1489.     return (nssCKFWHash *)NULL;
  1490.   }
  1491. #endif /* NSSDEBUG */
  1492.   return fwToken->sessionObjectHash;
  1493. }
  1494. /*
  1495.  * nssCKFWToken_GetMDObjectHash
  1496.  *
  1497.  */
  1498. NSS_IMPLEMENT nssCKFWHash *
  1499. nssCKFWToken_GetMDObjectHash
  1500. (
  1501.   NSSCKFWToken *fwToken
  1502. )
  1503. {
  1504. #ifdef NSSDEBUG
  1505.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1506.     return (nssCKFWHash *)NULL;
  1507.   }
  1508. #endif /* NSSDEBUG */
  1509.   return fwToken->mdObjectHash;
  1510. }
  1511. /*
  1512.  * nssCKFWToken_GetObjectHandleHash
  1513.  *
  1514.  */
  1515. NSS_IMPLEMENT nssCKFWHash *
  1516. nssCKFWToken_GetObjectHandleHash
  1517. (
  1518.   NSSCKFWToken *fwToken
  1519. )
  1520. {
  1521. #ifdef NSSDEBUG
  1522.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1523.     return (nssCKFWHash *)NULL;
  1524.   }
  1525. #endif /* NSSDEBUG */
  1526.   return fwToken->mdObjectHash;
  1527. }
  1528. /*
  1529.  * NSSCKFWToken_GetMDToken
  1530.  *
  1531.  */
  1532. NSS_IMPLEMENT NSSCKMDToken *
  1533. NSSCKFWToken_GetMDToken
  1534. (
  1535.   NSSCKFWToken *fwToken
  1536. )
  1537. {
  1538. #ifdef DEBUG
  1539.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1540.     return (NSSCKMDToken *)NULL;
  1541.   }
  1542. #endif /* DEBUG */
  1543.   return nssCKFWToken_GetMDToken(fwToken);
  1544. }
  1545. /*
  1546.  * NSSCKFWToken_GetArena
  1547.  *
  1548.  */
  1549. NSS_IMPLEMENT NSSArena *
  1550. NSSCKFWToken_GetArena
  1551. (
  1552.   NSSCKFWToken *fwToken,
  1553.   CK_RV *pError
  1554. )
  1555. {
  1556. #ifdef DEBUG
  1557.   if( (CK_RV *)NULL == pError ) {
  1558.     return (NSSArena *)NULL;
  1559.   }
  1560.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1561.     *pError = CKR_ARGUMENTS_BAD;
  1562.     return (NSSArena *)NULL;
  1563.   }
  1564. #endif /* DEBUG */
  1565.   return nssCKFWToken_GetArena(fwToken, pError);
  1566. }
  1567. /*
  1568.  * NSSCKFWToken_GetFWSlot
  1569.  *
  1570.  */
  1571. NSS_IMPLEMENT NSSCKFWSlot *
  1572. NSSCKFWToken_GetFWSlot
  1573. (
  1574.   NSSCKFWToken *fwToken
  1575. )
  1576. {
  1577. #ifdef DEBUG
  1578.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1579.     return (NSSCKFWSlot *)NULL;
  1580.   }
  1581. #endif /* DEBUG */
  1582.   return nssCKFWToken_GetFWSlot(fwToken);
  1583. }
  1584. /*
  1585.  * NSSCKFWToken_GetMDSlot
  1586.  *
  1587.  */
  1588. NSS_IMPLEMENT NSSCKMDSlot *
  1589. NSSCKFWToken_GetMDSlot
  1590. (
  1591.   NSSCKFWToken *fwToken
  1592. )
  1593. {
  1594. #ifdef DEBUG
  1595.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1596.     return (NSSCKMDSlot *)NULL;
  1597.   }
  1598. #endif /* DEBUG */
  1599.   return nssCKFWToken_GetMDSlot(fwToken);
  1600. }
  1601. /*
  1602.  * NSSCKFWToken_GetSessionState
  1603.  *
  1604.  */
  1605. NSS_IMPLEMENT CK_STATE
  1606. NSSCKFWSession_GetSessionState
  1607. (
  1608.   NSSCKFWToken *fwToken
  1609. )
  1610. {
  1611. #ifdef DEBUG
  1612.   if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
  1613.     return CKS_RO_PUBLIC_SESSION;
  1614.   }
  1615. #endif /* DEBUG */
  1616.   return nssCKFWToken_GetSessionState(fwToken);
  1617. }