summaryrefslogtreecommitdiff
path: root/lib/pk11wrap/pk11slot.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pk11wrap/pk11slot.c')
-rw-r--r--lib/pk11wrap/pk11slot.c73
1 files changed, 57 insertions, 16 deletions
diff --git a/lib/pk11wrap/pk11slot.c b/lib/pk11wrap/pk11slot.c
index c320019f9..99be9528f 100644
--- a/lib/pk11wrap/pk11slot.c
+++ b/lib/pk11wrap/pk11slot.c
@@ -362,19 +362,24 @@ PK11_NewSlotInfo(SECMODModule *mod)
PK11SlotInfo *slot;
slot = (PK11SlotInfo *)PORT_Alloc(sizeof(PK11SlotInfo));
- if (slot == NULL)
+ if (slot == NULL) {
return slot;
-
- slot->sessionLock = mod->isThreadSafe ? PZ_NewLock(nssILockSession) : mod->refLock;
- if (slot->sessionLock == NULL) {
- PORT_Free(slot);
- return NULL;
}
slot->freeListLock = PZ_NewLock(nssILockFreelist);
if (slot->freeListLock == NULL) {
- if (mod->isThreadSafe) {
- PZ_DestroyLock(slot->sessionLock);
- }
+ PORT_Free(slot);
+ return NULL;
+ }
+ slot->nssTokenLock = PZ_NewLock(nssILockOther);
+ if (slot->nssTokenLock == NULL) {
+ PZ_DestroyLock(slot->freeListLock);
+ PORT_Free(slot);
+ return NULL;
+ }
+ slot->sessionLock = mod->isThreadSafe ? PZ_NewLock(nssILockSession) : mod->refLock;
+ if (slot->sessionLock == NULL) {
+ PZ_DestroyLock(slot->nssTokenLock);
+ PZ_DestroyLock(slot->freeListLock);
PORT_Free(slot);
return NULL;
}
@@ -462,6 +467,10 @@ PK11_DestroySlot(PK11SlotInfo *slot)
PZ_DestroyLock(slot->freeListLock);
slot->freeListLock = NULL;
}
+ if (slot->nssTokenLock) {
+ PZ_DestroyLock(slot->nssTokenLock);
+ slot->nssTokenLock = NULL;
+ }
/* finally Tell our parent module that we've gone away so it can unload */
if (slot->module) {
@@ -1260,6 +1269,7 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
CK_RV crv;
SECStatus rv;
PRStatus status;
+ NSSToken *nssToken;
/* set the slot flags to the current token values */
if (!slot->isThreadSafe)
@@ -1297,7 +1307,9 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
slot->maxPassword = slot->tokenInfo.ulMaxPinLen;
PORT_Memcpy(slot->serial, slot->tokenInfo.serialNumber, sizeof(slot->serial));
- nssToken_UpdateName(slot->nssToken);
+ nssToken = PK11Slot_GetNSSToken(slot);
+ nssToken_UpdateName(nssToken); /* null token is OK */
+ (void)nssToken_Destroy(nssToken);
slot->defRWSession = (PRBool)((!slot->readOnly) &&
(slot->tokenInfo.ulMaxSessionCount == 1));
@@ -1365,7 +1377,9 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
PK11_ExitSlotMonitor(slot);
}
- status = nssToken_Refresh(slot->nssToken);
+ nssToken = PK11Slot_GetNSSToken(slot);
+ status = nssToken_Refresh(nssToken); /* null token is OK */
+ (void)nssToken_Destroy(nssToken);
if (status != PR_SUCCESS)
return SECFailure;
@@ -1598,8 +1612,11 @@ pk11_IsPresentCertLoad(PK11SlotInfo *slot, PRBool loadCerts)
return PR_TRUE;
}
- if (slot->nssToken) {
- return nssToken_IsPresent(slot->nssToken);
+ NSSToken *nssToken = PK11Slot_GetNSSToken(slot);
+ if (nssToken) {
+ PRBool present = nssToken_IsPresent(nssToken);
+ (void)nssToken_Destroy(nssToken);
+ return present;
}
/* removable slots have a flag that says they are present */
@@ -2649,20 +2666,44 @@ PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd)
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
- nssTrustDomain_UpdateCachedTokenCerts(slot->nssToken->trustDomain,
- slot->nssToken);
+ NSSToken *token = PK11Slot_GetNSSToken(slot);
+ if (token) {
+ nssTrustDomain_UpdateCachedTokenCerts(token->trustDomain, token);
+ (void)nssToken_Destroy(token);
+ }
return SECSuccess;
}
+
void
PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst)
{
+ NSSToken *old;
+ if (nsst) {
+ nsst = nssToken_AddRef(nsst);
+ }
+
+ PZ_Lock(sl->nssTokenLock);
+ old = sl->nssToken;
sl->nssToken = nsst;
+ PZ_Unlock(sl->nssTokenLock);
+
+ if (old) {
+ (void)nssToken_Destroy(old);
+ }
}
NSSToken *
PK11Slot_GetNSSToken(PK11SlotInfo *sl)
{
- return sl->nssToken;
+ NSSToken *rv = NULL;
+
+ PZ_Lock(sl->nssTokenLock);
+ if (sl->nssToken) {
+ rv = nssToken_AddRef(sl->nssToken);
+ }
+ PZ_Unlock(sl->nssTokenLock);
+
+ return rv;
}
PRBool