/* 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/. */

#include "pkcs11.h"

#ifndef DEVM_H
#include "devm.h"
#endif /* DEVM_H */

#ifndef CKHELPER_H
#include "ckhelper.h"
#endif /* CKHELPER_H */

#include "pk11func.h"
#include "dev3hack.h"
#include "secerr.h"

extern const NSSError NSS_ERROR_NOT_FOUND;
extern const NSSError NSS_ERROR_INVALID_ARGUMENT;
extern const NSSError NSS_ERROR_PKCS11;

/* The number of object handles to grab during each call to C_FindObjects */
#define OBJECT_STACK_SIZE 16

NSS_IMPLEMENT PRStatus
nssToken_Destroy(
    NSSToken *tok)
{
    if (tok) {
        if (PR_ATOMIC_DECREMENT(&tok->base.refCount) == 0) {
            PK11_FreeSlot(tok->pk11slot);
            PZ_DestroyLock(tok->base.lock);
            nssTokenObjectCache_Destroy(tok->cache);

            /* We're going away, let the nssSlot know in case it's held
             * alive by someone else. Usually we should hold the last ref. */
            nssSlot_EnterMonitor(tok->slot);
            tok->slot->token = NULL;
            nssSlot_ExitMonitor(tok->slot);

            (void)nssSlot_Destroy(tok->slot);
            return nssArena_Destroy(tok->base.arena);
        }
    }
    return PR_SUCCESS;
}

NSS_IMPLEMENT void
nssToken_Remove(
    NSSToken *tok)
{
    nssTokenObjectCache_Clear(tok->cache);
}

NSS_IMPLEMENT void
NSSToken_Destroy(
    NSSToken *tok)
{
    (void)nssToken_Destroy(tok);
}

NSS_IMPLEMENT NSSToken *
nssToken_AddRef(
    NSSToken *tok)
{
    PR_ATOMIC_INCREMENT(&tok->base.refCount);
    return tok;
}

NSS_IMPLEMENT NSSSlot *
nssToken_GetSlot(
    NSSToken *tok)
{
    return nssSlot_AddRef(tok->slot);
}

NSS_IMPLEMENT void *
nssToken_GetCryptokiEPV(
    NSSToken *token)
{
    return nssSlot_GetCryptokiEPV(token->slot);
}

NSS_IMPLEMENT nssSession *
nssToken_GetDefaultSession(
    NSSToken *token)
{
    return token->defaultSession;
}

NSS_IMPLEMENT NSSUTF8 *
nssToken_GetName(
    NSSToken *tok)
{
    if (tok == NULL) {
        return "";
    }
    if (tok->base.name[0] == 0) {
        (void)nssSlot_IsTokenPresent(tok->slot);
    }
    return tok->base.name;
}

NSS_IMPLEMENT NSSUTF8 *
NSSToken_GetName(
    NSSToken *token)
{
    return nssToken_GetName(token);
}

NSS_IMPLEMENT PRBool
nssToken_IsLoginRequired(
    NSSToken *token)
{
    return (token->ckFlags & CKF_LOGIN_REQUIRED);
}

NSS_IMPLEMENT PRBool
nssToken_NeedsPINInitialization(
    NSSToken *token)
{
    return (!(token->ckFlags & CKF_USER_PIN_INITIALIZED));
}

NSS_IMPLEMENT PRStatus
nssToken_DeleteStoredObject(
    nssCryptokiObject *instance)
{
    CK_RV ckrv;
    PRStatus status;
    PRBool createdSession = PR_FALSE;
    NSSToken *token = instance->token;
    nssSession *session = NULL;
    void *epv = nssToken_GetCryptokiEPV(instance->token);
    if (token->cache) {
        nssTokenObjectCache_RemoveObject(token->cache, instance);
    }
    if (instance->isTokenObject) {
        if (token->defaultSession &&
            nssSession_IsReadWrite(token->defaultSession)) {
            session = token->defaultSession;
        } else {
            session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE);
            createdSession = PR_TRUE;
        }
    }
    if (session == NULL) {
        return PR_FAILURE;
    }
    nssSession_EnterMonitor(session);
    ckrv = CKAPI(epv)->C_DestroyObject(session->handle, instance->handle);
    nssSession_ExitMonitor(session);
    if (createdSession) {
        nssSession_Destroy(session);
    }
    status = PR_SUCCESS;
    if (ckrv != CKR_OK) {
        status = PR_FAILURE;
        /* use the error stack to pass the PKCS #11 error out  */
        nss_SetError(ckrv);
        nss_SetError(NSS_ERROR_PKCS11);
    }
    return status;
}

static nssCryptokiObject *
import_object(
    NSSToken *tok,
    nssSession *sessionOpt,
    CK_ATTRIBUTE_PTR objectTemplate,
    CK_ULONG otsize)
{
    nssSession *session = NULL;
    PRBool createdSession = PR_FALSE;
    nssCryptokiObject *object = NULL;
    CK_OBJECT_HANDLE handle;
    CK_RV ckrv;
    void *epv = nssToken_GetCryptokiEPV(tok);
    if (nssCKObject_IsTokenObjectTemplate(objectTemplate, otsize)) {
        if (sessionOpt) {
            if (!nssSession_IsReadWrite(sessionOpt)) {
                nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
                return NULL;
            }
            session = sessionOpt;
        } else if (tok->defaultSession &&
                   nssSession_IsReadWrite(tok->defaultSession)) {
            session = tok->defaultSession;
        } else {
            session = nssSlot_CreateSession(tok->slot, NULL, PR_TRUE);
            createdSession = PR_TRUE;
        }
    } else {
        session = (sessionOpt) ? sessionOpt : tok->defaultSession;
    }
    if (session == NULL) {
        nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
        return NULL;
    }
    nssSession_EnterMonitor(session);
    ckrv = CKAPI(epv)->C_CreateObject(session->handle,
                                      objectTemplate, otsize,
                                      &handle);
    nssSession_ExitMonitor(session);
    if (ckrv == CKR_OK) {
        object = nssCryptokiObject_Create(tok, session, handle);
    } else {
        nss_SetError(ckrv);
        nss_SetError(NSS_ERROR_PKCS11);
    }
    if (createdSession) {
        nssSession_Destroy(session);
    }
    return object;
}

