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

/*
 * object.c
 *
 * This file implements the NSSCKFWObject type and methods.
 */

#ifndef CK_T
#include "ck.h"
#endif /* CK_T */

/*
 * NSSCKFWObject
 *
 * -- create/destroy --
 *  nssCKFWObject_Create
 *  nssCKFWObject_Finalize
 *  nssCKFWObject_Destroy
 *
 * -- public accessors --
 *  NSSCKFWObject_GetMDObject
 *  NSSCKFWObject_GetArena
 *  NSSCKFWObject_IsTokenObject
 *  NSSCKFWObject_GetAttributeCount
 *  NSSCKFWObject_GetAttributeTypes
 *  NSSCKFWObject_GetAttributeSize
 *  NSSCKFWObject_GetAttribute
 *  NSSCKFWObject_SetAttribute
 *  NSSCKFWObject_GetObjectSize
 *
 * -- implement public accessors --
 *  nssCKFWObject_GetMDObject
 *  nssCKFWObject_GetArena
 *
 * -- private accessors --
 *  nssCKFWObject_SetHandle
 *  nssCKFWObject_GetHandle
 *
 * -- module fronts --
 *  nssCKFWObject_IsTokenObject
 *  nssCKFWObject_GetAttributeCount
 *  nssCKFWObject_GetAttributeTypes
 *  nssCKFWObject_GetAttributeSize
 *  nssCKFWObject_GetAttribute
 *  nssCKFWObject_SetAttribute
 *  nssCKFWObject_GetObjectSize
 */

struct NSSCKFWObjectStr {
    NSSCKFWMutex *mutex; /* merely to serialise the MDObject calls */
    NSSArena *arena;
    NSSCKMDObject *mdObject;
    NSSCKMDSession *mdSession;
    NSSCKFWSession *fwSession;
    NSSCKMDToken *mdToken;
    NSSCKFWToken *fwToken;
    NSSCKMDInstance *mdInstance;
    NSSCKFWInstance *fwInstance;
    CK_OBJECT_HANDLE hObject;
};

#ifdef DEBUG
/*
 * But first, the pointer-tracking stuff.
 *
 * NOTE: the pointer-tracking support in NSS/base currently relies
 * upon NSPR's CallOnce support.  That, however, relies upon NSPR's
 * locking, which is tied into the runtime.  We need a pointer-tracker
 * implementation that uses the locks supplied through C_Initialize.
 * That support, however, can be filled in later.  So for now, I'll
 * just do this routines as no-ops.
 */

static CK_RV
object_add_pointer(
    const NSSCKFWObject *fwObject)
{
    return CKR_OK;
}

static CK_RV
object_remove_pointer(
    const NSSCKFWObject *fwObject)
{
    return CKR_OK;
}

NSS_IMPLEMENT CK_RV
nssCKFWObject_verifyPointer(
    const NSSCKFWObject *fwObject)
{
    return CKR_OK;
}

#endif /* DEBUG */

/*
 * nssCKFWObject_Create
 *
 */
NSS_IMPLEMENT NSSCKFWObject *
nssCKFWObject_Create(
    NSSArena *arena,
    NSSCKMDObject *mdObject,
    NSSCKFWSession *fwSession,
    NSSCKFWToken *fwToken,
    NSSCKFWInstance *fwInstance,
    CK_RV *pError)
{
    NSSCKFWObject *fwObject;
    nssCKFWHash *mdObjectHash;

#ifdef NSSDEBUG
    if (!pError) {
        return (NSSCKFWObject *)NULL;
    }

    if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
        *pError = CKR_ARGUMENTS_BAD;
        return (NSSCKFWObject *)NULL;
    }
