Bug 1608894 - use the new certificate viewer in thunderbird (about:certificate?cert=). r=mkmelin
authorKhushil Mistry <khushil324@gmail.com>
Thu, 28 May 2020 20:44:52 +1200
changeset 29679 3d86054fed856829c92a02ee3fe09157b503ab1a
parent 29678 dba64c20e3a8b91ef4750893e6b3f694fbefefc2
child 29680 397712fa160acf382c50c926067321b1165e5fad
push id17484
push usergeoff@darktrojan.net
push dateThu, 28 May 2020 09:48:54 +0000
treeherdercomm-central@397712fa160a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1608894
Bug 1608894 - use the new certificate viewer in thunderbird (about:certificate?cert=). r=mkmelin
mail/app/profile/all-thunderbird.js
mail/base/content/contentAreaClick.js
mail/base/content/specialTabs.js
mailnews/extensions/smime/content/msgCompSecurityInfo.js
mailnews/extensions/smime/content/msgReadSecurityInfo.js
--- a/mail/app/profile/all-thunderbird.js
+++ b/mail/app/profile/all-thunderbird.js
@@ -345,17 +345,17 @@ pref("network.hosts.pop_server",        
 // For testing purposes only: Flipping this pref to true allows
 // to skip the assertion that every about page ships with a CSP.
 pref("dom.security.skip_about_page_has_csp_assert", true);
 
 pref("security.warn_entering_secure", false);
 pref("security.warn_entering_weak", false);
 pref("security.warn_leaving_secure", false);
 pref("security.warn_viewing_mixed", false);
-pref("security.aboutcertificate.enabled", false);
+pref("security.aboutcertificate.enabled", true);
 
 // Prompt for the master password prior to opening application windows,
 // to avoid the race that triggers multiple prompts (see bug 177175).
 #ifdef XP_MACOSX
 // disabled because of platform specific bug 1612456
 pref("security.prompt_for_master_password_on_startup", false);
 #else
 pref("security.prompt_for_master_password_on_startup", true);
--- a/mail/base/content/contentAreaClick.js
+++ b/mail/base/content/contentAreaClick.js
@@ -255,14 +255,22 @@ function openUILinkIn(url, where, option
 
 function openTrustedLinkIn(url, where, aParams) {
   var params = aParams;
 
   if (!params) {
     params = {};
   }
 
+  if (url.startsWith("about:certificate")) {
+    document.getElementById("tabmail").openTab("contentTab", {
+      contentPage: url,
+      clickHandler: "specialTabs.aboutClickHandler(event);",
+    });
+    return;
+  }
+
   if (!params.triggeringPrincipal) {
     params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
   }
 
   openUILinkIn(url, where, params);
 }
--- a/mail/base/content/specialTabs.js
+++ b/mail/base/content/specialTabs.js
@@ -14,16 +14,40 @@ var { XPCOMUtils } = ChromeUtils.import(
 var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 var { AddonManager } = ChromeUtils.import(
   "resource://gre/modules/AddonManager.jsm"
 );
 var { ExtensionParent } = ChromeUtils.import(
   "resource://gre/modules/ExtensionParent.jsm"
 );
 
+function saveKeyToFile(content, fileName) {
+  let picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+  let mail3PaneWindow = Services.wm.getMostRecentWindow("mail:3pane");
+  picker.init(mail3PaneWindow, fileName, Ci.nsIFilePicker.modeSave);
+  picker.defaultString = fileName;
+  picker.defaultExtension = "pem";
+  picker.appendFilters(Ci.nsIFilePicker.filterAll);
+  return new Promise(resolve => {
+    picker.open(rv => {
+      if (
+        rv != Ci.nsIFilePicker.returnOK &&
+        rv != Ci.nsIFilePicker.returnReplace
+      ) {
+        resolve(null);
+        return;
+      }
+      try {
+        OS.File.writeAtomic(picker.file.path, decodeURI(content));
+        resolve(picker.file);
+      } catch (ex) {}
+    });
+  });
+}
+
 function tabProgressListener(aTab, aStartsBlank) {
   this.mTab = aTab;
   this.mBrowser = aTab.browser;
   this.mBlank = aStartsBlank;
   this.mProgressListener = null;
 }
 
 tabProgressListener.prototype = {
@@ -351,16 +375,17 @@ var kTelemetryPromptRev = 2;
 
 var contentTabBaseType = {
   // List of URLs that will receive special treatment when opened in a tab.
   // Note that about:preferences is loaded via a different mechanism.
   inContentWhitelist: [
     "about:addons",
     "about:blank",
     "about:profiles",
+    "about:certificate?*",
     "about:*",
   ],
 
   // Code to run if a particular document is loaded in a tab.
   // The array members (functions) are for the respective document URLs
   // as specified in inContentWhitelist.
   inContentOverlays: [
     // about:addons
@@ -384,16 +409,34 @@ var contentTabBaseType = {
         )) {
           button.textContent = l10n.formatValueSync(
             "profiles-launch-profile-plain"
           );
         }
       }, 500);
     },
 
+    // about:certificate
+    function(aDocument, aTab) {
+      // Need a timeout to let the script run to create the needed links.
+      setTimeout(() => {
+        let downloadLinks = aDocument
+          .querySelector("certificate-section")
+          .shadowRoot.querySelector(".miscellaneous")
+          .shadowRoot.querySelector(".download")
+          .shadowRoot.querySelectorAll(".download-link");
+        for (let link of downloadLinks) {
+          link.addEventListener("click", event => {
+            let content = link.getAttribute("href").split(",");
+            saveKeyToFile(content[1], link.getAttribute("download"));
+          });
+        }
+      }, 1000);
+    },
+
     // Other about:* pages.
     function(aDocument, aTab) {
       // Provide context menu for about:* pages.
       aTab.browser.setAttribute("context", "aboutPagesContext");
     },
   ],
 
   shouldSwitchTo({ contentPage: aContentPage, duplicate: aDuplicate }) {
@@ -464,16 +507,20 @@ var contentTabBaseType = {
 
     function onLoad(aEvent) {
       let doc = aEvent.originalTarget;
       let url = doc.defaultView.location.href;
 
       // If this document has an overlay defined, run it now.
       let ind = self.inContentWhitelist.indexOf(url);
       if (ind < 0) {
+        // about:certificate?<certid> like URLs.
+        ind = self.inContentWhitelist.indexOf(url.replace(/\?.*/, "?*"));
+      }
+      if (ind < 0) {
         // Try a wildcard.
         ind = self.inContentWhitelist.indexOf(url.replace(/:.*/, ":*"));
       }
       if (ind >= 0) {
         let overlayFunction = self.inContentOverlays[ind];
         if (overlayFunction) {
           overlayFunction(doc, aTab);
         }
--- a/mailnews/extensions/smime/content/msgCompSecurityInfo.js
+++ b/mailnews/extensions/smime/content/msgCompSecurityInfo.js
@@ -262,23 +262,22 @@ function asyncDetermineUsages(cert) {
 
 function onSelectionChange(event) {
   gViewButton.disabled = !(
     gListBox.selectedItems.length == 1 && certForRow(gListBox.selectedIndex)
   );
 }
 
 function viewCertHelper(parent, cert) {
-  Services.ww.openWindow(
-    parent,
-    "chrome://pippki/content/certViewer.xhtml",
-    "_blank",
-    "centerscreen,chrome,titlebar",
-    cert
-  );
+  let url = `about:certificate?cert=${encodeURIComponent(
+    cert.getBase64DERString()
+  )}`;
+  let mail3PaneWindow = Services.wm.getMostRecentWindow("mail:3pane");
+  mail3PaneWindow.switchToTabHavingURI(url, true, {});
+  parent.close();
 }
 
 function certForRow(aRowIndex) {
   return gCerts[aRowIndex];
 }
 
 function viewSelectedCert() {
   if (!gViewButton.disabled) {
--- a/mailnews/extensions/smime/content/msgReadSecurityInfo.js
+++ b/mailnews/extensions/smime/content/msgReadSecurityInfo.js
@@ -215,26 +215,24 @@ function onLoad() {
         gEncryptionCert.emailAddress;
     }
     if (gEncryptionCert.issuerName) {
       document.getElementById("encCertIssuedBy").value =
         gEncryptionCert.issuerCommonName;
     }
   }
 }
-/* eslint-enable complexity */
 
 function viewCertHelper(parent, cert) {
-  Services.ww.openWindow(
-    parent,
-    "chrome://pippki/content/certViewer.xhtml",
-    "_blank",
-    "centerscreen,chrome,titlebar",
-    cert
-  );
+  let url = `about:certificate?cert=${encodeURIComponent(
+    cert.getBase64DERString()
+  )}`;
+  let mail3PaneWindow = Services.wm.getMostRecentWindow("mail:3pane");
+  mail3PaneWindow.switchToTabHavingURI(url, true, {});
+  parent.close();
 }
 
 function viewSignatureCert() {
   if (gSignerCert) {
     viewCertHelper(window, gSignerCert);
   }
 }