add glue code for old NSS types; fix certificate lookup

This commit is contained in:
ian.mcgreer%sun.com 2001-10-11 16:33:38 +00:00
Родитель 4d44a81c81
Коммит 520c6909b0
10 изменённых файлов: 464 добавлений и 179 удалений

Просмотреть файл

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.4 $ $Date: 2001-10-08 20:19:29 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.5 $ $Date: 2001-10-11 16:33:36 $ $Name: $";
#endif /* DEBUG */
#ifndef PKIT_H
@ -95,6 +95,7 @@ nssCKObject_GetAttributes
CK_ULONG i;
CK_RV ckrv;
PRStatus nssrv;
PRBool alloced = PR_FALSE;
hSession = session->handle;
if (arenaOpt) {
mark = nssArena_Mark(arenaOpt);
@ -102,23 +103,29 @@ nssCKObject_GetAttributes
goto loser;
}
}
/* Get the storage size needed for each attribute */
nssSession_EnterMonitor(session);
ckrv = CKAPI(slot)->C_GetAttributeValue(hSession,
object, obj_template, count);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
/* set an error here */
goto loser;
}
/* Allocate memory for each attribute. */
for (i=0; i<count; i++) {
obj_template[i].pValue = nss_ZAlloc(arenaOpt,
obj_template[i].ulValueLen);
if (!obj_template[i].pValue) {
/* XXX kinda hacky, if the storage size is already in the first template
* item, then skip the alloc portion
*/
if (obj_template[0].ulValueLen == 0) {
/* Get the storage size needed for each attribute */
ckrv = CKAPI(slot)->C_GetAttributeValue(hSession,
object, obj_template, count);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
/* set an error here */
goto loser;
}
/* Allocate memory for each attribute. */
for (i=0; i<count; i++) {
obj_template[i].pValue = nss_ZAlloc(arenaOpt,
obj_template[i].ulValueLen);
if (!obj_template[i].pValue) {
nssSession_ExitMonitor(session);
goto loser;
}
}
alloced = PR_TRUE;
}
/* Obtain the actual attribute values. */
ckrv = CKAPI(slot)->C_GetAttributeValue(hSession,
@ -128,7 +135,7 @@ nssCKObject_GetAttributes
/* set an error here */
goto loser;
}
if (arenaOpt) {
if (alloced && arenaOpt) {
nssrv = nssArena_Unmark(arenaOpt, mark);
if (nssrv != PR_SUCCESS) {
goto loser;
@ -136,14 +143,16 @@ nssCKObject_GetAttributes
}
return PR_SUCCESS;
loser:
if (arenaOpt) {
/* release all arena memory allocated before the failure. */
(void)nssArena_Release(arenaOpt, mark);
} else {
CK_ULONG j;
/* free each heap object that was allocated before the failure. */
for (j=0; j<i; j++) {
nss_ZFreeIf(obj_template[j].pValue);
if (alloced) {
if (arenaOpt) {
/* release all arena memory allocated before the failure. */
(void)nssArena_Release(arenaOpt, mark);
} else {
CK_ULONG j;
/* free each heap object that was allocated before the failure. */
for (j=0; j<i; j++) {
nss_ZFreeIf(obj_template[j].pValue);
}
}
}
return PR_FAILURE;
@ -178,13 +187,13 @@ nssCKObject_IsAttributeTrue
(
CK_OBJECT_HANDLE object,
CK_ATTRIBUTE_TYPE attribute,
NSSArena *arenaOpt,
nssSession *session,
NSSSlot *slot,
PRStatus *rvStatus
)
{
CK_ATTRIBUTE attr = { attribute, g_ck_true.data, g_ck_true.size };
CK_BBOOL bool;
CK_ATTRIBUTE attr = { attribute, (CK_VOID_PTR)&bool, sizeof(bool) };
CK_RV ckrv;
nssSession_EnterMonitor(session);
ckrv = CKAPI(slot)->C_GetAttributeValue(session->handle, object, &attr, 1);
@ -194,6 +203,6 @@ nssCKObject_IsAttributeTrue
return PR_FALSE;
}
*rvStatus = PR_SUCCESS;
return (PRBool)(*((CK_BBOOL *)attr.pValue) == CK_TRUE);
return (PRBool)(bool == CK_TRUE);
}

Просмотреть файл

@ -41,7 +41,7 @@
#define CKHELPER_H
#ifdef DEBUG
static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.4 $ $Date: 2001-10-08 20:19:30 $ $Name: $";
static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.5 $ $Date: 2001-10-11 16:33:36 $ $Name: $";
#endif /* DEBUG */
#ifdef NSS_3_4_CODE
@ -106,6 +106,28 @@ nssCKObject_GetAttributes
NSSSlot *slot
);
/* Get a single attribute as an item. */
NSS_EXTERN PRStatus
nssCKObject_GetAttributeItem
(
CK_OBJECT_HANDLE object,
CK_ATTRIBUTE_TYPE attribute,
NSSArena *arenaOpt,
nssSession *session,
NSSSlot *slot,
NSSItem *rvItem
);
NSS_EXTERN PRBool
nssCKObject_IsAttributeTrue
(
CK_OBJECT_HANDLE object,
CK_ATTRIBUTE_TYPE attribute,
nssSession *session,
NSSSlot *slot,
PRStatus *rvStatus
);
PR_END_EXTERN_C
#endif /* CKHELPER_H */

Просмотреть файл

@ -35,7 +35,7 @@
#define DEV_H
#ifdef DEBUG
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.7 $ $Date: 2001-10-08 20:19:30 $ $Name: $";
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.8 $ $Date: 2001-10-11 16:33:38 $ $Name: $";
#endif /* DEBUG */
#ifndef DEVT_H
@ -284,33 +284,26 @@ nssToken_DeleteStoredObject
CK_OBJECT_HANDLE object
);
NSS_IMPLEMENT PRStatus
NSS_EXTERN CK_OBJECT_HANDLE
nssToken_FindObjectByTemplate
(
NSSToken *tok,
nssSession *sessionOpt,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize
);
NSS_EXTERN PRStatus
nssToken_FindCertificatesByTemplate
(
NSSToken *tok,
nssSession *sessionOpt,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize,
PRStatus (*callback)(NSSToken *t, nssSession *session,
CK_OBJECT_HANDLE h, void *arg),
PRStatus (*callback)(NSSCertificate *c, void *arg),
void *arg
);
#if 0
NSS_EXTERN PRStatus
nssToken_FindCertificatesByTemplate
(
NSSToken *tok,
nssSession *sessionOpt,
nssList *certList,
PRUint32 maximumOpt,
NSSArena *arenaOpt,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize
);
#endif
/* again, a questionable function. maybe some tokens allow this? */
NSS_EXTERN PRStatus *
nssToken_TraverseCertificates
(

Просмотреть файл

@ -35,9 +35,13 @@
#define DEVM_H
#ifdef DEBUG
static const char DEVM_CVS_ID[] = "@(#) $RCSfile: devm.h,v $ $Revision: 1.2 $ $Date: 2001-10-08 20:19:30 $ $Name: $";
static const char DEVM_CVS_ID[] = "@(#) $RCSfile: devm.h,v $ $Revision: 1.3 $ $Date: 2001-10-11 16:33:38 $ $Name: $";
#endif /* DEBUG */
#ifndef DEVT_H
#include "devt.h"
#endif /* DEVT_H */
#ifdef NSS_3_4_CODE
#include "pkcs11t.h"
#else

Просмотреть файл

@ -0,0 +1,50 @@
/*
* 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.
*/
#ifndef DEVNSS3HACK_H
#define DEVNSS3HACK_H
#ifdef DEBUG
static const char DEVNSS3HACK_CVS_ID[] = "@(#) $RCSfile: devnss3hack.h,v $ $Revision: 1.1 $ $Date: 2001-10-11 16:33:38 $ $Name: $";
#endif /* DEBUG */
#include "cert.h"
PR_BEGIN_EXTERN_C
NSS_EXTERN NSSToken *
nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot);
PR_END_EXTERN_C
#endif /* DEVNSS3HACK_H */

Просмотреть файл

@ -35,11 +35,11 @@
#define DEVT_H
#ifdef DEBUG
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.4 $ $Date: 2001-10-08 20:19:30 $ $Name: $";
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.5 $ $Date: 2001-10-11 16:33:38 $ $Name: $";
#endif /* DEBUG */
/*
* nssdevt.h
* devt.h
*
* This file contains definitions for the low-level cryptoki devices.
*/
@ -48,8 +48,17 @@ static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.4 $ $D
#include "nssbaset.h"
#endif /* NSSBASET_H */
#ifndef NSSPKIT_H
#include "nsspkit.h"
#endif /* NSSPKIT_H */
#ifndef NSSDEVT_H
#include "nssdevt.h"
#endif /* NSSDEVT_H */
#ifdef NSS_3_4_CODE
#include "pkcs11t.h"
#include "secmodt.h"
#else
#ifndef NSSCKT_H
#include "nssckt.h"
@ -58,18 +67,6 @@ static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.4 $ $D
PR_BEGIN_EXTERN_C
/*
* NSSModule and NSSSlot -- placeholders for the PKCS#11 types
*/
typedef struct NSSModuleStr NSSModule;
typedef struct NSSSlotStr NSSSlot;
typedef struct NSSTokenStr NSSToken;
typedef struct nssSessionStr nssSession;
/* The list of boolean flags used to describe properties of a
* module.
*/
@ -102,27 +99,36 @@ struct nssSlotAuthInfoStr
struct NSSSlotStr
{
NSSArena *arena;
PRInt32 refCount;
NSSModule *module; /* Parent */
NSSToken *token; /* Child (or peer, if you will) */
NSSUTF8 *name;
CK_SLOT_ID slotID;
void *epv;
CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */
PRUint32 flags;
NSSArena *arena;
PRInt32 refCount;
NSSModule *module; /* Parent */
NSSToken *token; /* Child (or peer, if you will) */
NSSUTF8 *name;
CK_SLOT_ID slotID;
void *epv;
CK_FLAGS ckFlags; /* from CK_SLOT_INFO.flags */
PRUint32 flags;
struct nssSlotAuthInfoStr authInfo;
NSSTrustDomain *trustDomain;
#ifdef NSS_3_4_CODE
PK11SlotInfo *pk11slot;
#endif
};
struct NSSTokenStr
{
NSSArena *arena;
PRInt32 refCount;
NSSSlot *slot; /* Parent (or peer, if you will) */
NSSUTF8 *name;
CK_FLAGS ckFlags; /* from CK_TOKEN_INFO.flags */
PRUint32 flags;
NSSArena *arena;
PRInt32 refCount;
NSSSlot *slot; /* Parent (or peer, if you will) */
NSSUTF8 *name;
CK_FLAGS ckFlags; /* from CK_TOKEN_INFO.flags */
PRUint32 flags;
void *epv;
nssSession *defaultSession;
NSSTrustDomain *trustDomain;
#ifdef NSS_3_4_CODE
PK11SlotInfo *pk11slot;
#endif
};
struct nssSessionStr

Просмотреть файл

@ -30,7 +30,7 @@
# may use your version of this file under either the MPL or the
# GPL.
#
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.1 $ $Date: 2001-09-13 22:06:10 $ $Name: $"
MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.2 $ $Date: 2001-10-11 16:33:38 $ $Name: $"
CORE_DEPTH = ../../..
@ -41,6 +41,7 @@ PRIVATE_EXPORTS = \
$(NULL)
EXPORTS = \
nssdevt.h \
$(NULL)
MODULE = security
@ -53,6 +54,13 @@ CSRCS = \
ckhelper.c \
$(NULL)
# here is where the 3.4 glue code is added
ifndef PURE_STAN_BUILD
CSRCS += nss3hack.c
PRIVATE_EXPORTS += devnss3hack.h
DEFINES = -DNSS_3_4_CODE
endif
REQUIRES = security nspr
LIBRARY_NAME = nssdev

Просмотреть файл

@ -0,0 +1,141 @@
/*
* 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: nss3hack.c,v $ $Revision: 1.1 $ $Date: 2001-10-11 16:33:38 $ $Name: $";
#endif /* DEBUG */
#ifndef PKIT_H
#include "pkit.h"
#endif /* PKIT_H */
#ifndef DEVT_H
#include "devt.h"
#endif /* DEVT_H */
#ifndef DEVM_H
#include "devm.h"
#endif /* DEVM_H */
#ifndef BASE_H
#include "base.h"
#endif /* BASE_H */
#include "pk11func.h"
#include "secmodti.h"
NSS_IMPLEMENT nssSession *
nssSession_ImportNSS3Session(NSSArena *arenaOpt,
CK_SESSION_HANDLE session,
PZLock *lock, PRBool rw)
{
nssSession *rvSession;
rvSession = nss_ZNEW(arenaOpt, nssSession);
rvSession->handle = session;
rvSession->lock = lock;
rvSession->isRW = rw;
return rvSession;
}
static NSSSlot *
nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
{
PRUint32 length;
NSSSlot *rvSlot;
rvSlot = nss_ZNEW(td->arena, NSSSlot);
if (!rvSlot) {
return NULL;
}
rvSlot->refCount = 1;
rvSlot->pk11slot = nss3slot;
rvSlot->epv = nss3slot->functionList;
rvSlot->slotID = nss3slot->slotID;
rvSlot->trustDomain = td;
/* Grab the slot name from the PKCS#11 fixed-length buffer */
length = nssPKCS11StringLength(nss3slot->slot_name,
sizeof(nss3slot->slot_name));
if (length > 0) {
rvSlot->name = nssUTF8_Create(td->arena, nssStringType_UTF8String,
(void *)nss3slot->slot_name, length);
}
return rvSlot;
}
NSS_IMPLEMENT NSSToken *
nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
{
PRUint32 length;
NSSToken *rvToken;
rvToken = nss_ZNEW(td->arena, NSSToken);
if (!rvToken) {
return NULL;
}
rvToken->refCount = 1;
rvToken->pk11slot = nss3slot;
rvToken->epv = nss3slot->functionList;
rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena,
nss3slot->session,
nss3slot->sessionLock,
nss3slot->defRWSession);
rvToken->trustDomain = td;
/* Grab the token name from the PKCS#11 fixed-length buffer */
length = nssPKCS11StringLength(nss3slot->token_name,
sizeof(nss3slot->token_name));
if (length > 0) {
rvToken->name = nssUTF8_Create(td->arena, nssStringType_UTF8String,
(void *)nss3slot->token_name, length);
}
rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot);
rvToken->slot->token = rvToken;
return rvToken;
}
typedef enum {
nssPK11Event_DefaultSessionRO = 0,
nssPK11Event_DefaultSessionRW = 1
} nssPK11Event;
NSS_IMPLEMENT PRStatus
nssToken_Nofify
(
NSSToken *tok,
nssPK11Event event
)
{
switch (event) {
default:
return PR_FAILURE;
}
return PR_FAILURE;
}