static nssCryptokiObject **
create_objects_from_handles(
    NSSToken *tok,
    nssSession *session,
    CK_OBJECT_HANDLE *handles,
    PRUint32 numH)
{
    nssCryptokiObject **objects;
    objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numH + 1);
    if (objects) {
        PRInt32 i;
        for (i = 0; i < (PRInt32)numH; i++) {
            objects[i] = nssCryptokiObject_Create(tok, session, handles[i]);
            if (!objects[i]) {
                for (--i; i > 0; --i) {
                    nssCryptokiObject_Destroy(objects[i]);
                }
                nss_ZFreeIf(objects);
                objects = NULL;
                break;
            }
        }
    }
    return objects;
}

static nssCryptokiObject **
find_objects(
    NSSToken *tok,
    nssSession *sessionOpt,
    CK_ATTRIBUTE_PTR obj_template,
    CK_ULONG otsize,
    PRUint32 maximumOpt,
    PRStatus *statusOpt)
{
    CK_RV ckrv = CKR_OK;
    CK_ULONG count;
    CK_OBJECT_HANDLE *objectHandles = NULL;
    CK_OBJECT_HANDLE staticObjects[OBJECT_STACK_SIZE];
    PRUint32 arraySize, numHandles;
    void *epv = nssToken_GetCryptokiEPV(tok);
    nssCryptokiObject **objects;
    nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession;

    /* Don't ask the module to use an invalid session handle. */
    if (!session || session->handle == CK_INVALID_SESSION) {
        ckrv = CKR_SESSION_HANDLE_INVALID;
        goto loser;
    }

    /* the arena is only for the array of object handles */
    if (maximumOpt > 0) {
        arraySize = maximumOpt;
    } else {
        arraySize = OBJECT_STACK_SIZE;
    }
    numHandles = 0;
    if (arraySize <= OBJECT_STACK_SIZE) {
        objectHandles = staticObjects;
    } else {
        objectHandles = nss_ZNEWARRAY(NULL, CK_OBJECT_HANDLE, arraySize);
    }
    if (!objectHandles) {
        ckrv = CKR_HOST_MEMORY;
        goto loser;
    }
    nssSession_EnterMonitor(session); /* ==== session lock === */
    /* Initialize the find with the template */
    ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle,
                                         obj_template, otsize);
    if (ckrv != CKR_OK) {
        nssSession_ExitMonitor(session);
        goto loser;
    }
    while (PR_TRUE) {
        /* Issue the find for up to arraySize - numHandles objects */
        ckrv = CKAPI(epv)->C_FindObjects(session->handle,
                                         objectHandles + numHandles,
                                         arraySize - numHandles,
                                         &count);
        if (ckrv != CKR_OK) {
            nssSession_ExitMonitor(session);
            goto loser;
        }
        /* bump the number of found objects */
        numHandles += count;
        if (maximumOpt > 0 || numHandles < arraySize) {
            /* When a maximum is provided, the search is done all at once,
             * so the search is finished.  If the number returned was less
             * than the number sought, the search is finished.
             */
            break;
        }
        /* the array is filled, double it and continue */
        arraySize *= 2;
        if (objectHandles == staticObjects) {
            objectHandles = nss_ZNEWARRAY(NULL, CK_OBJECT_HANDLE, arraySize);
            if (objectHandles) {
                PORT_Memcpy(objectHandles, staticObjects,
                            OBJECT_STACK_SIZE * sizeof(objectHandles[1]));
            }
        } else {
            objectHandles = nss_ZREALLOCARRAY(objectHandles,
                                              CK_OBJECT_HANDLE,
                                              arraySize);
        }
        if (!objectHandles) {
            nssSession_ExitMonitor(session);
            ckrv = CKR_HOST_MEMORY;
            goto loser;
        }
    }
    ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle);
    nssSession_ExitMonitor(session); /* ==== end session lock === */
    if (ckrv != CKR_OK) {
        goto loser;
    }
    if (numHandles > 0) {
        objects = create_objects_from_handles(tok, session,
                                              objectHandles, numHandles);
    } else {
        nss_SetError(NSS_ERROR_NOT_FOUND);
        objects = NULL;
    }
    if (objectHandles && objectHandles != staticObjects) {
        nss_ZFreeIf(objectHandles);
    }
    if (statusOpt)
        *statusOpt = PR_SUCCESS;
    return objects;
loser:
    if (objectHandles && objectHandles != staticObjects) {
        nss_ZFreeIf(objectHandles);
    }
    /*
     * These errors should be treated the same as if the objects just weren't
     * found..
     */
    if ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) ||
        (ckrv == CKR_ATTRIBUTE_VALUE_INVALID) ||
        (ckrv == CKR_DATA_INVALID) ||
        (ckrv == CKR_DATA_LEN_RANGE) ||
        (ckrv == CKR_FUNCTION_NOT_SUPPORTED) ||
        (ckrv == CKR_TEMPLATE_INCOMPLETE) ||
        (ckrv == CKR_TEMPLATE_INCONSISTENT)) {

        nss_SetError(NSS_ERROR_NOT_FOUND);
        if (statusOpt)
            *statusOpt = PR_SUCCESS;
    } else {
        nss_SetError(ckrv);
        nss_SetError(NSS_ERROR_PKCS11);
        if (statusOpt)
            *statusOpt = PR_FAILURE;
    }
    return (nssCryptokiObject **)NULL;
}

