/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
 * Internal PKCS #11 functions. Should only be called by pkcs11.c
 */
#include "pkcs11.h"
#include "pkcs11i.h"
#include "lowkeyi.h"
#include "secasn1.h"
#include "blapi.h"
#include "secerr.h"
#include "prnetdb.h" /* for PR_ntohl */
#include "sftkdb.h"
#include "softoken.h"

/*
 * ******************** Attribute Utilities *******************************
 */

/*
 * create a new attribute with type, value, and length. Space is allocated
 * to hold value.
 */
static SFTKAttribute *
sftk_NewAttribute(SFTKObject *object,
                  CK_ATTRIBUTE_TYPE type, const void *value, CK_ULONG len)
{
    SFTKAttribute *attribute;

    SFTKSessionObject *so = sftk_narrowToSessionObject(object);
    int index;

    if (so == NULL) {
        /* allocate new attribute in a buffer */
        PORT_Assert(0);
        return NULL;
    }
    /*
     * We attempt to keep down contention on Malloc and Arena locks by
     * limiting the number of these calls on high traversed paths. This
     * is done for attributes by 'allocating' them from a pool already
     * allocated by the parent object.
     */
    PZ_Lock(so->attributeLock);
    index = so->nextAttr++;
    PZ_Unlock(so->attributeLock);
    PORT_Assert(index < MAX_OBJS_ATTRS);
    if (index >= MAX_OBJS_ATTRS)
        return NULL;

    attribute = &so->attrList[index];
    attribute->attrib.type = type;
    attribute->freeAttr = PR_FALSE;
    attribute->freeData = PR_FALSE;
    if (value) {
        if (len <= ATTR_SPACE) {
            attribute->attrib.pValue = attribute->space;
        } else {
            attribute->attrib.pValue = PORT_Alloc(len);
            attribute->freeData = PR_TRUE;
        }
        if (attribute->attrib.pValue == NULL) {
            return NULL;
        }
        PORT_Memcpy(attribute->attrib.pValue, value, len);
        attribute->attrib.ulValueLen = len;
    } else {
        attribute->attrib.pValue = NULL;
        attribute->attrib.ulValueLen = 0;
    }
    attribute->attrib.type = type;
    attribute->handle = type;
    attribute->next = attribute->prev = NULL;
    return attribute;
}

/*
 * Free up all the memory associated with an attribute. Reference count
 * must be zero to call this.
 */
static void
sftk_DestroyAttribute(SFTKAttribute *attribute)
{
    if (attribute->freeData) {
        if (attribute->attrib.pValue) {
            /* clear out the data in the attribute value... it may have been
             * sensitive data */
            PORT_Memset(attribute->attrib.pValue, 0,
                        attribute->attrib.ulValueLen);
        }
        PORT_Free(attribute->attrib.pValue);
    }
    PORT_Free(attribute);
}

/*
 * release a reference to an attribute structure
 */
void
sftk_FreeAttribute(SFTKAttribute *attribute)
{
    if (attribute->freeAttr) {
        sftk_DestroyAttribute(attribute);
        return;
    }
}

static SFTKAttribute *
sftk_FindTokenAttribute(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *myattribute = NULL;
    SFTKDBHandle *dbHandle = NULL;
    CK_RV crv = CKR_HOST_MEMORY;

    myattribute = (SFTKAttribute *)PORT_Alloc(sizeof(SFTKAttribute));
    if (myattribute == NULL) {
        goto loser;
    }

    dbHandle = sftk_getDBForTokenObject(object->obj.slot, object->obj.handle);

    myattribute->handle = type;
    myattribute->attrib.type = type;
    myattribute->attrib.pValue = myattribute->space;
    myattribute->attrib.ulValueLen = ATTR_SPACE;
    myattribute->next = myattribute->prev = NULL;
    myattribute->freeAttr = PR_TRUE;
    myattribute->freeData = PR_FALSE;

    crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle,
                                   &myattribute->attrib, 1);

    /* attribute is bigger than our attribute space buffer, malloc it */
    if (crv == CKR_BUFFER_TOO_SMALL) {
        myattribute->attrib.pValue = NULL;
        crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle,
                                       &myattribute->attrib, 1);
        if (crv != CKR_OK) {
            goto loser;
        }
        myattribute->attrib.pValue = PORT_Alloc(myattribute->attrib.ulValueLen);
        if (myattribute->attrib.pValue == NULL) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }
        myattribute->freeData = PR_TRUE;
        crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle,
                                       &myattribute->attrib, 1);
    }
loser:
    if (dbHandle) {
        sftk_freeDB(dbHandle);
    }
    if (crv != CKR_OK) {
        if (myattribute) {
            myattribute->attrib.ulValueLen = 0;
            sftk_FreeAttribute(myattribute);
            myattribute = NULL;
        }
    }
    return myattribute;
}

/*
 * look up and attribute structure from a type and Object structure.
 * The returned attribute is referenced and needs to be freed when
 * it is no longer needed.
 */
SFTKAttribute *
sftk_FindAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;
    SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);

    if (sessObject == NULL) {
        return sftk_FindTokenAttribute(sftk_narrowToTokenObject(object), type);
    }

    PZ_Lock(sessObject->attributeLock);
    sftkqueue_find(attribute, type, sessObject->head, sessObject->hashSize);
    PZ_Unlock(sessObject->attributeLock);

    return (attribute);
}

/*
 * Take a buffer and it's length and return it's true size in bits;
 */
unsigned int
sftk_GetLengthInBits(unsigned char *buf, unsigned int bufLen)
{
    unsigned int size = bufLen * 8;
    unsigned int i;

    /* Get the real length in bytes */
    for (i = 0; i < bufLen; i++) {
        unsigned char c = *buf++;
        if (c != 0) {
            unsigned char m;
            for (m = 0x80; m > 0; m = m >> 1) {
                if ((c & m) != 0) {
                    break;
                }
                size--;
            }
            break;
        }
        size -= 8;
    }
    return size;
}

/*
 * Constrain a big num attribute. to size and padding
 * minLength means length of the object must be greater than equal to minLength
 * maxLength means length of the object must be less than equal to maxLength
 * minMultiple means that object length mod minMultiple must equal 0.
 * all input sizes are in bits.
 * if any constraint is '0' that constraint is not checked.
 */
CK_RV
sftk_ConstrainAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
                        int minLength, int maxLength, int minMultiple)
{
    SFTKAttribute *attribute;
    int size;
    unsigned char *ptr;

    attribute = sftk_FindAttribute(object, type);
    if (!attribute) {
        return CKR_TEMPLATE_INCOMPLETE;
    }
    ptr = (unsigned char *)attribute->attrib.pValue;
    if (ptr == NULL) {
        sftk_FreeAttribute(attribute);
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }
    size = sftk_GetLengthInBits(ptr, attribute->attrib.ulValueLen);
    sftk_FreeAttribute(attribute);

    if ((minLength != 0) && (size < minLength)) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }
    if ((maxLength != 0) && (size > maxLength)) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }
    if ((minMultiple != 0) && ((size % minMultiple) != 0)) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }
    return CKR_OK;
}

PRBool
sftk_hasAttributeToken(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type)
{
    CK_ATTRIBUTE template;
    CK_RV crv;
    SFTKDBHandle *dbHandle;

    dbHandle = sftk_getDBForTokenObject(object->obj.slot, object->obj.handle);
    template.type = type;
    template.pValue = NULL;
    template.ulValueLen = 0;

    crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle, &template, 1);
    sftk_freeDB(dbHandle);

    /* attribute is bigger than our attribute space buffer, malloc it */
    return (crv == CKR_OK) ? PR_TRUE : PR_FALSE;
}

