| Index: nss/lib/pki/pkistore.c
|
| diff --git a/nss/lib/pki/pkistore.c b/nss/lib/pki/pkistore.c
|
| deleted file mode 100644
|
| index 15bb6586506aee8d39bf1e8365ffdb1280093625..0000000000000000000000000000000000000000
|
| --- a/nss/lib/pki/pkistore.c
|
| +++ /dev/null
|
| @@ -1,713 +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/. */
|
| -
|
| -#ifndef PKIM_H
|
| -#include "pkim.h"
|
| -#endif /* PKIM_H */
|
| -
|
| -#ifndef PKI_H
|
| -#include "pki.h"
|
| -#endif /* PKI_H */
|
| -
|
| -#ifndef NSSPKI_H
|
| -#include "nsspki.h"
|
| -#endif /* NSSPKI_H */
|
| -
|
| -#ifndef BASE_H
|
| -#include "base.h"
|
| -#endif /* BASE_H */
|
| -
|
| -#ifndef PKISTORE_H
|
| -#include "pkistore.h"
|
| -#endif /* PKISTORE_H */
|
| -
|
| -#include "cert.h"
|
| -#include "pki3hack.h"
|
| -
|
| -#include "prbit.h"
|
| -
|
| -/*
|
| - * Certificate Store
|
| - *
|
| - * This differs from the cache in that it is a true storage facility. Items
|
| - * stay in until they are explicitly removed. It is only used by crypto
|
| - * contexts at this time, but may be more generally useful...
|
| - *
|
| - */
|
| -
|
| -struct nssCertificateStoreStr
|
| -{
|
| - PRBool i_alloced_arena;
|
| - NSSArena *arena;
|
| - PZLock *lock;
|
| - nssHash *subject;
|
| - nssHash *issuer_and_serial;
|
| -};
|
| -
|
| -typedef struct certificate_hash_entry_str certificate_hash_entry;
|
| -
|
| -struct certificate_hash_entry_str
|
| -{
|
| - NSSCertificate *cert;
|
| - NSSTrust *trust;
|
| - nssSMIMEProfile *profile;
|
| -};
|
| -
|
| -/* forward static declarations */
|
| -static NSSCertificate *
|
| -nssCertStore_FindCertByIssuerAndSerialNumberLocked (
|
| - nssCertificateStore *store,
|
| - NSSDER *issuer,
|
| - NSSDER *serial
|
| -);
|
| -
|
| -NSS_IMPLEMENT nssCertificateStore *
|
| -nssCertificateStore_Create (
|
| - NSSArena *arenaOpt
|
| -)
|
| -{
|
| - NSSArena *arena;
|
| - nssCertificateStore *store;
|
| - PRBool i_alloced_arena;
|
| - if (arenaOpt) {
|
| - arena = arenaOpt;
|
| - i_alloced_arena = PR_FALSE;
|
| - } else {
|
| - arena = nssArena_Create();
|
| - if (!arena) {
|
| - return NULL;
|
| - }
|
| - i_alloced_arena = PR_TRUE;
|
| - }
|
| - store = nss_ZNEW(arena, nssCertificateStore);
|
| - if (!store) {
|
| - goto loser;
|
| - }
|
| - store->lock = PZ_NewLock(nssILockOther);
|
| - if (!store->lock) {
|
| - goto loser;
|
| - }
|
| - /* Create the issuer/serial --> {cert, trust, S/MIME profile } hash */
|
| - store->issuer_and_serial = nssHash_CreateCertificate(arena, 0);
|
| - if (!store->issuer_and_serial) {
|
| - goto loser;
|
| - }
|
| - /* Create the subject DER --> subject list hash */
|
| - store->subject = nssHash_CreateItem(arena, 0);
|
| - if (!store->subject) {
|
| - goto loser;
|
| - }
|
| - store->arena = arena;
|
| - store->i_alloced_arena = i_alloced_arena;
|
| - return store;
|
| -loser:
|
| - if (store) {
|
| - if (store->lock) {
|
| - PZ_DestroyLock(store->lock);
|
| - }
|
| - if (store->issuer_and_serial) {
|
| - nssHash_Destroy(store->issuer_and_serial);
|
| - }
|
| - if (store->subject) {
|
| - nssHash_Destroy(store->subject);
|
| - }
|
| - }
|
| - if (i_alloced_arena) {
|
| - nssArena_Destroy(arena);
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| -extern const NSSError NSS_ERROR_BUSY;
|
| -
|
| -NSS_IMPLEMENT PRStatus
|
| -nssCertificateStore_Destroy (
|
| - nssCertificateStore *store
|
| -)
|
| -{
|
| - if (nssHash_Count(store->issuer_and_serial) > 0) {
|
| - nss_SetError(NSS_ERROR_BUSY);
|
| - return PR_FAILURE;
|
| - }
|
| - PZ_DestroyLock(store->lock);
|
| - nssHash_Destroy(store->issuer_and_serial);
|
| - nssHash_Destroy(store->subject);
|
| - if (store->i_alloced_arena) {
|
| - nssArena_Destroy(store->arena);
|
| - } else {
|
| - nss_ZFreeIf(store);
|
| - }
|
| - return PR_SUCCESS;
|
| -}
|
| -
|
| -static PRStatus
|
| -add_certificate_entry (
|
| - nssCertificateStore *store,
|
| - NSSCertificate *cert
|
| -)
|
| -{
|
| - PRStatus nssrv;
|
| - certificate_hash_entry *entry;
|
| - entry = nss_ZNEW(cert->object.arena, certificate_hash_entry);
|
| - if (!entry) {
|
| - return PR_FAILURE;
|
| - }
|
| - entry->cert = cert;
|
| - nssrv = nssHash_Add(store->issuer_and_serial, cert, entry);
|
| - if (nssrv != PR_SUCCESS) {
|
| - nss_ZFreeIf(entry);
|
| - }
|
| - return nssrv;
|
| -}
|
| -
|
| -static PRStatus
|
| -add_subject_entry (
|
| - nssCertificateStore *store,
|
| - NSSCertificate *cert
|
| -)
|
| -{
|
| - PRStatus nssrv;
|
| - nssList *subjectList;
|
| - subjectList = (nssList *)nssHash_Lookup(store->subject, &cert->subject);
|
| - if (subjectList) {
|
| - /* The subject is already in, add this cert to the list */
|
| - nssrv = nssList_AddUnique(subjectList, cert);
|
| - } else {
|
| - /* Create a new subject list for the subject */
|
| - subjectList = nssList_Create(NULL, PR_FALSE);
|
| - if (!subjectList) {
|
| - return PR_FAILURE;
|
| - }
|
| - nssList_SetSortFunction(subjectList, nssCertificate_SubjectListSort);
|
| - /* Add the cert entry to this list of subjects */
|
| - nssrv = nssList_Add(subjectList, cert);
|
| - if (nssrv != PR_SUCCESS) {
|
| - return nssrv;
|
| - }
|
| - /* Add the subject list to the cache */
|
| - nssrv = nssHash_Add(store->subject, &cert->subject, subjectList);
|
| - }
|
| - return nssrv;
|
| -}
|
| -
|
| -/* declared below */
|
| -static void
|
| -remove_certificate_entry (
|
| - nssCertificateStore *store,
|
| - NSSCertificate *cert
|
| -);
|
| -
|
| -/* Caller must hold store->lock */
|
| -static PRStatus
|
| -nssCertificateStore_AddLocked (
|
| - nssCertificateStore *store,
|
| - NSSCertificate *cert
|
| -)
|
| -{
|
| - PRStatus nssrv = add_certificate_entry(store, cert);
|
| - if (nssrv == PR_SUCCESS) {
|
| - nssrv = add_subject_entry(store, cert);
|
| - if (nssrv == PR_FAILURE) {
|
| - remove_certificate_entry(store, cert);
|
| - }
|
| - }
|
| - return nssrv;
|
| -}
|
| -
|
| -
|
| -NSS_IMPLEMENT NSSCertificate *
|
| -nssCertificateStore_FindOrAdd (
|
| - nssCertificateStore *store,
|
| - NSSCertificate *c
|
| -)
|
| -{
|
| - PRStatus nssrv;
|
| - NSSCertificate *rvCert = NULL;
|
| -
|
| - PZ_Lock(store->lock);
|
| - rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked(
|
| - store, &c->issuer, &c->serial);
|
| - if (!rvCert) {
|
| - nssrv = nssCertificateStore_AddLocked(store, c);
|
| - if (PR_SUCCESS == nssrv) {
|
| - rvCert = nssCertificate_AddRef(c);
|
| - }
|
| - }
|
| - PZ_Unlock(store->lock);
|
| - return rvCert;
|
| -}
|
| -
|
| -static void
|
| -remove_certificate_entry (
|
| - nssCertificateStore *store,
|
| - NSSCertificate *cert
|
| -)
|
| -{
|
| - certificate_hash_entry *entry;
|
| - entry = (certificate_hash_entry *)
|
| - nssHash_Lookup(store->issuer_and_serial, cert);
|
| - if (entry) {
|
| - nssHash_Remove(store->issuer_and_serial, cert);
|
| - if (entry->trust) {
|
| - nssTrust_Destroy(entry->trust);
|
| - }
|
| - if (entry->profile) {
|
| - nssSMIMEProfile_Destroy(entry->profile);
|
| - }
|
| - nss_ZFreeIf(entry);
|
| - }
|
| -}
|
| -
|
| -static void
|
| -remove_subject_entry (
|
| - nssCertificateStore *store,
|
| - NSSCertificate *cert
|
| -)
|
| -{
|
| - nssList *subjectList;
|
| - /* Get the subject list for the cert's subject */
|
| - subjectList = (nssList *)nssHash_Lookup(store->subject, &cert->subject);
|
| - if (subjectList) {
|
| - /* Remove the cert from the subject hash */
|
| - nssList_Remove(subjectList, cert);
|
| - nssHash_Remove(store->subject, &cert->subject);
|
| - if (nssList_Count(subjectList) == 0) {
|
| - nssList_Destroy(subjectList);
|
| - } else {
|
| - /* The cert being released may have keyed the subject entry.
|
| - * Since there are still subject certs around, get another and
|
| - * rekey the entry just in case.
|
| - */
|
| - NSSCertificate *subjectCert;
|
| - (void)nssList_GetArray(subjectList, (void **)&subjectCert, 1);
|
| - nssHash_Add(store->subject, &subjectCert->subject, subjectList);
|
| - }
|
| - }
|
| -}
|
| -
|
| -NSS_IMPLEMENT void
|
| -nssCertificateStore_RemoveCertLOCKED (
|
| - nssCertificateStore *store,
|
| - NSSCertificate *cert
|
| -)
|
| -{
|
| - certificate_hash_entry *entry;
|
| - entry = (certificate_hash_entry *)
|
| - nssHash_Lookup(store->issuer_and_serial, cert);
|
| - if (entry && entry->cert == cert) {
|
| - remove_certificate_entry(store, cert);
|
| - remove_subject_entry(store, cert);
|
| - }
|
| -}
|
| -
|
| -NSS_IMPLEMENT void
|
| -nssCertificateStore_Lock (
|
| - nssCertificateStore *store, nssCertificateStoreTrace* out
|
| -)
|
| -{
|
| -#ifdef DEBUG
|
| - PORT_Assert(out);
|
| - out->store = store;
|
| - out->lock = store->lock;
|
| - out->locked = PR_TRUE;
|
| - PZ_Lock(out->lock);
|
| -#else
|
| - PZ_Lock(store->lock);
|
| -#endif
|
| -}
|
| -
|
| -NSS_IMPLEMENT void
|
| -nssCertificateStore_Unlock (
|
| - nssCertificateStore *store, const nssCertificateStoreTrace* in,
|
| - nssCertificateStoreTrace* out
|
| -)
|
| -{
|
| -#ifdef DEBUG
|
| - PORT_Assert(in);
|
| - PORT_Assert(out);
|
| - out->store = store;
|
| - out->lock = store->lock;
|
| - PORT_Assert(!out->locked);
|
| - out->unlocked = PR_TRUE;
|
| -
|
| - PORT_Assert(in->store == out->store);
|
| - PORT_Assert(in->lock == out->lock);
|
| - PORT_Assert(in->locked);
|
| - PORT_Assert(!in->unlocked);
|
| -
|
| - PZ_Unlock(out->lock);
|
| -#else
|
| - PZ_Unlock(store->lock);
|
| -#endif
|
| -}
|
| -
|
| -static NSSCertificate **
|
| -get_array_from_list (
|
| - nssList *certList,
|
| - NSSCertificate *rvOpt[],
|
| - PRUint32 maximumOpt,
|
| - NSSArena *arenaOpt
|
| -)
|
| -{
|
| - PRUint32 count;
|
| - NSSCertificate **rvArray = NULL;
|
| - count = nssList_Count(certList);
|
| - if (count == 0) {
|
| - return NULL;
|
| - }
|
| - if (maximumOpt > 0) {
|
| - count = PR_MIN(maximumOpt, count);
|
| - }
|
| - if (rvOpt) {
|
| - nssList_GetArray(certList, (void **)rvOpt, count);
|
| - } else {
|
| - rvArray = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1);
|
| - if (rvArray) {
|
| - nssList_GetArray(certList, (void **)rvArray, count);
|
| - }
|
| - }
|
| - return rvArray;
|
| -}
|
| -
|
| -NSS_IMPLEMENT NSSCertificate **
|
| -nssCertificateStore_FindCertificatesBySubject (
|
| - nssCertificateStore *store,
|
| - NSSDER *subject,
|
| - NSSCertificate *rvOpt[],
|
| - PRUint32 maximumOpt,
|
| - NSSArena *arenaOpt
|
| -)
|
| -{
|
| - NSSCertificate **rvArray = NULL;
|
| - nssList *subjectList;
|
| - PZ_Lock(store->lock);
|
| - subjectList = (nssList *)nssHash_Lookup(store->subject, subject);
|
| - if (subjectList) {
|
| - nssCertificateList_AddReferences(subjectList);
|
| - rvArray = get_array_from_list(subjectList,
|
| - rvOpt, maximumOpt, arenaOpt);
|
| - }
|
| - PZ_Unlock(store->lock);
|
| - return rvArray;
|
| -}
|
| -
|
| -/* Because only subject indexing is implemented, all other lookups require
|
| - * full traversal (unfortunately, PLHashTable doesn't allow you to exit
|
| - * early from the enumeration). The assumptions are that 1) lookups by
|
| - * fields other than subject will be rare, and 2) the hash will not have
|
| - * a large number of entries. These assumptions will be tested.
|
| - *
|
| - * XXX
|
| - * For NSS 3.4, it is worth consideration to do all forms of indexing,
|
| - * because the only crypto context is global and persistent.
|
| - */
|
| -
|
| -struct nickname_template_str
|
| -{
|
| - NSSUTF8 *nickname;
|
| - nssList *subjectList;
|
| -};
|
| -
|
| -static void match_nickname(const void *k, void *v, void *a)
|
| -{
|
| - PRStatus nssrv;
|
| - NSSCertificate *c;
|
| - NSSUTF8 *nickname;
|
| - nssList *subjectList = (nssList *)v;
|
| - struct nickname_template_str *nt = (struct nickname_template_str *)a;
|
| - nssrv = nssList_GetArray(subjectList, (void **)&c, 1);
|
| - nickname = nssCertificate_GetNickname(c, NULL);
|
| - if (nssrv == PR_SUCCESS && nickname &&
|
| - nssUTF8_Equal(nickname, nt->nickname, &nssrv))
|
| - {
|
| - nt->subjectList = subjectList;
|
| - }
|
| - nss_ZFreeIf(nickname);
|
| -}
|
| -
|
| -/*
|
| - * Find all cached certs with this label.
|
| - */
|
| -NSS_IMPLEMENT NSSCertificate **
|
| -nssCertificateStore_FindCertificatesByNickname (
|
| - nssCertificateStore *store,
|
| - const NSSUTF8 *nickname,
|
| - NSSCertificate *rvOpt[],
|
| - PRUint32 maximumOpt,
|
| - NSSArena *arenaOpt
|
| -)
|
| -{
|
| - NSSCertificate **rvArray = NULL;
|
| - struct nickname_template_str nt;
|
| - nt.nickname = (char*) nickname;
|
| - nt.subjectList = NULL;
|
| - PZ_Lock(store->lock);
|
| - nssHash_Iterate(store->subject, match_nickname, &nt);
|
| - if (nt.subjectList) {
|
| - nssCertificateList_AddReferences(nt.subjectList);
|
| - rvArray = get_array_from_list(nt.subjectList,
|
| - rvOpt, maximumOpt, arenaOpt);
|
| - }
|
| - PZ_Unlock(store->lock);
|
| - return rvArray;
|
| -}
|
| -
|
| -struct email_template_str
|
| -{
|
| - NSSASCII7 *email;
|
| - nssList *emailList;
|
| -};
|
| -
|
| -static void match_email(const void *k, void *v, void *a)
|
| -{
|
| - PRStatus nssrv;
|
| - NSSCertificate *c;
|
| - nssList *subjectList = (nssList *)v;
|
| - struct email_template_str *et = (struct email_template_str *)a;
|
| - nssrv = nssList_GetArray(subjectList, (void **)&c, 1);
|
| - if (nssrv == PR_SUCCESS &&
|
| - nssUTF8_Equal(c->email, et->email, &nssrv))
|
| - {
|
| - nssListIterator *iter = nssList_CreateIterator(subjectList);
|
| - if (iter) {
|
| - for (c = (NSSCertificate *)nssListIterator_Start(iter);
|
| - c != (NSSCertificate *)NULL;
|
| - c = (NSSCertificate *)nssListIterator_Next(iter))
|
| - {
|
| - nssList_Add(et->emailList, c);
|
| - }
|
| - nssListIterator_Finish(iter);
|
| - nssListIterator_Destroy(iter);
|
| - }
|
| - }
|
| -}
|
| -
|
| -/*
|
| - * Find all cached certs with this email address.
|
| - */
|
| -NSS_IMPLEMENT NSSCertificate **
|
| -nssCertificateStore_FindCertificatesByEmail (
|
| - nssCertificateStore *store,
|
| - NSSASCII7 *email,
|
| - NSSCertificate *rvOpt[],
|
| - PRUint32 maximumOpt,
|
| - NSSArena *arenaOpt
|
| -)
|
| -{
|
| - NSSCertificate **rvArray = NULL;
|
| - struct email_template_str et;
|
| - et.email = email;
|
| - et.emailList = nssList_Create(NULL, PR_FALSE);
|
| - if (!et.emailList) {
|
| - return NULL;
|
| - }
|
| - PZ_Lock(store->lock);
|
| - nssHash_Iterate(store->subject, match_email, &et);
|
| - if (et.emailList) {
|
| - /* get references before leaving the store's lock protection */
|
| - nssCertificateList_AddReferences(et.emailList);
|
| - }
|
| - PZ_Unlock(store->lock);
|
| - if (et.emailList) {
|
| - rvArray = get_array_from_list(et.emailList,
|
| - rvOpt, maximumOpt, arenaOpt);
|
| - nssList_Destroy(et.emailList);
|
| - }
|
| - return rvArray;
|
| -}
|
| -
|
| -/* Caller holds store->lock */
|
| -static NSSCertificate *
|
| -nssCertStore_FindCertByIssuerAndSerialNumberLocked (
|
| - nssCertificateStore *store,
|
| - NSSDER *issuer,
|
| - NSSDER *serial
|
| -)
|
| -{
|
| - certificate_hash_entry *entry;
|
| - NSSCertificate *rvCert = NULL;
|
| - NSSCertificate index;
|
| -
|
| - index.issuer = *issuer;
|
| - index.serial = *serial;
|
| - entry = (certificate_hash_entry *)
|
| - nssHash_Lookup(store->issuer_and_serial, &index);
|
| - if (entry) {
|
| - rvCert = nssCertificate_AddRef(entry->cert);
|
| - }
|
| - return rvCert;
|
| -}
|
| -
|
| -NSS_IMPLEMENT NSSCertificate *
|
| -nssCertificateStore_FindCertificateByIssuerAndSerialNumber (
|
| - nssCertificateStore *store,
|
| - NSSDER *issuer,
|
| - NSSDER *serial
|
| -)
|
| -{
|
| - NSSCertificate *rvCert = NULL;
|
| -
|
| - PZ_Lock(store->lock);
|
| - rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked (
|
| - store, issuer, serial);
|
| - PZ_Unlock(store->lock);
|
| - return rvCert;
|
| -}
|
| -
|
| -NSS_IMPLEMENT NSSCertificate *
|
| -nssCertificateStore_FindCertificateByEncodedCertificate (
|
| - nssCertificateStore *store,
|
| - NSSDER *encoding
|
| -)
|
| -{
|
| - PRStatus nssrv = PR_FAILURE;
|
| - NSSDER issuer, serial;
|
| - NSSCertificate *rvCert = NULL;
|
| - nssrv = nssPKIX509_GetIssuerAndSerialFromDER(encoding, &issuer, &serial);
|
| - if (nssrv != PR_SUCCESS) {
|
| - return NULL;
|
| - }
|
| - rvCert = nssCertificateStore_FindCertificateByIssuerAndSerialNumber(store,
|
| - &issuer,
|
| - &serial);
|
| - PORT_Free(issuer.data);
|
| - PORT_Free(serial.data);
|
| - return rvCert;
|
| -}
|
| -
|
| -NSS_EXTERN PRStatus
|
| -nssCertificateStore_AddTrust (
|
| - nssCertificateStore *store,
|
| - NSSTrust *trust
|
| -)
|
| -{
|
| - NSSCertificate *cert;
|
| - certificate_hash_entry *entry;
|
| - cert = trust->certificate;
|
| - PZ_Lock(store->lock);
|
| - entry = (certificate_hash_entry *)
|
| - nssHash_Lookup(store->issuer_and_serial, cert);
|
| - if (entry) {
|
| - NSSTrust* newTrust = nssTrust_AddRef(trust);
|
| - if (entry->trust) {
|
| - nssTrust_Destroy(entry->trust);
|
| - }
|
| - entry->trust = newTrust;
|
| - }
|
| - PZ_Unlock(store->lock);
|
| - return (entry) ? PR_SUCCESS : PR_FAILURE;
|
| -}
|
| -
|
| -NSS_IMPLEMENT NSSTrust *
|
| -nssCertificateStore_FindTrustForCertificate (
|
| - nssCertificateStore *store,
|
| - NSSCertificate *cert
|
| -)
|
| -{
|
| - certificate_hash_entry *entry;
|
| - NSSTrust *rvTrust = NULL;
|
| - PZ_Lock(store->lock);
|
| - entry = (certificate_hash_entry *)
|
| - nssHash_Lookup(store->issuer_and_serial, cert);
|
| - if (entry && entry->trust) {
|
| - rvTrust = nssTrust_AddRef(entry->trust);
|
| - }
|
| - PZ_Unlock(store->lock);
|
| - return rvTrust;
|
| -}
|
| -
|
| -NSS_EXTERN PRStatus
|
| -nssCertificateStore_AddSMIMEProfile (
|
| - nssCertificateStore *store,
|
| - nssSMIMEProfile *profile
|
| -)
|
| -{
|
| - NSSCertificate *cert;
|
| - certificate_hash_entry *entry;
|
| - cert = profile->certificate;
|
| - PZ_Lock(store->lock);
|
| - entry = (certificate_hash_entry *)
|
| - nssHash_Lookup(store->issuer_and_serial, cert);
|
| - if (entry) {
|
| - nssSMIMEProfile* newProfile = nssSMIMEProfile_AddRef(profile);
|
| - if (entry->profile) {
|
| - nssSMIMEProfile_Destroy(entry->profile);
|
| - }
|
| - entry->profile = newProfile;
|
| - }
|
| - PZ_Unlock(store->lock);
|
| - return (entry) ? PR_SUCCESS : PR_FAILURE;
|
| -}
|
| -
|
| -NSS_IMPLEMENT nssSMIMEProfile *
|
| -nssCertificateStore_FindSMIMEProfileForCertificate (
|
| - nssCertificateStore *store,
|
| - NSSCertificate *cert
|
| -)
|
| -{
|
| - certificate_hash_entry *entry;
|
| - nssSMIMEProfile *rvProfile = NULL;
|
| - PZ_Lock(store->lock);
|
| - entry = (certificate_hash_entry *)
|
| - nssHash_Lookup(store->issuer_and_serial, cert);
|
| - if (entry && entry->profile) {
|
| - rvProfile = nssSMIMEProfile_AddRef(entry->profile);
|
| - }
|
| - PZ_Unlock(store->lock);
|
| - return rvProfile;
|
| -}
|
| -
|
| -/* XXX this is also used by cache and should be somewhere else */
|
| -
|
| -static PLHashNumber
|
| -nss_certificate_hash (
|
| - const void *key
|
| -)
|
| -{
|
| - unsigned int i;
|
| - PLHashNumber h;
|
| - NSSCertificate *c = (NSSCertificate *)key;
|
| - h = 0;
|
| - for (i=0; i<c->issuer.size; i++)
|
| - h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)c->issuer.data)[i];
|
| - for (i=0; i<c->serial.size; i++)
|
| - h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)c->serial.data)[i];
|
| - return h;
|
| -}
|
| -
|
| -static int
|
| -nss_compare_certs(const void *v1, const void *v2)
|
| -{
|
| - PRStatus ignore;
|
| - NSSCertificate *c1 = (NSSCertificate *)v1;
|
| - NSSCertificate *c2 = (NSSCertificate *)v2;
|
| - return (int)(nssItem_Equal(&c1->issuer, &c2->issuer, &ignore) &&
|
| - nssItem_Equal(&c1->serial, &c2->serial, &ignore));
|
| -}
|
| -
|
| -NSS_IMPLEMENT nssHash *
|
| -nssHash_CreateCertificate (
|
| - NSSArena *arenaOpt,
|
| - PRUint32 numBuckets
|
| -)
|
| -{
|
| - return nssHash_Create(arenaOpt,
|
| - numBuckets,
|
| - nss_certificate_hash,
|
| - nss_compare_certs,
|
| - PL_CompareValues);
|
| -}
|
| -
|
| -NSS_IMPLEMENT void
|
| -nssCertificateStore_DumpStoreInfo (
|
| - nssCertificateStore *store,
|
| - void (* cert_dump_iter)(const void *, void *, void *),
|
| - void *arg
|
| -)
|
| -{
|
| - PZ_Lock(store->lock);
|
| - nssHash_Iterate(store->issuer_and_serial, cert_dump_iter, arg);
|
| - PZ_Unlock(store->lock);
|
| -}
|
| -
|
|
|