Bug 1267229 - Handle wrong system time when kinto clock skew is not available. r=MattN
authorHeejong Ahn <heejongahn@gmail.com>
Thu, 28 Apr 2016 22:43:56 +0200
changeset 358374 645331fa032779e6324e32a11898a55e6c75ee24
parent 358373 2e438048aa9d6d90b4d0c96a506d7ef01a1053cc
child 358375 ece477bc26a761831519a9ad9893c504dcd14f03
push id10621
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 16:02:43 +0000
treeherdermozilla-aurora@dca7b42e6c67 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN
bugs1267229
milestone53.0a1
Bug 1267229 - Handle wrong system time when kinto clock skew is not available. r=MattN MozReview-Commit-ID: Ko2Rq6PLfoX
browser/base/content/aboutNetError.xhtml
browser/base/content/content.js
browser/base/content/test/general/browser_aboutCertError.js
browser/base/content/test/general/browser_misused_characters_in_strings.js
browser/locales/en-US/chrome/overrides/netError.dtd
--- a/browser/base/content/aboutNetError.xhtml
+++ b/browser/base/content/aboutNetError.xhtml
@@ -593,16 +593,20 @@
           <p id="errorShortDescText" />
         </div>
         <p id="badStsCertExplanation" hidden="true">&certerror.whatShouldIDo.badStsCertExplanation;</p>
 
         <div id="wrongSystemTimePanel" style="display: none;">
           &certerror.wrongSystemTime;
         </div>
 
+        <div id="wrongSystemTimeWithoutReferencePanel" style="display: none;">
+          &certerror.wrongSystemTimeWithoutReference;
+        </div>
+
         <!-- Long Description (Note: See netError.dtd for used XHTML tags) -->
         <div id="errorLongDesc" />
 
         <div id="learnMoreContainer">
           <p><a href="https://support.mozilla.org/kb/what-does-your-connection-is-not-secure-mean" id="learnMoreLink" target="new">&errorReporting.learnMore;</a></p>
         </div>
 
         <div id="prefChangeContainer" class="button-container">
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -300,46 +300,74 @@ var AboutNetAndCertErrorListener = {
     let learnMoreLink = content.document.getElementById("learnMoreLink");
     let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
 
     switch (msg.data.code) {
       case SEC_ERROR_UNKNOWN_ISSUER:
         learnMoreLink.href = baseURL + "security-error";
         break;
 
-      // in case the certificate expired we make sure the system clock
-      // matches settings server (kinto) time
+      // In case the certificate expired we make sure the system clock
+      // matches the blocklist ping (Kinto) time and is not before the build date.
       case SEC_ERROR_EXPIRED_CERTIFICATE:
       case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
       case SEC_ERROR_OCSP_FUTURE_RESPONSE:
       case SEC_ERROR_OCSP_OLD_RESPONSE:
       case MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE:
       case MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE:
 
-        // use blocklist stats if available
+        // We check against Kinto time first if available, because that allows us
+        // to give the user an approximation of what the correct time is.
+        let difference = 0;
         if (Services.prefs.getPrefType(PREF_BLOCKLIST_CLOCK_SKEW_SECONDS)) {
-          let difference = Services.prefs.getIntPref(PREF_BLOCKLIST_CLOCK_SKEW_SECONDS);
+          difference = Services.prefs.getIntPref(PREF_BLOCKLIST_CLOCK_SKEW_SECONDS);
+        }
+
+        // If the difference is more than a day.
+        if (Math.abs(difference) > 60 * 60 * 24) {
+          let formatter = new Intl.DateTimeFormat();
+          let systemDate = formatter.format(new Date());
+          // negative difference means local time is behind server time
+          let actualDate = formatter.format(new Date(Date.now() - difference * 1000));
+
+          content.document.getElementById("wrongSystemTime_URL")
+            .textContent = content.document.location.hostname;
+          content.document.getElementById("wrongSystemTime_systemDate")
+            .textContent = systemDate;
+          content.document.getElementById("wrongSystemTime_actualDate")
+            .textContent = actualDate;
 
-          // if the difference is more than a day
-          if (Math.abs(difference) > 60 * 60 * 24) {
+          content.document.getElementById("errorShortDesc")
+            .style.display = "none";
+          content.document.getElementById("wrongSystemTimePanel")
+            .style.display = "block";
+
+        // If there is no clock skew with Kinto servers, check against the build date.
+        // (The Kinto ping could have happened when the time was still right, or not at all)
+        } else {
+          let appBuildID = Services.appinfo.appBuildID;
+
+          let year = parseInt(appBuildID.substr(0, 4), 10);
+          let month = parseInt(appBuildID.substr(4, 2), 10) - 1;
+          let day = parseInt(appBuildID.substr(6, 2), 10);
+
+          let buildDate = new Date(year, month, day);
+          let systemDate = new Date();
+
+          if (buildDate > systemDate) {
             let formatter = new Intl.DateTimeFormat();
-            let systemDate = formatter.format(new Date());
-            // negative difference means local time is behind server time
-            let actualDate = formatter.format(new Date(Date.now() - difference * 1000));
 
-            content.document.getElementById("wrongSystemTime_URL")
+            content.document.getElementById("wrongSystemTimeWithoutReference_URL")
               .textContent = content.document.location.hostname;
-            content.document.getElementById("wrongSystemTime_systemDate")
-              .textContent = systemDate;
-            content.document.getElementById("wrongSystemTime_actualDate")
-              .textContent = actualDate;
+            content.document.getElementById("wrongSystemTimeWithoutReference_systemDate")
+              .textContent = formatter.format(systemDate);
 
             content.document.getElementById("errorShortDesc")
               .style.display = "none";
-            content.document.getElementById("wrongSystemTimePanel")
+            content.document.getElementById("wrongSystemTimeWithoutReferencePanel")
               .style.display = "block";
           }
         }
         learnMoreLink.href = baseURL + "time-errors";
         break;
     }
   },
 
--- a/browser/base/content/test/general/browser_aboutCertError.js
+++ b/browser/base/content/test/general/browser_aboutCertError.js
@@ -100,16 +100,29 @@ add_task(function* checkBadStsCert() {
     let exceptionButton = doc.getElementById("exceptionDialogButton");
     return exceptionButton.hidden;
   });
   ok(exceptionButtonHidden, "Exception button is hidden");
 
   yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
 });
 
