check in cert lookup functions using the cache

This commit is contained in:
ian.mcgreer%sun.com 2001-10-12 17:54:50 +00:00
Родитель 7b3b57d83f
Коммит ee48e4329a
6 изменённых файлов: 276 добавлений и 145 удалений

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

@ -35,7 +35,7 @@
#define DEV_H #define DEV_H
#ifdef DEBUG #ifdef DEBUG
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.8 $ $Date: 2001-10-11 16:33:38 $ $Name: $"; static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.9 $ $Date: 2001-10-12 17:54:47 $ $Name: $";
#endif /* DEBUG */ #endif /* DEBUG */
#ifndef DEVT_H #ifndef DEVT_H
@ -298,6 +298,7 @@ nssToken_FindCertificatesByTemplate
( (
NSSToken *tok, NSSToken *tok,
nssSession *sessionOpt, nssSession *sessionOpt,
nssList *cachedList,
CK_ATTRIBUTE_PTR cktemplate, CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize, CK_ULONG ctsize,
PRStatus (*callback)(NSSCertificate *c, void *arg), PRStatus (*callback)(NSSCertificate *c, void *arg),

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

@ -32,7 +32,7 @@
*/ */
#ifdef DEBUG #ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: token.c,v $ $Revision: 1.9 $ $Date: 2001-10-11 18:40:31 $ $Name: $"; static const char CVS_ID[] = "@(#) $RCSfile: token.c,v $ $Revision: 1.10 $ $Date: 2001-10-12 17:54:48 $ $Name: $";
#endif /* DEBUG */ #endif /* DEBUG */
#ifndef DEV_H #ifndef DEV_H
@ -313,37 +313,30 @@ loser:
} }
struct cert_callback_str { struct cert_callback_str {
nssListIterator *cachedCerts;
PRStatus (*callback)(NSSCertificate *c, void *arg); PRStatus (*callback)(NSSCertificate *c, void *arg);
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 static PRStatus
retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg) retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg)
{ {
PRStatus nssrv; NSSCertificate *cert = NULL;
NSSCertificate *cert; NSSCertificate *c;
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; struct cert_callback_str *ccb = (struct cert_callback_str *)arg;
template_size = sizeof(cert_template) / sizeof(cert_template[0]); if (ccb->cachedCerts) {
/* Get the unique id */ for (c = (NSSCertificate *)nssListIterator_Start(ccb->cachedCerts);
nssrv = nssCKObject_GetAttributes(h, cert_template, template_size, c != (NSSCertificate *)NULL;
NULL, session, t->slot); c = (NSSCertificate *)nssListIterator_Next(ccb->cachedCerts))
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[0], &issuer); {
NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[1], &serial); if (c->handle == h && c->token == t) {
/* Look in the cert's trust domain cache first */ /* this is enough, right? */
cert = nssTrustDomain_GetCertForIssuerAndSNFromCache(t->trustDomain, cert = c;
&issuer, &serial); break;
nss_ZFreeIf(issuer.data); }
nss_ZFreeIf(serial.data); }
nssListIterator_Finish(ccb->cachedCerts);
}
if (!cert) { if (!cert) {
/* Could not find cert, so create it */ /* Could not find cert, so create it */
cert = NSSCertificate_CreateFromHandle(NULL, h, session, t->slot); cert = NSSCertificate_CreateFromHandle(NULL, h, session, t->slot);
@ -455,7 +448,7 @@ nssToken_TraverseCertificates
}; };
CK_ULONG ctsize = sizeof(cert_template) / sizeof(cert_template[0]); CK_ULONG ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert); NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
nssrv = nssToken_FindCertificatesByTemplate(tok, sessionOpt, nssrv = nssToken_FindCertificatesByTemplate(tok, sessionOpt, NULL,
cert_template, ctsize, cert_template, ctsize,
callback, arg); callback, arg);
return NULL; /* XXX */ return NULL; /* XXX */
@ -466,6 +459,7 @@ nssToken_FindCertificatesByTemplate
( (
NSSToken *tok, NSSToken *tok,
nssSession *sessionOpt, nssSession *sessionOpt,
nssList *cachedList,
CK_ATTRIBUTE_PTR cktemplate, CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize, CK_ULONG ctsize,
PRStatus (*callback)(NSSCertificate *c, void *arg), PRStatus (*callback)(NSSCertificate *c, void *arg),
@ -477,6 +471,11 @@ nssToken_FindCertificatesByTemplate
struct cert_callback_str ccb; struct cert_callback_str ccb;
session = (sessionOpt) ? sessionOpt : tok->defaultSession; session = (sessionOpt) ? sessionOpt : tok->defaultSession;
/* this isn't really traversal, it's find by template ... */ /* this isn't really traversal, it's find by template ... */
if (cachedList) {
ccb.cachedCerts = nssList_CreateIterator(cachedList);
} else {
ccb.cachedCerts = NULL;
}
ccb.callback = callback; ccb.callback = callback;
ccb.arg = arg; ccb.arg = arg;
rvstack = nsstoken_TraverseObjects(tok, session, rvstack = nsstoken_TraverseObjects(tok, session,

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

@ -35,7 +35,7 @@
#define NSSPKI_H #define NSSPKI_H
#ifdef DEBUG #ifdef DEBUG
static const char NSSPKI_CVS_ID[] = "@(#) $RCSfile: nsspki.h,v $ $Revision: 1.4 $ $Date: 2001-10-11 16:34:44 $ $Name: $"; static const char NSSPKI_CVS_ID[] = "@(#) $RCSfile: nsspki.h,v $ $Revision: 1.5 $ $Date: 2001-10-12 17:54:50 $ $Name: $";
#endif /* DEBUG */ #endif /* DEBUG */
/* /*
@ -1747,7 +1747,7 @@ NSS_EXTERN NSSCertificate *
NSSTrustDomain_FindBestCertificateBySubject NSSTrustDomain_FindBestCertificateBySubject
( (
NSSTrustDomain *td, NSSTrustDomain *td,
NSSUTF8 *subject, NSSDER /*NSSUTF8*/ *subject,
NSSTime *timeOpt, NSSTime *timeOpt,
NSSUsage *usage, NSSUsage *usage,
NSSPolicies *policiesOpt NSSPolicies *policiesOpt
@ -1763,7 +1763,7 @@ NSS_EXTERN NSSCertificate **
NSSTrustDomain_FindCertificatesBySubject NSSTrustDomain_FindCertificatesBySubject
( (
NSSTrustDomain *td, NSSTrustDomain *td,
NSSUTF8 *subject, NSSDER /*NSSUTF8*/ *subject,
NSSCertificate *rvOpt[], NSSCertificate *rvOpt[],
PRUint32 maximumOpt, /* 0 for no max */ PRUint32 maximumOpt, /* 0 for no max */
NSSArena *arenaOpt NSSArena *arenaOpt

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

@ -35,7 +35,7 @@
#define PKI_H #define PKI_H
#ifdef DEBUG #ifdef DEBUG
static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.4 $ $Date: 2001-10-11 16:34:44 $ $Name: $"; static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.5 $ $Date: 2001-10-12 17:54:50 $ $Name: $";
#endif /* DEBUG */ #endif /* DEBUG */
#ifndef PKIT_H #ifndef PKIT_H
@ -75,17 +75,6 @@ NSSCertificate_GetID
NSSCertificate *c NSSCertificate *c
); );
/*
* Look for a specific cert in the cache.
*/
NSS_EXTERN NSSCertificate *
nssTrustDomain_GetCertForIssuerAndSNFromCache
(
NSSTrustDomain *td,
NSSDER *issuer,
NSSDER *serialNum
);
PR_END_EXTERN_C PR_END_EXTERN_C
#endif /* PKI_H */ #endif /* PKI_H */

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

@ -35,7 +35,7 @@
#define PKIM_H #define PKIM_H
#ifdef DEBUG #ifdef DEBUG
static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.1 $ $Date: 2001-10-11 16:34:44 $ $Name: $"; static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.2 $ $Date: 2001-10-12 17:54:50 $ $Name: $";
#endif /* DEBUG */ #endif /* DEBUG */
#ifndef BASE_H #ifndef BASE_H
@ -187,7 +187,6 @@ nssTrustDomain_GetCertsForSubjectFromCache
nssList *certListOpt nssList *certListOpt
); );
#if 0
/* /*
* Look for a specific cert in the cache. * Look for a specific cert in the cache.
*/ */
@ -198,7 +197,6 @@ nssTrustDomain_GetCertForIssuerAndSNFromCache
NSSDER *issuer, NSSDER *issuer,
NSSDER *serialNum NSSDER *serialNum
); );
#endif
/* /*
* Look for a specific cert in the cache. * Look for a specific cert in the cache.

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

@ -32,7 +32,7 @@
*/ */
#ifdef DEBUG #ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.8 $ $Date: 2001-10-11 18:41:51 $ $Name: $"; static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.9 $ $Date: 2001-10-12 17:54:50 $ $Name: $";
#endif /* DEBUG */ #endif /* DEBUG */
#ifndef NSSPKI_H #ifndef NSSPKI_H
@ -95,9 +95,14 @@ loser:
} }
static void static void
token_destructor(void *tok) token_destructor(void *t)
{ {
(void)nssToken_Destroy((NSSToken *)tok); NSSToken *tok = (NSSToken *)t;
#ifdef NSS_3_4_CODE
/* in 3.4, also destroy the slot (managed separately) */
(void)nssSlot_Destroy(tok->slot);
#endif
(void)nssToken_Destroy(tok);
} }
NSS_IMPLEMENT PRStatus NSS_IMPLEMENT PRStatus
@ -344,6 +349,7 @@ struct get_best_cert_arg_str {
NSSTime *time; NSSTime *time;
NSSUsage *usage; NSSUsage *usage;
NSSPolicies *policies; NSSPolicies *policies;
nssList *cached;
}; };
static PRStatus static PRStatus
@ -361,6 +367,84 @@ get_best_cert(NSSCertificate *c, void *arg)
return PR_SUCCESS; return PR_SUCCESS;
} }
static NSSCertificate *
find_best_cert_for_template
(
NSSTrustDomain *td,
struct get_best_cert_arg_str *best,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize
)
{
PRStatus nssrv;
NSSToken *tok;
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL, best->cached,
cktemplate, ctsize,
get_best_cert, &best);
}
nssListIterator_Finish(td->tokens);
return best->cert;
}
struct collect_arg_str {
nssList *list;
PRUint32 maximum;
NSSArena *arena;
NSSCertificate **rvOpt;
};
extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
static PRStatus
collect_certs(NSSCertificate *c, void *arg)
{
struct collect_arg_str *ca = (struct collect_arg_str *)arg;
/* Add the cert to the return list */
nssList_AddUnique(ca->list, (void *)c);
if (ca->maximum > 0 && nssList_Count(ca->list) >= ca->maximum) {
/* signal the end of collection) */
nss_SetError(NSS_ERROR_MAXIMUM_FOUND);
return PR_FAILURE;
}
return PR_SUCCESS;
}
static NSSCertificate **
find_all_certs_for_template
(
NSSTrustDomain *td,
struct collect_arg_str *ca,
CK_ATTRIBUTE_PTR cktemplate,
CK_ULONG ctsize
)
{
NSSCertificate **certs = NULL;
PRStatus nssrv;
PRUint32 count;
NSSToken *tok;
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL, ca->list,
cktemplate, ctsize,
collect_certs, ca);
}
nssListIterator_Finish(td->tokens);
count = nssList_Count(ca->list);
if (ca->rvOpt) {
certs = ca->rvOpt;
} else {
certs = nss_ZNEWARRAY(ca->arena, NSSCertificate *, count + 1);
}
nssrv = nssList_GetArray(ca->list, (void **)certs, count);
return certs;
}
NSS_IMPLEMENT NSSCertificate * NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindBestCertificateByNickname NSSTrustDomain_FindBestCertificateByNickname
( (
@ -371,67 +455,42 @@ NSSTrustDomain_FindBestCertificateByNickname
NSSPolicies *policiesOpt /* NULL for none */ NSSPolicies *policiesOpt /* NULL for none */
) )
{ {
NSSCertificate *rvCert = NULL;
PRStatus nssrv; PRStatus nssrv;
NSSToken *tok; struct get_best_cert_arg_str best;
CK_ATTRIBUTE cert_template[] = CK_ATTRIBUTE nick_template[] =
{ {
{ CKA_CLASS, NULL, 0 }, { CKA_CLASS, NULL, 0 },
{ CKA_LABEL, NULL, 0 } { CKA_LABEL, NULL, 0 }
}; };
struct get_best_cert_arg_str best;
CK_ULONG ctsize; CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(cert_template) / sizeof(cert_template[0])); nssList *nameList;
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert); /* set up the search template */
cert_template[1].pValue = (CK_VOID_PTR)name; ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
cert_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv); NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
nick_template[1].pValue = (CK_VOID_PTR)name;
nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
/* set the criteria for determining the best cert */
best.td = td; best.td = td;
best.cert = NULL; best.cert = NULL;
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL); best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
best.usage = usage; best.usage = usage;
best.policies = policiesOpt; best.policies = policiesOpt;
/* This will really be done through the search order, probably a /* find all matching certs in the cache */
* token array nameList = nssList_Create(NULL, PR_FALSE);
*/ (void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList);
for (tok = (NSSToken *)nssListIterator_Start(td->tokens); best.cached = nameList;
tok != (NSSToken *)NULL; /* now find the best cert on tokens */
tok = (NSSToken *)nssListIterator_Next(td->tokens)) rvCert = find_best_cert_for_template(td, &best, nick_template, ctsize);
{ if (!rvCert) {
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL,
cert_template, ctsize,
get_best_cert, &best);
/* This is to workaround the fact that PKCS#11 doesn't specify /* This is to workaround the fact that PKCS#11 doesn't specify
* whether the '\0' should be included. XXX Is that still true? * whether the '\0' should be included. XXX Is that still true?
*/ */
cert_template[1].ulValueLen++; nick_template[1].ulValueLen++;
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL, rvCert = find_best_cert_for_template(td, &best, nick_template, ctsize);
cert_template, ctsize,
get_best_cert, &best);
cert_template[1].ulValueLen--;
} }
nssListIterator_Finish(td->tokens); nssList_Destroy(nameList);
return best.cert; return rvCert;
}
struct collect_arg_str {
nssList *list;
PRUint32 maximum;
NSSArena *arena;
};
extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
static PRStatus
collect_certs(NSSCertificate *c, void *arg)
{
struct collect_arg_str *ca = (struct collect_arg_str *)arg;
/* Add the cert to the return list */
nssList_Add(ca->list, (void *)c);
if (ca->maximum > 0 && nssList_Count(ca->list) >= ca->maximum) {
/* signal the end of collection) */
nss_SetError(NSS_ERROR_MAXIMUM_FOUND);
return PR_FAILURE;
}
return PR_SUCCESS;
} }
NSS_IMPLEMENT NSSCertificate ** NSS_IMPLEMENT NSSCertificate **
@ -444,55 +503,28 @@ NSSTrustDomain_FindCertificatesByNickname
NSSArena *arenaOpt NSSArena *arenaOpt
) )
{ {
NSSCertificate **rvCerts = NULL;
PRStatus nssrv; PRStatus nssrv;
PRUint32 count; CK_ATTRIBUTE nick_template[] =
NSSCertificate **certs;
NSSToken *tok;
nssList *foundCerts;
CK_ATTRIBUTE cert_template[] =
{ {
{ CKA_CLASS, NULL, 0 }, { CKA_CLASS, NULL, 0 },
{ CKA_LABEL, NULL, 0 } { CKA_LABEL, NULL, 0 }
}; };
nssList *nickCerts;
struct collect_arg_str ca; struct collect_arg_str ca;
CK_ULONG ctsize; CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(cert_template) / sizeof(cert_template[0])); ctsize = (CK_ULONG)(sizeof(nick_template) / sizeof(nick_template[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert); NSS_CK_SET_ATTRIBUTE_ITEM(nick_template, 0, &g_ck_class_cert);
cert_template[1].pValue = (CK_VOID_PTR)name; nick_template[1].pValue = (CK_VOID_PTR)name;
cert_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv); nick_template[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv);
foundCerts = nssList_Create(NULL, PR_FALSE); nickCerts = nssList_Create(NULL, PR_FALSE);
ca.list = foundCerts; ca.list = nickCerts;
ca.maximum = maximumOpt; ca.maximum = maximumOpt;
ca.arena = arenaOpt; ca.arena = arenaOpt;
/* This will really be done through the search order, probably a ca.rvOpt = rvOpt;
* token array rvCerts = find_all_certs_for_template(td, &ca, nick_template, ctsize);
*/ nssList_Destroy(nickCerts);
for (tok = (NSSToken *)nssListIterator_Start(td->tokens); return rvCerts;
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL,
cert_template, ctsize,
collect_certs, &ca);
/* This is to workaround the fact that PKCS#11 doesn't specify
* whether the '\0' should be included. XXX Is that still true?
*/
cert_template[1].ulValueLen++;
nssrv = nssToken_FindCertificatesByTemplate(tok, NULL,
cert_template, ctsize,
collect_certs, &ca);
cert_template[1].ulValueLen--;
}
nssListIterator_Finish(td->tokens);
count = nssList_Count(foundCerts);
if (rvOpt) {
certs = rvOpt;
} else {
certs = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
}
nssrv = nssList_GetArray(foundCerts, (void **)certs, count);
nssList_Destroy(foundCerts);
return certs;
} }
NSS_IMPLEMENT NSSCertificate * NSS_IMPLEMENT NSSCertificate *
@ -520,36 +552,115 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber
NSSDER *serialNumber NSSDER *serialNumber
) )
{ {
nss_SetError(NSS_ERROR_NOT_FOUND); NSSCertificate *rvCert = NULL;
return NULL; NSSToken *tok;
CK_ULONG ctsize;
CK_OBJECT_HANDLE object;
CK_ATTRIBUTE cert_template[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_ISSUER, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0 }
};
ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
/* Set the unique id */
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, issuer);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, serialNumber);
/* Try the cache */
rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
issuer,
serialNumber);
if (!rvCert) {
/* Not cached, look for it on tokens */
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
object = nssToken_FindObjectByTemplate(tok, NULL,
cert_template, ctsize);
if (object != CK_INVALID_KEY) {
/* Could not find cert, so create it */
rvCert = NSSCertificate_CreateFromHandle(NULL, object,
NULL, tok->slot);
if (rvCert) {
/* cache it */
nssTrustDomain_AddCertsToCache(td, &rvCert, 1);
}
break;
}
}
nssListIterator_Finish(td->tokens);
}
return rvCert;
} }
NSS_IMPLEMENT NSSCertificate * NSS_IMPLEMENT NSSCertificate *
NSSTrustDomain_FindBestCertificateBySubject NSSTrustDomain_FindBestCertificateBySubject
( (
NSSTrustDomain *td, NSSTrustDomain *td,
NSSUTF8 *subject, NSSDER *subject,
NSSTime *timeOpt, NSSTime *timeOpt,
NSSUsage *usage, NSSUsage *usage,
NSSPolicies *policiesOpt NSSPolicies *policiesOpt
) )
{ {
nss_SetError(NSS_ERROR_NOT_FOUND); NSSCertificate *rvCert = NULL;
return NULL; nssList *subjectList;
CK_ATTRIBUTE subj_template[] =
{
{ CKA_CLASS, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 }
};
struct get_best_cert_arg_str best;
CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(subj_template) / sizeof(subj_template[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 0, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 1, subject);
best.td = td;
best.cert = NULL;
best.time = (timeOpt) ? timeOpt : NSSTime_Now(NULL);
best.usage = usage;
best.policies = policiesOpt;
subjectList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
best.cached = subjectList;
/* now find the best cert on tokens */
rvCert = find_best_cert_for_template(td, &best, subj_template, ctsize);
nssList_Destroy(subjectList);
return rvCert;
} }
NSS_IMPLEMENT NSSCertificate ** NSS_IMPLEMENT NSSCertificate **
NSSTrustDomain_FindCertificatesBySubject NSSTrustDomain_FindCertificatesBySubject
( (
NSSTrustDomain *td, NSSTrustDomain *td,
NSSUTF8 *subject, NSSDER *subject,
NSSCertificate *rvOpt[], NSSCertificate *rvOpt[],
PRUint32 maximumOpt, /* 0 for no max */ PRUint32 maximumOpt, /* 0 for no max */
NSSArena *arenaOpt NSSArena *arenaOpt
) )
{ {
nss_SetError(NSS_ERROR_NOT_FOUND); NSSCertificate **rvCerts = NULL;
return NULL; nssList *subjectList;
struct collect_arg_str ca;
CK_ATTRIBUTE subj_template[] =
{
{ CKA_CLASS, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 }
};
CK_ULONG ctsize;
ctsize = (CK_ULONG)(sizeof(subj_template) / sizeof(subj_template[0]));
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 0, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_ITEM(subj_template, 1, subject);
subjectList = nssList_Create(NULL, PR_FALSE);
(void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList);
ca.list = subjectList;
ca.maximum = maximumOpt;
ca.arena = arenaOpt;
ca.rvOpt = rvOpt;
rvCerts = find_all_certs_for_template(td, &ca, subj_template, ctsize);
nssList_Destroy(subjectList);
return rvCerts;
} }
NSS_IMPLEMENT NSSCertificate * NSS_IMPLEMENT NSSCertificate *
@ -587,8 +698,41 @@ NSSTrustDomain_FindCertificateByEncodedCertificate
NSSBER *encodedCertificate NSSBER *encodedCertificate
) )
{ {
nss_SetError(NSS_ERROR_NOT_FOUND); NSSCertificate *rvCert = NULL;
return NULL; NSSToken *tok;
CK_ULONG ctsize;
CK_OBJECT_HANDLE object;
CK_ATTRIBUTE cert_template[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_VALUE, NULL, 0 }
};
ctsize = sizeof(cert_template) / sizeof(cert_template[0]);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert);
NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, encodedCertificate);
/* Try the cache */
rvCert = nssTrustDomain_GetCertByDERFromCache(td, encodedCertificate);
if (!rvCert) {
/* Not cached, look for it on tokens */
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
{
object = nssToken_FindObjectByTemplate(tok, NULL,
cert_template, ctsize);
if (object != CK_INVALID_KEY) {
/* Could not find cert, so create it */
rvCert = NSSCertificate_CreateFromHandle(NULL, object,
NULL, tok->slot);
if (rvCert) {
/* cache it */
nssTrustDomain_AddCertsToCache(td, &rvCert, 1);
}
break;
}
}
nssListIterator_Finish(td->tokens);
}
return rvCert;
} }
NSS_IMPLEMENT NSSCertificate * NSS_IMPLEMENT NSSCertificate *