diff options
author | ian.mcgreer%sun.com <devnull@localhost> | 2003-02-11 22:34:43 +0000 |
---|---|---|
committer | ian.mcgreer%sun.com <devnull@localhost> | 2003-02-11 22:34:43 +0000 |
commit | be91526d53799929320e619f732b66f2b7624bb3 (patch) | |
tree | 726427f847ba1f135dfe406d77bbedc37162ddb0 | |
parent | 7d0e1e54d71aa71c03708b405f037fa27b60594c (diff) | |
download | nss-hg-be91526d53799929320e619f732b66f2b7624bb3.tar.gz |
remove token object cache
-rw-r--r-- | security/nss/lib/dev/ckhelper.c | 39 | ||||
-rw-r--r-- | security/nss/lib/dev/devm.h | 65 | ||||
-rw-r--r-- | security/nss/lib/dev/devtoken.c | 166 | ||||
-rw-r--r-- | security/nss/lib/dev/devutil.c | 857 |
4 files changed, 33 insertions, 1094 deletions
diff --git a/security/nss/lib/dev/ckhelper.c b/security/nss/lib/dev/ckhelper.c index 6de03b0b6..6288c2ea5 100644 --- a/security/nss/lib/dev/ckhelper.c +++ b/security/nss/lib/dev/ckhelper.c @@ -392,7 +392,6 @@ nssCryptokiCert_GetAttributes ( { PRStatus status; PRUint32 i; - nssTokenObjectCache *cache; NSSSlot *slot; CK_ULONG template_size; CK_ATTRIBUTE_PTR attr; @@ -427,17 +426,7 @@ nssCryptokiCert_GetAttributes ( return PR_SUCCESS; } - status = PR_FAILURE; - cache = nssToken_GetObjectCache(certObject->token); - if (cache) { - status = nssTokenObjectCache_GetObjectAttributes(cache, NULL, - certObject, - CKO_CERTIFICATE, - cert_template, - template_size); - } - if (status != PR_SUCCESS) { - + { slot = nssToken_GetSlot(certObject->token); status = nssCKObject_GetAttributes(certObject->handle, cert_template, template_size, @@ -667,7 +656,6 @@ nssCryptokiTrust_GetAttributes ( { PRStatus status; NSSSlot *slot; - nssTokenObjectCache *cache; CK_BBOOL isToken; CK_TRUST saTrust, caTrust, epTrust, csTrust; CK_ATTRIBUTE_PTR attr; @@ -683,17 +671,7 @@ nssCryptokiTrust_GetAttributes ( NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust); NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size); - status = PR_FAILURE; - cache = nssToken_GetObjectCache(trustObject->token); - if (cache) { - status = nssTokenObjectCache_GetObjectAttributes(cache, NULL, - trustObject, - CKO_NETSCAPE_TRUST, - trust_template, - trust_size); - } - if (status != PR_SUCCESS) { - + { slot = nssToken_GetSlot(trustObject->token); status = nssCKObject_GetAttributes(trustObject->handle, trust_template, trust_size, @@ -722,7 +700,6 @@ nssCryptokiCRL_GetAttributes ( { PRStatus status; NSSSlot *slot; - nssTokenObjectCache *cache; CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE crl_template[5]; CK_ULONG crl_size; @@ -740,17 +717,7 @@ nssCryptokiCRL_GetAttributes ( } NSS_CK_TEMPLATE_FINISH(crl_template, attr, crl_size); - status = PR_FAILURE; - cache = nssToken_GetObjectCache(crlObject->token); - if (cache) { - status = nssTokenObjectCache_GetObjectAttributes(cache, NULL, - crlObject, - CKO_NETSCAPE_CRL, - crl_template, - crl_size); - } - if (status != PR_SUCCESS) { - + { slot = nssToken_GetSlot(crlObject->token); status = nssCKObject_GetAttributes(crlObject->handle, crl_template, crl_size, diff --git a/security/nss/lib/dev/devm.h b/security/nss/lib/dev/devm.h index af39f0ad5..d1a7b87ee 100644 --- a/security/nss/lib/dev/devm.h +++ b/security/nss/lib/dev/devm.h @@ -118,12 +118,6 @@ nssToken_IsLoginRequired ( NSSToken *token ); -/* This is super-private!!! */ -NSS_EXTERN nssTokenObjectCache * -nssToken_GetObjectCache ( - NSSToken *token -); - /* XXX */ NSS_EXTERN void nssToken_Remove ( @@ -154,65 +148,6 @@ nss_SetGenericDeviceError ( CK_RV ckrv ); -NSS_EXTERN nssTokenObjectCache * -nssTokenObjectCache_Create ( - NSSToken *token, - PRBool cacheCerts, - PRBool cacheTrust, - PRBool cacheCRLs -); - -NSS_EXTERN void -nssTokenObjectCache_Destroy ( - nssTokenObjectCache *cache -); - -NSS_EXTERN void -nssTokenObjectCache_Clear ( - nssTokenObjectCache *cache -); - -NSS_EXTERN PRBool -nssTokenObjectCache_HaveObjectClass ( - nssTokenObjectCache *cache, - CK_OBJECT_CLASS objclass -); - -NSS_EXTERN nssCryptokiObject ** -nssTokenObjectCache_FindObjectsByTemplate ( - nssTokenObjectCache *cache, - CK_OBJECT_CLASS objclass, - CK_ATTRIBUTE_PTR otemplate, - CK_ULONG otlen, - PRUint32 maximumOpt, - PRStatus *statusOpt -); - -NSS_EXTERN PRStatus -nssTokenObjectCache_GetObjectAttributes ( - nssTokenObjectCache *cache, - NSSArena *arenaOpt, - nssCryptokiObject *object, - CK_OBJECT_CLASS objclass, - CK_ATTRIBUTE_PTR atemplate, - CK_ULONG atlen -); - -NSS_EXTERN PRStatus -nssTokenObjectCache_ImportObject ( - nssTokenObjectCache *cache, - nssCryptokiObject *object, - CK_OBJECT_CLASS objclass, - CK_ATTRIBUTE_PTR ot, - CK_ULONG otlen -); - -NSS_EXTERN void -nssTokenObjectCache_RemoveObject ( - nssTokenObjectCache *cache, - nssCryptokiObject *object -); - /* PKCS#11 stores strings in a fixed-length buffer padded with spaces. This * function gets the length of the actual string. */ diff --git a/security/nss/lib/dev/devtoken.c b/security/nss/lib/dev/devtoken.c index ab358a984..bb8130453 100644 --- a/security/nss/lib/dev/devtoken.c +++ b/security/nss/lib/dev/devtoken.c @@ -63,7 +63,6 @@ struct NSSTokenStr CK_MECHANISM_TYPE_PTR mechanisms; CK_ULONG numMechanisms; nssSession *defaultSession; - nssTokenObjectCache *cache; }; NSS_IMPLEMENT NSSToken * @@ -143,14 +142,6 @@ nssToken_Create ( } } rvToken->defaultSession = session; - if (nssSlot_IsHardware(peer)) { - rvToken->cache = nssTokenObjectCache_Create(rvToken, - PR_TRUE, PR_TRUE, PR_TRUE); - if (!rvToken->cache) { - nssSlot_Destroy(peer); - goto loser; - } - } return rvToken; loser: if (session) { @@ -170,7 +161,6 @@ nssToken_Destroy ( if (tok->base.refCount == 0) { nssSession_Destroy(tok->defaultSession); PZ_DestroyLock(tok->base.lock); - nssTokenObjectCache_Destroy(tok->cache); return nssArena_Destroy(tok->base.arena); } } @@ -182,7 +172,7 @@ nssToken_Remove ( NSSToken *tok ) { - nssTokenObjectCache_Clear(tok->cache); + return; } NSS_IMPLEMENT void @@ -310,14 +300,6 @@ NSSToken_GetName ( return nssToken_GetName(token); } -NSS_IMPLEMENT nssTokenObjectCache * -nssToken_GetObjectCache ( - NSSToken *token -) -{ - return token->cache; -} - NSS_IMPLEMENT PRBool nssToken_IsReadOnly ( NSSToken *token @@ -446,8 +428,8 @@ create_objects_from_handles ( } static nssCryptokiObject ** -find_objects ( - NSSToken *tok, +find_objects_by_template ( + NSSToken *token, nssSession *session, CK_ATTRIBUTE_PTR obj_template, CK_ULONG otsize, @@ -460,7 +442,7 @@ find_objects ( CK_OBJECT_HANDLE *objectHandles; CK_OBJECT_HANDLE staticObjects[OBJECT_STACK_SIZE]; PRUint32 arraySize, numHandles; - void *epv = nssToken_GetCryptokiEPV(tok); + void *epv = nssToken_GetCryptokiEPV(token); nssCryptokiObject **objects; PR_ASSERT(session); /* XXX remove later */ @@ -531,7 +513,7 @@ find_objects ( goto loser; } if (numHandles > 0) { - objects = create_objects_from_handles(tok, session, + objects = create_objects_from_handles(token, session, objectHandles, numHandles); } else { objects = NULL; @@ -549,49 +531,6 @@ loser: return (nssCryptokiObject **)NULL; } -static nssCryptokiObject ** -find_objects_by_template ( - NSSToken *token, - nssSession *session, - CK_ATTRIBUTE_PTR obj_template, - CK_ULONG otsize, - PRUint32 maximumOpt, - PRStatus *statusOpt -) -{ - CK_OBJECT_CLASS objclass; - nssCryptokiObject **objects = NULL; - PRUint32 i; - for (i=0; i<otsize; i++) { - if (obj_template[i].type == CKA_CLASS) { - objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue; - break; - } - } - PR_ASSERT(i < otsize); - /* If these objects are being cached, try looking there first */ - if (token->cache && - nssTokenObjectCache_HaveObjectClass(token->cache, objclass)) - { - PRStatus status; - objects = nssTokenObjectCache_FindObjectsByTemplate(token->cache, - objclass, - obj_template, - otsize, - maximumOpt, - &status); - if (status == PR_SUCCESS) { - if (statusOpt) *statusOpt = status; - return objects; - } - } - /* Either they are not cached, or cache failed; look on token. */ - objects = find_objects(token, session, - obj_template, otsize, - maximumOpt, statusOpt); - return objects; -} - NSS_IMPLEMENT nssCryptokiObject * nssToken_ImportCert ( NSSToken *tok, @@ -677,14 +616,6 @@ nssToken_ImportCert ( /* Import the certificate onto the token */ rvObject = import_object(tok, session, cert_tmpl, ctsize); } - if (rvObject && tok->cache) { - /* The cache will overwrite the attributes if the object already - * exists. - */ - nssTokenObjectCache_ImportObject(tok->cache, rvObject, - CKO_CERTIFICATE, - cert_tmpl, ctsize); - } return rvObject; } @@ -703,7 +634,7 @@ nssToken_FindCerts ( CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE cert_template[2]; CK_ULONG ctsize; - nssCryptokiObject **objects; + NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); /* Set the search to token/session only if provided */ if (searchType == nssTokenSearchType_SessionOnly) { @@ -715,16 +646,9 @@ nssToken_FindCerts ( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); - if (searchType == nssTokenSearchType_TokenForced) { - objects = find_objects(token, session, - cert_template, ctsize, - maximumOpt, statusOpt); - } else { - objects = find_objects_by_template(token, session, - cert_template, ctsize, - maximumOpt, statusOpt); - } - return objects; + return find_objects_by_template(token, session, + cert_template, ctsize, + maximumOpt, statusOpt); } NSS_IMPLEMENT nssCryptokiObject ** @@ -740,7 +664,7 @@ nssToken_FindCertsBySubject ( CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE subj_template[3]; CK_ULONG stsize; - nssCryptokiObject **objects; + NSS_CK_TEMPLATE_START(subj_template, attr, stsize); /* Set the search to token/session only if provided */ if (searchType == nssTokenSearchType_SessionOnly) { @@ -751,11 +675,11 @@ nssToken_FindCertsBySubject ( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); 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, session, - subj_template, stsize, - maximumOpt, statusOpt); - return objects; + return find_objects_by_template(token, session, + subj_template, stsize, + maximumOpt, statusOpt); } NSS_IMPLEMENT nssCryptokiObject ** @@ -772,6 +696,7 @@ nssToken_FindCertsByNickname ( CK_ATTRIBUTE nick_template[3]; CK_ULONG ntsize; nssCryptokiObject **objects; + NSS_CK_TEMPLATE_START(nick_template, attr, ntsize); NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, name); /* Set the search to token/session only if provided */ @@ -821,6 +746,7 @@ nssToken_FindCertsByEmail ( CK_ATTRIBUTE email_template[3]; CK_ULONG etsize; nssCryptokiObject **objects; + NSS_CK_TEMPLATE_START(email_template, attr, etsize); NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NETSCAPE_EMAIL, email); /* Set the search to token/session only if provided */ @@ -832,7 +758,7 @@ nssToken_FindCertsByEmail ( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); NSS_CK_TEMPLATE_FINISH(email_template, attr, etsize); /* now locate the token certs matching this template */ - objects = find_objects(token, session, + objects = find_objects_by_template(token, session, email_template, etsize, maximumOpt, statusOpt); if (!objects) { @@ -843,7 +769,7 @@ nssToken_FindCertsByEmail ( * well, its needed by the builtin token... */ email_template[0].ulValueLen++; - objects = find_objects(token, session, + objects = find_objects_by_template(token, session, email_template, etsize, maximumOpt, statusOpt); } @@ -863,7 +789,7 @@ nssToken_FindCertsByID ( CK_ATTRIBUTE_PTR attr; CK_ATTRIBUTE id_template[3]; CK_ULONG idtsize; - nssCryptokiObject **objects; + NSS_CK_TEMPLATE_START(id_template, attr, idtsize); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id); /* Set the search to token/session only if provided */ @@ -874,11 +800,11 @@ nssToken_FindCertsByID ( } 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, session, - id_template, idtsize, - maximumOpt, statusOpt); - return objects; + return find_objects_by_template(token, session, + id_template, idtsize, + maximumOpt, statusOpt); } /* @@ -954,15 +880,9 @@ nssToken_FindCertByIssuerAndSerialNumber ( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial); NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); /* get the object handle */ - if (searchType == nssTokenSearchType_TokenForced) { - objects = find_objects(token, session, - cert_template, ctsize, - 1, statusOpt); - } else { - objects = find_objects_by_template(token, session, + objects = find_objects_by_template(token, session, cert_template, ctsize, 1, statusOpt); - } if (objects) { rvObject = objects[0]; nss_ZFreeIf(objects); @@ -981,15 +901,9 @@ nssToken_FindCertByIssuerAndSerialNumber ( return NULL; } NSS_CK_SET_ATTRIBUTE_ITEM(serialAttr,CKA_SERIAL_NUMBER,&serialDecode); - if (searchType == nssTokenSearchType_TokenForced) { - objects = find_objects(token, session, - cert_template, ctsize, - 1, statusOpt); - } else { objects = find_objects_by_template(token, session, cert_template, ctsize, 1, statusOpt); - } if (objects) { rvObject = objects[0]; nss_ZFreeIf(objects); @@ -1254,10 +1168,6 @@ nssToken_ImportTrust ( NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize); /* import the trust object onto the token */ object = import_object(tok, session, trust_tmpl, tsize); - if (object && tok->cache) { - nssTokenObjectCache_ImportObject(tok->cache, object, tobjc, - trust_tmpl, tsize); - } return object; } @@ -1286,15 +1196,9 @@ nssToken_FindTrustObjects ( NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); - if (searchType == nssTokenSearchType_TokenForced) { - objects = find_objects(token, session, - tobj_template, tobj_size, - maximumOpt, statusOpt); - } else { - objects = find_objects_by_template(token, session, - tobj_template, tobj_size, - maximumOpt, statusOpt); - } + objects = find_objects_by_template(token, session, + tobj_template, tobj_size, + maximumOpt, statusOpt); return objects; } @@ -1371,10 +1275,6 @@ nssToken_ImportCRL ( /* import the crl object onto the token */ object = import_object(token, session, crl_tmpl, crlsize); - if (object && token->cache) { - nssTokenObjectCache_ImportObject(token->cache, object, crlobjc, - crl_tmpl, crlsize); - } return object; } @@ -1403,15 +1303,9 @@ nssToken_FindCRLs ( NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, crlobjc); NSS_CK_TEMPLATE_FINISH(crlobj_template, attr, crlobj_size); - if (searchType == nssTokenSearchType_TokenForced) { - objects = find_objects(token, session, - crlobj_template, crlobj_size, - maximumOpt, statusOpt); - } else { - objects = find_objects_by_template(token, session, - crlobj_template, crlobj_size, - maximumOpt, statusOpt); - } + objects = find_objects_by_template(token, session, + crlobj_template, crlobj_size, + maximumOpt, statusOpt); return objects; } diff --git a/security/nss/lib/dev/devutil.c b/security/nss/lib/dev/devutil.c index e196bdcbe..3554951a6 100644 --- a/security/nss/lib/dev/devutil.c +++ b/security/nss/lib/dev/devutil.c @@ -104,11 +104,7 @@ nssCryptokiObject_DeleteStoredObject ( { CK_RV ckrv; nssSession *rwSession; /* XXX is there a better way? */ - nssTokenObjectCache *cache = nssToken_GetObjectCache(object->token); void *epv = nssToken_GetCryptokiEPV(object->token); - if (cache) { - nssTokenObjectCache_RemoveObject(cache, object); - } if (!object->isTokenObject || nssSession_IsReadWrite(object->session)) { rwSession = object->session; @@ -614,856 +610,3 @@ nssSlotList_FindTokenByName ( return rvToken; } -/* object cache for token */ - -typedef struct -{ - NSSArena *arena; - nssCryptokiObject *object; - CK_ATTRIBUTE_PTR attributes; - CK_ULONG numAttributes; -} -nssCryptokiObjectAndAttributes; - -enum { - cachedCerts = 0, - cachedTrust = 1, - cachedCRLs = 2 -} cachedObjectType; - -struct nssTokenObjectCacheStr -{ - NSSToken *token; - PZLock *lock; - PRBool loggedIn; - PRBool doObjectType[3]; - PRBool searchedObjectType[3]; - nssCryptokiObjectAndAttributes **objects[3]; -}; - -NSS_IMPLEMENT nssTokenObjectCache * -nssTokenObjectCache_Create ( - NSSToken *token, - PRBool cacheCerts, - PRBool cacheTrust, - PRBool cacheCRLs -) -{ - nssTokenObjectCache *rvCache; - rvCache = nss_ZNEW(NULL, nssTokenObjectCache); - if (!rvCache) { - goto loser; - } - rvCache->lock = PZ_NewLock(nssILockOther); /* XXX */ - if (!rvCache->lock) { - goto loser; - } - rvCache->doObjectType[cachedCerts] = cacheCerts; - rvCache->doObjectType[cachedTrust] = cacheTrust; - rvCache->doObjectType[cachedCRLs] = cacheCRLs; - rvCache->token = token; /* cache goes away with token */ - return rvCache; -loser: - return (nssTokenObjectCache *)NULL; -} - -static void -clear_cache ( - nssTokenObjectCache *cache -) -{ - nssCryptokiObjectAndAttributes **oa; - PRUint32 objectType; - for (objectType = cachedCerts; objectType <= cachedCRLs; objectType++) { - if (!cache->objects[objectType]) { - continue; - } - for (oa = cache->objects[objectType]; *oa; oa++) { - /* prevent the token from being destroyed */ - (*oa)->object->token = NULL; - nssCryptokiObject_Destroy((*oa)->object); - nssArena_Destroy((*oa)->arena); - } - nss_ZFreeIf(cache->objects[objectType]); - cache->objects[objectType] = NULL; - cache->searchedObjectType[objectType] = PR_FALSE; - } -} - -NSS_IMPLEMENT void -nssTokenObjectCache_Clear ( - nssTokenObjectCache *cache -) -{ - if (cache) { - clear_cache(cache); - } -} - -NSS_IMPLEMENT void -nssTokenObjectCache_Destroy ( - nssTokenObjectCache *cache -) -{ - if (cache) { - clear_cache(cache); - PZ_DestroyLock(cache->lock); - nss_ZFreeIf(cache); - } -} - -NSS_IMPLEMENT PRBool -nssTokenObjectCache_HaveObjectClass ( - nssTokenObjectCache *cache, - CK_OBJECT_CLASS objclass -) -{ - PRBool haveIt; - PZ_Lock(cache->lock); - switch (objclass) { - case CKO_CERTIFICATE: haveIt = cache->doObjectType[cachedCerts]; break; - case CKO_NETSCAPE_TRUST: haveIt = cache->doObjectType[cachedTrust]; break; - case CKO_NETSCAPE_CRL: haveIt = cache->doObjectType[cachedCRLs]; break; - default: haveIt = PR_FALSE; - } - PZ_Unlock(cache->lock); - return haveIt; -} - -static nssCryptokiObjectAndAttributes ** -create_object_array ( - nssCryptokiObject **objects, - PRBool *doObjects, - PRUint32 *numObjects, - PRStatus *status -) -{ - nssCryptokiObject **op = objects; - nssCryptokiObjectAndAttributes **rvOandA = NULL; - *numObjects = 0; - /* There are no objects for this type */ - if (!objects) { - return (nssCryptokiObjectAndAttributes **)NULL; - } - while (*op++) (*numObjects)++; - if (*numObjects == MAX_LOCAL_CACHE_OBJECTS) { - /* Hit the maximum allowed, so don't use a cache (there are - * too many objects to make caching worthwhile, presumably, if - * the token can handle that many objects, it can handle searching. - */ - *doObjects = PR_FALSE; - *status = PR_FAILURE; - *numObjects = 0; - } else if (*numObjects > 0) { - rvOandA = nss_ZNEWARRAY(NULL, - nssCryptokiObjectAndAttributes *, - *numObjects + 1); - *status = rvOandA ? PR_SUCCESS : PR_FALSE; - } - return rvOandA; -} - -static nssCryptokiObjectAndAttributes * -create_object ( - nssCryptokiObject *object, - CK_ATTRIBUTE_TYPE *types, - PRUint32 numTypes, - PRStatus *status -) -{ - PRUint32 j; - NSSArena *arena; - NSSSlot *slot = NULL; - nssSession *session = NULL; - nssCryptokiObjectAndAttributes *rvCachedObject = NULL; - - slot = nssToken_GetSlot(object->token); - session = nssToken_GetDefaultSession(object->token); - - arena = nssArena_Create(); - if (!arena) { - nssSlot_Destroy(slot); - return (nssCryptokiObjectAndAttributes *)NULL; - } - rvCachedObject = nss_ZNEW(arena, nssCryptokiObjectAndAttributes); - if (!rvCachedObject) { - goto loser; - } - rvCachedObject->arena = arena; - /* The cache is tied to the token, and therefore the objects - * in it should not hold references to the token. - */ - nssToken_Destroy(object->token); - rvCachedObject->object = object; - rvCachedObject->attributes = nss_ZNEWARRAY(arena, CK_ATTRIBUTE, numTypes); - if (!rvCachedObject->attributes) { - goto loser; - } - for (j=0; j<numTypes; j++) { - rvCachedObject->attributes[j].type = types[j]; - } - *status = nssCKObject_GetAttributes(object->handle, - rvCachedObject->attributes, - numTypes, - arena, - session, - slot); - if (*status != PR_SUCCESS) { - goto loser; - } - rvCachedObject->numAttributes = numTypes; - *status = PR_SUCCESS; - if (slot) { - nssSlot_Destroy(slot); - } - return rvCachedObject; -loser: - *status = PR_FAILURE; - if (slot) { - nssSlot_Destroy(slot); - } - nssArena_Destroy(arena); - return (nssCryptokiObjectAndAttributes *)NULL; -} - -/* - * - * State diagram for cache: - * - * token !present token removed - * +-------------------------+<----------------------+ - * | ^ | - * v | | - * +----------+ slot friendly | token present +----------+ - * | cache | -----------------> % ---------------> | cache | - * | unloaded | | loaded | - * +----------+ +----------+ - * ^ | ^ | - * | | slot !friendly slot logged in | | - * | +-----------------------> % ----------------------+ | - * | | | - * | slot logged out v slot !friendly | - * +-----------------------------+<--------------------------+ - * - */ -static PRBool -search_for_objects ( - nssTokenObjectCache *cache -) -{ - PRBool doSearch = PR_FALSE; - NSSSlot *slot = nssToken_GetSlot(cache->token); - if (!nssSlot_IsTokenPresent(slot)) { - /* The token is no longer present, destroy any cached objects */ - /* clear_cache(cache); */ - nssSlot_Destroy(slot); - return PR_FALSE; - } - /* Handle non-friendly slots (slots which require login for objects) */ - if (!nssSlot_IsFriendly(slot)) { - if (nssSlot_IsLoggedIn(slot)) { - /* Either no state change, or went from !logged in -> logged in */ - cache->loggedIn = PR_TRUE; - doSearch = PR_TRUE; - } else { - if (cache->loggedIn) { - /* went from logged in -> !logged in, destroy cached objects */ - clear_cache(cache); - cache->loggedIn = PR_FALSE; - } /* else no state change, still not logged in, so exit */ - } - } else { - /* slot is friendly, thus always available for search */ - doSearch = PR_TRUE; - } - nssSlot_Destroy(slot); - return doSearch; -} - -static nssCryptokiObjectAndAttributes * -create_cert ( - nssCryptokiObject *object, - PRStatus *status -) -{ - CK_ATTRIBUTE_TYPE certAttr[] = { - CKA_CLASS, - CKA_TOKEN, - CKA_LABEL, - CKA_CERTIFICATE_TYPE, - CKA_ID, - CKA_VALUE, - CKA_ISSUER, - CKA_SERIAL_NUMBER, - CKA_SUBJECT, - CKA_NETSCAPE_EMAIL - }; - PRUint32 numCertAttr = sizeof(certAttr) / sizeof(certAttr[0]); - return create_object(object, certAttr, numCertAttr, status); -} - -static PRStatus -get_token_certs_for_cache ( - nssTokenObjectCache *cache -) -{ - PRStatus status; - nssCryptokiObject **objects; - PRBool *doIt = &cache->doObjectType[cachedCerts]; - PRUint32 i, numObjects; - nssSession *session; - - if (!search_for_objects(cache) || - cache->searchedObjectType[cachedCerts] || - !cache->doObjectType[cachedCerts]) - { - /* Either there was a state change that prevents a search - * (token removed or logged out), or the search was already done, - * or certs are not being cached. - */ - return PR_SUCCESS; - } - session = nssToken_GetDefaultSession(cache->token); /* XXX */ - objects = nssToken_FindCerts(cache->token, session, - nssTokenSearchType_TokenForced, - MAX_LOCAL_CACHE_OBJECTS, &status); - if (status != PR_SUCCESS) { - return status; - } - cache->objects[cachedCerts] = create_object_array(objects, - doIt, - &numObjects, - &status); - if (status != PR_SUCCESS) { - return status; - } - for (i=0; i<numObjects; i++) { - cache->objects[cachedCerts][i] = create_cert(objects[i], &status); - if (status != PR_SUCCESS) { - break; - } - } - if (status == PR_SUCCESS) { - nss_ZFreeIf(objects); - } else { - PRUint32 j; - for (j=0; j<i; j++) { - /* sigh */ - nssToken_AddRef(cache->objects[cachedCerts][i]->object->token); - nssArena_Destroy(cache->objects[cachedCerts][i]->arena); - } - nssCryptokiObjectArray_Destroy(objects); - } - cache->searchedObjectType[cachedCerts] = PR_TRUE; - return status; -} - -static nssCryptokiObjectAndAttributes * -create_trust ( - nssCryptokiObject *object, - PRStatus *status -) -{ - CK_ATTRIBUTE_TYPE trustAttr[] = { - CKA_CLASS, - CKA_TOKEN, - CKA_LABEL, - CKA_CERT_SHA1_HASH, - CKA_CERT_MD5_HASH, - CKA_ISSUER, - CKA_SUBJECT, - CKA_TRUST_SERVER_AUTH, - CKA_TRUST_CLIENT_AUTH, - CKA_TRUST_EMAIL_PROTECTION, - CKA_TRUST_CODE_SIGNING - }; - PRUint32 numTrustAttr = sizeof(trustAttr) / sizeof(trustAttr[0]); - return create_object(object, trustAttr, numTrustAttr, status); -} - -static PRStatus -get_token_trust_for_cache ( - nssTokenObjectCache *cache -) -{ - PRStatus status; - nssCryptokiObject **objects; - PRBool *doIt = &cache->doObjectType[cachedTrust]; - PRUint32 i, numObjects; - nssSession *session; - - if (!search_for_objects(cache) || - cache->searchedObjectType[cachedTrust] || - !cache->doObjectType[cachedTrust]) - { - /* Either there was a state change that prevents a search - * (token removed or logged out), or the search was already done, - * or trust is not being cached. - */ - return PR_SUCCESS; - } - session = nssToken_GetDefaultSession(cache->token); /* XXX */ - objects = nssToken_FindTrustObjects(cache->token, session, - nssTokenSearchType_TokenForced, - MAX_LOCAL_CACHE_OBJECTS, &status); - if (status != PR_SUCCESS) { - return status; - } - cache->objects[cachedTrust] = create_object_array(objects, - doIt, - &numObjects, - &status); - if (status != PR_SUCCESS) { - return status; - } - for (i=0; i<numObjects; i++) { - cache->objects[cachedTrust][i] = create_trust(objects[i], &status); - if (status != PR_SUCCESS) { - break; - } - } - if (status == PR_SUCCESS) { - nss_ZFreeIf(objects); - } else { - PRUint32 j; - for (j=0; j<i; j++) { - /* sigh */ - nssToken_AddRef(cache->objects[cachedTrust][i]->object->token); - nssArena_Destroy(cache->objects[cachedTrust][i]->arena); - } - nssCryptokiObjectArray_Destroy(objects); - } - cache->searchedObjectType[cachedTrust] = PR_TRUE; - return status; -} - -static nssCryptokiObjectAndAttributes * -create_crl ( - nssCryptokiObject *object, - PRStatus *status -) -{ - CK_ATTRIBUTE_TYPE crlAttr[] = { - CKA_CLASS, - CKA_TOKEN, - CKA_LABEL, - CKA_VALUE, - CKA_SUBJECT, - CKA_NETSCAPE_KRL, - CKA_NETSCAPE_URL - }; - PRUint32 numCRLAttr = sizeof(crlAttr) / sizeof(crlAttr[0]); - return create_object(object, crlAttr, numCRLAttr, status); -} - -static PRStatus -get_token_crls_for_cache ( - nssTokenObjectCache *cache -) -{ - PRStatus status; - nssCryptokiObject **objects; - PRBool *doIt = &cache->doObjectType[cachedCRLs]; - PRUint32 i, numObjects; - - if (!search_for_objects(cache) || - cache->searchedObjectType[cachedCRLs] || - !cache->doObjectType[cachedCRLs]) - { - /* Either there was a state change that prevents a search - * (token removed or logged out), or the search was already done, - * or CRLs are not being cached. - */ - return PR_SUCCESS; - } - objects = nssToken_FindCRLs(cache->token, NULL, - nssTokenSearchType_TokenForced, - MAX_LOCAL_CACHE_OBJECTS, &status); - if (status != PR_SUCCESS) { - return status; - } - cache->objects[cachedCRLs] = create_object_array(objects, - doIt, - &numObjects, - &status); - if (status != PR_SUCCESS) { - return status; - } - for (i=0; i<numObjects; i++) { - cache->objects[cachedCRLs][i] = create_crl(objects[i], &status); - if (status != PR_SUCCESS) { - break; - } - } - if (status == PR_SUCCESS) { - nss_ZFreeIf(objects); - } else { - PRUint32 j; - for (j=0; j<i; j++) { - /* sigh */ - nssToken_AddRef(cache->objects[cachedCRLs][i]->object->token); - nssArena_Destroy(cache->objects[cachedCRLs][i]->arena); - } - nssCryptokiObjectArray_Destroy(objects); - } - cache->searchedObjectType[cachedCRLs] = PR_TRUE; - return status; -} - -static nssCryptokiObject ** -find_objects_in_array ( - nssCryptokiObjectAndAttributes **objArray, - CK_ATTRIBUTE_PTR ot, - CK_ULONG otlen, - PRUint32 maximumOpt -) -{ - PRIntn oi; - PRUint32 i, j; - PRBool match; - NSSArena *arena; - PRUint32 size = 8; - PRUint32 numMatches = 0; - nssCryptokiObject **objects = NULL; - nssCryptokiObjectAndAttributes **matches = NULL; - if (!objArray) { - return (nssCryptokiObject **)NULL; - } - arena = nssArena_Create(); - if (!arena) { - return (nssCryptokiObject **)NULL; - } - matches = nss_ZNEWARRAY(arena, nssCryptokiObjectAndAttributes *, size); - if (!matches) { - goto loser; - } - if (maximumOpt == 0) maximumOpt = ~0; - for (; *objArray && numMatches < maximumOpt; objArray++) { - nssCryptokiObjectAndAttributes *obj = *objArray; - for (i=0; i<otlen; i++) { - for (j=0; j<obj->numAttributes; j++) { - if (ot[i].type == obj->attributes[j].type) { - if (ot[i].ulValueLen == obj->attributes[j].ulValueLen && - nsslibc_memequal(ot[i].pValue, - obj->attributes[j].pValue, - ot[i].ulValueLen, NULL)) - { - match = PR_TRUE; - } else { - match = PR_FALSE; - } - break; - } - } - if (j == obj->numAttributes || !match) { - break; - } - } - if (match) { - matches[numMatches++] = obj; - if (numMatches == size) { - size *= 2; - matches = nss_ZREALLOCARRAY(matches, - nssCryptokiObjectAndAttributes *, - size); - if (!matches) { - goto loser; - } - } - } - } - if (numMatches > 0) { - objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numMatches + 1); - if (!objects) { - goto loser; - } - for (oi=0; oi<(PRIntn)numMatches; oi++) { - objects[oi] = nssCryptokiObject_Clone(matches[oi]->object); - if (!objects[oi]) { - goto loser; - } - } - } - nssArena_Destroy(arena); - return objects; -loser: - if (objects) { - for (--oi; oi>=0; --oi) { - nssCryptokiObject_Destroy(objects[oi]); - } - } - nssArena_Destroy(arena); - return (nssCryptokiObject **)NULL; -} - -NSS_IMPLEMENT nssCryptokiObject ** -nssTokenObjectCache_FindObjectsByTemplate ( - nssTokenObjectCache *cache, - CK_OBJECT_CLASS objclass, - CK_ATTRIBUTE_PTR otemplate, - CK_ULONG otlen, - PRUint32 maximumOpt, - PRStatus *statusOpt -) -{ - PRStatus status = PR_FAILURE; - nssCryptokiObject **rvObjects = NULL; - PZ_Lock(cache->lock); - switch (objclass) { - case CKO_CERTIFICATE: - if (cache->doObjectType[cachedCerts]) { - status = get_token_certs_for_cache(cache); - if (status != PR_SUCCESS) { - goto finish; - } - rvObjects = find_objects_in_array(cache->objects[cachedCerts], - otemplate, otlen, maximumOpt); - } - break; - case CKO_NETSCAPE_TRUST: - if (cache->doObjectType[cachedTrust]) { - status = get_token_trust_for_cache(cache); - if (status != PR_SUCCESS) { - goto finish; - } - rvObjects = find_objects_in_array(cache->objects[cachedTrust], - otemplate, otlen, maximumOpt); - } - break; - case CKO_NETSCAPE_CRL: - if (cache->doObjectType[cachedCRLs]) { - status = get_token_crls_for_cache(cache); - if (status != PR_SUCCESS) { - goto finish; - } - rvObjects = find_objects_in_array(cache->objects[cachedCRLs], - otemplate, otlen, maximumOpt); - } - break; - default: break; - } -finish: - PZ_Unlock(cache->lock); - if (statusOpt) { - *statusOpt = status; - } - return rvObjects; -} - -static PRBool -cache_available_for_object_type ( - nssTokenObjectCache *cache, - PRUint32 objectType -) -{ - if (!cache->doObjectType[objectType]) { - /* not caching this object kind */ - return PR_FALSE; - } - if (!cache->searchedObjectType[objectType]) { - /* objects are not cached yet */ - return PR_FALSE; - } - if (!search_for_objects(cache)) { - /* not logged in or removed */ - return PR_FALSE; - } - return PR_TRUE; -} - -NSS_IMPLEMENT PRStatus -nssTokenObjectCache_GetObjectAttributes ( - nssTokenObjectCache *cache, - NSSArena *arenaOpt, - nssCryptokiObject *object, - CK_OBJECT_CLASS objclass, - CK_ATTRIBUTE_PTR atemplate, - CK_ULONG atlen -) -{ - PRUint32 i, j; - NSSArena *arena = NULL; - nssArenaMark *mark = NULL; - nssCryptokiObjectAndAttributes *cachedOA = NULL; - nssCryptokiObjectAndAttributes **oa = NULL; - PRUint32 objectType; - PZ_Lock(cache->lock); - switch (objclass) { - case CKO_CERTIFICATE: objectType = cachedCerts; break; - case CKO_NETSCAPE_TRUST: objectType = cachedTrust; break; - case CKO_NETSCAPE_CRL: objectType = cachedCRLs; break; - default: goto loser; - } - if (!cache_available_for_object_type(cache, objectType)) { - goto loser; - } - oa = cache->objects[objectType]; - if (!oa) { - goto loser; - } - for (; *oa; oa++) { - if (nssCryptokiObject_Equal((*oa)->object, object)) { - cachedOA = *oa; - break; - } - } - if (!cachedOA) { - goto loser; /* don't have this object */ - } - if (arenaOpt) { - arena = arenaOpt; - mark = nssArena_Mark(arena); - } - for (i=0; i<atlen; i++) { - for (j=0; j<cachedOA->numAttributes; j++) { - if (atemplate[i].type == cachedOA->attributes[j].type) { - CK_ATTRIBUTE_PTR attr = &cachedOA->attributes[j]; - if (cachedOA->attributes[j].ulValueLen == 0 || - cachedOA->attributes[j].ulValueLen == (CK_ULONG)-1) - { - break; /* invalid attribute */ - } - if (atemplate[i].ulValueLen > 0) { - if (atemplate[i].pValue == NULL || - atemplate[i].ulValueLen < attr->ulValueLen) - { - goto loser; - } - } else { - atemplate[i].pValue = nss_ZAlloc(arena, attr->ulValueLen); - if (!atemplate[i].pValue) { - goto loser; - } - } - nsslibc_memcpy(atemplate[i].pValue, - attr->pValue, attr->ulValueLen); - atemplate[i].ulValueLen = attr->ulValueLen; - break; - } - } - if (j == cachedOA->numAttributes) { - atemplate[i].ulValueLen = (CK_ULONG)-1; - } - } - PZ_Unlock(cache->lock); - if (mark) { - nssArena_Unmark(arena, mark); - } - return PR_SUCCESS; -loser: - PZ_Unlock(cache->lock); - if (mark) { - nssArena_Release(arena, mark); - } - return PR_FAILURE; -} - -NSS_IMPLEMENT PRStatus -nssTokenObjectCache_ImportObject ( - nssTokenObjectCache *cache, - nssCryptokiObject *object, - CK_OBJECT_CLASS objclass, - CK_ATTRIBUTE_PTR ot, - CK_ULONG otlen -) -{ - PRStatus status = PR_SUCCESS; - PRUint32 count; - nssCryptokiObjectAndAttributes **oa, ***otype; - PRUint32 objectType; - PRBool haveIt = PR_FALSE; - - PZ_Lock(cache->lock); - switch (objclass) { - case CKO_CERTIFICATE: objectType = cachedCerts; break; - case CKO_NETSCAPE_TRUST: objectType = cachedTrust; break; - case CKO_NETSCAPE_CRL: objectType = cachedCRLs; break; - default: - PZ_Unlock(cache->lock); - return PR_SUCCESS; /* don't need to import it here */ - } - if (!cache_available_for_object_type(cache, objectType)) { - PZ_Unlock(cache->lock); - return PR_SUCCESS; /* cache not active, ignored */ - } - count = 0; - otype = &cache->objects[objectType]; /* index into array of types */ - oa = *otype; /* the array of objects for this type */ - while (oa && *oa) { - if (nssCryptokiObject_Equal((*oa)->object, object)) { - haveIt = PR_TRUE; - break; - } - count++; - oa++; - } - if (haveIt) { - /* Destroy the old entry */ - (*oa)->object->token = NULL; - nssCryptokiObject_Destroy((*oa)->object); - nssArena_Destroy((*oa)->arena); - } else { - /* Create space for a new entry */ - if (count > 0) { - *otype = nss_ZREALLOCARRAY(*otype, - nssCryptokiObjectAndAttributes *, - count + 2); - } else { - *otype = nss_ZNEWARRAY(NULL, nssCryptokiObjectAndAttributes *, 2); - } - } - if (*otype) { - nssCryptokiObject *copyObject = nssCryptokiObject_Clone(object); - if (objectType == cachedCerts) { - (*otype)[count] = create_cert(copyObject, &status); - } else if (objectType == cachedTrust) { - (*otype)[count] = create_trust(copyObject, &status); - } else if (objectType == cachedCRLs) { - (*otype)[count] = create_crl(copyObject, &status); - } - } else { - status = PR_FAILURE; - } - PZ_Unlock(cache->lock); - return status; -} - -NSS_IMPLEMENT void -nssTokenObjectCache_RemoveObject ( - nssTokenObjectCache *cache, - nssCryptokiObject *object -) -{ - PRUint32 oType; - nssCryptokiObjectAndAttributes **oa, **swp = NULL; - PZ_Lock(cache->lock); - for (oType=0; oType<3; oType++) { - if (!cache_available_for_object_type(cache, oType) || - !cache->objects[oType]) - { - continue; - } - for (oa = cache->objects[oType]; *oa; oa++) { - if (nssCryptokiObject_Equal((*oa)->object, object)) { - swp = oa; /* the entry to remove */ - while (oa[1]) oa++; /* go to the tail */ - (*swp)->object->token = NULL; - nssCryptokiObject_Destroy((*swp)->object); - nssArena_Destroy((*swp)->arena); /* destroy it */ - *swp = *oa; /* swap the last with the removed */ - *oa = NULL; /* null-terminate the array */ - break; - } - } - if (swp) { - break; - } - } - if ((oType <3) && - cache->objects[oType] && cache->objects[oType][0] == NULL) { - nss_ZFreeIf(cache->objects[oType]); /* no entries remaining */ - cache->objects[oType] = NULL; - } - PZ_Unlock(cache->lock); -} - |