From 2d3ef1d51041d5a19fc4fe34496ca00dc41b5f3f Mon Sep 17 00:00:00 2001 From: "ian.mcgreer%sun.com" Date: Thu, 11 Oct 2001 16:33:38 +0000 Subject: [PATCH] add glue code for old NSS types; fix certificate lookup git-svn-id: svn://10.0.0.236/trunk@105161 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/security/nss/lib/dev/ckhelper.c | 61 ++--- mozilla/security/nss/lib/dev/ckhelper.h | 24 +- mozilla/security/nss/lib/dev/dev.h | 31 +-- mozilla/security/nss/lib/dev/devm.h | 6 +- mozilla/security/nss/lib/dev/devnss3hack.h | 50 +++++ mozilla/security/nss/lib/dev/devt.h | 64 +++--- mozilla/security/nss/lib/dev/manifest.mn | 10 +- mozilla/security/nss/lib/dev/nss3hack.c | 141 ++++++++++++ mozilla/security/nss/lib/dev/slot.c | 11 +- mozilla/security/nss/lib/dev/token.c | 245 ++++++++++++--------- 10 files changed, 464 insertions(+), 179 deletions(-) create mode 100644 mozilla/security/nss/lib/dev/devnss3hack.h create mode 100644 mozilla/security/nss/lib/dev/nss3hack.c diff --git a/mozilla/security/nss/lib/dev/ckhelper.c b/mozilla/security/nss/lib/dev/ckhelper.c index 0ef43929a9f..d95ac7a7548 100644 --- a/mozilla/security/nss/lib/dev/ckhelper.c +++ b/mozilla/security/nss/lib/dev/ckhelper.c @@ -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: not supported by cvs2svn $"; +static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.5 $ $Date: 2001-10-11 16:33:36 $ $Name: not supported by cvs2svn $"; #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; iC_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; iC_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; jC_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); } diff --git a/mozilla/security/nss/lib/dev/ckhelper.h b/mozilla/security/nss/lib/dev/ckhelper.h index 48cf7f06f25..d0660ad53a7 100644 --- a/mozilla/security/nss/lib/dev/ckhelper.h +++ b/mozilla/security/nss/lib/dev/ckhelper.h @@ -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: not supported by cvs2svn $"; +static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.5 $ $Date: 2001-10-11 16:33:36 $ $Name: not supported by cvs2svn $"; #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 */ diff --git a/mozilla/security/nss/lib/dev/dev.h b/mozilla/security/nss/lib/dev/dev.h index 45ced9fe087..9da9f41987b 100644 --- a/mozilla/security/nss/lib/dev/dev.h +++ b/mozilla/security/nss/lib/dev/dev.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: not supported by cvs2svn $"; +static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.8 $ $Date: 2001-10-11 16:33:38 $ $Name: not supported by cvs2svn $"; #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 ( diff --git a/mozilla/security/nss/lib/dev/devm.h b/mozilla/security/nss/lib/dev/devm.h index 5d7d73978e9..991c60c971c 100644 --- a/mozilla/security/nss/lib/dev/devm.h +++ b/mozilla/security/nss/lib/dev/devm.h @@ -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: not supported by cvs2svn $"; +static const char DEVM_CVS_ID[] = "@(#) $RCSfile: devm.h,v $ $Revision: 1.3 $ $Date: 2001-10-11 16:33:38 $ $Name: not supported by cvs2svn $"; #endif /* DEBUG */ +#ifndef DEVT_H +#include "devt.h" +#endif /* DEVT_H */ + #ifdef NSS_3_4_CODE #include "pkcs11t.h" #else diff --git a/mozilla/security/nss/lib/dev/devnss3hack.h b/mozilla/security/nss/lib/dev/devnss3hack.h new file mode 100644 index 00000000000..21f2f8cbe1b --- /dev/null +++ b/mozilla/security/nss/lib/dev/devnss3hack.h @@ -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: not supported by cvs2svn $"; +#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 */ diff --git a/mozilla/security/nss/lib/dev/devt.h b/mozilla/security/nss/lib/dev/devt.h index ed2ed0e508d..0691778bc16 100644 --- a/mozilla/security/nss/lib/dev/devt.h +++ b/mozilla/security/nss/lib/dev/devt.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: not supported by cvs2svn $"; +static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.5 $ $Date: 2001-10-11 16:33:38 $ $Name: not supported by cvs2svn $"; #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 diff --git a/mozilla/security/nss/lib/dev/manifest.mn b/mozilla/security/nss/lib/dev/manifest.mn index e3a2af317af..0d48ebd4b27 100644 --- a/mozilla/security/nss/lib/dev/manifest.mn +++ b/mozilla/security/nss/lib/dev/manifest.mn @@ -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: not supported by cvs2svn $" +MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.2 $ $Date: 2001-10-11 16:33:38 $ $Name: not supported by cvs2svn $" 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 diff --git a/mozilla/security/nss/lib/dev/nss3hack.c b/mozilla/security/nss/lib/dev/nss3hack.c new file mode 100644 index 00000000000..e526e755391 --- /dev/null +++ b/mozilla/security/nss/lib/dev/nss3hack.c @@ -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: not supported by cvs2svn $"; +#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; +} + diff --git a/mozilla/security/nss/lib/dev/slot.c b/mozilla/security/nss/lib/dev/slot.c index 030b10355fc..2f23f763ee0 100644 --- a/mozilla/security/nss/lib/dev/slot.c +++ b/mozilla/security/nss/lib/dev/slot.c @@ -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: not supported by cvs2svn $"; +static const char CVS_ID[] = "@(#) $RCSfile: slot.c,v $ $Revision: 1.9 $ $Date: 2001-10-11 16:33:38 $ $Name: not supported by cvs2svn $"; #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; } diff --git a/mozilla/security/nss/lib/dev/token.c b/mozilla/security/nss/lib/dev/token.c index 1c0169f3265..bc7cc79f81f 100644 --- a/mozilla/security/nss/lib/dev/token.c +++ b/mozilla/security/nss/lib/dev/token.c @@ -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: not supported by cvs2svn $"; +static const char CVS_ID[] = "@(#) $RCSfile: token.c,v $ $Revision: 1.8 $ $Date: 2001-10-11 16:33:38 $ $Name: not supported by cvs2svn $"; #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; idefaultSession; - 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 -