NSS_IMPLEMENT nssCryptokiObject **
nssToken_FindObjectsByTemplate(
    NSSToken *token,
    nssSession *sessionOpt,
    CK_ATTRIBUTE_PTR obj_template,
    CK_ULONG otsize,
    PRUint32 maximumOpt,
    PRStatus *statusOpt)
{
    CK_OBJECT_CLASS objclass = (CK_OBJECT_CLASS)-1;
    nssCryptokiObject **objects = NULL;
    PRUint32 i;

    if (!token) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        if (statusOpt)
            *statusOpt = PR_FAILURE;
        return NULL;
    }
    for (i = 0; i < otsize; i++) {
        if (obj_template[i].type == CKA_CLASS) {
            objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue;
            break;
        }
    }
    PR_ASSERT(i < otsize);
    if (i == otsize) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        if (statusOpt)
            *statusOpt = PR_FAILURE;
        return NULL;
    }
    /* If these objects are being cached, try looking there first */
    if (token->cache &&
        nssTokenObjectCache_HaveObjectClass(token->cache, objclass)) {
        PRStatus status;
        objects = nssTokenObjectCache_FindObjectsByTemplate(token->cache,
                                                            objclass,
                                                            obj_template,
                                                            otsize,
                                                            maximumOpt,
                                                            &status);
        if (status == PR_SUCCESS) {
            if (statusOpt)
                *statusOpt = status;
            return objects;
        }
    }
    /* Either they are not cached, or cache failed; look on token. */
    objects = find_objects(token, sessionOpt,
                           obj_template, otsize,
                           maximumOpt, statusOpt);
    return objects;
}

extern const NSSError NSS_ERROR_INVALID_CERTIFICATE;

NSS_IMPLEMENT nssCryptokiObject *
nssToken_ImportCertificate(
    NSSToken *tok,
    nssSession *sessionOpt,
    NSSCertificateType certType,
    NSSItem *id,
    const NSSUTF8 *nickname,
    NSSDER *encoding,
    NSSDER *issuer,
    NSSDER *subject,
    NSSDER *serial,
    NSSASCII7 *email,
    PRBool asTokenObject)
{
    PRStatus status;
    CK_CERTIFICATE_TYPE cert_type;
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE cert_tmpl[10];
    CK_ULONG ctsize;
    nssTokenSearchType searchType;
    nssCryptokiObject *rvObject = NULL;

    if (!tok) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        return NULL;
    }
    if (certType == NSSCertificateType_PKIX) {
        cert_type = CKC_X_509;
    } else {
        return (nssCryptokiObject *)NULL;
    }
    NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize);
    if (asTokenObject) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
        searchType = nssTokenSearchType_TokenOnly;
    } else {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
        searchType = nssTokenSearchType_SessionOnly;
    }
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CERTIFICATE_TYPE, cert_type);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
    NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial);
    if (email) {
        NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email);
    }
    NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
    /* see if the cert is already there */
    rvObject = nssToken_FindCertificateByIssuerAndSerialNumber(tok,
                                                               sessionOpt,
                                                               issuer,
                                                               serial,
                                                               searchType,
                                                               NULL);
    if (rvObject) {
        NSSItem existingDER;
        NSSSlot *slot = nssToken_GetSlot(tok);
        nssSession *session = nssSlot_CreateSession(slot, NULL, PR_TRUE);
        if (!session) {
            nssCryptokiObject_Destroy(rvObject);
            nssSlot_Destroy(slot);
            return (nssCryptokiObject *)NULL;
        }
        /* Reject any attempt to import a new cert that has the same
         * issuer/serial as an existing cert, but does not have the
         * same encoding
         */
        NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize);
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
        NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
        status = nssCKObject_GetAttributes(rvObject->handle,
                                           cert_tmpl, ctsize, NULL,
                                           session, slot);
        NSS_CK_ATTRIBUTE_TO_ITEM(cert_tmpl, &existingDER);
        if (status == PR_SUCCESS) {
            if (!nssItem_Equal(encoding, &existingDER, NULL)) {
                nss_SetError(NSS_ERROR_INVALID_CERTIFICATE);
                status = PR_FAILURE;
            }
            nss_ZFreeIf(existingDER.data);
        }
        if (status == PR_FAILURE) {
            nssCryptokiObject_Destroy(rvObject);
            nssSession_Destroy(session);
            nssSlot_Destroy(slot);
            return (nssCryptokiObject *)NULL;
        }
        /* according to PKCS#11, label, ID, issuer, and serial number
         * may change after the object has been created.  For PKIX, the
         * last two attributes can't change, so for now we'll only worry
         * about the first two.
         */
        NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize);
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
        if (!rvObject->label && nickname) {
            NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
        }
        NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
        /* reset the mutable attributes on the token */
        nssCKObject_SetAttributes(rvObject->handle,
                                  cert_tmpl, ctsize,
                                  session, slot);
        if (!rvObject->label && nickname) {
            rvObject->label = nssUTF8_Duplicate(nickname, NULL);
        }
        nssSession_Destroy(session);
        nssSlot_Destroy(slot);
    } else {
        /* Import the certificate onto the token */
        rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize);
    }
    if (rvObject && tok->cache) {
        /* The cache will overwrite the attributes if the object already
         * exists.
         */
        nssTokenObjectCache_ImportObject(tok->cache, rvObject,
                                         CKO_CERTIFICATE,
                                         cert_tmpl, ctsize);
    }
    return rvObject;
}

/* traverse all objects of the given class - this should only happen
 * if the token has been marked as "traversable"
 */
NSS_IMPLEMENT nssCryptokiObject **
nssToken_FindObjects(
    NSSToken *token,
    nssSession *sessionOpt,
    CK_OBJECT_CLASS objclass,
    nssTokenSearchType searchType,
    PRUint32 maximumOpt,
    PRStatus *statusOpt)
{
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE obj_template[2];
    CK_ULONG obj_size;
    nssCryptokiObject **objects;
    NSS_CK_TEMPLATE_START(obj_template, attr, obj_size);
    /* Set the search to token/session only if provided */
    if (searchType == nssTokenSearchType_SessionOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
    } else if (searchType == nssTokenSearchType_TokenOnly ||
               searchType == nssTokenSearchType_TokenForced) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    }
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, objclass);
    NSS_CK_TEMPLATE_FINISH(obj_template, attr, obj_size);

    if (searchType == nssTokenSearchType_TokenForced) {
        objects = find_objects(token, sessionOpt,
                               obj_template, obj_size,
                               maximumOpt, statusOpt);
    } else {
        objects = nssToken_FindObjectsByTemplate(token, sessionOpt,
                                                 obj_template, obj_size,
                                                 maximumOpt, statusOpt);
    }
    return objects;
}

