/* 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.
*/
/* 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;
}
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;
}
if (!*pFwInstance) {
error = CKR_CRYPTOKI_NOT_INITIALIZED; goto loser;
}
error = nssCKFWInstance_Destroy(*pFwInstance);
/* In any case */
*pFwInstance = (NSSCKFWInstance *)NULL;
loser: switch (error) { case CKR_OK: {
PRInt32 remainingInstances;
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;
}
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.
*/
/* * 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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
/* * 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); /* CreateObjectHandle returns CKR_GENERAL_ERROR if fwObject already * has a handle. This happens when another thread creates a handle * between our FindObjectHandle and CreateObjectHandle calls.
*/ if (error == CKR_GENERAL_ERROR) {
error = CKR_OK;
phObject[i] = nssCKFWInstance_FindObjectHandle(fwInstance, fwObject);
} if (error != CKR_OK || (CK_OBJECT_HANDLE)0 == phObject[i]) { 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;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.