/*
 * return true if object has attribute
 */
PRBool
sftk_hasAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;
    SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);

    if (sessObject == NULL) {
        return sftk_hasAttributeToken(sftk_narrowToTokenObject(object), type);
    }

    PZ_Lock(sessObject->attributeLock);
    sftkqueue_find(attribute, type, sessObject->head, sessObject->hashSize);
    PZ_Unlock(sessObject->attributeLock);

    return (PRBool)(attribute != NULL);
}

/*
 * add an attribute to an object
 */
static void
sftk_AddAttribute(SFTKObject *object, SFTKAttribute *attribute)
{
    SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);

    if (sessObject == NULL)
        return;
    PZ_Lock(sessObject->attributeLock);
    sftkqueue_add(attribute, attribute->handle,
                  sessObject->head, sessObject->hashSize);
    PZ_Unlock(sessObject->attributeLock);
}

/*
 * copy an unsigned attribute into a SECItem. Secitem is allocated in
 * the specified arena.
 */
CK_RV
sftk_Attribute2SSecItem(PLArenaPool *arena, SECItem *item, SFTKObject *object,
                        CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;

    item->data = NULL;

    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return CKR_TEMPLATE_INCOMPLETE;

    (void)SECITEM_AllocItem(arena, item, attribute->attrib.ulValueLen);
    if (item->data == NULL) {
        sftk_FreeAttribute(attribute);
        return CKR_HOST_MEMORY;
    }
    PORT_Memcpy(item->data, attribute->attrib.pValue, item->len);
    sftk_FreeAttribute(attribute);
    return CKR_OK;
}

/*
 * fetch multiple attributes into  SECItems. Secitem data is allocated in
 * the specified arena.
 */
CK_RV
sftk_MultipleAttribute2SecItem(PLArenaPool *arena, SFTKObject *object,
                               SFTKItemTemplate *itemTemplate, int itemTemplateCount)
{

    CK_RV crv = CKR_OK;
    CK_ATTRIBUTE templateSpace[SFTK_MAX_ITEM_TEMPLATE];
    CK_ATTRIBUTE *template;
    SFTKTokenObject *tokObject;
    SFTKDBHandle *dbHandle = NULL;
    int i;

    tokObject = sftk_narrowToTokenObject(object);

    /* session objects, just loop through the list */
    if (tokObject == NULL) {
        for (i = 0; i < itemTemplateCount; i++) {
            crv = sftk_Attribute2SecItem(arena, itemTemplate[i].item, object,
                                         itemTemplate[i].type);
            if (crv != CKR_OK) {
                return crv;
            }
        }
        return CKR_OK;
    }

    /* don't do any work if none is required */
    if (itemTemplateCount == 0) {
        return CKR_OK;
    }

    /* don't allocate the template unless we need it */
    if (itemTemplateCount > SFTK_MAX_ITEM_TEMPLATE) {
        template = PORT_NewArray(CK_ATTRIBUTE, itemTemplateCount);
    } else {
        template = templateSpace;
    }

    if (template == NULL) {
        crv = CKR_HOST_MEMORY;
        goto loser;
    }

    dbHandle = sftk_getDBForTokenObject(object->slot, object->handle);
    if (dbHandle == NULL) {
        crv = CKR_OBJECT_HANDLE_INVALID;
        goto loser;
    }

    /* set up the PKCS #11 template */
    for (i = 0; i < itemTemplateCount; i++) {
        template[i].type = itemTemplate[i].type;
        template[i].pValue = NULL;
        template[i].ulValueLen = 0;
    }

    /* fetch the attribute lengths */
    crv = sftkdb_GetAttributeValue(dbHandle, object->handle,
                                   template, itemTemplateCount);
    if (crv != CKR_OK) {
        goto loser;
    }

    /* allocate space for the attributes */
    for (i = 0; i < itemTemplateCount; i++) {
        template[i].pValue = PORT_ArenaAlloc(arena, template[i].ulValueLen);
        if (template[i].pValue == NULL) {
            crv = CKR_HOST_MEMORY;
            goto loser;
        }
    }

    /* fetch the attributes */
    crv = sftkdb_GetAttributeValue(dbHandle, object->handle,
                                   template, itemTemplateCount);
    if (crv != CKR_OK) {
        goto loser;
    }

    /* Fill in the items */
    for (i = 0; i < itemTemplateCount; i++) {
        itemTemplate[i].item->data = template[i].pValue;
        itemTemplate[i].item->len = template[i].ulValueLen;
    }

loser:
    if (template != templateSpace) {
        PORT_Free(template);
    }
    if (dbHandle) {
        sftk_freeDB(dbHandle);
    }

    return crv;
}

/*
 * delete an attribute from an object
 */
static void
sftk_DeleteAttribute(SFTKObject *object, SFTKAttribute *attribute)
{
    SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object);

    if (sessObject == NULL) {
        return;
    }
    PZ_Lock(sessObject->attributeLock);
    if (sftkqueue_is_queued(attribute, attribute->handle,
                            sessObject->head, sessObject->hashSize)) {
        sftkqueue_delete(attribute, attribute->handle,
                         sessObject->head, sessObject->hashSize);
    }
    PZ_Unlock(sessObject->attributeLock);
}

/*
 * this is only valid for CK_BBOOL type attributes. Return the state
 * of that attribute.
 */
PRBool
sftk_isTrue(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;
    PRBool tok = PR_FALSE;

    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL) {
        return PR_FALSE;
    }
    tok = (PRBool)(*(CK_BBOOL *)attribute->attrib.pValue);
    sftk_FreeAttribute(attribute);

    return tok;
}

/*
 * force an attribute to null.
 * this is for sensitive keys which are stored in the database, we don't
 * want to keep this info around in memory in the clear.
 */
void
sftk_nullAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;

    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return;

    if (attribute->attrib.pValue != NULL) {
        PORT_Memset(attribute->attrib.pValue, 0, attribute->attrib.ulValueLen);
        if (attribute->freeData) {
            PORT_Free(attribute->attrib.pValue);
        }
        attribute->freeData = PR_FALSE;
        attribute->attrib.pValue = NULL;
        attribute->attrib.ulValueLen = 0;
    }
    sftk_FreeAttribute(attribute);
}

static CK_RV
sftk_forceTokenAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
                         const void *value, unsigned int len)
{
    CK_ATTRIBUTE attribute;
    SFTKDBHandle *dbHandle = NULL;
    SFTKTokenObject *to = sftk_narrowToTokenObject(object);
    CK_RV crv;

    PORT_Assert(to);
    if (to == NULL) {
        return CKR_DEVICE_ERROR;
    }

    dbHandle = sftk_getDBForTokenObject(object->slot, object->handle);

    attribute.type = type;
    attribute.pValue = (void *)value;
    attribute.ulValueLen = len;

    crv = sftkdb_SetAttributeValue(dbHandle, object, &attribute, 1);
    sftk_freeDB(dbHandle);
    return crv;
}

/*
 * force an attribute to a specifc value.
 */