NSS_IMPLEMENT nssCryptokiObject **
nssToken_FindCertificatesBySubject(
    NSSToken *token,
    nssSession *sessionOpt,
    NSSDER *subject,
    nssTokenSearchType searchType,
    PRUint32 maximumOpt,
    PRStatus *statusOpt)
{
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE subj_template[3];
    CK_ULONG stsize;
    nssCryptokiObject **objects;
    NSS_CK_TEMPLATE_START(subj_template, attr, stsize);
    /* Set the search to token/session only if provided */
    if (searchType == nssTokenSearchType_SessionOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
    } else if (searchType == nssTokenSearchType_TokenOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    }
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
    NSS_CK_TEMPLATE_FINISH(subj_template, attr, stsize);
    /* now locate the token certs matching this template */
    objects = nssToken_FindObjectsByTemplate(token, sessionOpt,
                                             subj_template, stsize,
                                             maximumOpt, statusOpt);
    return objects;
}

NSS_IMPLEMENT nssCryptokiObject **
nssToken_FindCertificatesByNickname(
    NSSToken *token,
    nssSession *sessionOpt,
    const NSSUTF8 *name,
    nssTokenSearchType searchType,
    PRUint32 maximumOpt,
    PRStatus *statusOpt)
{
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE nick_template[3];
    CK_ULONG ntsize;
    nssCryptokiObject **objects;
    NSS_CK_TEMPLATE_START(nick_template, attr, ntsize);
    NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, name);
    /* Set the search to token/session only if provided */
    if (searchType == nssTokenSearchType_SessionOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
    } else if (searchType == nssTokenSearchType_TokenOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    }
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
    NSS_CK_TEMPLATE_FINISH(nick_template, attr, ntsize);
    /* now locate the token certs matching this template */
    objects = nssToken_FindObjectsByTemplate(token, sessionOpt,
                                             nick_template, ntsize,
                                             maximumOpt, statusOpt);
    if (!objects) {
        /* This is to workaround the fact that PKCS#11 doesn't specify
         * whether the '\0' should be included.  XXX Is that still true?
         * im - this is not needed by the current softoken.  However, I'm
         * leaving it in until I have surveyed more tokens to see if it needed.
         * well, its needed by the builtin token...
         */
        nick_template[0].ulValueLen++;
        objects = nssToken_FindObjectsByTemplate(token, sessionOpt,
                                                 nick_template, ntsize,
                                                 maximumOpt, statusOpt);
    }
    return objects;
}

/* XXX
 * This function *does not* use the token object cache, because not even
 * the softoken will return a value for CKA_NSS_EMAIL from a call
 * to GetAttributes.  The softoken does allow searches with that attribute,
 * it just won't return a value for it.
 */
NSS_IMPLEMENT nssCryptokiObject **
nssToken_FindCertificatesByEmail(
    NSSToken *token,
    nssSession *sessionOpt,
    NSSASCII7 *email,
    nssTokenSearchType searchType,
    PRUint32 maximumOpt,
    PRStatus *statusOpt)
{
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE email_template[3];
    CK_ULONG etsize;
    nssCryptokiObject **objects;
    NSS_CK_TEMPLATE_START(email_template, attr, etsize);
    NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_EMAIL, email);
    /* Set the search to token/session only if provided */
    if (searchType == nssTokenSearchType_SessionOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
    } else if (searchType == nssTokenSearchType_TokenOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    }
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
    NSS_CK_TEMPLATE_FINISH(email_template, attr, etsize);
    /* now locate the token certs matching this template */
    objects = find_objects(token, sessionOpt,
                           email_template, etsize,
                           maximumOpt, statusOpt);
    if (!objects) {
        /* This is to workaround the fact that PKCS#11 doesn't specify
         * whether the '\0' should be included.  XXX Is that still true?
         * im - this is not needed by the current softoken.  However, I'm
         * leaving it in until I have surveyed more tokens to see if it needed.
         * well, its needed by the builtin token...
         */
        email_template[0].ulValueLen++;
        objects = find_objects(token, sessionOpt,
                               email_template, etsize,
                               maximumOpt, statusOpt);
    }
    return objects;
}

NSS_IMPLEMENT nssCryptokiObject **
nssToken_FindCertificatesByID(
    NSSToken *token,
    nssSession *sessionOpt,
    NSSItem *id,
    nssTokenSearchType searchType,
    PRUint32 maximumOpt,
    PRStatus *statusOpt)
{
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE id_template[3];
    CK_ULONG idtsize;
    nssCryptokiObject **objects;
    NSS_CK_TEMPLATE_START(id_template, attr, idtsize);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
    /* Set the search to token/session only if provided */
    if (searchType == nssTokenSearchType_SessionOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
    } else if (searchType == nssTokenSearchType_TokenOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    }
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
    NSS_CK_TEMPLATE_FINISH(id_template, attr, idtsize);
    /* now locate the token certs matching this template */
    objects = nssToken_FindObjectsByTemplate(token, sessionOpt,
                                             id_template, idtsize,
                                             maximumOpt, statusOpt);
    return objects;
}

/*
 * decode the serial item and return our result.
 * NOTE serialDecode's data is really stored in serial. Don't free it.
 */
static PRStatus
nssToken_decodeSerialItem(NSSItem *serial, NSSItem *serialDecode)
{
    unsigned char *data = (unsigned char *)serial->data;
    int data_left, data_len, index;

    if ((serial->size >= 3) && (data[0] == 0x2)) {
        /* remove the der encoding of the serial number before generating the
         * key.. */
        data_left = serial->size - 2;
        data_len = data[1];
        index = 2;

        /* extended length ? (not very likely for a serial number) */
        if (data_len & 0x80) {
            int len_count = data_len & 0x7f;

            data_len = 0;
            data_left -= len_count;
            if (data_left > 0) {
                while (len_count--) {
                    data_len = (data_len << 8) | data[index++];
                }
            }
        }
        /* XXX leaving any leading zeros on the serial number for backwards
         * compatibility
         */
        /* not a valid der, must be just an unlucky serial number value */
        if (data_len == data_left) {
            serialDecode->size = data_len;
            serialDecode->data = &data[index];
            return PR_SUCCESS;
        }
    }
    return PR_FAILURE;
}

