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 377634 645331fa032779e6324e32a11898a55e6c75ee24
parent 377633 2e438048aa9d6d90b4d0c96a506d7ef01a1053cc
child 377635 ece477bc26a761831519a9ad9893c504dcd14f03
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN
bugs1267229
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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">