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