NSS_IMPLEMENT nssCryptokiObject *
nssToken_FindCertificateByIssuerAndSerialNumber(
    NSSToken *token,
    nssSession *sessionOpt,
    NSSDER *issuer,
    NSSDER *serial,
    nssTokenSearchType searchType,
    PRStatus *statusOpt)
{
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE_PTR serialAttr;
    CK_ATTRIBUTE cert_template[4];
    CK_ULONG ctsize;
    nssCryptokiObject **objects;
    nssCryptokiObject *rvObject = NULL;
    NSS_CK_TEMPLATE_START(cert_template, attr, ctsize);

    if (!token) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        if (statusOpt)
            *statusOpt = PR_FAILURE;
        return NULL;
    }
    /* Set the search to token/session only if provided */
    if (searchType == nssTokenSearchType_SessionOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
    } else if ((searchType == nssTokenSearchType_TokenOnly) ||
               (searchType == nssTokenSearchType_TokenForced)) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    }
    /* Set the unique id */
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer);
    serialAttr = attr;
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial);
    NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);
    /* get the object handle */
    if (searchType == nssTokenSearchType_TokenForced) {
        objects = find_objects(token, sessionOpt,
                               cert_template, ctsize,
                               1, statusOpt);
    } else {
        objects = nssToken_FindObjectsByTemplate(token, sessionOpt,
                                                 cert_template, ctsize,
                                                 1, statusOpt);
    }
    if (objects) {
        rvObject = objects[0];
        nss_ZFreeIf(objects);
    }

    /*
     * NSS used to incorrectly store serial numbers in their decoded form.
     * because of this old tokens have decoded serial numbers.
     */
    if (!objects) {
        NSSItem serialDecode;
        PRStatus status;

        status = nssToken_decodeSerialItem(serial, &serialDecode);
        if (status != PR_SUCCESS) {
            return NULL;
        }
        NSS_CK_SET_ATTRIBUTE_ITEM(serialAttr, CKA_SERIAL_NUMBER, &serialDecode);
        if (searchType == nssTokenSearchType_TokenForced) {
            objects = find_objects(token, sessionOpt,
                                   cert_template, ctsize,
                                   1, statusOpt);
        } else {
            objects = nssToken_FindObjectsByTemplate(token, sessionOpt,
                                                     cert_template, ctsize,
                                                     1, statusOpt);
        }
        if (objects) {
            rvObject = objects[0];
            nss_ZFreeIf(objects);
        }
    }
    return rvObject;
}

NSS_IMPLEMENT nssCryptokiObject *
nssToken_FindCertificateByEncodedCertificate(
    NSSToken *token,
    nssSession *sessionOpt,
    NSSBER *encodedCertificate,
    nssTokenSearchType searchType,
    PRStatus *statusOpt)
{
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE cert_template[3];
    CK_ULONG ctsize;
    nssCryptokiObject **objects;
    nssCryptokiObject *rvObject = NULL;
    NSS_CK_TEMPLATE_START(cert_template, attr, ctsize);
    /* Set the search to token/session only if provided */
    if (searchType == nssTokenSearchType_SessionOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
    } else if (searchType == nssTokenSearchType_TokenOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    }
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encodedCertificate);
    NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);
    /* get the object handle */
    objects = nssToken_FindObjectsByTemplate(token, sessionOpt,
                                             cert_template, ctsize,
                                             1, statusOpt);
    if (objects) {
        rvObject = objects[0];
        nss_ZFreeIf(objects);
    }
    return rvObject;
}

NSS_IMPLEMENT nssCryptokiObject **
nssToken_FindPrivateKeys(
    NSSToken *token,
    nssSession *sessionOpt,
    nssTokenSearchType searchType,
    PRUint32 maximumOpt,
    PRStatus *statusOpt)
{
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE key_template[2];
    CK_ULONG ktsize;
    nssCryptokiObject **objects;

    NSS_CK_TEMPLATE_START(key_template, attr, ktsize);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey);
    if (searchType == nssTokenSearchType_SessionOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
    } else if (searchType == nssTokenSearchType_TokenOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    }
    NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize);

    objects = nssToken_FindObjectsByTemplate(token, sessionOpt,
                                             key_template, ktsize,
                                             maximumOpt, statusOpt);
    return objects;
}

/* XXX ?there are no session cert objects, so only search token objects */
NSS_IMPLEMENT nssCryptokiObject *
nssToken_FindPrivateKeyByID(
    NSSToken *token,
    nssSession *sessionOpt,
    NSSItem *keyID)
{
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE key_template[3];
    CK_ULONG ktsize;
    nssCryptokiObject **objects;
    nssCryptokiObject *rvKey = NULL;

    NSS_CK_TEMPLATE_START(key_template, attr, ktsize);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_privkey);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID);
    NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize);

    objects = nssToken_FindObjectsByTemplate(token, sessionOpt,
                                             key_template, ktsize,
                                             1, NULL);
    if (objects) {
        rvKey = objects[0];
        nss_ZFreeIf(objects);
    }
    return rvKey;
}

/* XXX ?there are no session cert objects, so only search token objects */
NSS_IMPLEMENT nssCryptokiObject *
nssToken_FindPublicKeyByID(
    NSSToken *token,
    nssSession *sessionOpt,
    NSSItem *keyID)
{
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE key_template[3];
    CK_ULONG ktsize;
    nssCryptokiObject **objects;
    nssCryptokiObject *rvKey = NULL;

    NSS_CK_TEMPLATE_START(key_template, attr, ktsize);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_pubkey);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID);
    NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize);

    objects = nssToken_FindObjectsByTemplate(token, sessionOpt,
                                             key_template, ktsize,
                                             1, NULL);
    if (objects) {
        rvKey = objects[0];
        nss_ZFreeIf(objects);
    }
    return rvKey;
}

