diff options
Diffstat (limited to 'browser/components/preferences/tests/browser_cert_export.js')
-rw-r--r-- | browser/components/preferences/tests/browser_cert_export.js | 161 |
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 + ); +}); |