Просмотреть файл

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: slot.c,v $ $Revision: 1.8 $ $Date: 2001-10-08 20:19:30 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: slot.c,v $ $Revision: 1.9 $ $Date: 2001-10-11 16:33:38 $ $Name: $";
#endif /* DEBUG */
#ifndef DEV_H
@ -174,8 +174,15 @@ nssSlot_Destroy
)
{
if (--slot->refCount == 0) {
#ifndef NSS_3_4_CODE
/* Not going to do this in 3.4, maybe never */
nssToken_Destroy(slot->token);
return NSSArena_Destroy(slot->arena);
#endif
if (slot->arena) {
return NSSArena_Destroy(slot->arena);
} else {
nss_ZFreeIf(slot);
}
}
return PR_SUCCESS;
}

Просмотреть файл

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: token.c,v $ $Revision: 1.7 $ $Date: 2001-10-08 20:19:30 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: token.c,v $ $Revision: 1.8 $ $Date: 2001-10-11 16:33:38 $ $Name: $";
#endif /* DEBUG */
#ifndef DEV_H
@ -43,6 +43,11 @@ static const char CVS_ID[] = "@(#) $RCSfile: token.c,v $ $Revision: 1.7 $ $Date:
#include "devm.h"
#endif /* DEVM_H */
/* for the cache... */
#ifndef PKI_H
#include "pki.h"
#endif /* PKI_H */
#ifdef NSS_3_4_CODE
#include "pkcs11.h"
#else
@ -172,10 +177,17 @@ nssToken_Destroy
)
{
if (--tok->refCount == 0) {
#ifndef NSS_3_4_CODE
/* don't do this in 3.4 -- let PK11SlotInfo handle it */
if (tok->defaultSession) {
nssSession_Destroy(tok->defaultSession);
}
return NSSArena_Destroy(tok->arena);
#endif
if (tok->arena) {
return NSSArena_Destroy(tok->arena);
} else {
nss_ZFreeIf(tok);
}
}
return PR_SUCCESS;
}
@ -234,40 +246,39 @@ nssToken_ImportObject
return PR_SUCCESS;
}
/* This is only used by the Traverse function. If we ditch traversal,
* ditch this.
*/
struct certCallbackStr {
PRStatus (*callback)(NSSCertificate *c, void *arg);
void *arg;
};
/* also symmKeyCallbackStr, pubKeyCallbackStr, etc. */
/*
* This callback examines each matching certificate by passing it to
* a higher-level callback function.
*/
static PRStatus
examine_cert_callback(NSSToken *t, nssSession *session,
CK_OBJECT_HANDLE h, void *arg)
NSS_IMPLEMENT CK_OBJECT_HANDLE
nssToken_FindObjectByTemplate
(
NSSToken *tok,
nssSession *sessionOpt,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize
)
{
PRStatus cbrv;
NSSCertificate *cert;
struct certCallbackStr *ccb = (struct certCallbackStr *)arg;
/* maybe it should be nssToken_CreateCertificate(token, handle); */
cert = NSSCertificate_CreateFromHandle(NULL, h, session, t->slot);
if (!cert) {
goto loser;
CK_SESSION_HANDLE hSession;
CK_OBJECT_HANDLE rvObject;
CK_ULONG count;
CK_RV ckrv;
nssSession *session;
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
hSession = session->handle;
nssSession_EnterMonitor(session);
ckrv = CKAPI(tok)->C_FindObjectsInit(hSession, cktemplate, ctsize);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
return CK_INVALID_KEY;
}
cbrv = (*ccb->callback)(cert, ccb->arg);
if (cbrv != PR_SUCCESS) {
goto loser;
ckrv = CKAPI(tok)->C_FindObjects(hSession, &rvObject, 1, &count);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
return CK_INVALID_KEY;
}
NSSCertificate_Destroy(cert);
return PR_SUCCESS;
loser:
return PR_FAILURE;
ckrv = CKAPI(tok)->C_FindObjectsFinal(hSession);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
return CK_INVALID_KEY;
}
return rvObject;
}
extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
@ -301,6 +312,53 @@ loser:
return PR_FAILURE;
}
struct cert_callback_str {
PRStatus (*callback)(NSSCertificate *c, void *arg);
void *arg;
};
/* Parts of this (cache lookup, creating a cert) should be passed up to
* a higher level through a callback, but left here for now
*/
static PRStatus
retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg)
{
PRStatus nssrv;
NSSCertificate *cert;
NSSDER issuer, serial;
CK_ULONG template_size;
/* Set up the unique id */
CK_ATTRIBUTE cert_template[] = {
{ CKA_ISSUER, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0 }
};
struct cert_callback_str *ccb = (struct cert_callback_str *)arg;
template_size = sizeof(cert_template) / sizeof(cert_template[0]);
/* Get the unique id */
nssrv = nssCKObject_GetAttributes(h, cert_template, template_size,
NULL, session, t->slot);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[0], &issuer);
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[1], &serial);
/* Look in the cert's trust domain cache first */
cert = nssTrustDomain_GetCertForIssuerAndSNFromCache(t->trustDomain,
&issuer, &serial);
nss_ZFreeIf(issuer.data);
nss_ZFreeIf(serial.data);
if (!cert) {
/* Could not find cert, so create it */
cert = NSSCertificate_CreateFromHandle(NULL, h, session, t->slot);
if (!cert) {
goto loser;
}
}
/* Got the cert, feed it to the callback */
return (*ccb->callback)(cert, ccb->arg);
loser:
return PR_FAILURE;
}
#define OBJECT_STACK_SIZE 16
static PRStatus *
nsstoken_TraverseObjects
(
@ -315,41 +373,69 @@ nsstoken_TraverseObjects
{
NSSSlot *slot;
PRStatus cbrv;
PRUint32 i;
CK_RV ckrv;
CK_ULONG count;
CK_OBJECT_HANDLE object;
CK_OBJECT_HANDLE *objectStack;
CK_OBJECT_HANDLE startOS[OBJECT_STACK_SIZE];
CK_SESSION_HANDLE hSession;
NSSArena *objectArena = NULL;
nssList *objectList = NULL;
slot = tok->slot;
hSession = session->handle;
objectStack = startOS;
nssSession_EnterMonitor(session);
ckrv = CKAPI(slot)->C_FindObjectsInit(hSession, obj_template, otsize);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
goto loser;
}
while (PR_TRUE) {
/* this could be sped up by getting 5-10 at a time? */
ckrv = CKAPI(slot)->C_FindObjects(hSession, &object, 1, &count);
ckrv = CKAPI(slot)->C_FindObjects(hSession, objectStack,
OBJECT_STACK_SIZE, &count);
if (ckrv != CKR_OK) {
nssSession_ExitMonitor(session);
goto loser;
}
if (count == 0) {
break;
}
cbrv = (*callback)(tok, session, object, arg);
if (cbrv != PR_SUCCESS) {
NSSError e;
if ((e = NSS_GetError()) == NSS_ERROR_MAXIMUM_FOUND) {
/* The maximum number of elements have been found, exit. */
nss_ClearErrorStack();
break;
if (count == OBJECT_STACK_SIZE) {
if (!objectList) {
objectArena = NSSArena_Create();
objectList = nssList_Create(objectArena, PR_FALSE);
}
goto loser;
objectStack = nss_ZNEWARRAY(objectArena, CK_OBJECT_HANDLE,
OBJECT_STACK_SIZE);
nssList_Add(objectList, objectStack);
} else {
break;
}
}
ckrv = CKAPI(slot)->C_FindObjectsFinal(hSession);
nssSession_ExitMonitor(session);
if (ckrv != CKR_OK) {
goto loser;
}
if (objectList) {
nssListIterator *objects;
objects = nssList_CreateIterator(objectList);
for (objectStack = (CK_OBJECT_HANDLE *)nssListIterator_Start(objects);
objectStack != NULL;
objectStack = (CK_OBJECT_HANDLE *)nssListIterator_Next(objects)) {
for (i=0; i<count; i++) {
cbrv = (*callback)(tok, session, objectStack[i], arg);
}
}
nssListIterator_Finish(objects);
count = OBJECT_STACK_SIZE;
}
for (i=0; i<count; i++) {
cbrv = (*callback)(tok, session, startOS[i], arg);
}
if (objectArena)
NSSArena_Destroy(objectArena);
return NULL;
loser:
if (objectArena)
NSSArena_Destroy(objectArena);
return NULL; /* for now... */
}
@ -362,21 +448,16 @@ nssToken_TraverseCertificates
void *arg
)
{
PRStatus *rvstack;
nssSession *session;
struct certCallbackStr ccb;
PRStatus nssrv;
/* this is really traversal - the template is all certs */
CK_ATTRIBUTE cert_template[] = {
{ CKA_CLASS, g_ck_class_cert.data, g_ck_class_cert.size }
};
CK_ULONG ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
ccb.callback = callback;
ccb.arg = arg;
nssSession_EnterMonitor(session);
rvstack = nsstoken_TraverseObjects(tok, session, cert_template, ctsize,
examine_cert_callback, (void *)&ccb);
nssSession_ExitMonitor(session);
return rvstack;
nssrv = nssToken_FindCertificatesByTemplate(tok, sessionOpt,
cert_template, ctsize,
callback, arg);
return NULL; /* XXX */
}
NSS_IMPLEMENT PRStatus
@ -386,20 +467,20 @@ nssToken_FindCertificatesByTemplate
nssSession *sessionOpt,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize,
PRStatus (*callback)(NSSToken *t, nssSession *session,
CK_OBJECT_HANDLE h, void *arg),
PRStatus (*callback)(NSSCertificate *c, void *arg),
void *arg
)
{
PRStatus *rvstack;
nssSession *session;
struct cert_callback_str ccb;
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
nssSession_EnterMonitor(session);
/* this isn't really traversal, it's find by template ... */
ccb.callback = callback;
ccb.arg = arg;
rvstack = nsstoken_TraverseObjects(tok, session,
cktemplate, ctsize,
callback, arg);
nssSession_ExitMonitor(session);
cktemplate, ctsize,
retrieve_cert, (void *)&ccb);
if (rvstack) {
/* examine the errors */
goto loser;
@ -409,39 +490,3 @@ loser:
return PR_FAILURE;
}
#if 0
NSS_IMPLEMENT PRStatus
nssToken_FindCertificatesByTemplate
(
NSSToken *tok,
nssSession *sessionOpt,
nssList *certList,
PRUint32 maximumOpt,
NSSArena *arenaOpt,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize
)
{
PRStatus *rvstack;
nssSession *session;
struct collect_arg_str collectArgs;
session = (sessionOpt) ? sessionOpt : tok->defaultSession;
collectArgs.arena = arenaOpt;
collectArgs.list = certList;
collectArgs.maximum = maximumOpt;
nssSession_EnterMonitor(session);
/* this isn't really traversal, it's find by template ... */
rvstack = nsstoken_TraverseObjects(tok, session, cktemplate, ctsize,
collect_certs_callback,
(void *)&collectArgs);
nssSession_ExitMonitor(session);
if (rvstack) {
/* examine the errors */
goto loser;
}
return PR_SUCCESS;
loser:
return PR_FAILURE;
}
#endif