static void
sha1_hash(NSSItem *input, NSSItem *output)
{
    NSSAlgorithmAndParameters *ap;
    PK11SlotInfo *internal = PK11_GetInternalSlot();
    NSSToken *token = PK11Slot_GetNSSToken(internal);
    ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL);
    (void)nssToken_Digest(token, NULL, ap, input, output, NULL);
    PK11_FreeSlot(token->pk11slot);
    nss_ZFreeIf(ap);
}

static void
md5_hash(NSSItem *input, NSSItem *output)
{
    NSSAlgorithmAndParameters *ap;
    PK11SlotInfo *internal = PK11_GetInternalSlot();
    NSSToken *token = PK11Slot_GetNSSToken(internal);
    ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL);
    (void)nssToken_Digest(token, NULL, ap, input, output, NULL);
    PK11_FreeSlot(token->pk11slot);
    nss_ZFreeIf(ap);
}

static CK_TRUST
get_ck_trust(
    nssTrustLevel nssTrust)
{
    CK_TRUST t;
    switch (nssTrust) {
        case nssTrustLevel_NotTrusted:
            t = CKT_NSS_NOT_TRUSTED;
            break;
        case nssTrustLevel_TrustedDelegator:
            t = CKT_NSS_TRUSTED_DELEGATOR;
            break;
        case nssTrustLevel_ValidDelegator:
            t = CKT_NSS_VALID_DELEGATOR;
            break;
        case nssTrustLevel_Trusted:
            t = CKT_NSS_TRUSTED;
            break;
        case nssTrustLevel_MustVerify:
            t = CKT_NSS_MUST_VERIFY_TRUST;
            break;
        case nssTrustLevel_Unknown:
        default:
            t = CKT_NSS_TRUST_UNKNOWN;
            break;
    }
    return t;
}

NSS_IMPLEMENT nssCryptokiObject *
nssToken_ImportTrust(
    NSSToken *tok,
    nssSession *sessionOpt,
    NSSDER *certEncoding,
    NSSDER *certIssuer,
    NSSDER *certSerial,
    nssTrustLevel serverAuth,
    nssTrustLevel clientAuth,
    nssTrustLevel codeSigning,
    nssTrustLevel emailProtection,
    PRBool stepUpApproved,
    PRBool asTokenObject)
{
    nssCryptokiObject *object;
    CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST;
    CK_TRUST ckSA, ckCA, ckCS, ckEP;
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE trust_tmpl[11];
    CK_ULONG tsize;
    PRUint8 sha1[20]; /* this is cheating... */
    PRUint8 md5[16];
    NSSItem sha1_result, md5_result;
    sha1_result.data = sha1;
    sha1_result.size = sizeof sha1;
    md5_result.data = md5;
    md5_result.size = sizeof md5;
    sha1_hash(certEncoding, &sha1_result);
    md5_hash(certEncoding, &md5_result);
    ckSA = get_ck_trust(serverAuth);
    ckCA = get_ck_trust(clientAuth);
    ckCS = get_ck_trust(codeSigning);
    ckEP = get_ck_trust(emailProtection);
    NSS_CK_TEMPLATE_START(trust_tmpl, attr, tsize);
    if (asTokenObject) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    } else {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
    }
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, tobjc);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, &sha1_result);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_MD5_HASH, &md5_result);
    /* now set the trust values */
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, ckSA);
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, ckCA);
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, ckCS);
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, ckEP);
    if (stepUpApproved) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED,
                                  &g_ck_true);
    } else {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TRUST_STEP_UP_APPROVED,
                                  &g_ck_false);
    }
    NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize);
    /* import the trust object onto the token */
    object = import_object(tok, sessionOpt, trust_tmpl, tsize);
    if (object && tok->cache) {
        nssTokenObjectCache_ImportObject(tok->cache, object, tobjc,
                                         trust_tmpl, tsize);
    }
    return object;
}

NSS_IMPLEMENT nssCryptokiObject *
nssToken_FindTrustForCertificate(
    NSSToken *token,
    nssSession *sessionOpt,
    NSSDER *certEncoding,
    NSSDER *certIssuer,
    NSSDER *certSerial,
    nssTokenSearchType searchType)
{
    CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST;
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE tobj_template[5];
    CK_ULONG tobj_size;
    nssSession *session = sessionOpt ? sessionOpt : token->defaultSession;
    nssCryptokiObject *object = NULL, **objects;

    /* Don't ask the module to use an invalid session handle. */
    if (!session || session->handle == CK_INVALID_SESSION) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        return object;
    }

    NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size);
    if (searchType == nssTokenSearchType_TokenOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    }
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, tobjc);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial);
    NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size);
    objects = nssToken_FindObjectsByTemplate(token, session,
                                             tobj_template, tobj_size,
                                             1, NULL);
    if (objects) {
        object = objects[0];
        nss_ZFreeIf(objects);
    }
    return object;
}

NSS_IMPLEMENT nssCryptokiObject *
nssToken_ImportCRL(
    NSSToken *token,
    nssSession *sessionOpt,
    NSSDER *subject,
    NSSDER *encoding,
    PRBool isKRL,
    NSSUTF8 *url,
    PRBool asTokenObject)
{
    nssCryptokiObject *object;
    CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL;
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE crl_tmpl[6];
    CK_ULONG crlsize;

    NSS_CK_TEMPLATE_START(crl_tmpl, attr, crlsize);
    if (asTokenObject) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    } else {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
    }
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, crlobjc);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encoding);
    NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NSS_URL, url);
    if (isKRL) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_true);
    } else {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_NSS_KRL, &g_ck_false);
    }
    NSS_CK_TEMPLATE_FINISH(crl_tmpl, attr, crlsize);

    /* import the crl object onto the token */
    object = import_object(token, sessionOpt, crl_tmpl, crlsize);
    if (object && token->cache) {
        nssTokenObjectCache_ImportObject(token->cache, object, crlobjc,
                                         crl_tmpl, crlsize);
    }
    return object;
}

