diff options
Diffstat (limited to 'security/nss/lib/dev')
-rw-r--r-- | security/nss/lib/dev/dev.h | 9 | ||||
-rw-r--r-- | security/nss/lib/dev/devslot.c | 26 | ||||
-rw-r--r-- | security/nss/lib/dev/devtoken.c | 93 |
3 files changed, 79 insertions, 49 deletions
diff --git a/security/nss/lib/dev/dev.h b/security/nss/lib/dev/dev.h index 7e64e7612..26ac8957e 100644 --- a/security/nss/lib/dev/dev.h +++ b/security/nss/lib/dev/dev.h @@ -312,6 +312,15 @@ NSS_EXTERN PRBool nssToken_NeedsPINInitialization( NSSToken *token); +NSS_EXTERN nssCryptokiObject ** +nssToken_FindObjectsByTemplate( + NSSToken *token, + nssSession *sessionOpt, + CK_ATTRIBUTE_PTR obj_template, + CK_ULONG otsize, + PRUint32 maximumOpt, + PRStatus *statusOpt); + NSS_EXTERN nssCryptokiObject * nssToken_ImportCertificate( NSSToken *tok, diff --git a/security/nss/lib/dev/devslot.c b/security/nss/lib/dev/devslot.c index 5b0bb371a..9f0bd8226 100644 --- a/security/nss/lib/dev/devslot.c +++ b/security/nss/lib/dev/devslot.c @@ -31,6 +31,7 @@ nssSlot_Destroy( { if (slot) { if (PR_ATOMIC_DECREMENT(&slot->base.refCount) == 0) { + PK11_FreeSlot(slot->pk11slot); PZ_DestroyLock(slot->base.lock); return nssArena_Destroy(slot->base.arena); } @@ -91,7 +92,7 @@ nssSlot_ResetDelay( } static PRBool -within_token_delay_period(NSSSlot *slot) +within_token_delay_period(const NSSSlot *slot) { PRIntervalTime time, lastTime; /* Set the delay time for checking the token presence */ @@ -103,7 +104,6 @@ within_token_delay_period(NSSSlot *slot) if ((lastTime) && ((time - lastTime) < s_token_delay_time)) { return PR_TRUE; } - slot->lastTokenPing = time; return PR_FALSE; } @@ -136,6 +136,7 @@ nssSlot_IsTokenPresent( nssSlot_ExitMonitor(slot); if (ckrv != CKR_OK) { slot->token->base.name[0] = 0; /* XXX */ + slot->lastTokenPing = PR_IntervalNow(); return PR_FALSE; } slot->ckFlags = slotInfo.flags; @@ -143,6 +144,7 @@ nssSlot_IsTokenPresent( if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) { if (!slot->token) { /* token was never present */ + slot->lastTokenPing = PR_IntervalNow(); return PR_FALSE; } session = nssToken_GetDefaultSession(slot->token); @@ -165,6 +167,7 @@ nssSlot_IsTokenPresent( slot->token->base.name[0] = 0; /* XXX */ /* clear the token cache */ nssToken_Remove(slot->token); + slot->lastTokenPing = PR_IntervalNow(); return PR_FALSE; } /* token is present, use the session info to determine if the card @@ -187,8 +190,10 @@ nssSlot_IsTokenPresent( isPresent = session->handle != CK_INVALID_SESSION; nssSession_ExitMonitor(session); /* token not removed, finished */ - if (isPresent) + if (isPresent) { + slot->lastTokenPing = PR_IntervalNow(); return PR_TRUE; + } } /* the token has been removed, and reinserted, or the slot contains * a token it doesn't recognize. invalidate all the old @@ -201,8 +206,11 @@ nssSlot_IsTokenPresent( if (nssrv != PR_SUCCESS) { slot->token->base.name[0] = 0; /* XXX */ slot->ckFlags &= ~CKF_TOKEN_PRESENT; + /* TODO: insert a barrier here to avoid reordering of the assingments */ + slot->lastTokenPing = PR_IntervalNow(); return PR_FALSE; } + slot->lastTokenPing = PR_IntervalNow(); return PR_TRUE; } @@ -217,10 +225,18 @@ NSS_IMPLEMENT NSSToken * nssSlot_GetToken( NSSSlot *slot) { + NSSToken *rvToken = NULL; + if (nssSlot_IsTokenPresent(slot)) { - return nssToken_AddRef(slot->token); + /* Even if a token should be present, check `slot->token` too as it + * might be gone already. This would happen mostly on shutdown. */ + nssSlot_EnterMonitor(slot); + if (slot->token) + rvToken = nssToken_AddRef(slot->token); + nssSlot_ExitMonitor(slot); } - return (NSSToken *)NULL; + + return rvToken; } NSS_IMPLEMENT PRStatus diff --git a/security/nss/lib/dev/devtoken.c b/security/nss/lib/dev/devtoken.c index 0adbca8bc..0d4c3b5a7 100644 --- a/security/nss/lib/dev/devtoken.c +++ b/security/nss/lib/dev/devtoken.c @@ -29,11 +29,16 @@ nssToken_Destroy( { if (tok) { if (PR_ATOMIC_DECREMENT(&tok->base.refCount) == 0) { + PK11_FreeSlot(tok->pk11slot); PZ_DestroyLock(tok->base.lock); nssTokenObjectCache_Destroy(tok->cache); - /* The token holds the first/last reference to the slot. - * When the token is actually destroyed, that ref must go too. - */ + + /* We're going away, let the nssSlot know in case it's held + * alive by someone else. Usually we should hold the last ref. */ + nssSlot_EnterMonitor(tok->slot); + tok->slot->token = NULL; + nssSlot_ExitMonitor(tok->slot); + (void)nssSlot_Destroy(tok->slot); return nssArena_Destroy(tok->base.arena); } @@ -368,8 +373,8 @@ loser: return (nssCryptokiObject **)NULL; } -static nssCryptokiObject ** -find_objects_by_template( +NSS_IMPLEMENT nssCryptokiObject ** +nssToken_FindObjectsByTemplate( NSSToken *token, nssSession *sessionOpt, CK_ATTRIBUTE_PTR obj_template, @@ -581,9 +586,9 @@ nssToken_FindObjects( obj_template, obj_size, maximumOpt, statusOpt); } else { - objects = find_objects_by_template(token, sessionOpt, - obj_template, obj_size, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + obj_template, obj_size, + maximumOpt, statusOpt); } return objects; } @@ -612,9 +617,9 @@ nssToken_FindCertificatesBySubject( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); NSS_CK_TEMPLATE_FINISH(subj_template, attr, stsize); /* now locate the token certs matching this template */ - objects = find_objects_by_template(token, sessionOpt, - subj_template, stsize, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + subj_template, stsize, + maximumOpt, statusOpt); return objects; } @@ -642,9 +647,9 @@ nssToken_FindCertificatesByNickname( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); NSS_CK_TEMPLATE_FINISH(nick_template, attr, ntsize); /* now locate the token certs matching this template */ - objects = find_objects_by_template(token, sessionOpt, - nick_template, ntsize, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + nick_template, ntsize, + maximumOpt, statusOpt); if (!objects) { /* This is to workaround the fact that PKCS#11 doesn't specify * whether the '\0' should be included. XXX Is that still true? @@ -653,9 +658,9 @@ nssToken_FindCertificatesByNickname( * well, its needed by the builtin token... */ nick_template[0].ulValueLen++; - objects = find_objects_by_template(token, sessionOpt, - nick_template, ntsize, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + nick_template, ntsize, + maximumOpt, statusOpt); } return objects; } @@ -732,9 +737,9 @@ nssToken_FindCertificatesByID( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); NSS_CK_TEMPLATE_FINISH(id_template, attr, idtsize); /* now locate the token certs matching this template */ - objects = find_objects_by_template(token, sessionOpt, - id_template, idtsize, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + id_template, idtsize, + maximumOpt, statusOpt); return objects; } @@ -822,9 +827,9 @@ nssToken_FindCertificateByIssuerAndSerialNumber( cert_template, ctsize, 1, statusOpt); } else { - objects = find_objects_by_template(token, sessionOpt, - cert_template, ctsize, - 1, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + cert_template, ctsize, + 1, statusOpt); } if (objects) { rvObject = objects[0]; @@ -849,9 +854,9 @@ nssToken_FindCertificateByIssuerAndSerialNumber( cert_template, ctsize, 1, statusOpt); } else { - objects = find_objects_by_template(token, sessionOpt, - cert_template, ctsize, - 1, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + cert_template, ctsize, + 1, statusOpt); } if (objects) { rvObject = objects[0]; @@ -885,9 +890,9 @@ nssToken_FindCertificateByEncodedCertificate( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encodedCertificate); NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); /* get the object handle */ - objects = find_objects_by_template(token, sessionOpt, - cert_template, ctsize, - 1, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + cert_template, ctsize, + 1, statusOpt); if (objects) { rvObject = objects[0]; nss_ZFreeIf(objects); @@ -917,9 +922,9 @@ nssToken_FindPrivateKeys( } NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); - objects = find_objects_by_template(token, sessionOpt, - key_template, ktsize, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + key_template, ktsize, + maximumOpt, statusOpt); return objects; } @@ -942,9 +947,9 @@ nssToken_FindPrivateKeyByID( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID); NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); - objects = find_objects_by_template(token, sessionOpt, - key_template, ktsize, - 1, NULL); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + key_template, ktsize, + 1, NULL); if (objects) { rvKey = objects[0]; nss_ZFreeIf(objects); @@ -971,9 +976,9 @@ nssToken_FindPublicKeyByID( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID); NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); - objects = find_objects_by_template(token, sessionOpt, - key_template, ktsize, - 1, NULL); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + key_template, ktsize, + 1, NULL); if (objects) { rvKey = objects[0]; nss_ZFreeIf(objects); @@ -1130,9 +1135,9 @@ nssToken_FindTrustForCertificate( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial); NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); - objects = find_objects_by_template(token, session, - tobj_template, tobj_size, - 1, NULL); + objects = nssToken_FindObjectsByTemplate(token, session, + tobj_template, tobj_size, + 1, NULL); if (objects) { object = objects[0]; nss_ZFreeIf(objects); @@ -1215,9 +1220,9 @@ nssToken_FindCRLsBySubject( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); NSS_CK_TEMPLATE_FINISH(crlobj_template, attr, crlobj_size); - objects = find_objects_by_template(token, session, - crlobj_template, crlobj_size, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, session, + crlobj_template, crlobj_size, + maximumOpt, statusOpt); return objects; } |