#endif /* NSSDEBUG */

    if (!fwToken) {
        *pError = CKR_ARGUMENTS_BAD;
        return (NSSCKFWObject *)NULL;
    }
    mdObjectHash = nssCKFWToken_GetMDObjectHash(fwToken);
    if (!mdObjectHash) {
        *pError = CKR_GENERAL_ERROR;
        return (NSSCKFWObject *)NULL;
    }

    if (nssCKFWHash_Exists(mdObjectHash, mdObject)) {
        fwObject = nssCKFWHash_Lookup(mdObjectHash, mdObject);
        return fwObject;
    }

    fwObject = nss_ZNEW(arena, NSSCKFWObject);
    if (!fwObject) {
        *pError = CKR_HOST_MEMORY;
        return (NSSCKFWObject *)NULL;
    }

    fwObject->arena = arena;
    fwObject->mdObject = mdObject;
    fwObject->fwSession = fwSession;

    if (fwSession) {
        fwObject->mdSession = nssCKFWSession_GetMDSession(fwSession);
    }

    fwObject->fwToken = fwToken;
    fwObject->mdToken = nssCKFWToken_GetMDToken(fwToken);
    fwObject->fwInstance = fwInstance;
    fwObject->mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
    fwObject->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
    if (!fwObject->mutex) {
        if (CKR_OK == *pError) {
            *pError = CKR_GENERAL_ERROR;
        }
        nss_ZFreeIf(fwObject);
        return (NSSCKFWObject *)NULL;
    }

    *pError = nssCKFWHash_Add(mdObjectHash, mdObject, fwObject);
    if (CKR_OK != *pError) {
        nss_ZFreeIf(fwObject);
        return (NSSCKFWObject *)NULL;
    }

#ifdef DEBUG
    *pError = object_add_pointer(fwObject);
    if (CKR_OK != *pError) {
        nssCKFWHash_Remove(mdObjectHash, mdObject);
        nss_ZFreeIf(fwObject);
        return (NSSCKFWObject *)NULL;
    }
#endif /* DEBUG */

    *pError = CKR_OK;
    return fwObject;
}

/*
 * nssCKFWObject_Finalize
 *
 */
NSS_IMPLEMENT void
nssCKFWObject_Finalize(
    NSSCKFWObject *fwObject,
    PRBool removeFromHash)
{
    nssCKFWHash *mdObjectHash;

#ifdef NSSDEBUG
    if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
        return;
    }
#endif /* NSSDEBUG */

    (void)nssCKFWMutex_Destroy(fwObject->mutex);

    if (fwObject->mdObject->Finalize) {
        fwObject->mdObject->Finalize(fwObject->mdObject, fwObject,
                                     fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
                                     fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
    }

    if (removeFromHash) {
        mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken);
        if (mdObjectHash) {
            nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject);
        }
    }

    if (fwObject->fwSession) {
        nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
    }
    nss_ZFreeIf(fwObject);

#ifdef DEBUG
    (void)object_remove_pointer(fwObject);
#endif /* DEBUG */

    return;
}

/*
 * nssCKFWObject_Destroy
 *
 */
NSS_IMPLEMENT void
nssCKFWObject_Destroy(
    NSSCKFWObject *fwObject)
{
    nssCKFWHash *mdObjectHash;

#ifdef NSSDEBUG
    if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
        return;
    }
#endif /* NSSDEBUG */

    (void)nssCKFWMutex_Destroy(fwObject->mutex);

    if (fwObject->mdObject->Destroy) {
        fwObject->mdObject->Destroy(fwObject->mdObject, fwObject,
                                    fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
                                    fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
    }

    mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken);
    if (mdObjectHash) {
        nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject);
    }

    if (fwObject->fwSession) {
        nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
    }
    nss_ZFreeIf(fwObject);

#ifdef DEBUG
    (void)object_remove_pointer(fwObject);
#endif /* DEBUG */

    return;
}

/*
 * nssCKFWObject_GetMDObject
 *
 */
NSS_IMPLEMENT NSSCKMDObject *
nssCKFWObject_GetMDObject(
    NSSCKFWObject *fwObject)
{
#ifdef NSSDEBUG
    if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
        return (NSSCKMDObject *)NULL;
    }
#endif /* NSSDEBUG */

    return fwObject->mdObject;
}

/*
 * nssCKFWObject_GetArena
 *
 */
NSS_IMPLEMENT NSSArena *
nssCKFWObject_GetArena(
    NSSCKFWObject *fwObject,
    CK_RV *pError)
{
#ifdef NSSDEBUG
    if (!pError) {
        return (NSSArena *)NULL;
    }

    *pError = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != *pError) {
        return (NSSArena *)NULL;
    }
#endif /* NSSDEBUG */

    return fwObject->arena;
}

/*
 * nssCKFWObject_SetHandle
 *
 */
