Mercurial > trustbridge > nss-cmake-static
diff nss/lib/ckfw/wrap.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nss/lib/ckfw/wrap.c Mon Jul 28 10:47:06 2014 +0200 @@ -0,0 +1,5672 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * wrap.c + * + * This file contains the routines that actually implement the cryptoki + * API, using the internal APIs of the NSS Cryptoki Framework. There is + * one routine here for every cryptoki routine. For linking reasons + * the actual entry points passed back with C_GetFunctionList have to + * exist in one of the Module's source files; however, those are merely + * simple wrappers that call these routines. The intelligence of the + * implementations is here. + */ + +#ifndef CK_T +#include "ck.h" +#endif /* CK_T */ + +/* + * NSSCKFWC_Initialize + * NSSCKFWC_Finalize + * NSSCKFWC_GetInfo + * -- NSSCKFWC_GetFunctionList -- see the API insert file + * NSSCKFWC_GetSlotList + * NSSCKFWC_GetSlotInfo + * NSSCKFWC_GetTokenInfo + * NSSCKFWC_WaitForSlotEvent + * NSSCKFWC_GetMechanismList + * NSSCKFWC_GetMechanismInfo + * NSSCKFWC_InitToken + * NSSCKFWC_InitPIN + * NSSCKFWC_SetPIN + * NSSCKFWC_OpenSession + * NSSCKFWC_CloseSession + * NSSCKFWC_CloseAllSessions + * NSSCKFWC_GetSessionInfo + * NSSCKFWC_GetOperationState + * NSSCKFWC_SetOperationState + * NSSCKFWC_Login + * NSSCKFWC_Logout + * NSSCKFWC_CreateObject + * NSSCKFWC_CopyObject + * NSSCKFWC_DestroyObject + * NSSCKFWC_GetObjectSize + * NSSCKFWC_GetAttributeValue + * NSSCKFWC_SetAttributeValue + * NSSCKFWC_FindObjectsInit + * NSSCKFWC_FindObjects + * NSSCKFWC_FindObjectsFinal + * NSSCKFWC_EncryptInit + * NSSCKFWC_Encrypt + * NSSCKFWC_EncryptUpdate + * NSSCKFWC_EncryptFinal + * NSSCKFWC_DecryptInit + * NSSCKFWC_Decrypt + * NSSCKFWC_DecryptUpdate + * NSSCKFWC_DecryptFinal + * NSSCKFWC_DigestInit + * NSSCKFWC_Digest + * NSSCKFWC_DigestUpdate + * NSSCKFWC_DigestKey + * NSSCKFWC_DigestFinal + * NSSCKFWC_SignInit + * NSSCKFWC_Sign + * NSSCKFWC_SignUpdate + * NSSCKFWC_SignFinal + * NSSCKFWC_SignRecoverInit + * NSSCKFWC_SignRecover + * NSSCKFWC_VerifyInit + * NSSCKFWC_Verify + * NSSCKFWC_VerifyUpdate + * NSSCKFWC_VerifyFinal + * NSSCKFWC_VerifyRecoverInit + * NSSCKFWC_VerifyRecover + * NSSCKFWC_DigestEncryptUpdate + * NSSCKFWC_DecryptDigestUpdate + * NSSCKFWC_SignEncryptUpdate + * NSSCKFWC_DecryptVerifyUpdate + * NSSCKFWC_GenerateKey + * NSSCKFWC_GenerateKeyPair + * NSSCKFWC_WrapKey + * NSSCKFWC_UnwrapKey + * NSSCKFWC_DeriveKey + * NSSCKFWC_SeedRandom + * NSSCKFWC_GenerateRandom + * NSSCKFWC_GetFunctionStatus + * NSSCKFWC_CancelFunction + */ + +/* figure out out locking semantics */ +static CK_RV +nssCKFW_GetThreadSafeState(CK_C_INITIALIZE_ARGS_PTR pInitArgs, + CryptokiLockingState *pLocking_state) { + int functionCount = 0; + + /* parsed according to (PKCS #11 Section 11.4) */ + /* no args, the degenerate version of case 1 */ + if (!pInitArgs) { + *pLocking_state = SingleThreaded; + return CKR_OK; + } + + /* CKF_OS_LOCKING_OK set, Cases 2 and 4 */ + if (pInitArgs->flags & CKF_OS_LOCKING_OK) { + *pLocking_state = MultiThreaded; + return CKR_OK; + } + if ((CK_CREATEMUTEX) NULL != pInitArgs->CreateMutex) functionCount++; + if ((CK_DESTROYMUTEX) NULL != pInitArgs->DestroyMutex) functionCount++; + if ((CK_LOCKMUTEX) NULL != pInitArgs->LockMutex) functionCount++; + if ((CK_UNLOCKMUTEX) NULL != pInitArgs->UnlockMutex) functionCount++; + + /* CKF_OS_LOCKING_OK is not set, and not functions supplied, + * explicit case 1 */ + if (0 == functionCount) { + *pLocking_state = SingleThreaded; + return CKR_OK; + } + + /* OS_LOCKING_OK is not set and functions have been supplied. Since + * ckfw uses nssbase library which explicitly calls NSPR, and since + * there is no way to reliably override these explicit calls to NSPR, + * therefore we can't support applications which have their own threading + * module. Return CKR_CANT_LOCK if they supplied the correct number of + * arguments, or CKR_ARGUMENTS_BAD if they did not in either case we will + * fail the initialize */ + return (4 == functionCount) ? CKR_CANT_LOCK : CKR_ARGUMENTS_BAD; +} + +static PRInt32 liveInstances; + +/* + * NSSCKFWC_Initialize + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_Initialize +( + NSSCKFWInstance **pFwInstance, + NSSCKMDInstance *mdInstance, + CK_VOID_PTR pInitArgs +) +{ + CK_RV error = CKR_OK; + CryptokiLockingState locking_state; + + if( (NSSCKFWInstance **)NULL == pFwInstance ) { + error = CKR_GENERAL_ERROR; + goto loser; + } + + if (*pFwInstance) { + error = CKR_CRYPTOKI_ALREADY_INITIALIZED; + goto loser; + } + + if (!mdInstance) { + error = CKR_GENERAL_ERROR; + goto loser; + } + + error = nssCKFW_GetThreadSafeState(pInitArgs,&locking_state); + if( CKR_OK != error ) { + goto loser; + } + + *pFwInstance = nssCKFWInstance_Create(pInitArgs, locking_state, mdInstance, &error); + if (!*pFwInstance) { + goto loser; + } + PR_ATOMIC_INCREMENT(&liveInstances); + return CKR_OK; + + loser: + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_CANT_LOCK: + case CKR_CRYPTOKI_ALREADY_INITIALIZED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_NEED_TO_CREATE_THREADS: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_Finalize + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_Finalize +( + NSSCKFWInstance **pFwInstance +) +{ + CK_RV error = CKR_OK; + + if( (NSSCKFWInstance **)NULL == pFwInstance ) { + error = CKR_GENERAL_ERROR; + goto loser; + } + + if (!*pFwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + error = nssCKFWInstance_Destroy(*pFwInstance); + + /* In any case */ + *pFwInstance = (NSSCKFWInstance *)NULL; + + loser: + switch( error ) { + PRInt32 remainingInstances; + case CKR_OK: + remainingInstances = PR_ATOMIC_DECREMENT(&liveInstances); + if (!remainingInstances) { + nssArena_Shutdown(); + } + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + break; + default: + error = CKR_GENERAL_ERROR; + break; + } + + /* + * A thread's error stack is automatically destroyed when the thread + * terminates or, for the primordial thread, by PR_Cleanup. On + * Windows with MinGW, the thread private data destructor PR_Free + * registered by this module is actually a thunk for PR_Free defined + * in this module. When the thread that unloads this module terminates + * or calls PR_Cleanup, the thunk for PR_Free is already gone with the + * module. Therefore we need to destroy the error stack before the + * module is unloaded. + */ + nss_DestroyErrorStack(); + return error; +} + +/* + * NSSCKFWC_GetInfo + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GetInfo +( + NSSCKFWInstance *fwInstance, + CK_INFO_PTR pInfo +) +{ + CK_RV error = CKR_OK; + + if( (CK_INFO_PTR)CK_NULL_PTR == pInfo ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + /* + * A purify error here means a caller error + */ + (void)nsslibc_memset(pInfo, 0, sizeof(CK_INFO)); + + pInfo->cryptokiVersion = nssCKFWInstance_GetCryptokiVersion(fwInstance); + + error = nssCKFWInstance_GetManufacturerID(fwInstance, pInfo->manufacturerID); + if( CKR_OK != error ) { + goto loser; + } + + pInfo->flags = nssCKFWInstance_GetFlags(fwInstance); + + error = nssCKFWInstance_GetLibraryDescription(fwInstance, pInfo->libraryDescription); + if( CKR_OK != error ) { + goto loser; + } + + pInfo->libraryVersion = nssCKFWInstance_GetLibraryVersion(fwInstance); + + return CKR_OK; + + loser: + switch( error ) { + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + break; + default: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * C_GetFunctionList is implemented entirely in the Module's file which + * includes the Framework API insert file. It requires no "actual" + * NSSCKFW routine. + */ + +/* + * NSSCKFWC_GetSlotList + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GetSlotList +( + NSSCKFWInstance *fwInstance, + CK_BBOOL tokenPresent, + CK_SLOT_ID_PTR pSlotList, + CK_ULONG_PTR pulCount +) +{ + CK_RV error = CKR_OK; + CK_ULONG nSlots; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + switch( tokenPresent ) { + case CK_TRUE: + case CK_FALSE: + break; + default: + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + if( (CK_ULONG_PTR)CK_NULL_PTR == pulCount ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error); + if( (CK_ULONG)0 == nSlots ) { + goto loser; + } + + if( (CK_SLOT_ID_PTR)CK_NULL_PTR == pSlotList ) { + *pulCount = nSlots; + return CKR_OK; + } + + /* + * A purify error here indicates caller error. + */ + (void)nsslibc_memset(pSlotList, 0, *pulCount * sizeof(CK_SLOT_ID)); + + if( *pulCount < nSlots ) { + *pulCount = nSlots; + error = CKR_BUFFER_TOO_SMALL; + goto loser; + } else { + CK_ULONG i; + *pulCount = nSlots; + + /* + * Our secret "mapping": CK_SLOT_IDs are integers [1,N], and we + * just index one when we need it. + */ + + for( i = 0; i < nSlots; i++ ) { + pSlotList[i] = i+1; + } + + return CKR_OK; + } + + loser: + switch( error ) { + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_GetSlotInfo + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GetSlotInfo +( + NSSCKFWInstance *fwInstance, + CK_SLOT_ID slotID, + CK_SLOT_INFO_PTR pInfo +) +{ + CK_RV error = CKR_OK; + CK_ULONG nSlots; + NSSCKFWSlot **slots; + NSSCKFWSlot *fwSlot; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error); + if( (CK_ULONG)0 == nSlots ) { + goto loser; + } + + if( (slotID < 1) || (slotID > nSlots) ) { + error = CKR_SLOT_ID_INVALID; + goto loser; + } + + if( (CK_SLOT_INFO_PTR)CK_NULL_PTR == pInfo ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + /* + * A purify error here indicates caller error. + */ + (void)nsslibc_memset(pInfo, 0, sizeof(CK_SLOT_INFO)); + + slots = nssCKFWInstance_GetSlots(fwInstance, &error); + if( (NSSCKFWSlot **)NULL == slots ) { + goto loser; + } + + fwSlot = slots[ slotID-1 ]; + + error = nssCKFWSlot_GetSlotDescription(fwSlot, pInfo->slotDescription); + if( CKR_OK != error ) { + goto loser; + } + + error = nssCKFWSlot_GetManufacturerID(fwSlot, pInfo->manufacturerID); + if( CKR_OK != error ) { + goto loser; + } + + if( nssCKFWSlot_GetTokenPresent(fwSlot) ) { + pInfo->flags |= CKF_TOKEN_PRESENT; + } + + if( nssCKFWSlot_GetRemovableDevice(fwSlot) ) { + pInfo->flags |= CKF_REMOVABLE_DEVICE; + } + + if( nssCKFWSlot_GetHardwareSlot(fwSlot) ) { + pInfo->flags |= CKF_HW_SLOT; + } + + pInfo->hardwareVersion = nssCKFWSlot_GetHardwareVersion(fwSlot); + pInfo->firmwareVersion = nssCKFWSlot_GetFirmwareVersion(fwSlot); + + return CKR_OK; + + loser: + switch( error ) { + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_SLOT_ID_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + } + + return error; +} + +/* + * NSSCKFWC_GetTokenInfo + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GetTokenInfo +( + NSSCKFWInstance *fwInstance, + CK_SLOT_ID slotID, + CK_TOKEN_INFO_PTR pInfo +) +{ + CK_RV error = CKR_OK; + CK_ULONG nSlots; + NSSCKFWSlot **slots; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error); + if( (CK_ULONG)0 == nSlots ) { + goto loser; + } + + if( (slotID < 1) || (slotID > nSlots) ) { + error = CKR_SLOT_ID_INVALID; + goto loser; + } + + if( (CK_TOKEN_INFO_PTR)CK_NULL_PTR == pInfo ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + /* + * A purify error here indicates caller error. + */ + (void)nsslibc_memset(pInfo, 0, sizeof(CK_TOKEN_INFO)); + + slots = nssCKFWInstance_GetSlots(fwInstance, &error); + if( (NSSCKFWSlot **)NULL == slots ) { + goto loser; + } + + fwSlot = slots[ slotID-1 ]; + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + error = nssCKFWToken_GetLabel(fwToken, pInfo->label); + if( CKR_OK != error ) { + goto loser; + } + + error = nssCKFWToken_GetManufacturerID(fwToken, pInfo->manufacturerID); + if( CKR_OK != error ) { + goto loser; + } + + error = nssCKFWToken_GetModel(fwToken, pInfo->model); + if( CKR_OK != error ) { + goto loser; + } + + error = nssCKFWToken_GetSerialNumber(fwToken, pInfo->serialNumber); + if( CKR_OK != error ) { + goto loser; + } + + if( nssCKFWToken_GetHasRNG(fwToken) ) { + pInfo->flags |= CKF_RNG; + } + + if( nssCKFWToken_GetIsWriteProtected(fwToken) ) { + pInfo->flags |= CKF_WRITE_PROTECTED; + } + + if( nssCKFWToken_GetLoginRequired(fwToken) ) { + pInfo->flags |= CKF_LOGIN_REQUIRED; + } + + if( nssCKFWToken_GetUserPinInitialized(fwToken) ) { + pInfo->flags |= CKF_USER_PIN_INITIALIZED; + } + + if( nssCKFWToken_GetRestoreKeyNotNeeded(fwToken) ) { + pInfo->flags |= CKF_RESTORE_KEY_NOT_NEEDED; + } + + if( nssCKFWToken_GetHasClockOnToken(fwToken) ) { + pInfo->flags |= CKF_CLOCK_ON_TOKEN; + } + + if( nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken) ) { + pInfo->flags |= CKF_PROTECTED_AUTHENTICATION_PATH; + } + + if( nssCKFWToken_GetSupportsDualCryptoOperations(fwToken) ) { + pInfo->flags |= CKF_DUAL_CRYPTO_OPERATIONS; + } + + pInfo->ulMaxSessionCount = nssCKFWToken_GetMaxSessionCount(fwToken); + pInfo->ulSessionCount = nssCKFWToken_GetSessionCount(fwToken); + pInfo->ulMaxRwSessionCount = nssCKFWToken_GetMaxRwSessionCount(fwToken); + pInfo->ulRwSessionCount= nssCKFWToken_GetRwSessionCount(fwToken); + pInfo->ulMaxPinLen = nssCKFWToken_GetMaxPinLen(fwToken); + pInfo->ulMinPinLen = nssCKFWToken_GetMinPinLen(fwToken); + pInfo->ulTotalPublicMemory = nssCKFWToken_GetTotalPublicMemory(fwToken); + pInfo->ulFreePublicMemory = nssCKFWToken_GetFreePublicMemory(fwToken); + pInfo->ulTotalPrivateMemory = nssCKFWToken_GetTotalPrivateMemory(fwToken); + pInfo->ulFreePrivateMemory = nssCKFWToken_GetFreePrivateMemory(fwToken); + pInfo->hardwareVersion = nssCKFWToken_GetHardwareVersion(fwToken); + pInfo->firmwareVersion = nssCKFWToken_GetFirmwareVersion(fwToken); + + error = nssCKFWToken_GetUTCTime(fwToken, pInfo->utcTime); + if( CKR_OK != error ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_DEVICE_REMOVED: + case CKR_TOKEN_NOT_PRESENT: + if (fwToken) + nssCKFWToken_Destroy(fwToken); + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_SLOT_ID_INVALID: + case CKR_TOKEN_NOT_RECOGNIZED: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_WaitForSlotEvent + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_WaitForSlotEvent +( + NSSCKFWInstance *fwInstance, + CK_FLAGS flags, + CK_SLOT_ID_PTR pSlot, + CK_VOID_PTR pReserved +) +{ + CK_RV error = CKR_OK; + CK_ULONG nSlots; + CK_BBOOL block; + NSSCKFWSlot **slots; + NSSCKFWSlot *fwSlot; + CK_ULONG i; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + if( flags & ~CKF_DONT_BLOCK ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + block = (flags & CKF_DONT_BLOCK) ? CK_TRUE : CK_FALSE; + + nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error); + if( (CK_ULONG)0 == nSlots ) { + goto loser; + } + + if( (CK_SLOT_ID_PTR)CK_NULL_PTR == pSlot ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + if( (CK_VOID_PTR)CK_NULL_PTR != pReserved ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + slots = nssCKFWInstance_GetSlots(fwInstance, &error); + if( (NSSCKFWSlot **)NULL == slots ) { + goto loser; + } + + fwSlot = nssCKFWInstance_WaitForSlotEvent(fwInstance, block, &error); + if (!fwSlot) { + goto loser; + } + + for( i = 0; i < nSlots; i++ ) { + if( fwSlot == slots[i] ) { + *pSlot = (CK_SLOT_ID)(CK_ULONG)(i+1); + return CKR_OK; + } + } + + error = CKR_GENERAL_ERROR; /* returned something not in the slot list */ + + loser: + switch( error ) { + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_NO_EVENT: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_GetMechanismList + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GetMechanismList +( + NSSCKFWInstance *fwInstance, + CK_SLOT_ID slotID, + CK_MECHANISM_TYPE_PTR pMechanismList, + CK_ULONG_PTR pulCount +) +{ + CK_RV error = CKR_OK; + CK_ULONG nSlots; + NSSCKFWSlot **slots; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL; + CK_ULONG count; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error); + if( (CK_ULONG)0 == nSlots ) { + goto loser; + } + + if( (slotID < 1) || (slotID > nSlots) ) { + error = CKR_SLOT_ID_INVALID; + goto loser; + } + + if( (CK_ULONG_PTR)CK_NULL_PTR == pulCount ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + slots = nssCKFWInstance_GetSlots(fwInstance, &error); + if( (NSSCKFWSlot **)NULL == slots ) { + goto loser; + } + + fwSlot = slots[ slotID-1 ]; + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + count = nssCKFWToken_GetMechanismCount(fwToken); + + if( (CK_MECHANISM_TYPE_PTR)CK_NULL_PTR == pMechanismList ) { + *pulCount = count; + return CKR_OK; + } + + if( *pulCount < count ) { + *pulCount = count; + error = CKR_BUFFER_TOO_SMALL; + goto loser; + } + + /* + * A purify error here indicates caller error. + */ + (void)nsslibc_memset(pMechanismList, 0, *pulCount * sizeof(CK_MECHANISM_TYPE)); + + *pulCount = count; + + if( 0 != count ) { + error = nssCKFWToken_GetMechanismTypes(fwToken, pMechanismList); + } else { + error = CKR_OK; + } + + if( CKR_OK == error ) { + return CKR_OK; + } + + loser: + switch( error ) { + case CKR_DEVICE_REMOVED: + case CKR_TOKEN_NOT_PRESENT: + if (fwToken) + nssCKFWToken_Destroy(fwToken); + break; + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_SLOT_ID_INVALID: + case CKR_TOKEN_NOT_RECOGNIZED: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_GetMechanismInfo + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GetMechanismInfo +( + NSSCKFWInstance *fwInstance, + CK_SLOT_ID slotID, + CK_MECHANISM_TYPE type, + CK_MECHANISM_INFO_PTR pInfo +) +{ + CK_RV error = CKR_OK; + CK_ULONG nSlots; + NSSCKFWSlot **slots; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL; + NSSCKFWMechanism *fwMechanism; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error); + if( (CK_ULONG)0 == nSlots ) { + goto loser; + } + + if( (slotID < 1) || (slotID > nSlots) ) { + error = CKR_SLOT_ID_INVALID; + goto loser; + } + + slots = nssCKFWInstance_GetSlots(fwInstance, &error); + if( (NSSCKFWSlot **)NULL == slots ) { + goto loser; + } + + fwSlot = slots[ slotID-1 ]; + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + if( (CK_MECHANISM_INFO_PTR)CK_NULL_PTR == pInfo ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + /* + * A purify error here indicates caller error. + */ + (void)nsslibc_memset(pInfo, 0, sizeof(CK_MECHANISM_INFO)); + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwMechanism = nssCKFWToken_GetMechanism(fwToken, type, &error); + if (!fwMechanism) { + goto loser; + } + + pInfo->ulMinKeySize = nssCKFWMechanism_GetMinKeySize(fwMechanism, &error); + pInfo->ulMaxKeySize = nssCKFWMechanism_GetMaxKeySize(fwMechanism, &error); + + if( nssCKFWMechanism_GetInHardware(fwMechanism, &error) ) { + pInfo->flags |= CKF_HW; + } + if( nssCKFWMechanism_GetCanEncrypt(fwMechanism, &error) ) { + pInfo->flags |= CKF_ENCRYPT; + } + if( nssCKFWMechanism_GetCanDecrypt(fwMechanism, &error) ) { + pInfo->flags |= CKF_DECRYPT; + } + if( nssCKFWMechanism_GetCanDigest(fwMechanism, &error) ) { + pInfo->flags |= CKF_DIGEST; + } + if( nssCKFWMechanism_GetCanSign(fwMechanism, &error) ) { + pInfo->flags |= CKF_SIGN; + } + if( nssCKFWMechanism_GetCanSignRecover(fwMechanism, &error) ) { + pInfo->flags |= CKF_SIGN_RECOVER; + } + if( nssCKFWMechanism_GetCanVerify(fwMechanism, &error) ) { + pInfo->flags |= CKF_VERIFY; + } + if( nssCKFWMechanism_GetCanVerifyRecover(fwMechanism, &error) ) { + pInfo->flags |= CKF_VERIFY_RECOVER; + } + if( nssCKFWMechanism_GetCanGenerate(fwMechanism, &error) ) { + pInfo->flags |= CKF_GENERATE; + } + if( nssCKFWMechanism_GetCanGenerateKeyPair(fwMechanism, &error) ) { + pInfo->flags |= CKF_GENERATE_KEY_PAIR; + } + if( nssCKFWMechanism_GetCanWrap(fwMechanism, &error) ) { + pInfo->flags |= CKF_WRAP; + } + if( nssCKFWMechanism_GetCanUnwrap(fwMechanism, &error) ) { + pInfo->flags |= CKF_UNWRAP; + } + if( nssCKFWMechanism_GetCanDerive(fwMechanism, &error) ) { + pInfo->flags |= CKF_DERIVE; + } + nssCKFWMechanism_Destroy(fwMechanism); + + return error; + + loser: + switch( error ) { + case CKR_DEVICE_REMOVED: + case CKR_TOKEN_NOT_PRESENT: + if (fwToken) + nssCKFWToken_Destroy(fwToken); + break; + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_MECHANISM_INVALID: + case CKR_SLOT_ID_INVALID: + case CKR_TOKEN_NOT_RECOGNIZED: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_InitToken + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_InitToken +( + NSSCKFWInstance *fwInstance, + CK_SLOT_ID slotID, + CK_CHAR_PTR pPin, + CK_ULONG ulPinLen, + CK_CHAR_PTR pLabel +) +{ + CK_RV error = CKR_OK; + CK_ULONG nSlots; + NSSCKFWSlot **slots; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL; + NSSItem pin; + NSSUTF8 *label; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error); + if( (CK_ULONG)0 == nSlots ) { + goto loser; + } + + if( (slotID < 1) || (slotID > nSlots) ) { + error = CKR_SLOT_ID_INVALID; + goto loser; + } + + slots = nssCKFWInstance_GetSlots(fwInstance, &error); + if( (NSSCKFWSlot **)NULL == slots ) { + goto loser; + } + + fwSlot = slots[ slotID-1 ]; + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + pin.size = (PRUint32)ulPinLen; + pin.data = (void *)pPin; + label = (NSSUTF8 *)pLabel; /* identity conversion */ + + error = nssCKFWToken_InitToken(fwToken, &pin, label); + if( CKR_OK != error ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_DEVICE_REMOVED: + case CKR_TOKEN_NOT_PRESENT: + if (fwToken) + nssCKFWToken_Destroy(fwToken); + break; + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_PIN_INCORRECT: + case CKR_PIN_LOCKED: + case CKR_SESSION_EXISTS: + case CKR_SLOT_ID_INVALID: + case CKR_TOKEN_NOT_RECOGNIZED: + case CKR_TOKEN_WRITE_PROTECTED: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_InitPIN + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_InitPIN +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_CHAR_PTR pPin, + CK_ULONG ulPinLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSItem pin, *arg; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + if( (CK_CHAR_PTR)CK_NULL_PTR == pPin ) { + arg = (NSSItem *)NULL; + } else { + arg = &pin; + pin.size = (PRUint32)ulPinLen; + pin.data = (void *)pPin; + } + + error = nssCKFWSession_InitPIN(fwSession, arg); + if( CKR_OK != error ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_PIN_INVALID: + case CKR_PIN_LEN_RANGE: + case CKR_SESSION_READ_ONLY: + case CKR_SESSION_HANDLE_INVALID: + case CKR_TOKEN_WRITE_PROTECTED: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_SetPIN + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_SetPIN +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_CHAR_PTR pOldPin, + CK_ULONG ulOldLen, + CK_CHAR_PTR pNewPin, + CK_ULONG ulNewLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSItem oldPin, newPin, *oldArg, *newArg; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + if( (CK_CHAR_PTR)CK_NULL_PTR == pOldPin ) { + oldArg = (NSSItem *)NULL; + } else { + oldArg = &oldPin; + oldPin.size = (PRUint32)ulOldLen; + oldPin.data = (void *)pOldPin; + } + + if( (CK_CHAR_PTR)CK_NULL_PTR == pNewPin ) { + newArg = (NSSItem *)NULL; + } else { + newArg = &newPin; + newPin.size = (PRUint32)ulNewLen; + newPin.data = (void *)pNewPin; + } + + error = nssCKFWSession_SetPIN(fwSession, oldArg, newArg); + if( CKR_OK != error ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_PIN_INCORRECT: + case CKR_PIN_INVALID: + case CKR_PIN_LEN_RANGE: + case CKR_PIN_LOCKED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SESSION_READ_ONLY: + case CKR_TOKEN_WRITE_PROTECTED: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_OpenSession + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_OpenSession +( + NSSCKFWInstance *fwInstance, + CK_SLOT_ID slotID, + CK_FLAGS flags, + CK_VOID_PTR pApplication, + CK_NOTIFY Notify, + CK_SESSION_HANDLE_PTR phSession +) +{ + CK_RV error = CKR_OK; + CK_ULONG nSlots; + NSSCKFWSlot **slots; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL; + NSSCKFWSession *fwSession; + CK_BBOOL rw; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error); + if( (CK_ULONG)0 == nSlots ) { + goto loser; + } + + if( (slotID < 1) || (slotID > nSlots) ) { + error = CKR_SLOT_ID_INVALID; + goto loser; + } + + if( flags & CKF_RW_SESSION ) { + rw = CK_TRUE; + } else { + rw = CK_FALSE; + } + + if( flags & CKF_SERIAL_SESSION ) { + ; + } else { + error = CKR_SESSION_PARALLEL_NOT_SUPPORTED; + goto loser; + } + + if( flags & ~(CKF_RW_SESSION|CKF_SERIAL_SESSION) ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + if( (CK_SESSION_HANDLE_PTR)CK_NULL_PTR == phSession ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + /* + * A purify error here indicates caller error. + */ + *phSession = (CK_SESSION_HANDLE)0; + + slots = nssCKFWInstance_GetSlots(fwInstance, &error); + if( (NSSCKFWSlot **)NULL == slots ) { + goto loser; + } + + fwSlot = slots[ slotID-1 ]; + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwSession = nssCKFWToken_OpenSession(fwToken, rw, pApplication, + Notify, &error); + if (!fwSession) { + goto loser; + } + + *phSession = nssCKFWInstance_CreateSessionHandle(fwInstance, + fwSession, &error); + if( (CK_SESSION_HANDLE)0 == *phSession ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_SESSION_COUNT: + case CKR_SESSION_EXISTS: + case CKR_SESSION_PARALLEL_NOT_SUPPORTED: + case CKR_SESSION_READ_WRITE_SO_EXISTS: + case CKR_SLOT_ID_INVALID: + case CKR_TOKEN_NOT_PRESENT: + case CKR_TOKEN_NOT_RECOGNIZED: + case CKR_TOKEN_WRITE_PROTECTED: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_CloseSession + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_CloseSession +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + nssCKFWInstance_DestroySessionHandle(fwInstance, hSession); + error = nssCKFWSession_Destroy(fwSession, CK_TRUE); + + if( CKR_OK != error ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_CloseAllSessions + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_CloseAllSessions +( + NSSCKFWInstance *fwInstance, + CK_SLOT_ID slotID +) +{ + CK_RV error = CKR_OK; + CK_ULONG nSlots; + NSSCKFWSlot **slots; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error); + if( (CK_ULONG)0 == nSlots ) { + goto loser; + } + + if( (slotID < 1) || (slotID > nSlots) ) { + error = CKR_SLOT_ID_INVALID; + goto loser; + } + + slots = nssCKFWInstance_GetSlots(fwInstance, &error); + if( (NSSCKFWSlot **)NULL == slots ) { + goto loser; + } + + fwSlot = slots[ slotID-1 ]; + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + error = nssCKFWToken_CloseAllSessions(fwToken); + if( CKR_OK != error ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_SLOT_ID_INVALID: + case CKR_TOKEN_NOT_PRESENT: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_GetSessionInfo + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GetSessionInfo +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_SESSION_INFO_PTR pInfo +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWSlot *fwSlot; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + if( (CK_SESSION_INFO_PTR)CK_NULL_PTR == pInfo ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + /* + * A purify error here indicates caller error. + */ + (void)nsslibc_memset(pInfo, 0, sizeof(CK_SESSION_INFO)); + + fwSlot = nssCKFWSession_GetFWSlot(fwSession); + if (!fwSlot) { + error = CKR_GENERAL_ERROR; + goto loser; + } + + pInfo->slotID = nssCKFWSlot_GetSlotID(fwSlot); + pInfo->state = nssCKFWSession_GetSessionState(fwSession); + + if( CK_TRUE == nssCKFWSession_IsRWSession(fwSession) ) { + pInfo->flags |= CKF_RW_SESSION; + } + + pInfo->flags |= CKF_SERIAL_SESSION; /* Always true */ + + pInfo->ulDeviceError = nssCKFWSession_GetDeviceError(fwSession); + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_GetOperationState + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GetOperationState +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pOperationState, + CK_ULONG_PTR pulOperationStateLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + CK_ULONG len; + NSSItem buf; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + if( (CK_ULONG_PTR)CK_NULL_PTR == pulOperationStateLen ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + len = nssCKFWSession_GetOperationStateLen(fwSession, &error); + if( ((CK_ULONG)0 == len) && (CKR_OK != error) ) { + goto loser; + } + + if( (CK_BYTE_PTR)CK_NULL_PTR == pOperationState ) { + *pulOperationStateLen = len; + return CKR_OK; + } + + if( *pulOperationStateLen < len ) { + *pulOperationStateLen = len; + error = CKR_BUFFER_TOO_SMALL; + goto loser; + } + + buf.size = (PRUint32)*pulOperationStateLen; + buf.data = (void *)pOperationState; + *pulOperationStateLen = len; + error = nssCKFWSession_GetOperationState(fwSession, &buf); + + if( CKR_OK != error ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_STATE_UNSAVEABLE: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_SetOperationState + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_SetOperationState +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pOperationState, + CK_ULONG ulOperationStateLen, + CK_OBJECT_HANDLE hEncryptionKey, + CK_OBJECT_HANDLE hAuthenticationKey +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *eKey; + NSSCKFWObject *aKey; + NSSItem state; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + if( (CK_BYTE_PTR)CK_NULL_PTR == pOperationState ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + /* + * We could loop through the buffer, to catch any purify errors + * in a place with a "user error" note. + */ + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + if( (CK_OBJECT_HANDLE)0 == hEncryptionKey ) { + eKey = (NSSCKFWObject *)NULL; + } else { + eKey = nssCKFWInstance_ResolveObjectHandle(fwInstance, hEncryptionKey); + if (!eKey) { + error = CKR_KEY_HANDLE_INVALID; + goto loser; + } + } + + if( (CK_OBJECT_HANDLE)0 == hAuthenticationKey ) { + aKey = (NSSCKFWObject *)NULL; + } else { + aKey = nssCKFWInstance_ResolveObjectHandle(fwInstance, hAuthenticationKey); + if (!aKey) { + error = CKR_KEY_HANDLE_INVALID; + goto loser; + } + } + + state.data = pOperationState; + state.size = ulOperationStateLen; + + error = nssCKFWSession_SetOperationState(fwSession, &state, eKey, aKey); + if( CKR_OK != error ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_KEY_CHANGED: + case CKR_KEY_NEEDED: + case CKR_KEY_NOT_NEEDED: + case CKR_SAVED_STATE_INVALID: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_Login + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_Login +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_USER_TYPE userType, + CK_CHAR_PTR pPin, + CK_ULONG ulPinLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSItem pin, *arg; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + if( (CK_CHAR_PTR)CK_NULL_PTR == pPin ) { + arg = (NSSItem *)NULL; + } else { + arg = &pin; + pin.size = (PRUint32)ulPinLen; + pin.data = (void *)pPin; + } + + error = nssCKFWSession_Login(fwSession, userType, arg); + if( CKR_OK != error ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_PIN_EXPIRED: + case CKR_PIN_INCORRECT: + case CKR_PIN_LOCKED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SESSION_READ_ONLY_EXISTS: + case CKR_USER_ALREADY_LOGGED_IN: + case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: + case CKR_USER_PIN_NOT_INITIALIZED: + case CKR_USER_TOO_MANY_TYPES: + case CKR_USER_TYPE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_Logout + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_Logout +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_Logout(fwSession); + if( CKR_OK != error ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_CreateObject + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_CreateObject +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phObject +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phObject ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + /* + * A purify error here indicates caller error. + */ + *phObject = (CK_OBJECT_HANDLE)0; + + fwObject = nssCKFWSession_CreateObject(fwSession, pTemplate, + ulCount, &error); + if (!fwObject) { + goto loser; + } + + *phObject = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error); + if( (CK_OBJECT_HANDLE)0 == *phObject ) { + nssCKFWObject_Destroy(fwObject); + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_ATTRIBUTE_READ_ONLY: + case CKR_ATTRIBUTE_TYPE_INVALID: + case CKR_ATTRIBUTE_VALUE_INVALID: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SESSION_READ_ONLY: + case CKR_TEMPLATE_INCOMPLETE: + case CKR_TEMPLATE_INCONSISTENT: + case CKR_TOKEN_WRITE_PROTECTED: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_CopyObject + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_CopyObject +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phNewObject +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + NSSCKFWObject *fwNewObject; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phNewObject ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + /* + * A purify error here indicates caller error. + */ + *phNewObject = (CK_OBJECT_HANDLE)0; + + fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject); + if (!fwObject) { + error = CKR_OBJECT_HANDLE_INVALID; + goto loser; + } + + fwNewObject = nssCKFWSession_CopyObject(fwSession, fwObject, + pTemplate, ulCount, &error); + if (!fwNewObject) { + goto loser; + } + + *phNewObject = nssCKFWInstance_CreateObjectHandle(fwInstance, + fwNewObject, &error); + if( (CK_OBJECT_HANDLE)0 == *phNewObject ) { + nssCKFWObject_Destroy(fwNewObject); + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_ATTRIBUTE_READ_ONLY: + case CKR_ATTRIBUTE_TYPE_INVALID: + case CKR_ATTRIBUTE_VALUE_INVALID: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OBJECT_HANDLE_INVALID: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SESSION_READ_ONLY: + case CKR_TEMPLATE_INCONSISTENT: + case CKR_TOKEN_WRITE_PROTECTED: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_DestroyObject + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_DestroyObject +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject); + if (!fwObject) { + error = CKR_OBJECT_HANDLE_INVALID; + goto loser; + } + + nssCKFWInstance_DestroyObjectHandle(fwInstance, hObject); + nssCKFWObject_Destroy(fwObject); + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OBJECT_HANDLE_INVALID: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SESSION_READ_ONLY: + case CKR_TOKEN_WRITE_PROTECTED: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_GetObjectSize + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GetObjectSize +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ULONG_PTR pulSize +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject); + if (!fwObject) { + error = CKR_OBJECT_HANDLE_INVALID; + goto loser; + } + + if( (CK_ULONG_PTR)CK_NULL_PTR == pulSize ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + /* + * A purify error here indicates caller error. + */ + *pulSize = (CK_ULONG)0; + + *pulSize = nssCKFWObject_GetObjectSize(fwObject, &error); + if( ((CK_ULONG)0 == *pulSize) && (CKR_OK != error) ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_INFORMATION_SENSITIVE: + case CKR_OBJECT_HANDLE_INVALID: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_GetAttributeValue + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GetAttributeValue +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + CK_BBOOL sensitive = CK_FALSE; + CK_BBOOL invalid = CK_FALSE; + CK_BBOOL tooSmall = CK_FALSE; + CK_ULONG i; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject); + if (!fwObject) { + error = CKR_OBJECT_HANDLE_INVALID; + goto loser; + } + + if( (CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + for( i = 0; i < ulCount; i++ ) { + CK_ULONG size = nssCKFWObject_GetAttributeSize(fwObject, + pTemplate[i].type, &error); + if( (CK_ULONG)0 == size ) { + switch( error ) { + case CKR_ATTRIBUTE_SENSITIVE: + case CKR_INFORMATION_SENSITIVE: + sensitive = CK_TRUE; + pTemplate[i].ulValueLen = (CK_ULONG)(-1); + continue; + case CKR_ATTRIBUTE_TYPE_INVALID: + invalid = CK_TRUE; + pTemplate[i].ulValueLen = (CK_ULONG)(-1); + continue; + case CKR_OK: + break; + default: + goto loser; + } + } + + if( (CK_VOID_PTR)CK_NULL_PTR == pTemplate[i].pValue ) { + pTemplate[i].ulValueLen = size; + } else { + NSSItem it, *p; + + if( pTemplate[i].ulValueLen < size ) { + tooSmall = CK_TRUE; + continue; + } + + it.size = (PRUint32)pTemplate[i].ulValueLen; + it.data = (void *)pTemplate[i].pValue; + p = nssCKFWObject_GetAttribute(fwObject, pTemplate[i].type, &it, + (NSSArena *)NULL, &error); + if (!p) { + switch( error ) { + case CKR_ATTRIBUTE_SENSITIVE: + case CKR_INFORMATION_SENSITIVE: + sensitive = CK_TRUE; + pTemplate[i].ulValueLen = (CK_ULONG)(-1); + continue; + case CKR_ATTRIBUTE_TYPE_INVALID: + invalid = CK_TRUE; + pTemplate[i].ulValueLen = (CK_ULONG)(-1); + continue; + default: + goto loser; + } + } + + pTemplate[i].ulValueLen = size; + } + } + + if( sensitive ) { + error = CKR_ATTRIBUTE_SENSITIVE; + goto loser; + } else if( invalid ) { + error = CKR_ATTRIBUTE_TYPE_INVALID; + goto loser; + } else if( tooSmall ) { + error = CKR_BUFFER_TOO_SMALL; + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_ATTRIBUTE_SENSITIVE: + case CKR_ATTRIBUTE_TYPE_INVALID: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OBJECT_HANDLE_INVALID: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_SetAttributeValue + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_SetAttributeValue +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + CK_ULONG i; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject); + if (!fwObject) { + error = CKR_OBJECT_HANDLE_INVALID; + goto loser; + } + + if( (CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + for (i=0; i < ulCount; i++) { + NSSItem value; + + value.data = pTemplate[i].pValue; + value.size = pTemplate[i].ulValueLen; + + error = nssCKFWObject_SetAttribute(fwObject, fwSession, + pTemplate[i].type, &value); + + if( CKR_OK != error ) { + goto loser; + } + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_ATTRIBUTE_READ_ONLY: + case CKR_ATTRIBUTE_TYPE_INVALID: + case CKR_ATTRIBUTE_VALUE_INVALID: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OBJECT_HANDLE_INVALID: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SESSION_READ_ONLY: + case CKR_TEMPLATE_INCONSISTENT: + case CKR_TOKEN_WRITE_PROTECTED: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_FindObjectsInit + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_FindObjectsInit +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWFindObjects *fwFindObjects; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + if( ((CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate) && (ulCount != 0) ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error); + if (fwFindObjects) { + error = CKR_OPERATION_ACTIVE; + goto loser; + } + + if( CKR_OPERATION_NOT_INITIALIZED != error ) { + goto loser; + } + + fwFindObjects = nssCKFWSession_FindObjectsInit(fwSession, + pTemplate, ulCount, &error); + if (!fwFindObjects) { + goto loser; + } + + error = nssCKFWSession_SetFWFindObjects(fwSession, fwFindObjects); + + if( CKR_OK != error ) { + nssCKFWFindObjects_Destroy(fwFindObjects); + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_ATTRIBUTE_TYPE_INVALID: + case CKR_ATTRIBUTE_VALUE_INVALID: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_ACTIVE: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_FindObjects + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_FindObjects +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE_PTR phObject, + CK_ULONG ulMaxObjectCount, + CK_ULONG_PTR pulObjectCount +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWFindObjects *fwFindObjects; + CK_ULONG i; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phObject ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + /* + * A purify error here indicates caller error. + */ + (void)nsslibc_memset(phObject, 0, sizeof(CK_OBJECT_HANDLE) * ulMaxObjectCount); + *pulObjectCount = (CK_ULONG)0; + + fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error); + if (!fwFindObjects) { + goto loser; + } + + for( i = 0; i < ulMaxObjectCount; i++ ) { + NSSCKFWObject *fwObject = nssCKFWFindObjects_Next(fwFindObjects, + NULL, &error); + if (!fwObject) { + break; + } + + phObject[i] = nssCKFWInstance_FindObjectHandle(fwInstance, fwObject); + if( (CK_OBJECT_HANDLE)0 == phObject[i] ) { + phObject[i] = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error); + } + if( (CK_OBJECT_HANDLE)0 == phObject[i] ) { + /* This isn't right either, is it? */ + nssCKFWObject_Destroy(fwObject); + goto loser; + } + } + + *pulObjectCount = i; + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_FindObjectsFinal + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_FindObjectsFinal +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWFindObjects *fwFindObjects; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error); + if (!fwFindObjects) { + error = CKR_OPERATION_NOT_INITIALIZED; + goto loser; + } + + nssCKFWFindObjects_Destroy(fwFindObjects); + error = nssCKFWSession_SetFWFindObjects(fwSession, + (NSSCKFWFindObjects *)NULL); + + if( CKR_OK != error ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_EncryptInit + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_EncryptInit +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken; + NSSCKFWMechanism *fwMechanism; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey); + if (!fwObject) { + error = CKR_KEY_HANDLE_INVALID; + goto loser; + } + + fwSlot = nssCKFWSession_GetFWSlot(fwSession); + if (!fwSlot) { + error = CKR_GENERAL_ERROR; /* should never happen! */ + goto loser; + } + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error); + if (!fwMechanism) { + goto loser; + } + + error = nssCKFWMechanism_EncryptInit(fwMechanism, pMechanism, + fwSession, fwObject); + + nssCKFWMechanism_Destroy(fwMechanism); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_KEY_FUNCTION_NOT_PERMITTED: + case CKR_KEY_HANDLE_INVALID: + case CKR_KEY_SIZE_RANGE: + case CKR_KEY_TYPE_INCONSISTENT: + case CKR_MECHANISM_INVALID: + case CKR_MECHANISM_PARAM_INVALID: + case CKR_OPERATION_ACTIVE: + case CKR_PIN_EXPIRED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_Encrypt + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_Encrypt +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pEncryptedData, + CK_ULONG_PTR pulEncryptedDataLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_UpdateFinal(fwSession, + NSSCKFWCryptoOperationType_Encrypt, + NSSCKFWCryptoOperationState_EncryptDecrypt, + pData, ulDataLen, pEncryptedData, pulEncryptedDataLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_INVALID: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SESSION_CLOSED: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_EncryptUpdate + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_EncryptUpdate +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_Update(fwSession, + NSSCKFWCryptoOperationType_Encrypt, + NSSCKFWCryptoOperationState_EncryptDecrypt, + pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_EncryptFinal + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_EncryptFinal +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pLastEncryptedPart, + CK_ULONG_PTR pulLastEncryptedPartLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_Final(fwSession, + NSSCKFWCryptoOperationType_Encrypt, + NSSCKFWCryptoOperationState_EncryptDecrypt, + pLastEncryptedPart, pulLastEncryptedPartLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_DecryptInit + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_DecryptInit +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken; + NSSCKFWMechanism *fwMechanism; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey); + if (!fwObject) { + error = CKR_KEY_HANDLE_INVALID; + goto loser; + } + + fwSlot = nssCKFWSession_GetFWSlot(fwSession); + if (!fwSlot) { + error = CKR_GENERAL_ERROR; /* should never happen! */ + goto loser; + } + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error); + if (!fwMechanism) { + goto loser; + } + + error = nssCKFWMechanism_DecryptInit(fwMechanism, pMechanism, + fwSession, fwObject); + nssCKFWMechanism_Destroy(fwMechanism); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_KEY_FUNCTION_NOT_PERMITTED: + case CKR_KEY_HANDLE_INVALID: + case CKR_KEY_SIZE_RANGE: + case CKR_KEY_TYPE_INCONSISTENT: + case CKR_MECHANISM_INVALID: + case CKR_MECHANISM_PARAM_INVALID: + case CKR_OPERATION_ACTIVE: + case CKR_PIN_EXPIRED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_Decrypt + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_Decrypt +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedData, + CK_ULONG ulEncryptedDataLen, + CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_UpdateFinal(fwSession, + NSSCKFWCryptoOperationType_Decrypt, + NSSCKFWCryptoOperationState_EncryptDecrypt, + pEncryptedData, ulEncryptedDataLen, pData, pulDataLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_ENCRYPTED_DATA_INVALID: + case CKR_ENCRYPTED_DATA_LEN_RANGE: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + case CKR_DATA_LEN_RANGE: + error = CKR_ENCRYPTED_DATA_LEN_RANGE; + break; + case CKR_DATA_INVALID: + error = CKR_ENCRYPTED_DATA_INVALID; + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_DecryptUpdate + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_DecryptUpdate +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, + CK_ULONG_PTR pulPartLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_Update(fwSession, + NSSCKFWCryptoOperationType_Decrypt, + NSSCKFWCryptoOperationState_EncryptDecrypt, + pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_ENCRYPTED_DATA_INVALID: + case CKR_ENCRYPTED_DATA_LEN_RANGE: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + case CKR_DATA_LEN_RANGE: + error = CKR_ENCRYPTED_DATA_LEN_RANGE; + break; + case CKR_DATA_INVALID: + error = CKR_ENCRYPTED_DATA_INVALID; + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_DecryptFinal + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_DecryptFinal +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pLastPart, + CK_ULONG_PTR pulLastPartLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_Final(fwSession, + NSSCKFWCryptoOperationType_Decrypt, + NSSCKFWCryptoOperationState_EncryptDecrypt, + pLastPart, pulLastPartLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_FAILED: + case CKR_FUNCTION_CANCELED: + case CKR_ENCRYPTED_DATA_INVALID: + case CKR_ENCRYPTED_DATA_LEN_RANGE: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + case CKR_DATA_LEN_RANGE: + error = CKR_ENCRYPTED_DATA_LEN_RANGE; + break; + case CKR_DATA_INVALID: + error = CKR_ENCRYPTED_DATA_INVALID; + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_DigestInit + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_DigestInit +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken; + NSSCKFWMechanism *fwMechanism; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwSlot = nssCKFWSession_GetFWSlot(fwSession); + if (!fwSlot) { + error = CKR_GENERAL_ERROR; /* should never happen! */ + goto loser; + } + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error); + if (!fwMechanism) { + goto loser; + } + + error = nssCKFWMechanism_DigestInit(fwMechanism, pMechanism, fwSession); + + nssCKFWMechanism_Destroy(fwMechanism); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_MECHANISM_INVALID: + case CKR_MECHANISM_PARAM_INVALID: + case CKR_OPERATION_ACTIVE: + case CKR_PIN_EXPIRED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_Digest + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_Digest +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_UpdateFinal(fwSession, + NSSCKFWCryptoOperationType_Digest, + NSSCKFWCryptoOperationState_Digest, + pData, ulDataLen, pDigest, pulDigestLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_DigestUpdate + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_DigestUpdate +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_DigestUpdate(fwSession, + NSSCKFWCryptoOperationType_Digest, + NSSCKFWCryptoOperationState_Digest, + pData, ulDataLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_DigestKey + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_DigestKey +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hKey +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey); + if (!fwObject) { + error = CKR_KEY_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_DigestKey(fwSession, fwObject); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_KEY_HANDLE_INVALID: + case CKR_KEY_INDIGESTIBLE: + case CKR_KEY_SIZE_RANGE: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_DigestFinal + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_DigestFinal +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_Final(fwSession, + NSSCKFWCryptoOperationType_Digest, + NSSCKFWCryptoOperationState_Digest, + pDigest, pulDigestLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_SignInit + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_SignInit +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken; + NSSCKFWMechanism *fwMechanism; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey); + if (!fwObject) { + error = CKR_KEY_HANDLE_INVALID; + goto loser; + } + + fwSlot = nssCKFWSession_GetFWSlot(fwSession); + if (!fwSlot) { + error = CKR_GENERAL_ERROR; /* should never happen! */ + goto loser; + } + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error); + if (!fwMechanism) { + goto loser; + } + + error = nssCKFWMechanism_SignInit(fwMechanism, pMechanism, fwSession, + fwObject); + + nssCKFWMechanism_Destroy(fwMechanism); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_KEY_FUNCTION_NOT_PERMITTED: + case CKR_KEY_HANDLE_INVALID: + case CKR_KEY_SIZE_RANGE: + case CKR_KEY_TYPE_INCONSISTENT: + case CKR_MECHANISM_INVALID: + case CKR_MECHANISM_PARAM_INVALID: + case CKR_OPERATION_ACTIVE: + case CKR_PIN_EXPIRED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_Sign + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_Sign +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_UpdateFinal(fwSession, + NSSCKFWCryptoOperationType_Sign, + NSSCKFWCryptoOperationState_SignVerify, + pData, ulDataLen, pSignature, pulSignatureLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_INVALID: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + case CKR_FUNCTION_REJECTED: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_SignUpdate + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_SignUpdate +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_DigestUpdate(fwSession, + NSSCKFWCryptoOperationType_Sign, + NSSCKFWCryptoOperationState_SignVerify, + pPart, ulPartLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_SignFinal + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_SignFinal +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_Final(fwSession, + NSSCKFWCryptoOperationType_Sign, + NSSCKFWCryptoOperationState_SignVerify, + pSignature, pulSignatureLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + case CKR_FUNCTION_REJECTED: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_SignRecoverInit + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_SignRecoverInit +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken; + NSSCKFWMechanism *fwMechanism; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey); + if (!fwObject) { + error = CKR_KEY_HANDLE_INVALID; + goto loser; + } + + fwSlot = nssCKFWSession_GetFWSlot(fwSession); + if (!fwSlot) { + error = CKR_GENERAL_ERROR; /* should never happen! */ + goto loser; + } + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error); + if (!fwMechanism) { + goto loser; + } + + error = nssCKFWMechanism_SignRecoverInit(fwMechanism, pMechanism, fwSession, + fwObject); + + nssCKFWMechanism_Destroy(fwMechanism); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_KEY_FUNCTION_NOT_PERMITTED: + case CKR_KEY_HANDLE_INVALID: + case CKR_KEY_SIZE_RANGE: + case CKR_KEY_TYPE_INCONSISTENT: + case CKR_MECHANISM_INVALID: + case CKR_MECHANISM_PARAM_INVALID: + case CKR_OPERATION_ACTIVE: + case CKR_PIN_EXPIRED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_SignRecover + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_SignRecover +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_UpdateFinal(fwSession, + NSSCKFWCryptoOperationType_SignRecover, + NSSCKFWCryptoOperationState_SignVerify, + pData, ulDataLen, pSignature, pulSignatureLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_INVALID: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_VerifyInit + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_VerifyInit +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken; + NSSCKFWMechanism *fwMechanism; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey); + if (!fwObject) { + error = CKR_KEY_HANDLE_INVALID; + goto loser; + } + + fwSlot = nssCKFWSession_GetFWSlot(fwSession); + if (!fwSlot) { + error = CKR_GENERAL_ERROR; /* should never happen! */ + goto loser; + } + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error); + if (!fwMechanism) { + goto loser; + } + + error = nssCKFWMechanism_VerifyInit(fwMechanism, pMechanism, fwSession, + fwObject); + + nssCKFWMechanism_Destroy(fwMechanism); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_KEY_FUNCTION_NOT_PERMITTED: + case CKR_KEY_HANDLE_INVALID: + case CKR_KEY_SIZE_RANGE: + case CKR_KEY_TYPE_INCONSISTENT: + case CKR_MECHANISM_INVALID: + case CKR_MECHANISM_PARAM_INVALID: + case CKR_OPERATION_ACTIVE: + case CKR_PIN_EXPIRED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_Verify + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_Verify +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_UpdateFinal(fwSession, + NSSCKFWCryptoOperationType_Verify, + NSSCKFWCryptoOperationState_SignVerify, + pData, ulDataLen, pSignature, &ulSignatureLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_INVALID: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SIGNATURE_INVALID: + case CKR_SIGNATURE_LEN_RANGE: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_VerifyUpdate + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_VerifyUpdate +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_DigestUpdate(fwSession, + NSSCKFWCryptoOperationType_Verify, + NSSCKFWCryptoOperationState_SignVerify, + pPart, ulPartLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_VerifyFinal + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_VerifyFinal +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_Final(fwSession, + NSSCKFWCryptoOperationType_Verify, + NSSCKFWCryptoOperationState_SignVerify, + pSignature, &ulSignatureLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SIGNATURE_INVALID: + case CKR_SIGNATURE_LEN_RANGE: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_VerifyRecoverInit + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_VerifyRecoverInit +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken; + NSSCKFWMechanism *fwMechanism; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey); + if (!fwObject) { + error = CKR_KEY_HANDLE_INVALID; + goto loser; + } + + fwSlot = nssCKFWSession_GetFWSlot(fwSession); + if (!fwSlot) { + error = CKR_GENERAL_ERROR; /* should never happen! */ + goto loser; + } + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error); + if (!fwMechanism) { + goto loser; + } + + error = nssCKFWMechanism_VerifyRecoverInit(fwMechanism, pMechanism, + fwSession, fwObject); + + nssCKFWMechanism_Destroy(fwMechanism); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_KEY_FUNCTION_NOT_PERMITTED: + case CKR_KEY_HANDLE_INVALID: + case CKR_KEY_SIZE_RANGE: + case CKR_KEY_TYPE_INCONSISTENT: + case CKR_MECHANISM_INVALID: + case CKR_MECHANISM_PARAM_INVALID: + case CKR_OPERATION_ACTIVE: + case CKR_PIN_EXPIRED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SESSION_CLOSED: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_VerifyRecover + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_VerifyRecover +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen, + CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_UpdateFinal(fwSession, + NSSCKFWCryptoOperationType_VerifyRecover, + NSSCKFWCryptoOperationState_SignVerify, + pSignature, ulSignatureLen, pData, pulDataLen); + if (CKR_OK == error) { + return CKR_OK; + } +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_INVALID: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SIGNATURE_INVALID: + case CKR_SIGNATURE_LEN_RANGE: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_DigestEncryptUpdate + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_DigestEncryptUpdate +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_UpdateCombo(fwSession, + NSSCKFWCryptoOperationType_Encrypt, + NSSCKFWCryptoOperationType_Digest, + NSSCKFWCryptoOperationState_Digest, + pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_DecryptDigestUpdate + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_DecryptDigestUpdate +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, + CK_ULONG_PTR pulPartLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_UpdateCombo(fwSession, + NSSCKFWCryptoOperationType_Decrypt, + NSSCKFWCryptoOperationType_Digest, + NSSCKFWCryptoOperationState_Digest, + pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_ENCRYPTED_DATA_INVALID: + case CKR_ENCRYPTED_DATA_LEN_RANGE: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + break; + case CKR_DATA_INVALID: + error = CKR_ENCRYPTED_DATA_INVALID; + break; + case CKR_DATA_LEN_RANGE: + error = CKR_ENCRYPTED_DATA_LEN_RANGE; + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_SignEncryptUpdate + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_SignEncryptUpdate +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_UpdateCombo(fwSession, + NSSCKFWCryptoOperationType_Encrypt, + NSSCKFWCryptoOperationType_Sign, + NSSCKFWCryptoOperationState_SignVerify, + pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_DecryptVerifyUpdate + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_DecryptVerifyUpdate +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, + CK_ULONG_PTR pulPartLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + error = nssCKFWSession_UpdateCombo(fwSession, + NSSCKFWCryptoOperationType_Decrypt, + NSSCKFWCryptoOperationType_Verify, + NSSCKFWCryptoOperationState_SignVerify, + pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DATA_LEN_RANGE: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_ENCRYPTED_DATA_INVALID: + case CKR_ENCRYPTED_DATA_LEN_RANGE: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_NOT_INITIALIZED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + break; + case CKR_DATA_INVALID: + error = CKR_ENCRYPTED_DATA_INVALID; + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_GenerateKey + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GenerateKey +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken; + NSSCKFWMechanism *fwMechanism; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwSlot = nssCKFWSession_GetFWSlot(fwSession); + if (!fwSlot) { + error = CKR_GENERAL_ERROR; /* should never happen! */ + goto loser; + } + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error); + if (!fwMechanism) { + goto loser; + } + + fwObject = nssCKFWMechanism_GenerateKey( + fwMechanism, + pMechanism, + fwSession, + pTemplate, + ulCount, + &error); + + nssCKFWMechanism_Destroy(fwMechanism); + if (!fwObject) { + goto loser; + } + *phKey= nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_ATTRIBUTE_READ_ONLY: + case CKR_ATTRIBUTE_TYPE_INVALID: + case CKR_ATTRIBUTE_VALUE_INVALID: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_MECHANISM_INVALID: + case CKR_MECHANISM_PARAM_INVALID: + case CKR_OPERATION_ACTIVE: + case CKR_PIN_EXPIRED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SESSION_READ_ONLY: + case CKR_TEMPLATE_INCOMPLETE: + case CKR_TEMPLATE_INCONSISTENT: + case CKR_TOKEN_WRITE_PROTECTED: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_GenerateKeyPair + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GenerateKeyPair +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG ulPublicKeyAttributeCount, + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG ulPrivateKeyAttributeCount, + CK_OBJECT_HANDLE_PTR phPublicKey, + CK_OBJECT_HANDLE_PTR phPrivateKey +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwPrivateKeyObject; + NSSCKFWObject *fwPublicKeyObject; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken; + NSSCKFWMechanism *fwMechanism; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwSlot = nssCKFWSession_GetFWSlot(fwSession); + if (!fwSlot) { + error = CKR_GENERAL_ERROR; /* should never happen! */ + goto loser; + } + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error); + if (!fwMechanism) { + goto loser; + } + + error= nssCKFWMechanism_GenerateKeyPair( + fwMechanism, + pMechanism, + fwSession, + pPublicKeyTemplate, + ulPublicKeyAttributeCount, + pPublicKeyTemplate, + ulPublicKeyAttributeCount, + &fwPublicKeyObject, + &fwPrivateKeyObject); + + nssCKFWMechanism_Destroy(fwMechanism); + if (CKR_OK != error) { + goto loser; + } + *phPublicKey = nssCKFWInstance_CreateObjectHandle(fwInstance, + fwPublicKeyObject, + &error); + if (CKR_OK != error) { + goto loser; + } + *phPrivateKey = nssCKFWInstance_CreateObjectHandle(fwInstance, + fwPrivateKeyObject, + &error); + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_ATTRIBUTE_READ_ONLY: + case CKR_ATTRIBUTE_TYPE_INVALID: + case CKR_ATTRIBUTE_VALUE_INVALID: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_DOMAIN_PARAMS_INVALID: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_MECHANISM_INVALID: + case CKR_MECHANISM_PARAM_INVALID: + case CKR_OPERATION_ACTIVE: + case CKR_PIN_EXPIRED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SESSION_READ_ONLY: + case CKR_TEMPLATE_INCOMPLETE: + case CKR_TEMPLATE_INCONSISTENT: + case CKR_TOKEN_WRITE_PROTECTED: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_WrapKey + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_WrapKey +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hWrappingKey, + CK_OBJECT_HANDLE hKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG_PTR pulWrappedKeyLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwKeyObject; + NSSCKFWObject *fwWrappingKeyObject; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken; + NSSCKFWMechanism *fwMechanism; + NSSItem wrappedKey; + CK_ULONG wrappedKeyLength = 0; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwWrappingKeyObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, + hWrappingKey); + if (!fwWrappingKeyObject) { + error = CKR_WRAPPING_KEY_HANDLE_INVALID; + goto loser; + } + + fwKeyObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hKey); + if (!fwKeyObject) { + error = CKR_KEY_HANDLE_INVALID; + goto loser; + } + + fwSlot = nssCKFWSession_GetFWSlot(fwSession); + if (!fwSlot) { + error = CKR_GENERAL_ERROR; /* should never happen! */ + goto loser; + } + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error); + if (!fwMechanism) { + goto loser; + } + + /* + * first get the length... + */ + wrappedKeyLength = nssCKFWMechanism_GetWrapKeyLength( + fwMechanism, + pMechanism, + fwSession, + fwWrappingKeyObject, + fwKeyObject, + &error); + if ((CK_ULONG) 0 == wrappedKeyLength) { + nssCKFWMechanism_Destroy(fwMechanism); + goto loser; + } + if ((CK_BYTE_PTR)NULL == pWrappedKey) { + *pulWrappedKeyLen = wrappedKeyLength; + nssCKFWMechanism_Destroy(fwMechanism); + return CKR_OK; + } + if (wrappedKeyLength > *pulWrappedKeyLen) { + *pulWrappedKeyLen = wrappedKeyLength; + nssCKFWMechanism_Destroy(fwMechanism); + error = CKR_BUFFER_TOO_SMALL; + goto loser; + } + + + wrappedKey.data = pWrappedKey; + wrappedKey.size = wrappedKeyLength; + + error = nssCKFWMechanism_WrapKey( + fwMechanism, + pMechanism, + fwSession, + fwWrappingKeyObject, + fwKeyObject, + &wrappedKey); + + nssCKFWMechanism_Destroy(fwMechanism); + *pulWrappedKeyLen = wrappedKey.size; + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_KEY_HANDLE_INVALID: + case CKR_KEY_NOT_WRAPPABLE: + case CKR_KEY_SIZE_RANGE: + case CKR_KEY_UNEXTRACTABLE: + case CKR_MECHANISM_INVALID: + case CKR_MECHANISM_PARAM_INVALID: + case CKR_OPERATION_ACTIVE: + case CKR_PIN_EXPIRED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_WRAPPING_KEY_HANDLE_INVALID: + case CKR_WRAPPING_KEY_SIZE_RANGE: + case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: + break; + case CKR_KEY_TYPE_INCONSISTENT: + error = CKR_WRAPPING_KEY_TYPE_INCONSISTENT; + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_UnwrapKey + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_UnwrapKey +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hUnwrappingKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + NSSCKFWObject *fwWrappingKeyObject; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken; + NSSCKFWMechanism *fwMechanism; + NSSItem wrappedKey; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwWrappingKeyObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, + hUnwrappingKey); + if (!fwWrappingKeyObject) { + error = CKR_WRAPPING_KEY_HANDLE_INVALID; + goto loser; + } + + fwSlot = nssCKFWSession_GetFWSlot(fwSession); + if (!fwSlot) { + error = CKR_GENERAL_ERROR; /* should never happen! */ + goto loser; + } + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error); + if (!fwMechanism) { + goto loser; + } + + wrappedKey.data = pWrappedKey; + wrappedKey.size = ulWrappedKeyLen; + + fwObject = nssCKFWMechanism_UnwrapKey( + fwMechanism, + pMechanism, + fwSession, + fwWrappingKeyObject, + &wrappedKey, + pTemplate, + ulAttributeCount, + &error); + + nssCKFWMechanism_Destroy(fwMechanism); + if (!fwObject) { + goto loser; + } + *phKey = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_ATTRIBUTE_READ_ONLY: + case CKR_ATTRIBUTE_TYPE_INVALID: + case CKR_ATTRIBUTE_VALUE_INVALID: + case CKR_BUFFER_TOO_SMALL: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_DOMAIN_PARAMS_INVALID: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_MECHANISM_INVALID: + case CKR_MECHANISM_PARAM_INVALID: + case CKR_OPERATION_ACTIVE: + case CKR_PIN_EXPIRED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SESSION_READ_ONLY: + case CKR_TEMPLATE_INCOMPLETE: + case CKR_TEMPLATE_INCONSISTENT: + case CKR_TOKEN_WRITE_PROTECTED: + case CKR_UNWRAPPING_KEY_HANDLE_INVALID: + case CKR_UNWRAPPING_KEY_SIZE_RANGE: + case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: + case CKR_USER_NOT_LOGGED_IN: + case CKR_WRAPPED_KEY_INVALID: + case CKR_WRAPPED_KEY_LEN_RANGE: + break; + case CKR_KEY_HANDLE_INVALID: + error = CKR_UNWRAPPING_KEY_HANDLE_INVALID; + break; + case CKR_KEY_SIZE_RANGE: + error = CKR_UNWRAPPING_KEY_SIZE_RANGE; + break; + case CKR_KEY_TYPE_INCONSISTENT: + error = CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT; + break; + case CKR_ENCRYPTED_DATA_INVALID: + error = CKR_WRAPPED_KEY_INVALID; + break; + case CKR_ENCRYPTED_DATA_LEN_RANGE: + error = CKR_WRAPPED_KEY_LEN_RANGE; + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_DeriveKey + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_DeriveKey +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hBaseKey, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSCKFWObject *fwObject; + NSSCKFWObject *fwBaseKeyObject; + NSSCKFWSlot *fwSlot; + NSSCKFWToken *fwToken; + NSSCKFWMechanism *fwMechanism; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + fwBaseKeyObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hBaseKey); + if (!fwBaseKeyObject) { + error = CKR_KEY_HANDLE_INVALID; + goto loser; + } + + fwSlot = nssCKFWSession_GetFWSlot(fwSession); + if (!fwSlot) { + error = CKR_GENERAL_ERROR; /* should never happen! */ + goto loser; + } + + if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) { + error = CKR_TOKEN_NOT_PRESENT; + goto loser; + } + + fwToken = nssCKFWSlot_GetToken(fwSlot, &error); + if (!fwToken) { + goto loser; + } + + fwMechanism = nssCKFWToken_GetMechanism(fwToken, pMechanism->mechanism, &error); + if (!fwMechanism) { + goto loser; + } + + fwObject = nssCKFWMechanism_DeriveKey( + fwMechanism, + pMechanism, + fwSession, + fwBaseKeyObject, + pTemplate, + ulAttributeCount, + &error); + + nssCKFWMechanism_Destroy(fwMechanism); + if (!fwObject) { + goto loser; + } + *phKey = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error); + + if (CKR_OK == error) { + return CKR_OK; + } + +loser: + /* verify error */ + switch( error ) { + case CKR_ARGUMENTS_BAD: + case CKR_ATTRIBUTE_READ_ONLY: + case CKR_ATTRIBUTE_TYPE_INVALID: + case CKR_ATTRIBUTE_VALUE_INVALID: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_DEVICE_REMOVED: + case CKR_DOMAIN_PARAMS_INVALID: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_KEY_HANDLE_INVALID: + case CKR_KEY_SIZE_RANGE: + case CKR_KEY_TYPE_INCONSISTENT: + case CKR_MECHANISM_INVALID: + case CKR_MECHANISM_PARAM_INVALID: + case CKR_OPERATION_ACTIVE: + case CKR_PIN_EXPIRED: + case CKR_SESSION_CLOSED: + case CKR_SESSION_HANDLE_INVALID: + case CKR_SESSION_READ_ONLY: + case CKR_TEMPLATE_INCOMPLETE: + case CKR_TEMPLATE_INCONSISTENT: + case CKR_TOKEN_WRITE_PROTECTED: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + return error; +} + +/* + * NSSCKFWC_SeedRandom + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_SeedRandom +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSeed, + CK_ULONG ulSeedLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSItem seed; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + if( (CK_BYTE_PTR)CK_NULL_PTR == pSeed ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + /* We could read through the buffer in a Purify trap */ + + seed.size = (PRUint32)ulSeedLen; + seed.data = (void *)pSeed; + + error = nssCKFWSession_SeedRandom(fwSession, &seed); + + if( CKR_OK != error ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_ACTIVE: + case CKR_RANDOM_SEED_NOT_SUPPORTED: + case CKR_RANDOM_NO_RNG: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_GenerateRandom + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GenerateRandom +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pRandomData, + CK_ULONG ulRandomLen +) +{ + CK_RV error = CKR_OK; + NSSCKFWSession *fwSession; + NSSItem buffer; + + if (!fwInstance) { + error = CKR_CRYPTOKI_NOT_INITIALIZED; + goto loser; + } + + fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession); + if (!fwSession) { + error = CKR_SESSION_HANDLE_INVALID; + goto loser; + } + + if( (CK_BYTE_PTR)CK_NULL_PTR == pRandomData ) { + error = CKR_ARGUMENTS_BAD; + goto loser; + } + + /* + * A purify error here indicates caller error. + */ + (void)nsslibc_memset(pRandomData, 0, ulRandomLen); + + buffer.size = (PRUint32)ulRandomLen; + buffer.data = (void *)pRandomData; + + error = nssCKFWSession_GetRandom(fwSession, &buffer); + + if( CKR_OK != error ) { + goto loser; + } + + return CKR_OK; + + loser: + switch( error ) { + case CKR_SESSION_CLOSED: + /* destroy session? */ + break; + case CKR_DEVICE_REMOVED: + /* (void)nssCKFWToken_Destroy(fwToken); */ + break; + case CKR_ARGUMENTS_BAD: + case CKR_CRYPTOKI_NOT_INITIALIZED: + case CKR_DEVICE_ERROR: + case CKR_DEVICE_MEMORY: + case CKR_FUNCTION_CANCELED: + case CKR_FUNCTION_FAILED: + case CKR_GENERAL_ERROR: + case CKR_HOST_MEMORY: + case CKR_OPERATION_ACTIVE: + case CKR_RANDOM_NO_RNG: + case CKR_SESSION_HANDLE_INVALID: + case CKR_USER_NOT_LOGGED_IN: + break; + default: + case CKR_OK: + error = CKR_GENERAL_ERROR; + break; + } + + return error; +} + +/* + * NSSCKFWC_GetFunctionStatus + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_GetFunctionStatus +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession +) +{ + return CKR_FUNCTION_NOT_PARALLEL; +} + +/* + * NSSCKFWC_CancelFunction + * + */ +NSS_IMPLEMENT CK_RV +NSSCKFWC_CancelFunction +( + NSSCKFWInstance *fwInstance, + CK_SESSION_HANDLE hSession +) +{ + return CKR_FUNCTION_NOT_PARALLEL; +}