andre@0: /* This Source Code Form is subject to the terms of the Mozilla Public andre@0: * License, v. 2.0. If a copy of the MPL was not distributed with this andre@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ andre@0: andre@0: /* andre@0: * object.c andre@0: * andre@0: * This file implements the NSSCKFWObject type and methods. andre@0: */ andre@0: andre@0: #ifndef CK_T andre@0: #include "ck.h" andre@0: #endif /* CK_T */ andre@0: andre@0: /* andre@0: * NSSCKFWObject andre@0: * andre@0: * -- create/destroy -- andre@0: * nssCKFWObject_Create andre@0: * nssCKFWObject_Finalize andre@0: * nssCKFWObject_Destroy andre@0: * andre@0: * -- public accessors -- andre@0: * NSSCKFWObject_GetMDObject andre@0: * NSSCKFWObject_GetArena andre@0: * NSSCKFWObject_IsTokenObject andre@0: * NSSCKFWObject_GetAttributeCount andre@0: * NSSCKFWObject_GetAttributeTypes andre@0: * NSSCKFWObject_GetAttributeSize andre@0: * NSSCKFWObject_GetAttribute andre@0: * NSSCKFWObject_SetAttribute andre@0: * NSSCKFWObject_GetObjectSize andre@0: * andre@0: * -- implement public accessors -- andre@0: * nssCKFWObject_GetMDObject andre@0: * nssCKFWObject_GetArena andre@0: * andre@0: * -- private accessors -- andre@0: * nssCKFWObject_SetHandle andre@0: * nssCKFWObject_GetHandle andre@0: * andre@0: * -- module fronts -- andre@0: * nssCKFWObject_IsTokenObject andre@0: * nssCKFWObject_GetAttributeCount andre@0: * nssCKFWObject_GetAttributeTypes andre@0: * nssCKFWObject_GetAttributeSize andre@0: * nssCKFWObject_GetAttribute andre@0: * nssCKFWObject_SetAttribute andre@0: * nssCKFWObject_GetObjectSize andre@0: */ andre@0: andre@0: struct NSSCKFWObjectStr { andre@0: NSSCKFWMutex *mutex; /* merely to serialise the MDObject calls */ andre@0: NSSArena *arena; andre@0: NSSCKMDObject *mdObject; andre@0: NSSCKMDSession *mdSession; andre@0: NSSCKFWSession *fwSession; andre@0: NSSCKMDToken *mdToken; andre@0: NSSCKFWToken *fwToken; andre@0: NSSCKMDInstance *mdInstance; andre@0: NSSCKFWInstance *fwInstance; andre@0: CK_OBJECT_HANDLE hObject; andre@0: }; andre@0: andre@0: #ifdef DEBUG andre@0: /* andre@0: * But first, the pointer-tracking stuff. andre@0: * andre@0: * NOTE: the pointer-tracking support in NSS/base currently relies andre@0: * upon NSPR's CallOnce support. That, however, relies upon NSPR's andre@0: * locking, which is tied into the runtime. We need a pointer-tracker andre@0: * implementation that uses the locks supplied through C_Initialize. andre@0: * That support, however, can be filled in later. So for now, I'll andre@0: * just do this routines as no-ops. andre@0: */ andre@0: andre@0: static CK_RV andre@0: object_add_pointer andre@0: ( andre@0: const NSSCKFWObject *fwObject andre@0: ) andre@0: { andre@0: return CKR_OK; andre@0: } andre@0: andre@0: static CK_RV andre@0: object_remove_pointer andre@0: ( andre@0: const NSSCKFWObject *fwObject andre@0: ) andre@0: { andre@0: return CKR_OK; andre@0: } andre@0: andre@0: NSS_IMPLEMENT CK_RV andre@0: nssCKFWObject_verifyPointer andre@0: ( andre@0: const NSSCKFWObject *fwObject andre@0: ) andre@0: { andre@0: return CKR_OK; andre@0: } andre@0: andre@0: #endif /* DEBUG */ andre@0: andre@0: andre@0: /* andre@0: * nssCKFWObject_Create andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT NSSCKFWObject * andre@0: nssCKFWObject_Create andre@0: ( andre@0: NSSArena *arena, andre@0: NSSCKMDObject *mdObject, andre@0: NSSCKFWSession *fwSession, andre@0: NSSCKFWToken *fwToken, andre@0: NSSCKFWInstance *fwInstance, andre@0: CK_RV *pError andre@0: ) andre@0: { andre@0: NSSCKFWObject *fwObject; andre@0: nssCKFWHash *mdObjectHash; andre@0: andre@0: #ifdef NSSDEBUG andre@0: if (!pError) { andre@0: return (NSSCKFWObject *)NULL; andre@0: } andre@0: andre@0: if( PR_SUCCESS != nssArena_verifyPointer(arena) ) { andre@0: *pError = CKR_ARGUMENTS_BAD; andre@0: return (NSSCKFWObject *)NULL; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: if (!fwToken) { andre@0: *pError = CKR_ARGUMENTS_BAD; andre@0: return (NSSCKFWObject *)NULL; andre@0: } andre@0: mdObjectHash = nssCKFWToken_GetMDObjectHash(fwToken); andre@0: if (!mdObjectHash) { andre@0: *pError = CKR_GENERAL_ERROR; andre@0: return (NSSCKFWObject *)NULL; andre@0: } andre@0: andre@0: if( nssCKFWHash_Exists(mdObjectHash, mdObject) ) { andre@0: fwObject = nssCKFWHash_Lookup(mdObjectHash, mdObject); andre@0: return fwObject; andre@0: } andre@0: andre@0: fwObject = nss_ZNEW(arena, NSSCKFWObject); andre@0: if (!fwObject) { andre@0: *pError = CKR_HOST_MEMORY; andre@0: return (NSSCKFWObject *)NULL; andre@0: } andre@0: andre@0: fwObject->arena = arena; andre@0: fwObject->mdObject = mdObject; andre@0: fwObject->fwSession = fwSession; andre@0: andre@0: if (fwSession) { andre@0: fwObject->mdSession = nssCKFWSession_GetMDSession(fwSession); andre@0: } andre@0: andre@0: fwObject->fwToken = fwToken; andre@0: fwObject->mdToken = nssCKFWToken_GetMDToken(fwToken); andre@0: fwObject->fwInstance = fwInstance; andre@0: fwObject->mdInstance = nssCKFWInstance_GetMDInstance(fwInstance); andre@0: fwObject->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError); andre@0: if (!fwObject->mutex) { andre@0: if( CKR_OK == *pError ) { andre@0: *pError = CKR_GENERAL_ERROR; andre@0: } andre@0: return (NSSCKFWObject *)NULL; andre@0: } andre@0: andre@0: *pError = nssCKFWHash_Add(mdObjectHash, mdObject, fwObject); andre@0: if( CKR_OK != *pError ) { andre@0: nss_ZFreeIf(fwObject); andre@0: return (NSSCKFWObject *)NULL; andre@0: } andre@0: andre@0: #ifdef DEBUG andre@0: *pError = object_add_pointer(fwObject); andre@0: if( CKR_OK != *pError ) { andre@0: nssCKFWHash_Remove(mdObjectHash, mdObject); andre@0: nss_ZFreeIf(fwObject); andre@0: return (NSSCKFWObject *)NULL; andre@0: } andre@0: #endif /* DEBUG */ andre@0: andre@0: *pError = CKR_OK; andre@0: return fwObject; andre@0: } andre@0: andre@0: /* andre@0: * nssCKFWObject_Finalize andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT void andre@0: nssCKFWObject_Finalize andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: PRBool removeFromHash andre@0: ) andre@0: { andre@0: nssCKFWHash *mdObjectHash; andre@0: andre@0: #ifdef NSSDEBUG andre@0: if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { andre@0: return; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: (void)nssCKFWMutex_Destroy(fwObject->mutex); andre@0: andre@0: if (fwObject->mdObject->Finalize) { andre@0: fwObject->mdObject->Finalize(fwObject->mdObject, fwObject, andre@0: fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, andre@0: fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance); andre@0: } andre@0: andre@0: if (removeFromHash) { andre@0: mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken); andre@0: if (mdObjectHash) { andre@0: nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject); andre@0: } andre@0: } andre@0: andre@0: if (fwObject->fwSession) { andre@0: nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject); andre@0: } andre@0: nss_ZFreeIf(fwObject); andre@0: andre@0: #ifdef DEBUG andre@0: (void)object_remove_pointer(fwObject); andre@0: #endif /* DEBUG */ andre@0: andre@0: return; andre@0: } andre@0: andre@0: /* andre@0: * nssCKFWObject_Destroy andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT void andre@0: nssCKFWObject_Destroy andre@0: ( andre@0: NSSCKFWObject *fwObject andre@0: ) andre@0: { andre@0: nssCKFWHash *mdObjectHash; andre@0: andre@0: #ifdef NSSDEBUG andre@0: if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { andre@0: return; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: (void)nssCKFWMutex_Destroy(fwObject->mutex); andre@0: andre@0: if (fwObject->mdObject->Destroy) { andre@0: fwObject->mdObject->Destroy(fwObject->mdObject, fwObject, andre@0: fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, andre@0: fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance); andre@0: } andre@0: andre@0: mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken); andre@0: if (mdObjectHash) { andre@0: nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject); andre@0: } andre@0: andre@0: if (fwObject->fwSession) { andre@0: nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject); andre@0: } andre@0: nss_ZFreeIf(fwObject); andre@0: andre@0: #ifdef DEBUG andre@0: (void)object_remove_pointer(fwObject); andre@0: #endif /* DEBUG */ andre@0: andre@0: return; andre@0: } andre@0: andre@0: /* andre@0: * nssCKFWObject_GetMDObject andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT NSSCKMDObject * andre@0: nssCKFWObject_GetMDObject andre@0: ( andre@0: NSSCKFWObject *fwObject andre@0: ) andre@0: { andre@0: #ifdef NSSDEBUG andre@0: if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { andre@0: return (NSSCKMDObject *)NULL; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: return fwObject->mdObject; andre@0: } andre@0: andre@0: /* andre@0: * nssCKFWObject_GetArena andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT NSSArena * andre@0: nssCKFWObject_GetArena andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: CK_RV *pError andre@0: ) andre@0: { andre@0: #ifdef NSSDEBUG andre@0: if (!pError) { andre@0: return (NSSArena *)NULL; andre@0: } andre@0: andre@0: *pError = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != *pError ) { andre@0: return (NSSArena *)NULL; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: return fwObject->arena; andre@0: } andre@0: andre@0: /* andre@0: * nssCKFWObject_SetHandle andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT CK_RV andre@0: nssCKFWObject_SetHandle andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: CK_OBJECT_HANDLE hObject andre@0: ) andre@0: { andre@0: #ifdef NSSDEBUG andre@0: CK_RV error = CKR_OK; andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: #ifdef NSSDEBUG andre@0: error = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != error ) { andre@0: return error; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: if( (CK_OBJECT_HANDLE)0 != fwObject->hObject ) { andre@0: return CKR_GENERAL_ERROR; andre@0: } andre@0: andre@0: fwObject->hObject = hObject; andre@0: andre@0: return CKR_OK; andre@0: } andre@0: andre@0: /* andre@0: * nssCKFWObject_GetHandle andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT CK_OBJECT_HANDLE andre@0: nssCKFWObject_GetHandle andre@0: ( andre@0: NSSCKFWObject *fwObject andre@0: ) andre@0: { andre@0: #ifdef NSSDEBUG andre@0: if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { andre@0: return (CK_OBJECT_HANDLE)0; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: return fwObject->hObject; andre@0: } andre@0: andre@0: /* andre@0: * nssCKFWObject_IsTokenObject andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT CK_BBOOL andre@0: nssCKFWObject_IsTokenObject andre@0: ( andre@0: NSSCKFWObject *fwObject andre@0: ) andre@0: { andre@0: CK_BBOOL b = CK_FALSE; andre@0: andre@0: #ifdef NSSDEBUG andre@0: if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { andre@0: return CK_FALSE; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: if (!fwObject->mdObject->IsTokenObject) { andre@0: NSSItem item; andre@0: NSSItem *pItem; andre@0: CK_RV rv = CKR_OK; andre@0: andre@0: item.data = (void *)&b; andre@0: item.size = sizeof(b); andre@0: andre@0: pItem = nssCKFWObject_GetAttribute(fwObject, CKA_TOKEN, &item, andre@0: (NSSArena *)NULL, &rv); andre@0: if (!pItem) { andre@0: /* Error of some type */ andre@0: b = CK_FALSE; andre@0: goto done; andre@0: } andre@0: andre@0: goto done; andre@0: } andre@0: andre@0: b = fwObject->mdObject->IsTokenObject(fwObject->mdObject, fwObject, andre@0: fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, andre@0: fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance); andre@0: andre@0: done: andre@0: return b; andre@0: } andre@0: andre@0: /* andre@0: * nssCKFWObject_GetAttributeCount andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT CK_ULONG andre@0: nssCKFWObject_GetAttributeCount andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: CK_RV *pError andre@0: ) andre@0: { andre@0: CK_ULONG rv; andre@0: andre@0: #ifdef NSSDEBUG andre@0: if (!pError) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: andre@0: *pError = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != *pError ) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: if (!fwObject->mdObject->GetAttributeCount) { andre@0: *pError = CKR_GENERAL_ERROR; andre@0: return (CK_ULONG)0; andre@0: } andre@0: andre@0: *pError = nssCKFWMutex_Lock(fwObject->mutex); andre@0: if( CKR_OK != *pError ) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: andre@0: rv = fwObject->mdObject->GetAttributeCount(fwObject->mdObject, fwObject, andre@0: fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, andre@0: fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance, andre@0: pError); andre@0: andre@0: (void)nssCKFWMutex_Unlock(fwObject->mutex); andre@0: return rv; andre@0: } andre@0: andre@0: /* andre@0: * nssCKFWObject_GetAttributeTypes andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT CK_RV andre@0: nssCKFWObject_GetAttributeTypes andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: CK_ATTRIBUTE_TYPE_PTR typeArray, andre@0: CK_ULONG ulCount andre@0: ) andre@0: { andre@0: CK_RV error = CKR_OK; andre@0: andre@0: #ifdef NSSDEBUG andre@0: error = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != error ) { andre@0: return error; andre@0: } andre@0: andre@0: if( (CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray ) { andre@0: return CKR_ARGUMENTS_BAD; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: if (!fwObject->mdObject->GetAttributeTypes) { andre@0: return CKR_GENERAL_ERROR; andre@0: } andre@0: andre@0: error = nssCKFWMutex_Lock(fwObject->mutex); andre@0: if( CKR_OK != error ) { andre@0: return error; andre@0: } andre@0: andre@0: error = fwObject->mdObject->GetAttributeTypes(fwObject->mdObject, fwObject, andre@0: fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, andre@0: fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance, andre@0: typeArray, ulCount); andre@0: andre@0: (void)nssCKFWMutex_Unlock(fwObject->mutex); andre@0: return error; andre@0: } andre@0: andre@0: /* andre@0: * nssCKFWObject_GetAttributeSize andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT CK_ULONG andre@0: nssCKFWObject_GetAttributeSize andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: CK_ATTRIBUTE_TYPE attribute, andre@0: CK_RV *pError andre@0: ) andre@0: { andre@0: CK_ULONG rv; andre@0: andre@0: #ifdef NSSDEBUG andre@0: if (!pError) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: andre@0: *pError = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != *pError ) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: if (!fwObject->mdObject->GetAttributeSize) { andre@0: *pError = CKR_GENERAL_ERROR; andre@0: return (CK_ULONG )0; andre@0: } andre@0: andre@0: *pError = nssCKFWMutex_Lock(fwObject->mutex); andre@0: if( CKR_OK != *pError ) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: andre@0: rv = fwObject->mdObject->GetAttributeSize(fwObject->mdObject, fwObject, andre@0: fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, andre@0: fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance, andre@0: attribute, pError); andre@0: andre@0: (void)nssCKFWMutex_Unlock(fwObject->mutex); andre@0: return rv; andre@0: } andre@0: andre@0: /* andre@0: * nssCKFWObject_GetAttribute andre@0: * andre@0: * Usual NSS allocation rules: andre@0: * If itemOpt is not NULL, it will be returned; otherwise an NSSItem andre@0: * will be allocated. If itemOpt is not NULL but itemOpt->data is, andre@0: * the buffer will be allocated; otherwise, the buffer will be used. andre@0: * Any allocations will come from the optional arena, if one is andre@0: * specified. andre@0: */ andre@0: NSS_IMPLEMENT NSSItem * andre@0: nssCKFWObject_GetAttribute andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: CK_ATTRIBUTE_TYPE attribute, andre@0: NSSItem *itemOpt, andre@0: NSSArena *arenaOpt, andre@0: CK_RV *pError andre@0: ) andre@0: { andre@0: NSSItem *rv = (NSSItem *)NULL; andre@0: NSSCKFWItem mdItem; andre@0: andre@0: #ifdef NSSDEBUG andre@0: if (!pError) { andre@0: return (NSSItem *)NULL; andre@0: } andre@0: andre@0: *pError = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != *pError ) { andre@0: return (NSSItem *)NULL; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: if (!fwObject->mdObject->GetAttribute) { andre@0: *pError = CKR_GENERAL_ERROR; andre@0: return (NSSItem *)NULL; andre@0: } andre@0: andre@0: *pError = nssCKFWMutex_Lock(fwObject->mutex); andre@0: if( CKR_OK != *pError ) { andre@0: return (NSSItem *)NULL; andre@0: } andre@0: andre@0: mdItem = fwObject->mdObject->GetAttribute(fwObject->mdObject, fwObject, andre@0: fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, andre@0: fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance, andre@0: attribute, pError); andre@0: andre@0: if (!mdItem.item) { andre@0: if( CKR_OK == *pError ) { andre@0: *pError = CKR_GENERAL_ERROR; andre@0: } andre@0: andre@0: goto done; andre@0: } andre@0: andre@0: if (!itemOpt) { andre@0: rv = nss_ZNEW(arenaOpt, NSSItem); andre@0: if (!rv) { andre@0: *pError = CKR_HOST_MEMORY; andre@0: goto done; andre@0: } andre@0: } else { andre@0: rv = itemOpt; andre@0: } andre@0: andre@0: if (!rv->data) { andre@0: rv->size = mdItem.item->size; andre@0: rv->data = nss_ZAlloc(arenaOpt, rv->size); andre@0: if (!rv->data) { andre@0: *pError = CKR_HOST_MEMORY; andre@0: if (!itemOpt) { andre@0: nss_ZFreeIf(rv); andre@0: } andre@0: rv = (NSSItem *)NULL; andre@0: goto done; andre@0: } andre@0: } else { andre@0: if( rv->size >= mdItem.item->size ) { andre@0: rv->size = mdItem.item->size; andre@0: } else { andre@0: *pError = CKR_BUFFER_TOO_SMALL; andre@0: /* Should we set rv->size to mdItem->size? */ andre@0: /* rv can't have been allocated */ andre@0: rv = (NSSItem *)NULL; andre@0: goto done; andre@0: } andre@0: } andre@0: andre@0: (void)nsslibc_memcpy(rv->data, mdItem.item->data, rv->size); andre@0: andre@0: if (PR_TRUE == mdItem.needsFreeing) { andre@0: PR_ASSERT(fwObject->mdObject->FreeAttribute); andre@0: if (fwObject->mdObject->FreeAttribute) { andre@0: *pError = fwObject->mdObject->FreeAttribute(&mdItem); andre@0: } andre@0: } andre@0: andre@0: done: andre@0: (void)nssCKFWMutex_Unlock(fwObject->mutex); andre@0: return rv; andre@0: } andre@0: andre@0: /* andre@0: * nssCKFWObject_SetAttribute andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT CK_RV andre@0: nssCKFWObject_SetAttribute andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: NSSCKFWSession *fwSession, andre@0: CK_ATTRIBUTE_TYPE attribute, andre@0: NSSItem *value andre@0: ) andre@0: { andre@0: CK_RV error = CKR_OK; andre@0: andre@0: #ifdef NSSDEBUG andre@0: error = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != error ) { andre@0: return error; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: if( CKA_TOKEN == attribute ) { andre@0: /* andre@0: * We're changing from a session object to a token object or andre@0: * vice-versa. andre@0: */ andre@0: andre@0: CK_ATTRIBUTE a; andre@0: NSSCKFWObject *newFwObject; andre@0: NSSCKFWObject swab; andre@0: andre@0: a.type = CKA_TOKEN; andre@0: a.pValue = value->data; andre@0: a.ulValueLen = value->size; andre@0: andre@0: newFwObject = nssCKFWSession_CopyObject(fwSession, fwObject, andre@0: &a, 1, &error); andre@0: if (!newFwObject) { andre@0: if( CKR_OK == error ) { andre@0: error = CKR_GENERAL_ERROR; andre@0: } andre@0: return error; andre@0: } andre@0: andre@0: /* andre@0: * Actually, I bet the locking is worse than this.. this part of andre@0: * the code could probably use some scrutiny and reworking. andre@0: */ andre@0: error = nssCKFWMutex_Lock(fwObject->mutex); andre@0: if( CKR_OK != error ) { andre@0: nssCKFWObject_Destroy(newFwObject); andre@0: return error; andre@0: } andre@0: andre@0: error = nssCKFWMutex_Lock(newFwObject->mutex); andre@0: if( CKR_OK != error ) { andre@0: nssCKFWMutex_Unlock(fwObject->mutex); andre@0: nssCKFWObject_Destroy(newFwObject); andre@0: return error; andre@0: } andre@0: andre@0: /* andre@0: * Now, we have our new object, but it has a new fwObject pointer, andre@0: * while we have to keep the existing one. So quick swap the contents. andre@0: */ andre@0: swab = *fwObject; andre@0: *fwObject = *newFwObject; andre@0: *newFwObject = swab; andre@0: andre@0: /* But keep the mutexes the same */ andre@0: swab.mutex = fwObject->mutex; andre@0: fwObject->mutex = newFwObject->mutex; andre@0: newFwObject->mutex = swab.mutex; andre@0: andre@0: (void)nssCKFWMutex_Unlock(newFwObject->mutex); andre@0: (void)nssCKFWMutex_Unlock(fwObject->mutex); andre@0: andre@0: /* andre@0: * Either remove or add this to the list of session objects andre@0: */ andre@0: andre@0: if( CK_FALSE == *(CK_BBOOL *)value->data ) { andre@0: /* andre@0: * New one is a session object, except since we "stole" the fwObject, it's andre@0: * not in the list. Add it. andre@0: */ andre@0: nssCKFWSession_RegisterSessionObject(fwSession, fwObject); andre@0: } else { andre@0: /* andre@0: * New one is a token object, except since we "stole" the fwObject, it's andre@0: * in the list. Remove it. andre@0: */ andre@0: if (fwObject->fwSession) { andre@0: nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject); andre@0: } andre@0: } andre@0: andre@0: /* andre@0: * Now delete the old object. Remember the names have changed. andre@0: */ andre@0: nssCKFWObject_Destroy(newFwObject); andre@0: andre@0: return CKR_OK; andre@0: } else { andre@0: /* andre@0: * An "ordinary" change. andre@0: */ andre@0: if (!fwObject->mdObject->SetAttribute) { andre@0: /* We could fake it with copying, like above.. later */ andre@0: return CKR_ATTRIBUTE_READ_ONLY; andre@0: } andre@0: andre@0: error = nssCKFWMutex_Lock(fwObject->mutex); andre@0: if( CKR_OK != error ) { andre@0: return error; andre@0: } andre@0: andre@0: error = fwObject->mdObject->SetAttribute(fwObject->mdObject, fwObject, andre@0: fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, andre@0: fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance, andre@0: attribute, value); andre@0: andre@0: (void)nssCKFWMutex_Unlock(fwObject->mutex); andre@0: andre@0: return error; andre@0: } andre@0: } andre@0: andre@0: /* andre@0: * nssCKFWObject_GetObjectSize andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT CK_ULONG andre@0: nssCKFWObject_GetObjectSize andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: CK_RV *pError andre@0: ) andre@0: { andre@0: CK_ULONG rv; andre@0: andre@0: #ifdef NSSDEBUG andre@0: if (!pError) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: andre@0: *pError = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != *pError ) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: #endif /* NSSDEBUG */ andre@0: andre@0: if (!fwObject->mdObject->GetObjectSize) { andre@0: *pError = CKR_INFORMATION_SENSITIVE; andre@0: return (CK_ULONG)0; andre@0: } andre@0: andre@0: *pError = nssCKFWMutex_Lock(fwObject->mutex); andre@0: if( CKR_OK != *pError ) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: andre@0: rv = fwObject->mdObject->GetObjectSize(fwObject->mdObject, fwObject, andre@0: fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, andre@0: fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance, andre@0: pError); andre@0: andre@0: (void)nssCKFWMutex_Unlock(fwObject->mutex); andre@0: return rv; andre@0: } andre@0: andre@0: /* andre@0: * NSSCKFWObject_GetMDObject andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT NSSCKMDObject * andre@0: NSSCKFWObject_GetMDObject andre@0: ( andre@0: NSSCKFWObject *fwObject andre@0: ) andre@0: { andre@0: #ifdef DEBUG andre@0: if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { andre@0: return (NSSCKMDObject *)NULL; andre@0: } andre@0: #endif /* DEBUG */ andre@0: andre@0: return nssCKFWObject_GetMDObject(fwObject); andre@0: } andre@0: andre@0: /* andre@0: * NSSCKFWObject_GetArena andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT NSSArena * andre@0: NSSCKFWObject_GetArena andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: CK_RV *pError andre@0: ) andre@0: { andre@0: #ifdef DEBUG andre@0: if (!pError) { andre@0: return (NSSArena *)NULL; andre@0: } andre@0: andre@0: *pError = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != *pError ) { andre@0: return (NSSArena *)NULL; andre@0: } andre@0: #endif /* DEBUG */ andre@0: andre@0: return nssCKFWObject_GetArena(fwObject, pError); andre@0: } andre@0: andre@0: /* andre@0: * NSSCKFWObject_IsTokenObject andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT CK_BBOOL andre@0: NSSCKFWObject_IsTokenObject andre@0: ( andre@0: NSSCKFWObject *fwObject andre@0: ) andre@0: { andre@0: #ifdef DEBUG andre@0: if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { andre@0: return CK_FALSE; andre@0: } andre@0: #endif /* DEBUG */ andre@0: andre@0: return nssCKFWObject_IsTokenObject(fwObject); andre@0: } andre@0: andre@0: /* andre@0: * NSSCKFWObject_GetAttributeCount andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT CK_ULONG andre@0: NSSCKFWObject_GetAttributeCount andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: CK_RV *pError andre@0: ) andre@0: { andre@0: #ifdef DEBUG andre@0: if (!pError) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: andre@0: *pError = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != *pError ) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: #endif /* DEBUG */ andre@0: andre@0: return nssCKFWObject_GetAttributeCount(fwObject, pError); andre@0: } andre@0: andre@0: /* andre@0: * NSSCKFWObject_GetAttributeTypes andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT CK_RV andre@0: NSSCKFWObject_GetAttributeTypes andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: CK_ATTRIBUTE_TYPE_PTR typeArray, andre@0: CK_ULONG ulCount andre@0: ) andre@0: { andre@0: #ifdef DEBUG andre@0: CK_RV error = CKR_OK; andre@0: andre@0: error = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != error ) { andre@0: return error; andre@0: } andre@0: andre@0: if( (CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray ) { andre@0: return CKR_ARGUMENTS_BAD; andre@0: } andre@0: #endif /* DEBUG */ andre@0: andre@0: return nssCKFWObject_GetAttributeTypes(fwObject, typeArray, ulCount); andre@0: } andre@0: andre@0: /* andre@0: * NSSCKFWObject_GetAttributeSize andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT CK_ULONG andre@0: NSSCKFWObject_GetAttributeSize andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: CK_ATTRIBUTE_TYPE attribute, andre@0: CK_RV *pError andre@0: ) andre@0: { andre@0: #ifdef DEBUG andre@0: if (!pError) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: andre@0: *pError = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != *pError ) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: #endif /* DEBUG */ andre@0: andre@0: return nssCKFWObject_GetAttributeSize(fwObject, attribute, pError); andre@0: } andre@0: andre@0: /* andre@0: * NSSCKFWObject_GetAttribute andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT NSSItem * andre@0: NSSCKFWObject_GetAttribute andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: CK_ATTRIBUTE_TYPE attribute, andre@0: NSSItem *itemOpt, andre@0: NSSArena *arenaOpt, andre@0: CK_RV *pError andre@0: ) andre@0: { andre@0: #ifdef DEBUG andre@0: if (!pError) { andre@0: return (NSSItem *)NULL; andre@0: } andre@0: andre@0: *pError = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != *pError ) { andre@0: return (NSSItem *)NULL; andre@0: } andre@0: #endif /* DEBUG */ andre@0: andre@0: return nssCKFWObject_GetAttribute(fwObject, attribute, itemOpt, arenaOpt, pError); andre@0: } andre@0: andre@0: /* andre@0: * NSSCKFWObject_GetObjectSize andre@0: * andre@0: */ andre@0: NSS_IMPLEMENT CK_ULONG andre@0: NSSCKFWObject_GetObjectSize andre@0: ( andre@0: NSSCKFWObject *fwObject, andre@0: CK_RV *pError andre@0: ) andre@0: { andre@0: #ifdef DEBUG andre@0: if (!pError) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: andre@0: *pError = nssCKFWObject_verifyPointer(fwObject); andre@0: if( CKR_OK != *pError ) { andre@0: return (CK_ULONG)0; andre@0: } andre@0: #endif /* DEBUG */ andre@0: andre@0: return nssCKFWObject_GetObjectSize(fwObject, pError); andre@0: }