NSS_IMPLEMENT CK_RV
nssCKFWObject_SetHandle(
    NSSCKFWObject *fwObject,
    CK_OBJECT_HANDLE hObject)
{
#ifdef NSSDEBUG
    CK_RV error = CKR_OK;
#endif /* NSSDEBUG */

#ifdef NSSDEBUG
    error = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != error) {
        return error;
    }
#endif /* NSSDEBUG */

    if ((CK_OBJECT_HANDLE)0 != fwObject->hObject) {
        return CKR_GENERAL_ERROR;
    }

    fwObject->hObject = hObject;

    return CKR_OK;
}

/*
 * nssCKFWObject_GetHandle
 *
 */
NSS_IMPLEMENT CK_OBJECT_HANDLE
nssCKFWObject_GetHandle(
    NSSCKFWObject *fwObject)
{
#ifdef NSSDEBUG
    if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
        return (CK_OBJECT_HANDLE)0;
    }
#endif /* NSSDEBUG */

    return fwObject->hObject;
}

/*
 * nssCKFWObject_IsTokenObject
 *
 */
NSS_IMPLEMENT CK_BBOOL
nssCKFWObject_IsTokenObject(
    NSSCKFWObject *fwObject)
{
    CK_BBOOL b = CK_FALSE;

#ifdef NSSDEBUG
    if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
        return CK_FALSE;
    }
#endif /* NSSDEBUG */

    if (!fwObject->mdObject->IsTokenObject) {
        NSSItem item;
        NSSItem *pItem;
        CK_RV rv = CKR_OK;

        item.data = (void *)&b;
        item.size = sizeof(b);

        pItem = nssCKFWObject_GetAttribute(fwObject, CKA_TOKEN, &item,
                                           (NSSArena *)NULL, &rv);
        if (!pItem) {
            /* Error of some type */
            b = CK_FALSE;
            goto done;
        }

        goto done;
    }

    b = fwObject->mdObject->IsTokenObject(fwObject->mdObject, fwObject,
                                          fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
                                          fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);

done:
    return b;
}

/*
 * nssCKFWObject_GetAttributeCount
 *
 */
NSS_IMPLEMENT CK_ULONG
nssCKFWObject_GetAttributeCount(
    NSSCKFWObject *fwObject,
    CK_RV *pError)
{
    CK_ULONG rv;

#ifdef NSSDEBUG
    if (!pError) {
        return (CK_ULONG)0;
    }

    *pError = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != *pError) {
        return (CK_ULONG)0;
    }
#endif /* NSSDEBUG */

    if (!fwObject->mdObject->GetAttributeCount) {
        *pError = CKR_GENERAL_ERROR;
        return (CK_ULONG)0;
    }

    *pError = nssCKFWMutex_Lock(fwObject->mutex);
    if (CKR_OK != *pError) {
        return (CK_ULONG)0;
    }

    rv = fwObject->mdObject->GetAttributeCount(fwObject->mdObject, fwObject,
                                               fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
                                               fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
                                               pError);

    (void)nssCKFWMutex_Unlock(fwObject->mutex);
    return rv;
}

/*
 * nssCKFWObject_GetAttributeTypes
 *
 */
NSS_IMPLEMENT CK_RV
nssCKFWObject_GetAttributeTypes(
    NSSCKFWObject *fwObject,
    CK_ATTRIBUTE_TYPE_PTR typeArray,
    CK_ULONG ulCount)
{
    CK_RV error = CKR_OK;

#ifdef NSSDEBUG
    error = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != error) {
        return error;
    }

    if ((CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray) {
        return CKR_ARGUMENTS_BAD;
    }
#endif /* NSSDEBUG */

    if (!fwObject->mdObject->GetAttributeTypes) {
        return CKR_GENERAL_ERROR;
    }

    error = nssCKFWMutex_Lock(fwObject->mutex);
    if (CKR_OK != error) {
        return error;
    }

    error = fwObject->mdObject->GetAttributeTypes(fwObject->mdObject, fwObject,
                                                  fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
                                                  fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
                                                  typeArray, ulCount);

    (void)nssCKFWMutex_Unlock(fwObject->mutex);
    return error;
}

/*
 * nssCKFWObject_GetAttributeSize
 *
 */
