diff options
Diffstat (limited to 'lib/pk11wrap/pk11slot.c')
-rw-r--r-- | lib/pk11wrap/pk11slot.c | 73 |
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 |