/* 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/. */
/*
 * This file manages object type indepentent functions.
 */
#include <limits.h>
#include <stddef.h>

#include "seccomon.h"
#include "secmod.h"
#include "secmodi.h"
#include "secmodti.h"
#include "pkcs11.h"
#include "pkcs11t.h"
#include "pk11func.h"
#include "keyhi.h"
#include "secitem.h"
#include "secerr.h"
#include "sslerr.h"

#define PK11_SEARCH_CHUNKSIZE 10

/*
 * Build a block big enough to hold the data
 */
SECItem *
PK11_BlockData(SECItem *data, unsigned long size)
{
    SECItem *newData;

    if (size == 0u)
        return NULL;

    newData = (SECItem *)PORT_Alloc(sizeof(SECItem));
    if (newData == NULL)
        return NULL;

    newData->len = (data->len + (size - 1)) / size;
    newData->len *= size;

    newData->data = (unsigned char *)PORT_ZAlloc(newData->len);
    if (newData->data == NULL) {
        PORT_Free(newData);
        return NULL;
    }
    PORT_Memset(newData->data, newData->len - data->len, newData->len);
    PORT_Memcpy(newData->data, data->data, data->len);
    return newData;
}

SECStatus
PK11_DestroyObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE object)
{
    CK_RV crv;

    PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_DestroyObject(slot->session, object);
    PK11_ExitSlotMonitor(slot);
    if (crv != CKR_OK) {
        return SECFailure;
    }
    return SECSuccess;
}

SECStatus
PK11_DestroyTokenObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE object)
{
    CK_RV crv;
    SECStatus rv = SECSuccess;
    CK_SESSION_HANDLE rwsession;

    rwsession = PK11_GetRWSession(slot);
    if (rwsession == CK_INVALID_HANDLE) {
        PORT_SetError(SEC_ERROR_BAD_DATA);
        return SECFailure;
    }

    crv = PK11_GETTAB(slot)->C_DestroyObject(rwsession, object);
    if (crv != CKR_OK) {
        rv = SECFailure;
        PORT_SetError(PK11_MapError(crv));
    }
    PK11_RestoreROSession(slot, rwsession);
    return rv;
}

/*
 * Read in a single attribute into a SECItem. Allocate space for it with
 * PORT_Alloc unless an arena is supplied. In the latter case use the arena
 * to allocate the space.
 *
 * PK11_ReadAttribute sets the 'data' and 'len' fields of the SECItem but
 * does not modify its 'type' field.
 */
SECStatus
PK11_ReadAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
                   CK_ATTRIBUTE_TYPE type, PLArenaPool *arena, SECItem *result)
{
    CK_ATTRIBUTE attr = { 0, NULL, 0 };
    CK_RV crv;

    attr.type = type;

    PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session, id, &attr, 1);
    if (crv != CKR_OK) {
        PK11_ExitSlotMonitor(slot);
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    if (arena) {
        attr.pValue = PORT_ArenaAlloc(arena, attr.ulValueLen);
    } else {
        attr.pValue = PORT_Alloc(attr.ulValueLen);
    }
    if (attr.pValue == NULL) {
        PK11_ExitSlotMonitor(slot);
        return SECFailure;
    }
    crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session, id, &attr, 1);
    PK11_ExitSlotMonitor(slot);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        if (!arena)
            PORT_Free(attr.pValue);
        return SECFailure;
    }

    result->data = (unsigned char *)attr.pValue;
    result->len = attr.ulValueLen;

    return SECSuccess;
}

/*
 * Read in a single attribute into As a Ulong.
 */
CK_ULONG
PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
                        CK_ATTRIBUTE_TYPE type)
{
    CK_ATTRIBUTE attr;
    CK_ULONG value = CK_UNAVAILABLE_INFORMATION;
    CK_RV crv;

    PK11_SETATTRS(&attr, type, &value, sizeof(value));

    PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session, id, &attr, 1);
    PK11_ExitSlotMonitor(slot);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
    }
    return value;
}

/*
 * check to see if a bool has been set.
 */
CK_BBOOL
pk11_HasAttributeSet_Lock(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
                          CK_ATTRIBUTE_TYPE type, PRBool haslock)
{
    CK_BBOOL ckvalue = CK_FALSE;
    CK_ATTRIBUTE theTemplate;
    CK_RV crv;

    /* Prepare to retrieve the attribute. */
    PK11_SETATTRS(&theTemplate, type, &ckvalue, sizeof(CK_BBOOL));

    /* Retrieve attribute value. */
    if (!haslock)
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session, id,
                                                 &theTemplate, 1);
    if (!haslock)
        PK11_ExitSlotMonitor(slot);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return CK_FALSE;
    }

    return ckvalue;
}

CK_BBOOL
PK11_HasAttributeSet(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
                     CK_ATTRIBUTE_TYPE type, PRBool haslock)
{
    PR_ASSERT(haslock == PR_FALSE);
    return pk11_HasAttributeSet_Lock(slot, id, type, PR_FALSE);
}

/*
 * returns a full list of attributes. Allocate space for them. If an arena is
 * provided, allocate space out of the arena.
 */
CK_RV
PK11_GetAttributes(PLArenaPool *arena, PK11SlotInfo *slot,
                   CK_OBJECT_HANDLE obj, CK_ATTRIBUTE *attr, int count)
{
    int i;
    /* make pedantic happy... note that it's only used arena != NULL */
    void *mark = NULL;
    CK_RV crv;
    if (slot->session == CK_INVALID_HANDLE)
        return CKR_SESSION_HANDLE_INVALID;

    /*
     * first get all the lengths of the parameters.
     */
    PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session, obj, attr, count);
    if (crv != CKR_OK) {
        PK11_ExitSlotMonitor(slot);
        return crv;
    }

    if (arena) {
        mark = PORT_ArenaMark(arena);
        if (mark == NULL)
            return CKR_HOST_MEMORY;
    }

    /*
     * now allocate space to store the results.
     */
    for (i = 0; i < count; i++) {
        if (attr[i].ulValueLen == 0)
            continue;
        if (arena) {
            attr[i].pValue = PORT_ArenaAlloc(arena, attr[i].ulValueLen);
            if (attr[i].pValue == NULL) {
                /* arena failures, just release the mark */
                PORT_ArenaRelease(arena, mark);
                PK11_ExitSlotMonitor(slot);
                return CKR_HOST_MEMORY;
            }
        } else {
            attr[i].pValue = PORT_Alloc(attr[i].ulValueLen);
            if (attr[i].pValue == NULL) {
                /* Separate malloc failures, loop to release what we have
                 * so far */
                int j;
                for (j = 0; j < i; j++) {
                    PORT_Free(attr[j].pValue);
                    /* don't give the caller pointers to freed memory */
                    attr[j].pValue = NULL;
                }
                PK11_ExitSlotMonitor(slot);
                return CKR_HOST_MEMORY;
            }
        }
    }

    /*
     * finally get the results.
     */
    crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session, obj, attr, count);
    PK11_ExitSlotMonitor(slot);
    if (crv != CKR_OK) {
        if (arena) {
            PORT_ArenaRelease(arena, mark);
        } else {
            for (i = 0; i < count; i++) {
                PORT_Free(attr[i].pValue);
                /* don't give the caller pointers to freed memory */
                attr[i].pValue = NULL;
            }
        }
    } else if (arena && mark) {
        PORT_ArenaUnmark(arena, mark);
    }
    return crv;
}

PRBool
PK11_IsPermObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle)
{
    return (PRBool)PK11_HasAttributeSet(slot, handle, CKA_TOKEN, PR_FALSE);
}

char *
PK11_GetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id)
{
    char *nickname = NULL;
    SECItem result;
    SECStatus rv;

    rv = PK11_ReadAttribute(slot, id, CKA_LABEL, NULL, &result);
    if (rv != SECSuccess) {
        return NULL;
    }

    nickname = PORT_ZAlloc(result.len + 1);
    if (nickname == NULL) {
        PORT_Free(result.data);
        return NULL;
    }
    PORT_Memcpy(nickname, result.data, result.len);
    PORT_Free(result.data);
    return nickname;
}

SECStatus
PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
                       const char *nickname)
{
    int len = PORT_Strlen(nickname);
    CK_ATTRIBUTE setTemplate;
    CK_RV crv;
    CK_SESSION_HANDLE rwsession;

    if (len < 0) {
        return SECFailure;
    }

    PK11_SETATTRS(&setTemplate, CKA_LABEL, (CK_CHAR *)nickname, len);
    rwsession = PK11_GetRWSession(slot);
    if (rwsession == CK_INVALID_HANDLE) {
        PORT_SetError(SEC_ERROR_BAD_DATA);
        return SECFailure;
    }
    crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, id,
                                                 &setTemplate, 1);
    PK11_RestoreROSession(slot, rwsession);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    return SECSuccess;
}

/*
 * strip leading zero's from key material
 */
void
pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib)
{
    char *ptr = (char *)attrib->pValue;
    unsigned long len = attrib->ulValueLen;

    while ((len > 1) && (*ptr == 0)) {
        len--;
        ptr++;
    }
    attrib->pValue = ptr;
    attrib->ulValueLen = len;
}

/*
 * get a new session on a slot. If we run out of session, use the slot's
 * 'exclusive' session. In this case owner becomes false.
 */
CK_SESSION_HANDLE
pk11_GetNewSession(PK11SlotInfo *slot, PRBool *owner)
{
    CK_SESSION_HANDLE session;
    *owner = PR_TRUE;
    if (!slot->isThreadSafe)
        PK11_EnterSlotMonitor(slot);
    if (PK11_GETTAB(slot)->C_OpenSession(slot->slotID, CKF_SERIAL_SESSION,
                                         slot, pk11_notify, &session) != CKR_OK) {
        *owner = PR_FALSE;
        session = slot->session;
    }
    if (!slot->isThreadSafe)
        PK11_ExitSlotMonitor(slot);

    return session;
}

void
pk11_CloseSession(PK11SlotInfo *slot, CK_SESSION_HANDLE session, PRBool owner)
{
    if (!owner)
        return;
    if (!slot->isThreadSafe)
        PK11_EnterSlotMonitor(slot);
    (void)PK11_GETTAB(slot)->C_CloseSession(session);
    if (!slot->isThreadSafe)
        PK11_ExitSlotMonitor(slot);
}

SECStatus
PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
                     const CK_ATTRIBUTE *theTemplate, int count,
                     PRBool token, CK_OBJECT_HANDLE *objectID)
{
    CK_SESSION_HANDLE rwsession;
    CK_RV crv;
    SECStatus rv = SECSuccess;

    rwsession = session;
    if (token) {
        rwsession = PK11_GetRWSession(slot);
    } else if (rwsession == CK_INVALID_HANDLE) {
        rwsession = slot->session;
        if (rwsession != CK_INVALID_HANDLE)
            PK11_EnterSlotMonitor(slot);
    }
    if (rwsession == CK_INVALID_HANDLE) {
        PORT_SetError(SEC_ERROR_BAD_DATA);
        return SECFailure;
    }
    crv = PK11_GETTAB(slot)->C_CreateObject(rwsession,
                                            /* cast away const :-( */ (CK_ATTRIBUTE_PTR)theTemplate,
                                            count, objectID);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        rv = SECFailure;
    }
    if (token) {
        PK11_RestoreROSession(slot, rwsession);
    } else if (session == CK_INVALID_HANDLE) {
        PK11_ExitSlotMonitor(slot);
    }

    return rv;
}

/* This function may add a maximum of 9 attributes. */
unsigned int
pk11_OpFlagsToAttributes(CK_FLAGS flags, CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue)
{

    const static CK_ATTRIBUTE_TYPE attrTypes[12] = {
        CKA_ENCRYPT, CKA_DECRYPT, 0 /* DIGEST */, CKA_SIGN,
        CKA_SIGN_RECOVER, CKA_VERIFY, CKA_VERIFY_RECOVER, 0 /* GEN */,
        0 /* GEN PAIR */, CKA_WRAP, CKA_UNWRAP, CKA_DERIVE
    };

    const CK_ATTRIBUTE_TYPE *pType = attrTypes;
    CK_ATTRIBUTE *attr = attrs;
    CK_FLAGS test = CKF_ENCRYPT;

    PR_ASSERT(!(flags & ~CKF_KEY_OPERATION_FLAGS));
    flags &= CKF_KEY_OPERATION_FLAGS;

    for (; flags && test <= CKF_DERIVE; test <<= 1, ++pType) {
        if (test & flags) {
            flags ^= test;
            PR_ASSERT(*pType);
            PK11_SETATTRS(attr, *pType, ckTrue, sizeof *ckTrue);
            ++attr;
        }
    }
    return (attr - attrs);
}

/*
 * Check for conflicting flags, for example, if both PK11_ATTR_PRIVATE
 * and PK11_ATTR_PUBLIC are set.
 */
PRBool
pk11_BadAttrFlags(PK11AttrFlags attrFlags)
{
    PK11AttrFlags trueFlags = attrFlags & 0x55555555;
    PK11AttrFlags falseFlags = (attrFlags >> 1) & 0x55555555;
    return ((trueFlags & falseFlags) != 0);
}

/*
 * This function may add a maximum of 5 attributes.
 * The caller must make sure the attribute flags don't have conflicts.
 */
unsigned int
pk11_AttrFlagsToAttributes(PK11AttrFlags attrFlags, CK_ATTRIBUTE *attrs,
                           CK_BBOOL *ckTrue, CK_BBOOL *ckFalse)
{
    const static CK_ATTRIBUTE_TYPE attrTypes[5] = {
        CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_SENSITIVE,
        CKA_EXTRACTABLE
    };

    const CK_ATTRIBUTE_TYPE *pType = attrTypes;
    CK_ATTRIBUTE *attr = attrs;
    PK11AttrFlags test = PK11_ATTR_TOKEN;

    PR_ASSERT(!pk11_BadAttrFlags(attrFlags));

    /* we test two related bitflags in each iteration */
    for (; attrFlags && test <= PK11_ATTR_EXTRACTABLE; test <<= 2, ++pType) {
        if (test & attrFlags) {
            attrFlags ^= test;
            PK11_SETATTRS(attr, *pType, ckTrue, sizeof *ckTrue);
            ++attr;
        } else if ((test << 1) & attrFlags) {
            attrFlags ^= (test << 1);
            PK11_SETATTRS(attr, *pType, ckFalse, sizeof *ckFalse);
            ++attr;
        }
    }
    return (attr - attrs);
}

/*
 * Some non-compliant PKCS #11 vendors do not give us the modulus, so actually
 * set up a signature to get the signaure length.
 */
static int
pk11_backupGetSignLength(SECKEYPrivateKey *key)
{
    PK11SlotInfo *slot = key->pkcs11Slot;
    CK_MECHANISM mech = { 0, NULL, 0 };
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;
    CK_ULONG len;
    CK_RV crv;
    unsigned char h_data[20] = { 0 };
    unsigned char buf[20]; /* obviously to small */
    CK_ULONG smallLen = sizeof(buf);

    mech.mechanism = PK11_MapSignKeyType(key->keyType);

    session = pk11_GetNewSession(slot, &owner);
    if (!owner || !(slot->isThreadSafe))
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_SignInit(session, &mech, key->pkcs11ID);
    if (crv != CKR_OK) {
        if (!owner || !(slot->isThreadSafe))
            PK11_ExitSlotMonitor(slot);
        pk11_CloseSession(slot, session, owner);
        PORT_SetError(PK11_MapError(crv));
        return -1;
    }
    len = 0;
    crv = PK11_GETTAB(slot)->C_Sign(session, h_data, sizeof(h_data),
                                    NULL, &len);
    /* now call C_Sign with too small a buffer to clear the session state */
    (void)PK11_GETTAB(slot)->C_Sign(session, h_data, sizeof(h_data), buf, &smallLen);

    if (!owner || !(slot->isThreadSafe))
        PK11_ExitSlotMonitor(slot);
    pk11_CloseSession(slot, session, owner);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return -1;
    }
    return len;
}

/*
 * get the length of a signature object based on the key
 */
int
PK11_SignatureLen(SECKEYPrivateKey *key)
{
    int val;
    SECItem attributeItem = { siBuffer, NULL, 0 };
    SECStatus rv;
    int length;

    switch (key->keyType) {
        case rsaKey:
            val = PK11_GetPrivateModulusLen(key);
            if (val == -1) {
                return pk11_backupGetSignLength(key);
            }
            return (unsigned long)val;

        case fortezzaKey:
            return 40;

        case dsaKey:
            rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, CKA_SUBPRIME,
                                    NULL, &attributeItem);
            if (rv == SECSuccess) {
                length = attributeItem.len;
                if ((length > 0) && attributeItem.data[0] == 0) {
                    length--;
                }
                PORT_Free(attributeItem.data);
                return length * 2;
            }
            return pk11_backupGetSignLength(key);

        case ecKey:
            rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, CKA_EC_PARAMS,
                                    NULL, &attributeItem);
            if (rv == SECSuccess) {
                length = SECKEY_ECParamsToBasePointOrderLen(&attributeItem);
                PORT_Free(attributeItem.data);
                if (length != 0) {
                    length = ((length + 7) / 8) * 2;
                    return length;
                }
            }
            return pk11_backupGetSignLength(key);
        default:
            break;
    }
    PORT_SetError(SEC_ERROR_INVALID_KEY);
    return 0;
}

/*
 * copy a key (or any other object) on a token
 */
CK_OBJECT_HANDLE
PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject)
{
    CK_OBJECT_HANDLE destObject;
    CK_RV crv;

    PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_CopyObject(slot->session, srcObject, NULL, 0,
                                          &destObject);
    PK11_ExitSlotMonitor(slot);
    if (crv == CKR_OK)
        return destObject;
    PORT_SetError(PK11_MapError(crv));
    return CK_INVALID_HANDLE;
}

PRBool
pk11_FindAttrInTemplate(CK_ATTRIBUTE *attr, unsigned int numAttrs,
                        CK_ATTRIBUTE_TYPE target)
{
    for (; numAttrs > 0; ++attr, --numAttrs) {
        if (attr->type == target)
            return PR_TRUE;
    }
    return PR_FALSE;
}

/*
 * Recover the Signed data. We need this because our old verify can't
 * figure out which hash algorithm to use until we decryptted this.
 */
SECStatus
PK11_VerifyRecover(SECKEYPublicKey *key, const SECItem *sig,
                   SECItem *dsig, void *wincx)
{
    PK11SlotInfo *slot = key->pkcs11Slot;
    CK_OBJECT_HANDLE id = key->pkcs11ID;
    CK_MECHANISM mech = { 0, NULL, 0 };
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;
    CK_ULONG len;
    CK_RV crv;

    mech.mechanism = PK11_MapSignKeyType(key->keyType);

    if (slot == NULL) {
        slot = PK11_GetBestSlotWithAttributes(mech.mechanism,
                                              CKF_VERIFY_RECOVER, 0, wincx);
        if (slot == NULL) {
            PORT_SetError(SEC_ERROR_NO_MODULE);
            return SECFailure;
        }
        id = PK11_ImportPublicKey(slot, key, PR_FALSE);
    } else {
        PK11_ReferenceSlot(slot);
    }

    if (id == CK_INVALID_HANDLE) {
        PK11_FreeSlot(slot);
        PORT_SetError(SEC_ERROR_BAD_KEY);
        return SECFailure;
    }

    session = pk11_GetNewSession(slot, &owner);
    if (!owner || !(slot->isThreadSafe))
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_VerifyRecoverInit(session, &mech, id);
    if (crv != CKR_OK) {
        if (!owner || !(slot->isThreadSafe))
            PK11_ExitSlotMonitor(slot);
        pk11_CloseSession(slot, session, owner);
        PORT_SetError(PK11_MapError(crv));
        PK11_FreeSlot(slot);
        return SECFailure;
    }
    len = dsig->len;
    crv = PK11_GETTAB(slot)->C_VerifyRecover(session, sig->data,
                                             sig->len, dsig->data, &len);
    if (!owner || !(slot->isThreadSafe))
        PK11_ExitSlotMonitor(slot);
    pk11_CloseSession(slot, session, owner);
    dsig->len = len;
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        PK11_FreeSlot(slot);
        return SECFailure;
    }
    PK11_FreeSlot(slot);
    return SECSuccess;
}

/*
 * verify a signature from its hash.
 */
SECStatus
PK11_Verify(SECKEYPublicKey *key, const SECItem *sig, const SECItem *hash,
            void *wincx)
{
    CK_MECHANISM_TYPE mech = PK11_MapSignKeyType(key->keyType);
    return PK11_VerifyWithMechanism(key, mech, NULL, sig, hash, wincx);
}

/*
 * Verify a signature from its hash using the given algorithm.
 */
SECStatus
PK11_VerifyWithMechanism(SECKEYPublicKey *key, CK_MECHANISM_TYPE mechanism,
                         const SECItem *param, const SECItem *sig,
                         const SECItem *hash, void *wincx)
{
    PK11SlotInfo *slot = key->pkcs11Slot;
    CK_OBJECT_HANDLE id = key->pkcs11ID;
    CK_MECHANISM mech = { 0, NULL, 0 };
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;
    CK_RV crv;

    mech.mechanism = mechanism;
    if (param) {
        mech.pParameter = param->data;
        mech.ulParameterLen = param->len;
    }

    if (slot == NULL) {
        unsigned int length = 0;
        if ((mech.mechanism == CKM_DSA) &&
            /* 129 is 1024 bits translated to bytes and
             * padded with an optional '0' to maintain a
             * positive sign */
            (key->u.dsa.params.prime.len > 129)) {
            /* we need to get a slot that not only can do DSA, but can do DSA2
             * key lengths */
            length = key->u.dsa.params.prime.len;
            if (key->u.dsa.params.prime.data[0] == 0) {
                length--;
            }
            /* convert keysize to bits for slot lookup */
            length *= 8;
        }
        slot = PK11_GetBestSlotWithAttributes(mech.mechanism,
                                              CKF_VERIFY, length, wincx);
        if (slot == NULL) {
            PORT_SetError(SEC_ERROR_NO_MODULE);
            return SECFailure;
        }
        id = PK11_ImportPublicKey(slot, key, PR_FALSE);

    } else {
        PK11_ReferenceSlot(slot);
    }

    if (id == CK_INVALID_HANDLE) {
        PK11_FreeSlot(slot);
        PORT_SetError(SEC_ERROR_BAD_KEY);
        return SECFailure;
    }

    session = pk11_GetNewSession(slot, &owner);
    if (!owner || !(slot->isThreadSafe))
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_VerifyInit(session, &mech, id);
    if (crv != CKR_OK) {
        if (!owner || !(slot->isThreadSafe))
            PK11_ExitSlotMonitor(slot);
        pk11_CloseSession(slot, session, owner);
        PK11_FreeSlot(slot);
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    crv = PK11_GETTAB(slot)->C_Verify(session, hash->data,
                                      hash->len, sig->data, sig->len);
    if (!owner || !(slot->isThreadSafe))
        PK11_ExitSlotMonitor(slot);
    pk11_CloseSession(slot, session, owner);
    PK11_FreeSlot(slot);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    return SECSuccess;
}

/*
 * sign a hash. The algorithm is determined by the key.
 */
SECStatus
PK11_Sign(SECKEYPrivateKey *key, SECItem *sig, const SECItem *hash)
{
    CK_MECHANISM_TYPE mech = PK11_MapSignKeyType(key->keyType);
    return PK11_SignWithMechanism(key, mech, NULL, sig, hash);
}

/*
 * Sign a hash using the given algorithm.
 */
SECStatus
PK11_SignWithMechanism(SECKEYPrivateKey *key, CK_MECHANISM_TYPE mechanism,
                       const SECItem *param, SECItem *sig, const SECItem *hash)
{
    PK11SlotInfo *slot = key->pkcs11Slot;
    CK_MECHANISM mech = { 0, NULL, 0 };
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;
    PRBool haslock = PR_FALSE;
    CK_ULONG len;
    CK_RV crv;

    mech.mechanism = mechanism;
    if (param) {
        mech.pParameter = param->data;
        mech.ulParameterLen = param->len;
    }

    if (SECKEY_HAS_ATTRIBUTE_SET(key, CKA_PRIVATE)) {
        PK11_HandlePasswordCheck(slot, key->wincx);
    }

    session = pk11_GetNewSession(slot, &owner);
    haslock = (!owner || !(slot->isThreadSafe));
    if (haslock)
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_SignInit(session, &mech, key->pkcs11ID);
    if (crv != CKR_OK) {
        if (haslock)
            PK11_ExitSlotMonitor(slot);
        pk11_CloseSession(slot, session, owner);
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }

    /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then
     * do C_Login with CKU_CONTEXT_SPECIFIC
     * between C_SignInit and C_Sign */
    if (SECKEY_HAS_ATTRIBUTE_SET_LOCK(key, CKA_ALWAYS_AUTHENTICATE, haslock)) {
        PK11_DoPassword(slot, session, PR_FALSE, key->wincx, haslock, PR_TRUE);
    }

    len = sig->len;
    crv = PK11_GETTAB(slot)->C_Sign(session, hash->data,
                                    hash->len, sig->data, &len);
    if (haslock)
        PK11_ExitSlotMonitor(slot);
    pk11_CloseSession(slot, session, owner);
    sig->len = len;
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    return SECSuccess;
}

/*
 * sign data with a MAC key.
 */
SECStatus
PK11_SignWithSymKey(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism,
                    SECItem *param, SECItem *sig, const SECItem *data)
{
    PK11SlotInfo *slot = symKey->slot;
    CK_MECHANISM mech = { 0, NULL, 0 };
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;
    PRBool haslock = PR_FALSE;
    CK_ULONG len;
    CK_RV crv;

    mech.mechanism = mechanism;
    if (param) {
        mech.pParameter = param->data;
        mech.ulParameterLen = param->len;
    }

    session = pk11_GetNewSession(slot, &owner);
    haslock = (!owner || !(slot->isThreadSafe));
    if (haslock)
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_SignInit(session, &mech, symKey->objectID);
    if (crv != CKR_OK) {
        if (haslock)
            PK11_ExitSlotMonitor(slot);
        pk11_CloseSession(slot, session, owner);
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }

    len = sig->len;
    crv = PK11_GETTAB(slot)->C_Sign(session, data->data,
                                    data->len, sig->data, &len);
    if (haslock)
        PK11_ExitSlotMonitor(slot);
    pk11_CloseSession(slot, session, owner);
    sig->len = len;
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    return SECSuccess;
}

SECStatus
PK11_Decrypt(PK11SymKey *symKey,
             CK_MECHANISM_TYPE mechanism, SECItem *param,
             unsigned char *out, unsigned int *outLen,
             unsigned int maxLen,
             const unsigned char *enc, unsigned encLen)
{
    PK11SlotInfo *slot = symKey->slot;
    CK_MECHANISM mech = { 0, NULL, 0 };
    CK_ULONG len = maxLen;
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;
    PRBool haslock = PR_FALSE;
    CK_RV crv;

    mech.mechanism = mechanism;
    if (param) {
        mech.pParameter = param->data;
        mech.ulParameterLen = param->len;
    }

    session = pk11_GetNewSession(slot, &owner);
    haslock = (!owner || !slot->isThreadSafe);
    if (haslock)
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_DecryptInit(session, &mech, symKey->objectID);
    if (crv != CKR_OK) {
        if (haslock)
            PK11_ExitSlotMonitor(slot);
        pk11_CloseSession(slot, session, owner);
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }

    crv = PK11_GETTAB(slot)->C_Decrypt(session, (unsigned char *)enc, encLen,
                                       out, &len);
    if (haslock)
        PK11_ExitSlotMonitor(slot);
    pk11_CloseSession(slot, session, owner);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    *outLen = len;
    return SECSuccess;
}

SECStatus
PK11_Encrypt(PK11SymKey *symKey,
             CK_MECHANISM_TYPE mechanism, SECItem *param,
             unsigned char *out, unsigned int *outLen,
             unsigned int maxLen,
             const unsigned char *data, unsigned int dataLen)
{
    PK11SlotInfo *slot = symKey->slot;
    CK_MECHANISM mech = { 0, NULL, 0 };
    CK_ULONG len = maxLen;
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;
    PRBool haslock = PR_FALSE;
    CK_RV crv;

    mech.mechanism = mechanism;
    if (param) {
        mech.pParameter = param->data;
        mech.ulParameterLen = param->len;
    }

    session = pk11_GetNewSession(slot, &owner);
    haslock = (!owner || !slot->isThreadSafe);
    if (haslock)
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_EncryptInit(session, &mech, symKey->objectID);
    if (crv != CKR_OK) {
        if (haslock)
            PK11_ExitSlotMonitor(slot);
        pk11_CloseSession(slot, session, owner);
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    crv = PK11_GETTAB(slot)->C_Encrypt(session, (unsigned char *)data,
                                       dataLen, out, &len);
    if (haslock)
        PK11_ExitSlotMonitor(slot);
    pk11_CloseSession(slot, session, owner);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    *outLen = len;
    return SECSuccess;
}

static SECStatus
pk11_PrivDecryptRaw(SECKEYPrivateKey *key,
                    unsigned char *data, unsigned *outLen, unsigned int maxLen,
                    const unsigned char *enc, unsigned encLen,
                    CK_MECHANISM_PTR mech)
{
    PK11SlotInfo *slot = key->pkcs11Slot;
    CK_ULONG out = maxLen;
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;
    PRBool haslock = PR_FALSE;
    CK_RV crv;

    if (key->keyType != rsaKey) {
        PORT_SetError(SEC_ERROR_INVALID_KEY);
        return SECFailure;
    }

    /* Why do we do a PK11_handle check here? for simple
     * decryption? .. because the user may have asked for 'ask always'
     * and this is a private key operation. In practice, thought, it's mute
     * since only servers wind up using this function */
    if (SECKEY_HAS_ATTRIBUTE_SET(key, CKA_PRIVATE)) {
        PK11_HandlePasswordCheck(slot, key->wincx);
    }
    session = pk11_GetNewSession(slot, &owner);
    haslock = (!owner || !(slot->isThreadSafe));
    if (haslock)
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_DecryptInit(session, mech, key->pkcs11ID);
    if (crv != CKR_OK) {
        if (haslock)
            PK11_ExitSlotMonitor(slot);
        pk11_CloseSession(slot, session, owner);
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }

    /* PKCS11 2.20 says if CKA_ALWAYS_AUTHENTICATE then
     * do C_Login with CKU_CONTEXT_SPECIFIC
     * between C_DecryptInit and C_Decrypt
     * ... But see note above about servers */
    if (SECKEY_HAS_ATTRIBUTE_SET_LOCK(key, CKA_ALWAYS_AUTHENTICATE, haslock)) {
        PK11_DoPassword(slot, session, PR_FALSE, key->wincx, haslock, PR_TRUE);
    }

    crv = PK11_GETTAB(slot)->C_Decrypt(session, (unsigned char *)enc, encLen,
                                       data, &out);
    if (haslock)
        PK11_ExitSlotMonitor(slot);
    pk11_CloseSession(slot, session, owner);
    *outLen = out;
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    return SECSuccess;
}

SECStatus
PK11_PubDecryptRaw(SECKEYPrivateKey *key,
                   unsigned char *data, unsigned *outLen, unsigned int maxLen,
                   const unsigned char *enc, unsigned encLen)
{
    CK_MECHANISM mech = { CKM_RSA_X_509, NULL, 0 };
    return pk11_PrivDecryptRaw(key, data, outLen, maxLen, enc, encLen, &mech);
}

SECStatus
PK11_PrivDecryptPKCS1(SECKEYPrivateKey *key,
                      unsigned char *data, unsigned *outLen, unsigned int maxLen,
                      const unsigned char *enc, unsigned encLen)
{
    CK_MECHANISM mech = { CKM_RSA_PKCS, NULL, 0 };
    return pk11_PrivDecryptRaw(key, data, outLen, maxLen, enc, encLen, &mech);
}

static SECStatus
pk11_PubEncryptRaw(SECKEYPublicKey *key,
                   unsigned char *out, unsigned int *outLen,
                   unsigned int maxLen,
                   const unsigned char *data, unsigned dataLen,
                   CK_MECHANISM_PTR mech, void *wincx)
{
    PK11SlotInfo *slot;
    CK_OBJECT_HANDLE id;
    CK_ULONG len = maxLen;
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;
    CK_RV crv;

    slot = PK11_GetBestSlotWithAttributes(mech->mechanism, CKF_ENCRYPT, 0, wincx);
    if (slot == NULL) {
        PORT_SetError(SEC_ERROR_NO_MODULE);
        return SECFailure;
    }

    id = PK11_ImportPublicKey(slot, key, PR_FALSE);

    if (id == CK_INVALID_HANDLE) {
        PK11_FreeSlot(slot);
        PORT_SetError(SEC_ERROR_BAD_KEY);
        return SECFailure;
    }

    session = pk11_GetNewSession(slot, &owner);
    if (!owner || !(slot->isThreadSafe))
        PK11_EnterSlotMonitor(slot);
    crv = PK11_GETTAB(slot)->C_EncryptInit(session, mech, id);
    if (crv != CKR_OK) {
        if (!owner || !(slot->isThreadSafe))
            PK11_ExitSlotMonitor(slot);
        pk11_CloseSession(slot, session, owner);
        PK11_FreeSlot(slot);
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    crv = PK11_GETTAB(slot)->C_Encrypt(session, (unsigned char *)data, dataLen,
                                       out, &len);
    if (!owner || !(slot->isThreadSafe))
        PK11_ExitSlotMonitor(slot);
    pk11_CloseSession(slot, session, owner);
    PK11_FreeSlot(slot);
    *outLen = len;
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    return SECSuccess;
}

SECStatus
PK11_PubEncryptRaw(SECKEYPublicKey *key,
                   unsigned char *enc,
                   const unsigned char *data, unsigned dataLen,
                   void *wincx)
{
    CK_MECHANISM mech = { CKM_RSA_X_509, NULL, 0 };
    unsigned int outLen;
    if (!key || key->keyType != rsaKey) {
        PORT_SetError(SEC_ERROR_BAD_KEY);
        return SECFailure;
    }
    outLen = SECKEY_PublicKeyStrength(key);
    return pk11_PubEncryptRaw(key, enc, &outLen, outLen, data, dataLen, &mech,
                              wincx);
}

SECStatus
PK11_PubEncryptPKCS1(SECKEYPublicKey *key,
                     unsigned char *enc,
                     const unsigned char *data, unsigned dataLen,
                     void *wincx)
{
    CK_MECHANISM mech = { CKM_RSA_PKCS, NULL, 0 };
    unsigned int outLen;
    if (!key || key->keyType != rsaKey) {
        PORT_SetError(SEC_ERROR_BAD_KEY);
        return SECFailure;
    }
    outLen = SECKEY_PublicKeyStrength(key);
    return pk11_PubEncryptRaw(key, enc, &outLen, outLen, data, dataLen, &mech,
                              wincx);
}

SECStatus
PK11_PrivDecrypt(SECKEYPrivateKey *key,
                 CK_MECHANISM_TYPE mechanism, SECItem *param,
                 unsigned char *out, unsigned int *outLen,
                 unsigned int maxLen,
                 const unsigned char *enc, unsigned encLen)
{
    CK_MECHANISM mech = { mechanism, NULL, 0 };
    if (param) {
        mech.pParameter = param->data;
        mech.ulParameterLen = param->len;
    }
    return pk11_PrivDecryptRaw(key, out, outLen, maxLen, enc, encLen, &mech);
}

SECStatus
PK11_PubEncrypt(SECKEYPublicKey *key,
                CK_MECHANISM_TYPE mechanism, SECItem *param,
                unsigned char *out, unsigned int *outLen,
                unsigned int maxLen,
                const unsigned char *data, unsigned dataLen,
                void *wincx)
{
    CK_MECHANISM mech = { mechanism, NULL, 0 };
    if (param) {
        mech.pParameter = param->data;
        mech.ulParameterLen = param->len;
    }
    return pk11_PubEncryptRaw(key, out, outLen, maxLen, data, dataLen, &mech,
                              wincx);
}

SECKEYPrivateKey *
PK11_UnwrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
                   CK_MECHANISM_TYPE wrapType, SECItem *param,
                   SECItem *wrappedKey, SECItem *label,
                   SECItem *idValue, PRBool perm, PRBool sensitive,
                   CK_KEY_TYPE keyType, CK_ATTRIBUTE_TYPE *usage,
                   int usageCount, void *wincx)
{
    CK_BBOOL cktrue = CK_TRUE;
    CK_BBOOL ckfalse = CK_FALSE;
    CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
    CK_ATTRIBUTE keyTemplate[15];
    int templateCount = 0;
    CK_OBJECT_HANDLE privKeyID;
    CK_MECHANISM mechanism;
    CK_ATTRIBUTE *attrs = keyTemplate;
    SECItem *param_free = NULL, *ck_id = NULL;
    CK_RV crv;
    CK_SESSION_HANDLE rwsession;
    PK11SymKey *newKey = NULL;
    int i;

    if (!slot || !wrappedKey || !idValue) {
        /* SET AN ERROR!!! */
        return NULL;
    }

    ck_id = PK11_MakeIDFromPubKey(idValue);
    if (!ck_id) {
        return NULL;
    }

    PK11_SETATTRS(attrs, CKA_TOKEN, perm ? &cktrue : &ckfalse,
                  sizeof(cktrue));
    attrs++;
    PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
    attrs++;
    PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
    attrs++;
    PK11_SETATTRS(attrs, CKA_PRIVATE, sensitive ? &cktrue : &ckfalse,
                  sizeof(cktrue));
    attrs++;
    PK11_SETATTRS(attrs, CKA_SENSITIVE, sensitive ? &cktrue : &ckfalse,
                  sizeof(cktrue));
    attrs++;
    if (label && label->data) {
        PK11_SETATTRS(attrs, CKA_LABEL, label->data, label->len);
        attrs++;
    }
    PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
    attrs++;
    for (i = 0; i < usageCount; i++) {
        PK11_SETATTRS(attrs, usage[i], &cktrue, sizeof(cktrue));
        attrs++;
    }

    if (PK11_IsInternal(slot)) {
        PK11_SETATTRS(attrs, CKA_NSS_DB, idValue->data,
                      idValue->len);
        attrs++;
    }

    templateCount = attrs - keyTemplate;
    PR_ASSERT(templateCount <= (sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE)));

    mechanism.mechanism = wrapType;
    if (!param)
        param = param_free = PK11_ParamFromIV(wrapType, NULL);
    if (param) {
        mechanism.pParameter = param->data;
        mechanism.ulParameterLen = param->len;
    } else {
        mechanism.pParameter = NULL;
        mechanism.ulParameterLen = 0;
    }

    if (wrappingKey->slot != slot) {
        newKey = pk11_CopyToSlot(slot, wrapType, CKA_UNWRAP, wrappingKey);
    } else {
        newKey = PK11_ReferenceSymKey(wrappingKey);
    }

    if (newKey) {
        if (perm) {
            /* Get RW Session will either lock the monitor if necessary,
             *  or return a thread safe session handle, or fail. */
            rwsession = PK11_GetRWSession(slot);
        } else {
            rwsession = slot->session;
            if (rwsession != CK_INVALID_HANDLE)
                PK11_EnterSlotMonitor(slot);
        }
        /* This is a lot a work to deal with fussy PKCS #11 modules
         * that can't bother to return BAD_DATA when presented with an
         * invalid session! */
        if (rwsession == CK_INVALID_HANDLE) {
            PORT_SetError(SEC_ERROR_BAD_DATA);
            goto loser;
        }
        crv = PK11_GETTAB(slot)->C_UnwrapKey(rwsession, &mechanism,
                                             newKey->objectID,
                                             wrappedKey->data,
                                             wrappedKey->len, keyTemplate,
                                             templateCount, &privKeyID);

        if (perm) {
            PK11_RestoreROSession(slot, rwsession);
        } else {
            PK11_ExitSlotMonitor(slot);
        }
        PK11_FreeSymKey(newKey);
        newKey = NULL;
    } else {
        crv = CKR_FUNCTION_NOT_SUPPORTED;
    }

    SECITEM_FreeItem(ck_id, PR_TRUE);
    ck_id = NULL;

    if (crv != CKR_OK) {
        /* we couldn't unwrap the key, use the internal module to do the
         * unwrap, then load the new key into the token */
        PK11SlotInfo *int_slot = PK11_GetInternalSlot();

        if (int_slot && (slot != int_slot)) {
            SECKEYPrivateKey *privKey = PK11_UnwrapPrivKey(int_slot,
                                                           wrappingKey, wrapType, param, wrappedKey, label,
                                                           idValue, PR_FALSE, PR_FALSE,
                                                           keyType, usage, usageCount, wincx);
            if (privKey) {
                SECKEYPrivateKey *newPrivKey = PK11_LoadPrivKey(slot, privKey,
                                                                NULL, perm, sensitive);
                SECKEY_DestroyPrivateKey(privKey);
                PK11_FreeSlot(int_slot);
                SECITEM_FreeItem(param_free, PR_TRUE);
                return newPrivKey;
            }
        }
        if (int_slot)
            PK11_FreeSlot(int_slot);
        PORT_SetError(PK11_MapError(crv));
        SECITEM_FreeItem(param_free, PR_TRUE);
        return NULL;
    }
    SECITEM_FreeItem(param_free, PR_TRUE);
    return PK11_MakePrivKey(slot, nullKey, PR_FALSE, privKeyID, wincx);

loser:
    PK11_FreeSymKey(newKey);
    SECITEM_FreeItem(ck_id, PR_TRUE);
    SECITEM_FreeItem(param_free, PR_TRUE);
    return NULL;
}

/*
 * Now we're going to wrap a SECKEYPrivateKey with a PK11SymKey
 * The strategy is to get both keys to reside in the same slot,
 * one that can perform the desired crypto mechanism and then
 * call C_WrapKey after all the setup has taken place.
 */
SECStatus
PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
                 SECKEYPrivateKey *privKey, CK_MECHANISM_TYPE wrapType,
                 SECItem *param, SECItem *wrappedKey, void *wincx)
{
    PK11SlotInfo *privSlot = privKey->pkcs11Slot; /* The slot where
                                                   * the private key
                                                   * we are going to
                                                   * wrap lives.
                                                   */
    PK11SymKey *newSymKey = NULL;
    SECKEYPrivateKey *newPrivKey = NULL;
    SECItem *param_free = NULL;
    CK_ULONG len = wrappedKey->len;
    CK_MECHANISM mech;
    CK_RV crv;

    if (!privSlot || !PK11_DoesMechanism(privSlot, wrapType)) {
        /* Figure out a slot that does the mechanism and try to import
         * the private key onto that slot.
         */
        PK11SlotInfo *int_slot = PK11_GetInternalSlot();

        privSlot = int_slot; /* The private key has a new home */
        newPrivKey = PK11_LoadPrivKey(privSlot, privKey, NULL, PR_FALSE, PR_FALSE);
        /* newPrivKey has allocated its own reference to the slot, so it's
         * safe until we destroy newPrivkey.
         */
        PK11_FreeSlot(int_slot);
        if (newPrivKey == NULL) {
            return SECFailure;
        }
        privKey = newPrivKey;
    }

    if (privSlot != wrappingKey->slot) {
        newSymKey = pk11_CopyToSlot(privSlot, wrapType, CKA_WRAP,
                                    wrappingKey);
        wrappingKey = newSymKey;
    }

    if (wrappingKey == NULL) {
        if (newPrivKey) {
            SECKEY_DestroyPrivateKey(newPrivKey);
        }
        return SECFailure;
    }
    mech.mechanism = wrapType;
    if (!param) {
        param = param_free = PK11_ParamFromIV(wrapType, NULL);
    }
    if (param) {
        mech.pParameter = param->data;
        mech.ulParameterLen = param->len;
    } else {
        mech.pParameter = NULL;
        mech.ulParameterLen = 0;
    }

    PK11_EnterSlotMonitor(privSlot);
    crv = PK11_GETTAB(privSlot)->C_WrapKey(privSlot->session, &mech,
                                           wrappingKey->objectID,
                                           privKey->pkcs11ID,
                                           wrappedKey->data, &len);
    PK11_ExitSlotMonitor(privSlot);

    if (newSymKey) {
        PK11_FreeSymKey(newSymKey);
    }
    if (newPrivKey) {
        SECKEY_DestroyPrivateKey(newPrivKey);
    }
    if (param_free) {
        SECITEM_FreeItem(param_free, PR_TRUE);
    }

    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }

    wrappedKey->len = len;
    return SECSuccess;
}

