RetroZilla/security/nss/lib/ckfw/find.c
2018-05-19 22:01:21 +08:00

380 lines
9.6 KiB
C

/* 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/. */
/*
* find.c
*
* This file implements the nssCKFWFindObjects type and methods.
*/
#ifndef CK_H
#include "ck.h"
#endif /* CK_H */
/*
* NSSCKFWFindObjects
*
* -- create/destroy --
* nssCKFWFindObjects_Create
* nssCKFWFindObjects_Destroy
*
* -- public accessors --
* NSSCKFWFindObjects_GetMDFindObjects
*
* -- implement public accessors --
* nssCKFWFindObjects_GetMDFindObjects
*
* -- private accessors --
*
* -- module fronts --
* nssCKFWFindObjects_Next
*/
struct NSSCKFWFindObjectsStr {
NSSCKFWMutex *mutex; /* merely to serialise the MDObject calls */
NSSCKMDFindObjects *mdfo1;
NSSCKMDFindObjects *mdfo2;
NSSCKFWSession *fwSession;
NSSCKMDSession *mdSession;
NSSCKFWToken *fwToken;
NSSCKMDToken *mdToken;
NSSCKFWInstance *fwInstance;
NSSCKMDInstance *mdInstance;
NSSCKMDFindObjects *mdFindObjects; /* varies */
};
#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 these routines as no-ops.
*/
static CK_RV
findObjects_add_pointer
(
const NSSCKFWFindObjects *fwFindObjects
)
{
return CKR_OK;
}
static CK_RV
findObjects_remove_pointer
(
const NSSCKFWFindObjects *fwFindObjects
)
{
return CKR_OK;
}
NSS_IMPLEMENT CK_RV
nssCKFWFindObjects_verifyPointer
(
const NSSCKFWFindObjects *fwFindObjects
)
{
return CKR_OK;
}
#endif /* DEBUG */
/*
* nssCKFWFindObjects_Create
*
*/
NSS_EXTERN NSSCKFWFindObjects *
nssCKFWFindObjects_Create
(
NSSCKFWSession *fwSession,
NSSCKFWToken *fwToken,
NSSCKFWInstance *fwInstance,
NSSCKMDFindObjects *mdFindObjects1,
NSSCKMDFindObjects *mdFindObjects2,
CK_RV *pError
)
{
NSSCKFWFindObjects *fwFindObjects = NULL;
NSSCKMDSession *mdSession;
NSSCKMDToken *mdToken;
NSSCKMDInstance *mdInstance;
mdSession = nssCKFWSession_GetMDSession(fwSession);
mdToken = nssCKFWToken_GetMDToken(fwToken);
mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
fwFindObjects = nss_ZNEW(NULL, NSSCKFWFindObjects);
if (!fwFindObjects) {
*pError = CKR_HOST_MEMORY;
goto loser;
}
fwFindObjects->mdfo1 = mdFindObjects1;
fwFindObjects->mdfo2 = mdFindObjects2;
fwFindObjects->fwSession = fwSession;
fwFindObjects->mdSession = mdSession;
fwFindObjects->fwToken = fwToken;
fwFindObjects->mdToken = mdToken;
fwFindObjects->fwInstance = fwInstance;
fwFindObjects->mdInstance = mdInstance;
fwFindObjects->mutex = nssCKFWInstance_CreateMutex(fwInstance, NULL, pError);
if (!fwFindObjects->mutex) {
goto loser;
}
#ifdef DEBUG
*pError = findObjects_add_pointer(fwFindObjects);
if( CKR_OK != *pError ) {
goto loser;
}
#endif /* DEBUG */
return fwFindObjects;
loser:
if( fwFindObjects ) {
if( NULL != mdFindObjects1 ) {
if( NULL != mdFindObjects1->Final ) {
fwFindObjects->mdFindObjects = mdFindObjects1;
mdFindObjects1->Final(mdFindObjects1, fwFindObjects, mdSession,
fwSession, mdToken, fwToken, mdInstance, fwInstance);
}
}
if( NULL != mdFindObjects2 ) {
if( NULL != mdFindObjects2->Final ) {
fwFindObjects->mdFindObjects = mdFindObjects2;
mdFindObjects2->Final(mdFindObjects2, fwFindObjects, mdSession,
fwSession, mdToken, fwToken, mdInstance, fwInstance);
}
}
nss_ZFreeIf(fwFindObjects);
}
if( CKR_OK == *pError ) {
*pError = CKR_GENERAL_ERROR;
}
return (NSSCKFWFindObjects *)NULL;
}
/*
* nssCKFWFindObjects_Destroy
*
*/
NSS_EXTERN void
nssCKFWFindObjects_Destroy
(
NSSCKFWFindObjects *fwFindObjects
)
{
#ifdef NSSDEBUG
if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) {
return;
}
#endif /* NSSDEBUG */
(void)nssCKFWMutex_Destroy(fwFindObjects->mutex);
if (fwFindObjects->mdfo1) {
if (fwFindObjects->mdfo1->Final) {
fwFindObjects->mdFindObjects = fwFindObjects->mdfo1;
fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects,
fwFindObjects->mdSession, fwFindObjects->fwSession,
fwFindObjects->mdToken, fwFindObjects->fwToken,
fwFindObjects->mdInstance, fwFindObjects->fwInstance);
}
}
if (fwFindObjects->mdfo2) {
if (fwFindObjects->mdfo2->Final) {
fwFindObjects->mdFindObjects = fwFindObjects->mdfo2;
fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects,
fwFindObjects->mdSession, fwFindObjects->fwSession,
fwFindObjects->mdToken, fwFindObjects->fwToken,
fwFindObjects->mdInstance, fwFindObjects->fwInstance);
}
}
nss_ZFreeIf(fwFindObjects);
#ifdef DEBUG
(void)findObjects_remove_pointer(fwFindObjects);
#endif /* DEBUG */
return;
}
/*
* nssCKFWFindObjects_GetMDFindObjects
*
*/
NSS_EXTERN NSSCKMDFindObjects *
nssCKFWFindObjects_GetMDFindObjects
(
NSSCKFWFindObjects *fwFindObjects
)
{
#ifdef NSSDEBUG
if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) {
return (NSSCKMDFindObjects *)NULL;
}
#endif /* NSSDEBUG */
return fwFindObjects->mdFindObjects;
}
/*
* nssCKFWFindObjects_Next
*
*/
NSS_EXTERN NSSCKFWObject *
nssCKFWFindObjects_Next
(
NSSCKFWFindObjects *fwFindObjects,
NSSArena *arenaOpt,
CK_RV *pError
)
{
NSSCKMDObject *mdObject;
NSSCKFWObject *fwObject = (NSSCKFWObject *)NULL;
NSSArena *objArena;
#ifdef NSSDEBUG
if (!pError) {
return (NSSCKFWObject *)NULL;
}
*pError = nssCKFWFindObjects_verifyPointer(fwFindObjects);
if( CKR_OK != *pError ) {
return (NSSCKFWObject *)NULL;
}
#endif /* NSSDEBUG */
*pError = nssCKFWMutex_Lock(fwFindObjects->mutex);
if( CKR_OK != *pError ) {
return (NSSCKFWObject *)NULL;
}
if (fwFindObjects->mdfo1) {
if (fwFindObjects->mdfo1->Next) {
fwFindObjects->mdFindObjects = fwFindObjects->mdfo1;
mdObject = fwFindObjects->mdfo1->Next(fwFindObjects->mdfo1,
fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession,
fwFindObjects->mdToken, fwFindObjects->fwToken,
fwFindObjects->mdInstance, fwFindObjects->fwInstance,
arenaOpt, pError);
if (!mdObject) {
if( CKR_OK != *pError ) {
goto done;
}
/* All done. */
fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects,
fwFindObjects->mdSession, fwFindObjects->fwSession,
fwFindObjects->mdToken, fwFindObjects->fwToken,
fwFindObjects->mdInstance, fwFindObjects->fwInstance);
fwFindObjects->mdfo1 = (NSSCKMDFindObjects *)NULL;
} else {
goto wrap;
}
}
}
if (fwFindObjects->mdfo2) {
if (fwFindObjects->mdfo2->Next) {
fwFindObjects->mdFindObjects = fwFindObjects->mdfo2;
mdObject = fwFindObjects->mdfo2->Next(fwFindObjects->mdfo2,
fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession,
fwFindObjects->mdToken, fwFindObjects->fwToken,
fwFindObjects->mdInstance, fwFindObjects->fwInstance,
arenaOpt, pError);
if (!mdObject) {
if( CKR_OK != *pError ) {
goto done;
}
/* All done. */
fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects,
fwFindObjects->mdSession, fwFindObjects->fwSession,
fwFindObjects->mdToken, fwFindObjects->fwToken,
fwFindObjects->mdInstance, fwFindObjects->fwInstance);
fwFindObjects->mdfo2 = (NSSCKMDFindObjects *)NULL;
} else {
goto wrap;
}
}
}
/* No more objects */
*pError = CKR_OK;
goto done;
wrap:
/*
* This seems is less than ideal-- we should determine if it's a token
* object or a session object, and use the appropriate arena.
* But that duplicates logic in nssCKFWObject_IsTokenObject.
* Also we should lookup the real session the object was created on
* if the object was a session object... however this code is actually
* correct because nssCKFWObject_Create will return a cached version of
* the object from it's hash. This is necessary because 1) we don't want
* to create an arena style leak (where our arena grows with every search),
* and 2) we want the same object to always have the same ID. This means
* the only case the nssCKFWObject_Create() will need the objArena and the
* Session is in the case of token objects (session objects should already
* exist in the cache from their initial creation). So this code is correct,
* but it depends on nssCKFWObject_Create caching all objects.
*/
objArena = nssCKFWToken_GetArena(fwFindObjects->fwToken, pError);
if (!objArena) {
if( CKR_OK == *pError ) {
*pError = CKR_HOST_MEMORY;
}
goto done;
}
fwObject = nssCKFWObject_Create(objArena, mdObject,
NULL, fwFindObjects->fwToken,
fwFindObjects->fwInstance, pError);
if (!fwObject) {
if( CKR_OK == *pError ) {
*pError = CKR_GENERAL_ERROR;
}
}
done:
(void)nssCKFWMutex_Unlock(fwFindObjects->mutex);
return fwObject;
}
/*
* NSSCKFWFindObjects_GetMDFindObjects
*
*/
NSS_EXTERN NSSCKMDFindObjects *
NSSCKFWFindObjects_GetMDFindObjects
(
NSSCKFWFindObjects *fwFindObjects
)
{
#ifdef DEBUG
if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) {
return (NSSCKMDFindObjects *)NULL;
}
#endif /* DEBUG */
return nssCKFWFindObjects_GetMDFindObjects(fwFindObjects);
}