CK_RV
sftk_forceAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
                    const void *value, unsigned int len)
{
    SFTKAttribute *attribute;
    void *att_val = NULL;
    PRBool freeData = PR_FALSE;

    PORT_Assert(object);
    PORT_Assert(object->refCount);
    PORT_Assert(object->slot);
    if (!object ||
        !object->refCount ||
        !object->slot) {
        return CKR_DEVICE_ERROR;
    }
    if (sftk_isToken(object->handle)) {
        return sftk_forceTokenAttribute(object, type, value, len);
    }
    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return sftk_AddAttributeType(object, type, value, len);

    if (value) {
        if (len <= ATTR_SPACE) {
            att_val = attribute->space;
        } else {
            att_val = PORT_Alloc(len);
            freeData = PR_TRUE;
        }
        if (att_val == NULL) {
            return CKR_HOST_MEMORY;
        }
        if (attribute->attrib.pValue == att_val) {
            PORT_Memset(attribute->attrib.pValue, 0,
                        attribute->attrib.ulValueLen);
        }
        PORT_Memcpy(att_val, value, len);
    }
    if (attribute->attrib.pValue != NULL) {
        if (attribute->attrib.pValue != att_val) {
            PORT_Memset(attribute->attrib.pValue, 0,
                        attribute->attrib.ulValueLen);
        }
        if (attribute->freeData) {
            PORT_Free(attribute->attrib.pValue);
        }
        attribute->freeData = PR_FALSE;
        attribute->attrib.pValue = NULL;
        attribute->attrib.ulValueLen = 0;
    }
    if (att_val) {
        attribute->attrib.pValue = att_val;
        attribute->attrib.ulValueLen = len;
        attribute->freeData = freeData;
    }
    sftk_FreeAttribute(attribute);
    return CKR_OK;
}

/*
 * return a null terminated string from attribute 'type'. This string
 * is allocated and needs to be freed with PORT_Free() When complete.
 */
char *
sftk_getString(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;
    char *label = NULL;

    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return NULL;

    if (attribute->attrib.pValue != NULL) {
        label = (char *)PORT_Alloc(attribute->attrib.ulValueLen + 1);
        if (label == NULL) {
            sftk_FreeAttribute(attribute);
            return NULL;
        }

        PORT_Memcpy(label, attribute->attrib.pValue,
                    attribute->attrib.ulValueLen);
        label[attribute->attrib.ulValueLen] = 0;
    }
    sftk_FreeAttribute(attribute);
    return label;
}

/*
 * decode when a particular attribute may be modified
 *  SFTK_NEVER: This attribute must be set at object creation time and
 *  can never be modified.
 *  SFTK_ONCOPY: This attribute may be modified only when you copy the
 *  object.
 *  SFTK_SENSITIVE: The CKA_SENSITIVE attribute can only be changed from
 *  CK_FALSE to CK_TRUE.
 *  SFTK_ALWAYS: This attribute can always be modified.
 * Some attributes vary their modification type based on the class of the
 *   object.
 */
SFTKModifyType
sftk_modifyType(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass)
{
    /* if we don't know about it, user user defined, always allow modify */
    SFTKModifyType mtype = SFTK_ALWAYS;

    switch (type) {
        /* NEVER */
        case CKA_CLASS:
        case CKA_CERTIFICATE_TYPE:
        case CKA_KEY_TYPE:
        case CKA_MODULUS:
        case CKA_MODULUS_BITS:
        case CKA_PUBLIC_EXPONENT:
        case CKA_PRIVATE_EXPONENT:
        case CKA_PRIME:
        case CKA_SUBPRIME:
        case CKA_BASE:
        case CKA_PRIME_1:
        case CKA_PRIME_2:
        case CKA_EXPONENT_1:
        case CKA_EXPONENT_2:
        case CKA_COEFFICIENT:
        case CKA_VALUE_LEN:
        case CKA_ALWAYS_SENSITIVE:
        case CKA_NEVER_EXTRACTABLE:
        case CKA_NETSCAPE_DB:
            mtype = SFTK_NEVER;
            break;

        /* ONCOPY */
        case CKA_TOKEN:
        case CKA_PRIVATE:
        case CKA_MODIFIABLE:
            mtype = SFTK_ONCOPY;
            break;

        /* SENSITIVE */
        case CKA_SENSITIVE:
        case CKA_EXTRACTABLE:
            mtype = SFTK_SENSITIVE;
            break;

        /* ALWAYS */
        case CKA_LABEL:
        case CKA_APPLICATION:
        case CKA_ID:
        case CKA_SERIAL_NUMBER:
        case CKA_START_DATE:
        case CKA_END_DATE:
        case CKA_DERIVE:
        case CKA_ENCRYPT:
        case CKA_DECRYPT:
        case CKA_SIGN:
        case CKA_VERIFY:
        case CKA_SIGN_RECOVER:
        case CKA_VERIFY_RECOVER:
        case CKA_WRAP:
        case CKA_UNWRAP:
            mtype = SFTK_ALWAYS;
            break;

        /* DEPENDS ON CLASS */
        case CKA_VALUE:
            mtype = (inClass == CKO_DATA) ? SFTK_ALWAYS : SFTK_NEVER;
            break;

        case CKA_SUBJECT:
            mtype = (inClass == CKO_CERTIFICATE) ? SFTK_NEVER : SFTK_ALWAYS;
            break;
        default:
            break;
    }
    return mtype;
}

/* decode if a particular attribute is sensitive (cannot be read
 * back to the user of if the object is set to SENSITIVE) */
PRBool
sftk_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass)
{
    switch (type) {
        /* ALWAYS */
        case CKA_PRIVATE_EXPONENT:
        case CKA_PRIME_1:
        case CKA_PRIME_2:
        case CKA_EXPONENT_1:
        case CKA_EXPONENT_2:
        case CKA_COEFFICIENT:
            return PR_TRUE;

        /* DEPENDS ON CLASS */
        case CKA_VALUE:
            /* PRIVATE and SECRET KEYS have SENSITIVE values */
            return (PRBool)((inClass == CKO_PRIVATE_KEY) || (inClass == CKO_SECRET_KEY));

        default:
            break;
    }
    return PR_FALSE;
}

/*
 * copy an attribute into a SECItem. Secitem is allocated in the specified
 * arena.
 */
CK_RV
sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item, SFTKObject *object,
                       CK_ATTRIBUTE_TYPE type)
{
    int len;
    SFTKAttribute *attribute;

    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return CKR_TEMPLATE_INCOMPLETE;
    len = attribute->attrib.ulValueLen;

    if (arena) {
        item->data = (unsigned char *)PORT_ArenaAlloc(arena, len);
    } else {
        item->data = (unsigned char *)PORT_Alloc(len);
    }
    if (item->data == NULL) {
        sftk_FreeAttribute(attribute);
        return CKR_HOST_MEMORY;
    }
    item->len = len;
    PORT_Memcpy(item->data, attribute->attrib.pValue, len);
    sftk_FreeAttribute(attribute);
    return CKR_OK;
}

CK_RV
sftk_GetULongAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
                       CK_ULONG *longData)
{
    SFTKAttribute *attribute;

    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return CKR_TEMPLATE_INCOMPLETE;

    if (attribute->attrib.ulValueLen != sizeof(CK_ULONG)) {
        return CKR_ATTRIBUTE_VALUE_INVALID;
    }

    *longData = *(CK_ULONG *)attribute->attrib.pValue;
    sftk_FreeAttribute(attribute);
    return CKR_OK;
}

void
sftk_DeleteAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type)
{
    SFTKAttribute *attribute;
    attribute = sftk_FindAttribute(object, type);
    if (attribute == NULL)
        return;
    sftk_DeleteAttribute(object, attribute);
    sftk_FreeAttribute(attribute);
}

CK_RV
sftk_AddAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type,
                      const void *valPtr, CK_ULONG length)
{
    SFTKAttribute *attribute;
    attribute = sftk_NewAttribute(object, type, valPtr, length);
    if (attribute == NULL) {
        return CKR_HOST_MEMORY;
    }
    sftk_AddAttribute(object, attribute);
    return CKR_OK;
}

/*
 * ******************** Object Utilities *******************************
 */