#if 0
/*
 * Sample code relating to linked list returned by PK11_FindGenericObjects
 */

/*
 * You can walk the list with the following code:
 */
    firstObj = PK11_FindGenericObjects(slot, objClass);
    for (thisObj=firstObj;
         thisObj;
         thisObj=PK11_GetNextGenericObject(thisObj)) {
        /* operate on thisObj */
    }
/*
 * If you want a particular object from the list...
 */
    firstObj = PK11_FindGenericObjects(slot, objClass);
    for (thisObj=firstObj;
         thisObj;
         thisObj=PK11_GetNextGenericObject(thisObj)) {
      if (isMyObj(thisObj)) {
       if ( thisObj == firstObj) {
                /* NOTE: firstObj could be NULL at this point */
      firstObj = PK11_GetNextGenericObject(thsObj);
       }
       PK11_UnlinkGenericObject(thisObj);
            myObj = thisObj;
            break;
        }
    }

    PK11_DestroyGenericObjects(firstObj);

      /* use myObj */

    PK11_DestroyGenericObject(myObj);
#endif /* sample code */

/*
 * return a linked, non-circular list of generic objects.
 * If you are only interested
 * in one object, just use the first object in the list. To find the
 * rest of the list use PK11_GetNextGenericObject() to return the next object.
 */
