b=121906 Other People's certs not sorted

r=javi sr=jag
This commit is contained in:
kaie%netscape.com 2002-08-28 13:49:52 +00:00
Родитель f7030aafe7
Коммит d2d449e2a9
5 изменённых файлов: 212 добавлений и 132 удалений

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

@ -126,7 +126,9 @@ interface nsIX509Cert : nsISupports {
readonly attribute wstring sha1Fingerprint;
readonly attribute wstring md5Fingerprint;
readonly attribute wstring issuedDate;
readonly attribute wstring issuedDateSortable;
readonly attribute wstring expiresDate;
readonly attribute wstring expiresDateSortable;
readonly attribute wstring tokenName;
readonly attribute wstring issuerCommonName;
readonly attribute wstring issuerOrganization;

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

@ -60,11 +60,11 @@ struct treeArrayElStr {
};
CompareCacheHashEntry::CompareCacheHashEntry()
:key(nsnull),
mTokenInit(PR_FALSE),
mIssuerOrgInit(PR_FALSE),
mOrgInit(PR_FALSE)
:key(nsnull)
{
for (int i = 0; i < max_criterions; ++i) {
mCritInit[i] = PR_FALSE;
}
}
PR_STATIC_CALLBACK(const void *)
@ -182,122 +182,10 @@ 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(void *cache, nsIX509Cert *a, nsIX509Cert *b)
{
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;
}
}
// CmpByIssuerOrg
//
// Compare two certificates by their O= field. Returns -1, 0, 1 as
// in strcmp. No organization (null) is treated as <.
PRInt32
nsCertTree::CmpByIssuerOrg(void *cache, nsIX509Cert *a, nsIX509Cert *b)
{
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;
}
}
// CmpByOrg
//
// Compare two certificates by their CN= field. Returns -1, 0, 1 as
// in strcmp. No common name (null) is treated as <.
PRInt32
nsCertTree::CmpByOrg(void *cache, nsIX509Cert *a, nsIX509Cert *b)
{
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;
}
}
// CmpByTok_IssuerOrg_Name
//
// Compare two certificates by token name, issuer organization,
// and common name, in that order. Used to sort cert list.
PRInt32
nsCertTree::CmpByTok_IssuerOrg_Org(void *cache, nsIX509Cert *a, nsIX509Cert *b)
{
PRInt32 cmp;
cmp = CmpByToken(cache, a, b);
if (cmp != 0) return cmp;
cmp = CmpByIssuerOrg(cache, a, b);
if (cmp != 0) return cmp;
return CmpByOrg(cache, a, b);
}
// CountOrganizations
//
// Count the number of different organizations encountered in the cert
// list. Note that the same organization of a different token is counted
// seperately.
// list.
PRInt32
nsCertTree::CountOrganizations()
{
@ -312,8 +200,8 @@ nsCertTree::CountOrganizations()
for (i=1; i<certCount; i++) {
isupport = dont_AddRef(mCertArray->ElementAt(i));
nextCert = do_QueryInterface(isupport);
if (!(CmpByToken(&mCompareCache, orgCert, nextCert) == 0 &&
CmpByIssuerOrg(&mCompareCache, orgCert, nextCert) == 0)) {
// XXX we assume issuer org is always criterion 1
if (CmpBy(&mCompareCache, orgCert, nextCert, sort_IssuerOrg, sort_None, sort_None) != 0) {
orgCert = nextCert;
orgCount++;
}
@ -375,6 +263,22 @@ nsCertTree::GetCertAtIndex(PRInt32 index)
return rawPtr;
}
nsCertCompareFunc
nsCertTree::GetCompareFuncFromCertType(PRUint32 aType)
{
switch (aType) {
case nsIX509Cert::USER_CERT:
return CmpUserCert;
case nsIX509Cert::CA_CERT:
return CmpCACert;
case nsIX509Cert::EMAIL_CERT:
return CmpEmailCert;
case nsIX509Cert::SERVER_CERT:
default:
return CmpWebSiteCert;
}
}
// LoadCerts
//
// Load all of the certificates in the DB for this type. Sort them
@ -392,8 +296,9 @@ nsCertTree::LoadCertsFromCache(nsINSSCertCache *aCache, PRUint32 aType)
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,
GetCompareFuncFromCertType(aType), &mCompareCache,
getter_AddRefs(mCertArray));
if (NS_FAILED(rv)) return rv;
return UpdateUIContents();
@ -413,7 +318,7 @@ nsCertTree::LoadCerts(PRUint32 aType)
nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
if (certdb == nsnull) return NS_ERROR_FAILURE;
rv = certdb->GetCertsByType(aType,
CmpByTok_IssuerOrg_Org, &mCompareCache,
GetCompareFuncFromCertType(aType), &mCompareCache,
getter_AddRefs(mCertArray));
if (NS_FAILED(rv)) return rv;
return UpdateUIContents();
@ -439,7 +344,7 @@ nsCertTree::UpdateUIContents()
if (++j >= count) break;
isupport = dont_AddRef(mCertArray->ElementAt(j));
nsCOMPtr<nsIX509Cert> nextCert = do_QueryInterface(isupport);
while (CmpByIssuerOrg(&mCompareCache, orgCert, nextCert) == 0) {
while (0 == CmpBy(&mCompareCache, orgCert, nextCert, sort_IssuerOrg, sort_None, sort_None)) {
mTreeArray[i].numChildren++;
if (++j >= count) break;
isupport = dont_AddRef(mCertArray->ElementAt(j));
@ -946,3 +851,120 @@ NS_IMETHODIMP nsCertTree::IsSorted(PRBool *_retval)
*_retval = PR_FALSE;
return NS_OK;
}
void
nsCertTree::CmpInitCriterion(nsIX509Cert *cert, CompareCacheHashEntry *entry,
sortCriterion crit, PRInt32 level)
{
entry->mCritInit[level] = PR_TRUE;
nsXPIDLString &str = entry->mCrit[level];
switch (crit) {
case sort_IssuerOrg:
cert->GetIssuerOrganization(getter_Copies(str));
break;
case sort_Org:
cert->GetOrganization(getter_Copies(str));
break;
case sort_Token:
cert->GetTokenName(getter_Copies(str));
break;
case sort_CommonName:
cert->GetCommonName(getter_Copies(str));
break;
case sort_IssuedDateDescending:
cert->GetIssuedDateSortable(getter_Copies(str));
break;
case sort_Email:
cert->GetEmailAddress(getter_Copies(str));
break;
case sort_None:
default:
break;
}
}
PRInt32
nsCertTree::CmpByCrit(nsIX509Cert *a, CompareCacheHashEntry *ace,
nsIX509Cert *b, CompareCacheHashEntry *bce,
sortCriterion crit, PRInt32 level)
{
if (!ace->mCritInit[level]) {
CmpInitCriterion(a, ace, crit, level);
}
if (!bce->mCritInit[level]) {
CmpInitCriterion(b, bce, crit, level);
}
nsXPIDLString &str_a = ace->mCrit[level];
nsXPIDLString &str_b = bce->mCrit[level];
PRInt32 result;
if (str_a && str_b)
result = Compare(str_a, str_b);
else
result = !str_a ? (!str_b ? 0 : -1) : 1;
if (sort_IssuedDateDescending == crit)
result *= -1; // reverse compare order
return result;
}
PRInt32
nsCertTree::CmpBy(void *cache, nsIX509Cert *a, nsIX509Cert *b,
sortCriterion c0, sortCriterion c1, sortCriterion c2)
{
if (a == b)
return 0;
CompareCacheHashEntry *ace = getCacheEntry(cache, a);
CompareCacheHashEntry *bce = getCacheEntry(cache, b);
PRInt32 cmp;
cmp = CmpByCrit(a, ace, b, bce, c0, 0);
if (cmp != 0)
return cmp;
if (c1 != sort_None) {
cmp = CmpByCrit(a, ace, b, bce, c1, 1);
if (cmp != 0)
return cmp;
if (c2 != sort_None) {
return CmpByCrit(a, ace, b, bce, c2, 2);
}
}
return cmp;
}
PRInt32
nsCertTree::CmpCACert(void *cache, nsIX509Cert *a, nsIX509Cert *b)
{
// XXX we assume issuer org is always criterion 1
return CmpBy(cache, a, b, sort_IssuerOrg, sort_Org, sort_Token);
}
PRInt32
nsCertTree::CmpWebSiteCert(void *cache, nsIX509Cert *a, nsIX509Cert *b)
{
// XXX we assume issuer org is always criterion 1
return CmpBy(cache, a, b, sort_IssuerOrg, sort_CommonName, sort_None);
}
PRInt32
nsCertTree::CmpUserCert(void *cache, nsIX509Cert *a, nsIX509Cert *b)
{
// XXX we assume issuer org is always criterion 1
return CmpBy(cache, a, b, sort_IssuerOrg, sort_Token, sort_IssuedDateDescending);
}
PRInt32
nsCertTree::CmpEmailCert(void *cache, nsIX509Cert *a, nsIX509Cert *b)
{
// XXX we assume issuer org is always criterion 1
return CmpBy(cache, a, b, sort_IssuerOrg, sort_Email, sort_CommonName);
}

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

@ -50,13 +50,11 @@ typedef struct treeArrayElStr treeArrayEl;
struct CompareCacheHashEntry : PLDHashEntryHdr {
CompareCacheHashEntry();
enum { max_criterions = 3 };
void *key; // no ownership
PRPackedBool mTokenInit;
PRPackedBool mIssuerOrgInit;
PRPackedBool mOrgInit;
nsXPIDLString mToken;
nsXPIDLString mIssuerOrg;
nsXPIDLString mOrg;
PRPackedBool mCritInit[max_criterions];
nsXPIDLString mCrit[max_criterions];
};
class nsCertTree : public nsICertTree
@ -69,16 +67,27 @@ public:
nsCertTree();
virtual ~nsCertTree();
enum sortCriterion { sort_IssuerOrg, sort_Org, sort_Token,
sort_CommonName, sort_IssuedDateDescending, sort_Email, sort_None };
protected:
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);
static void CmpInitCriterion(nsIX509Cert *cert, CompareCacheHashEntry *entry,
sortCriterion crit, PRInt32 level);
static PRInt32 CmpByCrit(nsIX509Cert *a, CompareCacheHashEntry *ace,
nsIX509Cert *b, CompareCacheHashEntry *bce,
sortCriterion crit, PRInt32 level);
static PRInt32 CmpBy(void *cache, nsIX509Cert *a, nsIX509Cert *b,
sortCriterion c0, sortCriterion c1, sortCriterion c2);
static PRInt32 CmpCACert(void *cache, nsIX509Cert *a, nsIX509Cert *b);
static PRInt32 CmpWebSiteCert(void *cache, nsIX509Cert *a, nsIX509Cert *b);
static PRInt32 CmpUserCert(void *cache, nsIX509Cert *a, nsIX509Cert *b);
static PRInt32 CmpEmailCert(void *cache, nsIX509Cert *a, nsIX509Cert *b);
nsCertCompareFunc GetCompareFuncFromCertType(PRUint32 aType);
PRInt32 CountOrganizations();
private:

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

@ -1285,6 +1285,36 @@ nsNSSCertificate::GetIssuedDate(PRUnichar **_issuedDate)
return NS_OK;
}
nsresult
nsNSSCertificate::GetSortableDate(PRTime aTime, PRUnichar **_aSortableDate)
{
PRExplodedTime explodedTime;
PR_ExplodeTime(aTime, PR_GMTParameters, &explodedTime);
char datebuf[20]; // 4 + 2 + 2 + 2 + 2 + 2 + 1 = 15
if (0 != PR_FormatTime(datebuf, sizeof(datebuf), "%Y%m%d%H%M%S", &explodedTime)) {
*_aSortableDate = ToNewUnicode(nsDependentCString(datebuf));
return NS_OK;
}
else
return NS_ERROR_OUT_OF_MEMORY;
}
/* readonly attribute wstring issuedDateSortable; */
NS_IMETHODIMP
nsNSSCertificate::GetIssuedDateSortable(PRUnichar **_issuedDate)
{
NS_ENSURE_ARG(_issuedDate);
*_issuedDate = nsnull;
nsresult rv;
PRTime beforeTime;
nsCOMPtr<nsIX509CertValidity> validity;
rv = this->GetValidity(getter_AddRefs(validity));
if (NS_FAILED(rv)) return rv;
rv = validity->GetNotBefore(&beforeTime);
if (NS_FAILED(rv)) return rv;
return GetSortableDate(beforeTime, _issuedDate);
}
/* readonly attribute wstring expiresDate; */
NS_IMETHODIMP
nsNSSCertificate::GetExpiresDate(PRUnichar **_expiresDate)
@ -1308,6 +1338,22 @@ nsNSSCertificate::GetExpiresDate(PRUnichar **_expiresDate)
return NS_OK;
}
/* readonly attribute wstring expiresDateSortable; */
NS_IMETHODIMP
nsNSSCertificate::GetExpiresDateSortable(PRUnichar **_expiresDate)
{
NS_ENSURE_ARG(_expiresDate);
*_expiresDate = nsnull;
nsresult rv;
PRTime afterTime;
nsCOMPtr<nsIX509CertValidity> validity;
rv = this->GetValidity(getter_AddRefs(validity));
if (NS_FAILED(rv)) return rv;
rv = validity->GetNotAfter(&afterTime);
if (NS_FAILED(rv)) return rv;
return GetSortableDate(afterTime, _expiresDate);
}
NS_IMETHODIMP
nsNSSCertificate::GetTokenName(PRUnichar **aTokenName)
{

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

@ -80,6 +80,7 @@ private:
nsresult CreateASN1Struct();
nsresult CreateTBSCertificateASN1Struct(nsIASN1Sequence **retSequence,
nsINSSComponent *nssComponent);
nsresult GetSortableDate(PRTime aTime, PRUnichar **_aSortableDate);
};
/* Header file */