diff options
Diffstat (limited to 'security/nss/lib/pki/pkibase.c')
-rw-r--r-- | security/nss/lib/pki/pkibase.c | 1264 |
1 files changed, 0 insertions, 1264 deletions
diff --git a/security/nss/lib/pki/pkibase.c b/security/nss/lib/pki/pkibase.c deleted file mode 100644 index db1672395..000000000 --- a/security/nss/lib/pki/pkibase.c +++ /dev/null @@ -1,1264 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; -#endif /* DEBUG */ - -#ifndef DEV_H -#include "dev.h" -#endif /* DEV_H */ - -#ifndef PKIM_H -#include "pkim.h" -#endif /* PKIM_H */ - -#include "pki3hack.h" - -extern const NSSError NSS_ERROR_NOT_FOUND; - -NSS_IMPLEMENT void -nssPKIObject_Lock(nssPKIObject * object) -{ - switch (object->lockType) { - case nssPKIMonitor: - PZ_EnterMonitor(object->sync.mlock); - break; - case nssPKILock: - PZ_Lock(object->sync.lock); - break; - default: - PORT_Assert(0); - } -} - -NSS_IMPLEMENT void -nssPKIObject_Unlock(nssPKIObject * object) -{ - switch (object->lockType) { - case nssPKIMonitor: - PZ_ExitMonitor(object->sync.mlock); - break; - case nssPKILock: - PZ_Unlock(object->sync.lock); - break; - default: - PORT_Assert(0); - } -} - -NSS_IMPLEMENT PRStatus -nssPKIObject_NewLock(nssPKIObject * object, nssPKILockType lockType) -{ - object->lockType = lockType; - switch (lockType) { - case nssPKIMonitor: - object->sync.mlock = PZ_NewMonitor(nssILockSSL); - return (object->sync.mlock ? PR_SUCCESS : PR_FAILURE); - case nssPKILock: - object->sync.lock = PZ_NewLock(nssILockSSL); - return (object->sync.lock ? PR_SUCCESS : PR_FAILURE); - default: - PORT_Assert(0); - return PR_FAILURE; - } -} - -NSS_IMPLEMENT void -nssPKIObject_DestroyLock(nssPKIObject * object) -{ - switch (object->lockType) { - case nssPKIMonitor: - PZ_DestroyMonitor(object->sync.mlock); - object->sync.mlock = NULL; - break; - case nssPKILock: - PZ_DestroyLock(object->sync.lock); - object->sync.lock = NULL; - break; - default: - PORT_Assert(0); - } -} - - - -NSS_IMPLEMENT nssPKIObject * -nssPKIObject_Create ( - NSSArena *arenaOpt, - nssCryptokiObject *instanceOpt, - NSSTrustDomain *td, - NSSCryptoContext *cc, - nssPKILockType lockType -) -{ - NSSArena *arena; - nssArenaMark *mark = NULL; - nssPKIObject *object; - if (arenaOpt) { - arena = arenaOpt; - mark = nssArena_Mark(arena); - } else { - arena = nssArena_Create(); - if (!arena) { - return (nssPKIObject *)NULL; - } - } - object = nss_ZNEW(arena, nssPKIObject); - if (!object) { - goto loser; - } - object->arena = arena; - object->trustDomain = td; /* XXX */ - object->cryptoContext = cc; - if (PR_SUCCESS != nssPKIObject_NewLock(object, lockType)) { - goto loser; - } - if (instanceOpt) { - if (nssPKIObject_AddInstance(object, instanceOpt) != PR_SUCCESS) { - goto loser; - } - } - PR_AtomicIncrement(&object->refCount); - if (mark) { - nssArena_Unmark(arena, mark); - } - return object; -loser: - if (mark) { - nssArena_Release(arena, mark); - } else { - nssArena_Destroy(arena); - } - return (nssPKIObject *)NULL; -} - -NSS_IMPLEMENT PRBool -nssPKIObject_Destroy ( - nssPKIObject *object -) -{ - PRUint32 i; - PR_ASSERT(object->refCount > 0); - if (PR_AtomicDecrement(&object->refCount) == 0) { - for (i=0; i<object->numInstances; i++) { - nssCryptokiObject_Destroy(object->instances[i]); - } - nssPKIObject_DestroyLock(object); - nssArena_Destroy(object->arena); - return PR_TRUE; - } - return PR_FALSE; -} - -NSS_IMPLEMENT nssPKIObject * -nssPKIObject_AddRef ( - nssPKIObject *object -) -{ - PR_AtomicIncrement(&object->refCount); - return object; -} - -NSS_IMPLEMENT PRStatus -nssPKIObject_AddInstance ( - nssPKIObject *object, - nssCryptokiObject *instance -) -{ - nssPKIObject_Lock(object); - if (object->numInstances == 0) { - object->instances = nss_ZNEWARRAY(object->arena, - nssCryptokiObject *, - object->numInstances + 1); - } else { - PRUint32 i; - for (i=0; i<object->numInstances; i++) { - if (nssCryptokiObject_Equal(object->instances[i], instance)) { - nssPKIObject_Unlock(object); - if (instance->label) { - if (!object->instances[i]->label || - !nssUTF8_Equal(instance->label, - object->instances[i]->label, NULL)) - { - /* Either the old instance did not have a label, - * or the label has changed. - */ - nss_ZFreeIf(object->instances[i]->label); - object->instances[i]->label = instance->label; - instance->label = NULL; - } - } else if (object->instances[i]->label) { - /* The old label was removed */ - nss_ZFreeIf(object->instances[i]->label); - object->instances[i]->label = NULL; - } - nssCryptokiObject_Destroy(instance); - return PR_SUCCESS; - } - } - object->instances = nss_ZREALLOCARRAY(object->instances, - nssCryptokiObject *, - object->numInstances + 1); - } - if (!object->instances) { - nssPKIObject_Unlock(object); - return PR_FAILURE; - } - object->instances[object->numInstances++] = instance; - nssPKIObject_Unlock(object); - return PR_SUCCESS; -} - -NSS_IMPLEMENT PRBool -nssPKIObject_HasInstance ( - nssPKIObject *object, - nssCryptokiObject *instance -) -{ - PRUint32 i; - PRBool hasIt = PR_FALSE;; - nssPKIObject_Lock(object); - for (i=0; i<object->numInstances; i++) { - if (nssCryptokiObject_Equal(object->instances[i], instance)) { - hasIt = PR_TRUE; - break; - } - } - nssPKIObject_Unlock(object); - return hasIt; -} - -NSS_IMPLEMENT PRStatus -nssPKIObject_RemoveInstanceForToken ( - nssPKIObject *object, - NSSToken *token -) -{ - PRUint32 i; - nssCryptokiObject *instanceToRemove = NULL; - nssPKIObject_Lock(object); - if (object->numInstances == 0) { - nssPKIObject_Unlock(object); - return PR_SUCCESS; - } - for (i=0; i<object->numInstances; i++) { - if (object->instances[i]->token == token) { - instanceToRemove = object->instances[i]; - object->instances[i] = object->instances[object->numInstances-1]; - object->instances[object->numInstances-1] = NULL; - break; - } - } - if (--object->numInstances > 0) { - nssCryptokiObject **instances = nss_ZREALLOCARRAY(object->instances, - nssCryptokiObject *, - object->numInstances); - if (instances) { - object->instances = instances; - } - } else { - nss_ZFreeIf(object->instances); - } - nssCryptokiObject_Destroy(instanceToRemove); - nssPKIObject_Unlock(object); - return PR_SUCCESS; -} - -/* this needs more thought on what will happen when there are multiple - * instances - */ -NSS_IMPLEMENT PRStatus -nssPKIObject_DeleteStoredObject ( - nssPKIObject *object, - NSSCallback *uhh, - PRBool isFriendly -) -{ - PRUint32 i, numNotDestroyed; - PRStatus status = PR_SUCCESS; - numNotDestroyed = 0; - nssPKIObject_Lock(object); - for (i=0; i<object->numInstances; i++) { - nssCryptokiObject *instance = object->instances[i]; - status = nssToken_DeleteStoredObject(instance); - object->instances[i] = NULL; - if (status == PR_SUCCESS) { - nssCryptokiObject_Destroy(instance); - } else { - object->instances[numNotDestroyed++] = instance; - } - } - if (numNotDestroyed == 0) { - nss_ZFreeIf(object->instances); - object->numInstances = 0; - } else { - object->numInstances = numNotDestroyed; - } - nssPKIObject_Unlock(object); - return status; -} - -NSS_IMPLEMENT NSSToken ** -nssPKIObject_GetTokens ( - nssPKIObject *object, - PRStatus *statusOpt -) -{ - NSSToken **tokens = NULL; - nssPKIObject_Lock(object); - if (object->numInstances > 0) { - tokens = nss_ZNEWARRAY(NULL, NSSToken *, object->numInstances + 1); - if (tokens) { - PRUint32 i; - for (i=0; i<object->numInstances; i++) { - tokens[i] = nssToken_AddRef(object->instances[i]->token); - } - } - } - nssPKIObject_Unlock(object); - if (statusOpt) *statusOpt = PR_SUCCESS; /* until more logic here */ - return tokens; -} - -NSS_IMPLEMENT NSSUTF8 * -nssPKIObject_GetNicknameForToken ( - nssPKIObject *object, - NSSToken *tokenOpt -) -{ - PRUint32 i; - NSSUTF8 *nickname = NULL; - nssPKIObject_Lock(object); - for (i=0; i<object->numInstances; i++) { - if ((!tokenOpt && object->instances[i]->label) || - (object->instances[i]->token == tokenOpt)) - { - /* XXX should be copy? safe as long as caller has reference */ - nickname = object->instances[i]->label; - break; - } - } - nssPKIObject_Unlock(object); - return nickname; -} - -NSS_IMPLEMENT nssCryptokiObject ** -nssPKIObject_GetInstances ( - nssPKIObject *object -) -{ - nssCryptokiObject **instances = NULL; - PRUint32 i; - if (object->numInstances == 0) { - return (nssCryptokiObject **)NULL; - } - nssPKIObject_Lock(object); - instances = nss_ZNEWARRAY(NULL, nssCryptokiObject *, - object->numInstances + 1); - if (instances) { - for (i=0; i<object->numInstances; i++) { - instances[i] = nssCryptokiObject_Clone(object->instances[i]); - } - } - nssPKIObject_Unlock(object); - return instances; -} - -NSS_IMPLEMENT void -nssCertificateArray_Destroy ( - NSSCertificate **certs -) -{ - if (certs) { - NSSCertificate **certp; - for (certp = certs; *certp; certp++) { - if ((*certp)->decoding) { - CERTCertificate *cc = STAN_GetCERTCertificate(*certp); - if (cc) { - CERT_DestroyCertificate(cc); - } - continue; - } - nssCertificate_Destroy(*certp); - } - nss_ZFreeIf(certs); - } -} - -NSS_IMPLEMENT void -NSSCertificateArray_Destroy ( - NSSCertificate **certs -) -{ - nssCertificateArray_Destroy(certs); -} - -NSS_IMPLEMENT NSSCertificate ** -nssCertificateArray_Join ( - NSSCertificate **certs1, - NSSCertificate **certs2 -) -{ - if (certs1 && certs2) { - NSSCertificate **certs, **cp; - PRUint32 count = 0; - PRUint32 count1 = 0; - cp = certs1; - while (*cp++) count1++; - count = count1; - cp = certs2; - while (*cp++) count++; - certs = nss_ZREALLOCARRAY(certs1, NSSCertificate *, count + 1); - if (!certs) { - nss_ZFreeIf(certs1); - nss_ZFreeIf(certs2); - return (NSSCertificate **)NULL; - } - for (cp = certs2; *cp; cp++, count1++) { - certs[count1] = *cp; - } - nss_ZFreeIf(certs2); - return certs; - } else if (certs1) { - return certs1; - } else { - return certs2; - } -} - -NSS_IMPLEMENT NSSCertificate * -nssCertificateArray_FindBestCertificate ( - NSSCertificate **certs, - NSSTime *timeOpt, - const NSSUsage *usage, - NSSPolicies *policiesOpt -) -{ - NSSCertificate *bestCert = NULL; - NSSTime *time, sTime; - PRBool haveUsageMatch = PR_FALSE; - PRBool thisCertMatches; - - if (timeOpt) { - time = timeOpt; - } else { - NSSTime_Now(&sTime); - time = &sTime; - } - if (!certs) { - return (NSSCertificate *)NULL; - } - for (; *certs; certs++) { - nssDecodedCert *dc, *bestdc; - NSSCertificate *c = *certs; - dc = nssCertificate_GetDecoding(c); - if (!dc) continue; - thisCertMatches = dc->matchUsage(dc, usage); - if (!bestCert) { - /* always take the first cert, but remember whether or not - * the usage matched - */ - bestCert = nssCertificate_AddRef(c); - haveUsageMatch = thisCertMatches; - continue; - } else { - if (haveUsageMatch && !thisCertMatches) { - /* if already have a cert for this usage, and if this cert - * doesn't have the correct usage, continue - */ - continue; - } else if (!haveUsageMatch && thisCertMatches) { - /* this one does match usage, replace the other */ - nssCertificate_Destroy(bestCert); - bestCert = nssCertificate_AddRef(c); - haveUsageMatch = PR_TRUE; - continue; - } - /* this cert match as well as any cert we've found so far, - * defer to time/policies - * */ - } - bestdc = nssCertificate_GetDecoding(bestCert); - /* time */ - if (bestdc->isValidAtTime(bestdc, time)) { - /* The current best cert is valid at time */ - if (!dc->isValidAtTime(dc, time)) { - /* If the new cert isn't valid at time, it's not better */ - continue; - } - } else { - /* The current best cert is not valid at time */ - if (dc->isValidAtTime(dc, time)) { - /* If the new cert is valid at time, it's better */ - nssCertificate_Destroy(bestCert); - bestCert = nssCertificate_AddRef(c); - } - } - /* either they are both valid at time, or neither valid; - * take the newer one - */ - if (!bestdc->isNewerThan(bestdc, dc)) { - nssCertificate_Destroy(bestCert); - bestCert = nssCertificate_AddRef(c); - } - /* policies */ - /* XXX later -- defer to policies */ - } - return bestCert; -} - -NSS_IMPLEMENT PRStatus -nssCertificateArray_Traverse ( - NSSCertificate **certs, - PRStatus (* callback)(NSSCertificate *c, void *arg), - void *arg -) -{ - PRStatus status = PR_SUCCESS; - if (certs) { - NSSCertificate **certp; - for (certp = certs; *certp; certp++) { - status = (*callback)(*certp, arg); - if (status != PR_SUCCESS) { - break; - } - } - } - return status; -} - - -NSS_IMPLEMENT void -nssCRLArray_Destroy ( - NSSCRL **crls -) -{ - if (crls) { - NSSCRL **crlp; - for (crlp = crls; *crlp; crlp++) { - nssCRL_Destroy(*crlp); - } - nss_ZFreeIf(crls); - } -} - -/* - * Object collections - */ - -typedef enum -{ - pkiObjectType_Certificate = 0, - pkiObjectType_CRL = 1, - pkiObjectType_PrivateKey = 2, - pkiObjectType_PublicKey = 3 -} pkiObjectType; - -/* Each object is defined by a set of items that uniquely identify it. - * Here are the uid sets: - * - * NSSCertificate ==> { issuer, serial } - * NSSPrivateKey - * (RSA) ==> { modulus, public exponent } - * - */ -#define MAX_ITEMS_FOR_UID 2 - -/* pkiObjectCollectionNode - * - * A node in the collection is the set of unique identifiers for a single - * object, along with either the actual object or a proto-object. - */ -typedef struct -{ - PRCList link; - PRBool haveObject; - nssPKIObject *object; - NSSItem uid[MAX_ITEMS_FOR_UID]; -} -pkiObjectCollectionNode; - -/* nssPKIObjectCollection - * - * The collection is the set of all objects, plus the interfaces needed - * to manage the objects. - * - */ -struct nssPKIObjectCollectionStr -{ - NSSArena *arena; - NSSTrustDomain *td; - NSSCryptoContext *cc; - PRCList head; /* list of pkiObjectCollectionNode's */ - PRUint32 size; - pkiObjectType objectType; - void (* destroyObject)(nssPKIObject *o); - PRStatus (* getUIDFromObject)(nssPKIObject *o, NSSItem *uid); - PRStatus (* getUIDFromInstance)(nssCryptokiObject *co, NSSItem *uid, - NSSArena *arena); - nssPKIObject * (* createObject)(nssPKIObject *o); - nssPKILockType lockType; /* type of lock to use for new proto-objects */ -}; - -static nssPKIObjectCollection * -nssPKIObjectCollection_Create ( - NSSTrustDomain *td, - NSSCryptoContext *ccOpt, - nssPKILockType lockType -) -{ - NSSArena *arena; - nssPKIObjectCollection *rvCollection = NULL; - arena = nssArena_Create(); - if (!arena) { - return (nssPKIObjectCollection *)NULL; - } - rvCollection = nss_ZNEW(arena, nssPKIObjectCollection); - if (!rvCollection) { - goto loser; - } - PR_INIT_CLIST(&rvCollection->head); - rvCollection->arena = arena; - rvCollection->td = td; /* XXX */ - rvCollection->cc = ccOpt; - rvCollection->lockType = lockType; - return rvCollection; -loser: - nssArena_Destroy(arena); - return (nssPKIObjectCollection *)NULL; -} - -NSS_IMPLEMENT void -nssPKIObjectCollection_Destroy ( - nssPKIObjectCollection *collection -) -{ - if (collection) { - PRCList *link; - pkiObjectCollectionNode *node; - /* first destroy any objects in the collection */ - link = PR_NEXT_LINK(&collection->head); - while (link != &collection->head) { - node = (pkiObjectCollectionNode *)link; - if (node->haveObject) { - (*collection->destroyObject)(node->object); - } else { - nssPKIObject_Destroy(node->object); - } - link = PR_NEXT_LINK(link); - } - /* then destroy it */ - nssArena_Destroy(collection->arena); - } -} - -NSS_IMPLEMENT PRUint32 -nssPKIObjectCollection_Count ( - nssPKIObjectCollection *collection -) -{ - return collection->size; -} - -NSS_IMPLEMENT PRStatus -nssPKIObjectCollection_AddObject ( - nssPKIObjectCollection *collection, - nssPKIObject *object -) -{ - pkiObjectCollectionNode *node; - node = nss_ZNEW(collection->arena, pkiObjectCollectionNode); - if (!node) { - return PR_FAILURE; - } - node->haveObject = PR_TRUE; - node->object = nssPKIObject_AddRef(object); - (*collection->getUIDFromObject)(object, node->uid); - PR_INIT_CLIST(&node->link); - PR_INSERT_BEFORE(&node->link, &collection->head); - collection->size++; - return PR_SUCCESS; -} - -static pkiObjectCollectionNode * -find_instance_in_collection ( - nssPKIObjectCollection *collection, - nssCryptokiObject *instance -) -{ - PRCList *link; - pkiObjectCollectionNode *node; - link = PR_NEXT_LINK(&collection->head); - while (link != &collection->head) { - node = (pkiObjectCollectionNode *)link; - if (nssPKIObject_HasInstance(node->object, instance)) { - return node; - } - link = PR_NEXT_LINK(link); - } - return (pkiObjectCollectionNode *)NULL; -} - -static pkiObjectCollectionNode * -find_object_in_collection ( - nssPKIObjectCollection *collection, - NSSItem *uid -) -{ - PRUint32 i; - PRStatus status; - PRCList *link; - pkiObjectCollectionNode *node; - link = PR_NEXT_LINK(&collection->head); - while (link != &collection->head) { - node = (pkiObjectCollectionNode *)link; - for (i=0; i<MAX_ITEMS_FOR_UID; i++) { - if (!nssItem_Equal(&node->uid[i], &uid[i], &status)) { - break; - } - } - if (i == MAX_ITEMS_FOR_UID) { - return node; - } - link = PR_NEXT_LINK(link); - } - return (pkiObjectCollectionNode *)NULL; -} - -static pkiObjectCollectionNode * -add_object_instance ( - nssPKIObjectCollection *collection, - nssCryptokiObject *instance, - PRBool *foundIt -) -{ - PRUint32 i; - PRStatus status; - pkiObjectCollectionNode *node; - nssArenaMark *mark = NULL; - NSSItem uid[MAX_ITEMS_FOR_UID]; - nsslibc_memset(uid, 0, sizeof uid); - /* The list is traversed twice, first (here) looking to match the - * { token, handle } tuple, and if that is not found, below a search - * for unique identifier is done. Here, a match means this exact object - * instance is already in the collection, and we have nothing to do. - */ - *foundIt = PR_FALSE; - node = find_instance_in_collection(collection, instance); - if (node) { - /* The collection is assumed to take over the instance. Since we - * are not using it, it must be destroyed. - */ - nssCryptokiObject_Destroy(instance); - *foundIt = PR_TRUE; - return node; - } - mark = nssArena_Mark(collection->arena); - if (!mark) { - goto loser; - } - status = (*collection->getUIDFromInstance)(instance, uid, - collection->arena); - if (status != PR_SUCCESS) { - goto loser; - } - /* Search for unique identifier. A match here means the object exists - * in the collection, but does not have this instance, so the instance - * needs to be added. - */ - node = find_object_in_collection(collection, uid); - if (node) { - /* This is an object with multiple instances */ - status = nssPKIObject_AddInstance(node->object, instance); - } else { - /* This is a completely new object. Create a node for it. */ - node = nss_ZNEW(collection->arena, pkiObjectCollectionNode); - if (!node) { - goto loser; - } - node->object = nssPKIObject_Create(NULL, instance, - collection->td, collection->cc, - collection->lockType); - if (!node->object) { - goto loser; - } - for (i=0; i<MAX_ITEMS_FOR_UID; i++) { - node->uid[i] = uid[i]; - } - node->haveObject = PR_FALSE; - PR_INIT_CLIST(&node->link); - PR_INSERT_BEFORE(&node->link, &collection->head); - collection->size++; - status = PR_SUCCESS; - } - nssArena_Unmark(collection->arena, mark); - return node; -loser: - if (mark) { - nssArena_Release(collection->arena, mark); - } - nssCryptokiObject_Destroy(instance); - return (pkiObjectCollectionNode *)NULL; -} - -NSS_IMPLEMENT PRStatus -nssPKIObjectCollection_AddInstances ( - nssPKIObjectCollection *collection, - nssCryptokiObject **instances, - PRUint32 numInstances -) -{ - PRStatus status = PR_SUCCESS; - PRUint32 i = 0; - PRBool foundIt; - pkiObjectCollectionNode *node; - if (instances) { - while ((!numInstances || i < numInstances) && *instances) { - if (status == PR_SUCCESS) { - node = add_object_instance(collection, *instances, &foundIt); - if (node == NULL) { - /* add_object_instance freed the current instance */ - /* free the remaining instances */ - status = PR_FAILURE; - } - } else { - nssCryptokiObject_Destroy(*instances); - } - instances++; - i++; - } - } - return status; -} - -static void -nssPKIObjectCollection_RemoveNode ( - nssPKIObjectCollection *collection, - pkiObjectCollectionNode *node -) -{ - PR_REMOVE_LINK(&node->link); - collection->size--; -} - -static PRStatus -nssPKIObjectCollection_GetObjects ( - nssPKIObjectCollection *collection, - nssPKIObject **rvObjects, - PRUint32 rvSize -) -{ - PRUint32 i = 0; - PRCList *link = PR_NEXT_LINK(&collection->head); - pkiObjectCollectionNode *node; - int error=0; - while ((i < rvSize) && (link != &collection->head)) { - node = (pkiObjectCollectionNode *)link; - if (!node->haveObject) { - /* Convert the proto-object to an object */ - node->object = (*collection->createObject)(node->object); - if (!node->object) { - link = PR_NEXT_LINK(link); - /*remove bogus object from list*/ - nssPKIObjectCollection_RemoveNode(collection,node); - error++; - continue; - } - node->haveObject = PR_TRUE; - } - rvObjects[i++] = nssPKIObject_AddRef(node->object); - link = PR_NEXT_LINK(link); - } - if (!error && *rvObjects == NULL) { - nss_SetError(NSS_ERROR_NOT_FOUND); - } - return PR_SUCCESS; -} - -NSS_IMPLEMENT PRStatus -nssPKIObjectCollection_Traverse ( - nssPKIObjectCollection *collection, - nssPKIObjectCallback *callback -) -{ - PRStatus status; - PRCList *link = PR_NEXT_LINK(&collection->head); - pkiObjectCollectionNode *node; - while (link != &collection->head) { - node = (pkiObjectCollectionNode *)link; - if (!node->haveObject) { - node->object = (*collection->createObject)(node->object); - if (!node->object) { - link = PR_NEXT_LINK(link); - /*remove bogus object from list*/ - nssPKIObjectCollection_RemoveNode(collection,node); - continue; - } - node->haveObject = PR_TRUE; - } - switch (collection->objectType) { - case pkiObjectType_Certificate: - status = (*callback->func.cert)((NSSCertificate *)node->object, - callback->arg); - break; - case pkiObjectType_CRL: - status = (*callback->func.crl)((NSSCRL *)node->object, - callback->arg); - break; - case pkiObjectType_PrivateKey: - status = (*callback->func.pvkey)((NSSPrivateKey *)node->object, - callback->arg); - break; - case pkiObjectType_PublicKey: - status = (*callback->func.pbkey)((NSSPublicKey *)node->object, - callback->arg); - break; - } - link = PR_NEXT_LINK(link); - } - return PR_SUCCESS; -} - -NSS_IMPLEMENT PRStatus -nssPKIObjectCollection_AddInstanceAsObject ( - nssPKIObjectCollection *collection, - nssCryptokiObject *instance -) -{ - pkiObjectCollectionNode *node; - PRBool foundIt; - node = add_object_instance(collection, instance, &foundIt); - if (node == NULL) { - return PR_FAILURE; - } - if (!node->haveObject) { - node->object = (*collection->createObject)(node->object); - if (!node->object) { - /*remove bogus object from list*/ - nssPKIObjectCollection_RemoveNode(collection,node); - return PR_FAILURE; - } - node->haveObject = PR_TRUE; - } else if (!foundIt) { - /* The instance was added to a pre-existing node. This - * function is *only* being used for certificates, and having - * multiple instances of certs in 3.X requires updating the - * CERTCertificate. - * But only do it if it was a new instance!!! If the same instance - * is encountered, we set *foundIt to true. Detect that here and - * ignore it. - */ - STAN_ForceCERTCertificateUpdate((NSSCertificate *)node->object); - } - return PR_SUCCESS; -} - -/* - * Certificate collections - */ - -static void -cert_destroyObject(nssPKIObject *o) -{ - NSSCertificate *c = (NSSCertificate *)o; - if (c->decoding) { - CERTCertificate *cc = STAN_GetCERTCertificate(c); - if (cc) { - CERT_DestroyCertificate(cc); - return; - } /* else destroy it as NSSCertificate below */ - } - nssCertificate_Destroy(c); -} - -static PRStatus -cert_getUIDFromObject(nssPKIObject *o, NSSItem *uid) -{ - NSSCertificate *c = (NSSCertificate *)o; - /* The builtins are still returning decoded serial numbers. Until - * this compatibility issue is resolved, use the full DER of the - * cert to uniquely identify it. - */ - NSSDER *derCert; - derCert = nssCertificate_GetEncoding(c); - uid[0].data = NULL; uid[0].size = 0; - uid[1].data = NULL; uid[1].size = 0; - if (derCert != NULL) { - uid[0] = *derCert; - } - return PR_SUCCESS; -} - -static PRStatus -cert_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid, - NSSArena *arena) -{ - /* The builtins are still returning decoded serial numbers. Until - * this compatibility issue is resolved, use the full DER of the - * cert to uniquely identify it. - */ - uid[1].data = NULL; uid[1].size = 0; - return nssCryptokiCertificate_GetAttributes(instance, - NULL, /* XXX sessionOpt */ - arena, /* arena */ - NULL, /* type */ - NULL, /* id */ - &uid[0], /* encoding */ - NULL, /* issuer */ - NULL, /* serial */ - NULL); /* subject */ -} - -static nssPKIObject * -cert_createObject(nssPKIObject *o) -{ - NSSCertificate *cert; - cert = nssCertificate_Create(o); -/* if (STAN_GetCERTCertificate(cert) == NULL) { - nssCertificate_Destroy(cert); - return (nssPKIObject *)NULL; - } */ - /* In 3.4, have to maintain uniqueness of cert pointers by caching all - * certs. Cache the cert here, before returning. If it is already - * cached, take the cached entry. - */ - { - NSSTrustDomain *td = o->trustDomain; - nssTrustDomain_AddCertsToCache(td, &cert, 1); - } - return (nssPKIObject *)cert; -} - -NSS_IMPLEMENT nssPKIObjectCollection * -nssCertificateCollection_Create ( - NSSTrustDomain *td, - NSSCertificate **certsOpt -) -{ - PRStatus status; - nssPKIObjectCollection *collection; - collection = nssPKIObjectCollection_Create(td, NULL, nssPKIMonitor); - collection->objectType = pkiObjectType_Certificate; - collection->destroyObject = cert_destroyObject; - collection->getUIDFromObject = cert_getUIDFromObject; - collection->getUIDFromInstance = cert_getUIDFromInstance; - collection->createObject = cert_createObject; - if (certsOpt) { - for (; *certsOpt; certsOpt++) { - nssPKIObject *object = (nssPKIObject *)(*certsOpt); - status = nssPKIObjectCollection_AddObject(collection, object); - } - } - return collection; -} - -NSS_IMPLEMENT NSSCertificate ** -nssPKIObjectCollection_GetCertificates ( - nssPKIObjectCollection *collection, - NSSCertificate **rvOpt, - PRUint32 maximumOpt, - NSSArena *arenaOpt -) -{ - PRStatus status; - PRUint32 rvSize; - PRBool allocated = PR_FALSE; - if (collection->size == 0) { - return (NSSCertificate **)NULL; - } - if (maximumOpt == 0) { - rvSize = collection->size; - } else { - rvSize = PR_MIN(collection->size, maximumOpt); - } - if (!rvOpt) { - rvOpt = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, rvSize + 1); - if (!rvOpt) { - return (NSSCertificate **)NULL; - } - allocated = PR_TRUE; - } - status = nssPKIObjectCollection_GetObjects(collection, - (nssPKIObject **)rvOpt, - rvSize); - if (status != PR_SUCCESS) { - if (allocated) { - nss_ZFreeIf(rvOpt); - } - return (NSSCertificate **)NULL; - } - return rvOpt; -} - -/* - * CRL/KRL collections - */ - -static void -crl_destroyObject(nssPKIObject *o) -{ - NSSCRL *crl = (NSSCRL *)o; - nssCRL_Destroy(crl); -} - -static PRStatus -crl_getUIDFromObject(nssPKIObject *o, NSSItem *uid) -{ - NSSCRL *crl = (NSSCRL *)o; - NSSDER *encoding; - encoding = nssCRL_GetEncoding(crl); - if (!encoding) { - nss_SetError(NSS_ERROR_INVALID_ARGUMENT); - return PR_FALSE; - } - uid[0] = *encoding; - uid[1].data = NULL; uid[1].size = 0; - return PR_SUCCESS; -} - -static PRStatus -crl_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid, - NSSArena *arena) -{ - return nssCryptokiCRL_GetAttributes(instance, - NULL, /* XXX sessionOpt */ - arena, /* arena */ - &uid[0], /* encoding */ - NULL, /* subject */ - NULL, /* class */ - NULL, /* url */ - NULL); /* isKRL */ -} - -static nssPKIObject * -crl_createObject(nssPKIObject *o) -{ - return (nssPKIObject *)nssCRL_Create(o); -} - -NSS_IMPLEMENT nssPKIObjectCollection * -nssCRLCollection_Create ( - NSSTrustDomain *td, - NSSCRL **crlsOpt -) -{ - PRStatus status; - nssPKIObjectCollection *collection; - collection = nssPKIObjectCollection_Create(td, NULL, nssPKILock); - collection->objectType = pkiObjectType_CRL; - collection->destroyObject = crl_destroyObject; - collection->getUIDFromObject = crl_getUIDFromObject; - collection->getUIDFromInstance = crl_getUIDFromInstance; - collection->createObject = crl_createObject; - if (crlsOpt) { - for (; *crlsOpt; crlsOpt++) { - nssPKIObject *object = (nssPKIObject *)(*crlsOpt); - status = nssPKIObjectCollection_AddObject(collection, object); - } - } - return collection; -} - -NSS_IMPLEMENT NSSCRL ** -nssPKIObjectCollection_GetCRLs ( - nssPKIObjectCollection *collection, - NSSCRL **rvOpt, - PRUint32 maximumOpt, - NSSArena *arenaOpt -) -{ - PRStatus status; - PRUint32 rvSize; - PRBool allocated = PR_FALSE; - if (collection->size == 0) { - return (NSSCRL **)NULL; - } - if (maximumOpt == 0) { - rvSize = collection->size; - } else { - rvSize = PR_MIN(collection->size, maximumOpt); - } - if (!rvOpt) { - rvOpt = nss_ZNEWARRAY(arenaOpt, NSSCRL *, rvSize + 1); - if (!rvOpt) { - return (NSSCRL **)NULL; - } - allocated = PR_TRUE; - } - status = nssPKIObjectCollection_GetObjects(collection, - (nssPKIObject **)rvOpt, - rvSize); - if (status != PR_SUCCESS) { - if (allocated) { - nss_ZFreeIf(rvOpt); - } - return (NSSCRL **)NULL; - } - return rvOpt; -} - -/* how bad would it be to have a static now sitting around, updated whenever - * this was called? would avoid repeated allocs... - */ -NSS_IMPLEMENT NSSTime * -NSSTime_Now ( - NSSTime *timeOpt -) -{ - return NSSTime_SetPRTime(timeOpt, PR_Now()); -} - -NSS_IMPLEMENT NSSTime * -NSSTime_SetPRTime ( - NSSTime *timeOpt, - PRTime prTime -) -{ - NSSTime *rvTime; - rvTime = (timeOpt) ? timeOpt : nss_ZNEW(NULL, NSSTime); - rvTime->prTime = prTime; - return rvTime; -} - -NSS_IMPLEMENT PRTime -NSSTime_GetPRTime ( - NSSTime *time -) -{ - return time->prTime; -} - |