bug 867473 - (2/4) move certificate chain utility functions to a shared location r?jcj,fkiefer
MozReview-Commit-ID: JxlN95YLwRq
--- 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;
+}