+// This checks that the appinfo.appBuildID starts with a date string,
+// which is required for the misconfigured system time check.
+add_task(function* checkAppBuildIDIsDate() {
+  let appBuildID = Services.appinfo.appBuildID;
+  let year = parseInt(appBuildID.substr(0, 4), 10);
+  let month = parseInt(appBuildID.substr(4, 2), 10);
+  let day = parseInt(appBuildID.substr(6, 2), 10);
+
+  ok(year >= 2016 && year <= 2100, "appBuildID contains a valid year");
+  ok(month >= 1 && month <= 12, "appBuildID contains a valid month");
+  ok(day >= 1 && day <= 31, "appBuildID contains a valid day");
+});
+
 const PREF_BLOCKLIST_CLOCK_SKEW_SECONDS = "services.blocklist.clock_skew_seconds";
 
 add_task(function* checkWrongSystemTimeWarning() {
   function* setUpPage() {
     let browser;
     let certErrorLoaded;
     yield BrowserTestUtils.openNewForegroundTab(gBrowser, () => {
       gBrowser.selectedTab = gBrowser.addTab(BAD_CERT);
@@ -146,17 +159,17 @@ add_task(function* checkWrongSystemTimeW
 
   let skew = Math.floor((Date.now() - serverDate.getTime()) / 1000);
   yield SpecialPowers.pushPrefEnv({set: [[PREF_BLOCKLIST_CLOCK_SKEW_SECONDS, skew]]});
 
   info("Loading a bad cert page with a skewed clock");
   let message = yield Task.spawn(setUpPage);
 
   isnot(message.divDisplay, "none", "Wrong time message information is visible");
-  ok(message.text.includes("because your clock appears to show the wrong time"),
+  ok(message.text.includes("clock appears to show the wrong time"),
      "Correct error message found");
   ok(message.text.includes("expired.example.com"), "URL found in error message");
   ok(message.systemDate.includes(localDateFmt), "correct local date displayed");
   ok(message.actualDate.includes(serverDateFmt), "correct server date displayed");
   ok(message.learnMoreLink.includes("time-errors"), "time-errors in the Learn More URL");
 
   yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
 
@@ -167,17 +180,17 @@ add_task(function* checkWrongSystemTimeW
 
   skew = Math.floor((Date.now() - serverDate.getTime()) / 1000);
   yield SpecialPowers.pushPrefEnv({set: [[PREF_BLOCKLIST_CLOCK_SKEW_SECONDS, skew]]});
 
   info("Loading a bad cert page with a skewed clock");
   message = yield Task.spawn(setUpPage);
 
   isnot(message.divDisplay, "none", "Wrong time message information is visible");
-  ok(message.text.includes("because your clock appears to show the wrong time"),
+  ok(message.text.includes("clock appears to show the wrong time"),
      "Correct error message found");
   ok(message.text.includes("expired.example.com"), "URL found in error message");
   ok(message.systemDate.includes(localDateFmt), "correct local date displayed");
   ok(message.actualDate.includes(serverDateFmt), "correct server date displayed");
 
   yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
 
   // pretend we only have a slightly skewed system time, four hours
--- a/browser/base/content/test/general/browser_misused_characters_in_strings.js
+++ b/browser/base/content/test/general/browser_misused_characters_in_strings.js
@@ -28,16 +28,20 @@ let gWhitelist = [{
     file: "netError.dtd",
     key: "inadequateSecurityError.longDesc",
     type: "single-quote"
   }, {
     file: "netError.dtd",
     key: "certerror.wrongSystemTime",
     type: "single-quote"
   }, {
+    file: "netError.dtd",
+    key: "certerror.wrongSystemTimeWithoutReference",
+    type: "single-quote"
+  }, {
     file: "phishing-afterload-warning-message.dtd",
     key: "safeb.blocked.malwarePage.shortDesc",
     type: "single-quote"
   }, {
     file: "phishing-afterload-warning-message.dtd",
     key: "safeb.blocked.unwantedPage.shortDesc",
     type: "single-quote"
   }, {
--- a/browser/locales/en-US/chrome/overrides/netError.dtd
+++ b/browser/locales/en-US/chrome/overrides/netError.dtd
@@ -192,19 +192,21 @@ was trying to connect. -->
 <!ENTITY weakCryptoUsed.title "Your connection is not secure">
 <!-- LOCALIZATION NOTE (weakCryptoUsed.longDesc2) - Do not translate
      "SSL_ERROR_NO_CYPHER_OVERLAP". -->
 <!ENTITY weakCryptoUsed.longDesc2 "Advanced info: SSL_ERROR_NO_CYPHER_OVERLAP">
 <!ENTITY weakCryptoAdvanced.title "Advanced">
 <!ENTITY weakCryptoAdvanced.longDesc "<span class='hostname'></span> uses security technology that is outdated and vulnerable to attack. An attacker could easily reveal information which you thought to be safe.">
 <!ENTITY weakCryptoAdvanced.override "(Not secure) Try loading <span class='hostname'></span> using outdated security">
 
-<!-- LOCALIZATION NOTE (certerror.wrongSystemTime) - The <span id='..' /> tags will be injected with actual values,
-     please leave them unchanged. -->
-<!ENTITY certerror.wrongSystemTime "<p>A secure connection to <span id='wrongSystemTime_URL'/> isn’t possible because your clock appears to show the wrong time.</p> <p>Your computer thinks it is <span id='wrongSystemTime_systemDate'/>, when it should be <span id='wrongSystemTime_actualDate'/>. To fix this problem, change your date and time settings to match the correct time.</p>">
+<!-- LOCALIZATION NOTE (certerror.wrongSystemTime,
+                        certerror.wrongSystemTimeWithoutReference) - The <span id='..' />
+     tags will be injected with actual values, please leave them unchanged. -->
+<!ENTITY certerror.wrongSystemTime "<p> &brandShortName; did not connect to <span id='wrongSystemTime_URL'/> because your computer’s clock appears to show the wrong time and this is preventing a secure connection.</p> <p>Your computer is set to <span id='wrongSystemTime_systemDate'/>, when it should be <span id='wrongSystemTime_actualDate'/>. To fix this problem, change your date and time settings to match the correct time.</p>">
+<!ENTITY certerror.wrongSystemTimeWithoutReference "<p>&brandShortName; did not connect to <span id='wrongSystemTimeWithoutReference_URL'/> because your computer’s clock appears to show the wrong time and this is preventing a secure connection.</p> <p>Your computer is set to <span id='wrongSystemTimeWithoutReference_systemDate'/>. To fix this problem, change your date and time settings to match the correct time.</p>">
 
 <!ENTITY certerror.pagetitle1  "Insecure Connection">
 <!ENTITY certerror.whatShouldIDo.badStsCertExplanation "This site uses HTTP
 Strict Transport Security (HSTS) to specify that &brandShortName; may only connect
 to it securely. As a result, it is not possible to add an exception for this
 certificate.">
 <!ENTITY certerror.copyToClipboard.label "Copy text to clipboard">