PK11GenericObject *
PK11_FindGenericObjects(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass)
{
    CK_ATTRIBUTE template[1];
    CK_ATTRIBUTE *attrs = template;
    CK_OBJECT_HANDLE *objectIDs = NULL;
    PK11GenericObject *lastObj = NULL, *obj;
    PK11GenericObject *firstObj = NULL;
    int i, count = 0;

    PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass));
    attrs++;

    objectIDs = pk11_FindObjectsByTemplate(slot, template, 1, &count);
    if (objectIDs == NULL) {
        return NULL;
    }

    /* where we connect our object once we've created it.. */
    for (i = 0; i < count; i++) {
        obj = PORT_New(PK11GenericObject);
        if (!obj) {
            if (firstObj) {
                PK11_DestroyGenericObjects(firstObj);
            }
            PORT_Free(objectIDs);
            return NULL;
        }
        /* initialize it */
        obj->slot = PK11_ReferenceSlot(slot);
        obj->objectID = objectIDs[i];
        obj->owner = PR_FALSE;
        obj->next = NULL;
        obj->prev = NULL;

        /* link it in */
        if (firstObj == NULL) {
            firstObj = obj;
        } else {
            PK11_LinkGenericObject(lastObj, obj);
        }
        lastObj = obj;
    }
    PORT_Free(objectIDs);
    return firstObj;
}

/*
 * get the Next Object in the list.
 */
PK11GenericObject *
PK11_GetNextGenericObject(PK11GenericObject *object)
{
    return object->next;
}

PK11GenericObject *
PK11_GetPrevGenericObject(PK11GenericObject *object)
{
    return object->prev;
}

/*
 * Link a single object into a new list.
 * if the object is already in another list, remove it first.
 */
SECStatus
PK11_LinkGenericObject(PK11GenericObject *list, PK11GenericObject *object)
{
    PK11_UnlinkGenericObject(object);
    object->prev = list;
    object->next = list->next;
    list->next = object;
    if (object->next != NULL) {
        object->next->prev = object;
    }
    return SECSuccess;
}

/*
 * remove an object from the list. If the object isn't already in
 * a list unlink becomes a noop.
 */
SECStatus
PK11_UnlinkGenericObject(PK11GenericObject *object)
{
    if (object->prev != NULL) {
        object->prev->next = object->next;
    }
    if (object->next != NULL) {
        object->next->prev = object->prev;
    }

    object->next = NULL;
    object->prev = NULL;
    return SECSuccess;
}

/*
 * This function removes a single object from the list and destroys it.
 * For an already unlinked object there is no difference between
 * PK11_DestroyGenericObject and PK11_DestroyGenericObjects
 */
SECStatus
PK11_DestroyGenericObject(PK11GenericObject *object)
{
    if (object == NULL) {
        return SECSuccess;
    }

    PK11_UnlinkGenericObject(object);
    if (object->slot) {
        if (object->owner) {
            PK11_DestroyObject(object->slot, object->objectID);
        }
        PK11_FreeSlot(object->slot);
    }
    PORT_Free(object);
    return SECSuccess;
}

/*
 * walk down a link list of generic objects destroying them.
 * This will destroy all objects in a list that the object is linked into.
 * (the list is traversed in both directions).
 */
SECStatus
PK11_DestroyGenericObjects(PK11GenericObject *objects)
{
    PK11GenericObject *nextObject;
    PK11GenericObject *prevObject;

    if (objects == NULL) {
        return SECSuccess;
    }

    nextObject = objects->next;
    prevObject = objects->prev;

    /* delete all the objects after it in the list */
    for (; objects; objects = nextObject) {
        nextObject = objects->next;
        PK11_DestroyGenericObject(objects);
    }
    /* delete all the objects before it in the list */
    for (objects = prevObject; objects; objects = prevObject) {
        prevObject = objects->prev;
        PK11_DestroyGenericObject(objects);
    }
    return SECSuccess;
}

/*
 * Hand Create a new object and return the Generic object for our new object.
 */
PK11GenericObject *
pk11_CreateGenericObjectHelper(PK11SlotInfo *slot,
                               const CK_ATTRIBUTE *pTemplate,
                               int count, PRBool token, PRBool owner)
{
    CK_OBJECT_HANDLE objectID;
    PK11GenericObject *obj;
    CK_RV crv;

    PK11_EnterSlotMonitor(slot);
    crv = PK11_CreateNewObject(slot, slot->session, pTemplate, count,
                               token, &objectID);
    PK11_ExitSlotMonitor(slot);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return NULL;
    }

    obj = PORT_New(PK11GenericObject);
    if (!obj) {
        /* error set by PORT_New */
        return NULL;
    }

    /* initialize it */
    obj->slot = PK11_ReferenceSlot(slot);
    obj->objectID = objectID;
    obj->owner = owner;
    obj->next = NULL;
    obj->prev = NULL;
    return obj;
}

/* This is the classic interface. Applications would call this function to
 * create new object that would not be destroyed later. This lead to resource
 * leaks (and thus memory leaks in the PKCS #11 module).  To solve this we have
 * a new interface that automatically marks objects created on the fly to be
 * destroyed later.
 * The old interface is preserved because applications like Mozilla purposefully
 * leak the reference to be found later with PK11_FindGenericObjects. New
 * applications should use the new interface PK11_CreateManagedGenericObject */
PK11GenericObject *
PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate,
                         int count, PRBool token)
{
    return pk11_CreateGenericObjectHelper(slot, pTemplate, count, token,
                                          PR_FALSE);
}

/* Use this interface. It will automatically destroy any temporary objects
 * (token = PR_FALSE) when the PK11GenericObject is freed. Permanent objects still
 * need to be destroyed by hand with PK11_DestroyTokenObject.
 */
PK11GenericObject *
PK11_CreateManagedGenericObject(PK11SlotInfo *slot,
                                const CK_ATTRIBUTE *pTemplate, int count, PRBool token)
{
    return pk11_CreateGenericObjectHelper(slot, pTemplate, count, token,
                                          !token);
}

CK_OBJECT_HANDLE
PK11_GetObjectHandle(PK11ObjectType objType, void *objSpec,
                     PK11SlotInfo **slotp)
{
    CK_OBJECT_HANDLE handle = CK_INVALID_HANDLE;
    PK11SlotInfo *slot = NULL;

    switch (objType) {
        case PK11_TypeGeneric:
            slot = ((PK11GenericObject *)objSpec)->slot;
            handle = ((PK11GenericObject *)objSpec)->objectID;
            break;
        case PK11_TypePrivKey:
            slot = ((SECKEYPrivateKey *)objSpec)->pkcs11Slot;
            handle = ((SECKEYPrivateKey *)objSpec)->pkcs11ID;
            break;
        case PK11_TypePubKey:
            slot = ((SECKEYPublicKey *)objSpec)->pkcs11Slot;
            handle = ((SECKEYPublicKey *)objSpec)->pkcs11ID;
            break;
        case PK11_TypeSymKey:
            slot = ((PK11SymKey *)objSpec)->slot;
            handle = ((PK11SymKey *)objSpec)->objectID;
            break;
        case PK11_TypeCert: /* don't handle cert case for now */
        default:
            PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE);
            break;
    }
    if (slotp) {
        *slotp = slot;
    }
    /* paranoia. If the object doesn't have a slot, then it's handle isn't
     * valid either */
    if (slot == NULL) {
        handle = CK_INVALID_HANDLE;
    }
    return handle;
}

