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: #include "ckdbm.h" michael@0: michael@0: static void michael@0: nss_dbm_mdSession_Close michael@0: ( 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: nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc; michael@0: michael@0: struct nss_dbm_dbt_node *w; michael@0: michael@0: /* Lock */ michael@0: { michael@0: if( CKR_OK != NSSCKFWMutex_Lock(session->list_lock) ) { michael@0: return; michael@0: } michael@0: michael@0: w = session->session_objects; michael@0: session->session_objects = (struct nss_dbm_dbt_node *)NULL; /* sanity */ michael@0: michael@0: (void)NSSCKFWMutex_Unlock(session->list_lock); michael@0: } michael@0: michael@0: for( ; (struct nss_dbm_dbt_node *)NULL != w; w = w->next ) { michael@0: (void)nss_dbm_db_delete_object(w->dbt); michael@0: } michael@0: } michael@0: michael@0: static CK_ULONG michael@0: nss_dbm_mdSession_GetDeviceError michael@0: ( 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: nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc; michael@0: return session->deviceError; michael@0: } michael@0: michael@0: /* Login isn't needed */ michael@0: /* Logout isn't needed */ michael@0: /* InitPIN is irrelevant */ michael@0: /* SetPIN is irrelevant */ michael@0: /* GetOperationStateLen is irrelevant */ michael@0: /* GetOperationState is irrelevant */ michael@0: /* SetOperationState is irrelevant */ michael@0: michael@0: static NSSCKMDObject * michael@0: nss_dbm_mdSession_CreateObject michael@0: ( 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 *handyArenaPointer, michael@0: CK_ATTRIBUTE_PTR pTemplate, michael@0: CK_ULONG ulAttributeCount, michael@0: CK_RV *pError michael@0: ) michael@0: { michael@0: nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc; michael@0: nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc; michael@0: CK_ULONG i; michael@0: CK_BBOOL isToken = CK_FALSE; /* defaults to false */ michael@0: NSSCKMDObject *rv; michael@0: struct nss_dbm_dbt_node *node = (struct nss_dbm_dbt_node *)NULL; michael@0: nss_dbm_object_t *object; michael@0: nss_dbm_db_t *which_db; michael@0: michael@0: /* This framework should really pass this to me */ michael@0: for( i = 0; i < ulAttributeCount; i++ ) { michael@0: if( CKA_TOKEN == pTemplate[i].type ) { michael@0: isToken = *(CK_BBOOL *)pTemplate[i].pValue; michael@0: break; michael@0: } michael@0: } michael@0: michael@0: object = nss_ZNEW(handyArenaPointer, nss_dbm_object_t); michael@0: if( (nss_dbm_object_t *)NULL == object ) { michael@0: *pError = CKR_HOST_MEMORY; michael@0: return (NSSCKMDObject *)NULL; michael@0: } michael@0: michael@0: object->arena = handyArenaPointer; michael@0: which_db = isToken ? token->slot->token_db : token->session_db; michael@0: michael@0: /* Do this before the actual database call; it's easier to recover from */ michael@0: rv = nss_dbm_mdObject_factory(object, pError); michael@0: if( (NSSCKMDObject *)NULL == rv ) { michael@0: return (NSSCKMDObject *)NULL; michael@0: } michael@0: michael@0: if( CK_FALSE == isToken ) { michael@0: node = nss_ZNEW(session->arena, struct nss_dbm_dbt_node); michael@0: if( (struct nss_dbm_dbt_node *)NULL == node ) { michael@0: *pError = CKR_HOST_MEMORY; michael@0: return (NSSCKMDObject *)NULL; michael@0: } michael@0: } michael@0: michael@0: object->handle = nss_dbm_db_create_object(handyArenaPointer, which_db, michael@0: pTemplate, ulAttributeCount, michael@0: pError, &session->deviceError); michael@0: if( (nss_dbm_dbt_t *)NULL == object->handle ) { michael@0: return (NSSCKMDObject *)NULL; michael@0: } michael@0: michael@0: if( CK_FALSE == isToken ) { michael@0: node->dbt = object->handle; michael@0: /* Lock */ michael@0: { michael@0: *pError = NSSCKFWMutex_Lock(session->list_lock); michael@0: if( CKR_OK != *pError ) { michael@0: (void)nss_dbm_db_delete_object(object->handle); michael@0: return (NSSCKMDObject *)NULL; michael@0: } michael@0: michael@0: node->next = session->session_objects; michael@0: session->session_objects = node; michael@0: michael@0: *pError = NSSCKFWMutex_Unlock(session->list_lock); michael@0: } michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: /* CopyObject isn't needed; the framework will use CreateObject */ michael@0: michael@0: static NSSCKMDFindObjects * michael@0: nss_dbm_mdSession_FindObjectsInit michael@0: ( 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_PTR pTemplate, michael@0: CK_ULONG ulAttributeCount, michael@0: CK_RV *pError michael@0: ) michael@0: { michael@0: nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc; michael@0: nss_dbm_token_t *token = (nss_dbm_token_t *)mdToken->etc; michael@0: NSSArena *arena; michael@0: nss_dbm_find_t *find; michael@0: NSSCKMDFindObjects *rv; michael@0: michael@0: arena = NSSArena_Create(); michael@0: if( (NSSArena *)NULL == arena ) { michael@0: *pError = CKR_HOST_MEMORY; michael@0: goto loser; michael@0: } michael@0: michael@0: find = nss_ZNEW(arena, nss_dbm_find_t); michael@0: if( (nss_dbm_find_t *)NULL == find ) { michael@0: *pError = CKR_HOST_MEMORY; michael@0: goto loser; michael@0: } michael@0: michael@0: find->arena = arena; michael@0: find->list_lock = NSSCKFWInstance_CreateMutex(fwInstance, arena, pError); michael@0: if( (NSSCKFWMutex *)NULL == find->list_lock ) { michael@0: goto loser; michael@0: } michael@0: michael@0: *pError = nss_dbm_db_find_objects(find, token->slot->token_db, pTemplate, michael@0: ulAttributeCount, &session->deviceError); michael@0: if( CKR_OK != *pError ) { michael@0: goto loser; michael@0: } michael@0: michael@0: *pError = nss_dbm_db_find_objects(find, token->session_db, pTemplate, michael@0: ulAttributeCount, &session->deviceError); michael@0: if( CKR_OK != *pError ) { michael@0: goto loser; michael@0: } michael@0: michael@0: rv = nss_dbm_mdFindObjects_factory(find, pError); michael@0: if( (NSSCKMDFindObjects *)NULL == rv ) { michael@0: goto loser; michael@0: } michael@0: michael@0: return rv; michael@0: michael@0: loser: michael@0: if( (NSSArena *)NULL != arena ) { michael@0: (void)NSSArena_Destroy(arena); michael@0: } michael@0: michael@0: return (NSSCKMDFindObjects *)NULL; michael@0: } michael@0: michael@0: /* SeedRandom is irrelevant */ michael@0: /* GetRandom is irrelevant */ michael@0: michael@0: NSS_IMPLEMENT NSSCKMDSession * michael@0: nss_dbm_mdSession_factory michael@0: ( michael@0: nss_dbm_token_t *token, michael@0: NSSCKFWSession *fwSession, michael@0: NSSCKFWInstance *fwInstance, michael@0: CK_BBOOL rw, michael@0: CK_RV *pError michael@0: ) michael@0: { michael@0: NSSArena *arena; michael@0: nss_dbm_session_t *session; michael@0: NSSCKMDSession *rv; michael@0: michael@0: arena = NSSCKFWSession_GetArena(fwSession, pError); michael@0: michael@0: session = nss_ZNEW(arena, nss_dbm_session_t); michael@0: if( (nss_dbm_session_t *)NULL == session ) { michael@0: *pError = CKR_HOST_MEMORY; michael@0: return (NSSCKMDSession *)NULL; michael@0: } michael@0: michael@0: rv = nss_ZNEW(arena, NSSCKMDSession); michael@0: if( (NSSCKMDSession *)NULL == rv ) { michael@0: *pError = CKR_HOST_MEMORY; michael@0: return (NSSCKMDSession *)NULL; michael@0: } michael@0: michael@0: session->arena = arena; michael@0: session->token = token; michael@0: session->list_lock = NSSCKFWInstance_CreateMutex(fwInstance, arena, pError); michael@0: if( (NSSCKFWMutex *)NULL == session->list_lock ) { michael@0: return (NSSCKMDSession *)NULL; michael@0: } michael@0: michael@0: rv->etc = (void *)session; michael@0: rv->Close = nss_dbm_mdSession_Close; michael@0: rv->GetDeviceError = nss_dbm_mdSession_GetDeviceError; michael@0: /* Login isn't needed */ michael@0: /* Logout isn't needed */ michael@0: /* InitPIN is irrelevant */ michael@0: /* SetPIN is irrelevant */ michael@0: /* GetOperationStateLen is irrelevant */ michael@0: /* GetOperationState is irrelevant */ michael@0: /* SetOperationState is irrelevant */ michael@0: rv->CreateObject = nss_dbm_mdSession_CreateObject; michael@0: /* CopyObject isn't needed; the framework will use CreateObject */ michael@0: rv->FindObjectsInit = nss_dbm_mdSession_FindObjectsInit; michael@0: rv->null = NULL; michael@0: michael@0: return rv; michael@0: }