NSS_IMPLEMENT nssCryptokiObject **
nssToken_FindCRLsBySubject(
    NSSToken *token,
    nssSession *sessionOpt,
    NSSDER *subject,
    nssTokenSearchType searchType,
    PRUint32 maximumOpt,
    PRStatus *statusOpt)
{
    CK_OBJECT_CLASS crlobjc = CKO_NSS_CRL;
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE crlobj_template[3];
    CK_ULONG crlobj_size;
    nssCryptokiObject **objects = NULL;
    nssSession *session = sessionOpt ? sessionOpt : token->defaultSession;

    /* Don't ask the module to use an invalid session handle. */
    if (!session || session->handle == CK_INVALID_SESSION) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        return objects;
    }

    NSS_CK_TEMPLATE_START(crlobj_template, attr, crlobj_size);
    if (searchType == nssTokenSearchType_SessionOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
    } else if (searchType == nssTokenSearchType_TokenOnly ||
               searchType == nssTokenSearchType_TokenForced) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    }
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_CLASS, crlobjc);
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
    NSS_CK_TEMPLATE_FINISH(crlobj_template, attr, crlobj_size);

    objects = nssToken_FindObjectsByTemplate(token, session,
                                             crlobj_template, crlobj_size,
                                             maximumOpt, statusOpt);
    return objects;
}

NSS_IMPLEMENT PRStatus
nssToken_GetCachedObjectAttributes(
    NSSToken *token,
    NSSArena *arenaOpt,
    nssCryptokiObject *object,
    CK_OBJECT_CLASS objclass,
    CK_ATTRIBUTE_PTR atemplate,
    CK_ULONG atlen)
{
    if (!token->cache) {
        return PR_FAILURE;
    }
    return nssTokenObjectCache_GetObjectAttributes(token->cache, arenaOpt,
                                                   object, objclass,
                                                   atemplate, atlen);
}

NSS_IMPLEMENT NSSItem *
nssToken_Digest(
    NSSToken *tok,
    nssSession *sessionOpt,
    NSSAlgorithmAndParameters *ap,
    NSSItem *data,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    CK_RV ckrv;
    CK_ULONG digestLen;
    CK_BYTE_PTR digest;
    NSSItem *rvItem = NULL;
    void *epv = nssToken_GetCryptokiEPV(tok);
    nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession;

    /* Don't ask the module to use an invalid session handle. */
    if (!session || session->handle == CK_INVALID_SESSION) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        return rvItem;
    }

    nssSession_EnterMonitor(session);
    ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism);
    if (ckrv != CKR_OK) {
        nssSession_ExitMonitor(session);
        return NULL;
    }
#if 0
    /* XXX the standard says this should work, but it doesn't */
    ckrv = CKAPI(epv)->C_Digest(session->handle, NULL, 0, NULL, &digestLen);
    if (ckrv != CKR_OK) {
	nssSession_ExitMonitor(session);
	return NULL;
    }
#endif
    digestLen = 0; /* XXX for now */
    digest = NULL;
    if (rvOpt) {
        if (rvOpt->size > 0 && rvOpt->size < digestLen) {
            nssSession_ExitMonitor(session);
            /* the error should be bad args */
            return NULL;
        }
        if (rvOpt->data) {
            digest = rvOpt->data;
        }
        digestLen = rvOpt->size;
    }
    if (!digest) {
        digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen);
        if (!digest) {
            nssSession_ExitMonitor(session);
            return NULL;
        }
    }
    ckrv = CKAPI(epv)->C_Digest(session->handle,
                                (CK_BYTE_PTR)data->data,
                                (CK_ULONG)data->size,
                                (CK_BYTE_PTR)digest,
                                &digestLen);
    nssSession_ExitMonitor(session);
    if (ckrv != CKR_OK) {
        nss_ZFreeIf(digest);
        return NULL;
    }
    if (!rvOpt) {
        rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest);
    }
    return rvItem;
}

NSS_IMPLEMENT PRStatus
nssToken_BeginDigest(
    NSSToken *tok,
    nssSession *sessionOpt,
    NSSAlgorithmAndParameters *ap)
{
    CK_RV ckrv;
    void *epv = nssToken_GetCryptokiEPV(tok);
    nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession;

    /* Don't ask the module to use an invalid session handle. */
    if (!session || session->handle == CK_INVALID_SESSION) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        return PR_FAILURE;
    }

    nssSession_EnterMonitor(session);
    ckrv = CKAPI(epv)->C_DigestInit(session->handle, &ap->mechanism);
    nssSession_ExitMonitor(session);
    return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
}

NSS_IMPLEMENT PRStatus
nssToken_ContinueDigest(
    NSSToken *tok,
    nssSession *sessionOpt,
    NSSItem *item)
{
    CK_RV ckrv;
    void *epv = nssToken_GetCryptokiEPV(tok);
    nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession;

    /* Don't ask the module to use an invalid session handle. */
    if (!session || session->handle == CK_INVALID_SESSION) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        return PR_FAILURE;
    }

    nssSession_EnterMonitor(session);
    ckrv = CKAPI(epv)->C_DigestUpdate(session->handle,
                                      (CK_BYTE_PTR)item->data,
                                      (CK_ULONG)item->size);
    nssSession_ExitMonitor(session);
    return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
}

