summaryrefslogtreecommitdiffstats
path: root/browser/components/preferences/tests/browser_cert_export.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/preferences/tests/browser_cert_export.js')
-rw-r--r--browser/components/preferences/tests/browser_cert_export.js161
1 files changed, 161 insertions, 0 deletions
diff --git a/browser/components/preferences/tests/browser_cert_export.js b/browser/components/preferences/tests/browser_cert_export.js
new file mode 100644
index 0000000000..48769f84e6
--- /dev/null
+++ b/browser/components/preferences/tests/browser_cert_export.js
@@ -0,0 +1,161 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+var MockFilePicker = SpecialPowers.MockFilePicker;
+
+function createTemporarySaveDirectory() {
+ var saveDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
+ saveDir.append("testsavedir");
+ if (!saveDir.exists()) {
+ info("create testsavedir!");
+ saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
+ }
+ info("return from createTempSaveDir: " + saveDir.path);
+ return saveDir;
+}
+
+// Create the folder the certificates will be saved into.
+var destDir = createTemporarySaveDirectory();
+registerCleanupFunction(function () {
+ destDir.remove(true);
+ BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
+
+function stringOrArrayEquals(actual, expected, message) {
+ is(
+ typeof actual,
+ typeof expected,
+ "actual, expected should have the same type"
+ );
+ if (typeof expected == "string") {
+ is(actual, expected, message);
+ } else {
+ is(actual.toString(), expected.toString(), message);
+ }
+}
+
+var dialogWin;
+var exportButton;
+var expectedCert;
+
+async function setupTest() {
+ await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
+ let certButton = gBrowser.selectedBrowser.contentDocument.getElementById(
+ "viewCertificatesButton"
+ );
+ certButton.scrollIntoView();
+ let certDialogLoaded = promiseLoadSubDialog(
+ "chrome://pippki/content/certManager.xhtml"
+ );
+ certButton.click();
+ dialogWin = await certDialogLoaded;
+ let doc = dialogWin.document;
+ doc.getElementById("certmanagertabs").selectedTab =
+ doc.getElementById("ca_tab");
+ let treeView = doc.getElementById("ca-tree").view;
+ // Select any which cert. Ignore parent rows (ie rows without certs):
+ for (let i = 0; i < treeView.rowCount; i++) {
+ treeView.selection.select(i);
+ dialogWin.getSelectedCerts();
+ let certs = dialogWin.selected_certs; // yuck... but this is how the dialog works.
+ if (certs && certs.length == 1 && certs[0]) {
+ expectedCert = certs[0];
+ // OK, we managed to select a cert!
+ break;
+ }
+ }
+
+ exportButton = doc.getElementById("ca_exportButton");
+ is(exportButton.disabled, false, "Should enable export button");
+}
+
+async function checkCertExportWorks(
+ exportType,
+ encoding,
+ expectedFileContents
+) {
+ MockFilePicker.displayDirectory = destDir;
+ var destFile = destDir.clone();
+ MockFilePicker.init(window);
+ MockFilePicker.filterIndex = exportType;
+ MockFilePicker.showCallback = function (fp) {
+ info("showCallback");
+ let fileName = fp.defaultString;
+ info("fileName: " + fileName);
+ destFile.append(fileName);
+ MockFilePicker.setFiles([destFile]);
+ info("done showCallback");
+ };
+ let finishedExporting = TestUtils.topicObserved("cert-export-finished");
+ exportButton.click();
+ await finishedExporting;
+ MockFilePicker.cleanup();
+ if (destFile && destFile.exists()) {
+ let contents;
+ if (encoding === "utf-8") {
+ contents = await IOUtils.readUTF8(destFile.path);
+ } else {
+ is(encoding, "", "expected either utf-8 or empty string for encoding");
+ contents = await IOUtils.read(destFile.path);
+ }
+ stringOrArrayEquals(
+ contents,
+ expectedFileContents,
+ "Should have written correct contents"
+ );
+ destFile.remove(false);
+ } else {
+ ok(false, "No cert saved!");
+ }
+}
+
+add_task(setupTest);
+
+add_task(async function checkCertPEMExportWorks() {
+ let expectedContents = dialogWin.getPEMString(expectedCert);
+ await checkCertExportWorks(0, /* 0 = PEM */ "utf-8", expectedContents);
+});
+
+add_task(async function checkCertPEMChainExportWorks() {
+ let expectedContents = dialogWin.getPEMString(expectedCert);
+ await checkCertExportWorks(
+ 1, // 1 = PEM chain, but the chain is of length 1
+ "utf-8",
+ expectedContents
+ );
+});
+
+add_task(async function checkCertDERExportWorks() {
+ let expectedContents = Uint8Array.from(expectedCert.getRawDER());
+ await checkCertExportWorks(2, /* 2 = DER */ "", expectedContents);
+});
+
+function stringToTypedArray(str) {
+ let arr = new Uint8Array(str.length);
+ for (let i = 0; i < arr.length; i++) {
+ arr[i] = str.charCodeAt(i);
+ }
+ return arr;
+}
+
+add_task(async function checkCertPKCS7ExportWorks() {
+ let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
+ Ci.nsIX509CertDB
+ );
+ let expectedContents = stringToTypedArray(certdb.asPKCS7Blob([expectedCert]));
+ await checkCertExportWorks(3, /* 3 = PKCS7 */ "", expectedContents);
+});
+
+add_task(async function checkCertPKCS7ChainExportWorks() {
+ let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
+ Ci.nsIX509CertDB
+ );
+ let expectedContents = stringToTypedArray(certdb.asPKCS7Blob([expectedCert]));
+ await checkCertExportWorks(
+ 4, // 4 = PKCS7 chain, but the chain is of length 1
+ "",
+ expectedContents
+ );
+});