NSS_IMPLEMENT CK_ULONG
nssCKFWObject_GetAttributeSize(
    NSSCKFWObject *fwObject,
    CK_ATTRIBUTE_TYPE attribute,
    CK_RV *pError)
{
    CK_ULONG rv;

#ifdef NSSDEBUG
    if (!pError) {
        return (CK_ULONG)0;
    }

    *pError = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != *pError) {
        return (CK_ULONG)0;
    }
#endif /* NSSDEBUG */

    if (!fwObject->mdObject->GetAttributeSize) {
        *pError = CKR_GENERAL_ERROR;
        return (CK_ULONG)0;
    }

    *pError = nssCKFWMutex_Lock(fwObject->mutex);
    if (CKR_OK != *pError) {
        return (CK_ULONG)0;
    }

    rv = fwObject->mdObject->GetAttributeSize(fwObject->mdObject, fwObject,
                                              fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
                                              fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
                                              attribute, pError);

    (void)nssCKFWMutex_Unlock(fwObject->mutex);
    return rv;
}

/*
 * nssCKFWObject_GetAttribute
 *
 * Usual NSS allocation rules:
 * If itemOpt is not NULL, it will be returned; otherwise an NSSItem
 * will be allocated.  If itemOpt is not NULL but itemOpt->data is,
 * the buffer will be allocated; otherwise, the buffer will be used.
 * Any allocations will come from the optional arena, if one is
 * specified.
 */
NSS_IMPLEMENT NSSItem *
nssCKFWObject_GetAttribute(
    NSSCKFWObject *fwObject,
    CK_ATTRIBUTE_TYPE attribute,
    NSSItem *itemOpt,
    NSSArena *arenaOpt,
    CK_RV *pError)
{
    NSSItem *rv = (NSSItem *)NULL;
    NSSCKFWItem mdItem;

#ifdef NSSDEBUG
    if (!pError) {
        return (NSSItem *)NULL;
    }

    *pError = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != *pError) {
        return (NSSItem *)NULL;
    }
#endif /* NSSDEBUG */

    if (!fwObject->mdObject->GetAttribute) {
        *pError = CKR_GENERAL_ERROR;
        return (NSSItem *)NULL;
    }

    *pError = nssCKFWMutex_Lock(fwObject->mutex);
    if (CKR_OK != *pError) {
        return (NSSItem *)NULL;
    }

    mdItem = fwObject->mdObject->GetAttribute(fwObject->mdObject, fwObject,
                                              fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
                                              fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
                                              attribute, pError);

    if (!mdItem.item) {
        if (CKR_OK == *pError) {
            *pError = CKR_GENERAL_ERROR;
        }

        goto done;
    }

    if (!itemOpt) {
        rv = nss_ZNEW(arenaOpt, NSSItem);
        if (!rv) {
            *pError = CKR_HOST_MEMORY;
            goto done;
        }
    } else {
        rv = itemOpt;
    }

    if (!rv->data) {
        rv->size = mdItem.item->size;
        rv->data = nss_ZAlloc(arenaOpt, rv->size);
        if (!rv->data) {
            *pError = CKR_HOST_MEMORY;
            if (!itemOpt) {
                nss_ZFreeIf(rv);
            }
            rv = (NSSItem *)NULL;
            goto done;
        }
    } else {
        if (rv->size >= mdItem.item->size) {
            rv->size = mdItem.item->size;
        } else {
            *pError = CKR_BUFFER_TOO_SMALL;
            /* Should we set rv->size to mdItem->size? */
            /* rv can't have been allocated */
            rv = (NSSItem *)NULL;
            goto done;
        }
    }

    (void)nsslibc_memcpy(rv->data, mdItem.item->data, rv->size);

    if (PR_TRUE == mdItem.needsFreeing) {
        PR_ASSERT(fwObject->mdObject->FreeAttribute);
        if (fwObject->mdObject->FreeAttribute) {
            *pError = fwObject->mdObject->FreeAttribute(&mdItem);
        }
    }

done:
    (void)nssCKFWMutex_Unlock(fwObject->mutex);
    return rv;
}

/*
 * nssCKFWObject_SetAttribute
 *
 */
NSS_IMPLEMENT CK_RV
nssCKFWObject_SetAttribute(
    NSSCKFWObject *fwObject,
    NSSCKFWSession *fwSession,
    CK_ATTRIBUTE_TYPE attribute,
    NSSItem *value)
{
    CK_RV error = CKR_OK;

#ifdef NSSDEBUG
    error = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != error) {
        return error;
    }
