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