bug 867473 - (2/4) move certificate chain utility functions to a shared location r=fkiefer,jcj
authorDavid Keeler <dkeeler@mozilla.com>
Tue, 17 Apr 2018 12:37:15 -0700
changeset 468035 864b6ccea3023906fef9e7a741f902e5d082030f
parent 468034 d419e0c3d798d8df9bb07640e28546109cde4fe5
child 468036 2cf15e5e3918f4b06b25e0803ddb2af6cc09b50d
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfkiefer, jcj
bugs867473
milestone61.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 867473 - (2/4) move certificate chain utility functions to a shared location r=fkiefer,jcj MozReview-Commit-ID: JxlN95YLwRq
security/manager/pki/resources/content/certViewer.js
security/manager/pki/resources/content/pippki.js
--- a/security/manager/pki/resources/content/certViewer.js
+++ b/security/manager/pki/resources/content/certViewer.js
@@ -83,137 +83,34 @@ function setWindowName() {
   // asyncDetermineUsages finishes.
   AddCertChain("treesetDump", [cert]);
   DisplayGeneralDataFromCert(cert);
   BuildPrettyPrint(cert);
 
   asyncDetermineUsages(cert).then(displayUsages);
 }
 
-// Certificate usages we care about in the certificate viewer.
-const certificateUsageSSLClient              = 0x0001;
-const certificateUsageSSLServer              = 0x0002;
-const certificateUsageSSLCA                  = 0x0008;
-const certificateUsageEmailSigner            = 0x0010;
-const certificateUsageEmailRecipient         = 0x0020;
-
-// A map from the name of a certificate usage to the value of the usage.
-// Useful for printing debugging information and for enumerating all supported
-// usages.
-const certificateUsages = {
-  certificateUsageSSLClient,
-  certificateUsageSSLServer,
-  certificateUsageSSLCA,
-  certificateUsageEmailSigner,
-  certificateUsageEmailRecipient,
-};
-
 // Map of certificate usage name to localization identifier.
 const certificateUsageToStringBundleName = {
   certificateUsageSSLClient: "VerifySSLClient",
   certificateUsageSSLServer: "VerifySSLServer",
   certificateUsageSSLCA: "VerifySSLCA",
   certificateUsageEmailSigner: "VerifyEmailSigner",
   certificateUsageEmailRecipient: "VerifyEmailRecip",
 };
 
-const PRErrorCodeSuccess = 0;
-
 const SEC_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE;
 const SEC_ERROR_EXPIRED_CERTIFICATE                     = SEC_ERROR_BASE + 11;
 const SEC_ERROR_REVOKED_CERTIFICATE                     = SEC_ERROR_BASE + 12;
 const SEC_ERROR_UNKNOWN_ISSUER                          = SEC_ERROR_BASE + 13;
 const SEC_ERROR_UNTRUSTED_ISSUER                        = SEC_ERROR_BASE + 20;
 const SEC_ERROR_UNTRUSTED_CERT                          = SEC_ERROR_BASE + 21;
 const SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE              = SEC_ERROR_BASE + 30;
 const SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED       = SEC_ERROR_BASE + 176;
 
