/* 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;
    NSSArena *localArena;
    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)
{
    NSSArena *objArena = arena;
    NSSArena *localArena = NULL;
    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;
    }

    /* session objects should have their own arena so they can be destroyed in the end. */
    if (arena == NULL) {
        localArena = objArena = NSSArena_Create();
        if (objArena == NULL) {
            *pError = CKR_HOST_MEMORY;
            return (NSSCKFWObject *)NULL;
        }
    }

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

    fwObject->arena = objArena;
    fwObject->localArena = localArena;
    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, objArena, pError);
    if (!fwObject->mutex) {
        if (CKR_OK == *pError) {
            *pError = CKR_GENERAL_ERROR;
        }
        nss_ZFreeIf(fwObject);
        if (localArena) {
            NSSArena_Destroy(localArena);
        }
        return (NSSCKFWObject *)NULL;
    }

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

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

    *pError = CKR_OK;
    return fwObject;
}

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

#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);
    }
    arena = fwObject->localArena;
    nss_ZFreeIf(fwObject);
    if (arena) {
        NSSArena_Destroy(arena);
    }

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

    return;
}

/*
 * nssCKFWObject_Destroy
 *
 */
NSS_IMPLEMENT void
nssCKFWObject_Destroy(
    NSSCKFWObject *fwObject)
{
    nssCKFWHash *mdObjectHash;
    NSSArena *arena = NULL;

#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);
    }
    arena = fwObject->localArena;
    nss_ZFreeIf(fwObject);
    if (arena) {
        NSSArena_Destroy(arena);
    }

#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;

    if (!pError) {
        return (CK_ULONG)0;
    }

    if (!fwObject || !fwObject->mdObject || !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);
}
