LCOV - app.info - security/manager/ssl/src/nsCRLManager.cpp

LCOV - code coverage report
| Current view: | directory - security/manager/ssl/src - nsCRLManager.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 230 | 0 | 0.0 %
| Date: | 2012-04-21 | Functions: | 12 | 0 | 0.0 %

           1                 : /* ***** BEGIN LICENSE BLOCK *****
           2                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           3                 :  *
           4                 :  * The contents of this file are subject to the Mozilla Public License Version
           5                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           6                 :  * the License. You may obtain a copy of the License at
           7                 :  * http://www.mozilla.org/MPL/
           8                 :  *
           9                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          10                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          11                 :  * for the specific language governing rights and limitations under the
          12                 :  * License.
          13                 :  *
          14                 :  * The Original Code is the Netscape security libraries.
          15                 :  *
          16                 :  * The Initial Developer of the Original Code is
          17                 :  * Netscape Communications Corporation.
          18                 :  * Portions created by the Initial Developer are Copyright (C) 2000
          19                 :  * the Initial Developer. All Rights Reserved.
          20                 :  *
          21                 :  * Contributor(s):
          22                 :  *
          23                 :  * Alternatively, the contents of this file may be used under the terms of
          24                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          25                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          26                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          27                 :  * of those above. If you wish to allow use of your version of this file only
          28                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          29                 :  * use your version of this file under the terms of the MPL, indicate your
          30                 :  * decision by deleting the provisions above and replace them with the notice
          31                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          32                 :  * the provisions above, a recipient may use your version of this file under
          33                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          34                 :  *
          35                 :  * ***** END LICENSE BLOCK ***** */
          36                 :
          37                 : #include "nsCRLManager.h"
          38                 : #include "nsCRLInfo.h"
          39                 :
          40                 : #include "nsCOMPtr.h"
          41                 : #include "nsIDateTimeFormat.h"
          42                 : #include "nsDateTimeFormatCID.h"
          43                 : #include "nsComponentManagerUtils.h"
          44                 : #include "nsReadableUtils.h"
          45                 : #include "nsNSSComponent.h"
          46                 : #include "nsCOMPtr.h"
          47                 : #include "nsICertificateDialogs.h"
          48                 : #include "nsIMutableArray.h"
          49                 : #include "nsIPrefService.h"
          50                 : #include "nsIPrefBranch.h"
          51                 : #include "nsNSSShutDown.h"
          52                 : #include "nsThreadUtils.h"
          53                 :
          54                 : #include "nsNSSCertHeader.h"
          55                 :
          56                 : #include "nspr.h"
          57                 : extern "C" {
          58                 : #include "pk11func.h"
          59                 : #include "certdb.h"
          60                 : #include "cert.h"
          61                 : #include "secerr.h"
          62                 : #include "nssb64.h"
          63                 : #include "secasn1.h"
          64                 : #include "secder.h"
          65                 : }
          66                 : #include "ssl.h"
          67                 : #include "ocsp.h"
          68                 : #include "plbase64.h"
          69                 :
          70                 : static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
          71                 :
          72               0 : NS_IMPL_ISUPPORTS1(nsCRLManager, nsICRLManager)
          73                 :
          74               0 : nsCRLManager::nsCRLManager()
          75                 : {
          76               0 : }
          77                 :
          78               0 : nsCRLManager::~nsCRLManager()
          79                 : {
          80               0 : }
          81                 :
          82                 : NS_IMETHODIMP
          83               0 : nsCRLManager::ImportCrl (PRUint8 *aData, PRUint32 aLength, nsIURI * aURI, PRUint32 aType, bool doSilentDownload, const PRUnichar* crlKey)
          84                 : {
          85               0 :   if (!NS_IsMainThread()) {
          86               0 :     NS_ERROR("nsCRLManager::ImportCrl called off the main thread");
          87               0 :     return NS_ERROR_NOT_SAME_THREAD;
          88                 :   }
          89                 :
          90               0 :   nsNSSShutDownPreventionLock locker;
          91                 :   nsresult rv;
          92               0 :   PRArenaPool *arena = NULL;
          93                 :   CERTCertificate *caCert;
          94               0 :   SECItem derName = { siBuffer, NULL, 0 };
          95                 :   SECItem derCrl;
          96                 :   CERTSignedData sd;
          97                 :   SECStatus sec_rv;
          98                 :   CERTSignedCrl *crl;
          99               0 :   nsCAutoString url;
         100               0 :   nsCOMPtr<nsICRLInfo> crlData;
         101                 :   bool importSuccessful;
         102                 :   PRInt32 errorCode;
         103               0 :   nsString errorMessage;
         104                 :
         105               0 :   nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
         106               0 :   if (NS_FAILED(rv)) return rv;
         107                 :
         108               0 :   aURI->GetSpec(url);
         109               0 :   arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
         110               0 :   if (!arena) {
         111               0 :     goto loser;
         112                 :   }
         113               0 :   memset(&sd, 0, sizeof(sd));
         114                 :
         115               0 :   derCrl.data = (unsigned char*)aData;
         116               0 :   derCrl.len = aLength;
         117               0 :   sec_rv = CERT_KeyFromDERCrl(arena, &derCrl, &derName);
         118               0 :   if (sec_rv != SECSuccess) {
         119               0 :     goto loser;
         120                 :   }
         121                 :
         122               0 :   caCert = CERT_FindCertByName(CERT_GetDefaultCertDB(), &derName);
         123               0 :   if (!caCert) {
         124               0 :     if (aType == SEC_KRL_TYPE){
         125               0 :       goto loser;
         126                 :     }
         127                 :   } else {
         128                 :     sec_rv = SEC_ASN1DecodeItem(arena,
         129                 :                             &sd, SEC_ASN1_GET(CERT_SignedDataTemplate),
         130               0 :                             &derCrl);
         131               0 :     if (sec_rv != SECSuccess) {
         132               0 :       goto loser;
         133                 :     }
         134                 :     sec_rv = CERT_VerifySignedData(&sd, caCert, PR_Now(),
         135               0 :                                nsnull);
         136               0 :     if (sec_rv != SECSuccess) {
         137               0 :       goto loser;
         138                 :     }
         139                 :   }
         140                 :
         141               0 :   crl = SEC_NewCrl(CERT_GetDefaultCertDB(), const_cast<char*>(url.get()), &derCrl,
         142               0 :                    aType);
         143                 :
         144               0 :   if (!crl) {
         145               0 :     goto loser;
         146                 :   }
         147                 :
         148               0 :   crlData = new nsCRLInfo(crl);
         149               0 :   SSL_ClearSessionCache();
         150               0 :   SEC_DestroyCrl(crl);
         151                 :
         152               0 :   importSuccessful = true;
         153               0 :   goto done;
         154                 :
         155                 : loser:
         156               0 :   importSuccessful = false;
         157               0 :   errorCode = PR_GetError();
         158               0 :   switch (errorCode) {
         159                 :     case SEC_ERROR_CRL_EXPIRED:
         160               0 :       nssComponent->GetPIPNSSBundleString("CrlImportFailureExpired", errorMessage);
         161               0 :       break;
         162                 :
         163                 :         case SEC_ERROR_CRL_BAD_SIGNATURE:
         164               0 :       nssComponent->GetPIPNSSBundleString("CrlImportFailureBadSignature", errorMessage);
         165               0 :       break;
         166                 :
         167                 :         case SEC_ERROR_CRL_INVALID:
         168               0 :       nssComponent->GetPIPNSSBundleString("CrlImportFailureInvalid", errorMessage);
         169               0 :       break;
         170                 :
         171                 :         case SEC_ERROR_OLD_CRL:
         172               0 :       nssComponent->GetPIPNSSBundleString("CrlImportFailureOld", errorMessage);
         173               0 :       break;
         174                 :
         175                 :         case SEC_ERROR_CRL_NOT_YET_VALID:
         176               0 :       nssComponent->GetPIPNSSBundleString("CrlImportFailureNotYetValid", errorMessage);
         177               0 :       break;
         178                 :
         179                 :     default:
         180               0 :       nssComponent->GetPIPNSSBundleString("CrlImportFailureReasonUnknown", errorMessage);
         181               0 :       errorMessage.AppendInt(errorCode,16);
         182               0 :       break;
         183                 :   }
         184                 :
         185                 : done:
         186                 :
         187               0 :   if(!doSilentDownload){
         188               0 :     if (!importSuccessful){
         189               0 :       nsString message;
         190               0 :       nsString temp;
         191               0 :       nssComponent->GetPIPNSSBundleString("CrlImportFailure1x", message);
         192               0 :       message.Append(NS_LITERAL_STRING("\n").get());
         193               0 :       message.Append(errorMessage);
         194               0 :       nssComponent->GetPIPNSSBundleString("CrlImportFailure2", temp);
         195               0 :       message.Append(NS_LITERAL_STRING("\n").get());
         196               0 :       message.Append(temp);
         197                 :
         198               0 :       nsNSSComponent::ShowAlertWithConstructedString(message);
         199                 :     } else {
         200               0 :       nsCOMPtr<nsICertificateDialogs> certDialogs;
         201                 :       // Not being able to display the success dialog should not
         202                 :       // be a fatal error, so don't return a failure code.
         203                 :       {
         204               0 :         nsPSMUITracker tracker;
         205               0 :         if (tracker.isUIForbidden()) {
         206               0 :           rv = NS_ERROR_NOT_AVAILABLE;
         207                 :         }
         208                 :         else {
         209               0 :           rv = ::getNSSDialogs(getter_AddRefs(certDialogs),
         210               0 :             NS_GET_IID(nsICertificateDialogs), NS_CERTIFICATEDIALOGS_CONTRACTID);
         211                 :         }
         212                 :       }
         213               0 :       if (NS_SUCCEEDED(rv)) {
         214               0 :         nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
         215               0 :         certDialogs->CrlImportStatusDialog(cxt, crlData);
         216                 :       }
         217                 :     }
         218                 :   } else {
         219               0 :     if(crlKey == nsnull){
         220               0 :       return NS_ERROR_FAILURE;
         221                 :     }
         222               0 :     nsCOMPtr<nsIPrefService> prefSvc = do_GetService(NS_PREFSERVICE_CONTRACTID,&rv);
         223               0 :     nsCOMPtr<nsIPrefBranch> pref = do_GetService(NS_PREFSERVICE_CONTRACTID,&rv);
         224               0 :     if (NS_FAILED(rv)){
         225               0 :       return rv;
         226                 :     }
         227                 :
         228               0 :     nsCAutoString updateErrCntPrefStr(CRL_AUTOUPDATE_ERRCNT_PREF);
         229               0 :     updateErrCntPrefStr.AppendWithConversion(crlKey);
         230               0 :     if(importSuccessful){
         231                 :       PRUnichar *updateTime;
         232               0 :       nsCAutoString updateTimeStr;
         233               0 :       nsCString updateURL;
         234                 :       PRInt32 timingTypePref;
         235                 :       double dayCnt;
         236                 :       char *dayCntStr;
         237               0 :       nsCAutoString updateTypePrefStr(CRL_AUTOUPDATE_TIMIINGTYPE_PREF);
         238               0 :       nsCAutoString updateTimePrefStr(CRL_AUTOUPDATE_TIME_PREF);
         239               0 :       nsCAutoString updateUrlPrefStr(CRL_AUTOUPDATE_URL_PREF);
         240               0 :       nsCAutoString updateDayCntPrefStr(CRL_AUTOUPDATE_DAYCNT_PREF);
         241               0 :       nsCAutoString updateFreqCntPrefStr(CRL_AUTOUPDATE_FREQCNT_PREF);
         242               0 :       updateTypePrefStr.AppendWithConversion(crlKey);
         243               0 :       updateTimePrefStr.AppendWithConversion(crlKey);
         244               0 :       updateUrlPrefStr.AppendWithConversion(crlKey);
         245               0 :       updateDayCntPrefStr.AppendWithConversion(crlKey);
         246               0 :       updateFreqCntPrefStr.AppendWithConversion(crlKey);
         247                 :
         248               0 :       pref->GetIntPref(updateTypePrefStr.get(),&timingTypePref);
         249                 :
         250                 :       //Compute and update the next download instant
         251               0 :       if(timingTypePref == TYPE_AUTOUPDATE_TIME_BASED){
         252               0 :         pref->GetCharPref(updateDayCntPrefStr.get(),&dayCntStr);
         253                 :       }else{
         254               0 :         pref->GetCharPref(updateFreqCntPrefStr.get(),&dayCntStr);
         255                 :       }
         256               0 :       dayCnt = atof(dayCntStr);
         257               0 :       nsMemory::Free(dayCntStr);
         258                 :
         259               0 :       bool toBeRescheduled = false;
         260               0 :       if(NS_SUCCEEDED(ComputeNextAutoUpdateTime(crlData, timingTypePref, dayCnt, &updateTime))){
         261               0 :         updateTimeStr.AssignWithConversion(updateTime);
         262               0 :         nsMemory::Free(updateTime);
         263               0 :         pref->SetCharPref(updateTimePrefStr.get(),updateTimeStr.get());
         264                 :         //Now, check if this update time is already in the past. This would
         265                 :         //imply we have downloaded the same crl, or there is something wrong
         266                 :         //with the next update date. We will not reschedule this crl in this
         267                 :         //session anymore - or else, we land into a loop. It would anyway be
         268                 :         //imported once the browser is restarted.
         269                 :         PRTime nextTime;
         270               0 :         PR_ParseTimeString(updateTimeStr.get(),true, &nextTime);
         271               0 :         if(LL_CMP(nextTime, > , PR_Now())){
         272               0 :           toBeRescheduled = true;
         273                 :         }
         274                 :       }
         275                 :
         276                 :       //Update the url to download from, next time
         277               0 :       crlData->GetLastFetchURL(updateURL);
         278               0 :       pref->SetCharPref(updateUrlPrefStr.get(),updateURL.get());
         279                 :
         280               0 :       pref->SetIntPref(updateErrCntPrefStr.get(),0);
         281                 :
         282               0 :       if (toBeRescheduled) {
         283               0 :         nsAutoString hashKey(crlKey);
         284               0 :         nssComponent->RemoveCrlFromList(hashKey);
         285               0 :         nssComponent->DefineNextTimer();
         286                 :       }
         287                 :
         288                 :     } else{
         289                 :       PRInt32 errCnt;
         290               0 :       nsCAutoString errMsg;
         291               0 :       nsCAutoString updateErrDetailPrefStr(CRL_AUTOUPDATE_ERRDETAIL_PREF);
         292               0 :       updateErrDetailPrefStr.AppendWithConversion(crlKey);
         293               0 :       errMsg.AssignWithConversion(errorMessage.get());
         294               0 :       rv = pref->GetIntPref(updateErrCntPrefStr.get(),&errCnt);
         295               0 :       if(NS_FAILED(rv))
         296               0 :         errCnt = 0;
         297                 :
         298               0 :       pref->SetIntPref(updateErrCntPrefStr.get(),errCnt+1);
         299               0 :       pref->SetCharPref(updateErrDetailPrefStr.get(),errMsg.get());
         300                 :     }
         301               0 :     prefSvc->SavePrefFile(nsnull);
         302                 :   }
         303                 :
         304               0 :   return rv;
         305                 : }
         306                 :
         307                 : NS_IMETHODIMP
         308               0 : nsCRLManager::UpdateCRLFromURL( const PRUnichar *url, const PRUnichar* key, bool *res)
         309                 : {
         310                 :   nsresult rv;
         311               0 :   nsAutoString downloadUrl(url);
         312               0 :   nsAutoString dbKey(key);
         313               0 :   nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
         314               0 :   if(NS_FAILED(rv)){
         315               0 :     *res = false;
         316               0 :     return rv;
         317                 :   }
         318                 :
         319               0 :   rv = nssComponent->DownloadCRLDirectly(downloadUrl, dbKey);
         320               0 :   if(NS_FAILED(rv)){
         321               0 :     *res = false;
         322                 :   } else {
         323               0 :     *res = true;
         324                 :   }
         325               0 :   return NS_OK;
         326                 :
         327                 : }
         328                 :
         329                 : NS_IMETHODIMP
         330               0 : nsCRLManager::RescheduleCRLAutoUpdate(void)
         331                 : {
         332                 :   nsresult rv;
         333               0 :   nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
         334               0 :   if(NS_FAILED(rv)){
         335               0 :     return rv;
         336                 :   }
         337               0 :   rv = nssComponent->DefineNextTimer();
         338               0 :   return rv;
         339                 : }
         340                 :
         341                 : /**
         342                 :  * getCRLs
         343                 :  *
         344                 :  * Export a set of certs and keys from the database to a PKCS#12 file.
         345                 :  */
         346                 : NS_IMETHODIMP
         347               0 : nsCRLManager::GetCrls(nsIArray ** aCrls)
         348                 : {
         349               0 :   nsNSSShutDownPreventionLock locker;
         350                 :   SECStatus sec_rv;
         351               0 :   CERTCrlHeadNode *head = nsnull;
         352               0 :   CERTCrlNode *node = nsnull;
         353                 :   nsresult rv;
         354                 :   nsCOMPtr<nsIMutableArray> crlsArray =
         355               0 :     do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
         356               0 :   if (NS_FAILED(rv)) {
         357               0 :     return rv;
         358                 :   }
         359                 :
         360                 :   // Get the list of certs //
         361               0 :   sec_rv = SEC_LookupCrls(CERT_GetDefaultCertDB(), &head, -1);
         362               0 :   if (sec_rv != SECSuccess) {
         363               0 :     return NS_ERROR_FAILURE;
         364                 :   }
         365                 :
         366               0 :   if (head) {
         367               0 :     for (node=head->first; node != nsnull; node = node->next) {
         368                 :
         369               0 :       nsCOMPtr<nsICRLInfo> entry = new nsCRLInfo((node->crl));
         370               0 :       crlsArray->AppendElement(entry, false);
         371                 :     }
         372               0 :     PORT_FreeArena(head->arena, false);
         373                 :   }
         374                 :
         375               0 :   *aCrls = crlsArray;
         376               0 :   NS_IF_ADDREF(*aCrls);
         377               0 :   return NS_OK;
         378                 : }
         379                 :
         380                 : /**
         381                 :  * deleteCrl
         382                 :  *
         383                 :  * Delete a Crl entry from the cert db.
         384                 :  */
         385                 : NS_IMETHODIMP
         386               0 : nsCRLManager::DeleteCrl(PRUint32 aCrlIndex)
         387                 : {
         388               0 :   nsNSSShutDownPreventionLock locker;
         389               0 :   CERTSignedCrl *realCrl = nsnull;
         390               0 :   CERTCrlHeadNode *head = nsnull;
         391               0 :   CERTCrlNode *node = nsnull;
         392                 :   SECStatus sec_rv;
         393                 :   PRUint32 i;
         394                 :
         395                 :   // Get the list of certs //
         396               0 :   sec_rv = SEC_LookupCrls(CERT_GetDefaultCertDB(), &head, -1);
         397               0 :   if (sec_rv != SECSuccess) {
         398               0 :     return NS_ERROR_FAILURE;
         399                 :   }
         400                 :
         401               0 :   if (head) {
         402               0 :     for (i = 0, node=head->first; node != nsnull; i++, node = node->next) {
         403               0 :       if (i != aCrlIndex) {
         404               0 :         continue;
         405                 :       }
         406               0 :       realCrl = SEC_FindCrlByName(CERT_GetDefaultCertDB(), &(node->crl->crl.derName), node->type);
         407               0 :       SEC_DeletePermCRL(realCrl);
         408               0 :       SEC_DestroyCrl(realCrl);
         409               0 :       SSL_ClearSessionCache();
         410                 :     }
         411               0 :     PORT_FreeArena(head->arena, false);
         412                 :   }
         413               0 :   return NS_OK;
         414                 : }
         415                 :
         416                 : NS_IMETHODIMP
         417               0 : nsCRLManager::ComputeNextAutoUpdateTime(nsICRLInfo *info,
         418                 :   PRUint32 autoUpdateType, double dayCnt, PRUnichar **nextAutoUpdate)
         419                 : {
         420               0 :   if (!info)
         421               0 :     return NS_ERROR_FAILURE;
         422                 :
         423                 :   PRTime microsecInDayCnt;
         424               0 :   PRTime now = PR_Now();
         425                 :   PRTime tempTime;
         426               0 :   PRInt64 diff = 0;
         427               0 :   PRInt64 secsInDay = 86400UL;
         428                 :   PRInt64 temp;
         429               0 :   PRInt64 cycleCnt = 0;
         430                 :   PRInt64 secsInDayCnt;
         431                 :   PRFloat64 tmpData;
         432                 :
         433               0 :   LL_L2F(tmpData,secsInDay);
         434               0 :   LL_MUL(tmpData,dayCnt,tmpData);
         435               0 :   LL_F2L(secsInDayCnt,tmpData);
         436               0 :   LL_MUL(microsecInDayCnt, secsInDayCnt, PR_USEC_PER_SEC);
         437                 :
         438                 :   PRTime lastUpdate;
         439                 :   PRTime nextUpdate;
         440                 :
         441                 :   nsresult rv;
         442                 :
         443               0 :   rv = info->GetLastUpdate(&lastUpdate);
         444               0 :   if (NS_FAILED(rv))
         445               0 :     return rv;
         446                 :
         447               0 :   rv = info->GetNextUpdate(&nextUpdate);
         448               0 :   if (NS_FAILED(rv))
         449               0 :     return rv;
         450                 :
         451               0 :   switch (autoUpdateType) {
         452                 :   case TYPE_AUTOUPDATE_FREQ_BASED:
         453               0 :     LL_SUB(diff, now, lastUpdate);             //diff is the no of micro sec between now and last update
         454               0 :     LL_DIV(cycleCnt, diff, microsecInDayCnt);   //temp is the number of full cycles from lst update
         455               0 :     LL_MOD(temp, diff, microsecInDayCnt);
         456               0 :     if(!(LL_IS_ZERO(temp))) {
         457               0 :       LL_ADD(cycleCnt,cycleCnt,1);            //no of complete cycles till next autoupdate instant
         458                 :     }
         459               0 :     LL_MUL(temp,cycleCnt,microsecInDayCnt);    //micro secs from last update
         460               0 :     LL_ADD(tempTime, lastUpdate, temp);
         461               0 :     break;
         462                 :   case TYPE_AUTOUPDATE_TIME_BASED:
         463               0 :     LL_SUB(tempTime, nextUpdate, microsecInDayCnt);
         464               0 :     break;
         465                 :   default:
         466               0 :     return NS_ERROR_NOT_IMPLEMENTED;
         467                 :   }
         468                 :
         469                 :   //Now, a basic constraing is that the next auto update date can never be after
         470                 :   //next update, if one is defined
         471               0 :   if(LL_CMP(nextUpdate , > , 0 )) {
         472               0 :     if(LL_CMP(tempTime , > , nextUpdate)) {
         473               0 :       tempTime = nextUpdate;
         474                 :     }
         475                 :   }
         476                 :
         477               0 :   nsAutoString nextAutoUpdateDate;
         478                 :   PRExplodedTime explodedTime;
         479               0 :   nsCOMPtr<nsIDateTimeFormat> dateFormatter = do_CreateInstance(NS_DATETIMEFORMAT_CONTRACTID, &rv);
         480               0 :   if (NS_FAILED(rv))
         481               0 :     return rv;
         482               0 :   PR_ExplodeTime(tempTime, PR_GMTParameters, &explodedTime);
         483               0 :   dateFormatter->FormatPRExplodedTime(nsnull, kDateFormatShort, kTimeFormatSeconds,
         484               0 :                                       &explodedTime, nextAutoUpdateDate);
         485               0 :   *nextAutoUpdate = ToNewUnicode(nextAutoUpdateDate);
         486                 :
         487               0 :   return NS_OK;
         488                 : }
         489                 :

Generated by: LCOV version 1.7