-/**
- * Returns a promise that will resolve with a results array (see
- * `displayUsages`) consisting of what usages the given certificate successfully
- * verified for.
- *
- * @param {nsIX509Cert} cert
- *        The certificate to determine valid usages for.
- * @return {Promise}
- *        A promise that will resolve with the results of the verifications.
- */
-function asyncDetermineUsages(cert) {
-  let promises = [];
-  let now = Date.now() / 1000;
-  let certdb = Cc["@mozilla.org/security/x509certdb;1"]
-                 .getService(Ci.nsIX509CertDB);
-  Object.keys(certificateUsages).forEach(usageString => {
-    promises.push(new Promise((resolve, reject) => {
-      let usage = certificateUsages[usageString];
-      certdb.asyncVerifyCertAtTime(cert, usage, 0, null, now,
-        (aPRErrorCode, aVerifiedChain, aHasEVPolicy) => {
-          resolve({ usageString,
-                    errorCode: aPRErrorCode,
-                    chain: aVerifiedChain });
-        });
-    }));
-  });
-  return Promise.all(promises);
-}
-
-/**
- * Given a results array (see displayUsages), returns the chain corresponding to
- * the desired usage, if verifying for that usage succeeded. Returns null
- * otherwise.
- *
- * @param {Array} results
- *        An array of results from `asyncDetermineUsages`. See `displayUsages`.
- * @param {Number} usage
- *        A numerical value corresponding to a usage. See `certificateUsages`.
- * @returns {Array} An array of `nsIX509Cert` representing the verified
- *          certificate chain for the given usage, or null if there is none.
- */
-function getChainForUsage(results, usage) {
-  for (let result of results) {
-    if (certificateUsages[result.usageString] == usage &&
-        result.errorCode == PRErrorCodeSuccess) {
-      let array = [];
-      let enumerator = result.chain.getEnumerator();
-      while (enumerator.hasMoreElements()) {
-        let cert = enumerator.getNext().QueryInterface(Ci.nsIX509Cert);
-        array.push(cert);
-      }
-      return array;
-    }
-  }
-  return null;
-}
-
-/**
- * Given a results array (see displayUsages), returns the "best" verified
- * certificate chain. Since the primary use case is for TLS server certificates
- * in Firefox, such a verified chain will be returned if present. Otherwise, the
- * priority is: TLS client certificate, email signer, email recipient, CA.
- * Returns null if no usage verified successfully.
- *
- * @param {Array} results
- *        An array of results from `asyncDetermineUsages`. See `displayUsages`.
- * @param {Number} usage
- *        A numerical value corresponding to a usage. See `certificateUsages`.
- * @returns {Array} An array of `nsIX509Cert` representing the verified
- *          certificate chain for the given usage, or null if there is none.
- */
-function getBestChain(results) {
-  let usages = [ certificateUsageSSLServer, certificateUsageSSLClient,
-                 certificateUsageEmailSigner, certificateUsageEmailRecipient,
-                 certificateUsageSSLCA ];
-  for (let usage of usages) {
-    let chain = getChainForUsage(results, usage);
-    if (chain) {
-      return chain;
-    }
-  }
-  return null;
-}
 
 /**
  * Updates the usage display area given the results from asyncDetermineUsages.
  *
  * @param {Array} results
  *        An array of objects with the properties "usageString", "errorCode",
  *        and "chain".
  *        usageString is a string that is a key in the certificateUsages map.
--- a/security/manager/pki/resources/content/pippki.js
+++ b/security/manager/pki/resources/content/pippki.js
@@ -188,8 +188,112 @@ async function exportToFile(parent, cert
         msg = bundle.getString("writeFileUnknownError");
       }
       alertPromptService(bundle.getString("writeFileFailure"),
                          bundle.getFormattedString("writeFileFailed",
                          [fp.file.path, msg]));
     }
   }
 }
+
+const PRErrorCodeSuccess = 0;
+
+// Certificate usages we care about in the certificate viewer.
+const certificateUsageSSLClient              = 0x0001;
+const certificateUsageSSLServer              = 0x0002;
+const certificateUsageSSLCA                  = 0x0008;
+const certificateUsageEmailSigner            = 0x0010;
+const certificateUsageEmailRecipient         = 0x0020;
+
+// A map from the name of a certificate usage to the value of the usage.
+// Useful for printing debugging information and for enumerating all supported
+// usages.
+const certificateUsages = {
+  certificateUsageSSLClient,
+  certificateUsageSSLServer,
+  certificateUsageSSLCA,
+  certificateUsageEmailSigner,
+  certificateUsageEmailRecipient,
+};
+
+/**
+ * Returns a promise that will resolve with a results array (see
+ * `displayUsages` in certViewer.js) consisting of what usages the given
+ * certificate successfully verified for.
+ *
+ * @param {nsIX509Cert} cert
+ *        The certificate to determine valid usages for.
+ * @return {Promise}
+ *        A promise that will resolve with the results of the verifications.
+ */
+function asyncDetermineUsages(cert) {
+  let promises = [];
+  let now = Date.now() / 1000;
+  let certdb = Cc["@mozilla.org/security/x509certdb;1"]
+                 .getService(Ci.nsIX509CertDB);
+  Object.keys(certificateUsages).forEach(usageString => {
+    promises.push(new Promise((resolve, reject) => {
+      let usage = certificateUsages[usageString];
+      certdb.asyncVerifyCertAtTime(cert, usage, 0, null, now,
+        (aPRErrorCode, aVerifiedChain, aHasEVPolicy) => {
+          resolve({ usageString,
+                    errorCode: aPRErrorCode,
+                    chain: aVerifiedChain });
+        });
+    }));
+  });
+  return Promise.all(promises);
+}
+
+/**
+ * Given a results array (see `displayUsages` in certViewer.js), returns the
+ * "best" verified certificate chain. Since the primary use case is for TLS
+ * server certificates in Firefox, such a verified chain will be returned if
+ * present. Otherwise, the priority is: TLS client certificate, email signer,
+ * email recipient, CA. Returns null if no usage verified successfully.
+ *
+ * @param {Array} results
+ *        An array of results from `asyncDetermineUsages`. See `displayUsages`.
+ * @param {Number} usage
+ *        A numerical value corresponding to a usage. See `certificateUsages`.
+ * @returns {Array} An array of `nsIX509Cert` representing the verified
+ *          certificate chain for the given usage, or null if there is none.
+ */
+function getBestChain(results) {
+  let usages = [ certificateUsageSSLServer, certificateUsageSSLClient,
+                 certificateUsageEmailSigner, certificateUsageEmailRecipient,
+                 certificateUsageSSLCA ];
+  for (let usage of usages) {
+    let chain = getChainForUsage(results, usage);
+    if (chain) {
+      return chain;
+    }
+  }
+  return null;
+}
+
+/**
+ * Given a results array (see `displayUsages` in certViewer.js), returns the
+ * chain corresponding to the desired usage, if verifying for that usage
+ * succeeded. Returns null otherwise.
+ *
+ * @param {Array} results
+ *        An array of results from `asyncDetermineUsages`. See `displayUsages`.
+ * @param {Number} usage
+ *        A numerical value corresponding to a usage. See `certificateUsages`.
+ * @returns {Array} An array of `nsIX509Cert` representing the verified
+ *          certificate chain for the given usage, or null if there is none.
+ */
+function getChainForUsage(results, usage) {
+  for (let result of results) {
+    if (certificateUsages[result.usageString] == usage &&
+        result.errorCode == PRErrorCodeSuccess) {
+      let array = [];
+      let enumerator = result.chain.getEnumerator();
+      while (enumerator.hasMoreElements()) {
+        let cert = enumerator.getNext().QueryInterface(Ci.nsIX509Cert);
+        array.push(cert);
+      }
+      return array;
+    }
+  }
+  return null;
+}