Index: mozilla/security/nss/lib/dev/devutil.c |
=================================================================== |
--- mozilla/security/nss/lib/dev/devutil.c (revision 191424) |
+++ mozilla/security/nss/lib/dev/devutil.c (working copy) |
@@ -1,1010 +0,0 @@ |
-/* This Source Code Form is subject to the terms of the Mozilla Public |
- * License, v. 2.0. If a copy of the MPL was not distributed with this |
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
- |
-#ifdef DEBUG |
-static const char CVS_ID[] = "@(#) $RCSfile: devutil.c,v $ $Revision: 1.36 $ $Date: 2012/04/25 14:49:42 $"; |
-#endif /* DEBUG */ |
- |
-#ifndef DEVM_H |
-#include "devm.h" |
-#endif /* DEVM_H */ |
- |
-#ifndef CKHELPER_H |
-#include "ckhelper.h" |
-#endif /* CKHELPER_H */ |
- |
-NSS_IMPLEMENT nssCryptokiObject * |
-nssCryptokiObject_Create ( |
- NSSToken *t, |
- nssSession *session, |
- CK_OBJECT_HANDLE h |
-) |
-{ |
- PRStatus status; |
- NSSSlot *slot; |
- nssCryptokiObject *object; |
- CK_BBOOL *isTokenObject; |
- CK_ATTRIBUTE cert_template[] = { |
- { CKA_TOKEN, NULL, 0 }, |
- { CKA_LABEL, NULL, 0 } |
- }; |
- slot = nssToken_GetSlot(t); |
- status = nssCKObject_GetAttributes(h, cert_template, 2, |
- NULL, session, slot); |
- nssSlot_Destroy(slot); |
- if (status != PR_SUCCESS) { |
- /* a failure here indicates a device error */ |
- return (nssCryptokiObject *)NULL; |
- } |
- object = nss_ZNEW(NULL, nssCryptokiObject); |
- if (!object) { |
- return (nssCryptokiObject *)NULL; |
- } |
- object->handle = h; |
- object->token = nssToken_AddRef(t); |
- isTokenObject = (CK_BBOOL *)cert_template[0].pValue; |
- object->isTokenObject = *isTokenObject; |
- nss_ZFreeIf(isTokenObject); |
- NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[1], object->label); |
- return object; |
-} |
- |
-NSS_IMPLEMENT void |
-nssCryptokiObject_Destroy ( |
- nssCryptokiObject *object |
-) |
-{ |
- if (object) { |
- nssToken_Destroy(object->token); |
- nss_ZFreeIf(object->label); |
- nss_ZFreeIf(object); |
- } |
-} |
- |
-NSS_IMPLEMENT nssCryptokiObject * |
-nssCryptokiObject_Clone ( |
- nssCryptokiObject *object |
-) |
-{ |
- nssCryptokiObject *rvObject; |
- rvObject = nss_ZNEW(NULL, nssCryptokiObject); |
- if (rvObject) { |
- rvObject->handle = object->handle; |
- rvObject->token = nssToken_AddRef(object->token); |
- rvObject->isTokenObject = object->isTokenObject; |
- if (object->label) { |
- rvObject->label = nssUTF8_Duplicate(object->label, NULL); |
- } |
- } |
- return rvObject; |
-} |
- |
-NSS_EXTERN PRBool |
-nssCryptokiObject_Equal ( |
- nssCryptokiObject *o1, |
- nssCryptokiObject *o2 |
-) |
-{ |
- return (o1->token == o2->token && o1->handle == o2->handle); |
-} |
- |
-NSS_IMPLEMENT PRUint32 |
-nssPKCS11String_Length(CK_CHAR *pkcs11Str, PRUint32 bufLen) |
-{ |
- PRInt32 i; |
- for (i = bufLen - 1; i>=0; ) { |
- if (pkcs11Str[i] != ' ' && pkcs11Str[i] != '\0') break; |
- --i; |
- } |
- return (PRUint32)(i + 1); |
-} |
- |
-/* |
- * Slot arrays |
- */ |
- |
-NSS_IMPLEMENT NSSSlot ** |
-nssSlotArray_Clone ( |
- NSSSlot **slots |
-) |
-{ |
- NSSSlot **rvSlots = NULL; |
- NSSSlot **sp = slots; |
- PRUint32 count = 0; |
- while (sp && *sp) count++; |
- if (count > 0) { |
- rvSlots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1); |
- if (rvSlots) { |
- for (sp = slots, count = 0; *sp; sp++) { |
- rvSlots[count++] = nssSlot_AddRef(*sp); |
- } |
- } |
- } |
- return rvSlots; |
-} |
- |
-NSS_IMPLEMENT void |
-nssSlotArray_Destroy ( |
- NSSSlot **slots |
-) |
-{ |
- if (slots) { |
- NSSSlot **slotp; |
- for (slotp = slots; *slotp; slotp++) { |
- nssSlot_Destroy(*slotp); |
- } |
- nss_ZFreeIf(slots); |
- } |
-} |
- |
-NSS_IMPLEMENT void |
-NSSSlotArray_Destroy ( |
- NSSSlot **slots |
-) |
-{ |
- nssSlotArray_Destroy(slots); |
-} |
- |
-NSS_IMPLEMENT void |
-nssTokenArray_Destroy ( |
- NSSToken **tokens |
-) |
-{ |
- if (tokens) { |
- NSSToken **tokenp; |
- for (tokenp = tokens; *tokenp; tokenp++) { |
- nssToken_Destroy(*tokenp); |
- } |
- nss_ZFreeIf(tokens); |
- } |
-} |
- |
-NSS_IMPLEMENT void |
-NSSTokenArray_Destroy ( |
- NSSToken **tokens |
-) |
-{ |
- nssTokenArray_Destroy(tokens); |
-} |
- |
-NSS_IMPLEMENT void |
-nssCryptokiObjectArray_Destroy ( |
- nssCryptokiObject **objects |
-) |
-{ |
- if (objects) { |
- nssCryptokiObject **op; |
- for (op = objects; *op; op++) { |
- nssCryptokiObject_Destroy(*op); |
- } |
- nss_ZFreeIf(objects); |
- } |
-} |
- |
-/* 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: |
- nssTokenObjectCache_Destroy(rvCache); |
- return (nssTokenObjectCache *)NULL; |
-} |
- |
-static void |
-clear_cache ( |
- nssTokenObjectCache *cache |
-) |
-{ |
- nssCryptokiObjectAndAttributes **oa; |
- PRUint32 objectType; |
- for (objectType = cachedCerts; objectType <= cachedCRLs; objectType++) { |
- cache->searchedObjectType[objectType] = PR_FALSE; |
- 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; |
- } |
-} |
- |
-NSS_IMPLEMENT void |
-nssTokenObjectCache_Clear ( |
- nssTokenObjectCache *cache |
-) |
-{ |
- if (cache) { |
- PZ_Lock(cache->lock); |
- clear_cache(cache); |
- PZ_Unlock(cache->lock); |
- } |
-} |
- |
-NSS_IMPLEMENT void |
-nssTokenObjectCache_Destroy ( |
- nssTokenObjectCache *cache |
-) |
-{ |
- if (cache) { |
- clear_cache(cache); |
- if (cache->lock) { |
- 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 |
-) |
-{ |
- nssCryptokiObjectAndAttributes **rvOandA = NULL; |
- *numObjects = 0; |
- /* There are no objects for this type */ |
- if (!objects || !*objects) { |
- *status = PR_SUCCESS; |
- return rvOandA; |
- } |
- while (*objects++) (*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 { |
- rvOandA = nss_ZNEWARRAY(NULL, |
- nssCryptokiObjectAndAttributes *, |
- *numObjects + 1); |
- *status = rvOandA ? PR_SUCCESS : PR_FAILURE; |
- } |
- return rvOandA; |
-} |
- |
-static nssCryptokiObjectAndAttributes * |
-create_object ( |
- nssCryptokiObject *object, |
- const CK_ATTRIBUTE_TYPE *types, |
- PRUint32 numTypes, |
- PRStatus *status |
-) |
-{ |
- PRUint32 j; |
- NSSArena *arena = NULL; |
- NSSSlot *slot = NULL; |
- nssSession *session = NULL; |
- nssCryptokiObjectAndAttributes *rvCachedObject = NULL; |
- |
- slot = nssToken_GetSlot(object->token); |
- if (!slot) { |
- nss_SetError(NSS_ERROR_INVALID_POINTER); |
- goto loser; |
- } |
- session = nssToken_GetDefaultSession(object->token); |
- if (!session) { |
- nss_SetError(NSS_ERROR_INVALID_POINTER); |
- goto loser; |
- } |
- arena = nssArena_Create(); |
- if (!arena) { |
- goto loser; |
- } |
- 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; |
- nssSlot_Destroy(slot); |
- |
- return rvCachedObject; |
-loser: |
- *status = PR_FAILURE; |
- if (slot) { |
- nssSlot_Destroy(slot); |
- } |
- if (arena) |
- 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 | |
- * +-----------------------------+<--------------------------+ |
- * |
- */ |
- |
-/* This function must not be called with cache->lock locked. */ |
-static PRBool |
-token_is_present ( |
- nssTokenObjectCache *cache |
-) |
-{ |
- NSSSlot *slot = nssToken_GetSlot(cache->token); |
- PRBool tokenPresent = nssSlot_IsTokenPresent(slot); |
- nssSlot_Destroy(slot); |
- return tokenPresent; |
-} |
- |
-static PRBool |
-search_for_objects ( |
- nssTokenObjectCache *cache |
-) |
-{ |
- PRBool doSearch = PR_FALSE; |
- NSSSlot *slot = nssToken_GetSlot(cache->token); |
- /* 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 |
-) |
-{ |
- static const 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 |
- }; |
- static const PRUint32 numCertAttr = sizeof(certAttr) / sizeof(certAttr[0]); |
- return create_object(object, certAttr, numCertAttr, status); |
-} |
- |
-static nssCryptokiObjectAndAttributes * |
-create_trust ( |
- nssCryptokiObject *object, |
- PRStatus *status |
-) |
-{ |
- static const 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 |
- }; |
- static const PRUint32 numTrustAttr = sizeof(trustAttr) / sizeof(trustAttr[0]); |
- return create_object(object, trustAttr, numTrustAttr, status); |
-} |
- |
-static nssCryptokiObjectAndAttributes * |
-create_crl ( |
- nssCryptokiObject *object, |
- PRStatus *status |
-) |
-{ |
- static const CK_ATTRIBUTE_TYPE crlAttr[] = { |
- CKA_CLASS, |
- CKA_TOKEN, |
- CKA_LABEL, |
- CKA_VALUE, |
- CKA_SUBJECT, |
- CKA_NETSCAPE_KRL, |
- CKA_NETSCAPE_URL |
- }; |
- static const PRUint32 numCRLAttr = sizeof(crlAttr) / sizeof(crlAttr[0]); |
- return create_object(object, crlAttr, numCRLAttr, status); |
-} |
- |
-/* Dispatch to the create function for the object type */ |
-static nssCryptokiObjectAndAttributes * |
-create_object_of_type ( |
- nssCryptokiObject *object, |
- PRUint32 objectType, |
- PRStatus *status |
-) |
-{ |
- if (objectType == cachedCerts) { |
- return create_cert(object, status); |
- } |
- if (objectType == cachedTrust) { |
- return create_trust(object, status); |
- } |
- if (objectType == cachedCRLs) { |
- return create_crl(object, status); |
- } |
- return (nssCryptokiObjectAndAttributes *)NULL; |
-} |
- |
-static PRStatus |
-get_token_objects_for_cache ( |
- nssTokenObjectCache *cache, |
- PRUint32 objectType, |
- CK_OBJECT_CLASS objclass |
-) |
-{ |
- PRStatus status; |
- nssCryptokiObject **objects; |
- PRBool *doIt = &cache->doObjectType[objectType]; |
- PRUint32 i, numObjects; |
- |
- if (!search_for_objects(cache) || |
- cache->searchedObjectType[objectType] || |
- !cache->doObjectType[objectType]) |
- { |
- /* Either there was a state change that prevents a search |
- * (token logged out), or the search was already done, |
- * or objects of this type are not being cached. |
- */ |
- return PR_SUCCESS; |
- } |
- objects = nssToken_FindObjects(cache->token, NULL, objclass, |
- nssTokenSearchType_TokenForced, |
- MAX_LOCAL_CACHE_OBJECTS, &status); |
- if (status != PR_SUCCESS) { |
- return status; |
- } |
- cache->objects[objectType] = create_object_array(objects, |
- doIt, |
- &numObjects, |
- &status); |
- if (status != PR_SUCCESS) { |
- return status; |
- } |
- for (i=0; i<numObjects; i++) { |
- cache->objects[objectType][i] = create_object_of_type(objects[i], |
- objectType, |
- &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[objectType][j]->object->token); |
- nssArena_Destroy(cache->objects[objectType][j]->arena); |
- } |
- nss_ZFreeIf(cache->objects[objectType]); |
- cache->objects[objectType] = NULL; |
- nssCryptokiObjectArray_Destroy(objects); |
- } |
- cache->searchedObjectType[objectType] = PR_TRUE; |
- return status; |
-} |
- |
-static CK_ATTRIBUTE_PTR |
-find_attribute_in_object ( |
- nssCryptokiObjectAndAttributes *obj, |
- CK_ATTRIBUTE_TYPE attrType |
-) |
-{ |
- PRUint32 j; |
- for (j=0; j<obj->numAttributes; j++) { |
- if (attrType == obj->attributes[j].type) { |
- return &obj->attributes[j]; |
- } |
- } |
- return (CK_ATTRIBUTE_PTR)NULL; |
-} |
- |
-/* Find all objects in the array that match the supplied template */ |
-static nssCryptokiObject ** |
-find_objects_in_array ( |
- nssCryptokiObjectAndAttributes **objArray, |
- CK_ATTRIBUTE_PTR ot, |
- CK_ULONG otlen, |
- PRUint32 maximumOpt |
-) |
-{ |
- PRIntn oi = 0; |
- PRUint32 i; |
- NSSArena *arena; |
- PRUint32 size = 8; |
- PRUint32 numMatches = 0; |
- nssCryptokiObject **objects = NULL; |
- nssCryptokiObjectAndAttributes **matches = NULL; |
- CK_ATTRIBUTE_PTR attr; |
- |
- 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; |
- /* loop over the cached objects */ |
- for (; *objArray && numMatches < maximumOpt; objArray++) { |
- nssCryptokiObjectAndAttributes *obj = *objArray; |
- /* loop over the test template */ |
- for (i=0; i<otlen; i++) { |
- /* see if the object has the attribute */ |
- attr = find_attribute_in_object(obj, ot[i].type); |
- if (!attr) { |
- /* nope, match failed */ |
- break; |
- } |
- /* compare the attribute against the test value */ |
- if (ot[i].ulValueLen != attr->ulValueLen || |
- !nsslibc_memequal(ot[i].pValue, |
- attr->pValue, |
- attr->ulValueLen, NULL)) |
- { |
- /* nope, match failed */ |
- break; |
- } |
- } |
- if (i == otlen) { |
- /* all of the attributes in the test template were found |
- * in the object's template, and they all matched |
- */ |
- 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: |
- nssCryptokiObjectArray_Destroy(objects); |
- 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; |
- PRUint32 objectType; |
- if (!token_is_present(cache)) { |
- status = PR_SUCCESS; |
- goto finish; |
- } |
- switch (objclass) { |
- case CKO_CERTIFICATE: objectType = cachedCerts; break; |
- case CKO_NETSCAPE_TRUST: objectType = cachedTrust; break; |
- case CKO_NETSCAPE_CRL: objectType = cachedCRLs; break; |
- default: goto finish; |
- } |
- PZ_Lock(cache->lock); |
- if (cache->doObjectType[objectType]) { |
- status = get_token_objects_for_cache(cache, objectType, objclass); |
- if (status == PR_SUCCESS) { |
- rvObjects = find_objects_in_array(cache->objects[objectType], |
- otemplate, otlen, maximumOpt); |
- } |
- } |
- PZ_Unlock(cache->lock); |
-finish: |
- 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 */ |
- 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; |
- if (!token_is_present(cache)) { |
- return PR_FAILURE; |
- } |
- 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; |
- |
- if (!token_is_present(cache)) { |
- return PR_SUCCESS; /* cache not active, ignored */ |
- } |
- 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); |
- (*otype)[count] = create_object_of_type(copyObject, objectType, |
- &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; |
- if (!token_is_present(cache)) { |
- return; |
- } |
- 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); |
-} |
- |
-/* These two hash algorithms are presently sufficient. |
-** They are used for fingerprints of certs which are stored as the |
-** CKA_CERT_SHA1_HASH and CKA_CERT_MD5_HASH attributes. |
-** We don't need to add SHAxxx to these now. |
-*/ |
-/* XXX of course this doesn't belong here */ |
-NSS_IMPLEMENT NSSAlgorithmAndParameters * |
-NSSAlgorithmAndParameters_CreateSHA1Digest ( |
- NSSArena *arenaOpt |
-) |
-{ |
- NSSAlgorithmAndParameters *rvAP = NULL; |
- rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters); |
- if (rvAP) { |
- rvAP->mechanism.mechanism = CKM_SHA_1; |
- rvAP->mechanism.pParameter = NULL; |
- rvAP->mechanism.ulParameterLen = 0; |
- } |
- return rvAP; |
-} |
- |
-NSS_IMPLEMENT NSSAlgorithmAndParameters * |
-NSSAlgorithmAndParameters_CreateMD5Digest ( |
- NSSArena *arenaOpt |
-) |
-{ |
- NSSAlgorithmAndParameters *rvAP = NULL; |
- rvAP = nss_ZNEW(arenaOpt, NSSAlgorithmAndParameters); |
- if (rvAP) { |
- rvAP->mechanism.mechanism = CKM_MD5; |
- rvAP->mechanism.pParameter = NULL; |
- rvAP->mechanism.ulParameterLen = 0; |
- } |
- return rvAP; |
-} |
- |