/* must be called holding sftk_tokenKeyLock(slot) */
static SECItem *
sftk_lookupTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle)
{
    return (SECItem *)PL_HashTableLookup(slot->tokObjHashTable, (void *)handle);
}

/*
 * use the refLock. This operations should be very rare, so the added
 * contention on the ref lock should be lower than the overhead of adding
 * a new lock. We use separate functions for this just in case I'm wrong.
 */
static void
sftk_tokenKeyLock(SFTKSlot *slot)
{
    SKIP_AFTER_FORK(PZ_Lock(slot->objectLock));
}

static void
sftk_tokenKeyUnlock(SFTKSlot *slot)
{
    SKIP_AFTER_FORK(PZ_Unlock(slot->objectLock));
}

static PRIntn
sftk_freeHashItem(PLHashEntry *entry, PRIntn index, void *arg)
{
    SECItem *item = (SECItem *)entry->value;

    SECITEM_FreeItem(item, PR_TRUE);
    return HT_ENUMERATE_NEXT;
}

CK_RV
SFTK_ClearTokenKeyHashTable(SFTKSlot *slot)
{
    sftk_tokenKeyLock(slot);
    PORT_Assert(!slot->present);
    PL_HashTableEnumerateEntries(slot->tokObjHashTable, sftk_freeHashItem, NULL);
    sftk_tokenKeyUnlock(slot);
    return CKR_OK;
}

/* allocation hooks that allow us to recycle old object structures */
static SFTKObjectFreeList sessionObjectList = { NULL, NULL, 0 };
static SFTKObjectFreeList tokenObjectList = { NULL, NULL, 0 };

SFTKObject *
sftk_GetObjectFromList(PRBool *hasLocks, PRBool optimizeSpace,
                       SFTKObjectFreeList *list, unsigned int hashSize, PRBool isSessionObject)
{
    SFTKObject *object;
    int size = 0;

    if (!optimizeSpace) {
        PZ_Lock(list->lock);
        object = list->head;
        if (object) {
            list->head = object->next;
            list->count--;
        }
        PZ_Unlock(list->lock);
        if (object) {
            object->next = object->prev = NULL;
            *hasLocks = PR_TRUE;
            return object;
        }
    }
    size = isSessionObject ? sizeof(SFTKSessionObject) + hashSize * sizeof(SFTKAttribute *) : sizeof(SFTKTokenObject);

    object = (SFTKObject *)PORT_ZAlloc(size);
    if (isSessionObject && object) {
        ((SFTKSessionObject *)object)->hashSize = hashSize;
    }
    *hasLocks = PR_FALSE;
    return object;
}

static void
sftk_PutObjectToList(SFTKObject *object, SFTKObjectFreeList *list,
                     PRBool isSessionObject)
{

    /* the code below is equivalent to :
     *     optimizeSpace = isSessionObject ? object->optimizeSpace : PR_FALSE;
     * just faster.
     */
    PRBool optimizeSpace = isSessionObject &&
                           ((SFTKSessionObject *)object)->optimizeSpace;
    if (object->refLock && !optimizeSpace && (list->count < MAX_OBJECT_LIST_SIZE)) {
        PZ_Lock(list->lock);
        object->next = list->head;
        list->head = object;
        list->count++;
        PZ_Unlock(list->lock);
        return;
    }
    if (isSessionObject) {
        SFTKSessionObject *so = (SFTKSessionObject *)object;
        PZ_DestroyLock(so->attributeLock);
        so->attributeLock = NULL;
    }
    if (object->refLock) {
        PZ_DestroyLock(object->refLock);
        object->refLock = NULL;
    }
    PORT_Free(object);
}

static SFTKObject *
sftk_freeObjectData(SFTKObject *object)
{
    SFTKObject *next = object->next;

    PORT_Free(object);
    return next;
}

static void
sftk_InitFreeList(SFTKObjectFreeList *list)
{
    if (!list->lock) {
        list->lock = PZ_NewLock(nssILockObject);
    }
}

void
sftk_InitFreeLists(void)
{
    sftk_InitFreeList(&sessionObjectList);
    sftk_InitFreeList(&tokenObjectList);
}

static void
sftk_CleanupFreeList(SFTKObjectFreeList *list, PRBool isSessionList)
{
    SFTKObject *object;

    if (!list->lock) {
        return;
    }
    SKIP_AFTER_FORK(PZ_Lock(list->lock));
    for (object = list->head; object != NULL;
         object = sftk_freeObjectData(object)) {
        PZ_DestroyLock(object->refLock);
        if (isSessionList) {
            PZ_DestroyLock(((SFTKSessionObject *)object)->attributeLock);
        }
    }
    list->count = 0;
    list->head = NULL;
    SKIP_AFTER_FORK(PZ_Unlock(list->lock));
    SKIP_AFTER_FORK(PZ_DestroyLock(list->lock));
    list->lock = NULL;
}

void
sftk_CleanupFreeLists(void)
{
    sftk_CleanupFreeList(&sessionObjectList, PR_TRUE);
    sftk_CleanupFreeList(&tokenObjectList, PR_FALSE);
}

/*
 * Create a new object
 */
SFTKObject *
sftk_NewObject(SFTKSlot *slot)
{
    SFTKObject *object;
    SFTKSessionObject *sessObject;
    PRBool hasLocks = PR_FALSE;
    unsigned int i;
    unsigned int hashSize = 0;

    hashSize = (slot->optimizeSpace) ? SPACE_ATTRIBUTE_HASH_SIZE : TIME_ATTRIBUTE_HASH_SIZE;

    object = sftk_GetObjectFromList(&hasLocks, slot->optimizeSpace,
                                    &sessionObjectList, hashSize, PR_TRUE);
    if (object == NULL) {
        return NULL;
    }
    sessObject = (SFTKSessionObject *)object;
    sessObject->nextAttr = 0;

    for (i = 0; i < MAX_OBJS_ATTRS; i++) {
        sessObject->attrList[i].attrib.pValue = NULL;
        sessObject->attrList[i].freeData = PR_FALSE;
    }
    sessObject->optimizeSpace = slot->optimizeSpace;

    object->handle = 0;
    object->next = object->prev = NULL;
    object->slot = slot;

    object->refCount = 1;
    sessObject->sessionList.next = NULL;
    sessObject->sessionList.prev = NULL;
    sessObject->sessionList.parent = object;
    sessObject->session = NULL;
    sessObject->wasDerived = PR_FALSE;
    if (!hasLocks)
        object->refLock = PZ_NewLock(nssILockRefLock);
    if (object->refLock == NULL) {
        PORT_Free(object);
        return NULL;
    }
    if (!hasLocks)
        sessObject->attributeLock = PZ_NewLock(nssILockAttribute);
    if (sessObject->attributeLock == NULL) {
        PZ_DestroyLock(object->refLock);
        PORT_Free(object);
        return NULL;
    }
    for (i = 0; i < sessObject->hashSize; i++) {
        sessObject->head[i] = NULL;
    }
    object->objectInfo = NULL;
    object->infoFree = NULL;
    return object;
}

static CK_RV
sftk_DestroySessionObjectData(SFTKSessionObject *so)
{
    int i;

    for (i = 0; i < MAX_OBJS_ATTRS; i++) {
        unsigned char *value = so->attrList[i].attrib.pValue;
        if (value) {
            PORT_Memset(value, 0, so->attrList[i].attrib.ulValueLen);
            if (so->attrList[i].freeData) {
                PORT_Free(value);
            }
            so->attrList[i].attrib.pValue = NULL;
            so->attrList[i].freeData = PR_FALSE;
        }
    }
    /*  PZ_DestroyLock(so->attributeLock);*/
    return CKR_OK;
}

/*
 * free all the data associated with an object. Object reference count must
 * be 'zero'.
 */