#endif /* NSSDEBUG */

    if (CKA_TOKEN == attribute) {
        /*
         * We're changing from a session object to a token object or
         * vice-versa.
         */

        CK_ATTRIBUTE a;
        NSSCKFWObject *newFwObject;
        NSSCKFWObject swab;

        a.type = CKA_TOKEN;
        a.pValue = value->data;
        a.ulValueLen = value->size;

        newFwObject = nssCKFWSession_CopyObject(fwSession, fwObject,
                                                &a, 1, &error);
        if (!newFwObject) {
            if (CKR_OK == error) {
                error = CKR_GENERAL_ERROR;
            }
            return error;
        }

        /*
         * Actually, I bet the locking is worse than this.. this part of
         * the code could probably use some scrutiny and reworking.
         */
        error = nssCKFWMutex_Lock(fwObject->mutex);
        if (CKR_OK != error) {
            nssCKFWObject_Destroy(newFwObject);
            return error;
        }

        error = nssCKFWMutex_Lock(newFwObject->mutex);
        if (CKR_OK != error) {
            nssCKFWMutex_Unlock(fwObject->mutex);
            nssCKFWObject_Destroy(newFwObject);
            return error;
        }

        /*
         * Now, we have our new object, but it has a new fwObject pointer,
         * while we have to keep the existing one.  So quick swap the contents.
         */
        swab = *fwObject;
        *fwObject = *newFwObject;
        *newFwObject = swab;

        /* But keep the mutexes the same */
        swab.mutex = fwObject->mutex;
        fwObject->mutex = newFwObject->mutex;
        newFwObject->mutex = swab.mutex;

        (void)nssCKFWMutex_Unlock(newFwObject->mutex);
        (void)nssCKFWMutex_Unlock(fwObject->mutex);

        /*
         * Either remove or add this to the list of session objects
         */

        if (CK_FALSE == *(CK_BBOOL *)value->data) {
            /*
             * New one is a session object, except since we "stole" the fwObject, it's
             * not in the list.  Add it.
             */
            nssCKFWSession_RegisterSessionObject(fwSession, fwObject);
        } else {
            /*
             * New one is a token object, except since we "stole" the fwObject, it's
             * in the list.  Remove it.
             */
            if (fwObject->fwSession) {
                nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
            }
        }

        /*
         * Now delete the old object.  Remember the names have changed.
         */
        nssCKFWObject_Destroy(newFwObject);

        return CKR_OK;
    } else {
        /*
         * An "ordinary" change.
         */
        if (!fwObject->mdObject->SetAttribute) {
            /* We could fake it with copying, like above.. later */
            return CKR_ATTRIBUTE_READ_ONLY;
        }

        error = nssCKFWMutex_Lock(fwObject->mutex);
        if (CKR_OK != error) {
            return error;
        }

        error = fwObject->mdObject->SetAttribute(fwObject->mdObject, fwObject,
                                                 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
                                                 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
                                                 attribute, value);

        (void)nssCKFWMutex_Unlock(fwObject->mutex);

        return error;
    }
}

/*
 * nssCKFWObject_GetObjectSize
 *
 */
NSS_IMPLEMENT CK_ULONG
nssCKFWObject_GetObjectSize(
    NSSCKFWObject *fwObject,
    CK_RV *pError)
{
    CK_ULONG rv;

#ifdef NSSDEBUG
    if (!pError) {
        return (CK_ULONG)0;
    }

    *pError = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != *pError) {
        return (CK_ULONG)0;
    }
#endif /* NSSDEBUG */

    if (!fwObject->mdObject->GetObjectSize) {
        *pError = CKR_INFORMATION_SENSITIVE;
        return (CK_ULONG)0;
    }

    *pError = nssCKFWMutex_Lock(fwObject->mutex);
    if (CKR_OK != *pError) {
        return (CK_ULONG)0;
    }

    rv = fwObject->mdObject->GetObjectSize(fwObject->mdObject, fwObject,
                                           fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
                                           fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
                                           pError);

    (void)nssCKFWMutex_Unlock(fwObject->mutex);
    return rv;
}

/*
 * NSSCKFWObject_GetMDObject
 *
 */
