summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian.mcgreer%sun.com <devnull@localhost>2002-02-01 17:25:15 +0000
committerian.mcgreer%sun.com <devnull@localhost>2002-02-01 17:25:15 +0000
commit033e2aa53ec68924ec4dfcaf553ee4e0ab3ab7cd (patch)
tree6d9e0b85dd73b5b78e9e006eaa63e348ab39a828
parentc0fe98b2a7598c4335d391aef8980e2e2ce64359 (diff)
downloadnss-hg-033e2aa53ec68924ec4dfcaf553ee4e0ab3ab7cd.tar.gz
bug 121628, persistent cache of hardware token certs
-rw-r--r--security/nss/lib/dev/dev.h12
-rw-r--r--security/nss/lib/dev/devobject.c17
-rw-r--r--security/nss/lib/dev/devt.h1
-rw-r--r--security/nss/lib/dev/devtoken.c57
-rw-r--r--security/nss/lib/pk11wrap/dev3hack.c18
-rw-r--r--security/nss/lib/pk11wrap/dev3hack.h5
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c504
-rw-r--r--security/nss/lib/pki/certificate.c45
-rw-r--r--security/nss/lib/pki/pki3hack.c112
-rw-r--r--security/nss/lib/pki/pki3hack.h16
-rw-r--r--security/nss/lib/pki/pkim.h8
-rw-r--r--security/nss/lib/pki/trustdomain.c59
12 files changed, 744 insertions, 110 deletions
diff --git a/security/nss/lib/dev/dev.h b/security/nss/lib/dev/dev.h
index 7290a82f9..e25d5bb28 100644
--- a/security/nss/lib/dev/dev.h
+++ b/security/nss/lib/dev/dev.h
@@ -158,6 +158,12 @@ nssSlot_Destroy
NSSSlot *slot
);
+NSS_EXTERN PRStatus
+nssSlot_Refresh
+(
+ NSSSlot *slot
+);
+
NSS_EXTERN NSSSlot *
nssSlot_AddRef
(
@@ -232,6 +238,12 @@ nssToken_Destroy
NSSToken *tok
);
+NSS_EXTERN PRBool
+nssToken_IsPresent
+(
+ NSSToken *token
+);
+
NSS_EXTERN NSSToken *
nssToken_AddRef
(
diff --git a/security/nss/lib/dev/devobject.c b/security/nss/lib/dev/devobject.c
index 5a772e125..04e0b3b6f 100644
--- a/security/nss/lib/dev/devobject.c
+++ b/security/nss/lib/dev/devobject.c
@@ -462,12 +462,13 @@ static PRStatus
retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg)
{
PRStatus nssrv;
- PRBool found;
+ PRBool found, inCache;
nssTokenCertSearch *search = (nssTokenCertSearch *)arg;
NSSCertificate *cert = NULL;
nssListIterator *instances;
nssCryptokiInstance *ci;
CK_ATTRIBUTE derValue = { CKA_VALUE, NULL, 0 };
+ inCache = PR_FALSE;
if (search->cached) {
NSSCertificate csi; /* a fake cert for indexing */
nssrv = nssCKObject_GetAttributes(h, &derValue, 1,
@@ -478,13 +479,19 @@ retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg)
}
found = PR_FALSE;
if (cert) {
+ inCache = PR_TRUE;
nssCertificate_AddRef(cert);
instances = cert->object.instances;
for (ci = (nssCryptokiInstance *)nssListIterator_Start(instances);
ci != (nssCryptokiInstance *)NULL;
ci = (nssCryptokiInstance *)nssListIterator_Next(instances))
{
- if (ci->handle == h && ci->token == t) {
+ /* The builtins token will not return the same handle for objects
+ * during the lifetime of the token. Thus, assuming the found
+ * object is the same as the cached object if there is already an
+ * instance for the token.
+ */
+ if (ci->token == t) {
found = PR_TRUE;
break;
}
@@ -509,7 +516,11 @@ retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg)
nssListIterator_Destroy(cert->object.instances);
cert->object.instances = nssList_CreateIterator(cert->object.instanceList);
}
- nssrv = (*search->callback)(cert, search->cbarg);
+ if (!inCache) {
+ nssrv = (*search->callback)(cert, search->cbarg);
+ } else {
+ nssrv = PR_SUCCESS; /* cached entries already handled */
+ }
NSSCertificate_Destroy(cert);
return nssrv;
}
diff --git a/security/nss/lib/dev/devt.h b/security/nss/lib/dev/devt.h
index 2c364bdbf..cc681f9c2 100644
--- a/security/nss/lib/dev/devt.h
+++ b/security/nss/lib/dev/devt.h
@@ -133,6 +133,7 @@ struct NSSTokenStr
NSSTrustDomain *trustDomain;
#ifdef NSS_3_4_CODE
PK11SlotInfo *pk11slot;
+ nssList *certList; /* local cache of certs for slow tokens */
#endif
};
diff --git a/security/nss/lib/dev/devtoken.c b/security/nss/lib/dev/devtoken.c
index 5b5c4b320..13444ca8e 100644
--- a/security/nss/lib/dev/devtoken.c
+++ b/security/nss/lib/dev/devtoken.c
@@ -196,6 +196,63 @@ nssToken_GetName
return tok->name;
}
+NSS_IMPLEMENT PRBool
+nssToken_IsPresent
+(
+ NSSToken *token
+)
+{
+ CK_RV ckrv;
+ PRStatus nssrv;
+ nssSession *session;
+ CK_SLOT_INFO slotInfo;
+ NSSSlot *slot = token->slot;
+ session = token->defaultSession;
+ nssSession_EnterMonitor(session);
+ /* First obtain the slot info */
+ ckrv = CKAPI(slot)->C_GetSlotInfo(slot->slotID, &slotInfo);
+ if (ckrv != CKR_OK) {
+ nssSession_ExitMonitor(session);
+ return PR_FALSE;
+ }
+ slot->ckFlags = slotInfo.flags;
+ /* check for the presence of the token */
+ if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) {
+ /* token is not present */
+ if (session->handle != CK_INVALID_SESSION) {
+ /* session is valid, close and invalidate it */
+ CKAPI(slot)->C_CloseSession(session->handle);
+ session->handle = CK_INVALID_SESSION;
+ }
+ nssSession_ExitMonitor(session);
+ return PR_FALSE;
+ }
+ /* token is present, use the session info to determine if the card
+ * has been removed and reinserted.
+ */
+ if (session != CK_INVALID_SESSION) {
+ CK_SESSION_INFO sessionInfo;
+ ckrv = CKAPI(slot)->C_GetSessionInfo(session->handle, &sessionInfo);
+ if (ckrv != CKR_OK) {
+ /* session is screwy, close and invalidate it */
+ CKAPI(slot)->C_CloseSession(session->handle);
+ session->handle = CK_INVALID_SESSION;
+ }
+ }
+ nssSession_ExitMonitor(session);
+ /* token not removed, finished */
+ if (session->handle != CK_INVALID_SESSION) {
+ return PR_TRUE;
+ } else {
+ /* token has been removed, need to refresh with new session */
+ nssrv = nssSlot_Refresh(slot);
+ if (nssrv != PR_SUCCESS) {
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+ }
+}
+
NSS_IMPLEMENT NSSItem *
nssToken_Digest
(
diff --git a/security/nss/lib/pk11wrap/dev3hack.c b/security/nss/lib/pk11wrap/dev3hack.c
index cbcd468e5..bc2ad6b61 100644
--- a/security/nss/lib/pk11wrap/dev3hack.c
+++ b/security/nss/lib/pk11wrap/dev3hack.c
@@ -154,6 +154,24 @@ nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
return rvToken;
}
+NSS_IMPLEMENT PRStatus
+nssSlot_Refresh
+(
+ NSSSlot *slot
+)
+{
+ PK11SlotInfo *nss3slot = slot->pk11slot;
+ if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) {
+ return PR_FAILURE;
+ }
+ slot->token->defaultSession = nssSession_ImportNSS3Session(slot->arena,
+ nss3slot->session,
+ nss3slot->sessionLock,
+ nss3slot->defRWSession);
+ nssToken_DestroyCertList(slot->token);
+ return nssToken_LoadCerts(slot->token);
+}
+
NSSTrustDomain *
nssToken_GetTrustDomain(NSSToken *token)
diff --git a/security/nss/lib/pk11wrap/dev3hack.h b/security/nss/lib/pk11wrap/dev3hack.h
index 2ae362a15..3b8f1abf8 100644
--- a/security/nss/lib/pk11wrap/dev3hack.h
+++ b/security/nss/lib/pk11wrap/dev3hack.h
@@ -52,6 +52,11 @@ void PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst);
NSSToken * PK11Slot_GetNSSToken(PK11SlotInfo *sl);
+NSS_EXTERN void
+nssToken_DestroyCertList(NSSToken *token);
+
+NSS_IMPLEMENT PRStatus
+nssToken_LoadCerts(NSSToken *token);
PR_END_EXTERN_C
diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c
index 525fb2e05..37b1e1324 100644
--- a/security/nss/lib/pk11wrap/pk11cert.c
+++ b/security/nss/lib/pk11wrap/pk11cert.c
@@ -745,7 +745,12 @@ PK11_DeleteTokenCertAndKey(CERTCertificate *cert,void *wincx)
pubKey = pk11_FindPubKeyByAnyCert(cert, &slot, wincx);
if (privKey) {
+#ifdef NSS_CLASSIC
PK11_DestroyTokenObject(cert->slot,cert->pkcs11ID);
+#else
+ /* For 3.4, utilize the generic cert delete function */
+ SEC_DeletePermCertificate(cert);
+#endif
PK11_DeleteTokenPrivateKey(privKey);
}
if ((pubKey != CK_INVALID_HANDLE) && (slot != NULL)) {
@@ -999,12 +1004,25 @@ pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *),
return SECSuccess;
}
+struct fake_der_cb_argstr
+{
+ SECStatus(* callback)(CERTCertificate*, SECItem *, void *);
+ void *arg;
+};
+
+static PRStatus fake_der_cb(CERTCertificate *c, void *a)
+{
+ struct fake_der_cb_argstr *fda = (struct fake_der_cb_argstr *)a;
+ return (*fda->callback)(c, &c->derCert, fda->arg);
+}
+
/*
* Extract all the certs on a card from a slot.
*/
SECStatus
PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *),
void *arg, void *wincx) {
+#ifdef NSS_CLASSIC
pk11DoCertCallback caller;
pk11TraverseSlot creater;
CK_ATTRIBUTE theTemplate;
@@ -1022,6 +1040,17 @@ PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *),
creater.templateCount = 1;
return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, wincx);
+#else
+ NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
+ struct fake_der_cb_argstr fda;
+ struct nss3_cert_cbstr pk11cb;
+ fda.callback = callback;
+ fda.arg = arg;
+ pk11cb.callback = fake_der_cb;
+ pk11cb.arg = &fda;
+ NSSTrustDomain_TraverseCertificates(defaultTD, convert_cert, &pk11cb);
+ return SECSuccess;
+#endif
}
/*
@@ -1181,7 +1210,106 @@ get_newest_cert(NSSCertificate *c, void *arg)
return PR_SUCCESS;
}
-
+struct token_cbstr {
+ NSSToken *token;
+ PRStatus (* callback)(NSSCertificate *c, void *arg);
+ void *cbarg;
+};
+
+/* This callback matches all certs on a given token. It is used to filter
+ * cert lists to only those certs on a particular token.
+ */
+static PRStatus
+token_callback(NSSCertificate *c, void *arg)
+{
+ nssListIterator *instances;
+ nssCryptokiInstance *instance;
+ PRBool isToken = PR_FALSE;
+ struct token_cbstr *token_cb = (struct token_cbstr *)arg;
+ instances = c->object.instances;
+ for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
+ instance != (nssCryptokiInstance *)NULL;
+ instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
+ {
+ if (instance->token == token_cb->token) {
+ isToken = PR_TRUE;
+ break;
+ }
+ }
+ nssListIterator_Finish(instances);
+ if (isToken) {
+ return (*token_cb->callback)(c, token_cb->cbarg);
+ } else {
+ return PR_SUCCESS;
+ }
+}
+
+/* match all token certs with a nickname */
+static nssList *
+filter_token_certs_nickname(NSSToken *token, NSSUTF8 *nickname)
+{
+ nssListIterator *certs;
+ NSSCertificate *cert;
+ PRStatus nssrv;
+ nssList *rvList;
+ certs = nssList_CreateIterator(token->certList);
+ if (!certs) return NULL;
+ rvList = nssList_Create(NULL, PR_FALSE);
+ if (!rvList) {
+ nssListIterator_Destroy(certs);
+ return NULL;
+ }
+ for (cert = (NSSCertificate *)nssListIterator_Start(certs);
+ cert != (NSSCertificate *)NULL;
+ cert = (NSSCertificate *)nssListIterator_Next(certs))
+ {
+ if (!cert->nickname) continue;
+ if (nssUTF8_Equal(cert->nickname, nickname, &nssrv)) {
+ nssList_Add(rvList, nssCertificate_AddRef(cert));
+ }
+ }
+ nssListIterator_Finish(certs);
+ nssListIterator_Destroy(certs);
+ if (nssList_Count(rvList) == 0) {
+ nssList_Destroy(rvList);
+ rvList = NULL;
+ }
+ return rvList;
+}
+
+/* match all token certs with an email address */
+static nssList *
+filter_token_certs_email(NSSToken *token, NSSASCII7 *email)
+{
+ nssListIterator *certs;
+ NSSCertificate *cert;
+ PRStatus nssrv;
+ nssList *rvList;
+ certs = nssList_CreateIterator(token->certList);
+ if (!certs) return NULL;
+ rvList = nssList_Create(NULL, PR_FALSE);
+ if (!rvList) {
+ nssListIterator_Destroy(certs);
+ return NULL;
+ }
+ for (cert = (NSSCertificate *)nssListIterator_Start(certs);
+ cert != (NSSCertificate *)NULL;
+ cert = (NSSCertificate *)nssListIterator_Next(certs))
+ {
+ if (!cert->email) continue;
+ if (nssUTF8_Equal(cert->email, email, &nssrv)) {
+ nssList_Add(rvList, nssCertificate_AddRef(cert));
+ }
+ }
+ nssListIterator_Finish(certs);
+ nssListIterator_Destroy(certs);
+ if (nssList_Count(rvList) == 0) {
+ nssList_Destroy(rvList);
+ rvList = NULL;
+ }
+ return rvList;
+}
+
CERTCertificate *
PK11_FindCertFromNickname(char *nickname, void *wincx) {
#ifdef NSS_CLASSIC
@@ -1202,12 +1330,14 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
NSSUsage usage;
NSSToken *token;
PK11SlotInfo *slot = NULL;
+ char *nickCopy;
char *delimit = NULL;
char *tokenName;
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
usage.anyUsage = PR_TRUE;
- if ((delimit = PORT_Strchr(nickname,':')) != NULL) {
- tokenName = nickname;
+ nickCopy = PORT_Strdup(nickname);
+ if ((delimit = PORT_Strchr(nickCopy,':')) != NULL) {
+ tokenName = nickCopy;
nickname = delimit + 1;
*delimit = '\0';
/* find token by name */
@@ -1220,6 +1350,7 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
}
if (token) {
nssTokenCertSearch search;
+ struct token_cbstr token_cb;
nssList *certList;
if (!PK11_IsFriendly(slot)) {
if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) {
@@ -1227,33 +1358,77 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
return NULL;
}
}
- certList = nssList_Create(NULL, PR_FALSE);
- (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
- nickname,
- certList);
- /* set the search criteria */
- search.callback = get_newest_cert;
- search.cbarg = (void *)&cert;
- search.cached = certList;
- search.searchType = nssTokenSearchType_TokenOnly;
/* find best cert on token */
- nssToken_TraverseCertificatesByNickname(token, NULL,
- (NSSUTF8 *)nickname,
- &search);
- nssList_Clear(certList, cert_destructor);
- nssList_Destroy(certList);
- if (!cert) {
+ if (!nssToken_SearchCerts(token)) {
+ /* token certs are in cache, filter the list of token certs to
+ * match the nickname
+ */
+ certList = filter_token_certs_nickname(token, nickname);
+ if (certList) {
+ nssCertificateList_DoCallback(certList,
+ get_newest_cert,
+ (void *)&cert);
+ }
+ } else {
+ /* find matching certs on the token */
certList = nssList_Create(NULL, PR_FALSE);
- (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD,
- nickname,
- certList);
+ if (!certList) return NULL;
+ /* first, get all matching certs from the cache */
+ (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
+ nickname,
+ certList);
+ /* set the search criteria */
+ token_cb.callback = get_newest_cert;
+ token_cb.cbarg = (void *)&cert;
+ token_cb.token = token;
+ search.callback = token_callback;
+ search.cbarg = &token_cb;
search.cached = certList;
- nssToken_TraverseCertificatesByEmail(token, NULL,
- (NSSASCII7 *)nickname,
- &search);
+ search.searchType = nssTokenSearchType_TokenOnly;
+ /* then filter the list of cached certs for only those on the
+ * token
+ */
+ nssCertificateList_DoCallback(certList,
+ token_callback,
+ &token_cb);
+ /* now search the token */
+ nssToken_TraverseCertificatesByNickname(token, NULL,
+ (NSSUTF8 *)nickname,
+ &search);
+ }
+ if (certList) {
nssList_Clear(certList, cert_destructor);
nssList_Destroy(certList);
}
+ /* if it wasn't found, repeat the process for email address */
+ if (!cert) {
+ if (!nssToken_SearchCerts(token)) {
+ certList = filter_token_certs_email(token, nickname);
+ if (certList) {
+ nssCertificateList_DoCallback(certList,
+ get_newest_cert,
+ (void *)&cert);
+ }
+ } else {
+ certList = nssList_Create(NULL, PR_FALSE);
+ if (!certList) return NULL;
+ (void)nssTrustDomain_GetCertsForEmailAddressFromCache(
+ defaultTD,
+ nickname,
+ certList);
+ search.cached = certList;
+ nssCertificateList_DoCallback(certList,
+ token_callback,
+ &token_cb);
+ nssToken_TraverseCertificatesByEmail(token, NULL,
+ (NSSASCII7 *)nickname,
+ &search);
+ }
+ if (certList) {
+ nssList_Clear(certList, cert_destructor);
+ nssList_Destroy(certList);
+ }
+ }
if (cert) {
(void)nssTrustDomain_AddCertsToCache(defaultTD, &cert, 1);
rvCert = STAN_GetCERTCertificate(cert);
@@ -1262,6 +1437,7 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
if (slot) {
PK11_FreeSlot(slot);
}
+ if (nickCopy) PORT_Free(nickCopy);
return rvCert;
#endif
}
@@ -1306,6 +1482,7 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
return certList;
#else
PRStatus nssrv;
+ char *nickCopy;
char *delimit = NULL;
char *tokenName;
int i;
@@ -1315,8 +1492,9 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
NSSCertificate *c;
NSSToken *token;
PK11SlotInfo *slot;
- if ((delimit = PORT_Strchr(nickname,':')) != NULL) {
- tokenName = nickname;
+ nickCopy = PORT_Strdup(nickname);
+ if ((delimit = PORT_Strchr(nickCopy,':')) != NULL) {
+ tokenName = nickCopy;
nickname = delimit + 1;
*delimit = '\0';
/* find token by name */
@@ -1337,25 +1515,33 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
return NULL;
}
}
- nameList = nssList_Create(NULL, PR_FALSE);
- (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
- nickname,
- nameList);
- /* set the search criteria */
- search.callback = collect_certs;
- search.cbarg = nameList;
- search.cached = nameList;
- search.searchType = nssTokenSearchType_TokenOnly;
- nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
- nickname, &search);
- count = nssList_Count(nameList);
- foundCerts = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
- nssList_GetArray(nameList, (void **)foundCerts, count);
- nssList_Destroy(nameList);
+ if (!nssToken_SearchCerts(token)) {
+ nameList = filter_token_certs_nickname(token, nickname);
+ } else {
+ nameList = nssList_Create(NULL, PR_FALSE);
+ if (!nameList) return NULL;
+ (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
+ nickname,
+ nameList);
+ /* set the search criteria */
+ search.callback = collect_certs;
+ search.cbarg = nameList;
+ search.cached = nameList;
+ search.searchType = nssTokenSearchType_TokenOnly;
+ nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
+ nickname, &search);
+ }
+ if (nameList) {
+ count = nssList_Count(nameList);
+ foundCerts = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
+ nssList_GetArray(nameList, (void **)foundCerts, count);
+ nssList_Destroy(nameList);
+ }
}
if (slot) {
PK11_FreeSlot(slot);
}
+ if (nickCopy) PORT_Free(nickCopy);
if (foundCerts) {
certList = CERT_NewCertList();
for (i=0, c = *foundCerts; c; c = foundCerts[++i]) {
@@ -1504,6 +1690,7 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
CK_RV crv;
SECCertUsage *certUsage = NULL;
SECItem derSerial = { 0 };
+ NSSToken *token;
if (keyID == NULL) {
PORT_SetError(SEC_ERROR_ADDING_CERT);
@@ -1604,6 +1791,16 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
cert->nssCertificate = STAN_GetNSSCertificate(cert);
}
}
+ cert->trust = nssTrust_GetCERTCertTrustForCert(cert->nssCertificate, cert);
+ token = PK11Slot_GetNSSToken(slot);
+ if (token->certList) {
+ /* create a persistent reference for the token */
+ NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
+ nssCertificate_AddRef(cert->nssCertificate);
+ nssList_Add(token->certList, cert->nssCertificate);
+ /* and add the cert to the cache */
+ nssTrustDomain_AddCertsToCache(td, &cert->nssCertificate, 1);
+ }
done:
if (derSerial.data) PORT_Free(derSerial.data);
@@ -2368,6 +2565,72 @@ PK11_TraverseCertsForSubject(CERTCertificate *cert,
return PK11_TraverseCertsForSubjectInSlot(cert, cert->slot, callback, arg);
}
+/* Find all certs with a given subject in the list of token certs */
+static nssList *
+filter_token_certs_subject(NSSToken *token, NSSDER *subject)
+{
+ nssListIterator *certs;
+ NSSCertificate *cert;
+ PRStatus nssrv;
+ nssList *rvList;
+ certs = nssList_CreateIterator(token->certList);
+ if (!certs) return NULL;
+ rvList = nssList_Create(NULL, PR_FALSE);
+ if (!rvList) {
+ nssListIterator_Destroy(certs);
+ return NULL;
+ }
+ for (cert = (NSSCertificate *)nssListIterator_Start(certs);
+ cert != (NSSCertificate *)NULL;
+ cert = (NSSCertificate *)nssListIterator_Next(certs))
+ {
+ if (nssItem_Equal(&cert->subject, subject, &nssrv)) {
+ nssList_Add(rvList, nssCertificate_AddRef(cert));
+ }
+ }
+ nssListIterator_Finish(certs);
+ nssListIterator_Destroy(certs);
+ if (nssList_Count(rvList) == 0) {
+ nssList_Destroy(rvList);
+ rvList = NULL;
+ }
+ return rvList;
+}
+
+/* remove all certs in a list that are not on the given token */
+static void
+filter_list_for_token_certs(nssList *certList, NSSToken *token)
+{
+ nssListIterator *instances, *certs;
+ nssCryptokiInstance *instance;
+ NSSCertificate *c;
+ PRBool isToken = PR_FALSE;
+ certs = nssList_CreateIterator(certList);
+ if (!certs) return;
+ for (c = (NSSCertificate *)nssListIterator_Start(certs);
+ c != (NSSCertificate *)NULL;
+ c = (NSSCertificate *)nssListIterator_Next(certs)) {
+ instances = c->object.instances;
+ for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
+ instance != (nssCryptokiInstance *)NULL;
+ instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
+ {
+ if (instance->token == token) {
+ isToken = PR_TRUE;
+ break;
+ }
+ }
+ nssListIterator_Finish(instances);
+ if (!isToken) {
+ /* safe since iterator is copied */
+ nssList_Remove(certList, c);
+ NSSCertificate_Destroy(c);
+ }
+ }
+ nssListIterator_Finish(certs);
+ nssListIterator_Destroy(certs);
+}
+
SECStatus
PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
SECStatus(* callback)(CERTCertificate*, void *), void *arg)
@@ -2401,7 +2664,7 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
return PK11_TraverseSlot(slot, &callarg);
#else
struct nss3_cert_cbstr pk11cb;
- PRStatus nssrv;
+ PRStatus nssrv = PR_SUCCESS;
NSSToken *token;
NSSDER subject;
NSSTrustDomain *td;
@@ -2411,19 +2674,38 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
pk11cb.arg = arg;
td = STAN_GetDefaultTrustDomain();
NSSITEM_FROM_SECITEM(&subject, &cert->derSubject);
- subjectList = nssList_Create(NULL, PR_FALSE);
- (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject, subjectList);
- /* set the search criteria */
- search.callback = convert_and_cache_cert;
- search.cbarg = &pk11cb;
- search.cached = subjectList;
- search.searchType = nssTokenSearchType_TokenOnly;
- pk11cb.cached = subjectList;
token = PK11Slot_GetNSSToken(slot);
- nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
- &subject, &search);
- nssList_Clear(subjectList, cert_destructor);
- nssList_Destroy(subjectList);
+ if (!nssToken_SearchCerts(token)) {
+ subjectList = filter_token_certs_subject(token, &subject);
+ if (subjectList) {
+ nssrv = nssCertificateList_DoCallback(subjectList,
+ convert_cert, &pk11cb);
+ }
+ } else {
+ subjectList = nssList_Create(NULL, PR_FALSE);
+ if (!subjectList) {
+ return SECFailure;
+ }
+ (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject,
+ subjectList);
+ filter_list_for_token_certs(subjectList, token);
+ /* set the search criteria */
+ search.callback = convert_and_cache_cert;
+ search.cbarg = &pk11cb;
+ search.cached = subjectList;
+ search.searchType = nssTokenSearchType_TokenOnly;
+ pk11cb.cached = subjectList;
+ nssrv = nssCertificateList_DoCallback(subjectList,
+ convert_cert, &pk11cb);
+ if (nssrv == PR_SUCCESS) {
+ nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
+ &subject, &search);
+ }
+ }
+ if (subjectList) {
+ nssList_Clear(subjectList, cert_destructor);
+ nssList_Destroy(subjectList);
+ }
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
#endif
}
@@ -2466,7 +2748,7 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
return PK11_TraverseSlot(slot, &callarg);
#else
struct nss3_cert_cbstr pk11cb;
- PRStatus nssrv;
+ PRStatus nssrv = PR_SUCCESS;
NSSToken *token;
NSSTrustDomain *td;
NSSUTF8 *nick;
@@ -2477,25 +2759,40 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
pk11cb.arg = arg;
if (nickname->data[nickname->len-1] != '\0') {
nick = nssUTF8_Create(NULL, nssStringType_UTF8String,
- nickname->data, nickname->len-1);
+ nickname->data, nickname->len);
created = PR_TRUE;
} else {
nick = (NSSUTF8 *)nickname->data;
}
td = STAN_GetDefaultTrustDomain();
- nameList = nssList_Create(NULL, PR_FALSE);
- (void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList);
- /* set the search criteria */
- search.callback = convert_and_cache_cert;
- search.cbarg = &pk11cb;
- search.cached = nameList;
- search.searchType = nssTokenSearchType_TokenOnly;
- pk11cb.cached = nameList;
token = PK11Slot_GetNSSToken(slot);
- nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
- nick, &search);
- nssList_Clear(nameList, cert_destructor);
- nssList_Destroy(nameList);
+ if (!nssToken_SearchCerts(token)) {
+ nameList = filter_token_certs_nickname(token, nick);
+ if (nameList) {
+ nssrv = nssCertificateList_DoCallback(nameList,
+ convert_cert, &pk11cb);
+ }
+ } else {
+ nameList = nssList_Create(NULL, PR_FALSE);
+ (void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList);
+ filter_list_for_token_certs(nameList, token);
+ /* set the search criteria */
+ search.callback = convert_and_cache_cert;
+ search.cbarg = &pk11cb;
+ search.cached = nameList;
+ search.searchType = nssTokenSearchType_TokenOnly;
+ pk11cb.cached = nameList;
+ nssrv = nssCertificateList_DoCallback(nameList,
+ convert_cert, &pk11cb);
+ if (nssrv == PR_SUCCESS) {
+ nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
+ nick, &search);
+ }
+ }
+ if (nameList) {
+ nssList_Clear(nameList, cert_destructor);
+ nssList_Destroy(nameList);
+ }
if (created) nss_ZFreeIf(nick);
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
#endif
@@ -2535,29 +2832,62 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
struct nss3_cert_cbstr pk11cb;
NSSToken *tok;
- nssList *certList = nssList_Create(NULL, PR_FALSE);
+ nssList *certList = NULL;
nssTokenCertSearch search;
pk11cb.callback = callback;
pk11cb.arg = arg;
- (void *)nssTrustDomain_GetCertsFromCache(td, certList);
- /* set the search criteria */
- search.callback = convert_and_cache_cert;
- search.cbarg = &pk11cb;
- search.cached = certList;
- search.searchType = nssTokenSearchType_TokenOnly;
- pk11cb.cached = certList;
tok = PK11Slot_GetNSSToken(slot);
- if (tok) {
- nssrv = nssToken_TraverseCertificates(tok, NULL, &search);
+ if (!nssToken_SearchCerts(tok)) {
+ certList = tok->certList;
+ nssrv = nssCertificateList_DoCallback(certList, convert_cert, &pk11cb);
} else {
- nssrv = PR_FAILURE;
+ certList = nssList_Create(NULL, PR_FALSE);
+ if (!certList) {
+ return SECFailure;
+ }
+ (void *)nssTrustDomain_GetCertsFromCache(td, certList);
+ filter_list_for_token_certs(certList, tok);
+ /* set the search criteria */
+ search.callback = convert_and_cache_cert;
+ search.cbarg = &pk11cb;
+ search.cached = certList;
+ search.searchType = nssTokenSearchType_TokenOnly;
+ pk11cb.cached = certList;
+ nssrv = nssCertificateList_DoCallback(certList,
+ convert_cert, &pk11cb);
+ if (nssrv == PR_SUCCESS) {
+ nssrv = nssToken_TraverseCertificates(tok, NULL, &search);
+ }
+ nssList_Clear(certList, cert_destructor);
+ nssList_Destroy(certList);
}
- nssList_Clear(certList, cert_destructor);
- nssList_Destroy(certList);
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
#endif
}
+static NSSCertificate *
+filter_token_certs_DER(NSSToken *token, NSSDER *der)
+{
+ nssListIterator *certs;
+ NSSCertificate *cert, *rvCert;
+ PRStatus nssrv;
+ certs = nssList_CreateIterator(token->certList);
+ if (!certs) return NULL;
+ rvCert = NULL;
+ for (cert = (NSSCertificate *)nssListIterator_Start(certs);
+ cert != (NSSCertificate *)NULL;
+ cert = (NSSCertificate *)nssListIterator_Next(certs))
+ {
+ if (nssItem_Equal(&cert->encoding, der, &nssrv)) {
+ rvCert = nssCertificate_AddRef(cert);
+ break;
+ }
+ }
+ nssListIterator_Finish(certs);
+ nssListIterator_Destroy(certs);
+ return rvCert;
+}
+
/*
* return the certificate associated with a derCert
*/
@@ -2599,11 +2929,19 @@ PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
NSSCertificate *c;
NSSDER derCert;
NSSToken *tok;
+ NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
tok = PK11Slot_GetNSSToken(slot);
NSSITEM_FROM_SECITEM(&derCert, &cert->derCert);
- /* XXX login to slots */
- c = nssToken_FindCertificateByEncodedCertificate(tok, NULL, &derCert,
+ if (!nssToken_SearchCerts(tok)) {
+ c = filter_token_certs_DER(tok, &derCert);
+ } else {
+ c = nssTrustDomain_GetCertByDERFromCache(td, &derCert);
+ if (!c) {
+ c = nssToken_FindCertificateByEncodedCertificate(tok, NULL,
+ &derCert,
nssTokenSearchType_TokenOnly);
+ }
+ }
if (c) {
rvCert = STAN_GetCERTCertificate(c);
}
diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c
index 44dbfe4f0..1bfe1d7c8 100644
--- a/security/nss/lib/pki/certificate.c
+++ b/security/nss/lib/pki/certificate.c
@@ -110,13 +110,28 @@ NSSCertificate_DeleteStoredObject
instance != (nssCryptokiInstance *)NULL;
instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
{
+ /* XXX this should be fixed to understand read-only tokens, for
+ * now, to handle the builtins, just make the attempt.
+ */
nssrv = nssToken_DeleteStoredObject(instance);
- if (nssrv != PR_SUCCESS) {
- break;
+ if (nssrv == PR_SUCCESS) {
+ nssList_Remove(c->object.instanceList, instance);
+#ifdef NSS_3_4_CODE
+ if (instance->token->certList) {
+ /* If the cert has been cached locally on the token, remove
+ * that reference
+ */
+ nssList_Remove(instance->token->certList, c);
+ NSSCertificate_Destroy(c);
+ }
+#endif
}
}
nssListIterator_Finish(instances);
- return nssrv;
+ c->object.instances = nssList_CreateIterator(c->object.instanceList);
+ nssListIterator_Destroy(instances);
+ /* XXX for now, always success */
+ return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
@@ -803,3 +818,27 @@ loser:
return NULL;
}
+/* execute a callback function on all members of a cert list */
+NSS_EXTERN PRStatus
+nssCertificateList_DoCallback
+(
+ nssList *certList,
+ PRStatus (* callback)(NSSCertificate *c, void *arg),
+ void *arg
+)
+{
+ nssListIterator *certs;
+ NSSCertificate *cert;
+ PRStatus nssrv;
+ certs = nssList_CreateIterator(certList);
+ for (cert = (NSSCertificate *)nssListIterator_Start(certs);
+ cert != (NSSCertificate *)NULL;
+ cert = (NSSCertificate *)nssListIterator_Next(certs))
+ {
+ nssrv = (*callback)(cert, arg);
+ }
+ nssListIterator_Finish(certs);
+ nssListIterator_Destroy(certs);
+ return PR_SUCCESS;
+}
+
diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c
index 3239051ef..09d103119 100644
--- a/security/nss/lib/pki/pki3hack.c
+++ b/security/nss/lib/pki/pki3hack.c
@@ -68,6 +68,10 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "certt.h"
#include "cert.h"
#include "pk11func.h"
+#include "pkistore.h"
+
+/* if it's got more than 10 certs, it better handle traversal well */
+#define NSSTOKEN_MAX_LOCAL_CERTS 10
NSSTrustDomain *g_default_trust_domain = NULL;
@@ -95,7 +99,88 @@ STAN_GetDefaultCryptoToken
return PK11Slot_GetNSSToken(pk11slot);
}
+/* stuff the cert in the global trust domain cache, and then add a reference
+ * to remain with the token in a list.
+ */
+static PRStatus
+cache_token_cert(NSSCertificate *c, void *arg)
+{
+ NSSToken *token = (NSSToken *)arg;
+ NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
+ if (nssList_Count(token->certList) > NSSTOKEN_MAX_LOCAL_CERTS) {
+ nssToken_DestroyCertList(token);
+ /* terminate the traversal */
+ return PR_FAILURE;
+ }
+ nssTrustDomain_AddCertsToCache(td, &c, 1);
+ /* This list reference persists with the token */
+ nssList_Add(token->certList, nssCertificate_AddRef(c));
+ /* The cert needs to become external (made into a CERTCertificate)
+ * in order for it to be properly released.
+ */
+ (void)STAN_GetCERTCertificate(c);
+ return PR_SUCCESS;
+}
+
+static void cert_destructor(void *el)
+{
+ NSSCertificate *c = (NSSCertificate *)el;
+ CERTCertificate *cert = STAN_GetCERTCertificate(c);
+ CERT_DestroyCertificate(cert);
+}
+
+/* destroy the list of certs on a token */
NSS_IMPLEMENT void
+nssToken_DestroyCertList(NSSToken *token)
+{
+ nssList_Clear(token->certList, cert_destructor);
+ nssList_Destroy(token->certList);
+ token->certList = NULL;
+}
+
+/* create a list of local cert references for certain tokens */
+NSS_IMPLEMENT PRStatus
+nssToken_LoadCerts(NSSToken *token)
+{
+ PRStatus nssrv = PR_SUCCESS;
+ nssTokenCertSearch search;
+ if (!PK11_IsInternal(token->pk11slot) && PK11_IsHW(token->pk11slot)) {
+ /* Hardware token certs will be immediately cached, and no searches
+ * will be performed on the token (the certs will be discovered by
+ * cache lookups)
+ */
+ search.callback = cache_token_cert;
+ search.cbarg = token;
+ search.cached = NULL;
+ search.searchType = nssTokenSearchType_TokenOnly;
+ token->certList = nssList_Create(token->arena, PR_FALSE);
+ if (!token->certList) {
+ return PR_FAILURE;
+ }
+ /* ignore the rv, just work without the list */
+ (void)nssToken_TraverseCertificates(token, NULL, &search);
+ /* even if there are no certs, leave a valid list pointer should
+ * any be imported. Having the pointer will also prevent searches,
+ * see below.
+ */
+ }
+ return nssrv;
+}
+
+NSS_IMPLEMENT PRBool
+nssToken_SearchCerts
+(
+ NSSToken *token
+)
+{
+ if (!nssToken_IsPresent(token)) {
+ STAN_DestroyNSSToken(token); /* will free cached certs */
+ } else {
+ return (token->certList == NULL);
+ }
+}
+
+NSS_IMPLEMENT PRStatus
STAN_LoadDefaultNSS3TrustDomain
(
void
@@ -107,8 +192,7 @@ STAN_LoadDefaultNSS3TrustDomain
PK11SlotListElement *le;
td = NSSTrustDomain_Create(NULL, NULL, NULL, NULL);
if (!td) {
- /* um, some kind a fatal here */
- return;
+ return PR_FAILURE;
}
td->tokenList = nssList_Create(td->arena, PR_TRUE);
list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL);
@@ -123,9 +207,18 @@ STAN_LoadDefaultNSS3TrustDomain
*/
PK11_FreeSlotList(list);
}
- td->tokens = nssList_CreateIterator(td->tokenList);
g_default_trust_domain = td;
g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL);
+ /* Cache hardware token certs with the token to make them persistent */
+ td->tokens = nssList_CreateIterator(td->tokenList);
+ for (token = (NSSToken *)nssListIterator_Start(td->tokens);
+ token != (NSSToken *)NULL;
+ token = (NSSToken *)nssListIterator_Next(td->tokens))
+ {
+ nssToken_LoadCerts(token);
+ }
+ nssListIterator_Finish(td->tokens);
+ return PR_SUCCESS;
}
NSS_IMPLEMENT SECStatus
@@ -141,6 +234,7 @@ STAN_AddModuleToDefaultTrustDomain
for (i=0; i<module->slotCount; i++) {
token = nssToken_CreateFromPK11SlotInfo(td, module->slots[i]);
PK11Slot_SetNSSToken(module->slots[i], token);
+ nssToken_LoadCerts(token);
nssList_Add(td->tokenList, token);
}
nssListIterator_Destroy(td->tokens);
@@ -148,6 +242,15 @@ STAN_AddModuleToDefaultTrustDomain
return SECSuccess;
}
+NSS_IMPLEMENT void
+STAN_DestroyNSSToken(NSSToken *token)
+{
+ if (token->certList) {
+ nssToken_DestroyCertList(token);
+ }
+ nssToken_Destroy(token);
+}
+
NSS_IMPLEMENT SECStatus
STAN_RemoveModuleFromDefaultTrustDomain
(
@@ -161,6 +264,7 @@ STAN_RemoveModuleFromDefaultTrustDomain
for (i=0; i<module->slotCount; i++) {
token = PK11Slot_GetNSSToken(module->slots[i]);
nssList_Remove(td->tokenList, token);
+ STAN_DestroyNSSToken(token);
}
nssListIterator_Destroy(td->tokens);
td->tokens = nssList_CreateIterator(td->tokenList);
@@ -478,7 +582,7 @@ static int nsstoken_get_trust_order(NSSToken *token)
return module->trustOrder;
}
-static CERTCertTrust *
+CERTCertTrust *
nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
{
CERTCertTrust *rvTrust;
diff --git a/security/nss/lib/pki/pki3hack.h b/security/nss/lib/pki/pki3hack.h
index 8688264c3..df4010285 100644
--- a/security/nss/lib/pki/pki3hack.h
+++ b/security/nss/lib/pki/pki3hack.h
@@ -60,7 +60,7 @@ STAN_GetDefaultTrustDomain();
NSS_EXTERN NSSCryptoContext *
STAN_GetDefaultCryptoContext();
-NSS_EXTERN void
+NSS_EXTERN PRStatus
STAN_LoadDefaultNSS3TrustDomain
(
void
@@ -69,13 +69,22 @@ STAN_LoadDefaultNSS3TrustDomain
NSS_EXTERN void
STAN_Shutdown();
+NSS_EXTERN void
+STAN_DestroyNSSToken(NSSToken *token);
+
+NSS_EXTERN PRBool
+nssToken_SearchCerts
+(
+ NSSToken *token
+);
+
NSS_EXTERN SECStatus
STAN_AddModuleToDefaultTrustDomain
(
SECMODModule *module
);
-NSS_IMPLEMENT SECStatus
+NSS_EXTERN SECStatus
STAN_RemoveModuleFromDefaultTrustDomain
(
SECMODModule *module
@@ -87,6 +96,9 @@ STAN_GetCERTCertificate(NSSCertificate *c);
NSS_EXTERN NSSCertificate *
STAN_GetNSSCertificate(CERTCertificate *c);
+NSS_EXTERN CERTCertTrust *
+nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc);
+
NSS_EXTERN PRStatus
STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust);
diff --git a/security/nss/lib/pki/pkim.h b/security/nss/lib/pki/pkim.h
index bd16fd3ad..5473c5a1a 100644
--- a/security/nss/lib/pki/pkim.h
+++ b/security/nss/lib/pki/pkim.h
@@ -282,6 +282,14 @@ nssBestCertificate_Callback
);
NSS_EXTERN PRStatus
+nssCertificateList_DoCallback
+(
+ nssList *certList,
+ PRStatus (* callback)(NSSCertificate *c, void *arg),
+ void *arg
+);
+
+NSS_EXTERN PRStatus
nssPKIObject_Initialize
(
struct nssPKIObjectBaseStr *object,
diff --git a/security/nss/lib/pki/trustdomain.c b/security/nss/lib/pki/trustdomain.c
index c55a27ec1..a4047063e 100644
--- a/security/nss/lib/pki/trustdomain.c
+++ b/security/nss/lib/pki/trustdomain.c
@@ -109,8 +109,10 @@ token_destructor(void *t)
#ifdef NSS_3_4_CODE
/* in 3.4, also destroy the slot (managed separately) */
(void)nssSlot_Destroy(tok->slot);
-#endif
+ STAN_DestroyNSSToken(tok);
+#else
(void)nssToken_Destroy(tok);
+#endif
}
NSS_IMPLEMENT PRStatus
@@ -419,13 +421,17 @@ NSSTrustDomain_FindBestCertificateByNickname
search.cbarg = &best;
search.cached = nameList;
search.searchType = nssTokenSearchType_TokenOnly;
+ nssCertificateList_DoCallback(nameList,
+ nssBestCertificate_Callback, &best);
/* traverse the tokens */
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
token != (NSSToken *)NULL;
token = (NSSToken *)nssListIterator_Next(td->tokens))
{
- nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
- name, &search);
+ if (nssToken_SearchCerts(token)) {
+ nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
+ name, &search);
+ }
}
nssListIterator_Finish(td->tokens);
nssList_Clear(nameList, cert_destructor);
@@ -468,8 +474,10 @@ NSSTrustDomain_FindCertificatesByNickname
token != (NSSToken *)NULL;
token = (NSSToken *)nssListIterator_Next(td->tokens))
{
- nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
- name, &search);
+ if (nssToken_SearchCerts(token)) {
+ nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
+ name, &search);
+ }
}
nssListIterator_Finish(td->tokens);
count = nssList_Count(nameList);
@@ -511,11 +519,13 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
- rvCert = nssToken_FindCertificateByIssuerAndSerialNumber(tok,
+ if (nssToken_SearchCerts(tok)) {
+ rvCert = nssToken_FindCertificateByIssuerAndSerialNumber(tok,
NULL,
issuer,
serialNumber,
nssTokenSearchType_TokenOnly);
+ }
#ifdef NSS_3_4_CODE
if (!rvCert) {
/* Some tokens expect a decoded serial number. For compatibility,
@@ -531,11 +541,14 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
if (secrv == SECSuccess) {
decodedSerial.data = ds.data;
decodedSerial.size = ds.len;
- rvCert = nssToken_FindCertificateByIssuerAndSerialNumber(tok,
+ if (nssToken_SearchCerts(tok)) {
+ rvCert = nssToken_FindCertificateByIssuerAndSerialNumber(
+ tok,
NULL,
issuer,
&decodedSerial,
nssTokenSearchType_TokenOnly);
+ }
PORT_Free(ds.data);
}
}
@@ -575,13 +588,17 @@ NSSTrustDomain_FindBestCertificateBySubject
search.cbarg = &best;
search.cached = subjectList;
search.searchType = nssTokenSearchType_TokenOnly;
+ nssCertificateList_DoCallback(subjectList,
+ nssBestCertificate_Callback, &best);
/* traverse the tokens */
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
token != (NSSToken *)NULL;
token = (NSSToken *)nssListIterator_Next(td->tokens))
{
- nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
- subject, &search);
+ if (nssToken_SearchCerts(token)) {
+ nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
+ subject, &search);
+ }
}
nssListIterator_Finish(td->tokens);
nssList_Clear(subjectList, cert_destructor);
@@ -624,8 +641,10 @@ NSSTrustDomain_FindCertificatesBySubject
token != (NSSToken *)NULL;
token = (NSSToken *)nssListIterator_Next(td->tokens))
{
- nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
- subject, &search);
+ if (nssToken_SearchCerts(token)) {
+ nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
+ subject, &search);
+ }
}
nssListIterator_Finish(td->tokens);
count = nssList_Count(subjectList);
@@ -692,9 +711,11 @@ NSSTrustDomain_FindCertificateByEncodedCertificate
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
- rvCert = nssToken_FindCertificateByEncodedCertificate(tok, NULL,
+ if (nssToken_SearchCerts(tok)) {
+ rvCert = nssToken_FindCertificateByEncodedCertificate(tok, NULL,
encodedCertificate,
nssTokenSearchType_TokenOnly);
+ }
if (rvCert) {
/* cache it */
nssTrustDomain_AddCertsToCache(td, &rvCert, 1);
@@ -730,13 +751,17 @@ NSSTrustDomain_FindCertificateByEmail
search.cbarg = &best;
search.cached = emailList;
search.searchType = nssTokenSearchType_TokenOnly;
+ nssCertificateList_DoCallback(emailList,
+ nssBestCertificate_Callback, &best);
/* traverse the tokens */
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
token != (NSSToken *)NULL;
token = (NSSToken *)nssListIterator_Next(td->tokens))
{
- nssrv = nssToken_TraverseCertificatesByEmail(token, NULL,
- email, &search);
+ if (nssToken_SearchCerts(token)) {
+ nssrv = nssToken_TraverseCertificatesByEmail(token, NULL,
+ email, &search);
+ }
}
nssListIterator_Finish(td->tokens);
nssList_Clear(emailList, cert_destructor);
@@ -927,12 +952,16 @@ NSSTrustDomain_TraverseCertificates
search.cbarg = &ta;
search.cached = certList;
search.searchType = nssTokenSearchType_TokenOnly;
+ nssCertificateList_DoCallback(certList,
+ traverse_callback, &ta);
/* traverse the tokens */
for (token = (NSSToken *)nssListIterator_Start(td->tokens);
token != (NSSToken *)NULL;
token = (NSSToken *)nssListIterator_Next(td->tokens))
{
- nssrv = nssToken_TraverseCertificates(token, NULL, &search);
+ if (nssToken_SearchCerts(token)) {
+ nssrv = nssToken_TraverseCertificates(token, NULL, &search);
+ }
}
nssListIterator_Finish(td->tokens);
#ifdef NSS_3_4_CODE