static CK_RV
sftk_DestroyObject(SFTKObject *object)
{
    CK_RV crv = CKR_OK;
    SFTKSessionObject *so = sftk_narrowToSessionObject(object);
    SFTKTokenObject *to = sftk_narrowToTokenObject(object);

    PORT_Assert(object->refCount == 0);

    /* delete the database value */
    if (to) {
        if (to->dbKey.data) {
            PORT_Free(to->dbKey.data);
            to->dbKey.data = NULL;
        }
    }
    if (so) {
        sftk_DestroySessionObjectData(so);
    }
    if (object->objectInfo) {
        (*object->infoFree)(object->objectInfo);
        object->objectInfo = NULL;
        object->infoFree = NULL;
    }
    if (so) {
        sftk_PutObjectToList(object, &sessionObjectList, PR_TRUE);
    } else {
        sftk_PutObjectToList(object, &tokenObjectList, PR_FALSE);
    }
    return crv;
}

void
sftk_ReferenceObject(SFTKObject *object)
{
    PZ_Lock(object->refLock);
    object->refCount++;
    PZ_Unlock(object->refLock);
}

static SFTKObject *
sftk_ObjectFromHandleOnSlot(CK_OBJECT_HANDLE handle, SFTKSlot *slot)
{
    SFTKObject *object;
    PRUint32 index = sftk_hash(handle, slot->sessObjHashSize);

    if (sftk_isToken(handle)) {
        return sftk_NewTokenObject(slot, NULL, handle);
    }

    PZ_Lock(slot->objectLock);
    sftkqueue_find2(object, handle, index, slot->sessObjHashTable);
    if (object) {
        sftk_ReferenceObject(object);
    }
    PZ_Unlock(slot->objectLock);

    return (object);
}
/*
 * look up and object structure from a handle. OBJECT_Handles only make
 * sense in terms of a given session.  make a reference to that object
 * structure returned.
 */
SFTKObject *
sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle, SFTKSession *session)
{
    SFTKSlot *slot = sftk_SlotFromSession(session);

    return sftk_ObjectFromHandleOnSlot(handle, slot);
}

/*
 * release a reference to an object handle
 */
SFTKFreeStatus
sftk_FreeObject(SFTKObject *object)
{
    PRBool destroy = PR_FALSE;
    CK_RV crv;

    PZ_Lock(object->refLock);
    if (object->refCount == 1)
        destroy = PR_TRUE;
    object->refCount--;
    PZ_Unlock(object->refLock);

    if (destroy) {
        crv = sftk_DestroyObject(object);
        if (crv != CKR_OK) {
            return SFTK_DestroyFailure;
        }
        return SFTK_Destroyed;
    }
    return SFTK_Busy;
}

/*
 * add an object to a slot and session queue. These two functions
 * adopt the object.
 */
void
sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object)
{
    PRUint32 index = sftk_hash(object->handle, slot->sessObjHashSize);
    sftkqueue_init_element(object);
    PZ_Lock(slot->objectLock);
    sftkqueue_add2(object, object->handle, index, slot->sessObjHashTable);
    PZ_Unlock(slot->objectLock);
}

void
sftk_AddObject(SFTKSession *session, SFTKObject *object)
{
    SFTKSlot *slot = sftk_SlotFromSession(session);
    SFTKSessionObject *so = sftk_narrowToSessionObject(object);

    if (so) {
        PZ_Lock(session->objectLock);
        sftkqueue_add(&so->sessionList, 0, session->objects, 0);
        so->session = session;
        PZ_Unlock(session->objectLock);
    }
    sftk_AddSlotObject(slot, object);
    sftk_ReferenceObject(object);
}

/*
 * delete an object from a slot and session queue
 */
CK_RV
sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
{
    SFTKSlot *slot = sftk_SlotFromSession(session);
    SFTKSessionObject *so = sftk_narrowToSessionObject(object);
    CK_RV crv = CKR_OK;
    PRUint32 index = sftk_hash(object->handle, slot->sessObjHashSize);

    /* Handle Token case */
    if (so && so->session) {
        session = so->session;
        PZ_Lock(session->objectLock);
        sftkqueue_delete(&so->sessionList, 0, session->objects, 0);
        PZ_Unlock(session->objectLock);
        PZ_Lock(slot->objectLock);
        sftkqueue_delete2(object, object->handle, index, slot->sessObjHashTable);
        PZ_Unlock(slot->objectLock);
        sftkqueue_clear_deleted_element(object);
        sftk_FreeObject(object); /* free the reference owned by the queue */
    } else {
        SFTKDBHandle *handle = sftk_getDBForTokenObject(slot, object->handle);
#ifdef DEBUG
        SFTKTokenObject *to = sftk_narrowToTokenObject(object);
        PORT_Assert(to);
#endif
        crv = sftkdb_DestroyObject(handle, object->handle);
        sftk_freeDB(handle);
    }
    return crv;
}

/*
 * Token objects don't explicitly store their attributes, so we need to know
 * what attributes make up a particular token object before we can copy it.
 * below are the tables by object type.
 */
static const CK_ATTRIBUTE_TYPE commonAttrs[] = {
    CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_MODIFIABLE
};
static const CK_ULONG commonAttrsCount =
    sizeof(commonAttrs) / sizeof(commonAttrs[0]);

