/* Caller MUST hold slot->freeListLock (or ref count == 0?) !! */ void PK11_CleanKeyList(PK11SlotInfo *slot) { PK11SymKey *symKey = NULL; while (slot->freeSymKeysWithSessionHead) { symKey = slot->freeSymKeysWithSessionHead; slot->freeSymKeysWithSessionHead = symKey->next; pk11_CloseSession(slot, symKey->session, symKey->sessionOwner); PORT_Free(symKey); } while (slot->freeSymKeysHead) { symKey = slot->freeSymKeysHead; slot->freeSymKeysHead = symKey->next; pk11_CloseSession(slot, symKey->session, symKey->sessionOwner); PORT_Free(symKey); } return; }
/* * Free up a Cipher Context */ void PK11_DestroyContext(PK11Context *context, PRBool freeit) { pk11_CloseSession(context->slot,context->session,context->ownSession); /* initialize the critical fields of the context */ if (context->savedData != NULL ) PORT_Free(context->savedData); if (context->key) PK11_FreeSymKey(context->key); if (context->param && context->param != &pk11_null_params) SECITEM_FreeItem(context->param, PR_TRUE); if (context->sessionLock) PZ_DestroyLock(context->sessionLock); PK11_FreeSlot(context->slot); if (freeit) PORT_Free(context); }
/* * destroy a symetric key */ void PK11_FreeSymKey(PK11SymKey *symKey) { PK11SlotInfo *slot; PRBool freeit = PR_TRUE; if (PR_ATOMIC_DECREMENT(&symKey->refCount) == 0) { PK11SymKey *parent = symKey->parent; symKey->parent = NULL; if ((symKey->owner) && symKey->objectID != CK_INVALID_HANDLE) { pk11_EnterKeyMonitor(symKey); (void) PK11_GETTAB(symKey->slot)-> C_DestroyObject(symKey->session, symKey->objectID); pk11_ExitKeyMonitor(symKey); } if (symKey->data.data) { PORT_Memset(symKey->data.data, 0, symKey->data.len); PORT_Free(symKey->data.data); } /* free any existing data */ if (symKey->userData && symKey->freeFunc) { (*symKey->freeFunc)(symKey->userData); } slot = symKey->slot; PZ_Lock(slot->freeListLock); if (slot->keyCount < slot->maxKeyCount) { /* * freeSymkeysWithSessionHead contain a list of reusable * SymKey structures with valid sessions. * sessionOwner must be true. * session must be valid. * freeSymKeysHead contain a list of SymKey structures without * valid session. * session must be CK_INVALID_SESSION. * though sessionOwner is false, callers should not depend on * this fact. */ if (symKey->sessionOwner) { PORT_Assert (symKey->session != CK_INVALID_SESSION); symKey->next = slot->freeSymKeysWithSessionHead; slot->freeSymKeysWithSessionHead = symKey; } else { symKey->session = CK_INVALID_SESSION; symKey->next = slot->freeSymKeysHead; slot->freeSymKeysHead = symKey; } slot->keyCount++; symKey->slot = NULL; freeit = PR_FALSE; } PZ_Unlock(slot->freeListLock); if (freeit) { pk11_CloseSession(symKey->slot, symKey->session, symKey->sessionOwner); PORT_Free(symKey); } PK11_FreeSlot(slot); if (parent) { PK11_FreeSymKey(parent); } } }