Back to index

lightning-sunbird  0.9+nobinonly
wrap.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #ifdef DEBUG
00038 static const char CVS_ID[] = "@(#) $RCSfile: wrap.c,v $ $Revision: 1.13.2.1 $ $Date: 2006/06/10 22:19:16 $";
00039 #endif /* DEBUG */
00040 
00041 /*
00042  * wrap.c
00043  *
00044  * This file contains the routines that actually implement the cryptoki
00045  * API, using the internal APIs of the NSS Cryptoki Framework.  There is
00046  * one routine here for every cryptoki routine.  For linking reasons
00047  * the actual entry points passed back with C_GetFunctionList have to
00048  * exist in one of the Module's source files; however, those are merely
00049  * simple wrappers that call these routines.  The intelligence of the
00050  * implementations is here.
00051  */
00052 
00053 #ifndef CK_T
00054 #include "ck.h"
00055 #endif /* CK_T */
00056 
00057 /*
00058  * NSSCKFWC_Initialize
00059  * NSSCKFWC_Finalize
00060  * NSSCKFWC_GetInfo
00061  * -- NSSCKFWC_GetFunctionList -- see the API insert file
00062  * NSSCKFWC_GetSlotList
00063  * NSSCKFWC_GetSlotInfo
00064  * NSSCKFWC_GetTokenInfo
00065  * NSSCKFWC_WaitForSlotEvent
00066  * NSSCKFWC_GetMechanismList
00067  * NSSCKFWC_GetMechanismInfo
00068  * NSSCKFWC_InitToken
00069  * NSSCKFWC_InitPIN
00070  * NSSCKFWC_SetPIN
00071  * NSSCKFWC_OpenSession
00072  * NSSCKFWC_CloseSession
00073  * NSSCKFWC_CloseAllSessions
00074  * NSSCKFWC_GetSessionInfo
00075  * NSSCKFWC_GetOperationState
00076  * NSSCKFWC_SetOperationState
00077  * NSSCKFWC_Login
00078  * NSSCKFWC_Logout
00079  * NSSCKFWC_CreateObject
00080  * NSSCKFWC_CopyObject
00081  * NSSCKFWC_DestroyObject
00082  * NSSCKFWC_GetObjectSize
00083  * NSSCKFWC_GetAttributeValue
00084  * NSSCKFWC_SetAttributeValue
00085  * NSSCKFWC_FindObjectsInit
00086  * NSSCKFWC_FindObjects
00087  * NSSCKFWC_FindObjectsFinal
00088  * NSSCKFWC_EncryptInit
00089  * NSSCKFWC_Encrypt
00090  * NSSCKFWC_EncryptUpdate
00091  * NSSCKFWC_EncryptFinal
00092  * NSSCKFWC_DecryptInit
00093  * NSSCKFWC_Decrypt
00094  * NSSCKFWC_DecryptUpdate
00095  * NSSCKFWC_DecryptFinal
00096  * NSSCKFWC_DigestInit
00097  * NSSCKFWC_Digest
00098  * NSSCKFWC_DigestUpdate
00099  * NSSCKFWC_DigestKey
00100  * NSSCKFWC_DigestFinal
00101  * NSSCKFWC_SignInit
00102  * NSSCKFWC_Sign
00103  * NSSCKFWC_SignUpdate
00104  * NSSCKFWC_SignFinal
00105  * NSSCKFWC_SignRecoverInit
00106  * NSSCKFWC_SignRecover
00107  * NSSCKFWC_VerifyInit
00108  * NSSCKFWC_Verify
00109  * NSSCKFWC_VerifyUpdate
00110  * NSSCKFWC_VerifyFinal
00111  * NSSCKFWC_VerifyRecoverInit
00112  * NSSCKFWC_VerifyRecover
00113  * NSSCKFWC_DigestEncryptUpdate
00114  * NSSCKFWC_DecryptDigestUpdate
00115  * NSSCKFWC_SignEncryptUpdate
00116  * NSSCKFWC_DecryptVerifyUpdate
00117  * NSSCKFWC_GenerateKey
00118  * NSSCKFWC_GenerateKeyPair
00119  * NSSCKFWC_WrapKey
00120  * NSSCKFWC_UnwrapKey
00121  * NSSCKFWC_DeriveKey
00122  * NSSCKFWC_SeedRandom
00123  * NSSCKFWC_GenerateRandom
00124  * NSSCKFWC_GetFunctionStatus
00125  * NSSCKFWC_CancelFunction
00126  */
00127 
00128 /* figure out out locking semantics */
00129 static CK_RV
00130 nssCKFW_GetThreadSafeState(CK_C_INITIALIZE_ARGS_PTR pInitArgs,
00131                            CryptokiLockingState *pLocking_state) {
00132   int functionCount = 0;
00133 
00134   /* parsed according to (PKCS #11 Section 11.4) */
00135   /* no args, the degenerate version of case 1 */
00136   if (!pInitArgs) {
00137     *pLocking_state = SingleThreaded;
00138     return CKR_OK;
00139   } 
00140 
00141   /* CKF_OS_LOCKING_OK set, Cases 2 and 4 */
00142   if (pInitArgs->flags & CKF_OS_LOCKING_OK) {
00143     *pLocking_state = MultiThreaded;
00144     return CKR_OK;
00145   }
00146   if ((CK_CREATEMUTEX) NULL != pInitArgs->CreateMutex) functionCount++;
00147   if ((CK_DESTROYMUTEX) NULL != pInitArgs->DestroyMutex) functionCount++;
00148   if ((CK_LOCKMUTEX) NULL != pInitArgs->LockMutex) functionCount++;
00149   if ((CK_UNLOCKMUTEX) NULL != pInitArgs->UnlockMutex) functionCount++;
00150 
00151   /* CKF_OS_LOCKING_OK is not set, and not functions supplied, 
00152    * explicit case 1 */
00153   if (0 == functionCount) {
00154     *pLocking_state = SingleThreaded;
00155     return CKR_OK;
00156   }
00157 
00158   /* OS_LOCKING_OK is not set and functions have been supplied. Since
00159    * ckfw uses nssbase library which explicitly calls NSPR, and since 
00160    * there is no way to reliably override these explicit calls to NSPR,
00161    * therefore we can't support applications which have their own threading 
00162    * module.  Return CKR_CANT_LOCK if they supplied the correct number of 
00163    * arguments, or CKR_ARGUMENTS_BAD if they did not in either case we will 
00164    * fail the initialize */
00165   return (4 == functionCount) ? CKR_CANT_LOCK : CKR_ARGUMENTS_BAD;
00166 }
00167 
00168 /*
00169  * NSSCKFWC_Initialize
00170  *
00171  */
00172 NSS_IMPLEMENT CK_RV
00173 NSSCKFWC_Initialize
00174 (
00175   NSSCKFWInstance **pFwInstance,
00176   NSSCKMDInstance *mdInstance,
00177   CK_VOID_PTR pInitArgs
00178 )
00179 {
00180   CK_RV error = CKR_OK;
00181   CryptokiLockingState locking_state;
00182 
00183   if( (NSSCKFWInstance **)NULL == pFwInstance ) {
00184     error = CKR_GENERAL_ERROR;
00185     goto loser;
00186   }
00187 
00188   if( (NSSCKFWInstance *)NULL != *pFwInstance ) {
00189     error = CKR_CRYPTOKI_ALREADY_INITIALIZED;
00190     goto loser;
00191   }
00192 
00193   if( (NSSCKMDInstance *)NULL == mdInstance ) {
00194     error = CKR_GENERAL_ERROR;
00195     goto loser;
00196   }
00197 
00198   error = nssCKFW_GetThreadSafeState(pInitArgs,&locking_state);
00199   if( CKR_OK != error ) {
00200     goto loser;
00201   }
00202 
00203   *pFwInstance = nssCKFWInstance_Create(pInitArgs, locking_state, mdInstance, &error);
00204   if( (NSSCKFWInstance *)NULL == *pFwInstance ) {
00205     goto loser;
00206   }
00207 
00208   return CKR_OK;
00209 
00210  loser:
00211   switch( error ) {
00212   case CKR_ARGUMENTS_BAD:
00213   case CKR_CANT_LOCK:
00214   case CKR_CRYPTOKI_ALREADY_INITIALIZED:
00215   case CKR_FUNCTION_FAILED:
00216   case CKR_GENERAL_ERROR:
00217   case CKR_HOST_MEMORY:
00218   case CKR_NEED_TO_CREATE_THREADS:
00219     break;
00220   default:
00221   case CKR_OK:
00222     error = CKR_GENERAL_ERROR;
00223     break;
00224   }
00225 
00226   return error;
00227 }
00228 
00229 /*
00230  * NSSCKFWC_Finalize
00231  *
00232  */
00233 NSS_IMPLEMENT CK_RV
00234 NSSCKFWC_Finalize
00235 (
00236   NSSCKFWInstance **pFwInstance
00237 )
00238 {
00239   CK_RV error = CKR_OK;
00240 
00241   if( (NSSCKFWInstance **)NULL == pFwInstance ) {
00242     error = CKR_GENERAL_ERROR;
00243     goto loser;
00244   }
00245 
00246   if( (NSSCKFWInstance *)NULL == *pFwInstance ) {
00247     error = CKR_CRYPTOKI_NOT_INITIALIZED;
00248     goto loser;
00249   }
00250 
00251   error = nssCKFWInstance_Destroy(*pFwInstance);
00252 
00253   /* In any case */
00254   *pFwInstance = (NSSCKFWInstance *)NULL;
00255 
00256  loser:
00257   switch( error ) {
00258   case CKR_CRYPTOKI_NOT_INITIALIZED:
00259   case CKR_FUNCTION_FAILED:
00260   case CKR_GENERAL_ERROR:
00261   case CKR_HOST_MEMORY:
00262   case CKR_OK:
00263     break;
00264   default:
00265     error = CKR_GENERAL_ERROR;
00266     break;
00267   }
00268 
00269   return error;
00270 }
00271 
00272 /*
00273  * NSSCKFWC_GetInfo
00274  *
00275  */
00276 NSS_IMPLEMENT CK_RV
00277 NSSCKFWC_GetInfo
00278 (
00279   NSSCKFWInstance *fwInstance,
00280   CK_INFO_PTR pInfo
00281 )
00282 {
00283   CK_RV error = CKR_OK;
00284 
00285   if( (CK_INFO_PTR)CK_NULL_PTR == pInfo ) {
00286     error = CKR_ARGUMENTS_BAD;
00287     goto loser;
00288   }
00289 
00290   /*
00291    * A purify error here means a caller error
00292    */
00293   (void)nsslibc_memset(pInfo, 0, sizeof(CK_INFO));
00294 
00295   pInfo->cryptokiVersion = nssCKFWInstance_GetCryptokiVersion(fwInstance);
00296 
00297   error = nssCKFWInstance_GetManufacturerID(fwInstance, pInfo->manufacturerID);
00298   if( CKR_OK != error ) {
00299     goto loser;
00300   }
00301 
00302   pInfo->flags = nssCKFWInstance_GetFlags(fwInstance);
00303 
00304   error = nssCKFWInstance_GetLibraryDescription(fwInstance, pInfo->libraryDescription);
00305   if( CKR_OK != error ) {
00306     goto loser;
00307   }
00308 
00309   pInfo->libraryVersion = nssCKFWInstance_GetLibraryVersion(fwInstance);
00310 
00311   return CKR_OK;
00312 
00313  loser:
00314   switch( error ) {
00315   case CKR_CRYPTOKI_NOT_INITIALIZED:
00316   case CKR_FUNCTION_FAILED:
00317   case CKR_GENERAL_ERROR:
00318   case CKR_HOST_MEMORY:
00319     break;
00320   default:
00321     error = CKR_GENERAL_ERROR;
00322     break;
00323   }
00324 
00325   return error;
00326 }
00327   
00328 /*
00329  * C_GetFunctionList is implemented entirely in the Module's file which
00330  * includes the Framework API insert file.  It requires no "actual"
00331  * NSSCKFW routine.
00332  */
00333 
00334 /*
00335  * NSSCKFWC_GetSlotList
00336  *
00337  */
00338 NSS_IMPLEMENT CK_RV
00339 NSSCKFWC_GetSlotList
00340 (
00341   NSSCKFWInstance *fwInstance,
00342   CK_BBOOL tokenPresent,
00343   CK_SLOT_ID_PTR pSlotList,
00344   CK_ULONG_PTR pulCount
00345 )
00346 {
00347   CK_RV error = CKR_OK;
00348   CK_ULONG nSlots;
00349 
00350   if( (NSSCKFWInstance *)NULL == fwInstance ) {
00351     error = CKR_CRYPTOKI_NOT_INITIALIZED;
00352     goto loser;
00353   }
00354 
00355   switch( tokenPresent ) {
00356   case CK_TRUE:
00357   case CK_FALSE:
00358     break;
00359   default:
00360     error = CKR_ARGUMENTS_BAD;
00361     goto loser;
00362   }
00363 
00364   if( (CK_ULONG_PTR)CK_NULL_PTR == pulCount ) {
00365     error = CKR_ARGUMENTS_BAD;
00366     goto loser;
00367   }
00368 
00369   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
00370   if( (CK_ULONG)0 == nSlots ) {
00371     goto loser;
00372   }
00373 
00374   if( (CK_SLOT_ID_PTR)CK_NULL_PTR == pSlotList ) {
00375     *pulCount = nSlots;
00376     return CKR_OK;
00377   } 
00378     
00379   /*
00380    * A purify error here indicates caller error.
00381    */
00382   (void)nsslibc_memset(pSlotList, 0, *pulCount * sizeof(CK_SLOT_ID));
00383 
00384   if( *pulCount < nSlots ) {
00385     *pulCount = nSlots;
00386     error = CKR_BUFFER_TOO_SMALL;
00387     goto loser;
00388   } else {
00389     CK_ULONG i;
00390     *pulCount = nSlots;
00391     
00392     /* 
00393      * Our secret "mapping": CK_SLOT_IDs are integers [1,N], and we
00394      * just index one when we need it.
00395      */
00396 
00397     for( i = 0; i < nSlots; i++ ) {
00398       pSlotList[i] = i+1;
00399     }
00400 
00401     return CKR_OK;
00402   }
00403 
00404  loser:
00405   switch( error ) {
00406   case CKR_BUFFER_TOO_SMALL:
00407   case CKR_CRYPTOKI_NOT_INITIALIZED:
00408   case CKR_FUNCTION_FAILED:
00409   case CKR_GENERAL_ERROR:
00410   case CKR_HOST_MEMORY:
00411     break;
00412   default:
00413   case CKR_OK:
00414     error = CKR_GENERAL_ERROR;
00415     break;
00416   }
00417 
00418   return error;
00419 }
00420  
00421 /*
00422  * NSSCKFWC_GetSlotInfo
00423  *
00424  */
00425 NSS_IMPLEMENT CK_RV
00426 NSSCKFWC_GetSlotInfo
00427 (
00428   NSSCKFWInstance *fwInstance,
00429   CK_SLOT_ID slotID,
00430   CK_SLOT_INFO_PTR pInfo
00431 )
00432 {
00433   CK_RV error = CKR_OK;
00434   CK_ULONG nSlots;
00435   NSSCKFWSlot **slots;
00436   NSSCKFWSlot *fwSlot;
00437 
00438   if( (NSSCKFWInstance *)NULL == fwInstance ) {
00439     error = CKR_CRYPTOKI_NOT_INITIALIZED;
00440     goto loser;
00441   }
00442 
00443   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
00444   if( (CK_ULONG)0 == nSlots ) {
00445     goto loser;
00446   }
00447 
00448   if( (slotID < 1) || (slotID > nSlots) ) {
00449     error = CKR_SLOT_ID_INVALID;
00450     goto loser;
00451   }
00452 
00453   if( (CK_SLOT_INFO_PTR)CK_NULL_PTR == pInfo ) {
00454     error = CKR_ARGUMENTS_BAD;
00455     goto loser;
00456   }
00457 
00458   /*
00459    * A purify error here indicates caller error.
00460    */
00461   (void)nsslibc_memset(pInfo, 0, sizeof(CK_SLOT_INFO));
00462 
00463   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
00464   if( (NSSCKFWSlot **)NULL == slots ) {
00465     goto loser;
00466   }
00467 
00468   fwSlot = slots[ slotID-1 ];
00469 
00470   error = nssCKFWSlot_GetSlotDescription(fwSlot, pInfo->slotDescription);
00471   if( CKR_OK != error ) {
00472     goto loser;
00473   }
00474 
00475   error = nssCKFWSlot_GetManufacturerID(fwSlot, pInfo->manufacturerID);
00476   if( CKR_OK != error ) {
00477     goto loser;
00478   }
00479 
00480   if( nssCKFWSlot_GetTokenPresent(fwSlot) ) {
00481     pInfo->flags |= CKF_TOKEN_PRESENT;
00482   }
00483 
00484   if( nssCKFWSlot_GetRemovableDevice(fwSlot) ) {
00485     pInfo->flags |= CKF_REMOVABLE_DEVICE;
00486   }
00487 
00488   if( nssCKFWSlot_GetHardwareSlot(fwSlot) ) {
00489     pInfo->flags |= CKF_HW_SLOT;
00490   }
00491 
00492   pInfo->hardwareVersion = nssCKFWSlot_GetHardwareVersion(fwSlot);
00493   pInfo->firmwareVersion = nssCKFWSlot_GetFirmwareVersion(fwSlot);
00494 
00495   return CKR_OK;
00496 
00497  loser:
00498   switch( error ) {
00499   case CKR_CRYPTOKI_NOT_INITIALIZED:
00500   case CKR_DEVICE_ERROR:
00501   case CKR_FUNCTION_FAILED:
00502   case CKR_GENERAL_ERROR:
00503   case CKR_HOST_MEMORY:
00504   case CKR_SLOT_ID_INVALID:
00505     break;
00506   default:
00507   case CKR_OK:
00508     error = CKR_GENERAL_ERROR;
00509   }
00510 
00511   return error;
00512 }
00513 
00514 /*
00515  * NSSCKFWC_GetTokenInfo
00516  *
00517  */
00518 NSS_IMPLEMENT CK_RV
00519 NSSCKFWC_GetTokenInfo
00520 (
00521   NSSCKFWInstance *fwInstance,
00522   CK_SLOT_ID slotID,
00523   CK_TOKEN_INFO_PTR pInfo
00524 )
00525 {
00526   CK_RV error = CKR_OK;
00527   CK_ULONG nSlots;
00528   NSSCKFWSlot **slots;
00529   NSSCKFWSlot *fwSlot;
00530   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
00531 
00532   if( (NSSCKFWInstance *)NULL == fwInstance ) {
00533     error = CKR_CRYPTOKI_NOT_INITIALIZED;
00534     goto loser;
00535   }
00536 
00537   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
00538   if( (CK_ULONG)0 == nSlots ) {
00539     goto loser;
00540   }
00541 
00542   if( (slotID < 1) || (slotID > nSlots) ) {
00543     error = CKR_SLOT_ID_INVALID;
00544     goto loser;
00545   }
00546 
00547   if( (CK_TOKEN_INFO_PTR)CK_NULL_PTR == pInfo ) {
00548     error = CKR_ARGUMENTS_BAD;
00549     goto loser;
00550   }
00551 
00552   /*
00553    * A purify error here indicates caller error.
00554    */
00555   (void)nsslibc_memset(pInfo, 0, sizeof(CK_TOKEN_INFO));
00556 
00557   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
00558   if( (NSSCKFWSlot **)NULL == slots ) {
00559     goto loser;
00560   }
00561 
00562   fwSlot = slots[ slotID-1 ];
00563 
00564   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
00565     error = CKR_TOKEN_NOT_PRESENT;
00566     goto loser;
00567   }
00568 
00569   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
00570   if( (NSSCKFWToken *)NULL == fwToken ) {
00571     goto loser;
00572   }
00573 
00574   error = nssCKFWToken_GetLabel(fwToken, pInfo->label);
00575   if( CKR_OK != error ) {
00576     goto loser;
00577   }
00578 
00579   error = nssCKFWToken_GetManufacturerID(fwToken, pInfo->manufacturerID);
00580   if( CKR_OK != error ) {
00581     goto loser;
00582   }
00583 
00584   error = nssCKFWToken_GetModel(fwToken, pInfo->model);
00585   if( CKR_OK != error ) {
00586     goto loser;
00587   }
00588 
00589   error = nssCKFWToken_GetSerialNumber(fwToken, pInfo->serialNumber);
00590   if( CKR_OK != error ) {
00591     goto loser;
00592   }
00593 
00594   if( nssCKFWToken_GetHasRNG(fwToken) ) {
00595     pInfo->flags |= CKF_RNG;
00596   }
00597 
00598   if( nssCKFWToken_GetIsWriteProtected(fwToken) ) {
00599     pInfo->flags |= CKF_WRITE_PROTECTED;
00600   }
00601 
00602   if( nssCKFWToken_GetLoginRequired(fwToken) ) {
00603     pInfo->flags |= CKF_LOGIN_REQUIRED;
00604   }
00605 
00606   if( nssCKFWToken_GetUserPinInitialized(fwToken) ) {
00607     pInfo->flags |= CKF_USER_PIN_INITIALIZED;
00608   }
00609 
00610   if( nssCKFWToken_GetRestoreKeyNotNeeded(fwToken) ) {
00611     pInfo->flags |= CKF_RESTORE_KEY_NOT_NEEDED;
00612   }
00613 
00614   if( nssCKFWToken_GetHasClockOnToken(fwToken) ) {
00615     pInfo->flags |= CKF_CLOCK_ON_TOKEN;
00616   }
00617 
00618   if( nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken) ) {
00619     pInfo->flags |= CKF_PROTECTED_AUTHENTICATION_PATH;
00620   }
00621 
00622   if( nssCKFWToken_GetSupportsDualCryptoOperations(fwToken) ) {
00623     pInfo->flags |= CKF_DUAL_CRYPTO_OPERATIONS;
00624   }
00625 
00626   pInfo->ulMaxSessionCount = nssCKFWToken_GetMaxSessionCount(fwToken);
00627   pInfo->ulSessionCount = nssCKFWToken_GetSessionCount(fwToken);
00628   pInfo->ulMaxRwSessionCount = nssCKFWToken_GetMaxRwSessionCount(fwToken);
00629   pInfo->ulRwSessionCount= nssCKFWToken_GetRwSessionCount(fwToken);
00630   pInfo->ulMaxPinLen = nssCKFWToken_GetMaxPinLen(fwToken);
00631   pInfo->ulMinPinLen = nssCKFWToken_GetMinPinLen(fwToken);
00632   pInfo->ulTotalPublicMemory = nssCKFWToken_GetTotalPublicMemory(fwToken);
00633   pInfo->ulFreePublicMemory = nssCKFWToken_GetFreePublicMemory(fwToken);
00634   pInfo->ulTotalPrivateMemory = nssCKFWToken_GetTotalPrivateMemory(fwToken);
00635   pInfo->ulFreePrivateMemory = nssCKFWToken_GetFreePrivateMemory(fwToken);
00636   pInfo->hardwareVersion = nssCKFWToken_GetHardwareVersion(fwToken);
00637   pInfo->firmwareVersion = nssCKFWToken_GetFirmwareVersion(fwToken);
00638   
00639   error = nssCKFWToken_GetUTCTime(fwToken, pInfo->utcTime);
00640   if( CKR_OK != error ) {
00641     goto loser;
00642   }
00643 
00644   return CKR_OK;
00645 
00646  loser:
00647   switch( error ) {
00648   case CKR_DEVICE_REMOVED:
00649   case CKR_TOKEN_NOT_PRESENT:
00650     if (fwToken)
00651       nssCKFWToken_Destroy(fwToken);
00652     break;
00653   case CKR_CRYPTOKI_NOT_INITIALIZED:
00654   case CKR_DEVICE_ERROR:
00655   case CKR_DEVICE_MEMORY:
00656   case CKR_FUNCTION_FAILED:
00657   case CKR_GENERAL_ERROR:
00658   case CKR_HOST_MEMORY:
00659   case CKR_SLOT_ID_INVALID:
00660   case CKR_TOKEN_NOT_RECOGNIZED:
00661     break;
00662   default:
00663   case CKR_OK:
00664     error = CKR_GENERAL_ERROR;
00665     break;
00666   }
00667 
00668   return error;
00669 }
00670 
00671 /*
00672  * NSSCKFWC_WaitForSlotEvent
00673  *
00674  */
00675 NSS_IMPLEMENT CK_RV
00676 NSSCKFWC_WaitForSlotEvent
00677 (
00678   NSSCKFWInstance *fwInstance,
00679   CK_FLAGS flags,
00680   CK_SLOT_ID_PTR pSlot,
00681   CK_VOID_PTR pReserved
00682 )
00683 {
00684   CK_RV error = CKR_OK;
00685   CK_ULONG nSlots;
00686   CK_BBOOL block;
00687   NSSCKFWSlot **slots;
00688   NSSCKFWSlot *fwSlot;
00689   CK_ULONG i;
00690 
00691   if( (NSSCKFWInstance *)NULL == fwInstance ) {
00692     error = CKR_CRYPTOKI_NOT_INITIALIZED;
00693     goto loser;
00694   }
00695 
00696   if( flags & ~CKF_DONT_BLOCK ) {
00697     error = CKR_ARGUMENTS_BAD;
00698     goto loser;
00699   }
00700 
00701   block = (flags & CKF_DONT_BLOCK) ? CK_TRUE : CK_FALSE;
00702 
00703   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
00704   if( (CK_ULONG)0 == nSlots ) {
00705     goto loser;
00706   }
00707 
00708   if( (CK_SLOT_ID_PTR)CK_NULL_PTR == pSlot ) {
00709     error = CKR_ARGUMENTS_BAD;
00710     goto loser;
00711   }
00712 
00713   if( (CK_VOID_PTR)CK_NULL_PTR != pReserved ) {
00714     error = CKR_ARGUMENTS_BAD;
00715     goto loser;
00716   }
00717 
00718   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
00719   if( (NSSCKFWSlot **)NULL == slots ) {
00720     goto loser;
00721   }
00722 
00723   fwSlot = nssCKFWInstance_WaitForSlotEvent(fwInstance, block, &error);
00724   if( (NSSCKFWSlot *)NULL == fwSlot ) {
00725     goto loser;
00726   }
00727 
00728   for( i = 0; i < nSlots; i++ ) {
00729     if( fwSlot == slots[i] ) {
00730       *pSlot = (CK_SLOT_ID)(CK_ULONG)(i+1);
00731       return CKR_OK;
00732     }
00733   }
00734 
00735   error = CKR_GENERAL_ERROR; /* returned something not in the slot list */
00736 
00737  loser:
00738   switch( error ) {
00739   case CKR_CRYPTOKI_NOT_INITIALIZED:
00740   case CKR_FUNCTION_FAILED:
00741   case CKR_GENERAL_ERROR:
00742   case CKR_HOST_MEMORY:
00743   case CKR_NO_EVENT:
00744     break;
00745   default:
00746   case CKR_OK:
00747     error = CKR_GENERAL_ERROR;
00748     break;
00749   }
00750 
00751   return error;
00752 }
00753 
00754 /*
00755  * NSSCKFWC_GetMechanismList
00756  *
00757  */
00758 NSS_IMPLEMENT CK_RV
00759 NSSCKFWC_GetMechanismList
00760 (
00761   NSSCKFWInstance *fwInstance,
00762   CK_SLOT_ID slotID,
00763   CK_MECHANISM_TYPE_PTR pMechanismList,
00764   CK_ULONG_PTR pulCount
00765 )
00766 {
00767   CK_RV error = CKR_OK;
00768   CK_ULONG nSlots;
00769   NSSCKFWSlot **slots;
00770   NSSCKFWSlot *fwSlot;
00771   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
00772   CK_ULONG count;
00773 
00774   if( (NSSCKFWInstance *)NULL == fwInstance ) {
00775     error = CKR_CRYPTOKI_NOT_INITIALIZED;
00776     goto loser;
00777   }
00778 
00779   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
00780   if( (CK_ULONG)0 == nSlots ) {
00781     goto loser;
00782   }
00783 
00784   if( (slotID < 1) || (slotID > nSlots) ) {
00785     error = CKR_SLOT_ID_INVALID;
00786     goto loser;
00787   }
00788 
00789   if( (CK_ULONG_PTR)CK_NULL_PTR == pulCount ) {
00790     error = CKR_ARGUMENTS_BAD;
00791     goto loser;
00792   }
00793 
00794   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
00795   if( (NSSCKFWSlot **)NULL == slots ) {
00796     goto loser;
00797   }
00798 
00799   fwSlot = slots[ slotID-1 ];
00800 
00801   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
00802     error = CKR_TOKEN_NOT_PRESENT;
00803     goto loser;
00804   }
00805 
00806   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
00807   if( (NSSCKFWToken *)NULL == fwToken ) {
00808     goto loser;
00809   }
00810 
00811   count = nssCKFWToken_GetMechanismCount(fwToken);
00812 
00813   if( (CK_MECHANISM_TYPE_PTR)CK_NULL_PTR == pMechanismList ) {
00814     *pulCount = count;
00815     return CKR_OK;
00816   }
00817 
00818   if( *pulCount < count ) {
00819     *pulCount = count;
00820     error = CKR_BUFFER_TOO_SMALL;
00821     goto loser;
00822   }
00823 
00824   /*
00825    * A purify error here indicates caller error.
00826    */
00827   (void)nsslibc_memset(pMechanismList, 0, *pulCount * sizeof(CK_MECHANISM_TYPE));
00828 
00829   *pulCount = count;
00830 
00831   if( 0 != count ) {
00832     error = nssCKFWToken_GetMechanismTypes(fwToken, pMechanismList);
00833   } else {
00834     error = CKR_OK;
00835   }
00836 
00837   if( CKR_OK == error ) {
00838     return CKR_OK;
00839   }
00840 
00841  loser:
00842   switch( error ) {
00843   case CKR_DEVICE_REMOVED:
00844   case CKR_TOKEN_NOT_PRESENT:
00845     if (fwToken)
00846       nssCKFWToken_Destroy(fwToken);
00847     break;
00848   case CKR_BUFFER_TOO_SMALL:
00849   case CKR_CRYPTOKI_NOT_INITIALIZED:
00850   case CKR_DEVICE_ERROR:
00851   case CKR_DEVICE_MEMORY:
00852   case CKR_FUNCTION_FAILED:
00853   case CKR_GENERAL_ERROR:
00854   case CKR_HOST_MEMORY:
00855   case CKR_SLOT_ID_INVALID:
00856   case CKR_TOKEN_NOT_RECOGNIZED:
00857     break;
00858   default:
00859   case CKR_OK:
00860     error = CKR_GENERAL_ERROR;
00861     break;
00862   }
00863 
00864   return error;
00865 }
00866 
00867 /*
00868  * NSSCKFWC_GetMechanismInfo
00869  *
00870  */
00871 NSS_IMPLEMENT CK_RV
00872 NSSCKFWC_GetMechanismInfo
00873 (
00874   NSSCKFWInstance *fwInstance,
00875   CK_SLOT_ID slotID,
00876   CK_MECHANISM_TYPE type,
00877   CK_MECHANISM_INFO_PTR pInfo
00878 )
00879 {
00880   CK_RV error = CKR_OK;
00881   CK_ULONG nSlots;
00882   NSSCKFWSlot **slots;
00883   NSSCKFWSlot *fwSlot;
00884   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
00885   NSSCKFWMechanism *fwMechanism;
00886 
00887   if( (NSSCKFWInstance *)NULL == fwInstance ) {
00888     error = CKR_CRYPTOKI_NOT_INITIALIZED;
00889     goto loser;
00890   }
00891 
00892   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
00893   if( (CK_ULONG)0 == nSlots ) {
00894     goto loser;
00895   }
00896 
00897   if( (slotID < 1) || (slotID > nSlots) ) {
00898     error = CKR_SLOT_ID_INVALID;
00899     goto loser;
00900   }
00901 
00902   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
00903   if( (NSSCKFWSlot **)NULL == slots ) {
00904     goto loser;
00905   }
00906 
00907   fwSlot = slots[ slotID-1 ];
00908 
00909   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
00910     error = CKR_TOKEN_NOT_PRESENT;
00911     goto loser;
00912   }
00913 
00914   if( (CK_MECHANISM_INFO_PTR)CK_NULL_PTR == pInfo ) {
00915     error = CKR_ARGUMENTS_BAD;
00916     goto loser;
00917   }
00918 
00919   /*
00920    * A purify error here indicates caller error.
00921    */
00922   (void)nsslibc_memset(pInfo, 0, sizeof(CK_MECHANISM_INFO));
00923 
00924   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
00925   if( (NSSCKFWToken *)NULL == fwToken ) {
00926     goto loser;
00927   }
00928 
00929   fwMechanism = nssCKFWToken_GetMechanism(fwToken, type, &error);
00930   if( (NSSCKFWMechanism *)NULL == fwMechanism ) {
00931     goto loser;
00932   }
00933 
00934   pInfo->ulMinKeySize = nssCKFWMechanism_GetMinKeySize(fwMechanism);
00935   pInfo->ulMaxKeySize = nssCKFWMechanism_GetMaxKeySize(fwMechanism);
00936 
00937   if( nssCKFWMechanism_GetInHardware(fwMechanism) ) {
00938     pInfo->flags |= CKF_HW;
00939   }
00940 
00941   /* More here... */
00942 
00943   return CKR_OK;
00944 
00945  loser:
00946   switch( error ) {
00947   case CKR_DEVICE_REMOVED:
00948   case CKR_TOKEN_NOT_PRESENT:
00949     if (fwToken)
00950       nssCKFWToken_Destroy(fwToken);
00951     break;
00952   case CKR_CRYPTOKI_NOT_INITIALIZED:
00953   case CKR_DEVICE_ERROR:
00954   case CKR_DEVICE_MEMORY:
00955   case CKR_FUNCTION_FAILED:
00956   case CKR_GENERAL_ERROR:
00957   case CKR_HOST_MEMORY:
00958   case CKR_MECHANISM_INVALID:
00959   case CKR_SLOT_ID_INVALID:
00960   case CKR_TOKEN_NOT_RECOGNIZED:
00961     break;
00962   default:
00963   case CKR_OK:
00964     error = CKR_GENERAL_ERROR;
00965     break;
00966   }
00967 
00968   return error;
00969 }
00970 
00971 /*
00972  * NSSCKFWC_InitToken
00973  *
00974  */
00975 NSS_IMPLEMENT CK_RV
00976 NSSCKFWC_InitToken
00977 (
00978   NSSCKFWInstance *fwInstance,
00979   CK_SLOT_ID slotID,
00980   CK_CHAR_PTR pPin,
00981   CK_ULONG ulPinLen,
00982   CK_CHAR_PTR pLabel
00983 )
00984 {
00985   CK_RV error = CKR_OK;
00986   CK_ULONG nSlots;
00987   NSSCKFWSlot **slots;
00988   NSSCKFWSlot *fwSlot;
00989   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
00990   NSSItem pin;
00991   NSSUTF8 *label;
00992 
00993   if( (NSSCKFWInstance *)NULL == fwInstance ) {
00994     error = CKR_CRYPTOKI_NOT_INITIALIZED;
00995     goto loser;
00996   }
00997 
00998   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
00999   if( (CK_ULONG)0 == nSlots ) {
01000     goto loser;
01001   }
01002 
01003   if( (slotID < 1) || (slotID > nSlots) ) {
01004     error = CKR_SLOT_ID_INVALID;
01005     goto loser;
01006   }
01007 
01008   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
01009   if( (NSSCKFWSlot **)NULL == slots ) {
01010     goto loser;
01011   }
01012 
01013   fwSlot = slots[ slotID-1 ];
01014 
01015   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
01016     error = CKR_TOKEN_NOT_PRESENT;
01017     goto loser;
01018   }
01019 
01020   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
01021   if( (NSSCKFWToken *)NULL == fwToken ) {
01022     goto loser;
01023   }
01024 
01025   pin.size = (PRUint32)ulPinLen;
01026   pin.data = (void *)pPin;
01027   label = (NSSUTF8 *)pLabel; /* identity conversion */
01028 
01029   error = nssCKFWToken_InitToken(fwToken, &pin, label);
01030   if( CKR_OK != error ) {
01031     goto loser;
01032   }
01033 
01034   return CKR_OK;
01035 
01036  loser:
01037   switch( error ) {
01038   case CKR_DEVICE_REMOVED:
01039   case CKR_TOKEN_NOT_PRESENT:
01040     if (fwToken)
01041       nssCKFWToken_Destroy(fwToken);
01042     break;
01043   case CKR_CRYPTOKI_NOT_INITIALIZED:
01044   case CKR_DEVICE_ERROR:
01045   case CKR_DEVICE_MEMORY:
01046   case CKR_FUNCTION_FAILED:
01047   case CKR_GENERAL_ERROR:
01048   case CKR_HOST_MEMORY:
01049   case CKR_PIN_INCORRECT:
01050   case CKR_PIN_LOCKED:
01051   case CKR_SESSION_EXISTS:
01052   case CKR_SLOT_ID_INVALID:
01053   case CKR_TOKEN_NOT_RECOGNIZED:
01054   case CKR_TOKEN_WRITE_PROTECTED:
01055     break;
01056   default:
01057   case CKR_OK:
01058     error = CKR_GENERAL_ERROR;
01059     break;
01060   }
01061 
01062   return error;
01063 }
01064 
01065 /*
01066  * NSSCKFWC_InitPIN
01067  *
01068  */
01069 NSS_IMPLEMENT CK_RV
01070 NSSCKFWC_InitPIN
01071 (
01072   NSSCKFWInstance *fwInstance,
01073   CK_SESSION_HANDLE hSession,
01074   CK_CHAR_PTR pPin,
01075   CK_ULONG ulPinLen
01076 )
01077 {
01078   CK_RV error = CKR_OK;
01079   NSSCKFWSession *fwSession;
01080   NSSItem pin, *arg;
01081 
01082   if( (NSSCKFWInstance *)NULL == fwInstance ) {
01083     error = CKR_CRYPTOKI_NOT_INITIALIZED;
01084     goto loser;
01085   }
01086 
01087   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
01088   if( (NSSCKFWSession *)NULL == fwSession ) {
01089     error = CKR_SESSION_HANDLE_INVALID;
01090     goto loser;
01091   }
01092 
01093   if( (CK_CHAR_PTR)CK_NULL_PTR == pPin ) {
01094     arg = (NSSItem *)NULL;
01095   } else {
01096     arg = &pin;
01097     pin.size = (PRUint32)ulPinLen;
01098     pin.data = (void *)pPin;
01099   }
01100 
01101   error = nssCKFWSession_InitPIN(fwSession, arg);
01102   if( CKR_OK != error ) {
01103     goto loser;
01104   }
01105 
01106   return CKR_OK;
01107 
01108  loser:
01109   switch( error ) {
01110   case CKR_SESSION_CLOSED:
01111     /* destroy session? */
01112     break;
01113   case CKR_DEVICE_REMOVED:
01114     /* (void)nssCKFWToken_Destroy(fwToken); */
01115     break;
01116   case CKR_CRYPTOKI_NOT_INITIALIZED:
01117   case CKR_DEVICE_ERROR:
01118   case CKR_DEVICE_MEMORY:
01119   case CKR_FUNCTION_FAILED:
01120   case CKR_GENERAL_ERROR:
01121   case CKR_HOST_MEMORY:
01122   case CKR_PIN_INVALID:
01123   case CKR_PIN_LEN_RANGE:
01124   case CKR_SESSION_READ_ONLY:
01125   case CKR_SESSION_HANDLE_INVALID:
01126   case CKR_TOKEN_WRITE_PROTECTED:
01127   case CKR_USER_NOT_LOGGED_IN:
01128     break;
01129   default:
01130   case CKR_OK:
01131     error = CKR_GENERAL_ERROR;
01132     break;
01133   }
01134 
01135   return error;
01136 }
01137 
01138 /*
01139  * NSSCKFWC_SetPIN
01140  *
01141  */
01142 NSS_IMPLEMENT CK_RV
01143 NSSCKFWC_SetPIN
01144 (
01145   NSSCKFWInstance *fwInstance,
01146   CK_SESSION_HANDLE hSession,
01147   CK_CHAR_PTR pOldPin,
01148   CK_ULONG ulOldLen,
01149   CK_CHAR_PTR pNewPin,
01150   CK_ULONG ulNewLen
01151 )
01152 {
01153   CK_RV error = CKR_OK;
01154   NSSCKFWSession *fwSession;
01155   NSSItem oldPin, newPin, *oldArg, *newArg;
01156 
01157   if( (NSSCKFWInstance *)NULL == fwInstance ) {
01158     error = CKR_CRYPTOKI_NOT_INITIALIZED;
01159     goto loser;
01160   }
01161 
01162   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
01163   if( (NSSCKFWSession *)NULL == fwSession ) {
01164     error = CKR_SESSION_HANDLE_INVALID;
01165     goto loser;
01166   }
01167 
01168   if( (CK_CHAR_PTR)CK_NULL_PTR == pOldPin ) {
01169     oldArg = (NSSItem *)NULL;
01170   } else {
01171     oldArg = &oldPin;
01172     oldPin.size = (PRUint32)ulOldLen;
01173     oldPin.data = (void *)pOldPin;
01174   }
01175 
01176   if( (CK_CHAR_PTR)CK_NULL_PTR == pNewPin ) {
01177     newArg = (NSSItem *)NULL;
01178   } else {
01179     newArg = &newPin;
01180     newPin.size = (PRUint32)ulNewLen;
01181     newPin.data = (void *)pNewPin;
01182   }
01183 
01184   error = nssCKFWSession_SetPIN(fwSession, oldArg, newArg);
01185   if( CKR_OK != error ) {
01186     goto loser;
01187   }
01188 
01189   return CKR_OK;
01190 
01191  loser:
01192   switch( error ) {
01193   case CKR_SESSION_CLOSED:
01194     /* destroy session? */
01195     break;
01196   case CKR_DEVICE_REMOVED:
01197     /* (void)nssCKFWToken_Destroy(fwToken); */
01198     break;
01199   case CKR_CRYPTOKI_NOT_INITIALIZED:
01200   case CKR_DEVICE_ERROR:
01201   case CKR_DEVICE_MEMORY:
01202   case CKR_FUNCTION_FAILED:
01203   case CKR_GENERAL_ERROR:
01204   case CKR_HOST_MEMORY:
01205   case CKR_PIN_INCORRECT:
01206   case CKR_PIN_INVALID:
01207   case CKR_PIN_LEN_RANGE:
01208   case CKR_PIN_LOCKED:
01209   case CKR_SESSION_HANDLE_INVALID:
01210   case CKR_SESSION_READ_ONLY:
01211   case CKR_TOKEN_WRITE_PROTECTED:
01212     break;
01213   default:
01214   case CKR_OK:
01215     error = CKR_GENERAL_ERROR;
01216     break;
01217   }
01218 
01219   return error;
01220 }
01221 
01222 /*
01223  * NSSCKFWC_OpenSession
01224  *
01225  */
01226 NSS_IMPLEMENT CK_RV
01227 NSSCKFWC_OpenSession
01228 (
01229   NSSCKFWInstance *fwInstance,
01230   CK_SLOT_ID slotID,
01231   CK_FLAGS flags,
01232   CK_VOID_PTR pApplication,
01233   CK_NOTIFY Notify,
01234   CK_SESSION_HANDLE_PTR phSession
01235 )
01236 {
01237   CK_RV error = CKR_OK;
01238   CK_ULONG nSlots;
01239   NSSCKFWSlot **slots;
01240   NSSCKFWSlot *fwSlot;
01241   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
01242   NSSCKFWSession *fwSession;
01243   CK_BBOOL rw;
01244 
01245   if( (NSSCKFWInstance *)NULL == fwInstance ) {
01246     error = CKR_CRYPTOKI_NOT_INITIALIZED;
01247     goto loser;
01248   }
01249 
01250   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
01251   if( (CK_ULONG)0 == nSlots ) {
01252     goto loser;
01253   }
01254 
01255   if( (slotID < 1) || (slotID > nSlots) ) {
01256     error = CKR_SLOT_ID_INVALID;
01257     goto loser;
01258   }
01259 
01260   if( flags & CKF_RW_SESSION ) {
01261     rw = CK_TRUE;
01262   } else {
01263     rw = CK_FALSE;
01264   }
01265 
01266   if( flags & CKF_SERIAL_SESSION ) {
01267     ;
01268   } else {
01269     error = CKR_SESSION_PARALLEL_NOT_SUPPORTED;
01270     goto loser;
01271   }
01272 
01273   if( flags & ~(CKF_RW_SESSION|CKF_SERIAL_SESSION) ) {
01274     error = CKR_ARGUMENTS_BAD;
01275     goto loser;
01276   }
01277 
01278   if( (CK_SESSION_HANDLE_PTR)CK_NULL_PTR == phSession ) {
01279     error = CKR_ARGUMENTS_BAD;
01280     goto loser;
01281   }
01282 
01283   /*
01284    * A purify error here indicates caller error.
01285    */
01286   *phSession = (CK_SESSION_HANDLE)0;
01287 
01288   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
01289   if( (NSSCKFWSlot **)NULL == slots ) {
01290     goto loser;
01291   }
01292 
01293   fwSlot = slots[ slotID-1 ];
01294 
01295   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
01296     error = CKR_TOKEN_NOT_PRESENT;
01297     goto loser;
01298   }
01299 
01300   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
01301   if( (NSSCKFWToken *)NULL == fwToken ) {
01302     goto loser;
01303   }
01304 
01305   fwSession = nssCKFWToken_OpenSession(fwToken, rw, pApplication,
01306                Notify, &error);
01307   if( (NSSCKFWSession *)NULL == fwSession ) {
01308     goto loser;
01309   }
01310 
01311   *phSession = nssCKFWInstance_CreateSessionHandle(fwInstance,
01312                  fwSession, &error);
01313   if( (CK_SESSION_HANDLE)0 == *phSession ) {
01314     goto loser;
01315   }
01316 
01317   return CKR_OK;
01318 
01319  loser:
01320   switch( error ) {
01321   case CKR_SESSION_CLOSED:
01322     /* destroy session? */
01323     break;
01324   case CKR_DEVICE_REMOVED:
01325     /* (void)nssCKFWToken_Destroy(fwToken); */
01326     break;
01327   case CKR_CRYPTOKI_NOT_INITIALIZED:
01328   case CKR_DEVICE_ERROR:
01329   case CKR_DEVICE_MEMORY:
01330   case CKR_FUNCTION_FAILED:
01331   case CKR_GENERAL_ERROR:
01332   case CKR_HOST_MEMORY:
01333   case CKR_SESSION_COUNT:
01334   case CKR_SESSION_EXISTS:
01335   case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
01336   case CKR_SESSION_READ_WRITE_SO_EXISTS:
01337   case CKR_SLOT_ID_INVALID:
01338   case CKR_TOKEN_NOT_PRESENT:
01339   case CKR_TOKEN_NOT_RECOGNIZED:
01340   case CKR_TOKEN_WRITE_PROTECTED:
01341     break;
01342   default:
01343   case CKR_OK:
01344     error = CKR_GENERAL_ERROR;
01345     break;
01346   }
01347 
01348   return error;
01349 }
01350 
01351 /*
01352  * NSSCKFWC_CloseSession
01353  *
01354  */
01355 NSS_IMPLEMENT CK_RV
01356 NSSCKFWC_CloseSession
01357 (
01358   NSSCKFWInstance *fwInstance,
01359   CK_SESSION_HANDLE hSession
01360 )
01361 {
01362   CK_RV error = CKR_OK;
01363   NSSCKFWSession *fwSession;
01364 
01365   if( (NSSCKFWInstance *)NULL == fwInstance ) {
01366     error = CKR_CRYPTOKI_NOT_INITIALIZED;
01367     goto loser;
01368   }
01369 
01370   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
01371   if( (NSSCKFWSession *)NULL == fwSession ) {
01372     error = CKR_SESSION_HANDLE_INVALID;
01373     goto loser;
01374   }
01375 
01376   nssCKFWInstance_DestroySessionHandle(fwInstance, hSession);
01377   error = nssCKFWSession_Destroy(fwSession, CK_TRUE);
01378 
01379   if( CKR_OK != error ) {
01380     goto loser;
01381   }
01382 
01383   return CKR_OK;
01384 
01385  loser:
01386   switch( error ) {
01387   case CKR_SESSION_CLOSED:
01388     /* destroy session? */
01389     break;
01390   case CKR_DEVICE_REMOVED:
01391     /* (void)nssCKFWToken_Destroy(fwToken); */
01392     break;
01393   case CKR_CRYPTOKI_NOT_INITIALIZED:
01394   case CKR_DEVICE_ERROR:
01395   case CKR_DEVICE_MEMORY:
01396   case CKR_FUNCTION_FAILED:
01397   case CKR_GENERAL_ERROR:
01398   case CKR_HOST_MEMORY:
01399   case CKR_SESSION_HANDLE_INVALID:
01400     break;
01401   default:
01402   case CKR_OK:
01403     error = CKR_GENERAL_ERROR;
01404     break;
01405   }
01406 
01407   return error;
01408 }
01409 
01410 /*
01411  * NSSCKFWC_CloseAllSessions
01412  *
01413  */
01414 NSS_IMPLEMENT CK_RV
01415 NSSCKFWC_CloseAllSessions
01416 (
01417   NSSCKFWInstance *fwInstance,
01418   CK_SLOT_ID slotID
01419 )
01420 {
01421   CK_RV error = CKR_OK;
01422   CK_ULONG nSlots;
01423   NSSCKFWSlot **slots;
01424   NSSCKFWSlot *fwSlot;
01425   NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
01426 
01427   if( (NSSCKFWInstance *)NULL == fwInstance ) {
01428     error = CKR_CRYPTOKI_NOT_INITIALIZED;
01429     goto loser;
01430   }
01431 
01432   nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
01433   if( (CK_ULONG)0 == nSlots ) {
01434     goto loser;
01435   }
01436 
01437   if( (slotID < 1) || (slotID > nSlots) ) {
01438     error = CKR_SLOT_ID_INVALID;
01439     goto loser;
01440   }
01441 
01442   slots = nssCKFWInstance_GetSlots(fwInstance, &error);
01443   if( (NSSCKFWSlot **)NULL == slots ) {
01444     goto loser;
01445   }
01446 
01447   fwSlot = slots[ slotID-1 ];
01448 
01449   if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
01450     error = CKR_TOKEN_NOT_PRESENT;
01451     goto loser;
01452   }
01453 
01454   fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
01455   if( (NSSCKFWToken *)NULL == fwToken ) {
01456     goto loser;
01457   }
01458 
01459   error = nssCKFWToken_CloseAllSessions(fwToken);
01460   if( CKR_OK != error ) {
01461     goto loser;
01462   }
01463 
01464   return CKR_OK;
01465 
01466  loser:
01467   switch( error ) {
01468   case CKR_DEVICE_REMOVED:
01469     /* (void)nssCKFWToken_Destroy(fwToken); */
01470     break;
01471   case CKR_CRYPTOKI_NOT_INITIALIZED:
01472   case CKR_DEVICE_ERROR:
01473   case CKR_DEVICE_MEMORY:
01474   case CKR_FUNCTION_FAILED:
01475   case CKR_GENERAL_ERROR:
01476   case CKR_HOST_MEMORY:
01477   case CKR_SLOT_ID_INVALID:
01478   case CKR_TOKEN_NOT_PRESENT:
01479     break;
01480   default:
01481   case CKR_OK:
01482     error = CKR_GENERAL_ERROR;
01483     break;
01484   }
01485 
01486   return error;
01487 }
01488 
01489 /*
01490  * NSSCKFWC_GetSessionInfo
01491  *
01492  */
01493 NSS_IMPLEMENT CK_RV
01494 NSSCKFWC_GetSessionInfo
01495 (
01496   NSSCKFWInstance *fwInstance,
01497   CK_SESSION_HANDLE hSession,
01498   CK_SESSION_INFO_PTR pInfo
01499 )
01500 {
01501   CK_RV error = CKR_OK;
01502   NSSCKFWSession *fwSession;
01503   NSSCKFWSlot *fwSlot;
01504 
01505   if( (NSSCKFWInstance *)NULL == fwInstance ) {
01506     error = CKR_CRYPTOKI_NOT_INITIALIZED;
01507     goto loser;
01508   }
01509 
01510   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
01511   if( (NSSCKFWSession *)NULL == fwSession ) {
01512     error = CKR_SESSION_HANDLE_INVALID;
01513     goto loser;
01514   }
01515 
01516   if( (CK_SESSION_INFO_PTR)CK_NULL_PTR == pInfo ) {
01517     error = CKR_ARGUMENTS_BAD;
01518     goto loser;
01519   }
01520 
01521   /*
01522    * A purify error here indicates caller error.
01523    */
01524   (void)nsslibc_memset(pInfo, 0, sizeof(CK_SESSION_INFO));
01525 
01526   fwSlot = nssCKFWSession_GetFWSlot(fwSession);
01527   if( (NSSCKFWSlot *)NULL == fwSlot ) {
01528     error = CKR_GENERAL_ERROR;
01529     goto loser;
01530   }
01531 
01532   pInfo->slotID = nssCKFWSlot_GetSlotID(fwSlot);
01533   pInfo->state = nssCKFWSession_GetSessionState(fwSession);
01534 
01535   if( CK_TRUE == nssCKFWSession_IsRWSession(fwSession) ) {
01536     pInfo->flags |= CKF_RW_SESSION;
01537   }
01538 
01539   pInfo->flags |= CKF_SERIAL_SESSION; /* Always true */
01540 
01541   pInfo->ulDeviceError = nssCKFWSession_GetDeviceError(fwSession);
01542 
01543   return CKR_OK;
01544 
01545  loser:
01546   switch( error ) {
01547   case CKR_SESSION_CLOSED:
01548     /* destroy session? */
01549     break;
01550   case CKR_DEVICE_REMOVED:
01551     /* (void)nssCKFWToken_Destroy(fwToken); */
01552     break;
01553   case CKR_CRYPTOKI_NOT_INITIALIZED:
01554   case CKR_DEVICE_ERROR:
01555   case CKR_DEVICE_MEMORY:
01556   case CKR_FUNCTION_FAILED:
01557   case CKR_GENERAL_ERROR:
01558   case CKR_HOST_MEMORY:
01559   case CKR_SESSION_HANDLE_INVALID:
01560     break;
01561   default:
01562   case CKR_OK:
01563     error = CKR_GENERAL_ERROR;
01564     break;
01565   }
01566 
01567   return error;
01568 }
01569 
01570 /*
01571  * NSSCKFWC_GetOperationState
01572  *
01573  */
01574 NSS_IMPLEMENT CK_RV
01575 NSSCKFWC_GetOperationState
01576 (
01577   NSSCKFWInstance *fwInstance,
01578   CK_SESSION_HANDLE hSession,
01579   CK_BYTE_PTR pOperationState,
01580   CK_ULONG_PTR pulOperationStateLen
01581 )
01582 {
01583   CK_RV error = CKR_OK;
01584   NSSCKFWSession *fwSession;
01585   CK_ULONG len;
01586   NSSItem buf;
01587 
01588   if( (NSSCKFWInstance *)NULL == fwInstance ) {
01589     error = CKR_CRYPTOKI_NOT_INITIALIZED;
01590     goto loser;
01591   }
01592 
01593   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
01594   if( (NSSCKFWSession *)NULL == fwSession ) {
01595     error = CKR_SESSION_HANDLE_INVALID;
01596     goto loser;
01597   }
01598 
01599   if( (CK_ULONG_PTR)CK_NULL_PTR == pulOperationStateLen ) {
01600     error = CKR_ARGUMENTS_BAD;
01601     goto loser;
01602   }
01603 
01604   len = nssCKFWSession_GetOperationStateLen(fwSession, &error);
01605   if( ((CK_ULONG)0 == len) && (CKR_OK != error) ) {
01606     goto loser;
01607   }
01608 
01609   if( (CK_BYTE_PTR)CK_NULL_PTR == pOperationState ) {
01610     *pulOperationStateLen = len;
01611     return CKR_OK;
01612   }
01613 
01614   if( *pulOperationStateLen < len ) {
01615     *pulOperationStateLen = len;
01616     error = CKR_BUFFER_TOO_SMALL;
01617     goto loser;
01618   }
01619 
01620   buf.size = (PRUint32)*pulOperationStateLen;
01621   buf.data = (void *)pOperationState;
01622   *pulOperationStateLen = len;
01623   error = nssCKFWSession_GetOperationState(fwSession, &buf);
01624 
01625   if( CKR_OK != error ) {
01626     goto loser;
01627   }
01628 
01629   return CKR_OK;
01630 
01631  loser:
01632   switch( error ) {
01633   case CKR_SESSION_CLOSED:
01634     /* destroy session? */
01635     break;
01636   case CKR_DEVICE_REMOVED:
01637     /* (void)nssCKFWToken_Destroy(fwToken); */
01638     break;
01639   case CKR_BUFFER_TOO_SMALL:
01640   case CKR_CRYPTOKI_NOT_INITIALIZED:
01641   case CKR_DEVICE_ERROR:
01642   case CKR_DEVICE_MEMORY:
01643   case CKR_FUNCTION_FAILED:
01644   case CKR_GENERAL_ERROR:
01645   case CKR_HOST_MEMORY:
01646   case CKR_OPERATION_NOT_INITIALIZED:
01647   case CKR_SESSION_HANDLE_INVALID:
01648   case CKR_STATE_UNSAVEABLE:
01649     break;
01650   default:
01651   case CKR_OK:
01652     error = CKR_GENERAL_ERROR;
01653     break;
01654   }
01655 
01656   return error;
01657 }
01658 
01659 /*
01660  * NSSCKFWC_SetOperationState
01661  *
01662  */
01663 NSS_IMPLEMENT CK_RV
01664 NSSCKFWC_SetOperationState
01665 (
01666   NSSCKFWInstance *fwInstance,
01667   CK_SESSION_HANDLE hSession,
01668   CK_BYTE_PTR pOperationState,
01669   CK_ULONG ulOperationStateLen,
01670   CK_OBJECT_HANDLE hEncryptionKey,
01671   CK_OBJECT_HANDLE hAuthenticationKey
01672 )
01673 {
01674   CK_RV error = CKR_OK;
01675   NSSCKFWSession *fwSession;
01676   NSSCKFWObject *eKey;
01677   NSSCKFWObject *aKey;
01678   NSSItem state;
01679 
01680   if( (NSSCKFWInstance *)NULL == fwInstance ) {
01681     error = CKR_CRYPTOKI_NOT_INITIALIZED;
01682     goto loser;
01683   }
01684   
01685   if( (CK_BYTE_PTR)CK_NULL_PTR == pOperationState ) {
01686     error = CKR_ARGUMENTS_BAD;
01687     goto loser;
01688   }
01689 
01690   /* 
01691    * We could loop through the buffer, to catch any purify errors
01692    * in a place with a "user error" note.
01693    */
01694 
01695   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
01696   if( (NSSCKFWSession *)NULL == fwSession ) {
01697     error = CKR_SESSION_HANDLE_INVALID;
01698     goto loser;
01699   }
01700 
01701   if( (CK_OBJECT_HANDLE)0 == hEncryptionKey ) {
01702     eKey = (NSSCKFWObject *)NULL;
01703   } else {
01704     eKey = nssCKFWInstance_ResolveObjectHandle(fwInstance, hEncryptionKey);
01705     if( (NSSCKFWObject *)NULL == eKey ) {
01706       error = CKR_KEY_HANDLE_INVALID;
01707       goto loser;
01708     }
01709   }
01710 
01711   if( (CK_OBJECT_HANDLE)0 == hAuthenticationKey ) {
01712     aKey = (NSSCKFWObject *)NULL;
01713   } else {
01714     aKey = nssCKFWInstance_ResolveObjectHandle(fwInstance, hAuthenticationKey);
01715     if( (NSSCKFWObject *)NULL == aKey ) {
01716       error = CKR_KEY_HANDLE_INVALID;
01717       goto loser;
01718     }
01719   }
01720 
01721   error = nssCKFWSession_SetOperationState(fwSession, &state, eKey, aKey);
01722   if( CKR_OK != error ) {
01723     goto loser;
01724   }
01725 
01726   return CKR_OK;
01727 
01728  loser:
01729   switch( error ) {
01730   case CKR_SESSION_CLOSED:
01731     /* destroy session? */
01732     break;
01733   case CKR_DEVICE_REMOVED:
01734     /* (void)nssCKFWToken_Destroy(fwToken); */
01735     break;
01736   case CKR_CRYPTOKI_NOT_INITIALIZED:
01737   case CKR_DEVICE_ERROR:
01738   case CKR_DEVICE_MEMORY:
01739   case CKR_FUNCTION_FAILED:
01740   case CKR_GENERAL_ERROR:
01741   case CKR_HOST_MEMORY:
01742   case CKR_KEY_CHANGED:
01743   case CKR_KEY_NEEDED:
01744   case CKR_KEY_NOT_NEEDED:
01745   case CKR_SAVED_STATE_INVALID:
01746   case CKR_SESSION_HANDLE_INVALID:
01747     break;
01748   default:
01749   case CKR_OK:
01750     error = CKR_GENERAL_ERROR;
01751     break;
01752   }
01753 
01754   return error;
01755 }
01756 
01757 /*
01758  * NSSCKFWC_Login
01759  *
01760  */
01761 NSS_IMPLEMENT CK_RV
01762 NSSCKFWC_Login
01763 (
01764   NSSCKFWInstance *fwInstance,
01765   CK_SESSION_HANDLE hSession,
01766   CK_USER_TYPE userType,
01767   CK_CHAR_PTR pPin,
01768   CK_ULONG ulPinLen
01769 )
01770 {
01771   CK_RV error = CKR_OK;
01772   NSSCKFWSession *fwSession;
01773   NSSItem pin, *arg;
01774 
01775   if( (NSSCKFWInstance *)NULL == fwInstance ) {
01776     error = CKR_CRYPTOKI_NOT_INITIALIZED;
01777     goto loser;
01778   }
01779   
01780   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
01781   if( (NSSCKFWSession *)NULL == fwSession ) {
01782     error = CKR_SESSION_HANDLE_INVALID;
01783     goto loser;
01784   }
01785 
01786   if( (CK_CHAR_PTR)CK_NULL_PTR == pPin ) {
01787     arg = (NSSItem *)NULL;
01788   } else {
01789     arg = &pin;
01790     pin.size = (PRUint32)ulPinLen;
01791     pin.data = (void *)pPin;
01792   }
01793 
01794   error = nssCKFWSession_Login(fwSession, userType, arg);
01795   if( CKR_OK != error ) {
01796     goto loser;
01797   }
01798 
01799   return CKR_OK;
01800 
01801  loser:
01802   switch( error ) {
01803   case CKR_SESSION_CLOSED:
01804     /* destroy session? */
01805     break;
01806   case CKR_DEVICE_REMOVED:
01807     /* (void)nssCKFWToken_Destroy(fwToken); */
01808     break;
01809   case CKR_CRYPTOKI_NOT_INITIALIZED:
01810   case CKR_DEVICE_ERROR:
01811   case CKR_DEVICE_MEMORY:
01812   case CKR_FUNCTION_FAILED:
01813   case CKR_GENERAL_ERROR:
01814   case CKR_HOST_MEMORY:
01815   case CKR_PIN_EXPIRED:
01816   case CKR_PIN_INCORRECT:
01817   case CKR_PIN_LOCKED:
01818   case CKR_SESSION_HANDLE_INVALID:
01819   case CKR_SESSION_READ_ONLY_EXISTS:
01820   case CKR_USER_ALREADY_LOGGED_IN:
01821   case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
01822   case CKR_USER_PIN_NOT_INITIALIZED:
01823   case CKR_USER_TOO_MANY_TYPES:
01824   case CKR_USER_TYPE_INVALID:
01825     break;
01826   default:
01827   case CKR_OK:
01828     error = CKR_GENERAL_ERROR;
01829     break;
01830   }
01831 
01832   return error;
01833 }
01834 
01835 /*
01836  * NSSCKFWC_Logout
01837  *
01838  */
01839 NSS_IMPLEMENT CK_RV
01840 NSSCKFWC_Logout
01841 (
01842   NSSCKFWInstance *fwInstance,
01843   CK_SESSION_HANDLE hSession
01844 )
01845 {
01846   CK_RV error = CKR_OK;
01847   NSSCKFWSession *fwSession;
01848 
01849   if( (NSSCKFWInstance *)NULL == fwInstance ) {
01850     error = CKR_CRYPTOKI_NOT_INITIALIZED;
01851     goto loser;
01852   }
01853   
01854   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
01855   if( (NSSCKFWSession *)NULL == fwSession ) {
01856     error = CKR_SESSION_HANDLE_INVALID;
01857     goto loser;
01858   }
01859 
01860   error = nssCKFWSession_Logout(fwSession);
01861   if( CKR_OK != error ) {
01862     goto loser;
01863   }
01864 
01865   return CKR_OK;
01866 
01867  loser:
01868   switch( error ) {
01869   case CKR_SESSION_CLOSED:
01870     /* destroy session? */
01871     break;
01872   case CKR_DEVICE_REMOVED:
01873     /* (void)nssCKFWToken_Destroy(fwToken); */
01874     break;
01875   case CKR_CRYPTOKI_NOT_INITIALIZED:
01876   case CKR_DEVICE_ERROR:
01877   case CKR_DEVICE_MEMORY:
01878   case CKR_FUNCTION_FAILED:
01879   case CKR_GENERAL_ERROR:
01880   case CKR_HOST_MEMORY:
01881   case CKR_SESSION_HANDLE_INVALID:
01882   case CKR_USER_NOT_LOGGED_IN:
01883     break;
01884   default:
01885   case CKR_OK:
01886     error = CKR_GENERAL_ERROR;
01887     break;
01888   }
01889 
01890   return error;
01891 }
01892 
01893 /*
01894  * NSSCKFWC_CreateObject
01895  *
01896  */
01897 NSS_IMPLEMENT CK_RV
01898 NSSCKFWC_CreateObject
01899 (
01900   NSSCKFWInstance *fwInstance,
01901   CK_SESSION_HANDLE hSession,
01902   CK_ATTRIBUTE_PTR pTemplate,
01903   CK_ULONG ulCount,
01904   CK_OBJECT_HANDLE_PTR phObject
01905 )
01906 {
01907   CK_RV error = CKR_OK;
01908   NSSCKFWSession *fwSession;
01909   NSSCKFWObject *fwObject;
01910 
01911   if( (NSSCKFWInstance *)NULL == fwInstance ) {
01912     error = CKR_CRYPTOKI_NOT_INITIALIZED;
01913     goto loser;
01914   }
01915   
01916   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
01917   if( (NSSCKFWSession *)NULL == fwSession ) {
01918     error = CKR_SESSION_HANDLE_INVALID;
01919     goto loser;
01920   }
01921 
01922   if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phObject ) {
01923     error = CKR_ARGUMENTS_BAD;
01924     goto loser;
01925   }
01926 
01927   /*
01928    * A purify error here indicates caller error.
01929    */
01930   *phObject = (CK_OBJECT_HANDLE)0;
01931 
01932   fwObject = nssCKFWSession_CreateObject(fwSession, pTemplate,
01933                ulCount, &error);
01934   if( (NSSCKFWObject *)NULL == fwObject ) {
01935     goto loser;
01936   }
01937 
01938   *phObject = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
01939   if( (CK_OBJECT_HANDLE)0 == *phObject ) {
01940     nssCKFWObject_Destroy(fwObject);
01941     goto loser;
01942   }
01943 
01944   return CKR_OK;
01945 
01946  loser:
01947   switch( error ) {
01948   case CKR_SESSION_CLOSED:
01949     /* destroy session? */
01950     break;
01951   case CKR_DEVICE_REMOVED:
01952     /* (void)nssCKFWToken_Destroy(fwToken); */
01953     break;
01954   case CKR_ATTRIBUTE_READ_ONLY:
01955   case CKR_ATTRIBUTE_TYPE_INVALID:
01956   case CKR_ATTRIBUTE_VALUE_INVALID:
01957   case CKR_CRYPTOKI_NOT_INITIALIZED:
01958   case CKR_DEVICE_ERROR:
01959   case CKR_DEVICE_MEMORY:
01960   case CKR_FUNCTION_FAILED:
01961   case CKR_GENERAL_ERROR:
01962   case CKR_HOST_MEMORY:
01963   case CKR_SESSION_HANDLE_INVALID:
01964   case CKR_SESSION_READ_ONLY:
01965   case CKR_TEMPLATE_INCOMPLETE:
01966   case CKR_TEMPLATE_INCONSISTENT:
01967   case CKR_TOKEN_WRITE_PROTECTED:
01968   case CKR_USER_NOT_LOGGED_IN:
01969     break;
01970   default:
01971   case CKR_OK:
01972     error = CKR_GENERAL_ERROR;
01973     break;
01974   }
01975 
01976   return error;
01977 }
01978 
01979 /*
01980  * NSSCKFWC_CopyObject
01981  *
01982  */
01983 NSS_IMPLEMENT CK_RV
01984 NSSCKFWC_CopyObject
01985 (
01986   NSSCKFWInstance *fwInstance,
01987   CK_SESSION_HANDLE hSession,
01988   CK_OBJECT_HANDLE hObject,
01989   CK_ATTRIBUTE_PTR pTemplate,
01990   CK_ULONG ulCount,
01991   CK_OBJECT_HANDLE_PTR phNewObject
01992 )
01993 {
01994   CK_RV error = CKR_OK;
01995   NSSCKFWSession *fwSession;
01996   NSSCKFWObject *fwObject;
01997   NSSCKFWObject *fwNewObject;
01998 
01999   if( (NSSCKFWInstance *)NULL == fwInstance ) {
02000     error = CKR_CRYPTOKI_NOT_INITIALIZED;
02001     goto loser;
02002   }
02003   
02004   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
02005   if( (NSSCKFWSession *)NULL == fwSession ) {
02006     error = CKR_SESSION_HANDLE_INVALID;
02007     goto loser;
02008   }
02009 
02010   if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phNewObject ) {
02011     error = CKR_ARGUMENTS_BAD;
02012     goto loser;
02013   }
02014 
02015   /*
02016    * A purify error here indicates caller error.
02017    */
02018   *phNewObject = (CK_OBJECT_HANDLE)0;
02019 
02020   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
02021   if( (NSSCKFWObject *)NULL == fwObject ) {
02022     error = CKR_OBJECT_HANDLE_INVALID;
02023     goto loser;
02024   }
02025 
02026   fwNewObject = nssCKFWSession_CopyObject(fwSession, fwObject,
02027                   pTemplate, ulCount, &error);
02028   if( (NSSCKFWObject *)NULL == fwNewObject ) {
02029     goto loser;
02030   }
02031 
02032   *phNewObject = nssCKFWInstance_CreateObjectHandle(fwInstance, 
02033                    fwNewObject, &error);
02034   if( (CK_OBJECT_HANDLE)0 == *phNewObject ) {
02035     nssCKFWObject_Destroy(fwNewObject);
02036     goto loser;
02037   }
02038 
02039   return CKR_OK;
02040 
02041  loser:
02042   switch( error ) {
02043   case CKR_SESSION_CLOSED:
02044     /* destroy session? */
02045     break;
02046   case CKR_DEVICE_REMOVED:
02047     /* (void)nssCKFWToken_Destroy(fwToken); */
02048     break;
02049   case CKR_ATTRIBUTE_READ_ONLY:
02050   case CKR_ATTRIBUTE_TYPE_INVALID:
02051   case CKR_ATTRIBUTE_VALUE_INVALID:
02052   case CKR_CRYPTOKI_NOT_INITIALIZED:
02053   case CKR_DEVICE_ERROR:
02054   case CKR_DEVICE_MEMORY:
02055   case CKR_FUNCTION_FAILED:
02056   case CKR_GENERAL_ERROR:
02057   case CKR_HOST_MEMORY:
02058   case CKR_OBJECT_HANDLE_INVALID:
02059   case CKR_SESSION_HANDLE_INVALID:
02060   case CKR_SESSION_READ_ONLY:
02061   case CKR_TEMPLATE_INCONSISTENT:
02062   case CKR_TOKEN_WRITE_PROTECTED:
02063   case CKR_USER_NOT_LOGGED_IN:
02064     break;
02065   default:
02066   case CKR_OK:
02067     error = CKR_GENERAL_ERROR;
02068     break;
02069   }
02070 
02071   return error;
02072 }
02073 
02074 /*
02075  * NSSCKFWC_DestroyObject
02076  *
02077  */
02078 NSS_IMPLEMENT CK_RV
02079 NSSCKFWC_DestroyObject
02080 (
02081   NSSCKFWInstance *fwInstance,
02082   CK_SESSION_HANDLE hSession,
02083   CK_OBJECT_HANDLE hObject
02084 )
02085 {
02086   CK_RV error = CKR_OK;
02087   NSSCKFWSession *fwSession;
02088   NSSCKFWObject *fwObject;
02089 
02090   if( (NSSCKFWInstance *)NULL == fwInstance ) {
02091     error = CKR_CRYPTOKI_NOT_INITIALIZED;
02092     goto loser;
02093   }
02094   
02095   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
02096   if( (NSSCKFWSession *)NULL == fwSession ) {
02097     error = CKR_SESSION_HANDLE_INVALID;
02098     goto loser;
02099   }
02100 
02101   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
02102   if( (NSSCKFWObject *)NULL == fwObject ) {
02103     error = CKR_OBJECT_HANDLE_INVALID;
02104     goto loser;
02105   }
02106 
02107   nssCKFWInstance_DestroyObjectHandle(fwInstance, hObject);
02108   nssCKFWObject_Destroy(fwObject);
02109 
02110   return CKR_OK;
02111 
02112  loser:
02113   switch( error ) {
02114   case CKR_SESSION_CLOSED:
02115     /* destroy session? */
02116     break;
02117   case CKR_DEVICE_REMOVED:
02118     /* (void)nssCKFWToken_Destroy(fwToken); */
02119     break;
02120   case CKR_CRYPTOKI_NOT_INITIALIZED:
02121   case CKR_DEVICE_ERROR:
02122   case CKR_DEVICE_MEMORY:
02123   case CKR_FUNCTION_FAILED:
02124   case CKR_GENERAL_ERROR:
02125   case CKR_HOST_MEMORY:
02126   case CKR_OBJECT_HANDLE_INVALID:
02127   case CKR_SESSION_HANDLE_INVALID:
02128   case CKR_SESSION_READ_ONLY:
02129   case CKR_TOKEN_WRITE_PROTECTED:
02130     break;
02131   default:
02132   case CKR_OK:
02133     error = CKR_GENERAL_ERROR;
02134     break;
02135   }
02136 
02137   return error;
02138 }
02139 
02140 /*
02141  * NSSCKFWC_GetObjectSize
02142  *
02143  */
02144 NSS_IMPLEMENT CK_RV
02145 NSSCKFWC_GetObjectSize
02146 (
02147   NSSCKFWInstance *fwInstance,
02148   CK_SESSION_HANDLE hSession,
02149   CK_OBJECT_HANDLE hObject,
02150   CK_ULONG_PTR pulSize
02151 )
02152 {
02153   CK_RV error = CKR_OK;
02154   NSSCKFWSession *fwSession;
02155   NSSCKFWObject *fwObject;
02156 
02157   if( (NSSCKFWInstance *)NULL == fwInstance ) {
02158     error = CKR_CRYPTOKI_NOT_INITIALIZED;
02159     goto loser;
02160   }
02161   
02162   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
02163   if( (NSSCKFWSession *)NULL == fwSession ) {
02164     error = CKR_SESSION_HANDLE_INVALID;
02165     goto loser;
02166   }
02167 
02168   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
02169   if( (NSSCKFWObject *)NULL == fwObject ) {
02170     error = CKR_OBJECT_HANDLE_INVALID;
02171     goto loser;
02172   }
02173 
02174   if( (CK_ULONG_PTR)CK_NULL_PTR == pulSize ) {
02175     error = CKR_ARGUMENTS_BAD;
02176     goto loser;
02177   }
02178 
02179   /*
02180    * A purify error here indicates caller error.
02181    */
02182   *pulSize = (CK_ULONG)0;
02183 
02184   *pulSize = nssCKFWObject_GetObjectSize(fwObject, &error);
02185   if( ((CK_ULONG)0 == *pulSize) && (CKR_OK != error) ) {
02186     goto loser;
02187   }
02188 
02189   return CKR_OK;
02190 
02191  loser:
02192   switch( error ) {
02193   case CKR_SESSION_CLOSED:
02194     /* destroy session? */
02195     break;
02196   case CKR_DEVICE_REMOVED:
02197     /* (void)nssCKFWToken_Destroy(fwToken); */
02198     break;
02199   case CKR_CRYPTOKI_NOT_INITIALIZED:
02200   case CKR_DEVICE_ERROR:
02201   case CKR_DEVICE_MEMORY:
02202   case CKR_FUNCTION_FAILED:
02203   case CKR_GENERAL_ERROR:
02204   case CKR_HOST_MEMORY:
02205   case CKR_INFORMATION_SENSITIVE:
02206   case CKR_OBJECT_HANDLE_INVALID:
02207   case CKR_SESSION_HANDLE_INVALID:
02208     break;
02209   default:
02210   case CKR_OK:
02211     error = CKR_GENERAL_ERROR;
02212     break;
02213   }
02214 
02215   return error;
02216 }
02217 
02218 /*
02219  * NSSCKFWC_GetAttributeValue
02220  *
02221  */
02222 NSS_IMPLEMENT CK_RV
02223 NSSCKFWC_GetAttributeValue
02224 (
02225   NSSCKFWInstance *fwInstance,
02226   CK_SESSION_HANDLE hSession,
02227   CK_OBJECT_HANDLE hObject,
02228   CK_ATTRIBUTE_PTR pTemplate,
02229   CK_ULONG ulCount
02230 )
02231 {
02232   CK_RV error = CKR_OK;
02233   NSSCKFWSession *fwSession;
02234   NSSCKFWObject *fwObject;
02235   CK_BBOOL sensitive = CK_FALSE;
02236   CK_BBOOL invalid = CK_FALSE;
02237   CK_BBOOL tooSmall = CK_FALSE;
02238   CK_ULONG i;
02239 
02240   if( (NSSCKFWInstance *)NULL == fwInstance ) {
02241     error = CKR_CRYPTOKI_NOT_INITIALIZED;
02242     goto loser;
02243   }
02244   
02245   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
02246   if( (NSSCKFWSession *)NULL == fwSession ) {
02247     error = CKR_SESSION_HANDLE_INVALID;
02248     goto loser;
02249   }
02250 
02251   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
02252   if( (NSSCKFWObject *)NULL == fwObject ) {
02253     error = CKR_OBJECT_HANDLE_INVALID;
02254     goto loser;
02255   }
02256 
02257   if( (CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate ) {
02258     error = CKR_ARGUMENTS_BAD;
02259     goto loser;
02260   }
02261 
02262   for( i = 0; i < ulCount; i++ ) {
02263     CK_ULONG size = nssCKFWObject_GetAttributeSize(fwObject, 
02264                       pTemplate[i].type, &error);
02265     if( (CK_ULONG)0 == size ) {
02266       switch( error ) {
02267       case CKR_ATTRIBUTE_SENSITIVE:
02268       case CKR_INFORMATION_SENSITIVE:
02269         sensitive = CK_TRUE;
02270         pTemplate[i].ulValueLen = (CK_ULONG)(-1);
02271         continue;
02272       case CKR_ATTRIBUTE_TYPE_INVALID:
02273         invalid = CK_TRUE;
02274         pTemplate[i].ulValueLen = (CK_ULONG)(-1);
02275         continue;
02276       case CKR_OK:
02277         break;
02278       default:
02279         goto loser;
02280       }
02281     }
02282 
02283     if( (CK_VOID_PTR)CK_NULL_PTR == pTemplate[i].pValue ) {
02284       pTemplate[i].ulValueLen = size;
02285     } else {
02286       NSSItem it, *p;
02287 
02288       if( pTemplate[i].ulValueLen < size ) {
02289         tooSmall = CK_TRUE;
02290         continue;
02291       }
02292 
02293       it.size = (PRUint32)pTemplate[i].ulValueLen;
02294       it.data = (void *)pTemplate[i].pValue;
02295       p = nssCKFWObject_GetAttribute(fwObject, pTemplate[i].type, &it, 
02296             (NSSArena *)NULL, &error);
02297       if( (NSSItem *)NULL == p ) {
02298         switch( error ) {
02299         case CKR_ATTRIBUTE_SENSITIVE:
02300         case CKR_INFORMATION_SENSITIVE:
02301           sensitive = CK_TRUE;
02302           pTemplate[i].ulValueLen = (CK_ULONG)(-1);
02303           continue;
02304         case CKR_ATTRIBUTE_TYPE_INVALID:
02305           invalid = CK_TRUE;
02306           pTemplate[i].ulValueLen = (CK_ULONG)(-1);
02307           continue;
02308         default:
02309           goto loser;
02310         }
02311       }
02312 
02313       pTemplate[i].ulValueLen = size;
02314     }
02315   }
02316 
02317   if( sensitive ) {
02318     error = CKR_ATTRIBUTE_SENSITIVE;
02319     goto loser;
02320   } else if( invalid ) {
02321     error = CKR_ATTRIBUTE_TYPE_INVALID;
02322     goto loser;
02323   } else if( tooSmall ) {
02324     error = CKR_BUFFER_TOO_SMALL;
02325     goto loser;
02326   }
02327 
02328   return CKR_OK;
02329 
02330  loser:
02331   switch( error ) {
02332   case CKR_SESSION_CLOSED:
02333     /* destroy session? */
02334     break;
02335   case CKR_DEVICE_REMOVED:
02336     /* (void)nssCKFWToken_Destroy(fwToken); */
02337     break;
02338   case CKR_ATTRIBUTE_SENSITIVE:
02339   case CKR_ATTRIBUTE_TYPE_INVALID:
02340   case CKR_BUFFER_TOO_SMALL:
02341   case CKR_CRYPTOKI_NOT_INITIALIZED:
02342   case CKR_DEVICE_ERROR:
02343   case CKR_DEVICE_MEMORY:
02344   case CKR_FUNCTION_FAILED:
02345   case CKR_GENERAL_ERROR:
02346   case CKR_HOST_MEMORY:
02347   case CKR_OBJECT_HANDLE_INVALID:
02348   case CKR_SESSION_HANDLE_INVALID:
02349     break;
02350   default:
02351   case CKR_OK:
02352     error = CKR_GENERAL_ERROR;
02353     break;
02354   }
02355 
02356   return error;
02357 }
02358   
02359 /*
02360  * NSSCKFWC_SetAttributeValue
02361  *
02362  */
02363 NSS_IMPLEMENT CK_RV
02364 NSSCKFWC_SetAttributeValue
02365 (
02366   NSSCKFWInstance *fwInstance,
02367   CK_SESSION_HANDLE hSession,
02368   CK_OBJECT_HANDLE hObject,
02369   CK_ATTRIBUTE_PTR pTemplate,
02370   CK_ULONG ulCount
02371 )
02372 {
02373   CK_RV error = CKR_OK;
02374   NSSCKFWSession *fwSession;
02375   NSSCKFWObject *fwObject;
02376   NSSCKFWObject *newFwObject;
02377 
02378   if( (NSSCKFWInstance *)NULL == fwInstance ) {
02379     error = CKR_CRYPTOKI_NOT_INITIALIZED;
02380     goto loser;
02381   }
02382   
02383   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
02384   if( (NSSCKFWSession *)NULL == fwSession ) {
02385     error = CKR_SESSION_HANDLE_INVALID;
02386     goto loser;
02387   }
02388 
02389   fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
02390   if( (NSSCKFWObject *)NULL == fwObject ) {
02391     error = CKR_OBJECT_HANDLE_INVALID;
02392     goto loser;
02393   }
02394 
02395   if( (CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate ) {
02396     error = CKR_ARGUMENTS_BAD;
02397     goto loser;
02398   }
02399 
02400   newFwObject = nssCKFWSession_CopyObject(fwSession, fwObject, pTemplate, 
02401                   ulCount, &error);
02402   if( (NSSCKFWObject *)NULL == newFwObject ) {
02403     goto loser;
02404   }
02405 
02406   error = nssCKFWInstance_ReassignObjectHandle(fwInstance, hObject, newFwObject);
02407   nssCKFWObject_Destroy(fwObject);
02408 
02409   if( CKR_OK != error ) {
02410     goto loser;
02411   }
02412 
02413   return CKR_OK;
02414 
02415  loser:
02416   switch( error ) {
02417   case CKR_SESSION_CLOSED:
02418     /* destroy session? */
02419     break;
02420   case CKR_DEVICE_REMOVED:
02421     /* (void)nssCKFWToken_Destroy(fwToken); */
02422     break;
02423   case CKR_ATTRIBUTE_READ_ONLY:
02424   case CKR_ATTRIBUTE_TYPE_INVALID:
02425   case CKR_ATTRIBUTE_VALUE_INVALID:
02426   case CKR_CRYPTOKI_NOT_INITIALIZED:
02427   case CKR_DEVICE_ERROR:
02428   case CKR_DEVICE_MEMORY:
02429   case CKR_FUNCTION_FAILED:
02430   case CKR_GENERAL_ERROR:
02431   case CKR_HOST_MEMORY:
02432   case CKR_OBJECT_HANDLE_INVALID:
02433   case CKR_SESSION_HANDLE_INVALID:
02434   case CKR_SESSION_READ_ONLY:
02435   case CKR_TEMPLATE_INCONSISTENT:
02436   case CKR_TOKEN_WRITE_PROTECTED:
02437     break;
02438   default:
02439   case CKR_OK:
02440     error = CKR_GENERAL_ERROR;
02441     break;
02442   }
02443 
02444   return error;
02445 }
02446 
02447 /*
02448  * NSSCKFWC_FindObjectsInit
02449  *
02450  */
02451 NSS_IMPLEMENT CK_RV
02452 NSSCKFWC_FindObjectsInit
02453 (
02454   NSSCKFWInstance *fwInstance,
02455   CK_SESSION_HANDLE hSession,
02456   CK_ATTRIBUTE_PTR pTemplate,
02457   CK_ULONG ulCount
02458 )
02459 {
02460   CK_RV error = CKR_OK;
02461   NSSCKFWSession *fwSession;
02462   NSSCKFWFindObjects *fwFindObjects;
02463 
02464   if( (NSSCKFWInstance *)NULL == fwInstance ) {
02465     error = CKR_CRYPTOKI_NOT_INITIALIZED;
02466     goto loser;
02467   }
02468   
02469   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
02470   if( (NSSCKFWSession *)NULL == fwSession ) {
02471     error = CKR_SESSION_HANDLE_INVALID;
02472     goto loser;
02473   }
02474 
02475   if( ((CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate) && (ulCount != 0) ) {
02476     error = CKR_ARGUMENTS_BAD;
02477     goto loser;
02478   }
02479 
02480   fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error);
02481   if( (NSSCKFWFindObjects *)NULL != fwFindObjects ) {
02482     error = CKR_OPERATION_ACTIVE;
02483     goto loser;
02484   }
02485 
02486   if( CKR_OPERATION_NOT_INITIALIZED != error ) {
02487     goto loser;
02488   }
02489 
02490   fwFindObjects = nssCKFWSession_FindObjectsInit(fwSession,
02491                     pTemplate, ulCount, &error);
02492   if( (NSSCKFWFindObjects *)NULL == fwFindObjects ) {
02493     goto loser;
02494   }
02495 
02496   error = nssCKFWSession_SetFWFindObjects(fwSession, fwFindObjects);
02497 
02498   if( CKR_OK != error ) {
02499     nssCKFWFindObjects_Destroy(fwFindObjects);
02500     goto loser;
02501   }
02502 
02503   return CKR_OK;
02504 
02505  loser:
02506   switch( error ) {
02507   case CKR_SESSION_CLOSED:
02508     /* destroy session? */
02509     break;
02510   case CKR_DEVICE_REMOVED:
02511     /* (void)nssCKFWToken_Destroy(fwToken); */
02512     break;
02513   case CKR_ATTRIBUTE_TYPE_INVALID:
02514   case CKR_ATTRIBUTE_VALUE_INVALID:
02515   case CKR_CRYPTOKI_NOT_INITIALIZED:
02516   case CKR_DEVICE_ERROR:
02517   case CKR_DEVICE_MEMORY:
02518   case CKR_FUNCTION_FAILED:
02519   case CKR_GENERAL_ERROR:
02520   case CKR_HOST_MEMORY:
02521   case CKR_OPERATION_ACTIVE:
02522   case CKR_SESSION_HANDLE_INVALID:
02523     break;
02524   default:
02525   case CKR_OK:
02526     error = CKR_GENERAL_ERROR;
02527     break;
02528   }
02529 
02530   return error;
02531 }
02532 
02533 /*
02534  * NSSCKFWC_FindObjects
02535  *
02536  */
02537 NSS_IMPLEMENT CK_RV
02538 NSSCKFWC_FindObjects
02539 (
02540   NSSCKFWInstance *fwInstance,
02541   CK_SESSION_HANDLE hSession,
02542   CK_OBJECT_HANDLE_PTR phObject,
02543   CK_ULONG ulMaxObjectCount,
02544   CK_ULONG_PTR pulObjectCount
02545 )
02546 {
02547   CK_RV error = CKR_OK;
02548   NSSCKFWSession *fwSession;
02549   NSSCKFWFindObjects *fwFindObjects;
02550   CK_ULONG i;
02551 
02552   if( (NSSCKFWInstance *)NULL == fwInstance ) {
02553     error = CKR_CRYPTOKI_NOT_INITIALIZED;
02554     goto loser;
02555   }
02556   
02557   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
02558   if( (NSSCKFWSession *)NULL == fwSession ) {
02559     error = CKR_SESSION_HANDLE_INVALID;
02560     goto loser;
02561   }
02562 
02563   if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phObject ) {
02564     error = CKR_ARGUMENTS_BAD;
02565     goto loser;
02566   }
02567 
02568   /*
02569    * A purify error here indicates caller error.
02570    */
02571   (void)nsslibc_memset(phObject, 0, sizeof(CK_OBJECT_HANDLE) * ulMaxObjectCount);
02572   *pulObjectCount = (CK_ULONG)0;
02573 
02574   fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error);
02575   if( (NSSCKFWFindObjects *)NULL == fwFindObjects ) {
02576     goto loser;
02577   }
02578 
02579   for( i = 0; i < ulMaxObjectCount; i++ ) {
02580     NSSCKFWObject *fwObject = nssCKFWFindObjects_Next(fwFindObjects,
02581                                 NULL, &error);
02582     if( (NSSCKFWObject *)NULL == fwObject ) {
02583       break;
02584     }
02585 
02586     phObject[i] = nssCKFWInstance_FindObjectHandle(fwInstance, fwObject);
02587     if( (CK_OBJECT_HANDLE)0 == phObject[i] ) {
02588       phObject[i] = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
02589     }
02590     if( (CK_OBJECT_HANDLE)0 == phObject[i] ) {
02591       /* This isn't right either, is it? */
02592       nssCKFWObject_Destroy(fwObject);
02593       goto loser;
02594     }
02595   }
02596 
02597   *pulObjectCount = i;
02598 
02599   return CKR_OK;
02600 
02601  loser:
02602   switch( error ) {
02603   case CKR_SESSION_CLOSED:
02604     /* destroy session? */
02605     break;
02606   case CKR_DEVICE_REMOVED:
02607     /* (void)nssCKFWToken_Destroy(fwToken); */
02608     break;
02609   case CKR_CRYPTOKI_NOT_INITIALIZED:
02610   case CKR_DEVICE_ERROR:
02611   case CKR_DEVICE_MEMORY:
02612   case CKR_FUNCTION_FAILED:
02613   case CKR_GENERAL_ERROR:
02614   case CKR_HOST_MEMORY:
02615   case CKR_OPERATION_NOT_INITIALIZED:
02616   case CKR_SESSION_HANDLE_INVALID:
02617     break;
02618   default:
02619   case CKR_OK:
02620     error = CKR_GENERAL_ERROR;
02621     break;
02622   }
02623 
02624   return error;
02625 }
02626 
02627 /*
02628  * NSSCKFWC_FindObjectsFinal
02629  *
02630  */
02631 NSS_IMPLEMENT CK_RV
02632 NSSCKFWC_FindObjectsFinal
02633 (
02634   NSSCKFWInstance *fwInstance,
02635   CK_SESSION_HANDLE hSession
02636 )
02637 {
02638   CK_RV error = CKR_OK;
02639   NSSCKFWSession *fwSession;
02640   NSSCKFWFindObjects *fwFindObjects;
02641   
02642   if( (NSSCKFWInstance *)NULL == fwInstance ) {
02643     error = CKR_CRYPTOKI_NOT_INITIALIZED;
02644     goto loser;
02645   }
02646   
02647   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
02648   if( (NSSCKFWSession *)NULL == fwSession ) {
02649     error = CKR_SESSION_HANDLE_INVALID;
02650     goto loser;
02651   }
02652 
02653   fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error);
02654   if( (NSSCKFWFindObjects *)NULL == fwFindObjects ) {
02655     error = CKR_OPERATION_NOT_INITIALIZED;
02656     goto loser;
02657   }
02658 
02659   nssCKFWFindObjects_Destroy(fwFindObjects);
02660   error = nssCKFWSession_SetFWFindObjects(fwSession, (NSSCKFWFindObjects *)NULL);
02661 
02662   if( CKR_OK != error ) {
02663     goto loser;
02664   }
02665 
02666   return CKR_OK;
02667 
02668  loser:
02669   switch( error ) {
02670   case CKR_SESSION_CLOSED:
02671     /* destroy session? */
02672     break;
02673   case CKR_DEVICE_REMOVED:
02674     /* (void)nssCKFWToken_Destroy(fwToken); */
02675     break;
02676   case CKR_CRYPTOKI_NOT_INITIALIZED:
02677   case CKR_DEVICE_ERROR:
02678   case CKR_DEVICE_MEMORY:
02679   case CKR_FUNCTION_FAILED:
02680   case CKR_GENERAL_ERROR:
02681   case CKR_HOST_MEMORY:
02682   case CKR_OPERATION_NOT_INITIALIZED:
02683   case CKR_SESSION_HANDLE_INVALID:
02684     break;
02685   default:
02686   case CKR_OK:
02687     error = CKR_GENERAL_ERROR;
02688     break;
02689   }
02690 
02691   return error;
02692 }
02693 
02694 /*
02695  * NSSCKFWC_EncryptInit
02696  *
02697  */
02698 NSS_IMPLEMENT CK_RV
02699 NSSCKFWC_EncryptInit
02700 (
02701   NSSCKFWInstance *fwInstance,
02702   CK_SESSION_HANDLE hSession,
02703   CK_MECHANISM_PTR pMechanism,
02704   CK_OBJECT_HANDLE hKey
02705 )
02706 {
02707   return CKR_FUNCTION_FAILED;
02708 }
02709 
02710 /*
02711  * NSSCKFWC_Encrypt
02712  *
02713  */
02714 NSS_IMPLEMENT CK_RV
02715 NSSCKFWC_Encrypt
02716 (
02717   NSSCKFWInstance *fwInstance,
02718   CK_SESSION_HANDLE hSession,
02719   CK_BYTE_PTR pData,
02720   CK_ULONG ulDataLen,
02721   CK_BYTE_PTR pEncryptedData,
02722   CK_ULONG_PTR pulEncryptedDataLen
02723 )
02724 {
02725   return CKR_FUNCTION_FAILED;
02726 }
02727 
02728 /*
02729  * NSSCKFWC_EncryptUpdate
02730  *
02731  */
02732 NSS_IMPLEMENT CK_RV
02733 NSSCKFWC_EncryptUpdate
02734 (
02735   NSSCKFWInstance *fwInstance,
02736   CK_SESSION_HANDLE hSession,
02737   CK_BYTE_PTR pPart,
02738   CK_ULONG ulPartLen,
02739   CK_BYTE_PTR pEncryptedPart,
02740   CK_ULONG_PTR pulEncryptedPartLen
02741 )
02742 {
02743   return CKR_FUNCTION_FAILED;
02744 }
02745 
02746 /*
02747  * NSSCKFWC_EncryptFinal
02748  *
02749  */
02750 NSS_IMPLEMENT CK_RV
02751 NSSCKFWC_EncryptFinal
02752 (
02753   NSSCKFWInstance *fwInstance,
02754   CK_SESSION_HANDLE hSession,
02755   CK_BYTE_PTR pLastEncryptedPart,
02756   CK_ULONG_PTR pulLastEncryptedPartLen
02757 )
02758 {
02759   return CKR_FUNCTION_FAILED;
02760 }
02761 
02762 /*
02763  * NSSCKFWC_DecryptInit
02764  *
02765  */
02766 NSS_IMPLEMENT CK_RV
02767 NSSCKFWC_DecryptInit
02768 (
02769   NSSCKFWInstance *fwInstance,
02770   CK_SESSION_HANDLE hSession,
02771   CK_MECHANISM_PTR pMechanism,
02772   CK_OBJECT_HANDLE hKey
02773 )
02774 {
02775   return CKR_FUNCTION_FAILED;
02776 }
02777 
02778 /*
02779  * NSSCKFWC_Decrypt
02780  *
02781  */
02782 NSS_IMPLEMENT CK_RV
02783 NSSCKFWC_Decrypt
02784 (
02785   NSSCKFWInstance *fwInstance,
02786   CK_SESSION_HANDLE hSession,
02787   CK_BYTE_PTR pEncryptedData,
02788   CK_ULONG ulEncryptedDataLen,
02789   CK_BYTE_PTR pData,
02790   CK_ULONG_PTR pulDataLen
02791 )
02792 {
02793   return CKR_FUNCTION_FAILED;
02794 }
02795 
02796 /*
02797  * NSSCKFWC_DecryptUpdate
02798  *
02799  */
02800 NSS_IMPLEMENT CK_RV
02801 NSSCKFWC_DecryptUpdate
02802 (
02803   NSSCKFWInstance *fwInstance,
02804   CK_SESSION_HANDLE hSession,
02805   CK_BYTE_PTR pEncryptedPart,
02806   CK_ULONG ulEncryptedPartLen,
02807   CK_BYTE_PTR pPart,
02808   CK_ULONG_PTR pulPartLen
02809 )
02810 {
02811   return CKR_FUNCTION_FAILED;
02812 }
02813 
02814 /*
02815  * NSSCKFWC_DecryptFinal
02816  *
02817  */
02818 NSS_IMPLEMENT CK_RV
02819 NSSCKFWC_DecryptFinal
02820 (
02821   NSSCKFWInstance *fwInstance,
02822   CK_SESSION_HANDLE hSession,
02823   CK_BYTE_PTR pLastPart,
02824   CK_ULONG_PTR pulLastPartLen
02825 )
02826 {
02827   return CKR_FUNCTION_FAILED;
02828 }
02829 
02830 /*
02831  * NSSCKFWC_DigestInit
02832  *
02833  */
02834 NSS_IMPLEMENT CK_RV
02835 NSSCKFWC_DigestInit
02836 (
02837   NSSCKFWInstance *fwInstance,
02838   CK_SESSION_HANDLE hSession,
02839   CK_MECHANISM_PTR pMechanism
02840 )
02841 {
02842   return CKR_FUNCTION_FAILED;
02843 }
02844 
02845 /*
02846  * NSSCKFWC_Digest
02847  *
02848  */
02849 NSS_IMPLEMENT CK_RV
02850 NSSCKFWC_Digest
02851 (
02852   NSSCKFWInstance *fwInstance,
02853   CK_SESSION_HANDLE hSession,
02854   CK_BYTE_PTR pData,
02855   CK_ULONG ulDataLen,
02856   CK_BYTE_PTR pDigest,
02857   CK_ULONG_PTR pulDigestLen
02858 )
02859 {
02860   return CKR_FUNCTION_FAILED;
02861 }
02862 
02863 /*
02864  * NSSCKFWC_DigestUpdate
02865  *
02866  */
02867 NSS_IMPLEMENT CK_RV
02868 NSSCKFWC_DigestUpdate
02869 (
02870   NSSCKFWInstance *fwInstance,
02871   CK_SESSION_HANDLE hSession,
02872   CK_BYTE_PTR pData,
02873   CK_ULONG ulDataLen
02874 )
02875 {
02876   return CKR_FUNCTION_FAILED;
02877 }
02878 
02879 /*
02880  * NSSCKFWC_DigestKey
02881  *
02882  */
02883 NSS_IMPLEMENT CK_RV
02884 NSSCKFWC_DigestKey
02885 (
02886   NSSCKFWInstance *fwInstance,
02887   CK_SESSION_HANDLE hSession,
02888   CK_OBJECT_HANDLE hKey
02889 )
02890 {
02891   return CKR_FUNCTION_FAILED;
02892 }
02893 
02894 /*
02895  * NSSCKFWC_DigestFinal
02896  *
02897  */
02898 NSS_IMPLEMENT CK_RV
02899 NSSCKFWC_DigestFinal
02900 (
02901   NSSCKFWInstance *fwInstance,
02902   CK_SESSION_HANDLE hSession,
02903   CK_BYTE_PTR pDigest,
02904   CK_ULONG_PTR pulDigestLen
02905 )
02906 {
02907   return CKR_FUNCTION_FAILED;
02908 }
02909 
02910 /*
02911  * NSSCKFWC_SignInit
02912  *
02913  */
02914 NSS_IMPLEMENT CK_RV
02915 NSSCKFWC_SignInit
02916 (
02917   NSSCKFWInstance *fwInstance,
02918   CK_SESSION_HANDLE hSession,
02919   CK_MECHANISM_PTR pMechanism,
02920   CK_OBJECT_HANDLE hKey
02921 )
02922 {
02923   return CKR_FUNCTION_FAILED;
02924 }
02925 
02926 /*
02927  * NSSCKFWC_Sign
02928  *
02929  */
02930 NSS_IMPLEMENT CK_RV
02931 NSSCKFWC_Sign
02932 (
02933   NSSCKFWInstance *fwInstance,
02934   CK_SESSION_HANDLE hSession,
02935   CK_BYTE_PTR pData,
02936   CK_ULONG ulDataLen,
02937   CK_BYTE_PTR pSignature,
02938   CK_ULONG_PTR pulSignatureLen
02939 )
02940 {
02941   return CKR_FUNCTION_FAILED;
02942 }
02943 
02944 /*
02945  * NSSCKFWC_SignUpdate
02946  *
02947  */
02948 NSS_IMPLEMENT CK_RV
02949 NSSCKFWC_SignUpdate
02950 (
02951   NSSCKFWInstance *fwInstance,
02952   CK_SESSION_HANDLE hSession,
02953   CK_BYTE_PTR pPart,
02954   CK_ULONG ulPartLen
02955 )
02956 {
02957   return CKR_FUNCTION_FAILED;
02958 }
02959 
02960 /*
02961  * NSSCKFWC_SignFinal
02962  *
02963  */
02964 NSS_IMPLEMENT CK_RV
02965 NSSCKFWC_SignFinal
02966 (
02967   NSSCKFWInstance *fwInstance,
02968   CK_SESSION_HANDLE hSession,
02969   CK_BYTE_PTR pSignature,
02970   CK_ULONG_PTR pulSignatureLen
02971 )
02972 {
02973   return CKR_FUNCTION_FAILED;
02974 }
02975 
02976 /*
02977  * NSSCKFWC_SignRecoverInit
02978  *
02979  */
02980 NSS_IMPLEMENT CK_RV
02981 NSSCKFWC_SignRecoverInit
02982 (
02983   NSSCKFWInstance *fwInstance,
02984   CK_SESSION_HANDLE hSession,
02985   CK_MECHANISM_PTR pMechanism,
02986   CK_OBJECT_HANDLE hKey
02987 )
02988 {
02989   return CKR_FUNCTION_FAILED;
02990 }
02991 
02992 /*
02993  * NSSCKFWC_SignRecover
02994  *
02995  */
02996 NSS_IMPLEMENT CK_RV
02997 NSSCKFWC_SignRecover
02998 (
02999   NSSCKFWInstance *fwInstance,
03000   CK_SESSION_HANDLE hSession,
03001   CK_BYTE_PTR pData,
03002   CK_ULONG ulDataLen,
03003   CK_BYTE_PTR pSignature,
03004   CK_ULONG_PTR pulSignatureLen
03005 )
03006 {
03007   return CKR_FUNCTION_FAILED;
03008 }
03009 
03010 /*
03011  * NSSCKFWC_VerifyInit
03012  *
03013  */
03014 NSS_IMPLEMENT CK_RV
03015 NSSCKFWC_VerifyInit
03016 (
03017   NSSCKFWInstance *fwInstance,
03018   CK_SESSION_HANDLE hSession,
03019   CK_MECHANISM_PTR pMechanism,
03020   CK_OBJECT_HANDLE hKey
03021 )
03022 {
03023   return CKR_FUNCTION_FAILED;
03024 }
03025 
03026 /*
03027  * NSSCKFWC_Verify
03028  *
03029  */
03030 NSS_IMPLEMENT CK_RV
03031 NSSCKFWC_Verify
03032 (
03033   NSSCKFWInstance *fwInstance,
03034   CK_SESSION_HANDLE hSession,
03035   CK_BYTE_PTR pData,
03036   CK_ULONG ulDataLen,
03037   CK_BYTE_PTR pSignature,
03038   CK_ULONG ulSignatureLen
03039 )
03040 {
03041   return CKR_FUNCTION_FAILED;
03042 }
03043 
03044 /*
03045  * NSSCKFWC_VerifyUpdate
03046  *
03047  */
03048 NSS_IMPLEMENT CK_RV
03049 NSSCKFWC_VerifyUpdate
03050 (
03051   NSSCKFWInstance *fwInstance,
03052   CK_SESSION_HANDLE hSession,
03053   CK_BYTE_PTR pPart,
03054   CK_ULONG ulPartLen
03055 )
03056 {
03057   return CKR_FUNCTION_FAILED;
03058 }
03059 
03060 /*
03061  * NSSCKFWC_VerifyFinal
03062  *
03063  */
03064 NSS_IMPLEMENT CK_RV
03065 NSSCKFWC_VerifyFinal
03066 (
03067   NSSCKFWInstance *fwInstance,
03068   CK_SESSION_HANDLE hSession,
03069   CK_BYTE_PTR pSignature,
03070   CK_ULONG ulSignatureLen
03071 )
03072 {
03073   return CKR_FUNCTION_FAILED;
03074 }
03075 
03076 /*
03077  * NSSCKFWC_VerifyRecoverInit
03078  *
03079  */
03080 NSS_IMPLEMENT CK_RV
03081 NSSCKFWC_VerifyRecoverInit
03082 (
03083   NSSCKFWInstance *fwInstance,
03084   CK_SESSION_HANDLE hSession,
03085   CK_MECHANISM_PTR pMechanism,
03086   CK_OBJECT_HANDLE hKey
03087 )
03088 {
03089   return CKR_FUNCTION_FAILED;
03090 }
03091 
03092 /*
03093  * NSSCKFWC_VerifyRecover
03094  *
03095  */
03096 NSS_IMPLEMENT CK_RV
03097 NSSCKFWC_VerifyRecover
03098 (
03099   NSSCKFWInstance *fwInstance,
03100   CK_SESSION_HANDLE hSession,
03101   CK_BYTE_PTR pSignature,
03102   CK_ULONG ulSignatureLen,
03103   CK_BYTE_PTR pData,
03104   CK_ULONG_PTR pulDataLen
03105 )
03106 {
03107   return CKR_FUNCTION_FAILED;
03108 }
03109 
03110 /*
03111  * NSSCKFWC_DigestEncryptUpdate
03112  *
03113  */
03114 NSS_IMPLEMENT CK_RV
03115 NSSCKFWC_DigestEncryptUpdate
03116 (
03117   NSSCKFWInstance *fwInstance,
03118   CK_SESSION_HANDLE hSession,
03119   CK_BYTE_PTR pPart,
03120   CK_ULONG ulPartLen,
03121   CK_BYTE_PTR pEncryptedPart,
03122   CK_ULONG_PTR pulEncryptedPartLen
03123 )
03124 {
03125   return CKR_FUNCTION_FAILED;
03126 }
03127 
03128 /*
03129  * NSSCKFWC_DecryptDigestUpdate
03130  *
03131  */
03132 NSS_IMPLEMENT CK_RV
03133 NSSCKFWC_DecryptDigestUpdate
03134 (
03135   NSSCKFWInstance *fwInstance,
03136   CK_SESSION_HANDLE hSession,
03137   CK_BYTE_PTR pEncryptedPart,
03138   CK_ULONG ulEncryptedPartLen,
03139   CK_BYTE_PTR pPart,
03140   CK_ULONG_PTR pulPartLen
03141 )
03142 {
03143   return CKR_FUNCTION_FAILED;
03144 }
03145 
03146 /*
03147  * NSSCKFWC_SignEncryptUpdate
03148  *
03149  */
03150 NSS_IMPLEMENT CK_RV
03151 NSSCKFWC_SignEncryptUpdate
03152 (
03153   NSSCKFWInstance *fwInstance,
03154   CK_SESSION_HANDLE hSession,
03155   CK_BYTE_PTR pPart,
03156   CK_ULONG ulPartLen,
03157   CK_BYTE_PTR pEncryptedPart,
03158   CK_ULONG_PTR pulEncryptedPartLen
03159 )
03160 {
03161   return CKR_FUNCTION_FAILED;
03162 }
03163 
03164 /*
03165  * NSSCKFWC_DecryptVerifyUpdate
03166  *
03167  */
03168 NSS_IMPLEMENT CK_RV
03169 NSSCKFWC_DecryptVerifyUpdate
03170 (
03171   NSSCKFWInstance *fwInstance,
03172   CK_SESSION_HANDLE hSession,
03173   CK_BYTE_PTR pEncryptedPart,
03174   CK_ULONG ulEncryptedPartLen,
03175   CK_BYTE_PTR pPart,
03176   CK_ULONG_PTR pulPartLen
03177 )
03178 {
03179   return CKR_FUNCTION_FAILED;
03180 }
03181 
03182 /*
03183  * NSSCKFWC_GenerateKey
03184  *
03185  */
03186 NSS_IMPLEMENT CK_RV
03187 NSSCKFWC_GenerateKey
03188 (
03189   NSSCKFWInstance *fwInstance,
03190   CK_SESSION_HANDLE hSession,
03191   CK_MECHANISM_PTR pMechanism,
03192   CK_ATTRIBUTE_PTR pTemplate,
03193   CK_ULONG ulCount,
03194   CK_OBJECT_HANDLE_PTR phKey
03195 )
03196 {
03197   return CKR_FUNCTION_FAILED;
03198 }
03199 
03200 /*
03201  * NSSCKFWC_GenerateKeyPair
03202  *
03203  */
03204 NSS_IMPLEMENT CK_RV
03205 NSSCKFWC_GenerateKeyPair
03206 (
03207   NSSCKFWInstance *fwInstance,
03208   CK_SESSION_HANDLE hSession,
03209   CK_MECHANISM_PTR pMechanism,
03210   CK_ATTRIBUTE_PTR pPublicKeyTemplate,
03211   CK_ULONG ulPublicKeyAttributeCount,
03212   CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
03213   CK_ULONG ulPrivateKeyAttributeCount,
03214   CK_OBJECT_HANDLE_PTR phPublicKey,
03215   CK_OBJECT_HANDLE_PTR phPrivateKey
03216 )
03217 {
03218   return CKR_FUNCTION_FAILED;
03219 }
03220 
03221 /*
03222  * NSSCKFWC_WrapKey
03223  *
03224  */
03225 NSS_IMPLEMENT CK_RV
03226 NSSCKFWC_WrapKey
03227 (
03228   NSSCKFWInstance *fwInstance,
03229   CK_SESSION_HANDLE hSession,
03230   CK_MECHANISM_PTR pMechanism,
03231   CK_OBJECT_HANDLE hWrappingKey,
03232   CK_OBJECT_HANDLE hKey,
03233   CK_BYTE_PTR pWrappedKey,
03234   CK_ULONG_PTR pulWrappedKeyLen
03235 )
03236 {
03237   return CKR_FUNCTION_FAILED;
03238 }
03239 
03240 /*
03241  * NSSCKFWC_UnwrapKey
03242  *
03243  */
03244 NSS_IMPLEMENT CK_RV
03245 NSSCKFWC_UnwrapKey
03246 (
03247   NSSCKFWInstance *fwInstance,
03248   CK_SESSION_HANDLE hSession,
03249   CK_MECHANISM_PTR pMechanism,
03250   CK_OBJECT_HANDLE hUnwrappingKey,
03251   CK_BYTE_PTR pWrappedKey,
03252   CK_ULONG ulWrappedKeyLen,
03253   CK_ATTRIBUTE_PTR pTemplate,
03254   CK_ULONG ulAttributeCount,
03255   CK_OBJECT_HANDLE_PTR phKey
03256 )
03257 {
03258   return CKR_FUNCTION_FAILED;
03259 }
03260 
03261 /*
03262  * NSSCKFWC_DeriveKey
03263  *
03264  */
03265 NSS_IMPLEMENT CK_RV
03266 NSSCKFWC_DeriveKey
03267 (
03268   NSSCKFWInstance *fwInstance,
03269   CK_SESSION_HANDLE hSession,
03270   CK_MECHANISM_PTR pMechanism,
03271   CK_OBJECT_HANDLE hBaseKey,
03272   CK_ATTRIBUTE_PTR pTemplate,
03273   CK_ULONG ulAttributeCount,
03274   CK_OBJECT_HANDLE_PTR phKey
03275 )
03276 {
03277   return CKR_FUNCTION_FAILED;
03278 }
03279 
03280 /*
03281  * NSSCKFWC_SeedRandom
03282  *
03283  */
03284 NSS_IMPLEMENT CK_RV
03285 NSSCKFWC_SeedRandom
03286 (
03287   NSSCKFWInstance *fwInstance,
03288   CK_SESSION_HANDLE hSession,
03289   CK_BYTE_PTR pSeed,
03290   CK_ULONG ulSeedLen
03291 )
03292 {
03293   CK_RV error = CKR_OK;
03294   NSSCKFWSession *fwSession;
03295   NSSItem seed;
03296 
03297   if( (NSSCKFWInstance *)NULL == fwInstance ) {
03298     error = CKR_CRYPTOKI_NOT_INITIALIZED;
03299     goto loser;
03300   }
03301 
03302   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
03303   if( (NSSCKFWSession *)NULL == fwSession ) {
03304     error = CKR_SESSION_HANDLE_INVALID;
03305     goto loser;
03306   }
03307 
03308   if( (CK_BYTE_PTR)CK_NULL_PTR == pSeed ) {
03309     error = CKR_ARGUMENTS_BAD;
03310     goto loser;
03311   }
03312 
03313   /* We could read through the buffer in a Purify trap */
03314 
03315   seed.size = (PRUint32)ulSeedLen;
03316   seed.data = (void *)pSeed;
03317 
03318   error = nssCKFWSession_SeedRandom(fwSession, &seed);
03319 
03320   if( CKR_OK != error ) {
03321     goto loser;
03322   }
03323 
03324   return CKR_OK;
03325 
03326  loser:
03327   switch( error ) {
03328   case CKR_SESSION_CLOSED:
03329     /* destroy session? */
03330     break;
03331   case CKR_DEVICE_REMOVED:
03332     /* (void)nssCKFWToken_Destroy(fwToken); */
03333     break;
03334   case CKR_CRYPTOKI_NOT_INITIALIZED:
03335   case CKR_DEVICE_ERROR:
03336   case CKR_DEVICE_MEMORY:
03337   case CKR_FUNCTION_CANCELED:
03338   case CKR_FUNCTION_FAILED:
03339   case CKR_GENERAL_ERROR:
03340   case CKR_HOST_MEMORY:
03341   case CKR_OPERATION_ACTIVE:
03342   case CKR_RANDOM_SEED_NOT_SUPPORTED:
03343   case CKR_RANDOM_NO_RNG:
03344   case CKR_SESSION_HANDLE_INVALID:
03345   case CKR_USER_NOT_LOGGED_IN:
03346     break;
03347   default:
03348   case CKR_OK:
03349     error = CKR_GENERAL_ERROR;
03350     break;
03351   }
03352 
03353   return error;
03354 }
03355 
03356 /*
03357  * NSSCKFWC_GenerateRandom
03358  *
03359  */
03360 NSS_IMPLEMENT CK_RV
03361 NSSCKFWC_GenerateRandom
03362 (
03363   NSSCKFWInstance *fwInstance,
03364   CK_SESSION_HANDLE hSession,
03365   CK_BYTE_PTR pRandomData,
03366   CK_ULONG ulRandomLen
03367 )
03368 {
03369   CK_RV error = CKR_OK;
03370   NSSCKFWSession *fwSession;
03371   NSSItem buffer;
03372 
03373   if( (NSSCKFWInstance *)NULL == fwInstance ) {
03374     error = CKR_CRYPTOKI_NOT_INITIALIZED;
03375     goto loser;
03376   }
03377 
03378   fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
03379   if( (NSSCKFWSession *)NULL == fwSession ) {
03380     error = CKR_SESSION_HANDLE_INVALID;
03381     goto loser;
03382   }
03383 
03384   if( (CK_BYTE_PTR)CK_NULL_PTR == pRandomData ) {
03385     error = CKR_ARGUMENTS_BAD;
03386     goto loser;
03387   }
03388 
03389   /*
03390    * A purify error here indicates caller error.
03391    */
03392   (void)nsslibc_memset(pRandomData, 0, ulRandomLen);
03393 
03394   buffer.size = (PRUint32)ulRandomLen;
03395   buffer.data = (void *)pRandomData;
03396 
03397   error = nssCKFWSession_GetRandom(fwSession, &buffer);
03398 
03399   if( CKR_OK != error ) {
03400     goto loser;
03401   }
03402 
03403   return CKR_OK;
03404 
03405  loser:
03406   switch( error ) {
03407   case CKR_SESSION_CLOSED:
03408     /* destroy session? */
03409     break;
03410   case CKR_DEVICE_REMOVED:
03411     /* (void)nssCKFWToken_Destroy(fwToken); */
03412     break;
03413   case CKR_CRYPTOKI_NOT_INITIALIZED:
03414   case CKR_DEVICE_ERROR:
03415   case CKR_DEVICE_MEMORY:
03416   case CKR_FUNCTION_CANCELED:
03417   case CKR_FUNCTION_FAILED:
03418   case CKR_GENERAL_ERROR:
03419   case CKR_HOST_MEMORY:
03420   case CKR_OPERATION_ACTIVE:
03421   case CKR_RANDOM_NO_RNG:
03422   case CKR_SESSION_HANDLE_INVALID:
03423   case CKR_USER_NOT_LOGGED_IN:
03424     break;
03425   default:
03426   case CKR_OK:
03427     error = CKR_GENERAL_ERROR;
03428     break;
03429   }
03430 
03431   return error;
03432 }
03433 
03434 /*
03435  * NSSCKFWC_GetFunctionStatus
03436  *
03437  */
03438 NSS_IMPLEMENT CK_RV
03439 NSSCKFWC_GetFunctionStatus
03440 (
03441   NSSCKFWInstance *fwInstance,
03442   CK_SESSION_HANDLE hSession
03443 )
03444 {
03445   return CKR_FUNCTION_NOT_PARALLEL;
03446 }
03447 
03448 /*
03449  * NSSCKFWC_CancelFunction
03450  *
03451  */
03452 NSS_IMPLEMENT CK_RV
03453 NSSCKFWC_CancelFunction
03454 (
03455   NSSCKFWInstance *fwInstance,
03456   CK_SESSION_HANDLE hSession
03457 )
03458 {
03459   return CKR_FUNCTION_NOT_PARALLEL;
03460 }