static const CK_ATTRIBUTE_TYPE commonKeyAttrs[] = {
    CKA_ID, CKA_START_DATE, CKA_END_DATE, CKA_DERIVE, CKA_LOCAL, CKA_KEY_TYPE
};
static const CK_ULONG commonKeyAttrsCount =
    sizeof(commonKeyAttrs) / sizeof(commonKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE secretKeyAttrs[] = {
    CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_ENCRYPT, CKA_DECRYPT, CKA_SIGN,
    CKA_VERIFY, CKA_WRAP, CKA_UNWRAP, CKA_VALUE
};
static const CK_ULONG secretKeyAttrsCount =
    sizeof(secretKeyAttrs) / sizeof(secretKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE commonPubKeyAttrs[] = {
    CKA_ENCRYPT, CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_WRAP, CKA_SUBJECT
};
static const CK_ULONG commonPubKeyAttrsCount =
    sizeof(commonPubKeyAttrs) / sizeof(commonPubKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE rsaPubKeyAttrs[] = {
    CKA_MODULUS, CKA_PUBLIC_EXPONENT
};
static const CK_ULONG rsaPubKeyAttrsCount =
    sizeof(rsaPubKeyAttrs) / sizeof(rsaPubKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE dsaPubKeyAttrs[] = {
    CKA_SUBPRIME, CKA_PRIME, CKA_BASE, CKA_VALUE
};
static const CK_ULONG dsaPubKeyAttrsCount =
    sizeof(dsaPubKeyAttrs) / sizeof(dsaPubKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE dhPubKeyAttrs[] = {
    CKA_PRIME, CKA_BASE, CKA_VALUE
};
static const CK_ULONG dhPubKeyAttrsCount =
    sizeof(dhPubKeyAttrs) / sizeof(dhPubKeyAttrs[0]);
static const CK_ATTRIBUTE_TYPE ecPubKeyAttrs[] = {
    CKA_EC_PARAMS, CKA_EC_POINT
};
static const CK_ULONG ecPubKeyAttrsCount =
    sizeof(ecPubKeyAttrs) / sizeof(ecPubKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE commonPrivKeyAttrs[] = {
    CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER, CKA_UNWRAP, CKA_SUBJECT,
    CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_NETSCAPE_DB, CKA_PUBLIC_KEY_INFO
};
static const CK_ULONG commonPrivKeyAttrsCount =
    sizeof(commonPrivKeyAttrs) / sizeof(commonPrivKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE rsaPrivKeyAttrs[] = {
    CKA_MODULUS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT,
    CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT
};
static const CK_ULONG rsaPrivKeyAttrsCount =
    sizeof(rsaPrivKeyAttrs) / sizeof(rsaPrivKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE dsaPrivKeyAttrs[] = {
    CKA_SUBPRIME, CKA_PRIME, CKA_BASE, CKA_VALUE
};
static const CK_ULONG dsaPrivKeyAttrsCount =
    sizeof(dsaPrivKeyAttrs) / sizeof(dsaPrivKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE dhPrivKeyAttrs[] = {
    CKA_PRIME, CKA_BASE, CKA_VALUE
};
static const CK_ULONG dhPrivKeyAttrsCount =
    sizeof(dhPrivKeyAttrs) / sizeof(dhPrivKeyAttrs[0]);
static const CK_ATTRIBUTE_TYPE ecPrivKeyAttrs[] = {
    CKA_EC_PARAMS, CKA_VALUE
};
static const CK_ULONG ecPrivKeyAttrsCount =
    sizeof(ecPrivKeyAttrs) / sizeof(ecPrivKeyAttrs[0]);

static const CK_ATTRIBUTE_TYPE certAttrs[] = {
    CKA_CERTIFICATE_TYPE, CKA_VALUE, CKA_SUBJECT, CKA_ISSUER, CKA_SERIAL_NUMBER
};
static const CK_ULONG certAttrsCount =
    sizeof(certAttrs) / sizeof(certAttrs[0]);

static const CK_ATTRIBUTE_TYPE trustAttrs[] = {
    CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
    CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, CKA_TRUST_EMAIL_PROTECTION,
    CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED
};
static const CK_ULONG trustAttrsCount =
    sizeof(trustAttrs) / sizeof(trustAttrs[0]);

static const CK_ATTRIBUTE_TYPE smimeAttrs[] = {
    CKA_SUBJECT, CKA_NETSCAPE_EMAIL, CKA_NETSCAPE_SMIME_TIMESTAMP, CKA_VALUE
};
static const CK_ULONG smimeAttrsCount =
    sizeof(smimeAttrs) / sizeof(smimeAttrs[0]);

static const CK_ATTRIBUTE_TYPE crlAttrs[] = {
    CKA_SUBJECT, CKA_VALUE, CKA_NETSCAPE_URL, CKA_NETSCAPE_KRL
};
static const CK_ULONG crlAttrsCount =
    sizeof(crlAttrs) / sizeof(crlAttrs[0]);

/* copy an object based on it's table */
CK_RV
stfk_CopyTokenAttributes(SFTKObject *destObject, SFTKTokenObject *src_to,
                         const CK_ATTRIBUTE_TYPE *attrArray, CK_ULONG attrCount)
{
    SFTKAttribute *attribute;
    SFTKAttribute *newAttribute;
    CK_RV crv = CKR_OK;
    unsigned int i;

    for (i = 0; i < attrCount; i++) {
        if (!sftk_hasAttribute(destObject, attrArray[i])) {
            attribute = sftk_FindAttribute(&src_to->obj, attrArray[i]);
            if (!attribute) {
                continue; /* return CKR_ATTRIBUTE_VALUE_INVALID; */
            }
            /* we need to copy the attribute since each attribute
             * only has one set of link list pointers */
            newAttribute = sftk_NewAttribute(destObject,
                                             sftk_attr_expand(&attribute->attrib));
            sftk_FreeAttribute(attribute); /* free the old attribute */
            if (!newAttribute) {
                return CKR_HOST_MEMORY;
            }
            sftk_AddAttribute(destObject, newAttribute);
        }
    }
    return crv;
}

CK_RV
stfk_CopyTokenPrivateKey(SFTKObject *destObject, SFTKTokenObject *src_to)
{
    CK_RV crv;
    CK_KEY_TYPE key_type;
    SFTKAttribute *attribute;

    /* copy the common attributes for all keys first */
    crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
                                   commonKeyAttrsCount);
    if (crv != CKR_OK) {
        goto fail;
    }
    /* copy the common attributes for all private keys next */
    crv = stfk_CopyTokenAttributes(destObject, src_to, commonPrivKeyAttrs,
                                   commonPrivKeyAttrsCount);
    if (crv != CKR_OK) {
        goto fail;
    }
    attribute = sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE);
    PORT_Assert(attribute); /* if it wasn't here, ww should have failed
                 * copying the common attributes */
    if (!attribute) {
        /* OK, so CKR_ATTRIBUTE_VALUE_INVALID is the immediate error, but
         * the fact is, the only reason we couldn't get the attribute would
         * be a memory error or database error (an error in the 'device').
         * if we have a database error code, we could return it here */
        crv = CKR_DEVICE_ERROR;
        goto fail;
    }
    key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
    sftk_FreeAttribute(attribute);

    /* finally copy the attributes for various private key types */
    switch (key_type) {
        case CKK_RSA:
            crv = stfk_CopyTokenAttributes(destObject, src_to, rsaPrivKeyAttrs,
                                           rsaPrivKeyAttrsCount);
            break;
        case CKK_DSA:
            crv = stfk_CopyTokenAttributes(destObject, src_to, dsaPrivKeyAttrs,
                                           dsaPrivKeyAttrsCount);
            break;
        case CKK_DH:
            crv = stfk_CopyTokenAttributes(destObject, src_to, dhPrivKeyAttrs,
                                           dhPrivKeyAttrsCount);
            break;
        case CKK_EC:
            crv = stfk_CopyTokenAttributes(destObject, src_to, ecPrivKeyAttrs,
                                           ecPrivKeyAttrsCount);
            break;
        default:
            crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
                                     * of token keys into our database. */
    }
fail:
    return crv;
}

CK_RV
stfk_CopyTokenPublicKey(SFTKObject *destObject, SFTKTokenObject *src_to)
{
    CK_RV crv;
    CK_KEY_TYPE key_type;
    SFTKAttribute *attribute;

    /* copy the common attributes for all keys first */
    crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
                                   commonKeyAttrsCount);
    if (crv != CKR_OK) {
        goto fail;
    }

    /* copy the common attributes for all public keys next */
    crv = stfk_CopyTokenAttributes(destObject, src_to, commonPubKeyAttrs,
                                   commonPubKeyAttrsCount);
    if (crv != CKR_OK) {
        goto fail;
    }
    attribute = sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE);
    PORT_Assert(attribute); /* if it wasn't here, ww should have failed
                 * copying the common attributes */
    if (!attribute) {
        /* OK, so CKR_ATTRIBUTE_VALUE_INVALID is the immediate error, but
         * the fact is, the only reason we couldn't get the attribute would
         * be a memory error or database error (an error in the 'device').
         * if we have a database error code, we could return it here */
        crv = CKR_DEVICE_ERROR;
        goto fail;
    }
    key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue;
    sftk_FreeAttribute(attribute);

    /* finally copy the attributes for various public key types */
    switch (key_type) {
        case CKK_RSA:
            crv = stfk_CopyTokenAttributes(destObject, src_to, rsaPubKeyAttrs,
                                           rsaPubKeyAttrsCount);
            break;
        case CKK_DSA:
            crv = stfk_CopyTokenAttributes(destObject, src_to, dsaPubKeyAttrs,
                                           dsaPubKeyAttrsCount);
            break;
        case CKK_DH:
            crv = stfk_CopyTokenAttributes(destObject, src_to, dhPubKeyAttrs,
                                           dhPubKeyAttrsCount);
            break;
        case CKK_EC:
            crv = stfk_CopyTokenAttributes(destObject, src_to, ecPubKeyAttrs,
                                           ecPubKeyAttrsCount);
            break;
        default:
            crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
                                     * of token keys into our database. */
    }
fail:
    return crv;
}
CK_RV
stfk_CopyTokenSecretKey(SFTKObject *destObject, SFTKTokenObject *src_to)
{
    CK_RV crv;
    crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs,
                                   commonKeyAttrsCount);
    if (crv != CKR_OK) {
        goto fail;
    }
    crv = stfk_CopyTokenAttributes(destObject, src_to, secretKeyAttrs,
                                   secretKeyAttrsCount);
fail:
    return crv;
}

/*
 * Copy a token object. We need to explicitly copy the relevant
 * attributes since token objects don't store those attributes in
 * the token itself.
 */
CK_RV
sftk_CopyTokenObject(SFTKObject *destObject, SFTKObject *srcObject)
{
    SFTKTokenObject *src_to = sftk_narrowToTokenObject(srcObject);
    CK_RV crv;

    PORT_Assert(src_to);
    if (src_to == NULL) {
        return CKR_DEVICE_ERROR; /* internal state inconsistant */
    }

    crv = stfk_CopyTokenAttributes(destObject, src_to, commonAttrs,
                                   commonAttrsCount);
    if (crv != CKR_OK) {
        goto fail;
    }
    switch (src_to->obj.objclass) {
        case CKO_CERTIFICATE:
            crv = stfk_CopyTokenAttributes(destObject, src_to, certAttrs,
                                           certAttrsCount);
            break;
        case CKO_NETSCAPE_TRUST:
            crv = stfk_CopyTokenAttributes(destObject, src_to, trustAttrs,
                                           trustAttrsCount);
            break;
        case CKO_NETSCAPE_SMIME:
            crv = stfk_CopyTokenAttributes(destObject, src_to, smimeAttrs,
                                           smimeAttrsCount);
            break;
        case CKO_NETSCAPE_CRL:
            crv = stfk_CopyTokenAttributes(destObject, src_to, crlAttrs,
                                           crlAttrsCount);
            break;
        case CKO_PRIVATE_KEY:
            crv = stfk_CopyTokenPrivateKey(destObject, src_to);
            break;
        case CKO_PUBLIC_KEY:
            crv = stfk_CopyTokenPublicKey(destObject, src_to);
            break;
        case CKO_SECRET_KEY:
            crv = stfk_CopyTokenSecretKey(destObject, src_to);
            break;
        default:
            crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types
                                     * of token keys into our database. */
    }
fail:
    return crv;
}

/*
 * copy the attributes from one object to another. Don't overwrite existing
 * attributes. NOTE: This is a pretty expensive operation since it
 * grabs the attribute locks for the src object for a *long* time.
 */
CK_RV
sftk_CopyObject(SFTKObject *destObject, SFTKObject *srcObject)
{
    SFTKAttribute *attribute;
    SFTKSessionObject *src_so = sftk_narrowToSessionObject(srcObject);
    unsigned int i;

    if (src_so == NULL) {
        return sftk_CopyTokenObject(destObject, srcObject);
    }

    PZ_Lock(src_so->attributeLock);
    for (i = 0; i < src_so->hashSize; i++) {
        attribute = src_so->head[i];
        do {
            if (attribute) {
                if (!sftk_hasAttribute(destObject, attribute->handle)) {
                    /* we need to copy the attribute since each attribute
                     * only has one set of link list pointers */
                    SFTKAttribute *newAttribute = sftk_NewAttribute(
                        destObject, sftk_attr_expand(&attribute->attrib));
                    if (newAttribute == NULL) {
                        PZ_Unlock(src_so->attributeLock);
                        return CKR_HOST_MEMORY;
                    }
                    sftk_AddAttribute(destObject, newAttribute);
                }
                attribute = attribute->next;
            }
        } while (attribute != NULL);
    }
    PZ_Unlock(src_so->attributeLock);

    return CKR_OK;
}

/*
 * ******************** Search Utilities *******************************
 */

/* add an object to a search list */
CK_RV
AddToList(SFTKObjectListElement **list, SFTKObject *object)
{
    SFTKObjectListElement *newElem =
        (SFTKObjectListElement *)PORT_Alloc(sizeof(SFTKObjectListElement));

    if (newElem == NULL)
        return CKR_HOST_MEMORY;

    newElem->next = *list;
    newElem->object = object;
    sftk_ReferenceObject(object);

    *list = newElem;
    return CKR_OK;
}

/* return true if the object matches the template */
PRBool
sftk_objectMatch(SFTKObject *object, CK_ATTRIBUTE_PTR theTemplate, int count)
{
    int i;

    for (i = 0; i < count; i++) {
        SFTKAttribute *attribute = sftk_FindAttribute(object, theTemplate[i].type);
        if (attribute == NULL) {
            return PR_FALSE;
        }
        if (attribute->attrib.ulValueLen == theTemplate[i].ulValueLen) {
            if (PORT_Memcmp(attribute->attrib.pValue, theTemplate[i].pValue,
                            theTemplate[i].ulValueLen) == 0) {
                sftk_FreeAttribute(attribute);
                continue;
            }
        }
        sftk_FreeAttribute(attribute);
        return PR_FALSE;
    }
    return PR_TRUE;
}

/* search through all the objects in the queue and return the template matches
 * in the object list.
 */
CK_RV
sftk_searchObjectList(SFTKSearchResults *search, SFTKObject **head,
                      unsigned int size, PZLock *lock, CK_ATTRIBUTE_PTR theTemplate,
                      int count, PRBool isLoggedIn)
{
    unsigned int i;
    SFTKObject *object;
    CK_RV crv = CKR_OK;

    PZ_Lock(lock);
    for (i = 0; i < size; i++) {
        for (object = head[i]; object != NULL; object = object->next) {
            if (sftk_objectMatch(object, theTemplate, count)) {
                /* don't return objects that aren't yet visible */
                if ((!isLoggedIn) && sftk_isTrue(object, CKA_PRIVATE))
                    continue;
                sftk_addHandle(search, object->handle);
            }
        }
    }
    PZ_Unlock(lock);
    return crv;
}

/*
 * free a single list element. Return the Next object in the list.
 */
SFTKObjectListElement *
sftk_FreeObjectListElement(SFTKObjectListElement *objectList)
{
    SFTKObjectListElement *ol = objectList->next;

    sftk_FreeObject(objectList->object);
    PORT_Free(objectList);
    return ol;
}

/* free an entire object list */
void
sftk_FreeObjectList(SFTKObjectListElement *objectList)
{
    SFTKObjectListElement *ol;

    for (ol = objectList; ol != NULL; ol = sftk_FreeObjectListElement(ol)) {
    }
}

/*
 * free a search structure
 */
void
sftk_FreeSearch(SFTKSearchResults *search)
{
    if (search->handles) {
        PORT_Free(search->handles);
    }
    PORT_Free(search);
}

/*
 * ******************** Session Utilities *******************************
 */

/* update the sessions state based in it's flags and wether or not it's
 * logged in */
void
sftk_update_state(SFTKSlot *slot, SFTKSession *session)
{
    if (slot->isLoggedIn) {
        if (slot->ssoLoggedIn) {
            session->info.state = CKS_RW_SO_FUNCTIONS;
        } else if (session->info.flags & CKF_RW_SESSION) {
            session->info.state = CKS_RW_USER_FUNCTIONS;
        } else {
            session->info.state = CKS_RO_USER_FUNCTIONS;
        }
    } else {
        if (session->info.flags & CKF_RW_SESSION) {
            session->info.state = CKS_RW_PUBLIC_SESSION;
        } else {
            session->info.state = CKS_RO_PUBLIC_SESSION;
        }
    }
}

/* update the state of all the sessions on a slot */
void
sftk_update_all_states(SFTKSlot *slot)
{
    unsigned int i;
    SFTKSession *session;

    for (i = 0; i < slot->sessHashSize; i++) {
        PZLock *lock = SFTK_SESSION_LOCK(slot, i);
        PZ_Lock(lock);
        for (session = slot->head[i]; session; session = session->next) {
            sftk_update_state(slot, session);
        }
        PZ_Unlock(lock);
    }
}

/*
 * context are cipher and digest contexts that are associated with a session
 */
void
sftk_FreeContext(SFTKSessionContext *context)
{
    if (context->cipherInfo) {
        (*context->destroy)(context->cipherInfo, PR_TRUE);
    }
    if (context->hashInfo) {
        (*context->hashdestroy)(context->hashInfo, PR_TRUE);
    }
    if (context->key) {
        sftk_FreeObject(context->key);
        context->key = NULL;
    }
    PORT_Free(context);
}

/*
 * create a new nession. NOTE: The session handle is not set, and the
 * session is not added to the slot's session queue.
 */
SFTKSession *
sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication,
                CK_FLAGS flags)
{
    SFTKSession *session;
    SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE);

    if (slot == NULL)
        return NULL;

    session = (SFTKSession *)PORT_Alloc(sizeof(SFTKSession));
    if (session == NULL)
        return NULL;

    session->next = session->prev = NULL;
    session->refCount = 1;
    session->enc_context = NULL;
    session->hash_context = NULL;
    session->sign_context = NULL;
    session->search = NULL;
    session->objectIDCount = 1;
    session->objectLock = PZ_NewLock(nssILockObject);
    if (session->objectLock == NULL) {
        PORT_Free(session);
        return NULL;
    }
    session->objects[0] = NULL;

    session->slot = slot;
    session->notify = notify;
    session->appData = pApplication;
    session->info.flags = flags;
    session->info.slotID = slotID;
    session->info.ulDeviceError = 0;
    sftk_update_state(slot, session);
    return session;
}

/* free all the data associated with a session. */
static void
sftk_DestroySession(SFTKSession *session)
{
    SFTKObjectList *op, *next;
    PORT_Assert(session->refCount == 0);

    /* clean out the attributes */
    /* since no one is referencing us, it's safe to walk the chain
     * without a lock */
    for (op = session->objects[0]; op != NULL; op = next) {
        next = op->next;
        /* paranoia */
        op->next = op->prev = NULL;
        sftk_DeleteObject(session, op->parent);
    }
    PZ_DestroyLock(session->objectLock);
    if (session->enc_context) {
        sftk_FreeContext(session->enc_context);
    }
    if (session->hash_context) {
        sftk_FreeContext(session->hash_context);
    }
    if (session->sign_context) {
        sftk_FreeContext(session->sign_context);
    }
    if (session->search) {
        sftk_FreeSearch(session->search);
    }
    PORT_Free(session);
}

/*
 * look up a session structure from a session handle
 * generate a reference to it.
 */
SFTKSession *
sftk_SessionFromHandle(CK_SESSION_HANDLE handle)
{
    SFTKSlot *slot = sftk_SlotFromSessionHandle(handle);
    SFTKSession *session;
    PZLock *lock;

    if (!slot)
        return NULL;
    lock = SFTK_SESSION_LOCK(slot, handle);

    PZ_Lock(lock);
    sftkqueue_find(session, handle, slot->head, slot->sessHashSize);
    if (session)
        session->refCount++;
    PZ_Unlock(lock);

    return (session);
}

/*
 * release a reference to a session handle
 */
void
sftk_FreeSession(SFTKSession *session)
{
    PRBool destroy = PR_FALSE;
    SFTKSlot *slot = sftk_SlotFromSession(session);
    PZLock *lock = SFTK_SESSION_LOCK(slot, session->handle);

    PZ_Lock(lock);
    if (session->refCount == 1)
        destroy = PR_TRUE;
    session->refCount--;
    PZ_Unlock(lock);

    if (destroy)
        sftk_DestroySession(session);
}

void
sftk_addHandle(SFTKSearchResults *search, CK_OBJECT_HANDLE handle)
{
    if (search->handles == NULL) {
        return;
    }
    if (search->size >= search->array_size) {
        search->array_size += NSC_SEARCH_BLOCK_SIZE;
        search->handles = (CK_OBJECT_HANDLE *)PORT_Realloc(search->handles,
                                                           sizeof(CK_OBJECT_HANDLE) * search->array_size);
        if (search->handles == NULL) {
            return;
        }
    }
    search->handles[search->size] = handle;
    search->size++;
}

static CK_RV
handleToClass(SFTKSlot *slot, CK_OBJECT_HANDLE handle,
              CK_OBJECT_CLASS *objClass)
{
    SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, handle);
    CK_ATTRIBUTE objClassTemplate;
    CK_RV crv;

    *objClass = CKO_DATA;
    objClassTemplate.type = CKA_CLASS;
    objClassTemplate.pValue = objClass;
    objClassTemplate.ulValueLen = sizeof(*objClass);
    crv = sftkdb_GetAttributeValue(dbHandle, handle, &objClassTemplate, 1);
    sftk_freeDB(dbHandle);
    return crv;
}

SFTKObject *
sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey, CK_OBJECT_HANDLE handle)
{
    SFTKObject *object = NULL;
    PRBool hasLocks = PR_FALSE;
    CK_RV crv;

    object = sftk_GetObjectFromList(&hasLocks, PR_FALSE, &tokenObjectList, 0,
                                    PR_FALSE);
    if (object == NULL) {
        return NULL;
    }

    object->handle = handle;
    /* every object must have a class, if we can't get it, the object
     * doesn't exist */
    crv = handleToClass(slot, handle, &object->objclass);
    if (crv != CKR_OK) {
        goto loser;
    }
    object->slot = slot;
    object->objectInfo = NULL;
    object->infoFree = NULL;
    if (!hasLocks) {
        object->refLock = PZ_NewLock(nssILockRefLock);
    }
    if (object->refLock == NULL) {
        goto loser;
    }
    object->refCount = 1;

    return object;
loser:
    (void)sftk_DestroyObject(object);
    return NULL;
}