NSS_IMPLEMENT NSSItem *
nssToken_FinishDigest(
    NSSToken *tok,
    nssSession *sessionOpt,
    NSSItem *rvOpt,
    NSSArena *arenaOpt)
{
    CK_RV ckrv;
    CK_ULONG digestLen;
    CK_BYTE_PTR digest;
    NSSItem *rvItem = NULL;
    void *epv = nssToken_GetCryptokiEPV(tok);
    nssSession *session = (sessionOpt) ? sessionOpt : tok->defaultSession;

    /* Don't ask the module to use an invalid session handle. */
    if (!session || session->handle == CK_INVALID_SESSION) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        return NULL;
    }

    nssSession_EnterMonitor(session);
    ckrv = CKAPI(epv)->C_DigestFinal(session->handle, NULL, &digestLen);
    if (ckrv != CKR_OK || digestLen == 0) {
        nssSession_ExitMonitor(session);
        return NULL;
    }
    digest = NULL;
    if (rvOpt) {
        if (rvOpt->size > 0 && rvOpt->size < digestLen) {
            nssSession_ExitMonitor(session);
            /* the error should be bad args */
            return NULL;
        }
        if (rvOpt->data) {
            digest = rvOpt->data;
        }
        digestLen = rvOpt->size;
    }
    if (!digest) {
        digest = (CK_BYTE_PTR)nss_ZAlloc(arenaOpt, digestLen);
        if (!digest) {
            nssSession_ExitMonitor(session);
            return NULL;
        }
    }
    ckrv = CKAPI(epv)->C_DigestFinal(session->handle, digest, &digestLen);
    nssSession_ExitMonitor(session);
    if (ckrv != CKR_OK) {
        nss_ZFreeIf(digest);
        return NULL;
    }
    if (!rvOpt) {
        rvItem = nssItem_Create(arenaOpt, NULL, digestLen, (void *)digest);
    }
    return rvItem;
}

NSS_IMPLEMENT PRBool
nssToken_IsPresent(
    NSSToken *token)
{
    return nssSlot_IsTokenPresent(token->slot);
}

/* Sigh.  The methods to find objects declared above cause problems with
 * the low-level object cache in the softoken -- the objects are found in
 * toto, then one wave of GetAttributes is done, then another.  Having a
 * large number of objects causes the cache to be thrashed, as the objects
 * are gone before there's any chance to ask for their attributes.
 * So, for now, bringing back traversal methods for certs.  This way all of
 * the cert's attributes can be grabbed immediately after finding it,
 * increasing the likelihood that the cache takes care of it.
 */
NSS_IMPLEMENT PRStatus
nssToken_TraverseCertificates(
    NSSToken *token,
    nssSession *sessionOpt,
    nssTokenSearchType searchType,
    PRStatus (*callback)(nssCryptokiObject *instance, void *arg),
    void *arg)
{
    CK_RV ckrv;
    CK_ULONG count;
    CK_OBJECT_HANDLE *objectHandles;
    CK_ATTRIBUTE_PTR attr;
    CK_ATTRIBUTE cert_template[2];
    CK_ULONG ctsize;
    NSSArena *arena;
    PRUint32 arraySize, numHandles;
    nssCryptokiObject **objects;
    void *epv = nssToken_GetCryptokiEPV(token);
    nssSession *session = (sessionOpt) ? sessionOpt : token->defaultSession;

    /* Don't ask the module to use an invalid session handle. */
    if (!session || session->handle == CK_INVALID_SESSION) {
        PORT_SetError(SEC_ERROR_NO_TOKEN);
        return PR_FAILURE;
    }

    /* template for all certs */
    NSS_CK_TEMPLATE_START(cert_template, attr, ctsize);
    if (searchType == nssTokenSearchType_SessionOnly) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
    } else if (searchType == nssTokenSearchType_TokenOnly ||
               searchType == nssTokenSearchType_TokenForced) {
        NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
    }
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert);
    NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);

    /* the arena is only for the array of object handles */
    arena = nssArena_Create();
    if (!arena) {
        return PR_FAILURE;
    }
    arraySize = OBJECT_STACK_SIZE;
    numHandles = 0;
    objectHandles = nss_ZNEWARRAY(arena, CK_OBJECT_HANDLE, arraySize);
    if (!objectHandles) {
        goto loser;
    }
    nssSession_EnterMonitor(session); /* ==== session lock === */
    /* Initialize the find with the template */
    ckrv = CKAPI(epv)->C_FindObjectsInit(session->handle,
                                         cert_template, ctsize);
    if (ckrv != CKR_OK) {
        nssSession_ExitMonitor(session);
        goto loser;
    }
    while (PR_TRUE) {
        /* Issue the find for up to arraySize - numHandles objects */
        ckrv = CKAPI(epv)->C_FindObjects(session->handle,
                                         objectHandles + numHandles,
                                         arraySize - numHandles,
                                         &count);
        if (ckrv != CKR_OK) {
            nssSession_ExitMonitor(session);
            goto loser;
        }
        /* bump the number of found objects */
        numHandles += count;
        if (numHandles < arraySize) {
            break;
        }
        /* the array is filled, double it and continue */
        arraySize *= 2;
        objectHandles = nss_ZREALLOCARRAY(objectHandles,
                                          CK_OBJECT_HANDLE,
                                          arraySize);
        if (!objectHandles) {
            nssSession_ExitMonitor(session);
            goto loser;
        }
    }
    ckrv = CKAPI(epv)->C_FindObjectsFinal(session->handle);
    nssSession_ExitMonitor(session); /* ==== end session lock === */
    if (ckrv != CKR_OK) {
        goto loser;
    }
    if (numHandles > 0) {
        objects = create_objects_from_handles(token, session,
                                              objectHandles, numHandles);
        if (objects) {
            nssCryptokiObject **op;
            for (op = objects; *op; op++) {
                (void)(*callback)(*op, arg);
            }
            nss_ZFreeIf(objects);
        }
    }
    nssArena_Destroy(arena);
    return PR_SUCCESS;
loser:
    nssArena_Destroy(arena);
    return PR_FAILURE;
}

NSS_IMPLEMENT PRBool
nssToken_IsPrivateKeyAvailable(
    NSSToken *token,
    NSSCertificate *c,
    nssCryptokiObject *instance)
{
    CK_OBJECT_CLASS theClass;

    if (token == NULL)
        return PR_FALSE;
    if (c == NULL)
        return PR_FALSE;

    theClass = CKO_PRIVATE_KEY;
    if (!nssSlot_IsLoggedIn(token->slot)) {
        theClass = CKO_PUBLIC_KEY;
    }
    if (PK11_MatchItem(token->pk11slot, instance->handle, theClass) !=
        CK_INVALID_HANDLE) {
        return PR_TRUE;
    }
    return PR_FALSE;
}