/*
 * Change an attribute on a raw object
 */
SECStatus
PK11_WriteRawAttribute(PK11ObjectType objType, void *objSpec,
                       CK_ATTRIBUTE_TYPE attrType, SECItem *item)
{
    PK11SlotInfo *slot = NULL;
    CK_OBJECT_HANDLE handle = 0;
    CK_ATTRIBUTE setTemplate;
    CK_RV crv;
    CK_SESSION_HANDLE rwsession;

    handle = PK11_GetObjectHandle(objType, objSpec, &slot);
    if (handle == CK_INVALID_HANDLE) {
        PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE);
        return SECFailure;
    }

    PK11_SETATTRS(&setTemplate, attrType, (CK_CHAR *)item->data, item->len);
    rwsession = PK11_GetRWSession(slot);
    if (rwsession == CK_INVALID_HANDLE) {
        PORT_SetError(SEC_ERROR_BAD_DATA);
        return SECFailure;
    }
    crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, handle,
                                                 &setTemplate, 1);
    PK11_RestoreROSession(slot, rwsession);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    return SECSuccess;
}

SECStatus
PK11_ReadRawAttribute(PK11ObjectType objType, void *objSpec,
                      CK_ATTRIBUTE_TYPE attrType, SECItem *item)
{
    PK11SlotInfo *slot = NULL;
    CK_OBJECT_HANDLE handle = 0;

    handle = PK11_GetObjectHandle(objType, objSpec, &slot);
    if (handle == CK_INVALID_HANDLE) {
        PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE);
        return SECFailure;
    }

    return PK11_ReadAttribute(slot, handle, attrType, NULL, item);
}

SECStatus
PK11_ReadRawAttributes(PLArenaPool *arena, PK11ObjectType objType, void *objSpec,
                       CK_ATTRIBUTE *pTemplate, unsigned int count)
{
    PK11SlotInfo *slot = NULL;
    CK_OBJECT_HANDLE handle = 0;

    handle = PK11_GetObjectHandle(objType, objSpec, &slot);
    if (handle == CK_INVALID_HANDLE) {
        PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE);
        return SECFailure;
    }
    CK_RV crv = PK11_GetAttributes(arena, slot, handle, pTemplate, count);
    if (crv != CKR_OK) {
        PORT_SetError(PK11_MapError(crv));
        return SECFailure;
    }
    return SECSuccess;
}

/*
 * return the object handle that matches the template
 */
CK_OBJECT_HANDLE
pk11_FindObjectByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *theTemplate, size_t tsize)
{
    CK_OBJECT_HANDLE object;
    CK_RV crv = CKR_SESSION_HANDLE_INVALID;
    CK_ULONG objectCount;

    /*
     * issue the find
     */
    PK11_EnterSlotMonitor(slot);
    if (slot->session != CK_INVALID_HANDLE) {
        crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session,
                                                   theTemplate, tsize);
    }
    if (crv != CKR_OK) {
        PK11_ExitSlotMonitor(slot);
        PORT_SetError(PK11_MapError(crv));
        return CK_INVALID_HANDLE;
    }

    crv = PK11_GETTAB(slot)->C_FindObjects(slot->session, &object, 1, &objectCount);
    PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session);
    PK11_ExitSlotMonitor(slot);
    if ((crv != CKR_OK) || (objectCount < 1)) {
        /* shouldn't use SSL_ERROR... here */
        PORT_SetError(crv != CKR_OK ? PK11_MapError(crv) : SSL_ERROR_NO_CERTIFICATE);
        return CK_INVALID_HANDLE;
    }

    /* blow up if the PKCS #11 module returns us and invalid object handle */
    PORT_Assert(object != CK_INVALID_HANDLE);
    return object;
}

/*
 * return all the object handles that matches the template
 */
CK_OBJECT_HANDLE *
pk11_FindObjectsByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
                           size_t templCount, int *object_count)
{
    CK_OBJECT_HANDLE *objID = NULL;
    CK_ULONG returned_count = 0;
    PRBool owner = PR_TRUE;
    CK_SESSION_HANDLE session;
    PRBool haslock = PR_FALSE;
    CK_RV crv = CKR_SESSION_HANDLE_INVALID;

    session = pk11_GetNewSession(slot, &owner);
    haslock = (!owner || !(slot->isThreadSafe));
    if (haslock) {
        PK11_EnterSlotMonitor(slot);
    }
    if (session != CK_INVALID_HANDLE) {
        crv = PK11_GETTAB(slot)->C_FindObjectsInit(session,
                                                   findTemplate, templCount);
    }
    if (crv != CKR_OK) {
        if (haslock)
            PK11_ExitSlotMonitor(slot);
        pk11_CloseSession(slot, session, owner);
        PORT_SetError(PK11_MapError(crv));
        *object_count = -1;
        return NULL;
    }

    /*
     * collect all the Matching Objects
     */
    do {
        CK_OBJECT_HANDLE *oldObjID = objID;

        if (objID == NULL) {
            objID = (CK_OBJECT_HANDLE *)PORT_Alloc(sizeof(CK_OBJECT_HANDLE) *
                                                   (*object_count + PK11_SEARCH_CHUNKSIZE));
        } else {
            objID = (CK_OBJECT_HANDLE *)PORT_Realloc(objID,
                                                     sizeof(CK_OBJECT_HANDLE) * (*object_count + PK11_SEARCH_CHUNKSIZE));
        }

        if (objID == NULL) {
            if (oldObjID)
                PORT_Free(oldObjID);
            break;
        }
        crv = PK11_GETTAB(slot)->C_FindObjects(session,
                                               &objID[*object_count], PK11_SEARCH_CHUNKSIZE, &returned_count);
        if (crv != CKR_OK) {
            PORT_SetError(PK11_MapError(crv));
            PORT_Free(objID);
            objID = NULL;
            break;
        }
        *object_count += returned_count;
    } while (returned_count == PK11_SEARCH_CHUNKSIZE);

    PK11_GETTAB(slot)->C_FindObjectsFinal(session);
    if (haslock) {
        PK11_ExitSlotMonitor(slot);
    }
    pk11_CloseSession(slot, session, owner);

    if (objID && (*object_count == 0)) {
        PORT_Free(objID);
        return NULL;
    }
    if (objID == NULL)
        *object_count = -1;
    return objID;
}

SECStatus
PK11_FindRawCertsWithSubject(PK11SlotInfo *slot, SECItem *derSubject,
                             CERTCertificateList **results)
{
    if (!slot || !derSubject || !results) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    *results = NULL;

    // derSubject->data may be null. If so, derSubject->len must be 0.
    if (!derSubject->data && derSubject->len != 0) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    CK_CERTIFICATE_TYPE ckc_x_509 = CKC_X_509;
    CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
    CK_ATTRIBUTE subjectTemplate[] = {
        { CKA_CERTIFICATE_TYPE, &ckc_x_509, sizeof(ckc_x_509) },
        { CKA_CLASS, &cko_certificate, sizeof(cko_certificate) },
        { CKA_SUBJECT, derSubject->data, derSubject->len },
    };
    const size_t templateCount = sizeof(subjectTemplate) / sizeof(subjectTemplate[0]);
    int handleCount = 0;
    CK_OBJECT_HANDLE *handles =
        pk11_FindObjectsByTemplate(slot, subjectTemplate, templateCount,
                                   &handleCount);
    if (!handles) {
        // pk11_FindObjectsByTemplate indicates there was an error by setting
        // handleCount to -1 (and it has set an error with PORT_SetError).
        if (handleCount == -1) {
            return SECFailure;
        }
        return SECSuccess;
    }
    PORT_Assert(handleCount > 0);
    if (handleCount <= 0) {
        PORT_Free(handles);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    if (handleCount > INT_MAX / sizeof(SECItem)) {
        PORT_Free(handles);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena) {
        PORT_Free(handles);
        return SECFailure;
    }
    CERTCertificateList *rawCertificates =
        PORT_ArenaNew(arena, CERTCertificateList);
    if (!rawCertificates) {
        PORT_Free(handles);
        PORT_FreeArena(arena, PR_FALSE);
        return SECFailure;
    }
    rawCertificates->arena = arena;
    rawCertificates->certs = PORT_ArenaNewArray(arena, SECItem, handleCount);
    if (!rawCertificates->certs) {
        PORT_Free(handles);
        PORT_FreeArena(arena, PR_FALSE);
        return SECFailure;
    }
    rawCertificates->len = handleCount;
    int handleIndex;
    for (handleIndex = 0; handleIndex < handleCount; handleIndex++) {
        SECStatus rv =
            PK11_ReadAttribute(slot, handles[handleIndex], CKA_VALUE, arena,
                               &rawCertificates->certs[handleIndex]);
        if (rv != SECSuccess) {
            PORT_Free(handles);
            PORT_FreeArena(arena, PR_FALSE);
            return SECFailure;
        }
        if (!rawCertificates->certs[handleIndex].data) {
            PORT_Free(handles);
            PORT_FreeArena(arena, PR_FALSE);
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            return SECFailure;
        }
    }
    PORT_Free(handles);
    *results = rawCertificates;
    return SECSuccess;
}

/*
 * given a PKCS #11 object, match it's peer based on the KeyID. searchID
 * is typically a privateKey or a certificate while the peer is the opposite
 */
CK_OBJECT_HANDLE
PK11_MatchItem(PK11SlotInfo *slot, CK_OBJECT_HANDLE searchID,
               CK_OBJECT_CLASS matchclass)
{
    CK_ATTRIBUTE theTemplate[] = {
        { CKA_ID, NULL, 0 },
        { CKA_CLASS, NULL, 0 }
    };
    /* if you change the array, change the variable below as well */
    CK_ATTRIBUTE *keyclass = &theTemplate[1];
    const size_t tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
    /* if you change the array, change the variable below as well */
    CK_OBJECT_HANDLE peerID;
    PORTCheapArenaPool tmpArena;
    CK_RV crv;

    /* now we need to create space for the public key */
    PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);

    crv = PK11_GetAttributes(&tmpArena.arena, slot, searchID, theTemplate, tsize);
    if (crv != CKR_OK) {
        PORT_DestroyCheapArena(&tmpArena);
        PORT_SetError(PK11_MapError(crv));
        return CK_INVALID_HANDLE;
    }

    if ((theTemplate[0].ulValueLen == 0) || (theTemplate[0].ulValueLen == -1)) {
        PORT_DestroyCheapArena(&tmpArena);
        if (matchclass == CKO_CERTIFICATE)
            PORT_SetError(SEC_ERROR_BAD_KEY);
        else
            PORT_SetError(SEC_ERROR_NO_KEY);
        return CK_INVALID_HANDLE;
    }

    /*
     * issue the find
     */
    *(CK_OBJECT_CLASS *)(keyclass->pValue) = matchclass;

    peerID = pk11_FindObjectByTemplate(slot, theTemplate, tsize);
    PORT_DestroyCheapArena(&tmpArena);

    return peerID;
}