SFTKTokenObject *
sftk_convertSessionToToken(SFTKObject *obj)
{
    SECItem *key;
    SFTKSessionObject *so = (SFTKSessionObject *)obj;
    SFTKTokenObject *to = sftk_narrowToTokenObject(obj);
    SECStatus rv;

    sftk_DestroySessionObjectData(so);
    PZ_DestroyLock(so->attributeLock);
    if (to == NULL) {
        return NULL;
    }
    sftk_tokenKeyLock(so->obj.slot);
    key = sftk_lookupTokenKeyByHandle(so->obj.slot, so->obj.handle);
    if (key == NULL) {
        sftk_tokenKeyUnlock(so->obj.slot);
        return NULL;
    }
    rv = SECITEM_CopyItem(NULL, &to->dbKey, key);
    sftk_tokenKeyUnlock(so->obj.slot);
    if (rv == SECFailure) {
        return NULL;
    }

    return to;
}

SFTKSessionObject *
sftk_narrowToSessionObject(SFTKObject *obj)
{
    return !sftk_isToken(obj->handle) ? (SFTKSessionObject *)obj : NULL;
}

SFTKTokenObject *
sftk_narrowToTokenObject(SFTKObject *obj)
{
    return sftk_isToken(obj->handle) ? (SFTKTokenObject *)obj : NULL;
}
