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: * sessobj.c michael@0: * michael@0: * This file contains an NSSCKMDObject implementation for session michael@0: * objects. The framework uses this implementation to manage michael@0: * session objects when a Module doesn't wish to be bothered. 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: * nssCKMDSessionObject michael@0: * michael@0: * -- create -- michael@0: * nssCKMDSessionObject_Create michael@0: * michael@0: * -- EPV calls -- michael@0: * nss_ckmdSessionObject_Finalize michael@0: * nss_ckmdSessionObject_IsTokenObject michael@0: * nss_ckmdSessionObject_GetAttributeCount michael@0: * nss_ckmdSessionObject_GetAttributeTypes michael@0: * nss_ckmdSessionObject_GetAttributeSize michael@0: * nss_ckmdSessionObject_GetAttribute michael@0: * nss_ckmdSessionObject_SetAttribute michael@0: * nss_ckmdSessionObject_GetObjectSize michael@0: */ michael@0: michael@0: struct nssCKMDSessionObjectStr { michael@0: CK_ULONG n; michael@0: NSSArena *arena; michael@0: NSSItem *attributes; michael@0: CK_ATTRIBUTE_TYPE_PTR types; michael@0: nssCKFWHash *hash; michael@0: }; michael@0: typedef struct nssCKMDSessionObjectStr nssCKMDSessionObject; 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: nss_ckmdSessionObject_add_pointer michael@0: ( michael@0: const NSSCKMDObject *mdObject michael@0: ) michael@0: { michael@0: return CKR_OK; michael@0: } michael@0: michael@0: static CK_RV michael@0: nss_ckmdSessionObject_remove_pointer michael@0: ( michael@0: const NSSCKMDObject *mdObject michael@0: ) michael@0: { michael@0: return CKR_OK; michael@0: } michael@0: michael@0: #ifdef NSS_DEBUG michael@0: static CK_RV michael@0: nss_ckmdSessionObject_verifyPointer michael@0: ( michael@0: const NSSCKMDObject *mdObject michael@0: ) michael@0: { michael@0: return CKR_OK; michael@0: } michael@0: #endif michael@0: michael@0: #endif /* DEBUG */ michael@0: michael@0: /* michael@0: * We must forward-declare these routines michael@0: */ michael@0: static void michael@0: nss_ckmdSessionObject_Finalize michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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: ); michael@0: michael@0: static CK_RV michael@0: nss_ckmdSessionObject_Destroy michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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: ); michael@0: michael@0: static CK_BBOOL michael@0: nss_ckmdSessionObject_IsTokenObject michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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: ); michael@0: michael@0: static CK_ULONG michael@0: nss_ckmdSessionObject_GetAttributeCount michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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_RV *pError michael@0: ); michael@0: michael@0: static CK_RV michael@0: nss_ckmdSessionObject_GetAttributeTypes michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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_ATTRIBUTE_TYPE_PTR typeArray, michael@0: CK_ULONG ulCount michael@0: ); michael@0: michael@0: static CK_ULONG michael@0: nss_ckmdSessionObject_GetAttributeSize michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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_ATTRIBUTE_TYPE attribute, michael@0: CK_RV *pError michael@0: ); michael@0: michael@0: static NSSCKFWItem michael@0: nss_ckmdSessionObject_GetAttribute michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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_ATTRIBUTE_TYPE attribute, michael@0: CK_RV *pError michael@0: ); michael@0: michael@0: static CK_RV michael@0: nss_ckmdSessionObject_SetAttribute michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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_ATTRIBUTE_TYPE attribute, michael@0: NSSItem *value michael@0: ); michael@0: michael@0: static CK_ULONG michael@0: nss_ckmdSessionObject_GetObjectSize michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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_RV *pError michael@0: ); michael@0: michael@0: /* michael@0: * nssCKMDSessionObject_Create michael@0: * michael@0: */ michael@0: NSS_IMPLEMENT NSSCKMDObject * michael@0: nssCKMDSessionObject_Create michael@0: ( michael@0: NSSCKFWToken *fwToken, michael@0: NSSArena *arena, michael@0: CK_ATTRIBUTE_PTR attributes, michael@0: CK_ULONG ulCount, michael@0: CK_RV *pError michael@0: ) michael@0: { michael@0: NSSCKMDObject *mdObject = (NSSCKMDObject *)NULL; michael@0: nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)NULL; michael@0: CK_ULONG i; michael@0: nssCKFWHash *hash; michael@0: michael@0: *pError = CKR_OK; michael@0: michael@0: mdso = nss_ZNEW(arena, nssCKMDSessionObject); michael@0: if (!mdso) { michael@0: goto loser; michael@0: } michael@0: michael@0: mdso->arena = arena; michael@0: mdso->n = ulCount; michael@0: mdso->attributes = nss_ZNEWARRAY(arena, NSSItem, ulCount); michael@0: if (!mdso->attributes) { michael@0: goto loser; michael@0: } michael@0: michael@0: mdso->types = nss_ZNEWARRAY(arena, CK_ATTRIBUTE_TYPE, ulCount); michael@0: if (!mdso->types) { michael@0: goto loser; michael@0: } michael@0: for( i = 0; i < ulCount; i++ ) { michael@0: mdso->types[i] = attributes[i].type; michael@0: mdso->attributes[i].size = attributes[i].ulValueLen; michael@0: mdso->attributes[i].data = nss_ZAlloc(arena, attributes[i].ulValueLen); michael@0: if (!mdso->attributes[i].data) { michael@0: goto loser; michael@0: } michael@0: (void)nsslibc_memcpy(mdso->attributes[i].data, attributes[i].pValue, michael@0: attributes[i].ulValueLen); michael@0: } michael@0: michael@0: mdObject = nss_ZNEW(arena, NSSCKMDObject); michael@0: if (!mdObject) { michael@0: goto loser; michael@0: } michael@0: michael@0: mdObject->etc = (void *)mdso; michael@0: mdObject->Finalize = nss_ckmdSessionObject_Finalize; michael@0: mdObject->Destroy = nss_ckmdSessionObject_Destroy; michael@0: mdObject->IsTokenObject = nss_ckmdSessionObject_IsTokenObject; michael@0: mdObject->GetAttributeCount = nss_ckmdSessionObject_GetAttributeCount; michael@0: mdObject->GetAttributeTypes = nss_ckmdSessionObject_GetAttributeTypes; michael@0: mdObject->GetAttributeSize = nss_ckmdSessionObject_GetAttributeSize; michael@0: mdObject->GetAttribute = nss_ckmdSessionObject_GetAttribute; michael@0: mdObject->SetAttribute = nss_ckmdSessionObject_SetAttribute; michael@0: mdObject->GetObjectSize = nss_ckmdSessionObject_GetObjectSize; michael@0: michael@0: hash = nssCKFWToken_GetSessionObjectHash(fwToken); michael@0: if (!hash) { michael@0: *pError = CKR_GENERAL_ERROR; michael@0: goto loser; michael@0: } michael@0: michael@0: mdso->hash = hash; michael@0: michael@0: *pError = nssCKFWHash_Add(hash, mdObject, mdObject); michael@0: if( CKR_OK != *pError ) { michael@0: goto loser; michael@0: } michael@0: michael@0: #ifdef DEBUG michael@0: if(( *pError = nss_ckmdSessionObject_add_pointer(mdObject)) != CKR_OK ) { michael@0: goto loser; michael@0: } michael@0: #endif /* DEBUG */ michael@0: michael@0: return mdObject; michael@0: michael@0: loser: michael@0: if (mdso) { michael@0: if (mdso->attributes) { michael@0: for( i = 0; i < ulCount; i++ ) { michael@0: nss_ZFreeIf(mdso->attributes[i].data); michael@0: } michael@0: nss_ZFreeIf(mdso->attributes); michael@0: } michael@0: nss_ZFreeIf(mdso->types); michael@0: nss_ZFreeIf(mdso); michael@0: } michael@0: michael@0: nss_ZFreeIf(mdObject); michael@0: if (*pError == CKR_OK) { michael@0: *pError = CKR_HOST_MEMORY; michael@0: } michael@0: return (NSSCKMDObject *)NULL; michael@0: } michael@0: michael@0: /* michael@0: * nss_ckmdSessionObject_Finalize michael@0: * michael@0: */ michael@0: static void michael@0: nss_ckmdSessionObject_Finalize michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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: ) michael@0: { michael@0: /* This shouldn't ever be called */ michael@0: return; michael@0: } michael@0: michael@0: /* michael@0: * nss_ckmdSessionObject_Destroy michael@0: * michael@0: */ michael@0: michael@0: static CK_RV michael@0: nss_ckmdSessionObject_Destroy michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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: ) michael@0: { michael@0: #ifdef NSSDEBUG michael@0: CK_RV error = CKR_OK; michael@0: #endif /* NSSDEBUG */ michael@0: nssCKMDSessionObject *mdso; michael@0: CK_ULONG i; michael@0: michael@0: #ifdef NSSDEBUG michael@0: error = nss_ckmdSessionObject_verifyPointer(mdObject); michael@0: if( CKR_OK != error ) { michael@0: return error; michael@0: } michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: mdso = (nssCKMDSessionObject *)mdObject->etc; michael@0: michael@0: nssCKFWHash_Remove(mdso->hash, mdObject); michael@0: michael@0: for( i = 0; i < mdso->n; i++ ) { michael@0: nss_ZFreeIf(mdso->attributes[i].data); michael@0: } michael@0: nss_ZFreeIf(mdso->attributes); michael@0: nss_ZFreeIf(mdso->types); michael@0: nss_ZFreeIf(mdso); michael@0: nss_ZFreeIf(mdObject); michael@0: michael@0: #ifdef DEBUG michael@0: (void)nss_ckmdSessionObject_remove_pointer(mdObject); michael@0: #endif /* DEBUG */ michael@0: michael@0: return CKR_OK; michael@0: } michael@0: michael@0: /* michael@0: * nss_ckmdSessionObject_IsTokenObject michael@0: * michael@0: */ michael@0: michael@0: static CK_BBOOL michael@0: nss_ckmdSessionObject_IsTokenObject michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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: ) michael@0: { michael@0: #ifdef NSSDEBUG michael@0: if( CKR_OK != nss_ckmdSessionObject_verifyPointer(mdObject) ) { michael@0: return CK_FALSE; michael@0: } michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: /* michael@0: * This implementation is only ever used for session objects. michael@0: */ michael@0: return CK_FALSE; michael@0: } michael@0: michael@0: /* michael@0: * nss_ckmdSessionObject_GetAttributeCount michael@0: * michael@0: */ michael@0: static CK_ULONG michael@0: nss_ckmdSessionObject_GetAttributeCount michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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_RV *pError michael@0: ) michael@0: { michael@0: nssCKMDSessionObject *obj; michael@0: michael@0: #ifdef NSSDEBUG michael@0: if (!pError) { michael@0: return 0; michael@0: } michael@0: michael@0: *pError = nss_ckmdSessionObject_verifyPointer(mdObject); michael@0: if( CKR_OK != *pError ) { michael@0: return 0; michael@0: } michael@0: michael@0: /* We could even check all the other arguments, for sanity. */ michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: obj = (nssCKMDSessionObject *)mdObject->etc; michael@0: michael@0: return obj->n; michael@0: } michael@0: michael@0: /* michael@0: * nss_ckmdSessionObject_GetAttributeTypes michael@0: * michael@0: */ michael@0: static CK_RV michael@0: nss_ckmdSessionObject_GetAttributeTypes michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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_ATTRIBUTE_TYPE_PTR typeArray, michael@0: CK_ULONG ulCount michael@0: ) michael@0: { michael@0: #ifdef NSSDEBUG michael@0: CK_RV error = CKR_OK; michael@0: #endif /* NSSDEBUG */ michael@0: nssCKMDSessionObject *obj; michael@0: michael@0: #ifdef NSSDEBUG michael@0: error = nss_ckmdSessionObject_verifyPointer(mdObject); michael@0: if( CKR_OK != error ) { michael@0: return error; michael@0: } michael@0: michael@0: /* We could even check all the other arguments, for sanity. */ michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: obj = (nssCKMDSessionObject *)mdObject->etc; michael@0: michael@0: if( ulCount < obj->n ) { michael@0: return CKR_BUFFER_TOO_SMALL; michael@0: } michael@0: michael@0: (void)nsslibc_memcpy(typeArray, obj->types, michael@0: sizeof(CK_ATTRIBUTE_TYPE) * obj->n); michael@0: michael@0: return CKR_OK; michael@0: } michael@0: michael@0: /* michael@0: * nss_ckmdSessionObject_GetAttributeSize michael@0: * michael@0: */ michael@0: static CK_ULONG michael@0: nss_ckmdSessionObject_GetAttributeSize michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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_ATTRIBUTE_TYPE attribute, michael@0: CK_RV *pError michael@0: ) michael@0: { michael@0: nssCKMDSessionObject *obj; michael@0: CK_ULONG i; michael@0: michael@0: #ifdef NSSDEBUG michael@0: if (!pError) { michael@0: return 0; michael@0: } michael@0: michael@0: *pError = nss_ckmdSessionObject_verifyPointer(mdObject); michael@0: if( CKR_OK != *pError ) { michael@0: return 0; michael@0: } michael@0: michael@0: /* We could even check all the other arguments, for sanity. */ michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: obj = (nssCKMDSessionObject *)mdObject->etc; michael@0: michael@0: for( i = 0; i < obj->n; i++ ) { michael@0: if( attribute == obj->types[i] ) { michael@0: return (CK_ULONG)(obj->attributes[i].size); michael@0: } michael@0: } michael@0: michael@0: *pError = CKR_ATTRIBUTE_TYPE_INVALID; michael@0: return 0; michael@0: } michael@0: michael@0: /* michael@0: * nss_ckmdSessionObject_GetAttribute michael@0: * michael@0: */ michael@0: static NSSCKFWItem michael@0: nss_ckmdSessionObject_GetAttribute michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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_ATTRIBUTE_TYPE attribute, michael@0: CK_RV *pError michael@0: ) michael@0: { michael@0: NSSCKFWItem item; michael@0: nssCKMDSessionObject *obj; michael@0: CK_ULONG i; michael@0: michael@0: item.needsFreeing = PR_FALSE; michael@0: item.item = NULL; michael@0: #ifdef NSSDEBUG michael@0: if (!pError) { michael@0: return item; michael@0: } michael@0: michael@0: *pError = nss_ckmdSessionObject_verifyPointer(mdObject); michael@0: if( CKR_OK != *pError ) { michael@0: return item; michael@0: } michael@0: michael@0: /* We could even check all the other arguments, for sanity. */ michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: obj = (nssCKMDSessionObject *)mdObject->etc; michael@0: michael@0: for( i = 0; i < obj->n; i++ ) { michael@0: if( attribute == obj->types[i] ) { michael@0: item.item = &obj->attributes[i]; michael@0: return item; michael@0: } michael@0: } michael@0: michael@0: *pError = CKR_ATTRIBUTE_TYPE_INVALID; michael@0: return item; michael@0: } michael@0: michael@0: /* michael@0: * nss_ckmdSessionObject_SetAttribute michael@0: * michael@0: */ michael@0: michael@0: /* michael@0: * Okay, so this implementation sucks. It doesn't support removing michael@0: * an attribute (if value == NULL), and could be more graceful about michael@0: * memory. It should allow "blank" slots in the arrays, with some michael@0: * invalid attribute type, and then it could support removal much michael@0: * more easily. Do this later. michael@0: */ michael@0: static CK_RV michael@0: nss_ckmdSessionObject_SetAttribute michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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_ATTRIBUTE_TYPE attribute, michael@0: NSSItem *value michael@0: ) michael@0: { michael@0: nssCKMDSessionObject *obj; michael@0: CK_ULONG i; michael@0: NSSItem n; michael@0: NSSItem *ra; michael@0: CK_ATTRIBUTE_TYPE_PTR rt; michael@0: #ifdef NSSDEBUG michael@0: CK_RV error; michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: #ifdef NSSDEBUG michael@0: error = nss_ckmdSessionObject_verifyPointer(mdObject); michael@0: if( CKR_OK != error ) { michael@0: return 0; michael@0: } michael@0: michael@0: /* We could even check all the other arguments, for sanity. */ michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: obj = (nssCKMDSessionObject *)mdObject->etc; michael@0: michael@0: n.size = value->size; michael@0: n.data = nss_ZAlloc(obj->arena, n.size); michael@0: if (!n.data) { michael@0: return CKR_HOST_MEMORY; michael@0: } michael@0: (void)nsslibc_memcpy(n.data, value->data, n.size); michael@0: michael@0: for( i = 0; i < obj->n; i++ ) { michael@0: if( attribute == obj->types[i] ) { michael@0: nss_ZFreeIf(obj->attributes[i].data); michael@0: obj->attributes[i] = n; michael@0: return CKR_OK; michael@0: } michael@0: } michael@0: michael@0: /* michael@0: * It's new. michael@0: */ michael@0: michael@0: ra = (NSSItem *)nss_ZRealloc(obj->attributes, sizeof(NSSItem) * (obj->n + 1)); michael@0: if (!ra) { michael@0: nss_ZFreeIf(n.data); michael@0: return CKR_HOST_MEMORY; michael@0: } michael@0: obj->attributes = ra; michael@0: michael@0: rt = (CK_ATTRIBUTE_TYPE_PTR)nss_ZRealloc(obj->types, michael@0: sizeof(CK_ATTRIBUTE_TYPE) * (obj->n + 1)); michael@0: if (!rt) { michael@0: nss_ZFreeIf(n.data); michael@0: return CKR_HOST_MEMORY; michael@0: } michael@0: michael@0: obj->types = rt; michael@0: obj->attributes[obj->n] = n; michael@0: obj->types[obj->n] = attribute; michael@0: obj->n++; michael@0: michael@0: return CKR_OK; michael@0: } michael@0: michael@0: /* michael@0: * nss_ckmdSessionObject_GetObjectSize michael@0: * michael@0: */ michael@0: static CK_ULONG michael@0: nss_ckmdSessionObject_GetObjectSize michael@0: ( michael@0: NSSCKMDObject *mdObject, michael@0: NSSCKFWObject *fwObject, 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_RV *pError michael@0: ) michael@0: { michael@0: nssCKMDSessionObject *obj; michael@0: CK_ULONG i; michael@0: CK_ULONG rv = (CK_ULONG)0; michael@0: michael@0: #ifdef NSSDEBUG michael@0: if (!pError) { michael@0: return 0; michael@0: } michael@0: michael@0: *pError = nss_ckmdSessionObject_verifyPointer(mdObject); michael@0: if( CKR_OK != *pError ) { michael@0: return 0; michael@0: } michael@0: michael@0: /* We could even check all the other arguments, for sanity. */ michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: obj = (nssCKMDSessionObject *)mdObject->etc; michael@0: michael@0: for( i = 0; i < obj->n; i++ ) { michael@0: rv += obj->attributes[i].size; michael@0: } michael@0: michael@0: rv += sizeof(NSSItem) * obj->n; michael@0: rv += sizeof(CK_ATTRIBUTE_TYPE) * obj->n; michael@0: rv += sizeof(nssCKMDSessionObject); michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: /* michael@0: * nssCKMDFindSessionObjects michael@0: * michael@0: * -- create -- michael@0: * nssCKMDFindSessionObjects_Create michael@0: * michael@0: * -- EPV calls -- michael@0: * nss_ckmdFindSessionObjects_Final michael@0: * nss_ckmdFindSessionObjects_Next michael@0: */ michael@0: michael@0: struct nodeStr { michael@0: struct nodeStr *next; michael@0: NSSCKMDObject *mdObject; michael@0: }; michael@0: michael@0: struct nssCKMDFindSessionObjectsStr { michael@0: NSSArena *arena; michael@0: CK_RV error; michael@0: CK_ATTRIBUTE_PTR pTemplate; michael@0: CK_ULONG ulCount; michael@0: struct nodeStr *list; michael@0: nssCKFWHash *hash; michael@0: michael@0: }; michael@0: typedef struct nssCKMDFindSessionObjectsStr nssCKMDFindSessionObjects; 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: nss_ckmdFindSessionObjects_add_pointer michael@0: ( michael@0: const NSSCKMDFindObjects *mdFindObjects michael@0: ) michael@0: { michael@0: return CKR_OK; michael@0: } michael@0: michael@0: static CK_RV michael@0: nss_ckmdFindSessionObjects_remove_pointer michael@0: ( michael@0: const NSSCKMDFindObjects *mdFindObjects michael@0: ) michael@0: { michael@0: return CKR_OK; michael@0: } michael@0: michael@0: #ifdef NSS_DEBUG michael@0: static CK_RV michael@0: nss_ckmdFindSessionObjects_verifyPointer michael@0: ( michael@0: const NSSCKMDFindObjects *mdFindObjects michael@0: ) michael@0: { michael@0: return CKR_OK; michael@0: } michael@0: #endif michael@0: michael@0: #endif /* DEBUG */ michael@0: michael@0: /* michael@0: * We must forward-declare these routines. michael@0: */ michael@0: static void michael@0: nss_ckmdFindSessionObjects_Final michael@0: ( michael@0: NSSCKMDFindObjects *mdFindObjects, michael@0: NSSCKFWFindObjects *fwFindObjects, 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: ); michael@0: michael@0: static NSSCKMDObject * michael@0: nss_ckmdFindSessionObjects_Next michael@0: ( michael@0: NSSCKMDFindObjects *mdFindObjects, michael@0: NSSCKFWFindObjects *fwFindObjects, 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: NSSArena *arena, michael@0: CK_RV *pError michael@0: ); michael@0: michael@0: static CK_BBOOL michael@0: items_match michael@0: ( michael@0: NSSItem *a, michael@0: CK_VOID_PTR pValue, michael@0: CK_ULONG ulValueLen michael@0: ) michael@0: { michael@0: if( a->size != ulValueLen ) { michael@0: return CK_FALSE; michael@0: } michael@0: michael@0: if( PR_TRUE == nsslibc_memequal(a->data, pValue, ulValueLen, (PRStatus *)NULL) ) { michael@0: return CK_TRUE; michael@0: } else { michael@0: return CK_FALSE; michael@0: } michael@0: } michael@0: michael@0: /* michael@0: * Our hashtable iterator michael@0: */ michael@0: static void michael@0: findfcn michael@0: ( michael@0: const void *key, michael@0: void *value, michael@0: void *closure michael@0: ) michael@0: { michael@0: NSSCKMDObject *mdObject = (NSSCKMDObject *)value; michael@0: nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)mdObject->etc; michael@0: nssCKMDFindSessionObjects *mdfso = (nssCKMDFindSessionObjects *)closure; michael@0: CK_ULONG i, j; michael@0: struct nodeStr *node; michael@0: michael@0: if( CKR_OK != mdfso->error ) { michael@0: return; michael@0: } michael@0: michael@0: for( i = 0; i < mdfso->ulCount; i++ ) { michael@0: CK_ATTRIBUTE_PTR p = &mdfso->pTemplate[i]; michael@0: michael@0: for( j = 0; j < mdso->n; j++ ) { michael@0: if( mdso->types[j] == p->type ) { michael@0: if( !items_match(&mdso->attributes[j], p->pValue, p->ulValueLen) ) { michael@0: return; michael@0: } else { michael@0: break; michael@0: } michael@0: } michael@0: } michael@0: michael@0: if( j == mdso->n ) { michael@0: /* Attribute not found */ michael@0: return; michael@0: } michael@0: } michael@0: michael@0: /* Matches */ michael@0: node = nss_ZNEW(mdfso->arena, struct nodeStr); michael@0: if( (struct nodeStr *)NULL == node ) { michael@0: mdfso->error = CKR_HOST_MEMORY; michael@0: return; michael@0: } michael@0: michael@0: node->mdObject = mdObject; michael@0: node->next = mdfso->list; michael@0: mdfso->list = node; michael@0: michael@0: return; michael@0: } michael@0: michael@0: /* michael@0: * nssCKMDFindSessionObjects_Create michael@0: * michael@0: */ michael@0: NSS_IMPLEMENT NSSCKMDFindObjects * michael@0: nssCKMDFindSessionObjects_Create michael@0: ( michael@0: NSSCKFWToken *fwToken, michael@0: CK_ATTRIBUTE_PTR pTemplate, michael@0: CK_ULONG ulCount, michael@0: CK_RV *pError michael@0: ) michael@0: { michael@0: NSSArena *arena; michael@0: nssCKMDFindSessionObjects *mdfso; michael@0: nssCKFWHash *hash; michael@0: NSSCKMDFindObjects *rv; michael@0: michael@0: #ifdef NSSDEBUG michael@0: if (!pError) { michael@0: return (NSSCKMDFindObjects *)NULL; michael@0: } michael@0: michael@0: *pError = nssCKFWToken_verifyPointer(fwToken); michael@0: if( CKR_OK != *pError ) { michael@0: return (NSSCKMDFindObjects *)NULL; michael@0: } michael@0: michael@0: if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) { michael@0: *pError = CKR_ARGUMENTS_BAD; michael@0: return (NSSCKMDFindObjects *)NULL; michael@0: } michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: *pError = CKR_OK; michael@0: michael@0: hash = nssCKFWToken_GetSessionObjectHash(fwToken); michael@0: if (!hash) { michael@0: *pError= CKR_GENERAL_ERROR; michael@0: return (NSSCKMDFindObjects *)NULL; michael@0: } michael@0: michael@0: arena = NSSArena_Create(); michael@0: if (!arena) { michael@0: *pError = CKR_HOST_MEMORY; michael@0: return (NSSCKMDFindObjects *)NULL; michael@0: } michael@0: michael@0: mdfso = nss_ZNEW(arena, nssCKMDFindSessionObjects); michael@0: if (!mdfso) { michael@0: goto loser; michael@0: } michael@0: michael@0: rv = nss_ZNEW(arena, NSSCKMDFindObjects); michael@0: if(rv == NULL) { michael@0: goto loser; michael@0: } michael@0: michael@0: mdfso->error = CKR_OK; michael@0: mdfso->pTemplate = pTemplate; michael@0: mdfso->ulCount = ulCount; michael@0: mdfso->hash = hash; michael@0: michael@0: nssCKFWHash_Iterate(hash, findfcn, mdfso); michael@0: michael@0: if( CKR_OK != mdfso->error ) { michael@0: goto loser; michael@0: } michael@0: michael@0: rv->etc = (void *)mdfso; michael@0: rv->Final = nss_ckmdFindSessionObjects_Final; michael@0: rv->Next = nss_ckmdFindSessionObjects_Next; michael@0: michael@0: #ifdef DEBUG michael@0: if( (*pError = nss_ckmdFindSessionObjects_add_pointer(rv)) != CKR_OK ) { michael@0: goto loser; michael@0: } michael@0: #endif /* DEBUG */ michael@0: mdfso->arena = arena; michael@0: michael@0: return rv; michael@0: michael@0: loser: michael@0: if (arena) { michael@0: NSSArena_Destroy(arena); michael@0: } michael@0: if (*pError == CKR_OK) { michael@0: *pError = CKR_HOST_MEMORY; michael@0: } michael@0: return NULL; michael@0: } michael@0: michael@0: static void michael@0: nss_ckmdFindSessionObjects_Final michael@0: ( michael@0: NSSCKMDFindObjects *mdFindObjects, michael@0: NSSCKFWFindObjects *fwFindObjects, 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: ) michael@0: { michael@0: nssCKMDFindSessionObjects *mdfso; michael@0: michael@0: #ifdef NSSDEBUG michael@0: if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) { michael@0: return; michael@0: } michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc; michael@0: if (mdfso->arena) NSSArena_Destroy(mdfso->arena); michael@0: michael@0: #ifdef DEBUG michael@0: (void)nss_ckmdFindSessionObjects_remove_pointer(mdFindObjects); michael@0: #endif /* DEBUG */ michael@0: michael@0: return; michael@0: } michael@0: michael@0: static NSSCKMDObject * michael@0: nss_ckmdFindSessionObjects_Next michael@0: ( michael@0: NSSCKMDFindObjects *mdFindObjects, michael@0: NSSCKFWFindObjects *fwFindObjects, 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: NSSArena *arena, michael@0: CK_RV *pError michael@0: ) michael@0: { michael@0: nssCKMDFindSessionObjects *mdfso; michael@0: NSSCKMDObject *rv = (NSSCKMDObject *)NULL; michael@0: michael@0: #ifdef NSSDEBUG michael@0: if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) { michael@0: return (NSSCKMDObject *)NULL; michael@0: } michael@0: #endif /* NSSDEBUG */ michael@0: michael@0: mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc; michael@0: michael@0: while (!rv) { michael@0: if( (struct nodeStr *)NULL == mdfso->list ) { michael@0: *pError = CKR_OK; michael@0: return (NSSCKMDObject *)NULL; michael@0: } michael@0: michael@0: if( nssCKFWHash_Exists(mdfso->hash, mdfso->list->mdObject) ) { michael@0: rv = mdfso->list->mdObject; michael@0: } michael@0: michael@0: mdfso->list = mdfso->list->next; michael@0: } michael@0: michael@0: return rv; michael@0: }