зеркало из https://github.com/mozilla/pjs.git
bug 125808, refresh trust and slot pointers of cert after token removal/insertion
This commit is contained in:
Родитель
dda0e40b19
Коммит
40f9ef3670
|
@ -101,10 +101,6 @@ static PRStatus convert_and_cache_cert(NSSCertificate *c, void *arg)
|
|||
* a CERTCertificate and fed into the callback.
|
||||
*/
|
||||
nssrv = nssTrustDomain_AddCertsToCache(td, &c, 1);
|
||||
if (!nssList_Get(nss3cb->cached, c)) {
|
||||
nssCertificate_AddRef(c);
|
||||
nssList_Add(nss3cb->cached, c);
|
||||
}
|
||||
/* This is why the hack of copying the cert was done above. The pointer
|
||||
* c passed to this function is provided by retrieve_cert. That function
|
||||
* will destroy the pointer once this function returns. Since c is a local
|
||||
|
@ -1426,16 +1422,14 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
|
|||
search.cbarg = &token_cb;
|
||||
search.cached = certList;
|
||||
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);
|
||||
/* filter the list of cached certs for only those on the token */
|
||||
nssCertificateList_DoCallback(certList,
|
||||
token_callback,
|
||||
&token_cb);
|
||||
}
|
||||
if (certList) {
|
||||
nssList_Clear(certList, cert_destructor);
|
||||
|
@ -1458,12 +1452,12 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
|
|||
nickname,
|
||||
certList);
|
||||
search.cached = certList;
|
||||
nssCertificateList_DoCallback(certList,
|
||||
token_callback,
|
||||
&token_cb);
|
||||
nssToken_TraverseCertificatesByEmail(token, NULL,
|
||||
(NSSASCII7 *)nickname,
|
||||
&search);
|
||||
nssCertificateList_DoCallback(certList,
|
||||
token_callback,
|
||||
&token_cb);
|
||||
}
|
||||
if (certList) {
|
||||
nssList_Clear(certList, cert_destructor);
|
||||
|
@ -2733,18 +2727,18 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
|
|||
}
|
||||
(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);
|
||||
nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
|
||||
&subject, &search);
|
||||
if (nssrv == PR_SUCCESS) {
|
||||
nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
|
||||
&subject, &search);
|
||||
filter_list_for_token_certs(subjectList, token);
|
||||
nssrv = nssCertificateList_DoCallback(subjectList,
|
||||
convert_cert, &pk11cb);
|
||||
}
|
||||
}
|
||||
if (subjectList) {
|
||||
|
@ -2820,18 +2814,18 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
|
|||
} 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);
|
||||
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
|
||||
nick, &search);
|
||||
if (nssrv == PR_SUCCESS) {
|
||||
nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
|
||||
nick, &search);
|
||||
filter_list_for_token_certs(nameList, token);
|
||||
nssrv = nssCertificateList_DoCallback(nameList,
|
||||
convert_cert, &pk11cb);
|
||||
}
|
||||
}
|
||||
if (nameList) {
|
||||
|
@ -2891,17 +2885,17 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
|
|||
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);
|
||||
nssrv = nssToken_TraverseCertificates(tok, NULL, &search);
|
||||
if (nssrv == PR_SUCCESS) {
|
||||
nssrv = nssToken_TraverseCertificates(tok, NULL, &search);
|
||||
filter_list_for_token_certs(certList, tok);
|
||||
nssrv = nssCertificateList_DoCallback(certList,
|
||||
convert_cert, &pk11cb);
|
||||
}
|
||||
nssList_Clear(certList, cert_destructor);
|
||||
nssList_Destroy(certList);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.35 $ $Date: 2002-02-27 22:41:56 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.36 $ $Date: 2002-02-28 22:55:29 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
|
@ -100,6 +100,9 @@ STAN_GetDefaultCryptoToken
|
|||
return PK11Slot_GetNSSToken(pk11slot);
|
||||
}
|
||||
|
||||
static CERTCertificate *
|
||||
stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate);
|
||||
|
||||
/* stuff the cert in the global trust domain cache, and then add a reference
|
||||
* to remain with the token in a list.
|
||||
*/
|
||||
|
@ -110,7 +113,7 @@ cache_token_cert(NSSCertificate *c, void *arg)
|
|||
NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
|
||||
NSSCertificate *cp = nssCertificate_AddRef(c);
|
||||
if (nssList_Count(token->certList) > NSSTOKEN_MAX_LOCAL_CERTS) {
|
||||
nssToken_DestroyCertList(token);
|
||||
nssToken_DestroyCertList(token, PR_TRUE);
|
||||
/* terminate the traversal */
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
@ -122,8 +125,9 @@ cache_token_cert(NSSCertificate *c, void *arg)
|
|||
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.
|
||||
* Force an update of the nickname and slot fields.
|
||||
*/
|
||||
(void)STAN_GetCERTCertificate(c);
|
||||
(void)stan_GetCERTCertificate(c, PR_TRUE);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -151,7 +155,6 @@ static void remove_token_instance(NSSCertificate *c, NSSToken *token)
|
|||
|
||||
static PRBool instance_destructor(NSSCertificate *c, NSSToken *token)
|
||||
{
|
||||
CERTCertificate *cert = STAN_GetCERTCertificate(c);
|
||||
remove_token_instance(c, token);
|
||||
if (nssList_Count(c->object.instanceList) == 0) {
|
||||
return PR_TRUE;
|
||||
|
@ -160,7 +163,7 @@ static PRBool instance_destructor(NSSCertificate *c, NSSToken *token)
|
|||
}
|
||||
|
||||
NSS_IMPLEMENT void
|
||||
nssCertificateList_DestroyTokenCerts(nssList *certList, NSSToken *token)
|
||||
destroy_token_certs(nssList *certList, NSSToken *token, PRBool renewInstances)
|
||||
{
|
||||
nssListIterator *certs;
|
||||
NSSCertificate *cert;
|
||||
|
@ -171,15 +174,24 @@ nssCertificateList_DestroyTokenCerts(nssList *certList, NSSToken *token)
|
|||
cert = (NSSCertificate *)nssListIterator_Next(certs))
|
||||
{
|
||||
removeIt = instance_destructor(cert, token);
|
||||
if (removeIt) {
|
||||
if (removeIt || !renewInstances) {
|
||||
nssList_Remove(certList, cert);
|
||||
CERT_DestroyCertificate(STAN_GetCERTCertificate(cert));
|
||||
} else {
|
||||
/* force an update of the nickname and slot fields of the cert */
|
||||
(void)stan_GetCERTCertificate(cert, PR_TRUE);
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(certs);
|
||||
nssListIterator_Destroy(certs);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT void
|
||||
nssCertificateList_DestroyTokenCerts(nssList *certList, NSSToken *token)
|
||||
{
|
||||
destroy_token_certs(certList, token, PR_FALSE);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT void
|
||||
nssCertificateList_RemoveTokenCerts(nssList *certList, NSSToken *token)
|
||||
{
|
||||
|
@ -194,6 +206,9 @@ nssCertificateList_RemoveTokenCerts(nssList *certList, NSSToken *token)
|
|||
removeIt = instance_destructor(cert, token);
|
||||
if (removeIt) {
|
||||
nssList_Remove(certList, cert);
|
||||
} else {
|
||||
/* force an update of the nickname and slot fields of the cert */
|
||||
(void)stan_GetCERTCertificate(cert, PR_TRUE);
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(certs);
|
||||
|
@ -202,12 +217,12 @@ nssCertificateList_RemoveTokenCerts(nssList *certList, NSSToken *token)
|
|||
|
||||
/* destroy the list of certs on a token */
|
||||
NSS_IMPLEMENT void
|
||||
nssToken_DestroyCertList(NSSToken *token)
|
||||
nssToken_DestroyCertList(NSSToken *token, PRBool renewInstances)
|
||||
{
|
||||
if (!token->certList) {
|
||||
return;
|
||||
}
|
||||
nssCertificateList_DestroyTokenCerts(token->certList, token);
|
||||
destroy_token_certs(token->certList, token, renewInstances);
|
||||
nssList_Clear(token->certList, NULL);
|
||||
/* leave the list non-null to prevent it from being searched */
|
||||
}
|
||||
|
@ -261,7 +276,7 @@ nssToken_SearchCerts
|
|||
*notPresentOpt = PR_FALSE;
|
||||
}
|
||||
if (!nssToken_IsPresent(token)) {
|
||||
nssToken_DestroyCertList(token); /* will free cached certs */
|
||||
nssToken_DestroyCertList(token, PR_TRUE); /* will free cached certs */
|
||||
if (notPresentOpt) {
|
||||
*notPresentOpt = PR_TRUE;
|
||||
}
|
||||
|
@ -346,7 +361,7 @@ NSS_IMPLEMENT void
|
|||
STAN_DestroyNSSToken(NSSToken *token)
|
||||
{
|
||||
if (token->certList) {
|
||||
nssToken_DestroyCertList(token);
|
||||
nssToken_DestroyCertList(token, PR_FALSE);
|
||||
}
|
||||
nssToken_Destroy(token);
|
||||
}
|
||||
|
@ -689,6 +704,24 @@ static int nsstoken_get_trust_order(NSSToken *token)
|
|||
return module->trustOrder;
|
||||
}
|
||||
|
||||
/* check all cert instances for private key */
|
||||
static PRBool is_user_cert(NSSCertificate *c, CERTCertificate *cc)
|
||||
{
|
||||
PRBool isUser = PR_FALSE;
|
||||
nssCryptokiInstance *instance;
|
||||
nssListIterator *instances = c->object.instances;
|
||||
for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances);
|
||||
instance != (nssCryptokiInstance *)NULL;
|
||||
instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
|
||||
{
|
||||
if (PK11_IsUserCert(instance->token->pk11slot, cc, instance->handle)) {
|
||||
isUser = PR_TRUE;
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(instances);
|
||||
return isUser;
|
||||
}
|
||||
|
||||
CERTCertTrust *
|
||||
nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
|
||||
{
|
||||
|
@ -738,7 +771,7 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
|
|||
nssListIterator_Destroy(tokens);
|
||||
rvTrust = cert_trust_from_stan_trust(&t, cc->arena);
|
||||
if (!rvTrust) return NULL;
|
||||
if (cc->slot && PK11_IsUserCert(cc->slot, cc, cc->pkcs11ID)) {
|
||||
if (is_user_cert(c, cc)) {
|
||||
rvTrust->sslFlags |= CERTDB_USER;
|
||||
rvTrust->emailFlags |= CERTDB_USER;
|
||||
rvTrust->objectSigningFlags |= CERTDB_USER;
|
||||
|
@ -749,20 +782,38 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
|
|||
static nssCryptokiInstance *
|
||||
get_cert_instance(NSSCertificate *c)
|
||||
{
|
||||
nssCryptokiInstance *instance;
|
||||
nssCryptokiInstance *instance, *ci;
|
||||
nssListIterator *instances = c->object.instances;
|
||||
instance = NULL;
|
||||
nssList_GetArray(c->object.instanceList, (void **)&instance, 1);
|
||||
for (ci = (nssCryptokiInstance *)nssListIterator_Start(instances);
|
||||
ci != (nssCryptokiInstance *)NULL;
|
||||
ci = (nssCryptokiInstance *)nssListIterator_Next(instances))
|
||||
{
|
||||
if (!instance) {
|
||||
instance = ci;
|
||||
} else {
|
||||
/* This only really works for two instances... But 3.4 can't
|
||||
* handle more anyway. The logic is, if there are multiple
|
||||
* instances, prefer the one that is not internal (e.g., on
|
||||
* a hardware device.
|
||||
*/
|
||||
if (PK11_IsInternal(instance->token->pk11slot)) {
|
||||
instance = ci;
|
||||
}
|
||||
}
|
||||
}
|
||||
nssListIterator_Finish(instances);
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void
|
||||
fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc)
|
||||
fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced)
|
||||
{
|
||||
NSSTrust *nssTrust;
|
||||
NSSCryptoContext *context = c->object.cryptoContext;
|
||||
nssCryptokiInstance *instance = get_cert_instance(c);
|
||||
/* fill other fields needed by NSS3 functions using CERTCertificate */
|
||||
if (!cc->nickname && c->nickname) {
|
||||
if ((!cc->nickname && c->nickname) || forced) {
|
||||
PRStatus nssrv;
|
||||
int nicklen, tokenlen, len;
|
||||
NSSUTF8 *tokenName = NULL;
|
||||
|
@ -812,8 +863,8 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc)
|
|||
cc->nssCertificate = c;
|
||||
}
|
||||
|
||||
NSS_EXTERN CERTCertificate *
|
||||
STAN_GetCERTCertificate(NSSCertificate *c)
|
||||
static CERTCertificate *
|
||||
stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate)
|
||||
{
|
||||
nssDecodedCert *dc;
|
||||
CERTCertificate *cc;
|
||||
|
@ -826,8 +877,8 @@ STAN_GetCERTCertificate(NSSCertificate *c)
|
|||
}
|
||||
cc = (CERTCertificate *)dc->data;
|
||||
if (cc) {
|
||||
if (!cc->nssCertificate) {
|
||||
fill_CERTCertificateFields(c, cc);
|
||||
if (!cc->nssCertificate || forceUpdate) {
|
||||
fill_CERTCertificateFields(c, cc, forceUpdate);
|
||||
} else if (!cc->trust && !c->object.cryptoContext) {
|
||||
/* if it's a perm cert, it might have been stored before the
|
||||
* trust, so look for the trust again. But a temp cert can be
|
||||
|
@ -839,6 +890,12 @@ STAN_GetCERTCertificate(NSSCertificate *c)
|
|||
return cc;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT CERTCertificate *
|
||||
STAN_GetCERTCertificate(NSSCertificate *c)
|
||||
{
|
||||
return stan_GetCERTCertificate(c, PR_FALSE);
|
||||
}
|
||||
|
||||
static CK_TRUST
|
||||
get_stan_trust(unsigned int t, PRBool isClientAuth)
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define PKINSS3HACK_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.6 $ $Date: 2002-02-27 22:41:56 $ $Name: $";
|
||||
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.7 $ $Date: 2002-02-28 22:55:30 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKIT_H
|
||||
|
@ -81,8 +81,12 @@ nssToken_SearchCerts
|
|||
PRBool *notPresentOpt
|
||||
);
|
||||
|
||||
/* renewInstances -- if the cached token certs have multiple instances,
|
||||
* don't destroy them. If this parameter is false, they will be destroyed
|
||||
* anyway (used for clean shutdown).
|
||||
*/
|
||||
NSS_EXTERN void
|
||||
nssToken_DestroyCertList(NSSToken *token);
|
||||
nssToken_DestroyCertList(NSSToken *token, PRBool renewInstances);
|
||||
|
||||
NSS_EXTERN void
|
||||
nssCertificateList_DestroyTokenCerts(nssList *certList, NSSToken *token);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.35 $ $Date: 2002-02-27 22:41:56 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.36 $ $Date: 2002-02-28 22:55:30 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKI_H
|
||||
|
@ -515,7 +515,7 @@ static PRBool cert_token_not_present(NSSCertificate *c)
|
|||
instance = (nssCryptokiInstance *)nssListIterator_Next(instances))
|
||||
{
|
||||
if (!nssToken_IsPresent(instance->token)) {
|
||||
nssToken_DestroyCertList(instance->token);
|
||||
nssToken_DestroyCertList(instance->token, PR_TRUE);
|
||||
nssList_Remove(c->object.instanceList, instance);
|
||||
} else {
|
||||
freeIt = PR_FALSE;
|
||||
|
|
Загрузка…
Ссылка в новой задаче