LCOV - code coverage report
Current view: top level - security/manager/ssl - nsCertTree.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 683 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 88 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       3             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       4             : 
       5             : #include "nsCertTree.h"
       6             : 
       7             : #include "ScopedNSSTypes.h"
       8             : #include "mozilla/Logging.h"
       9             : #include "nsArray.h"
      10             : #include "nsArrayUtils.h"
      11             : #include "nsHashKeys.h"
      12             : #include "nsISupportsPrimitives.h"
      13             : #include "nsITreeColumns.h"
      14             : #include "nsIX509CertDB.h"
      15             : #include "nsIX509Cert.h"
      16             : #include "nsIX509CertValidity.h"
      17             : #include "nsNSSCertHelper.h"
      18             : #include "nsNSSCertificate.h"
      19             : #include "nsNSSComponent.h" // for PIPNSS string bundle calls.
      20             : #include "nsNSSHelper.h"
      21             : #include "nsReadableUtils.h"
      22             : #include "nsTHashtable.h"
      23             : #include "nsUnicharUtils.h"
      24             : #include "nsXPCOMCID.h"
      25             : #include "nsXPIDLString.h"
      26             : #include "pkix/pkixtypes.h"
      27             : 
      28             : using namespace mozilla;
      29             : 
      30             : extern LazyLogModule gPIPNSSLog;
      31             : 
      32             : static NS_DEFINE_CID(kCertOverrideCID, NS_CERTOVERRIDE_CID);
      33             : 
      34             : // treeArrayElStr
      35             : //
      36             : // structure used to hold map of tree.  Each thread (an organization
      37             : // field from a cert) has an element in the array.  The numChildren field
      38             : // stores the number of certs corresponding to that thread.
      39           0 : struct treeArrayElStr {
      40             :   nsString   orgName;     /* heading for thread                   */
      41             :   bool       open;        /* toggle open state for thread         */
      42             :   int32_t    certIndex;   /* index into cert array for 1st cert   */
      43             :   int32_t    numChildren; /* number of chidren (certs) for thread */
      44             : };
      45             : 
      46           0 : CompareCacheHashEntryPtr::CompareCacheHashEntryPtr()
      47             : {
      48           0 :   entry = new CompareCacheHashEntry;
      49           0 : }
      50             : 
      51           0 : CompareCacheHashEntryPtr::~CompareCacheHashEntryPtr()
      52             : {
      53           0 :   delete entry;
      54           0 : }
      55             : 
      56           0 : CompareCacheHashEntry::CompareCacheHashEntry()
      57           0 : :key(nullptr)
      58             : {
      59           0 :   for (int i = 0; i < max_criterions; ++i) {
      60           0 :     mCritInit[i] = false;
      61             :   }
      62           0 : }
      63             : 
      64             : static bool
      65           0 : CompareCacheMatchEntry(const PLDHashEntryHdr *hdr, const void *key)
      66             : {
      67           0 :   const CompareCacheHashEntryPtr *entryPtr = static_cast<const CompareCacheHashEntryPtr*>(hdr);
      68           0 :   return entryPtr->entry->key == key;
      69             : }
      70             : 
      71             : static void
      72           0 : CompareCacheInitEntry(PLDHashEntryHdr *hdr, const void *key)
      73             : {
      74           0 :   new (hdr) CompareCacheHashEntryPtr();
      75           0 :   CompareCacheHashEntryPtr *entryPtr = static_cast<CompareCacheHashEntryPtr*>(hdr);
      76           0 :   entryPtr->entry->key = (void*)key;
      77           0 : }
      78             : 
      79             : static void
      80           0 : CompareCacheClearEntry(PLDHashTable *table, PLDHashEntryHdr *hdr)
      81             : {
      82           0 :   CompareCacheHashEntryPtr *entryPtr = static_cast<CompareCacheHashEntryPtr*>(hdr);
      83           0 :   entryPtr->~CompareCacheHashEntryPtr();
      84           0 : }
      85             : 
      86             : static const PLDHashTableOps gMapOps = {
      87             :   PLDHashTable::HashVoidPtrKeyStub,
      88             :   CompareCacheMatchEntry,
      89             :   PLDHashTable::MoveEntryStub,
      90             :   CompareCacheClearEntry,
      91             :   CompareCacheInitEntry
      92             : };
      93             : 
      94           0 : NS_IMPL_ISUPPORTS0(nsCertAddonInfo)
      95           0 : NS_IMPL_ISUPPORTS(nsCertTreeDispInfo, nsICertTreeItem)
      96             : 
      97           0 : nsCertTreeDispInfo::nsCertTreeDispInfo()
      98             :   : mAddonInfo(nullptr)
      99             :   , mTypeOfEntry(direct_db)
     100             :   , mPort(-1)
     101             :   , mOverrideBits(nsCertOverride::OverrideBits::None)
     102           0 :   , mIsTemporary(true)
     103             : {
     104           0 : }
     105             : 
     106           0 : nsCertTreeDispInfo::nsCertTreeDispInfo(nsCertTreeDispInfo &other)
     107             : {
     108           0 :   mAddonInfo = other.mAddonInfo;
     109           0 :   mTypeOfEntry = other.mTypeOfEntry;
     110           0 :   mAsciiHost = other.mAsciiHost;
     111           0 :   mPort = other.mPort;
     112           0 :   mOverrideBits = other.mOverrideBits;
     113           0 :   mIsTemporary = other.mIsTemporary;
     114           0 :   mCert = other.mCert;
     115           0 : }
     116             : 
     117           0 : nsCertTreeDispInfo::~nsCertTreeDispInfo()
     118             : {
     119           0 : }
     120             : 
     121             : NS_IMETHODIMP
     122           0 : nsCertTreeDispInfo::GetCert(nsIX509Cert **_cert)
     123             : {
     124           0 :   NS_ENSURE_ARG(_cert);
     125           0 :   if (mCert) {
     126             :     // we may already have the cert for temporary overrides
     127           0 :     *_cert = mCert;
     128           0 :     NS_IF_ADDREF(*_cert);
     129           0 :     return NS_OK;
     130             :   }
     131           0 :   if (mAddonInfo) {
     132           0 :     *_cert = mAddonInfo->mCert.get();
     133           0 :     NS_IF_ADDREF(*_cert);
     134             :   }
     135             :   else {
     136           0 :     *_cert = nullptr;
     137             :   }
     138           0 :   return NS_OK;
     139             : }
     140             : 
     141             : NS_IMETHODIMP
     142           0 : nsCertTreeDispInfo::GetHostPort(nsAString &aHostPort)
     143             : {
     144           0 :   nsAutoCString hostPort;
     145           0 :   nsCertOverrideService::GetHostWithPort(mAsciiHost, mPort, hostPort);
     146           0 :   aHostPort = NS_ConvertUTF8toUTF16(hostPort);
     147           0 :   return NS_OK;
     148             : }
     149             : 
     150           0 : NS_IMPL_ISUPPORTS(nsCertTree, nsICertTree, nsITreeView)
     151             : 
     152           0 : nsCertTree::nsCertTree()
     153             :   : mTreeArray(nullptr)
     154             :   , mCompareCache(&gMapOps, sizeof(CompareCacheHashEntryPtr),
     155           0 :                   kInitialCacheLength)
     156             : {
     157             :   static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
     158             : 
     159           0 :   mNSSComponent = do_GetService(kNSSComponentCID);
     160           0 :   mOverrideService = do_GetService("@mozilla.org/security/certoverride;1");
     161             :   // Might be a different service if someone is overriding the contract
     162             :   nsCOMPtr<nsICertOverrideService> origCertOverride =
     163           0 :     do_GetService(kCertOverrideCID);
     164             :   mOriginalOverrideService =
     165           0 :     static_cast<nsCertOverrideService*>(origCertOverride.get());
     166           0 :   mCellText = nullptr;
     167           0 : }
     168             : 
     169           0 : void nsCertTree::ClearCompareHash()
     170             : {
     171           0 :   mCompareCache.ClearAndPrepareForLength(kInitialCacheLength);
     172           0 : }
     173             : 
     174           0 : nsCertTree::~nsCertTree()
     175             : {
     176           0 :   delete [] mTreeArray;
     177           0 : }
     178             : 
     179             : void
     180           0 : nsCertTree::FreeCertArray()
     181             : {
     182           0 :   mDispInfo.Clear();
     183           0 : }
     184             : 
     185             : CompareCacheHashEntry*
     186           0 : nsCertTree::getCacheEntry(void* cache, void* aCert)
     187             : {
     188           0 :   PLDHashTable& aCompareCache = *static_cast<PLDHashTable*>(cache);
     189             :   auto entryPtr = static_cast<CompareCacheHashEntryPtr*>
     190           0 :                              (aCompareCache.Add(aCert, fallible));
     191           0 :   return entryPtr ? entryPtr->entry : nullptr;
     192             : }
     193             : 
     194           0 : void nsCertTree::RemoveCacheEntry(void *key)
     195             : {
     196           0 :   mCompareCache.Remove(key);
     197           0 : }
     198             : 
     199             : // CountOrganizations
     200             : //
     201             : // Count the number of different organizations encountered in the cert
     202             : // list.
     203             : int32_t
     204           0 : nsCertTree::CountOrganizations()
     205             : {
     206             :   uint32_t i, certCount;
     207           0 :   certCount = mDispInfo.Length();
     208           0 :   if (certCount == 0) return 0;
     209           0 :   nsCOMPtr<nsIX509Cert> orgCert = nullptr;
     210           0 :   nsCertAddonInfo *addonInfo = mDispInfo.ElementAt(0)->mAddonInfo;
     211           0 :   if (addonInfo) {
     212           0 :     orgCert = addonInfo->mCert;
     213             :   }
     214           0 :   nsCOMPtr<nsIX509Cert> nextCert = nullptr;
     215           0 :   int32_t orgCount = 1;
     216           0 :   for (i=1; i<certCount; i++) {
     217           0 :     nextCert = nullptr;
     218           0 :     addonInfo = mDispInfo.SafeElementAt(i, nullptr)->mAddonInfo;
     219           0 :     if (addonInfo) {
     220           0 :       nextCert = addonInfo->mCert;
     221             :     }
     222             :     // XXX we assume issuer org is always criterion 1
     223           0 :     if (CmpBy(&mCompareCache, orgCert, nextCert, sort_IssuerOrg, sort_None, sort_None) != 0) {
     224           0 :       orgCert = nextCert;
     225           0 :       orgCount++;
     226             :     }
     227             :   }
     228           0 :   return orgCount;
     229             : }
     230             : 
     231             : // GetThreadDescAtIndex
     232             : //
     233             : // If the row at index is an organization thread, return the collection
     234             : // associated with that thread.  Otherwise, return null.
     235             : treeArrayEl *
     236           0 : nsCertTree::GetThreadDescAtIndex(int32_t index)
     237             : {
     238           0 :   int i, idx=0;
     239           0 :   if (index < 0) return nullptr;
     240           0 :   for (i=0; i<mNumOrgs; i++) {
     241           0 :     if (index == idx) {
     242           0 :       return &mTreeArray[i];
     243             :     }
     244           0 :     if (mTreeArray[i].open) {
     245           0 :       idx += mTreeArray[i].numChildren;
     246             :     }
     247           0 :     idx++;
     248           0 :     if (idx > index) break;
     249             :   }
     250           0 :   return nullptr;
     251             : }
     252             : 
     253             : //  GetCertAtIndex
     254             : //
     255             : //  If the row at index is a cert, return that cert.  Otherwise, return null.
     256             : already_AddRefed<nsIX509Cert>
     257           0 : nsCertTree::GetCertAtIndex(int32_t index, int32_t *outAbsoluteCertOffset)
     258             : {
     259             :   RefPtr<nsCertTreeDispInfo> certdi(
     260           0 :     GetDispInfoAtIndex(index, outAbsoluteCertOffset));
     261           0 :   if (!certdi)
     262           0 :     return nullptr;
     263             : 
     264           0 :   nsCOMPtr<nsIX509Cert> ret;
     265           0 :   if (certdi->mCert) {
     266           0 :     ret = certdi->mCert;
     267           0 :   } else if (certdi->mAddonInfo) {
     268           0 :     ret = certdi->mAddonInfo->mCert;
     269             :   }
     270           0 :   return ret.forget();
     271             : }
     272             : 
     273             : //  If the row at index is a cert, return that cert.  Otherwise, return null.
     274             : already_AddRefed<nsCertTreeDispInfo>
     275           0 : nsCertTree::GetDispInfoAtIndex(int32_t index,
     276             :                                int32_t *outAbsoluteCertOffset)
     277             : {
     278           0 :   int i, idx = 0, cIndex = 0, nc;
     279           0 :   if (index < 0) return nullptr;
     280             :   // Loop over the threads
     281           0 :   for (i=0; i<mNumOrgs; i++) {
     282           0 :     if (index == idx) return nullptr; // index is for thread
     283           0 :     idx++; // get past the thread
     284           0 :     nc = (mTreeArray[i].open) ? mTreeArray[i].numChildren : 0;
     285           0 :     if (index < idx + nc) { // cert is within range of this thread
     286           0 :       int32_t certIndex = cIndex + index - idx;
     287           0 :       if (outAbsoluteCertOffset)
     288           0 :         *outAbsoluteCertOffset = certIndex;
     289             :       RefPtr<nsCertTreeDispInfo> certdi(mDispInfo.SafeElementAt(certIndex,
     290           0 :                                                                 nullptr));
     291           0 :       if (certdi) {
     292           0 :         return certdi.forget();
     293             :       }
     294           0 :       break;
     295             :     }
     296           0 :     if (mTreeArray[i].open)
     297           0 :       idx += mTreeArray[i].numChildren;
     298           0 :     cIndex += mTreeArray[i].numChildren;
     299           0 :     if (idx > index) break;
     300             :   }
     301           0 :   return nullptr;
     302             : }
     303             : 
     304             : nsCertTree::nsCertCompareFunc
     305           0 : nsCertTree::GetCompareFuncFromCertType(uint32_t aType)
     306             : {
     307           0 :   switch (aType) {
     308             :     case nsIX509Cert::ANY_CERT:
     309             :     case nsIX509Cert::USER_CERT:
     310           0 :       return CmpUserCert;
     311             :     case nsIX509Cert::CA_CERT:
     312           0 :       return CmpCACert;
     313             :     case nsIX509Cert::EMAIL_CERT:
     314           0 :       return CmpEmailCert;
     315             :     case nsIX509Cert::SERVER_CERT:
     316             :     default:
     317           0 :       return CmpWebSiteCert;
     318             :   }
     319             : }
     320             : 
     321           0 : struct nsCertAndArrayAndPositionAndCounterAndTracker
     322             : {
     323             :   RefPtr<nsCertAddonInfo> certai;
     324             :   nsTArray< RefPtr<nsCertTreeDispInfo> > *array;
     325             :   int position;
     326             :   int counter;
     327             :   nsTHashtable<nsCStringHashKey> *tracker;
     328             : };
     329             : 
     330             : // Used to enumerate host:port overrides that match a stored
     331             : // certificate, creates and adds a display-info-object to the
     332             : // provided array. Increments insert position and entry counter.
     333             : // We remove the given key from the tracker, which is used to
     334             : // track entries that have not yet been handled.
     335             : // The created display-info references the cert, so make a note
     336             : // of that by incrementing the cert usage counter.
     337             : static void
     338           0 : MatchingCertOverridesCallback(const nsCertOverride &aSettings,
     339             :                               void *aUserData)
     340             : {
     341             :   nsCertAndArrayAndPositionAndCounterAndTracker *cap =
     342           0 :     (nsCertAndArrayAndPositionAndCounterAndTracker*)aUserData;
     343           0 :   if (!cap)
     344           0 :     return;
     345             : 
     346           0 :   nsCertTreeDispInfo *certdi = new nsCertTreeDispInfo;
     347           0 :   if (certdi) {
     348           0 :     if (cap->certai)
     349           0 :       cap->certai->mUsageCount++;
     350           0 :     certdi->mAddonInfo = cap->certai;
     351           0 :     certdi->mTypeOfEntry = nsCertTreeDispInfo::host_port_override;
     352           0 :     certdi->mAsciiHost = aSettings.mAsciiHost;
     353           0 :     certdi->mPort = aSettings.mPort;
     354           0 :     certdi->mOverrideBits = aSettings.mOverrideBits;
     355           0 :     certdi->mIsTemporary = aSettings.mIsTemporary;
     356           0 :     certdi->mCert = aSettings.mCert;
     357           0 :     cap->array->InsertElementAt(cap->position, certdi);
     358           0 :     cap->position++;
     359           0 :     cap->counter++;
     360             :   }
     361             : 
     362             :   // this entry is now associated to a displayed cert, remove
     363             :   // it from the list of remaining entries
     364           0 :   nsAutoCString hostPort;
     365           0 :   nsCertOverrideService::GetHostWithPort(aSettings.mAsciiHost, aSettings.mPort, hostPort);
     366           0 :   cap->tracker->RemoveEntry(hostPort);
     367             : }
     368             : 
     369             : // Used to collect a list of the (unique) host:port keys
     370             : // for all stored overrides.
     371             : static void
     372           0 : CollectAllHostPortOverridesCallback(const nsCertOverride &aSettings,
     373             :                                     void *aUserData)
     374             : {
     375             :   nsTHashtable<nsCStringHashKey> *collectorTable =
     376           0 :     (nsTHashtable<nsCStringHashKey> *)aUserData;
     377           0 :   if (!collectorTable)
     378           0 :     return;
     379             : 
     380           0 :   nsAutoCString hostPort;
     381           0 :   nsCertOverrideService::GetHostWithPort(aSettings.mAsciiHost, aSettings.mPort, hostPort);
     382           0 :   collectorTable->PutEntry(hostPort);
     383             : }
     384             : 
     385             : struct nsArrayAndPositionAndCounterAndTracker
     386             : {
     387             :   nsTArray< RefPtr<nsCertTreeDispInfo> > *array;
     388             :   int position;
     389             :   int counter;
     390             :   nsTHashtable<nsCStringHashKey> *tracker;
     391             : };
     392             : 
     393             : // Used when enumerating the stored host:port overrides where
     394             : // no associated certificate was found in the NSS database.
     395             : static void
     396           0 : AddRemaningHostPortOverridesCallback(const nsCertOverride &aSettings,
     397             :                                      void *aUserData)
     398             : {
     399             :   nsArrayAndPositionAndCounterAndTracker *cap =
     400           0 :     (nsArrayAndPositionAndCounterAndTracker*)aUserData;
     401           0 :   if (!cap)
     402           0 :     return;
     403             : 
     404           0 :   nsAutoCString hostPort;
     405           0 :   nsCertOverrideService::GetHostWithPort(aSettings.mAsciiHost, aSettings.mPort, hostPort);
     406           0 :   if (!cap->tracker->GetEntry(hostPort))
     407           0 :     return;
     408             : 
     409             :   // This entry is not associated to any stored cert,
     410             :   // so we still need to display it.
     411             : 
     412           0 :   nsCertTreeDispInfo *certdi = new nsCertTreeDispInfo;
     413           0 :   if (certdi) {
     414           0 :     certdi->mAddonInfo = nullptr;
     415           0 :     certdi->mTypeOfEntry = nsCertTreeDispInfo::host_port_override;
     416           0 :     certdi->mAsciiHost = aSettings.mAsciiHost;
     417           0 :     certdi->mPort = aSettings.mPort;
     418           0 :     certdi->mOverrideBits = aSettings.mOverrideBits;
     419           0 :     certdi->mIsTemporary = aSettings.mIsTemporary;
     420           0 :     certdi->mCert = aSettings.mCert;
     421           0 :     cap->array->InsertElementAt(cap->position, certdi);
     422           0 :     cap->position++;
     423           0 :     cap->counter++;
     424             :   }
     425             : }
     426             : 
     427             : nsresult
     428           0 : nsCertTree::GetCertsByTypeFromCertList(CERTCertList *aCertList,
     429             :                                        uint32_t aWantedType,
     430             :                                        nsCertCompareFunc  aCertCmpFn,
     431             :                                        void *aCertCmpFnArg)
     432             : {
     433           0 :   MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("GetCertsByTypeFromCertList"));
     434           0 :   if (!aCertList)
     435           0 :     return NS_ERROR_FAILURE;
     436             : 
     437           0 :   if (!mOriginalOverrideService)
     438           0 :     return NS_ERROR_FAILURE;
     439             : 
     440           0 :   nsTHashtable<nsCStringHashKey> allHostPortOverrideKeys;
     441             : 
     442           0 :   if (aWantedType == nsIX509Cert::SERVER_CERT) {
     443             :     mOriginalOverrideService->
     444           0 :       EnumerateCertOverrides(nullptr,
     445             :                              CollectAllHostPortOverridesCallback,
     446           0 :                              &allHostPortOverrideKeys);
     447             :   }
     448             : 
     449             :   CERTCertListNode *node;
     450           0 :   int count = 0;
     451           0 :   for (node = CERT_LIST_HEAD(aCertList);
     452           0 :        !CERT_LIST_END(node, aCertList);
     453           0 :        node = CERT_LIST_NEXT(node)) {
     454             : 
     455           0 :     bool wantThisCert = (aWantedType == nsIX509Cert::ANY_CERT);
     456           0 :     bool wantThisCertIfNoOverrides = false;
     457           0 :     bool wantThisCertIfHaveOverrides = false;
     458           0 :     bool addOverrides = false;
     459             : 
     460           0 :     if (!wantThisCert) {
     461           0 :       uint32_t thisCertType = getCertType(node->cert);
     462             : 
     463             :       // The output from getCertType is a "guess", which can be wrong.
     464             :       // The guess is based on stored trust flags, but for the host:port
     465             :       // overrides, we are storing certs without any trust flags associated.
     466             :       // So we must check whether the cert really belongs to the
     467             :       // server, email or unknown tab. We will lookup the cert in the override
     468             :       // list to come to the decision. Unfortunately, the lookup in the
     469             :       // override list is quite expensive. Therefore we are using this
     470             :       // lengthy if/else statement to minimize
     471             :       // the number of override-list-lookups.
     472             : 
     473           0 :       if (aWantedType == nsIX509Cert::SERVER_CERT
     474           0 :           && thisCertType == nsIX509Cert::UNKNOWN_CERT) {
     475             :         // This unknown cert was stored without trust
     476             :         // Are there host:port based overrides stored?
     477             :         // If yes, display them.
     478           0 :         addOverrides = true;
     479             :       }
     480             :       else
     481           0 :       if (aWantedType == nsIX509Cert::UNKNOWN_CERT
     482           0 :           && thisCertType == nsIX509Cert::UNKNOWN_CERT) {
     483             :         // This unknown cert was stored without trust.
     484             :         // If there are associated overrides, do not show as unknown.
     485             :         // If there are no associated overrides, display as unknown.
     486           0 :         wantThisCertIfNoOverrides = true;
     487             :       }
     488             :       else
     489           0 :       if (aWantedType == nsIX509Cert::SERVER_CERT
     490           0 :           && thisCertType == nsIX509Cert::SERVER_CERT) {
     491             :         // This server cert is explicitly marked as a web site peer,
     492             :         // with or without trust, but editable, so show it
     493           0 :         wantThisCert = true;
     494             :         // Are there host:port based overrides stored?
     495             :         // If yes, display them.
     496           0 :         addOverrides = true;
     497             :       }
     498             :       else
     499           0 :       if (aWantedType == nsIX509Cert::SERVER_CERT
     500           0 :           && thisCertType == nsIX509Cert::EMAIL_CERT) {
     501             :         // This cert might have been categorized as an email cert
     502             :         // because it carries an email address. But is it really one?
     503             :         // Our cert categorization is uncertain when it comes to
     504             :         // distinguish between email certs and web site certs.
     505             :         // So, let's see if we have an override for that cert
     506             :         // and if there is, conclude it's really a web site cert.
     507           0 :         addOverrides = true;
     508             :       }
     509             :       else
     510           0 :       if (aWantedType == nsIX509Cert::EMAIL_CERT
     511           0 :           && thisCertType == nsIX509Cert::EMAIL_CERT) {
     512             :         // This cert might have been categorized as an email cert
     513             :         // because it carries an email address. But is it really one?
     514             :         // Our cert categorization is uncertain when it comes to
     515             :         // distinguish between email certs and web site certs.
     516             :         // So, let's see if we have an override for that cert
     517             :         // and if there is, conclude it's really a web site cert.
     518           0 :         wantThisCertIfNoOverrides = true;
     519             :       }
     520             :       else
     521           0 :       if (thisCertType == aWantedType) {
     522           0 :         wantThisCert = true;
     523             :       }
     524             :     }
     525             : 
     526           0 :     nsCOMPtr<nsIX509Cert> pipCert = nsNSSCertificate::Create(node->cert);
     527           0 :     if (!pipCert)
     528           0 :       return NS_ERROR_OUT_OF_MEMORY;
     529             : 
     530           0 :     if (wantThisCertIfNoOverrides || wantThisCertIfHaveOverrides) {
     531           0 :       uint32_t ocount = 0;
     532             :       nsresult rv =
     533           0 :         mOverrideService->IsCertUsedForOverrides(pipCert,
     534             :                                                  true, // we want temporaries
     535             :                                                  true, // we want permanents
     536           0 :                                                  &ocount);
     537           0 :       if (wantThisCertIfNoOverrides) {
     538           0 :         if (NS_FAILED(rv) || ocount == 0) {
     539             :           // no overrides for this cert
     540           0 :           wantThisCert = true;
     541             :         }
     542             :       }
     543             : 
     544           0 :       if (wantThisCertIfHaveOverrides) {
     545           0 :         if (NS_SUCCEEDED(rv) && ocount > 0) {
     546             :           // there are overrides for this cert
     547           0 :           wantThisCert = true;
     548             :         }
     549             :       }
     550             :     }
     551             : 
     552           0 :     RefPtr<nsCertAddonInfo> certai(new nsCertAddonInfo);
     553           0 :     certai->mCert = pipCert;
     554           0 :     certai->mUsageCount = 0;
     555             : 
     556           0 :     if (wantThisCert || addOverrides) {
     557           0 :       int InsertPosition = 0;
     558           0 :       for (; InsertPosition < count; ++InsertPosition) {
     559           0 :         nsCOMPtr<nsIX509Cert> cert = nullptr;
     560             :         RefPtr<nsCertTreeDispInfo> elem(
     561           0 :           mDispInfo.SafeElementAt(InsertPosition, nullptr));
     562           0 :         if (elem && elem->mAddonInfo) {
     563           0 :           cert = elem->mAddonInfo->mCert;
     564             :         }
     565           0 :         if ((*aCertCmpFn)(aCertCmpFnArg, pipCert, cert) < 0) {
     566           0 :           break;
     567             :         }
     568             :       }
     569           0 :       if (wantThisCert) {
     570           0 :         nsCertTreeDispInfo *certdi = new nsCertTreeDispInfo;
     571           0 :         certdi->mAddonInfo = certai;
     572           0 :         certai->mUsageCount++;
     573           0 :         certdi->mTypeOfEntry = nsCertTreeDispInfo::direct_db;
     574             :         // not necessary: certdi->mAsciiHost.Clear(); certdi->mPort = -1;
     575           0 :         certdi->mOverrideBits = nsCertOverride::OverrideBits::None;
     576           0 :         certdi->mIsTemporary = false;
     577           0 :         mDispInfo.InsertElementAt(InsertPosition, certdi);
     578           0 :         ++count;
     579           0 :         ++InsertPosition;
     580             :       }
     581           0 :       if (addOverrides) {
     582           0 :         nsCertAndArrayAndPositionAndCounterAndTracker cap;
     583           0 :         cap.certai = certai;
     584           0 :         cap.array = &mDispInfo;
     585           0 :         cap.position = InsertPosition;
     586           0 :         cap.counter = 0;
     587           0 :         cap.tracker = &allHostPortOverrideKeys;
     588             : 
     589             :         mOriginalOverrideService->
     590           0 :           EnumerateCertOverrides(pipCert, MatchingCertOverridesCallback, &cap);
     591           0 :         count += cap.counter;
     592             :       }
     593             :     }
     594             :   }
     595             : 
     596           0 :   if (aWantedType == nsIX509Cert::SERVER_CERT) {
     597             :     nsArrayAndPositionAndCounterAndTracker cap;
     598           0 :     cap.array = &mDispInfo;
     599           0 :     cap.position = 0;
     600           0 :     cap.counter = 0;
     601           0 :     cap.tracker = &allHostPortOverrideKeys;
     602             :     mOriginalOverrideService->
     603           0 :       EnumerateCertOverrides(nullptr, AddRemaningHostPortOverridesCallback, &cap);
     604             :   }
     605             : 
     606           0 :   return NS_OK;
     607             : }
     608             : 
     609             : nsresult
     610           0 : nsCertTree::GetCertsByType(uint32_t           aType,
     611             :                            nsCertCompareFunc  aCertCmpFn,
     612             :                            void              *aCertCmpFnArg)
     613             : {
     614           0 :   nsNSSShutDownPreventionLock locker;
     615           0 :   nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
     616           0 :   UniqueCERTCertList certList(PK11_ListCerts(PK11CertListUnique, cxt));
     617           0 :   return GetCertsByTypeFromCertList(certList.get(), aType, aCertCmpFn,
     618           0 :                                     aCertCmpFnArg);
     619             : }
     620             : 
     621             : nsresult
     622           0 : nsCertTree::GetCertsByTypeFromCache(nsIX509CertList   *aCache,
     623             :                                     uint32_t           aType,
     624             :                                     nsCertCompareFunc  aCertCmpFn,
     625             :                                     void              *aCertCmpFnArg)
     626             : {
     627           0 :   NS_ENSURE_ARG_POINTER(aCache);
     628             :   // GetRawCertList checks for NSS shutdown since we can't do it ourselves here
     629             :   // easily. We still have to acquire a shutdown prevention lock to prevent NSS
     630             :   // shutting down after GetRawCertList has returned. While cumbersome, this is
     631             :   // at least mostly correct. The rest of this implementation doesn't even go
     632             :   // this far in attempting to check for or prevent NSS shutdown at the
     633             :   // appropriate times. If this were reimplemented at a higher level using
     634             :   // more encapsulated types that handled NSS shutdown themselves, we wouldn't
     635             :   // be having these kinds of problems.
     636           0 :   nsNSSShutDownPreventionLock locker;
     637           0 :   CERTCertList* certList = aCache->GetRawCertList();
     638           0 :   if (!certList)
     639           0 :     return NS_ERROR_FAILURE;
     640           0 :   return GetCertsByTypeFromCertList(certList, aType, aCertCmpFn, aCertCmpFnArg);
     641             : }
     642             : 
     643             : // LoadCerts
     644             : //
     645             : // Load all of the certificates in the DB for this type.  Sort them
     646             : // by token, organization, then common name.
     647             : NS_IMETHODIMP
     648           0 : nsCertTree::LoadCertsFromCache(nsIX509CertList *aCache, uint32_t aType)
     649             : {
     650           0 :   if (mTreeArray) {
     651           0 :     FreeCertArray();
     652           0 :     delete [] mTreeArray;
     653           0 :     mTreeArray = nullptr;
     654           0 :     mNumRows = 0;
     655             :   }
     656           0 :   ClearCompareHash();
     657             : 
     658           0 :   nsresult rv = GetCertsByTypeFromCache(aCache, aType,
     659             :                                         GetCompareFuncFromCertType(aType),
     660           0 :                                         &mCompareCache);
     661           0 :   if (NS_FAILED(rv)) return rv;
     662           0 :   return UpdateUIContents();
     663             : }
     664             : 
     665             : NS_IMETHODIMP
     666           0 : nsCertTree::LoadCerts(uint32_t aType)
     667             : {
     668           0 :   if (mTreeArray) {
     669           0 :     FreeCertArray();
     670           0 :     delete [] mTreeArray;
     671           0 :     mTreeArray = nullptr;
     672           0 :     mNumRows = 0;
     673             :   }
     674           0 :   ClearCompareHash();
     675             : 
     676           0 :   nsresult rv = GetCertsByType(aType, GetCompareFuncFromCertType(aType),
     677           0 :                                &mCompareCache);
     678           0 :   if (NS_FAILED(rv)) return rv;
     679           0 :   return UpdateUIContents();
     680             : }
     681             : 
     682             : nsresult
     683           0 : nsCertTree::UpdateUIContents()
     684             : {
     685           0 :   uint32_t count = mDispInfo.Length();
     686           0 :   mNumOrgs = CountOrganizations();
     687           0 :   mTreeArray = new treeArrayEl[mNumOrgs];
     688             : 
     689           0 :   mCellText = nsArrayBase::Create();
     690             : 
     691           0 : if (count) {
     692           0 :   uint32_t j = 0;
     693           0 :   nsCOMPtr<nsIX509Cert> orgCert = nullptr;
     694           0 :   nsCertAddonInfo *addonInfo = mDispInfo.ElementAt(j)->mAddonInfo;
     695           0 :   if (addonInfo) {
     696           0 :     orgCert = addonInfo->mCert;
     697             :   }
     698           0 :   for (int32_t i=0; i<mNumOrgs; i++) {
     699           0 :     nsString &orgNameRef = mTreeArray[i].orgName;
     700           0 :     if (!orgCert) {
     701           0 :       mNSSComponent->GetPIPNSSBundleString("CertOrgUnknown", orgNameRef);
     702             :     }
     703             :     else {
     704           0 :       orgCert->GetIssuerOrganization(orgNameRef);
     705           0 :       if (orgNameRef.IsEmpty())
     706           0 :         orgCert->GetCommonName(orgNameRef);
     707             :     }
     708           0 :     mTreeArray[i].open = true;
     709           0 :     mTreeArray[i].certIndex = j;
     710           0 :     mTreeArray[i].numChildren = 1;
     711           0 :     if (++j >= count) break;
     712           0 :     nsCOMPtr<nsIX509Cert> nextCert = nullptr;
     713           0 :     nsCertAddonInfo *addonInfo = mDispInfo.SafeElementAt(j, nullptr)->mAddonInfo;
     714           0 :     if (addonInfo) {
     715           0 :       nextCert = addonInfo->mCert;
     716             :     }
     717           0 :     while (0 == CmpBy(&mCompareCache, orgCert, nextCert, sort_IssuerOrg, sort_None, sort_None)) {
     718           0 :       mTreeArray[i].numChildren++;
     719           0 :       if (++j >= count) break;
     720           0 :       nextCert = nullptr;
     721           0 :       addonInfo = mDispInfo.SafeElementAt(j, nullptr)->mAddonInfo;
     722           0 :       if (addonInfo) {
     723           0 :         nextCert = addonInfo->mCert;
     724             :       }
     725             :     }
     726           0 :     orgCert = nextCert;
     727             :   }
     728             : }
     729           0 :   if (mTree) {
     730           0 :     mTree->BeginUpdateBatch();
     731           0 :     mTree->RowCountChanged(0, -mNumRows);
     732             :   }
     733           0 :   mNumRows = count + mNumOrgs;
     734           0 :   if (mTree)
     735           0 :     mTree->EndUpdateBatch();
     736           0 :   return NS_OK;
     737             : }
     738             : 
     739             : NS_IMETHODIMP
     740           0 : nsCertTree::DeleteEntryObject(uint32_t index)
     741             : {
     742           0 :   if (!mTreeArray) {
     743           0 :     return NS_ERROR_FAILURE;
     744             :   }
     745             : 
     746             :   nsCOMPtr<nsIX509CertDB> certdb =
     747           0 :     do_GetService("@mozilla.org/security/x509certdb;1");
     748           0 :   if (!certdb) {
     749           0 :     return NS_ERROR_FAILURE;
     750             :   }
     751             : 
     752             :   int i;
     753           0 :   uint32_t idx = 0, cIndex = 0, nc;
     754             :   // Loop over the threads
     755           0 :   for (i=0; i<mNumOrgs; i++) {
     756           0 :     if (index == idx)
     757           0 :       return NS_OK; // index is for thread
     758           0 :     idx++; // get past the thread
     759           0 :     nc = (mTreeArray[i].open) ? mTreeArray[i].numChildren : 0;
     760           0 :     if (index < idx + nc) { // cert is within range of this thread
     761           0 :       int32_t certIndex = cIndex + index - idx;
     762             : 
     763           0 :       bool canRemoveEntry = false;
     764             :       RefPtr<nsCertTreeDispInfo> certdi(mDispInfo.SafeElementAt(certIndex,
     765           0 :                                                                 nullptr));
     766             : 
     767             :       // We will remove the element from the visual tree.
     768             :       // Only if we have a certdi, then we can check for additional actions.
     769           0 :       nsCOMPtr<nsIX509Cert> cert = nullptr;
     770           0 :       if (certdi) {
     771           0 :         if (certdi->mAddonInfo) {
     772           0 :           cert = certdi->mAddonInfo->mCert;
     773             :         }
     774             :         nsCertAddonInfo* addonInfo =
     775           0 :           certdi->mAddonInfo ? certdi->mAddonInfo.get() : nullptr;
     776           0 :         if (certdi->mTypeOfEntry == nsCertTreeDispInfo::host_port_override) {
     777           0 :           mOverrideService->ClearValidityOverride(certdi->mAsciiHost, certdi->mPort);
     778           0 :           if (addonInfo) {
     779           0 :             addonInfo->mUsageCount--;
     780           0 :             if (addonInfo->mUsageCount == 0) {
     781             :               // The certificate stored in the database is no longer
     782             :               // referenced by any other object displayed.
     783             :               // That means we no longer need to keep it around
     784             :               // and really can remove it.
     785           0 :               canRemoveEntry = true;
     786             :             }
     787             :           }
     788             :         }
     789             :         else {
     790           0 :           if (addonInfo && addonInfo->mUsageCount > 1) {
     791             :             // user is trying to delete a perm trusted cert,
     792             :             // although there are still overrides stored,
     793             :             // so, we keep the cert, but remove the trust
     794             : 
     795           0 :             UniqueCERTCertificate nsscert(cert->GetCert());
     796             : 
     797           0 :             if (nsscert) {
     798             :               CERTCertTrust trust;
     799           0 :               memset((void*)&trust, 0, sizeof(trust));
     800             : 
     801           0 :               SECStatus srv = CERT_DecodeTrustString(&trust, ""); // no override
     802           0 :               if (srv == SECSuccess) {
     803           0 :                 CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nsscert.get(),
     804           0 :                                      &trust);
     805             :               }
     806           0 :             }
     807             :           }
     808             :           else {
     809           0 :             canRemoveEntry = true;
     810             :           }
     811             :         }
     812             :       }
     813             : 
     814           0 :       mDispInfo.RemoveElementAt(certIndex);
     815             : 
     816           0 :       if (canRemoveEntry) {
     817           0 :         RemoveCacheEntry(cert);
     818           0 :         certdb->DeleteCertificate(cert);
     819             :       }
     820             : 
     821           0 :       delete [] mTreeArray;
     822           0 :       mTreeArray = nullptr;
     823           0 :       return UpdateUIContents();
     824             :     }
     825           0 :     if (mTreeArray[i].open)
     826           0 :       idx += mTreeArray[i].numChildren;
     827           0 :     cIndex += mTreeArray[i].numChildren;
     828           0 :     if (idx > index)
     829           0 :       break;
     830             :   }
     831           0 :   return NS_ERROR_FAILURE;
     832             : }
     833             : 
     834             : //////////////////////////////////////////////////////////////////////////////
     835             : //
     836             : //  Begin nsITreeView methods
     837             : //
     838             : /////////////////////////////////////////////////////////////////////////////
     839             : 
     840             : NS_IMETHODIMP
     841           0 : nsCertTree::GetCert(uint32_t aIndex, nsIX509Cert **_cert)
     842             : {
     843           0 :   NS_ENSURE_ARG(_cert);
     844           0 :   *_cert = GetCertAtIndex(aIndex).take();
     845           0 :   return NS_OK;
     846             : }
     847             : 
     848             : NS_IMETHODIMP
     849           0 : nsCertTree::GetTreeItem(uint32_t aIndex, nsICertTreeItem **_treeitem)
     850             : {
     851           0 :   NS_ENSURE_ARG(_treeitem);
     852             : 
     853           0 :   RefPtr<nsCertTreeDispInfo> certdi(GetDispInfoAtIndex(aIndex));
     854           0 :   if (!certdi)
     855           0 :     return NS_ERROR_FAILURE;
     856             : 
     857           0 :   *_treeitem = certdi;
     858           0 :   NS_IF_ADDREF(*_treeitem);
     859           0 :   return NS_OK;
     860             : }
     861             : 
     862             : NS_IMETHODIMP
     863           0 : nsCertTree::GetRowCount(int32_t *aRowCount)
     864             : {
     865           0 :   if (!mTreeArray)
     866           0 :     return NS_ERROR_NOT_INITIALIZED;
     867           0 :   uint32_t count = 0;
     868           0 :   for (int32_t i=0; i<mNumOrgs; i++) {
     869           0 :     if (mTreeArray[i].open) {
     870           0 :       count += mTreeArray[i].numChildren;
     871             :     }
     872           0 :     count++;
     873             :   }
     874           0 :   *aRowCount = count;
     875           0 :   return NS_OK;
     876             : }
     877             : 
     878             : NS_IMETHODIMP
     879           0 : nsCertTree::GetSelection(nsITreeSelection * *aSelection)
     880             : {
     881           0 :   *aSelection = mSelection;
     882           0 :   NS_IF_ADDREF(*aSelection);
     883           0 :   return NS_OK;
     884             : }
     885             : 
     886             : NS_IMETHODIMP
     887           0 : nsCertTree::SetSelection(nsITreeSelection * aSelection)
     888             : {
     889           0 :   mSelection = aSelection;
     890           0 :   return NS_OK;
     891             : }
     892             : 
     893             : NS_IMETHODIMP
     894           0 : nsCertTree::GetRowProperties(int32_t index, nsAString& aProps)
     895             : {
     896           0 :   return NS_OK;
     897             : }
     898             : 
     899             : NS_IMETHODIMP
     900           0 : nsCertTree::GetCellProperties(int32_t row, nsITreeColumn* col,
     901             :                               nsAString& aProps)
     902             : {
     903           0 :   return NS_OK;
     904             : }
     905             : 
     906             : NS_IMETHODIMP
     907           0 : nsCertTree::GetColumnProperties(nsITreeColumn* col, nsAString& aProps)
     908             : {
     909           0 :   return NS_OK;
     910             : }
     911             : NS_IMETHODIMP
     912           0 : nsCertTree::IsContainer(int32_t index, bool *_retval)
     913             : {
     914           0 :   if (!mTreeArray)
     915           0 :     return NS_ERROR_NOT_INITIALIZED;
     916           0 :   treeArrayEl *el = GetThreadDescAtIndex(index);
     917           0 :   if (el) {
     918           0 :     *_retval = true;
     919             :   } else {
     920           0 :     *_retval = false;
     921             :   }
     922           0 :   return NS_OK;
     923             : }
     924             : 
     925             : NS_IMETHODIMP
     926           0 : nsCertTree::IsContainerOpen(int32_t index, bool *_retval)
     927             : {
     928           0 :   if (!mTreeArray)
     929           0 :     return NS_ERROR_NOT_INITIALIZED;
     930           0 :   treeArrayEl *el = GetThreadDescAtIndex(index);
     931           0 :   if (el && el->open) {
     932           0 :     *_retval = true;
     933             :   } else {
     934           0 :     *_retval = false;
     935             :   }
     936           0 :   return NS_OK;
     937             : }
     938             : 
     939             : NS_IMETHODIMP
     940           0 : nsCertTree::IsContainerEmpty(int32_t index, bool *_retval)
     941             : {
     942           0 :   *_retval = !mTreeArray;
     943           0 :   return NS_OK;
     944             : }
     945             : 
     946             : NS_IMETHODIMP
     947           0 : nsCertTree::IsSeparator(int32_t index, bool *_retval)
     948             : {
     949           0 :   *_retval = false;
     950           0 :   return NS_OK;
     951             : }
     952             : 
     953             : NS_IMETHODIMP
     954           0 : nsCertTree::GetParentIndex(int32_t rowIndex, int32_t *_retval)
     955             : {
     956           0 :   if (!mTreeArray)
     957           0 :     return NS_ERROR_NOT_INITIALIZED;
     958           0 :   int i, idx = 0;
     959           0 :   for (i = 0; i < mNumOrgs && idx < rowIndex; i++, idx++) {
     960           0 :     if (mTreeArray[i].open) {
     961           0 :       if (rowIndex <= idx + mTreeArray[i].numChildren) {
     962           0 :         *_retval = idx;
     963           0 :         return NS_OK;
     964             :       }
     965           0 :       idx += mTreeArray[i].numChildren;
     966             :     }
     967             :   }
     968           0 :   *_retval = -1;
     969           0 :   return NS_OK;
     970             : }
     971             : 
     972             : NS_IMETHODIMP
     973           0 : nsCertTree::HasNextSibling(int32_t rowIndex, int32_t afterIndex,
     974             :                                bool *_retval)
     975             : {
     976           0 :   if (!mTreeArray)
     977           0 :     return NS_ERROR_NOT_INITIALIZED;
     978             : 
     979           0 :   int i, idx = 0;
     980           0 :   for (i = 0; i < mNumOrgs && idx <= rowIndex; i++, idx++) {
     981           0 :     if (mTreeArray[i].open) {
     982           0 :       idx += mTreeArray[i].numChildren;
     983           0 :       if (afterIndex <= idx) {
     984           0 :         *_retval = afterIndex < idx;
     985           0 :         return NS_OK;
     986             :       }
     987             :     }
     988             :   }
     989           0 :   *_retval = false;
     990           0 :   return NS_OK;
     991             : }
     992             : 
     993             : NS_IMETHODIMP
     994           0 : nsCertTree::GetLevel(int32_t index, int32_t *_retval)
     995             : {
     996           0 :   if (!mTreeArray)
     997           0 :     return NS_ERROR_NOT_INITIALIZED;
     998           0 :   treeArrayEl *el = GetThreadDescAtIndex(index);
     999           0 :   if (el) {
    1000           0 :     *_retval = 0;
    1001             :   } else {
    1002           0 :     *_retval = 1;
    1003             :   }
    1004           0 :   return NS_OK;
    1005             : }
    1006             : 
    1007             : NS_IMETHODIMP
    1008           0 : nsCertTree::GetImageSrc(int32_t row, nsITreeColumn* col,
    1009             :                         nsAString& _retval)
    1010             : {
    1011           0 :   _retval.Truncate();
    1012           0 :   return NS_OK;
    1013             : }
    1014             : 
    1015             : NS_IMETHODIMP
    1016           0 : nsCertTree::GetProgressMode(int32_t row, nsITreeColumn* col, int32_t* _retval)
    1017             : {
    1018           0 :   return NS_OK;
    1019             : }
    1020             : 
    1021             : NS_IMETHODIMP
    1022           0 : nsCertTree::GetCellValue(int32_t row, nsITreeColumn* col,
    1023             :                          nsAString& _retval)
    1024             : {
    1025           0 :   _retval.Truncate();
    1026           0 :   return NS_OK;
    1027             : }
    1028             : 
    1029             : NS_IMETHODIMP
    1030           0 : nsCertTree::GetCellText(int32_t row, nsITreeColumn* col,
    1031             :                         nsAString& _retval)
    1032             : {
    1033           0 :   if (!mTreeArray)
    1034           0 :     return NS_ERROR_NOT_INITIALIZED;
    1035             : 
    1036           0 :   nsresult rv = NS_OK;
    1037           0 :   _retval.Truncate();
    1038             : 
    1039             :   const char16_t* colID;
    1040           0 :   col->GetIdConst(&colID);
    1041             : 
    1042           0 :   treeArrayEl *el = GetThreadDescAtIndex(row);
    1043           0 :   if (el) {
    1044           0 :     if (NS_LITERAL_STRING("certcol").Equals(colID))
    1045           0 :       _retval.Assign(el->orgName);
    1046             :     else
    1047           0 :       _retval.Truncate();
    1048           0 :     return NS_OK;
    1049             :   }
    1050             : 
    1051             :   int32_t absoluteCertOffset;
    1052           0 :   RefPtr<nsCertTreeDispInfo> certdi(GetDispInfoAtIndex(row, &absoluteCertOffset));
    1053           0 :   if (!certdi)
    1054           0 :     return NS_ERROR_FAILURE;
    1055             : 
    1056           0 :   nsCOMPtr<nsIX509Cert> cert = certdi->mCert;
    1057           0 :   if (!cert && certdi->mAddonInfo) {
    1058           0 :     cert = certdi->mAddonInfo->mCert;
    1059             :   }
    1060             : 
    1061             :   int32_t colIndex;
    1062           0 :   col->GetIndex(&colIndex);
    1063           0 :   uint32_t arrayIndex=absoluteCertOffset+colIndex*(mNumRows-mNumOrgs);
    1064           0 :   uint32_t arrayLength=0;
    1065           0 :   if (mCellText) {
    1066           0 :     mCellText->GetLength(&arrayLength);
    1067             :   }
    1068           0 :   if (arrayIndex < arrayLength) {
    1069           0 :     nsCOMPtr<nsISupportsString> myString(do_QueryElementAt(mCellText, arrayIndex));
    1070           0 :     if (myString) {
    1071           0 :       myString->GetData(_retval);
    1072           0 :       return NS_OK;
    1073             :     }
    1074             :   }
    1075             : 
    1076           0 :   if (NS_LITERAL_STRING("certcol").Equals(colID)) {
    1077           0 :     if (!cert) {
    1078           0 :       rv = mNSSComponent->GetPIPNSSBundleString("CertNotStored", _retval);
    1079             :     } else {
    1080           0 :       rv = cert->GetDisplayName(_retval);
    1081             :     }
    1082           0 :   } else if (NS_LITERAL_STRING("tokencol").Equals(colID) && cert) {
    1083           0 :     rv = cert->GetTokenName(_retval);
    1084           0 :   } else if (NS_LITERAL_STRING("emailcol").Equals(colID) && cert) {
    1085           0 :     rv = cert->GetEmailAddress(_retval);
    1086           0 :   } else if (NS_LITERAL_STRING("issuedcol").Equals(colID) && cert) {
    1087           0 :     nsCOMPtr<nsIX509CertValidity> validity;
    1088             : 
    1089           0 :     rv = cert->GetValidity(getter_AddRefs(validity));
    1090           0 :     if (NS_SUCCEEDED(rv)) {
    1091           0 :       validity->GetNotBeforeLocalDay(_retval);
    1092             :     }
    1093           0 :   } else if (NS_LITERAL_STRING("expiredcol").Equals(colID) && cert) {
    1094           0 :     nsCOMPtr<nsIX509CertValidity> validity;
    1095             : 
    1096           0 :     rv = cert->GetValidity(getter_AddRefs(validity));
    1097           0 :     if (NS_SUCCEEDED(rv)) {
    1098           0 :       validity->GetNotAfterLocalDay(_retval);
    1099             :     }
    1100           0 :   } else if (NS_LITERAL_STRING("serialnumcol").Equals(colID) && cert) {
    1101           0 :     rv = cert->GetSerialNumber(_retval);
    1102           0 :   } else if (NS_LITERAL_STRING("sitecol").Equals(colID)) {
    1103           0 :     if (certdi->mTypeOfEntry == nsCertTreeDispInfo::host_port_override) {
    1104           0 :       nsAutoCString hostPort;
    1105           0 :       nsCertOverrideService::GetHostWithPort(certdi->mAsciiHost, certdi->mPort, hostPort);
    1106           0 :       _retval = NS_ConvertUTF8toUTF16(hostPort);
    1107             :     }
    1108             :     else {
    1109           0 :       _retval = NS_LITERAL_STRING("*");
    1110             :     }
    1111           0 :   } else if (NS_LITERAL_STRING("lifetimecol").Equals(colID)) {
    1112             :     const char *stringID =
    1113           0 :       (certdi->mIsTemporary) ? "CertExceptionTemporary" : "CertExceptionPermanent";
    1114           0 :     rv = mNSSComponent->GetPIPNSSBundleString(stringID, _retval);
    1115             :   } else {
    1116           0 :     return NS_ERROR_FAILURE;
    1117             :   }
    1118           0 :   if (mCellText) {
    1119           0 :     nsCOMPtr<nsISupportsString> text(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv));
    1120           0 :     NS_ENSURE_SUCCESS(rv, rv);
    1121           0 :     text->SetData(_retval);
    1122           0 :     mCellText->ReplaceElementAt(text, arrayIndex, false);
    1123             :   }
    1124           0 :   return rv;
    1125             : }
    1126             : 
    1127             : NS_IMETHODIMP
    1128           0 : nsCertTree::SetTree(nsITreeBoxObject *tree)
    1129             : {
    1130           0 :   mTree = tree;
    1131           0 :   return NS_OK;
    1132             : }
    1133             : 
    1134             : NS_IMETHODIMP
    1135           0 : nsCertTree::ToggleOpenState(int32_t index)
    1136             : {
    1137           0 :   if (!mTreeArray)
    1138           0 :     return NS_ERROR_NOT_INITIALIZED;
    1139           0 :   treeArrayEl *el = GetThreadDescAtIndex(index);
    1140           0 :   if (el) {
    1141           0 :     el->open = !el->open;
    1142           0 :     int32_t newChildren = (el->open) ? el->numChildren : -el->numChildren;
    1143           0 :     if (mTree) mTree->RowCountChanged(index + 1, newChildren);
    1144             :   }
    1145           0 :   return NS_OK;
    1146             : }
    1147             : 
    1148             : NS_IMETHODIMP
    1149           0 : nsCertTree::CycleHeader(nsITreeColumn* col)
    1150             : {
    1151           0 :   return NS_OK;
    1152             : }
    1153             : 
    1154             : NS_IMETHODIMP
    1155           0 : nsCertTree::SelectionChanged()
    1156             : {
    1157           0 :   return NS_ERROR_NOT_IMPLEMENTED;
    1158             : }
    1159             : 
    1160             : NS_IMETHODIMP
    1161           0 : nsCertTree::CycleCell(int32_t row, nsITreeColumn* col)
    1162             : {
    1163           0 :   return NS_OK;
    1164             : }
    1165             : 
    1166             : NS_IMETHODIMP
    1167           0 : nsCertTree::IsEditable(int32_t row, nsITreeColumn* col, bool *_retval)
    1168             : {
    1169           0 :   *_retval = false;
    1170           0 :   return NS_OK;
    1171             : }
    1172             : 
    1173             : NS_IMETHODIMP
    1174           0 : nsCertTree::IsSelectable(int32_t row, nsITreeColumn* col, bool *_retval)
    1175             : {
    1176           0 :   *_retval = false;
    1177           0 :   return NS_OK;
    1178             : }
    1179             : 
    1180             : NS_IMETHODIMP
    1181           0 : nsCertTree::SetCellValue(int32_t row, nsITreeColumn* col,
    1182             :                          const nsAString& value)
    1183             : {
    1184           0 :   return NS_OK;
    1185             : }
    1186             : 
    1187             : NS_IMETHODIMP
    1188           0 : nsCertTree::SetCellText(int32_t row, nsITreeColumn* col,
    1189             :                         const nsAString& value)
    1190             : {
    1191           0 :   return NS_OK;
    1192             : }
    1193             : 
    1194             : NS_IMETHODIMP
    1195           0 : nsCertTree::PerformAction(const char16_t *action)
    1196             : {
    1197           0 :   return NS_OK;
    1198             : }
    1199             : 
    1200             : NS_IMETHODIMP
    1201           0 : nsCertTree::PerformActionOnRow(const char16_t *action, int32_t row)
    1202             : {
    1203           0 :   return NS_OK;
    1204             : }
    1205             : 
    1206             : NS_IMETHODIMP
    1207           0 : nsCertTree::PerformActionOnCell(const char16_t *action, int32_t row,
    1208             :                                 nsITreeColumn* col)
    1209             : {
    1210           0 :   return NS_OK;
    1211             : }
    1212             : 
    1213             : #ifdef DEBUG_CERT_TREE
    1214             : void
    1215             : nsCertTree::dumpMap()
    1216             : {
    1217             :   for (int i=0; i<mNumOrgs; i++) {
    1218             :     nsAutoString org(mTreeArray[i].orgName);
    1219             :     MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("ORG[%s]", NS_LossyConvertUTF16toASCII(org).get()));
    1220             :     MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("OPEN[%d]", mTreeArray[i].open));
    1221             :     MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("INDEX[%d]", mTreeArray[i].certIndex));
    1222             :     MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("NCHILD[%d]", mTreeArray[i].numChildren));
    1223             :   }
    1224             :   for (int i=0; i<mNumRows; i++) {
    1225             :     treeArrayEl *el = GetThreadDescAtIndex(i);
    1226             :     if (el) {
    1227             :       nsAutoString td(el->orgName);
    1228             :       MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("thread desc[%d]: %s", i, NS_LossyConvertUTF16toASCII(td).get()));
    1229             :     }
    1230             :     nsCOMPtr<nsIX509Cert> ct = GetCertAtIndex(i);
    1231             :     if (ct) {
    1232             :       char16_t *goo;
    1233             :       ct->GetCommonName(&goo);
    1234             :       nsAutoString doo(goo);
    1235             :       MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("cert [%d]: %s", i, NS_LossyConvertUTF16toASCII(doo).get()));
    1236             :     }
    1237             :   }
    1238             : }
    1239             : #endif
    1240             : 
    1241             : //
    1242             : // CanDrop
    1243             : //
    1244           0 : NS_IMETHODIMP nsCertTree::CanDrop(int32_t index, int32_t orientation,
    1245             :                                   nsIDOMDataTransfer* aDataTransfer, bool *_retval)
    1246             : {
    1247           0 :   NS_ENSURE_ARG_POINTER(_retval);
    1248           0 :   *_retval = false;
    1249             : 
    1250           0 :   return NS_OK;
    1251             : }
    1252             : 
    1253             : 
    1254             : //
    1255             : // Drop
    1256             : //
    1257           0 : NS_IMETHODIMP nsCertTree::Drop(int32_t row, int32_t orient, nsIDOMDataTransfer* aDataTransfer)
    1258             : {
    1259           0 :   return NS_OK;
    1260             : }
    1261             : 
    1262             : 
    1263             : //
    1264             : // IsSorted
    1265             : //
    1266             : // ...
    1267             : //
    1268           0 : NS_IMETHODIMP nsCertTree::IsSorted(bool *_retval)
    1269             : {
    1270           0 :   *_retval = false;
    1271           0 :   return NS_OK;
    1272             : }
    1273             : 
    1274             : #define RETURN_NOTHING
    1275             : 
    1276             : void
    1277           0 : nsCertTree::CmpInitCriterion(nsIX509Cert *cert, CompareCacheHashEntry *entry,
    1278             :                              sortCriterion crit, int32_t level)
    1279             : {
    1280           0 :   NS_ENSURE_TRUE(cert && entry, RETURN_NOTHING);
    1281             : 
    1282           0 :   entry->mCritInit[level] = true;
    1283           0 :   nsXPIDLString &str = entry->mCrit[level];
    1284             : 
    1285           0 :   switch (crit) {
    1286             :     case sort_IssuerOrg:
    1287           0 :       cert->GetIssuerOrganization(str);
    1288           0 :       if (str.IsEmpty())
    1289           0 :         cert->GetCommonName(str);
    1290           0 :       break;
    1291             :     case sort_Org:
    1292           0 :       cert->GetOrganization(str);
    1293           0 :       break;
    1294             :     case sort_Token:
    1295           0 :       cert->GetTokenName(str);
    1296           0 :       break;
    1297             :     case sort_CommonName:
    1298           0 :       cert->GetCommonName(str);
    1299           0 :       break;
    1300             :     case sort_IssuedDateDescending:
    1301             :       {
    1302             :         nsresult rv;
    1303           0 :         nsCOMPtr<nsIX509CertValidity> validity;
    1304             :         PRTime notBefore;
    1305             : 
    1306           0 :         rv = cert->GetValidity(getter_AddRefs(validity));
    1307           0 :         if (NS_SUCCEEDED(rv)) {
    1308           0 :           rv = validity->GetNotBefore(&notBefore);
    1309             :         }
    1310             : 
    1311           0 :         if (NS_SUCCEEDED(rv)) {
    1312             :           PRExplodedTime explodedTime;
    1313           0 :           PR_ExplodeTime(notBefore, PR_GMTParameters, &explodedTime);
    1314             :           char datebuf[20]; // 4 + 2 + 2 + 2 + 2 + 2 + 1 = 15
    1315           0 :           if (0 != PR_FormatTime(datebuf, sizeof(datebuf), "%Y%m%d%H%M%S", &explodedTime)) {
    1316           0 :             str = NS_ConvertASCIItoUTF16(nsDependentCString(datebuf));
    1317             :           }
    1318             :         }
    1319             :       }
    1320           0 :       break;
    1321             :     case sort_Email:
    1322           0 :       cert->GetEmailAddress(str);
    1323           0 :       break;
    1324             :     case sort_None:
    1325             :     default:
    1326           0 :       break;
    1327             :   }
    1328             : }
    1329             : 
    1330             : int32_t
    1331           0 : nsCertTree::CmpByCrit(nsIX509Cert *a, CompareCacheHashEntry *ace,
    1332             :                       nsIX509Cert *b, CompareCacheHashEntry *bce,
    1333             :                       sortCriterion crit, int32_t level)
    1334             : {
    1335           0 :   NS_ENSURE_TRUE(a && ace && b && bce, 0);
    1336             : 
    1337           0 :   if (!ace->mCritInit[level]) {
    1338           0 :     CmpInitCriterion(a, ace, crit, level);
    1339             :   }
    1340             : 
    1341           0 :   if (!bce->mCritInit[level]) {
    1342           0 :     CmpInitCriterion(b, bce, crit, level);
    1343             :   }
    1344             : 
    1345           0 :   nsXPIDLString &str_a = ace->mCrit[level];
    1346           0 :   nsXPIDLString &str_b = bce->mCrit[level];
    1347             : 
    1348             :   int32_t result;
    1349           0 :   if (str_a && str_b)
    1350           0 :     result = Compare(str_a, str_b, nsCaseInsensitiveStringComparator());
    1351             :   else
    1352           0 :     result = !str_a ? (!str_b ? 0 : -1) : 1;
    1353             : 
    1354           0 :   if (sort_IssuedDateDescending == crit)
    1355           0 :     result *= -1; // reverse compare order
    1356             : 
    1357           0 :   return result;
    1358             : }
    1359             : 
    1360             : int32_t
    1361           0 : nsCertTree::CmpBy(void *cache, nsIX509Cert *a, nsIX509Cert *b,
    1362             :                   sortCriterion c0, sortCriterion c1, sortCriterion c2)
    1363             : {
    1364             :   // This will be called when comparing items for display sorting.
    1365             :   // Some items might have no cert associated, so either a or b is null.
    1366             :   // We want all those orphans show at the top of the list,
    1367             :   // so we treat a null cert as "smaller" by returning -1.
    1368             :   // We don't try to sort within the group of no-cert entries,
    1369             :   // so we treat them as equal wrt sort order.
    1370             : 
    1371           0 :   if (!a && !b)
    1372           0 :     return 0;
    1373             : 
    1374           0 :   if (!a)
    1375           0 :     return -1;
    1376             : 
    1377           0 :   if (!b)
    1378           0 :     return 1;
    1379             : 
    1380           0 :   NS_ENSURE_TRUE(cache && a && b, 0);
    1381             : 
    1382           0 :   CompareCacheHashEntry *ace = getCacheEntry(cache, a);
    1383           0 :   CompareCacheHashEntry *bce = getCacheEntry(cache, b);
    1384             : 
    1385             :   int32_t cmp;
    1386           0 :   cmp = CmpByCrit(a, ace, b, bce, c0, 0);
    1387           0 :   if (cmp != 0)
    1388           0 :     return cmp;
    1389             : 
    1390           0 :   if (c1 != sort_None) {
    1391           0 :     cmp = CmpByCrit(a, ace, b, bce, c1, 1);
    1392           0 :     if (cmp != 0)
    1393           0 :       return cmp;
    1394             : 
    1395           0 :     if (c2 != sort_None) {
    1396           0 :       return CmpByCrit(a, ace, b, bce, c2, 2);
    1397             :     }
    1398             :   }
    1399             : 
    1400           0 :   return cmp;
    1401             : }
    1402             : 
    1403             : int32_t
    1404           0 : nsCertTree::CmpCACert(void *cache, nsIX509Cert *a, nsIX509Cert *b)
    1405             : {
    1406             :   // XXX we assume issuer org is always criterion 1
    1407           0 :   return CmpBy(cache, a, b, sort_IssuerOrg, sort_Org, sort_Token);
    1408             : }
    1409             : 
    1410             : int32_t
    1411           0 : nsCertTree::CmpWebSiteCert(void *cache, nsIX509Cert *a, nsIX509Cert *b)
    1412             : {
    1413             :   // XXX we assume issuer org is always criterion 1
    1414           0 :   return CmpBy(cache, a, b, sort_IssuerOrg, sort_CommonName, sort_None);
    1415             : }
    1416             : 
    1417             : int32_t
    1418           0 : nsCertTree::CmpUserCert(void *cache, nsIX509Cert *a, nsIX509Cert *b)
    1419             : {
    1420             :   // XXX we assume issuer org is always criterion 1
    1421           0 :   return CmpBy(cache, a, b, sort_IssuerOrg, sort_Token, sort_IssuedDateDescending);
    1422             : }
    1423             : 
    1424             : int32_t
    1425           0 : nsCertTree::CmpEmailCert(void *cache, nsIX509Cert *a, nsIX509Cert *b)
    1426             : {
    1427             :   // XXX we assume issuer org is always criterion 1
    1428           0 :   return CmpBy(cache, a, b, sort_IssuerOrg, sort_Email, sort_CommonName);
    1429             : }
    1430             : 

Generated by: LCOV version 1.13