зеркало из https://github.com/mozilla/gecko-dev.git
bug 121628, persistent cache of hardware token certs
This commit is contained in:
Родитель
1e25a6993c
Коммит
c124ec770d
|
@ -35,7 +35,7 @@
|
|||
#define DEV_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.15 $ $Date: 2001/12/11 20:28:33 $ $Name: $";
|
||||
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.16 $ $Date: 2002/02/01 17:25:10 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef DEVT_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
|
||||
(
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: devobject.c,v $ $Revision: 1.14 $ $Date: 2002/01/23 17:00:34 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: devobject.c,v $ $Revision: 1.15 $ $Date: 2002/02/01 17:25:10 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef DEV_H
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define DEVT_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.8 $ $Date: 2001/12/11 20:28:34 $ $Name: $";
|
||||
static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.9 $ $Date: 2002/02/01 17:25:11 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.4 $ $Date: 2001/12/07 01:35:54 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.5 $ $Date: 2002/02/01 17:25:11 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef DEV_H
|
||||
|
@ -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
|
||||
(
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: dev3hack.c,v $ $Revision: 1.4 $ $Date: 2002/01/31 17:28:49 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: dev3hack.c,v $ $Revision: 1.5 $ $Date: 2002/02/01 17:25:12 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSS_3_4_CODE
|
||||
|
@ -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)
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define DEVNSS3HACK_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char DEVNSS3HACK_CVS_ID[] = "@(#) $RCSfile: dev3hack.h,v $ $Revision: 1.1 $ $Date: 2001/11/08 00:15:06 $ $Name: $";
|
||||
static const char DEVNSS3HACK_CVS_ID[] = "@(#) $RCSfile: dev3hack.h,v $ $Revision: 1.2 $ $Date: 2002/02/01 17:25:13 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#include "cert.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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.27 $ $Date: 2002/01/24 00:26:24 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.28 $ $Date: 2002/02/01 17:25:15 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKI_H
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.29 $ $Date: 2002/01/31 17:08:32 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.30 $ $Date: 2002/02/01 17:25:15 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -68,6 +68,10 @@ static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.29 $ $D
|
|||
#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;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define PKINSS3HACK_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.4 $ $Date: 2002/01/23 17:00:39 $ $Name: $";
|
||||
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.5 $ $Date: 2002/02/01 17:25:15 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKIT_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);
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define PKIM_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.14 $ $Date: 2002/01/31 17:08:32 $ $Name: $";
|
||||
static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.15 $ $Date: 2002/02/01 17:25:15 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef BASE_H
|
||||
|
@ -281,6 +281,14 @@ nssBestCertificate_Callback
|
|||
void *arg
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
nssCertificateList_DoCallback
|
||||
(
|
||||
nssList *certList,
|
||||
PRStatus (* callback)(NSSCertificate *c, void *arg),
|
||||
void *arg
|
||||
);
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
nssPKIObject_Initialize
|
||||
(
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.30 $ $Date: 2002/01/24 15:45:55 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.31 $ $Date: 2002/02/01 17:25:15 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKI_H
|
||||
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче