mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-06 09:05:45 +00:00
1047 lines
22 KiB
C
1047 lines
22 KiB
C
/*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is the Netscape security libraries.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*
|
|
* Alternatively, the contents of this file may be used under the
|
|
* terms of the GNU General Public License Version 2 or later (the
|
|
* "GPL"), in which case the provisions of the GPL are applicable
|
|
* instead of those above. If you wish to allow use of your
|
|
* version of this file only under the terms of the GPL and not to
|
|
* allow others to use your version of this file under the MPL,
|
|
* indicate your decision by deleting the provisions above and
|
|
* replace them with the notice and other provisions required by
|
|
* the GPL. If you do not delete the provisions above, a recipient
|
|
* may use your version of this file under either the MPL or the
|
|
* GPL.
|
|
*/
|
|
|
|
#ifdef DEBUG
|
|
static const char CVS_ID[] = "@(#) $RCSfile: object.c,v $ $Revision: 1.9 $ $Date: 2002/03/29 18:53:15 $ $Name: $";
|
|
#endif /* DEBUG */
|
|
|
|
/*
|
|
* 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( (CK_RV *)NULL == pError ) {
|
|
return (NSSCKFWObject *)NULL;
|
|
}
|
|
|
|
if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
|
|
*pError = CKR_ARGUMENTS_BAD;
|
|
return (NSSCKFWObject *)NULL;
|
|
}
|
|
#endif /* NSSDEBUG */
|
|
|
|
mdObjectHash = nssCKFWToken_GetMDObjectHash(fwToken);
|
|
if( (nssCKFWHash *)NULL == 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( (NSSCKFWObject *)NULL == fwObject ) {
|
|
*pError = CKR_HOST_MEMORY;
|
|
return (NSSCKFWObject *)NULL;
|
|
}
|
|
|
|
fwObject->arena = arena;
|
|
fwObject->mdObject = mdObject;
|
|
fwObject->fwSession = fwSession;
|
|
|
|
if( (NSSCKFWSession *)NULL != fwSession ) {
|
|
fwObject->mdSession = nssCKFWSession_GetMDSession(fwSession);
|
|
}
|
|
|
|
fwObject->fwToken = fwToken;
|
|
|
|
if( (NSSCKFWToken *)NULL != fwToken ) {
|
|
fwObject->mdToken = nssCKFWToken_GetMDToken(fwToken);
|
|
}
|
|
|
|
fwObject->fwInstance = fwInstance;
|
|
fwObject->mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
|
|
fwObject->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
|
|
if( (NSSCKFWMutex *)NULL == fwObject->mutex ) {
|
|
if( CKR_OK == *pError ) {
|
|
*pError = CKR_GENERAL_ERROR;
|
|
}
|
|
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
|
|
)
|
|
{
|
|
nssCKFWHash *mdObjectHash;
|
|
|
|
#ifdef NSSDEBUG
|
|
if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
|
|
return;
|
|
}
|
|
#endif /* NSSDEBUG */
|
|
|
|
(void)nssCKFWMutex_Destroy(fwObject->mutex);
|
|
|
|
if( (void *)NULL != (void *)fwObject->mdObject->Finalize ) {
|
|
fwObject->mdObject->Finalize(fwObject->mdObject, fwObject,
|
|
fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
|
|
fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
|
|
}
|
|
|
|
mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken);
|
|
if( (nssCKFWHash *)NULL != mdObjectHash ) {
|
|
nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject);
|
|
}
|
|
|
|
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( (void *)NULL != (void *)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( (nssCKFWHash *)NULL != mdObjectHash ) {
|
|
nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject);
|
|
}
|
|
|
|
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( (CK_RV *)NULL == 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( (void *)NULL == (void *)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( (NSSItem *)NULL == 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( (CK_RV *)NULL == pError ) {
|
|
return (CK_ULONG)0;
|
|
}
|
|
|
|
*pError = nssCKFWObject_verifyPointer(fwObject);
|
|
if( CKR_OK != *pError ) {
|
|
return (CK_ULONG)0;
|
|
}
|
|
#endif /* NSSDEBUG */
|
|
|
|
if( (void *)NULL == (void *)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( (void *)NULL == (void *)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( (CK_RV *)NULL == pError ) {
|
|
return (CK_ULONG)0;
|
|
}
|
|
|
|
*pError = nssCKFWObject_verifyPointer(fwObject);
|
|
if( CKR_OK != *pError ) {
|
|
return (CK_ULONG)0;
|
|
}
|
|
#endif /* NSSDEBUG */
|
|
|
|
if( (void *)NULL == (void *)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( (CK_RV *)NULL == pError ) {
|
|
return (NSSItem *)NULL;
|
|
}
|
|
|
|
*pError = nssCKFWObject_verifyPointer(fwObject);
|
|
if( CKR_OK != *pError ) {
|
|
return (NSSItem *)NULL;
|
|
}
|
|
#endif /* NSSDEBUG */
|
|
|
|
if( (void *)NULL == (void *)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( (NSSItem *)NULL == mdItem.item ) {
|
|
if( CKR_OK == *pError ) {
|
|
*pError = CKR_GENERAL_ERROR;
|
|
}
|
|
|
|
goto done;
|
|
}
|
|
|
|
if( (NSSItem *)NULL == itemOpt ) {
|
|
rv = nss_ZNEW(arenaOpt, NSSItem);
|
|
if( (NSSItem *)NULL == rv ) {
|
|
*pError = CKR_HOST_MEMORY;
|
|
goto done;
|
|
}
|
|
} else {
|
|
rv = itemOpt;
|
|
}
|
|
|
|
if( (void *)NULL == rv->data ) {
|
|
rv->size = mdItem.item->size;
|
|
rv->data = nss_ZAlloc(arenaOpt, rv->size);
|
|
if( (void *)NULL == rv->data ) {
|
|
*pError = CKR_HOST_MEMORY;
|
|
if( (NSSItem *)NULL == 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,
|
|
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(fwObject->fwSession, fwObject,
|
|
&a, 1, &error);
|
|
if( (NSSCKFWObject *)NULL == 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(fwObject->fwSession, fwObject);
|
|
} else {
|
|
/*
|
|
* New one is a token object, except since we "stole" the fwObject, it's
|
|
* in the list. Remove it.
|
|
*/
|
|
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( (void *)NULL == (void *)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( (CK_RV *)NULL == pError ) {
|
|
return (CK_ULONG)0;
|
|
}
|
|
|
|
*pError = nssCKFWObject_verifyPointer(fwObject);
|
|
if( CKR_OK != *pError ) {
|
|
return (CK_ULONG)0;
|
|
}
|
|
#endif /* NSSDEBUG */
|
|
|
|
if( (void *)NULL == (void *)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( (CK_RV *)NULL == 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( (CK_RV *)NULL == 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( (CK_RV *)NULL == 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( (CK_RV *)NULL == 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( (CK_RV *)NULL == pError ) {
|
|
return (CK_ULONG)0;
|
|
}
|
|
|
|
*pError = nssCKFWObject_verifyPointer(fwObject);
|
|
if( CKR_OK != *pError ) {
|
|
return (CK_ULONG)0;
|
|
}
|
|
#endif /* DEBUG */
|
|
|
|
return nssCKFWObject_GetObjectSize(fwObject, pError);
|
|
}
|