gecko/security/nss/lib/ckfw/find.c
2009-02-10 09:18:32 -08:00

416 lines
11 KiB
C

/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 the Initial Developer are Copyright (C) 1994-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: find.c,v $ $Revision: 1.9 $ $Date: 2009/02/09 07:55:52 $";
#endif /* DEBUG */
/*
* 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);
}