b=124037 Decrease cert manager loading time.

r=rangansen/jkeiser sr=alecf
This commit is contained in:
kaie%netscape.com 2002-08-06 13:25:23 +00:00
Родитель 41d86022a1
Коммит de37d9d76f
8 изменённых файлов: 399 добавлений и 85 удалений

Просмотреть файл

@ -32,7 +32,8 @@ const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
const nsDialogParamBlock = "@mozilla.org/embedcomp/dialogparam;1";
const nsIPKIParamBlock = Components.interfaces.nsIPKIParamBlock;
const nsPKIParamBlock = "@mozilla.org/security/pkiparamblock;1";
const nsINSSCertCache = Components.interfaces.nsINSSCertCache;
const nsNSSCertCache = "@mozilla.org/security/nsscertcache;1";
var key;
@ -48,31 +49,36 @@ var userTreeView;
function LoadCerts()
{
certdb = Components.classes[nsX509CertDB].getService(nsIX509CertDB);
certcache = Components.classes[nsNSSCertCache].createInstance(nsINSSCertCache);
certcache.cacheAllCerts();
caTreeView = Components.classes[nsCertTree]
.createInstance(nsICertTree);
caTreeView.loadCerts(nsIX509Cert.CA_CERT);
caTreeView.loadCertsFromCache(certcache, nsIX509Cert.CA_CERT);
document.getElementById('ca-tree')
.treeBoxObject.view = caTreeView;
serverTreeView = Components.classes[nsCertTree]
.createInstance(nsICertTree);
serverTreeView.loadCerts(nsIX509Cert.SERVER_CERT);
serverTreeView.loadCertsFromCache(certcache, nsIX509Cert.SERVER_CERT);
document.getElementById('server-tree')
.treeBoxObject.view = serverTreeView;
emailTreeView = Components.classes[nsCertTree]
.createInstance(nsICertTree);
emailTreeView.loadCerts(nsIX509Cert.EMAIL_CERT);
emailTreeView.loadCertsFromCache(certcache, nsIX509Cert.EMAIL_CERT);
document.getElementById('email-tree')
.treeBoxObject.view = emailTreeView;
userTreeView = Components.classes[nsCertTree]
.createInstance(nsICertTree);
userTreeView.loadCerts(nsIX509Cert.USER_CERT);
userTreeView.loadCertsFromCache(certcache, nsIX509Cert.USER_CERT);
document.getElementById('user-tree')
.treeBoxObject.view = userTreeView;
certcache = null;
var rowCnt = userTreeView.rowCount;
var enableBackupAllButton=document.getElementById('mine_backupAllButton');
if(rowCnt < 1) {

Просмотреть файл

@ -36,11 +36,13 @@
#include "nsISupports.idl"
#include "nsITreeView.idl"
#include "nsIX509Cert.idl"
#include "nsIX509CertDB.idl"
[scriptable, uuid(4ea60761-31d6-491d-9e34-4b53a26c416c)]
interface nsICertTree : nsITreeView {
void loadCerts(in unsigned long type);
void loadCertsFromCache(in nsINSSCertCache cache, in unsigned long type);
nsIX509Cert getCert(in unsigned long index);

Просмотреть файл

@ -53,7 +53,16 @@ interface nsIURI;
#define NS_X509CERTDB_CONTRACTID "@mozilla.org/security/x509certdb;1"
typedef int (*nsCertCompareFunc)(nsIX509Cert *a, nsIX509Cert *b);
typedef int (*nsCertCompareFunc)(void *, nsIX509Cert *a, nsIX509Cert *b);
#define NS_NSSCERTCACHE_CID { /* 3f429a14-dffe-417d-8cb8-fdf09bacd09e */ \
0x3f429a14, \
0xdffe, \
0x417d, \
{0x8c, 0xb8, 0xfd, 0xf0, 0x9b, 0xac, 0xd0, 0x9e} \
}
#define NS_NSSCERTCACHE_CONTRACTID "@mozilla.org/security/nsscertcache;1"
%}
@ -85,6 +94,24 @@ interface nsICrlEntry : nsISupports {
};
[scriptable, uuid(6c143dac-bd65-4333-b594-7ed1e748e0f9)]
interface nsINSSCertCache : nsISupports {
/*
* cacheAllCerts
*
* Creates a cache of all certificates currently known to NSS.
*/
void cacheAllCerts();
/*
* getCachedCerts
*
* Returns the cached CERTCertList*
*/
[notxpcom, noscript] voidPtr getCachedCerts();
};
[scriptable, uuid(da48b3c0-1284-11d5-ac67-000064657374)]
interface nsIX509CertDB : nsISupports {
@ -123,6 +150,18 @@ interface nsIX509CertDB : nsISupports {
out unsigned long count,
[array, size_is(count)] out wstring certNameList);
/*
* getCertsByType
*
* Obtain a list of certs from the database.
*
*/
[notxpcom, noscript] boolean getCertsByTypeFromCache(in nsINSSCertCache cache,
in unsigned long aType,
in nsCertCompareFunc aCertCmpFn,
in voidPtr aCertCmpFnArg,
out nsISupportsArray certs);
/*
* getCertsByType
*
@ -131,6 +170,7 @@ interface nsIX509CertDB : nsISupports {
*/
[notxpcom, noscript] boolean getCertsByType(in unsigned long aType,
in nsCertCompareFunc aCertCmpFn,
in voidPtr aCertCmpFnArg,
out nsISupportsArray certs);
/* Get the user encryption cert */

Просмотреть файл

@ -59,15 +59,85 @@ struct treeArrayElStr {
PRInt32 numChildren; /* number of chidren (certs) for thread */
};
CompareCacheHashEntry::CompareCacheHashEntry()
:key(nsnull),
mTokenInit(PR_FALSE),
mIssuerOrgInit(PR_FALSE),
mOrgInit(PR_FALSE)
{
}
PR_STATIC_CALLBACK(const void *)
CompareCacheGetKey(PLDHashTable *table, PLDHashEntryHdr *hdr)
{
CompareCacheHashEntry *entry = NS_STATIC_CAST(CompareCacheHashEntry*, hdr);
return entry->key;
}
PR_STATIC_CALLBACK(PRBool)
CompareCacheMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr,
const void *key)
{
const CompareCacheHashEntry *entry = NS_STATIC_CAST(const CompareCacheHashEntry*, hdr);
return entry->key == key;
}
PR_STATIC_CALLBACK(void)
CompareCacheInitEntry(PLDHashTable *table, PLDHashEntryHdr *hdr,
const void *key)
{
new (hdr) CompareCacheHashEntry();
CompareCacheHashEntry *entry = NS_STATIC_CAST(CompareCacheHashEntry*, hdr);
entry->key = (void*)key;
}
PR_STATIC_CALLBACK(void)
CompareCacheClearEntry(PLDHashTable *table, PLDHashEntryHdr *hdr)
{
CompareCacheHashEntry *entry = NS_STATIC_CAST(CompareCacheHashEntry*, hdr);
entry->~CompareCacheHashEntry();
}
static PLDHashTableOps gMapOps = {
PL_DHashAllocTable,
PL_DHashFreeTable,
CompareCacheGetKey,
PL_DHashVoidPtrKeyStub,
CompareCacheMatchEntry,
PL_DHashMoveEntryStub,
CompareCacheClearEntry,
PL_DHashFinalizeStub,
CompareCacheInitEntry
};
NS_IMPL_ISUPPORTS2(nsCertTree, nsICertTree, nsITreeView)
nsCertTree::nsCertTree() : mTreeArray(NULL)
{
NS_INIT_ISUPPORTS();
mCompareCache.ops = nsnull;
}
void nsCertTree::ClearCompareHash()
{
if (mCompareCache.ops) {
PL_DHashTableFinish(&mCompareCache);
mCompareCache.ops = nsnull;
}
}
void nsCertTree::InitCompareHash()
{
ClearCompareHash();
PL_DHashTableInit(&mCompareCache, &gMapOps, nsnull,
sizeof(CompareCacheHashEntry), 128);
}
nsCertTree::~nsCertTree()
{
ClearCompareHash();
if (mTreeArray)
nsMemory::Free(mTreeArray);
}
@ -91,23 +161,56 @@ nsCertTree::FreeCertArray()
}
}
CompareCacheHashEntry *
nsCertTree::getCacheEntry(void *cache, void *aCert)
{
PLDHashTable &aCompareCache = *NS_REINTERPRET_CAST(PLDHashTable*, cache);
PLDHashEntryHdr *entry = PL_DHashTableOperate(&aCompareCache, aCert, PL_DHASH_LOOKUP);
if (PL_DHASH_ENTRY_IS_BUSY(entry))
{
return NS_STATIC_CAST(CompareCacheHashEntry*, entry);
}
else
{
return NS_STATIC_CAST(CompareCacheHashEntry*, PL_DHashTableOperate(&aCompareCache, aCert, PL_DHASH_ADD));
}
}
void nsCertTree::RemoveCacheEntry(void *key)
{
PL_DHashTableOperate(&mCompareCache, key, PL_DHASH_REMOVE);
}
// CmpByToken
//
// Compare two certificate by their token name. Returns -1, 0, 1 as
// in strcmp. No token name (null) is treated as <.
PRInt32
nsCertTree::CmpByToken(nsIX509Cert *a, nsIX509Cert *b)
nsCertTree::CmpByToken(void *cache, nsIX509Cert *a, nsIX509Cert *b)
{
PRInt32 cmp1;
nsXPIDLString aTok, bTok;
a->GetTokenName(getter_Copies(aTok));
b->GetTokenName(getter_Copies(bTok));
if (aTok != nsnull && bTok != nsnull) {
cmp1 = Compare(aTok, bTok);
} else {
cmp1 = (aTok == nsnull) ? -1 : 1;
if (a == b)
return 0;
CompareCacheHashEntry *ace = getCacheEntry(cache, a);
CompareCacheHashEntry *bce = getCacheEntry(cache, b);
if (!ace->mTokenInit)
{
ace->mTokenInit = PR_TRUE;
a->GetTokenName(getter_Copies(ace->mToken));
}
if (!bce->mTokenInit)
{
bce->mTokenInit = PR_TRUE;
b->GetTokenName(getter_Copies(bce->mToken));
}
if (ace->mToken != nsnull && bce->mToken != nsnull) {
return Compare(ace->mToken, bce->mToken);
} else {
return !ace->mToken ? (!bce->mToken ? 0 : -1) : 1;
}
return cmp1;
}
// CmpByIssuerOrg
@ -115,37 +218,63 @@ nsCertTree::CmpByToken(nsIX509Cert *a, nsIX509Cert *b)
// Compare two certificates by their O= field. Returns -1, 0, 1 as
// in strcmp. No organization (null) is treated as <.
PRInt32
nsCertTree::CmpByIssuerOrg(nsIX509Cert *a, nsIX509Cert *b)
nsCertTree::CmpByIssuerOrg(void *cache, nsIX509Cert *a, nsIX509Cert *b)
{
PRInt32 cmp1;
nsXPIDLString aOrg, bOrg;
a->GetIssuerOrganization(getter_Copies(aOrg));
b->GetIssuerOrganization(getter_Copies(bOrg));
if (aOrg != nsnull && bOrg != nsnull) {
cmp1 = Compare(aOrg, bOrg);
} else {
cmp1 = (aOrg == nsnull) ? -1 : 1;
if (a == b)
return 0;
CompareCacheHashEntry *ace = getCacheEntry(cache, a);
CompareCacheHashEntry *bce = getCacheEntry(cache, b);
if (!ace->mIssuerOrgInit)
{
ace->mIssuerOrgInit = PR_TRUE;
a->GetIssuerOrganization(getter_Copies(ace->mIssuerOrg));
}
if (!bce->mIssuerOrgInit)
{
bce->mIssuerOrgInit = PR_TRUE;
b->GetIssuerOrganization(getter_Copies(bce->mIssuerOrg));
}
if (ace->mIssuerOrg != nsnull && bce->mIssuerOrg != nsnull) {
return Compare(ace->mIssuerOrg, bce->mIssuerOrg);
} else {
return !ace->mIssuerOrg ? (!bce->mIssuerOrg ? 0 : -1) : 1;
}
return cmp1;
}
// CmpByName
// CmpByOrg
//
// Compare two certificates by their CN= field. Returns -1, 0, 1 as
// in strcmp. No common name (null) is treated as <.
PRInt32
nsCertTree::CmpByName(nsIX509Cert *a, nsIX509Cert *b)
nsCertTree::CmpByOrg(void *cache, nsIX509Cert *a, nsIX509Cert *b)
{
PRInt32 cmp1;
nsXPIDLString aName, bName;
a->GetOrganization(getter_Copies(aName));
b->GetOrganization(getter_Copies(bName));
if (aName != nsnull && bName != nsnull) {
cmp1 = Compare(aName, bName);
} else {
cmp1 = (aName == nsnull) ? -1 : 1;
if (a == b)
return 0;
CompareCacheHashEntry *ace = getCacheEntry(cache, a);
CompareCacheHashEntry *bce = getCacheEntry(cache, b);
if (!ace->mOrgInit)
{
ace->mOrgInit = PR_TRUE;
a->GetOrganization(getter_Copies(ace->mOrg));
}
if (!bce->mOrgInit)
{
bce->mOrgInit = PR_TRUE;
b->GetOrganization(getter_Copies(bce->mOrg));
}
if (ace->mOrg != nsnull && bce->mOrg != nsnull) {
return Compare(ace->mOrg, bce->mOrg);
} else {
return !ace->mOrg ? (!bce->mOrg ? 0 : -1) : 1;
}
return cmp1;
}
// CmpByTok_IssuerOrg_Name
@ -153,14 +282,14 @@ nsCertTree::CmpByName(nsIX509Cert *a, nsIX509Cert *b)
// Compare two certificates by token name, issuer organization,
// and common name, in that order. Used to sort cert list.
PRInt32
nsCertTree::CmpByTok_IssuerOrg_Name(nsIX509Cert *a, nsIX509Cert *b)
nsCertTree::CmpByTok_IssuerOrg_Org(void *cache, nsIX509Cert *a, nsIX509Cert *b)
{
PRInt32 cmp;
cmp = CmpByToken(a, b);
cmp = CmpByToken(cache, a, b);
if (cmp != 0) return cmp;
cmp = CmpByIssuerOrg(a, b);
cmp = CmpByIssuerOrg(cache, a, b);
if (cmp != 0) return cmp;
return CmpByName(a, b);
return CmpByOrg(cache, a, b);
}
// CountOrganizations
@ -182,8 +311,8 @@ nsCertTree::CountOrganizations()
for (i=1; i<certCount; i++) {
isupport = dont_AddRef(mCertArray->ElementAt(i));
nextCert = do_QueryInterface(isupport);
if (!(CmpByToken(orgCert, nextCert) == 0 &&
CmpByIssuerOrg(orgCert, nextCert) == 0)) {
if (!(CmpByToken(&mCompareCache, orgCert, nextCert) == 0 &&
CmpByIssuerOrg(&mCompareCache, orgCert, nextCert) == 0)) {
orgCert = nextCert;
orgCount++;
}
@ -249,6 +378,26 @@ nsCertTree::GetCertAtIndex(PRInt32 index)
//
// Load all of the certificates in the DB for this type. Sort them
// by token, organization, then common name.
NS_IMETHODIMP
nsCertTree::LoadCertsFromCache(nsINSSCertCache *aCache, PRUint32 aType)
{
nsresult rv;
if (mTreeArray) {
FreeCertArray();
nsMemory::Free(mTreeArray);
mTreeArray = NULL;
mNumRows = 0;
}
InitCompareHash();
nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
if (certdb == nsnull) return NS_ERROR_FAILURE;
rv = certdb->GetCertsByTypeFromCache(aCache, aType,
CmpByTok_IssuerOrg_Org, &mCompareCache,
getter_AddRefs(mCertArray));
if (NS_FAILED(rv)) return rv;
return UpdateUIContents();
}
NS_IMETHODIMP
nsCertTree::LoadCerts(PRUint32 aType)
{
@ -259,10 +408,11 @@ nsCertTree::LoadCerts(PRUint32 aType)
mTreeArray = NULL;
mNumRows = 0;
}
InitCompareHash();
nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
if (certdb == nsnull) return NS_ERROR_FAILURE;
rv = certdb->GetCertsByType(aType,
CmpByTok_IssuerOrg_Name,
CmpByTok_IssuerOrg_Org, &mCompareCache,
getter_AddRefs(mCertArray));
if (NS_FAILED(rv)) return rv;
return UpdateUIContents();
@ -288,7 +438,7 @@ nsCertTree::UpdateUIContents()
if (++j >= count) break;
isupport = dont_AddRef(mCertArray->ElementAt(j));
nsCOMPtr<nsIX509Cert> nextCert = do_QueryInterface(isupport);
while (CmpByIssuerOrg(orgCert, nextCert) == 0) {
while (CmpByIssuerOrg(&mCompareCache, orgCert, nextCert) == 0) {
mTreeArray[i].numChildren++;
if (++j >= count) break;
isupport = dont_AddRef(mCertArray->ElementAt(j));
@ -312,7 +462,6 @@ nsCertTree::RemoveCert(PRUint32 index)
}
int i, idx = 0, cIndex = 0, nc;
nsIX509Cert *rawPtr = nsnull;
// Loop over the threads
for (i=0; i<mNumOrgs; i++) {
if (index == idx)
@ -321,6 +470,8 @@ nsCertTree::RemoveCert(PRUint32 index)
nc = (mTreeArray[i].open) ? mTreeArray[i].numChildren : 0;
if (index < idx + nc) { // cert is within range of this thread
PRInt32 certIndex = cIndex + index - idx;
nsCOMPtr<nsISupports> isupport = dont_AddRef(mCertArray->ElementAt(certIndex));
RemoveCacheEntry(isupport);
mCertArray->RemoveElementAt(certIndex);
nsMemory::Free(mTreeArray);
mTreeArray = NULL;

Просмотреть файл

@ -43,9 +43,22 @@
#include "nsITreeBoxObject.h"
#include "nsITreeSelection.h"
#include "nsISupportsArray.h"
#include "pldhash.h"
typedef struct treeArrayElStr treeArrayEl;
struct CompareCacheHashEntry : PLDHashEntryHdr {
CompareCacheHashEntry();
void *key; // no ownership
PRPackedBool mTokenInit;
PRPackedBool mIssuerOrgInit;
PRPackedBool mOrgInit;
nsXPIDLString mToken;
nsXPIDLString mIssuerOrg;
nsXPIDLString mOrg;
};
class nsCertTree : public nsICertTree
{
public:
@ -57,10 +70,15 @@ public:
virtual ~nsCertTree();
protected:
static PRInt32 CmpByToken(nsIX509Cert *a, nsIX509Cert *b);
static PRInt32 CmpByIssuerOrg(nsIX509Cert *a, nsIX509Cert *b);
static PRInt32 CmpByName(nsIX509Cert *a, nsIX509Cert *b);
static PRInt32 CmpByTok_IssuerOrg_Name(nsIX509Cert *a, nsIX509Cert *b);
void InitCompareHash();
void ClearCompareHash();
void RemoveCacheEntry(void *key);
static CompareCacheHashEntry *getCacheEntry(void *cache, void *aCert);
static PRInt32 CmpByToken(void *cache, nsIX509Cert *a, nsIX509Cert *b);
static PRInt32 CmpByIssuerOrg(void *cache, nsIX509Cert *a, nsIX509Cert *b);
static PRInt32 CmpByOrg(void *cache, nsIX509Cert *a, nsIX509Cert *b);
static PRInt32 CmpByTok_IssuerOrg_Org(void *cache, nsIX509Cert *a, nsIX509Cert *b);
PRInt32 CountOrganizations();
private:
@ -70,6 +88,7 @@ private:
treeArrayEl *mTreeArray;
PRInt32 mNumOrgs;
PRInt32 mNumRows;
PLDHashTable mCompareCache;
treeArrayEl *GetThreadDescAtIndex(PRInt32 _index);
nsIX509Cert *GetCertAtIndex(PRInt32 _index);

Просмотреть файл

@ -60,6 +60,7 @@
#include "nsTime.h"
#include "nsIProxyObjectManager.h"
#include "nsCRT.h"
#include "nsAutoLock.h"
#include "nspr.h"
extern "C" {
@ -1008,6 +1009,7 @@ nsNSSCertificate::GetCommonName(PRUnichar **aCommonName)
char *commonName = CERT_GetCommonName(&mCert->subject);
if (commonName) {
*aCommonName = ToNewUnicode(NS_ConvertUTF8toUCS2(commonName));
PORT_Free(commonName);
} /*else {
*aCommonName = ToNewUnicode(NS_LITERAL_STRING("<not set>")),
}*/
@ -1024,6 +1026,7 @@ nsNSSCertificate::GetOrganization(PRUnichar **aOrganization)
char *organization = CERT_GetOrgName(&mCert->subject);
if (organization) {
*aOrganization = ToNewUnicode(NS_ConvertUTF8toUCS2(organization));
PORT_Free(organization);
} /*else {
*aOrganization = ToNewUnicode(NS_LITERAL_STRING("<not set>")),
}*/
@ -1040,6 +1043,7 @@ nsNSSCertificate::GetIssuerCommonName(PRUnichar **aCommonName)
char *commonName = CERT_GetCommonName(&mCert->issuer);
if (commonName) {
*aCommonName = ToNewUnicode(NS_ConvertUTF8toUCS2(commonName));
PORT_Free(commonName);
}
}
return NS_OK;
@ -1054,6 +1058,7 @@ nsNSSCertificate::GetIssuerOrganization(PRUnichar **aOrganization)
char *organization = CERT_GetOrgName(&mCert->issuer);
if (organization) {
*aOrganization = ToNewUnicode(NS_ConvertUTF8toUCS2(organization));
PORT_Free(organization);
}
}
return NS_OK;
@ -1068,6 +1073,7 @@ nsNSSCertificate::GetIssuerOrganizationUnit(PRUnichar **aOrganizationUnit)
char *organizationUnit = CERT_GetOrgUnitName(&mCert->issuer);
if (organizationUnit) {
*aOrganizationUnit = ToNewUnicode(NS_ConvertUTF8toUCS2(organizationUnit));
PORT_Free(organizationUnit);
}
}
return NS_OK;
@ -1099,6 +1105,7 @@ nsNSSCertificate::GetOrganizationalUnit(PRUnichar **aOrganizationalUnit)
char *orgunit = CERT_GetOrgUnitName(&mCert->subject);
if (orgunit) {
*aOrganizationalUnit = ToNewUnicode(NS_ConvertUTF8toUCS2(orgunit));
PORT_Free(orgunit);
} /*else {
*aOrganizationalUnit = ToNewUnicode(NS_LITERAL_STRING("<not set>")),
}*/
@ -2905,62 +2912,76 @@ cleanup:
return rv;
}
/*
* [noscript] unsigned long getCertsByType(in unsigned long aType,
* in nsCertCompareFunc aCertCmpFn,
* out nsISupportsArray certs);
*/
PRBool
nsNSSCertificateDB::GetCertsByType(PRUint32 aType,
nsCertCompareFunc aCertCmpFn,
nsISupportsArray **_certs)
PRBool
nsNSSCertificateDB::GetCertsByTypeFromCertList(CERTCertList *aCertList,
PRUint32 aType,
nsCertCompareFunc aCertCmpFn,
void *aCertCmpFnArg,
nsISupportsArray **_certs)
{
CERTCertList *certList = NULL;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("GetCertsByType"));
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("GetCertsByTypeFromCertList"));
if (!aCertList)
return PR_FALSE;
nsCOMPtr<nsISupportsArray> certarray;
nsresult rv = NS_NewISupportsArray(getter_AddRefs(certarray));
if (NS_FAILED(rv)) return PR_FALSE;
nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
#ifdef NSS_3_4
if (aType == nsIX509Cert::USER_CERT) {
certList = PK11_ListCerts(PK11CertListUser, cxt);
} else if (aType == nsIX509Cert::CA_CERT) {
certList = PK11_ListCerts(PK11CertListCA, cxt); /* or RootUnique? */
} else {
certList = PK11_ListCerts(PK11CertListUnique, cxt);
}
#else
certList = PK11_ListCerts(PK11CertListUnique, cxt);
#endif
CERTCertListNode *node;
int i, count = 0;
for (node = CERT_LIST_HEAD(certList);
!CERT_LIST_END(node, certList);
for (node = CERT_LIST_HEAD(aCertList);
!CERT_LIST_END(node, aCertList);
node = CERT_LIST_NEXT(node)) {
if (getCertType(node->cert) == aType) {
nsCOMPtr<nsIX509Cert> pipCert = new nsNSSCertificate(node->cert);
if (pipCert) {
for (i=0; i<count; i++) {
nsCOMPtr<nsISupports> isupport =
getter_AddRefs(certarray->ElementAt(i));
dont_AddRef(certarray->ElementAt(i));
nsCOMPtr<nsIX509Cert> cert = do_QueryInterface(isupport);
if ((*aCertCmpFn)(pipCert, cert) < 0) {
if ((*aCertCmpFn)(aCertCmpFnArg, pipCert, cert) < 0) {
certarray->InsertElementAt(pipCert, i);
break;
}
}
if (i == count) certarray->AppendElement(pipCert);
count++;
break;
}
}
if (i == count) certarray->AppendElement(pipCert);
count++;
}
}
}
*_certs = certarray;
NS_ADDREF(*_certs);
if (certList)
CERT_DestroyCertList(certList);
return PR_TRUE;
}
PRBool
nsNSSCertificateDB::GetCertsByType(PRUint32 aType,
nsCertCompareFunc aCertCmpFn,
void *aCertCmpFnArg,
nsISupportsArray **_certs)
{
CERTCertList *certList = NULL;
nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
certList = PK11_ListCerts(PK11CertListUnique, cxt);
PRBool rv = GetCertsByTypeFromCertList(certList, aType, aCertCmpFn, aCertCmpFnArg, _certs);
if (certList)
CERT_DestroyCertList(certList);
return rv;
}
PRBool
nsNSSCertificateDB::GetCertsByTypeFromCache(nsINSSCertCache *aCache,
PRUint32 aType,
nsCertCompareFunc aCertCmpFn,
void *aCertCmpFnArg,
nsISupportsArray **_certs)
{
NS_ENSURE_ARG_POINTER(aCache);
CERTCertList *certList = NS_REINTERPRET_CAST(CERTCertList*, aCache->GetCachedCerts());
if (!certList)
return NS_ERROR_FAILURE;
return GetCertsByTypeFromCertList(certList, aType, aCertCmpFn, aCertCmpFnArg, _certs);
}
SECStatus PR_CALLBACK
collect_certs(void *arg, SECItem **certs, int numcerts)
{
@ -4022,7 +4043,7 @@ GetOCSPResponders (CERTCertificate *aCert,
// Sort the items according to nickname //
rv = array->Count(&count);
for (i=0; i < count; ++i) {
nsCOMPtr<nsISupports> isupport = getter_AddRefs(array->ElementAt(i));
nsCOMPtr<nsISupports> isupport = dont_AddRef(array->ElementAt(i));
nsCOMPtr<nsIOCSPResponder> entry = do_QueryInterface(isupport);
if (nsOCSPResponder::CompareEntries(new_entry, entry) < 0) {
array->InsertElementAt(new_entry, i);
@ -4941,3 +4962,51 @@ nsNSSCertificateDB::ConstructX509FromBase64(const char * base64, nsIX509Cert **_
}
return rv;
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsNSSCertCache, nsINSSCertCache)
nsNSSCertCache::nsNSSCertCache()
:mCertList(nsnull)
{
mutex = PR_NewLock();
}
nsNSSCertCache::~nsNSSCertCache()
{
if (mCertList) {
CERT_DestroyCertList(mCertList);
}
if (mutex) {
PR_DestroyLock(mutex);
mutex = nsnull;
}
}
NS_IMETHODIMP
nsNSSCertCache::CacheAllCerts()
{
{
nsAutoLock lock(mutex);
if (mCertList) {
CERT_DestroyCertList(mCertList);
mCertList = nsnull;
}
}
nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
CERTCertList *newList = PK11_ListCerts(PK11CertListUnique, cxt);
if (newList) {
nsAutoLock lock(mutex);
mCertList = newList;
}
return NS_OK;
}
void* nsNSSCertCache::GetCachedCerts()
{
nsAutoLock lock(mutex);
return mCertList;
}

Просмотреть файл

@ -118,6 +118,19 @@ private:
nsString mNextAutoUpdateDate;
};
class nsNSSCertCache : public nsINSSCertCache
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSINSSCERTCACHE
nsNSSCertCache();
virtual ~nsNSSCertCache();
private:
PRLock *mutex;
CERTCertList *mCertList;
};
class nsNSSCertificateDB : public nsIX509CertDB
{
@ -141,6 +154,12 @@ private:
PRUint32 length);
nsresult handleCACertDownload(nsISupportsArray *x509Certs,
nsIInterfaceRequestor *ctx);
PRBool GetCertsByTypeFromCertList(CERTCertList *aCertList,
PRUint32 aType,
nsCertCompareFunc aCertCmpFn,
void *aCertCmpFnArg,
nsISupportsArray **_certs);
};
// Use this function to generate a default nickname for a user

Просмотреть файл

@ -146,6 +146,7 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsPK11TokenDB)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsPKCS11ModuleDB)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(PR_FALSE, PSMContentListener, init)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsNSSCertificateDB)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsNSSCertCache)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsCertTree)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsCrypto)
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsPkcs11)
@ -264,6 +265,13 @@ static const nsModuleComponentInfo components[] =
nsNSSCertificateDBConstructor
},
{
"NSS Certificate Cache",
NS_NSSCERTCACHE_CID,
NS_NSSCERTCACHE_CONTRACTID,
nsNSSCertCacheConstructor
},
{
"Form Processor",
NS_FORMPROCESSOR_CID,