NSS_IMPLEMENT NSSCKMDObject *
NSSCKFWObject_GetMDObject(
    NSSCKFWObject *fwObject)
{
#ifdef DEBUG
    if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
        return (NSSCKMDObject *)NULL;
    }
#endif /* DEBUG */

    return nssCKFWObject_GetMDObject(fwObject);
}

/*
 * NSSCKFWObject_GetArena
 *
 */
NSS_IMPLEMENT NSSArena *
NSSCKFWObject_GetArena(
    NSSCKFWObject *fwObject,
    CK_RV *pError)
{
#ifdef DEBUG
    if (!pError) {
        return (NSSArena *)NULL;
    }

    *pError = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != *pError) {
        return (NSSArena *)NULL;
    }
#endif /* DEBUG */

    return nssCKFWObject_GetArena(fwObject, pError);
}

/*
 * NSSCKFWObject_IsTokenObject
 *
 */
NSS_IMPLEMENT CK_BBOOL
NSSCKFWObject_IsTokenObject(
    NSSCKFWObject *fwObject)
{
#ifdef DEBUG
    if (CKR_OK != nssCKFWObject_verifyPointer(fwObject)) {
        return CK_FALSE;
    }
#endif /* DEBUG */

    return nssCKFWObject_IsTokenObject(fwObject);
}

/*
 * NSSCKFWObject_GetAttributeCount
 *
 */
NSS_IMPLEMENT CK_ULONG
NSSCKFWObject_GetAttributeCount(
    NSSCKFWObject *fwObject,
    CK_RV *pError)
{
#ifdef DEBUG
    if (!pError) {
        return (CK_ULONG)0;
    }

    *pError = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != *pError) {
        return (CK_ULONG)0;
    }
#endif /* DEBUG */

    return nssCKFWObject_GetAttributeCount(fwObject, pError);
}

/*
 * NSSCKFWObject_GetAttributeTypes
 *
 */
NSS_IMPLEMENT CK_RV
NSSCKFWObject_GetAttributeTypes(
    NSSCKFWObject *fwObject,
    CK_ATTRIBUTE_TYPE_PTR typeArray,
    CK_ULONG ulCount)
{
#ifdef DEBUG
    CK_RV error = CKR_OK;

    error = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != error) {
        return error;
    }

    if ((CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray) {
        return CKR_ARGUMENTS_BAD;
    }
#endif /* DEBUG */

    return nssCKFWObject_GetAttributeTypes(fwObject, typeArray, ulCount);
}

/*
 * NSSCKFWObject_GetAttributeSize
 *
 */
NSS_IMPLEMENT CK_ULONG
NSSCKFWObject_GetAttributeSize(
    NSSCKFWObject *fwObject,
    CK_ATTRIBUTE_TYPE attribute,
    CK_RV *pError)
{
#ifdef DEBUG
    if (!pError) {
        return (CK_ULONG)0;
    }

    *pError = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != *pError) {
        return (CK_ULONG)0;
    }
#endif /* DEBUG */

    return nssCKFWObject_GetAttributeSize(fwObject, attribute, pError);
}

/*
 * NSSCKFWObject_GetAttribute
 *
 */
NSS_IMPLEMENT NSSItem *
NSSCKFWObject_GetAttribute(
    NSSCKFWObject *fwObject,
    CK_ATTRIBUTE_TYPE attribute,
    NSSItem *itemOpt,
    NSSArena *arenaOpt,
    CK_RV *pError)
{
#ifdef DEBUG
    if (!pError) {
        return (NSSItem *)NULL;
    }

    *pError = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != *pError) {
        return (NSSItem *)NULL;
    }
#endif /* DEBUG */

    return nssCKFWObject_GetAttribute(fwObject, attribute, itemOpt, arenaOpt, pError);
}

/*
 * NSSCKFWObject_GetObjectSize
 *
 */
NSS_IMPLEMENT CK_ULONG
NSSCKFWObject_GetObjectSize(
    NSSCKFWObject *fwObject,
    CK_RV *pError)
{
#ifdef DEBUG
    if (!pError) {
        return (CK_ULONG)0;
    }

    *pError = nssCKFWObject_verifyPointer(fwObject);
    if (CKR_OK != *pError) {
        return (CK_ULONG)0;
    }
#endif /* DEBUG */

    return nssCKFWObject_GetObjectSize(fwObject, pError);
}