/*
 * count the number of objects that match the template.
 */
int
PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
                      int templCount)
{
    CK_OBJECT_HANDLE objID[PK11_SEARCH_CHUNKSIZE];
    int object_count = 0;
    CK_ULONG returned_count = 0;
    CK_RV crv = CKR_SESSION_HANDLE_INVALID;

    PK11_EnterSlotMonitor(slot);
    if (slot->session != CK_INVALID_HANDLE) {
        crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session,
                                                   findTemplate, templCount);
    }
    if (crv != CKR_OK) {
        PK11_ExitSlotMonitor(slot);
        PORT_SetError(PK11_MapError(crv));
        return object_count;
    }

    /*
     * collect all the Matching Objects
     */
    do {
        crv = PK11_GETTAB(slot)->C_FindObjects(slot->session, objID,
                                               PK11_SEARCH_CHUNKSIZE,
                                               &returned_count);
        if (crv != CKR_OK) {
            PORT_SetError(PK11_MapError(crv));
            break;
        }
        object_count += returned_count;
    } while (returned_count == PK11_SEARCH_CHUNKSIZE);

    PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session);
    PK11_ExitSlotMonitor(slot);
    return object_count;
}

/*
 * Traverse all the objects in a given slot.
 */
SECStatus
PK11_TraverseSlot(PK11SlotInfo *slot, void *arg)
{
    int i;
    CK_OBJECT_HANDLE *objID = NULL;
    int object_count = 0;
    pk11TraverseSlot *slotcb = (pk11TraverseSlot *)arg;

    objID = pk11_FindObjectsByTemplate(slot, slotcb->findTemplate,
                                       slotcb->templateCount, &object_count);

    /*Actually this isn't a failure... there just were no objs to be found*/
    if (object_count == 0) {
        return SECSuccess;
    }

    if (objID == NULL) {
        return SECFailure;
    }

    for (i = 0; i < object_count; i++) {
        (*slotcb->callback)(slot, objID[i], slotcb->callbackArg);
    }
    PORT_Free(objID);
    return SECSuccess;
}

/*
 * Traverse all the objects in all slots.
 */
SECStatus
pk11_TraverseAllSlots(SECStatus (*callback)(PK11SlotInfo *, void *),
                      void *arg, PRBool forceLogin, void *wincx)
{
    PK11SlotList *list;
    PK11SlotListElement *le;
    SECStatus rv;

    /* get them all! */
    list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, wincx);
    if (list == NULL)
        return SECFailure;

    /* look at each slot and authenticate as necessary */
    for (le = list->head; le; le = le->next) {
        if (forceLogin) {
            rv = pk11_AuthenticateUnfriendly(le->slot, PR_FALSE, wincx);
            if (rv != SECSuccess) {
                continue;
            }
        }
        if (callback) {
            (*callback)(le->slot, arg);
        }
    }

    PK11_FreeSlotList(list);

    return SECSuccess;
}

CK_OBJECT_HANDLE *
PK11_FindObjectsFromNickname(char *nickname, PK11SlotInfo **slotptr,
                             CK_OBJECT_CLASS objclass, int *returnCount, void *wincx)
{
    char *tokenName;
    char *delimit;
    PK11SlotInfo *slot;
    CK_OBJECT_HANDLE *objID;
    CK_ATTRIBUTE findTemplate[] = {
        { CKA_LABEL, NULL, 0 },
        { CKA_CLASS, NULL, 0 },
    };
    const size_t findCount = sizeof(findTemplate) / sizeof(findTemplate[0]);
    SECStatus rv;
    PK11_SETATTRS(&findTemplate[1], CKA_CLASS, &objclass, sizeof(objclass));

    *slotptr = slot = NULL;
    *returnCount = 0;
    /* first find the slot associated with this nickname */
    if ((delimit = PORT_Strchr(nickname, ':')) != NULL) {
        int len = delimit - nickname;
        tokenName = (char *)PORT_Alloc(len + 1);
        if (!tokenName) {
            return CK_INVALID_HANDLE;
        }
        PORT_Memcpy(tokenName, nickname, len);
        tokenName[len] = 0;

        slot = *slotptr = PK11_FindSlotByName(tokenName);
        PORT_Free(tokenName);
        /* if we couldn't find a slot, assume the nickname is an internal cert
         * with no proceding slot name */
        if (slot == NULL) {
            slot = *slotptr = PK11_GetInternalKeySlot();
        } else {
            nickname = delimit + 1;
        }
    } else {
        *slotptr = slot = PK11_GetInternalKeySlot();
    }
    if (slot == NULL) {
        return CK_INVALID_HANDLE;
    }

    rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
    if (rv != SECSuccess) {
        PK11_FreeSlot(slot);
        *slotptr = NULL;
        return CK_INVALID_HANDLE;
    }

    findTemplate[0].pValue = nickname;
    findTemplate[0].ulValueLen = PORT_Strlen(nickname);
    objID = pk11_FindObjectsByTemplate(slot, findTemplate, findCount, returnCount);
    if (objID == NULL) {
        /* PKCS #11 isn't clear on whether or not the NULL is
         * stored in the template.... try the find again with the
         * full null terminated string. */
        findTemplate[0].ulValueLen += 1;
        objID = pk11_FindObjectsByTemplate(slot, findTemplate, findCount,
                                           returnCount);
        if (objID == NULL) {
            /* Well that's the best we can do. It's just not here */
            /* what about faked nicknames? */
            PK11_FreeSlot(slot);
            *slotptr = NULL;
            *returnCount = 0;
        }
    }

    return objID;
}

SECItem *
pk11_GetLowLevelKeyFromHandle(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle)
{
    CK_ATTRIBUTE theTemplate[] = {
        { CKA_ID, NULL, 0 },
    };
    int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
    CK_RV crv;
    SECItem *item;

    item = SECITEM_AllocItem(NULL, NULL, 0);

    if (item == NULL) {
        return NULL;
    }

    crv = PK11_GetAttributes(NULL, slot, handle, theTemplate, tsize);
    if (crv != CKR_OK) {
        SECITEM_FreeItem(item, PR_TRUE);
        PORT_SetError(PK11_MapError(crv));
        return NULL;
    }

    item->data = (unsigned char *)theTemplate[0].pValue;
    item->len = theTemplate[0].ulValueLen;

    return item;
}

PRBool
PK11_ObjectGetFIPSStatus(PK11ObjectType objType, void *objSpec)
{
    PK11SlotInfo *slot = NULL;
    CK_OBJECT_HANDLE handle = 0;

    handle = PK11_GetObjectHandle(objType, objSpec, &slot);
    if (handle == CK_INVALID_HANDLE) {
        PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE);
        return PR_FALSE;
    }
    return pk11slot_GetFIPSStatus(slot, slot->session, handle,
                                  CKT_NSS_OBJECT_CHECK);
}
