diff options
Diffstat (limited to 'security/manager/ssl/tests/mochitest')
121 files changed, 4160 insertions, 0 deletions
diff --git a/security/manager/ssl/tests/mochitest/browser/.eslintrc.js b/security/manager/ssl/tests/mochitest/browser/.eslintrc.js new file mode 100644 index 000000000..c15988365 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/.eslintrc.js @@ -0,0 +1,5 @@ +"use strict"; + +module.exports = { // eslint-disable-line no-undef + "extends": "../../../../../../testing/mochitest/browser.eslintrc.js" +}; diff --git a/security/manager/ssl/tests/mochitest/browser/browser.ini b/security/manager/ssl/tests/mochitest/browser/browser.ini new file mode 100644 index 000000000..3c91ceb80 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser.ini @@ -0,0 +1,18 @@ +[DEFAULT] +tags = psm +support-files = + head.js + *.pem + +[browser_bug627234_perwindowpb.js] +[browser_certificateManagerLeak.js] +[browser_certViewer.js] +[browser_clientAuth_connection.js] +[browser_clientAuth_ui.js] +[browser_deleteCert_ui.js] +[browser_downloadCert_ui.js] +[browser_editCACertTrust.js] +# An earlier attempt at landing this test resulted in frequent intermittent +# failures, almost entirely on Linux. See Bug 1309519. +skip-if = os == "linux" +[browser_exportP12_passwordUI.js] diff --git a/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js b/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js new file mode 100644 index 000000000..081521ca9 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js @@ -0,0 +1,102 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +var FakeSSLStatus = function() { +}; + +FakeSSLStatus.prototype = { + serverCert: null, + cipherName: null, + keyLength: 2048, + isDomainMismatch: false, + isNotValidAtThisTime: false, + isUntrusted: false, + isExtendedValidation: false, + getInterface: function(aIID) { + return this.QueryInterface(aIID); + }, + QueryInterface: function(aIID) { + if (aIID.equals(Ci.nsISSLStatus) || + aIID.equals(Ci.nsISupports)) { + return this; + } + throw new Error(Cr.NS_ERROR_NO_INTERFACE); + }, +}; + +function whenNewWindowLoaded(aOptions, aCallback) { + let win = OpenBrowserWindow(aOptions); + win.addEventListener("load", function onLoad() { + win.removeEventListener("load", onLoad, false); + aCallback(win); + }, false); +} + +// This is a template to help porting global private browsing tests +// to per-window private browsing tests +function test() { + // initialization + waitForExplicitFinish(); + let windowsToClose = []; + let testURI = "about:blank"; + let uri; + let gSSService = Cc["@mozilla.org/ssservice;1"]. + getService(Ci.nsISiteSecurityService); + + function privacyFlags(aIsPrivateMode) { + return aIsPrivateMode ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0; + } + + function doTest(aIsPrivateMode, aWindow, aCallback) { + aWindow.gBrowser.selectedBrowser.addEventListener("load", function onLoad() { + aWindow.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true); + let sslStatus = new FakeSSLStatus(); + uri = aWindow.Services.io.newURI("https://localhost/img.png", null, null); + gSSService.processHeader(Ci.nsISiteSecurityService.HEADER_HSTS, uri, + "max-age=1000", sslStatus, privacyFlags(aIsPrivateMode)); + ok(gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HSTS, "localhost", privacyFlags(aIsPrivateMode)), "checking sts host"); + + aCallback(); + }, true); + + aWindow.gBrowser.selectedBrowser.loadURI(testURI); + } + + function testOnWindow(aOptions, aCallback) { + whenNewWindowLoaded(aOptions, function(aWin) { + windowsToClose.push(aWin); + // execute should only be called when need, like when you are opening + // web pages on the test. If calling executeSoon() is not necesary, then + // call whenNewWindowLoaded() instead of testOnWindow() on your test. + executeSoon(function() { aCallback(aWin); }); + }); + } + + // this function is called after calling finish() on the test. + registerCleanupFunction(function() { + windowsToClose.forEach(function(aWin) { + aWin.close(); + }); + uri = Services.io.newURI("http://localhost", null, null); + gSSService.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0); + }); + + // test first when on private mode + testOnWindow({private: true}, function(aWin) { + doTest(true, aWin, function() { + //test when not on private mode + testOnWindow({}, function(aWin) { + doTest(false, aWin, function() { + //test again when on private mode + testOnWindow({private: true}, function(aWin) { + doTest(true, aWin, function () { + finish(); + }); + }); + }); + }); + }); + }); +} diff --git a/security/manager/ssl/tests/mochitest/browser/browser_certViewer.js b/security/manager/ssl/tests/mochitest/browser/browser_certViewer.js new file mode 100644 index 000000000..d75f9f207 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_certViewer.js @@ -0,0 +1,224 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +// Repeatedly opens the certificate viewer dialog with various certificates and +// determines that the viewer correctly identifies either what usages those +// certificates are valid for or what errors prevented the certificates from +// being verified. + +var { OS } = Cu.import("resource://gre/modules/osfile.jsm", {}); + +add_task(function* testCAandTitle() { + let cert = yield readCertificate("ca.pem", "CTu,CTu,CTu"); + let win = yield displayCertificate(cert); + checkUsages(win, ["SSL Certificate Authority"]); + + // There's no real need to test the title for every cert, so we just test it + // once here. + Assert.equal(win.document.title, "Certificate Viewer: \u201Cca\u201D", + "Actual and expected title should match"); + yield BrowserTestUtils.closeWindow(win); +}); + +add_task(function* testSSLEndEntity() { + let cert = yield readCertificate("ssl-ee.pem", ",,"); + let win = yield displayCertificate(cert); + checkUsages(win, ["SSL Server Certificate", "SSL Client Certificate"]); + yield BrowserTestUtils.closeWindow(win); +}); + +add_task(function* testEmailEndEntity() { + let cert = yield readCertificate("email-ee.pem", ",,"); + let win = yield displayCertificate(cert); + checkUsages(win, ["Email Recipient Certificate", "Email Signer Certificate"]); + yield BrowserTestUtils.closeWindow(win); +}); + +add_task(function* testCodeSignEndEntity() { + let cert = yield readCertificate("code-ee.pem", ",,"); + let win = yield displayCertificate(cert); + checkUsages(win, ["Object Signer"]); + yield BrowserTestUtils.closeWindow(win); +}); + +add_task(function* testExpired() { + let cert = yield readCertificate("expired-ca.pem", ",,"); + let win = yield displayCertificate(cert); + checkError(win, "Could not verify this certificate because it has expired."); + yield BrowserTestUtils.closeWindow(win); +}); + +add_task(function* testIssuerExpired() { + let cert = yield readCertificate("ee-from-expired-ca.pem", ",,"); + let win = yield displayCertificate(cert); + checkError(win, + "Could not verify this certificate because the CA certificate " + + "is invalid."); + yield BrowserTestUtils.closeWindow(win); +}); + +add_task(function* testUnknownIssuer() { + let cert = yield readCertificate("unknown-issuer.pem", ",,"); + let win = yield displayCertificate(cert); + checkError(win, + "Could not verify this certificate because the issuer is " + + "unknown."); + yield BrowserTestUtils.closeWindow(win); +}); + +add_task(function* testInsecureAlgo() { + let cert = yield readCertificate("md5-ee.pem", ",,"); + let win = yield displayCertificate(cert); + checkError(win, + "Could not verify this certificate because it was signed using " + + "a signature algorithm that was disabled because that algorithm " + + "is not secure."); + yield BrowserTestUtils.closeWindow(win); +}); + +add_task(function* testUntrusted() { + let cert = yield readCertificate("untrusted-ca.pem", "p,p,p"); + let win = yield displayCertificate(cert); + checkError(win, + "Could not verify this certificate because it is not trusted."); + yield BrowserTestUtils.closeWindow(win); +}); + +add_task(function* testUntrustedIssuer() { + let cert = yield readCertificate("ee-from-untrusted-ca.pem", ",,"); + let win = yield displayCertificate(cert); + checkError(win, + "Could not verify this certificate because the issuer is not " + + "trusted."); + yield BrowserTestUtils.closeWindow(win); +}); + +add_task(function* testRevoked() { + // Note that there's currently no way to un-do this. This should only be a + // problem if another test re-uses a certificate with this same key (perhaps + // likely) and subject (less likely). + let certBlocklist = Cc["@mozilla.org/security/certblocklist;1"] + .getService(Ci.nsICertBlocklist); + certBlocklist.revokeCertBySubjectAndPubKey( + "MBIxEDAOBgNVBAMMB3Jldm9rZWQ=", // CN=revoked + "VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8="); // hash of the shared key + let cert = yield readCertificate("revoked.pem", ",,"); + let win = yield displayCertificate(cert); + // As of bug 1312827, OneCRL only applies to TLS web server certificates, so + // this certificate will actually verify successfully for every end-entity + // usage except TLS web server. + checkUsages(win, ["Email Recipient Certificate", "Email Signer Certificate", + "Object Signer", "SSL Client Certificate"]); + yield BrowserTestUtils.closeWindow(win); +}); + +add_task(function* testInvalid() { + // This certificate has a keyUsage extension asserting cRLSign and + // keyCertSign, but it doesn't have a basicConstraints extension. This + // shouldn't be valid for any usage. Sadly, we give a pretty lame error + // message in this case. + let cert = yield readCertificate("invalid.pem", ",,"); + let win = yield displayCertificate(cert); + checkError(win, "Could not verify this certificate for unknown reasons."); + yield BrowserTestUtils.closeWindow(win); +}); + +/** + * Given a certificate, returns a promise that will resolve when the certificate + * viewer has opened is displaying that certificate, and has finished + * determining its valid usages. + * + * @param {nsIX509Cert} certificate + * The certificate to view and determine usages for. + * @return {Promise} + * A promise that will resolve with a handle on the opened certificate + * viewer window when the usages have been determined. + */ +function displayCertificate(certificate) { + let win = window.openDialog("chrome://pippki/content/certViewer.xul", "", + "", certificate); + return TestUtils.topicObserved("ViewCertDetails:CertUsagesDone", + (subject, data) => subject == win) + .then(([subject, data]) => subject, error => { throw error; }); +} + +/** + * Given a certificate viewer window, finds the usages the certificate is valid + * for. + * + * @param {window} win + * The certificate viewer window. + * @return {String[]} + * An array of strings describing the usages the certificate is valid + * for. + */ +function getUsages(win) { + let determinedUsages = []; + let verifyInfoBox = win.document.getElementById("verify_info_box"); + Array.from(verifyInfoBox.children).forEach(child => { + if (child.getAttribute("hidden") != "true" && + child.getAttribute("id") != "verified") { + determinedUsages.push(child.getAttribute("value")); + } + }); + return determinedUsages.sort(); +} + +/** + * Given a certificate viewer window, returns the error string describing a + * failure encountered when determining the certificate's usages. It will be + * "This certificate has been verified for the following uses:" when the + * certificate has successfully verified for at least one usage. + * + * @param {window} win + * The certificate viewer window. + * @return {String} + * A string describing the error encountered, or the success message if + * the certificate is valid for at least one usage. + */ +function getError(win) { + return win.document.getElementById("verified").textContent; +} + +/** + * Given a certificate viewer window and an array of expected usage + * descriptions, verifies that the window is actually showing that the + * certificate has validated for those usages. + * + * @param {window} win + * The certificate viewer window. + * @param {String[]} usages + * An array of expected usage descriptions. + */ +function checkUsages(win, usages) { + Assert.equal(getError(win), + "This certificate has been verified for the following uses:", + "should have successful verification message"); + let determinedUsages = getUsages(win); + usages.sort(); + Assert.equal(determinedUsages.length, usages.length, + "number of usages as determined by cert viewer should be equal"); + while (usages.length > 0) { + Assert.equal(determinedUsages.pop(), usages.pop(), + "usages as determined by cert viewer should be equal"); + } +} + +/** + * Given a certificate viewer window and an expected error, verifies that the + * window is actually showing that error. + * + * @param {window} win + * The certificate viewer window. + * @param {String} error + * The expected error message. + */ +function checkError(win, error) { + let determinedUsages = getUsages(win); + Assert.equal(determinedUsages.length, 0, + "should not have any successful usages in error case"); + Assert.equal(getError(win), error, + "determined error should be the same as expected error"); +} diff --git a/security/manager/ssl/tests/mochitest/browser/browser_certificateManagerLeak.js b/security/manager/ssl/tests/mochitest/browser/browser_certificateManagerLeak.js new file mode 100644 index 000000000..d1db319d0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_certificateManagerLeak.js @@ -0,0 +1,32 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +var gBugWindow; + +function onLoad() { + gBugWindow.removeEventListener("load", onLoad); + gBugWindow.addEventListener("unload", onUnload); + gBugWindow.close(); +} + +function onUnload() { + gBugWindow.removeEventListener("unload", onUnload); + window.focus(); + finish(); +} + +// This test opens and then closes the certificate manager to test that it +// does not leak. The test harness keeps track of and reports leaks, so +// there are no actual checks here. +function test() { + waitForExplicitFinish(); + + // This test relies on the test timing out in order to indicate failure so + // let's add a dummy pass. + ok(true, "Each test requires at least one pass, fail or todo so here is a pass."); + + gBugWindow = window.openDialog("chrome://pippki/content/certManager.xul"); + gBugWindow.addEventListener("load", onLoad); +} diff --git a/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_connection.js b/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_connection.js new file mode 100644 index 000000000..6362fd34d --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_connection.js @@ -0,0 +1,135 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests various scenarios connecting to a server that requires client cert +// authentication. Also tests that nsIClientAuthDialogs.chooseCertificate +// is called at the appropriate times and with the correct arguments. + +const { MockRegistrar } = + Cu.import("resource://testing-common/MockRegistrar.jsm", {}); + +const DialogState = { + // Assert that chooseCertificate() is never called. + ASSERT_NOT_CALLED: "ASSERT_NOT_CALLED", + // Return that the user selected the first given cert. + RETURN_CERT_SELECTED: "RETURN_CERT_SELECTED", + // Return that the user canceled. + RETURN_CERT_NOT_SELECTED: "RETURN_CERT_NOT_SELECTED", +}; + +let sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing); + +// Mock implementation of nsIClientAuthDialogs. +const gClientAuthDialogs = { + _state: DialogState.ASSERT_NOT_CALLED, + + set state(newState) { + info(`old state: ${this._state}`); + this._state = newState; + info(`new state: ${this._state}`); + }, + + get state() { + return this._state; + }, + + chooseCertificate(ctx, hostname, port, organization, issuerOrg, certList, + selectedIndex) { + Assert.notEqual(this.state, DialogState.ASSERT_NOT_CALLED, + "chooseCertificate() should be called only when expected"); + + let caud = ctx.QueryInterface(Ci.nsIClientAuthUserDecision); + Assert.notEqual(caud, null, + "nsIClientAuthUserDecision should be queryable from the " + + "given context"); + caud.rememberClientAuthCertificate = false; + + Assert.equal(hostname, "requireclientcert.example.com", + "Hostname should be 'requireclientcert.example.com'"); + Assert.equal(port, 443, "Port should be 443"); + Assert.equal(organization, "", + "Server cert Organization should be empty/not present"); + Assert.equal(issuerOrg, "Mozilla Testing", + "Server cert issuer Organization should be 'Mozilla Testing'"); + + // For mochitests, only the cert at build/pgo/certs/mochitest.client should + // be selectable, so we do some brief checks to confirm this. + Assert.notEqual(certList, null, "Cert list should not be null"); + Assert.equal(certList.length, 1, "Only 1 certificate should be available"); + let cert = certList.queryElementAt(0, Ci.nsIX509Cert); + Assert.notEqual(cert, null, "Cert list should contain an nsIX509Cert"); + Assert.equal(cert.commonName, "Mochitest client", + "Cert CN should be 'Mochitest client'"); + + if (this.state == DialogState.RETURN_CERT_SELECTED) { + selectedIndex.value = 0; + return true; + } + return false; + }, + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIClientAuthDialogs]) +}; + +add_task(function* setup() { + let clientAuthDialogsCID = + MockRegistrar.register("@mozilla.org/nsClientAuthDialogs;1", + gClientAuthDialogs); + registerCleanupFunction(() => { + MockRegistrar.unregister(clientAuthDialogsCID); + }); +}); + +/** + * Test helper for the tests below. + * + * @param {String} prefValue + * Value to set the "security.default_personal_cert" pref to. + * @param {String} expectedURL + * If the connection is expected to load successfully, the URL that + * should load. If the connection is expected to fail and result in an + * error page, |undefined|. + */ +function* testHelper(prefValue, expectedURL) { + yield SpecialPowers.pushPrefEnv({"set": [ + ["security.default_personal_cert", prefValue], + ]}); + + yield BrowserTestUtils.loadURI(gBrowser.selectedBrowser, + "https://requireclientcert.example.com:443"); + + // |loadedURL| will be a string URL if browserLoaded() wins the race, or + // |undefined| if waitForErrorPage() wins the race. + let loadedURL = yield Promise.race([ + BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser), + BrowserTestUtils.waitForErrorPage(gBrowser.selectedBrowser), + ]); + Assert.equal(expectedURL, loadedURL, "Expected and actual URLs should match"); + + // Ensure previously successful connections don't influence future tests. + sdr.logoutAndTeardown(); +} + +// Test that if a certificate is chosen automatically the connection succeeds, +// and that nsIClientAuthDialogs.chooseCertificate() is never called. +add_task(function* testCertChosenAutomatically() { + gClientAuthDialogs.state = DialogState.ASSERT_NOT_CALLED; + yield* testHelper("Select Automatically", + "https://requireclientcert.example.com/"); +}); + +// Test that if the user doesn't choose a certificate, the connection fails and +// an error page is displayed. +add_task(function* testCertNotChosenByUser() { + gClientAuthDialogs.state = DialogState.RETURN_CERT_NOT_SELECTED; + yield* testHelper("Ask Every Time", undefined); +}); + +// Test that if the user chooses a certificate the connection suceeeds. +add_task(function* testCertChosenByUser() { + gClientAuthDialogs.state = DialogState.RETURN_CERT_SELECTED; + yield* testHelper("Ask Every Time", + "https://requireclientcert.example.com/"); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_ui.js b/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_ui.js new file mode 100644 index 000000000..bf4f179c0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_ui.js @@ -0,0 +1,137 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the client authentication certificate chooser correctly displays +// provided information and correctly returns user input. + +const TEST_HOSTNAME = "Test Hostname"; +const TEST_ORG = "Test Org"; +const TEST_ISSUER_ORG = "Test Issuer Org"; +const TEST_PORT = 123; + +var certDB = Cc["@mozilla.org/security/x509certdb;1"] + .getService(Ci.nsIX509CertDB); +/** + * Test certificate (i.e. build/pgo/certs/mochitest.client). + * @type nsIX509Cert + */ +var cert; + +/** + * Opens the client auth cert chooser dialog. + * + * @param {nsIX509Cert} cert The cert to pass to the dialog for display. + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * an array consisting of: + * 1. The window of the opened dialog. + * 2. The return value nsIWritablePropertyBag2 passed to the dialog. + */ +function openClientAuthDialog(cert) { + let certList = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); + certList.appendElement(cert, false); + + let returnVals = Cc["@mozilla.org/hash-property-bag;1"] + .createInstance(Ci.nsIWritablePropertyBag2); + let win = window.openDialog("chrome://pippki/content/clientauthask.xul", "", + "", TEST_HOSTNAME, TEST_ORG, TEST_ISSUER_ORG, + TEST_PORT, certList, returnVals); + return new Promise((resolve, reject) => { + win.addEventListener("load", function onLoad() { + win.removeEventListener("load", onLoad); + resolve([win, returnVals]); + }); + }); +} + +/** + * Checks that the contents of the given cert chooser dialog match the details + * of build/pgo/certs/mochitest.client. + * + * @param {window} win The cert chooser window. + * @param {String} notBefore + * The notBeforeLocalTime attribute of mochitest.client. + * @param {String} notAfter + * The notAfterLocalTime attribute of mochitest.client. + */ +function checkDialogContents(win, notBefore, notAfter) { + Assert.equal(win.document.getElementById("hostname").textContent, + `${TEST_HOSTNAME}:${TEST_PORT}`, + "Actual and expected hostname and port should be equal"); + // “ and ” don't seem to work when embedded in the following literals, which + // is why escape codes are used instead. + Assert.equal(win.document.getElementById("organization").textContent, + `Organization: \u201C${TEST_ORG}\u201D`, + "Actual and expected organization should be equal"); + Assert.equal(win.document.getElementById("issuer").textContent, + `Issued Under: \u201C${TEST_ISSUER_ORG}\u201D`, + "Actual and expected issuer organization should be equal"); + + Assert.equal(win.document.getElementById("nicknames").label, + "test client certificate [03]", + "Actual and expected selected cert nickname and serial should " + + "be equal"); + + let [subject, serialNum, validity, issuer, tokenName] = + win.document.getElementById("details").value.split("\n"); + Assert.equal(subject, "Issued to: CN=Mochitest client", + "Actual and expected subject should be equal"); + Assert.equal(serialNum, "Serial number: 03", + "Actual and expected serial number should be equal"); + Assert.equal(validity, `Valid from ${notBefore} to ${notAfter}`, + "Actual and expected validity should be equal"); + Assert.equal(issuer, + "Issued by: CN=Temporary Certificate Authority,O=Mozilla " + + "Testing,OU=Profile Guided Optimization", + "Actual and expected issuer should be equal"); + Assert.equal(tokenName, "Stored on: Software Security Device", + "Actual and expected token name should be equal"); +} + +add_task(function* setup() { + cert = certDB.findCertByNickname("test client certificate"); + Assert.notEqual(cert, null, "Should be able to find the test client cert"); +}); + +// Test that the contents of the dialog correspond to the details of the +// provided cert. +add_task(function* testContents() { + let [win, retVals] = yield openClientAuthDialog(cert); + checkDialogContents(win, cert.validity.notBeforeLocalTime, + cert.validity.notAfterLocalTime); + yield BrowserTestUtils.closeWindow(win); +}); + +// Test that the right values are returned when the dialog is accepted. +add_task(function* testAcceptDialogReturnValues() { + let [win, retVals] = yield openClientAuthDialog(cert); + win.document.getElementById("rememberBox").checked = true; + info("Accepting dialog"); + win.document.getElementById("certAuthAsk").acceptDialog(); + yield BrowserTestUtils.windowClosed(win); + + Assert.ok(retVals.get("certChosen"), + "Return value should signal user chose a certificate"); + Assert.equal(retVals.get("selectedIndex"), 0, + "0 should be returned as the selected index"); + Assert.ok(retVals.get("rememberSelection"), + "Return value should signal 'Remember this decision' checkbox was" + + "checked"); +}); + +// Test that the right values are returned when the dialog is canceled. +add_task(function* testCancelDialogReturnValues() { + let [win, retVals] = yield openClientAuthDialog(cert); + win.document.getElementById("rememberBox").checked = false; + info("Canceling dialog"); + win.document.getElementById("certAuthAsk").cancelDialog(); + yield BrowserTestUtils.windowClosed(win); + + Assert.ok(!retVals.get("certChosen"), + "Return value should signal user did not choose a certificate"); + Assert.ok(!retVals.get("rememberSelection"), + "Return value should signal 'Remember this decision' checkbox was" + + "unchecked"); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_deleteCert_ui.js b/security/manager/ssl/tests/mochitest/browser/browser_deleteCert_ui.js new file mode 100644 index 000000000..b0ac8f95c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_deleteCert_ui.js @@ -0,0 +1,215 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests various aspects of the cert delete confirmation dialog. +// Among other things, tests that for each type of cert that can be deleted: +// 1. The various lines of explanation text are correctly set. +// 2. The implementation correctly falls back through multiple cert attributes +// to determine what to display to represent a cert. + +/** + * An array of tree items corresponding to TEST_CASES. + * @type nsICertTreeItem[] + */ +var gCertArray = []; + +const FAKE_HOST_PORT = "Fake host and port"; + +/** + * @typedef {TestCase} + * @type Object + * @property {String} certFilename + * Filename of the cert, or null if we don't want to import a cert for + * this test case (i.e. we expect the hostPort attribute of + * nsICertTreeItem to be used). + * @property {String} expectedDisplayString + * The string we expect the UI to display to represent the given cert. + */ + +/** + * A list of test cases representing certs that get "deleted". + * @type TestCase[] + */ +const TEST_CASES = [ + { certFilename: null, + expectedDisplayString: FAKE_HOST_PORT }, + { certFilename: "has-cn.pem", + expectedDisplayString: "Foo" }, + { certFilename: "has-ou.pem", + expectedDisplayString: "Bar" }, + { certFilename: "has-o.pem", + expectedDisplayString: "Baz" }, + { certFilename: "has-non-empty-subject.pem", + expectedDisplayString: "C=US" }, + { certFilename: "has-empty-subject.pem", + expectedDisplayString: "Certificate with serial number: 0A" }, +]; + +/** + * Opens the cert delete confirmation dialog. + * + * @param {String} tabID + * The ID of the cert category tab the certs to delete belong to. + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * an array consisting of: + * 1. The window of the opened dialog. + * 2. The return value object passed to the dialog. + */ +function openDeleteCertConfirmDialog(tabID) { + let retVals = { + deleteConfirmed: false, + }; + let win = window.openDialog("chrome://pippki/content/deletecert.xul", "", "", + tabID, gCertArray, retVals); + return new Promise((resolve, reject) => { + win.addEventListener("load", function onLoad() { + win.removeEventListener("load", onLoad); + resolve([win, retVals]); + }); + }); +} + +add_task(function* setup() { + for (let testCase of TEST_CASES) { + let cert = null; + if (testCase.certFilename) { + cert = yield readCertificate(testCase.certFilename, ",,"); + } + let certTreeItem = { + hostPort: FAKE_HOST_PORT, + cert: cert, + QueryInterface(iid) { + if (iid.equals(Ci.nsICertTreeItem)) { + return this; + } + + throw new Error(Cr.NS_ERROR_NO_INTERFACE); + } + }; + gCertArray.push(certTreeItem); + } +}); + +/** + * Test helper for the below test cases. + * + * @param {String} tabID + * ID of the cert category tab the certs to delete belong to. + * @param {String} expectedTitle + * Title the dialog is expected to have. + * @param {String} expectedConfirmMsg + * Confirmation message the dialog is expected to show. + * @param {String} expectedImpact + * Impact the dialog is expected to show. + */ +function* testHelper(tabID, expectedTitle, expectedConfirmMsg, expectedImpact) { + let [win, retVals] = yield openDeleteCertConfirmDialog(tabID); + let certList = win.document.getElementById("certlist"); + + Assert.equal(win.document.title, expectedTitle, + `Actual and expected titles should match for ${tabID}`); + Assert.equal(win.document.getElementById("confirm").textContent, + expectedConfirmMsg, + `Actual and expected confirm message should match for ${tabID}`); + Assert.equal(win.document.getElementById("impact").textContent, + expectedImpact, + `Actual and expected impact should match for ${tabID}`); + + Assert.equal(certList.itemCount, TEST_CASES.length, + `No. of certs displayed should match for ${tabID}`); + for (let i = 0; i < certList.itemCount; i++) { + Assert.equal(certList.getItemAtIndex(i).label, + TEST_CASES[i].expectedDisplayString, + "Actual and expected display string should match for " + + `index ${i} for ${tabID}`); + } + + yield BrowserTestUtils.closeWindow(win); +} + +// Test deleting certs from the "Your Certificates" tab. +add_task(function* testDeletePersonalCerts() { + const expectedTitle = "Delete your Certificates"; + const expectedConfirmMsg = + "Are you sure you want to delete these certificates?"; + const expectedImpact = + "If you delete one of your own certificates, you can no longer use it to " + + "identify yourself."; + yield* testHelper("mine_tab", expectedTitle, expectedConfirmMsg, + expectedImpact); +}); + +// Test deleting certs from the "People" tab. +add_task(function* testDeleteOtherPeopleCerts() { + const expectedTitle = "Delete E-Mail Certificates"; + // ’ doesn't seem to work when embedded in the following literals, which is + // why escape codes are used instead. + const expectedConfirmMsg = + "Are you sure you want to delete these people\u2019s e-mail certificates?"; + const expectedImpact = + "If you delete a person\u2019s e-mail certificate, you will no longer be " + + "able to send encrypted e-mail to that person."; + yield* testHelper("others_tab", expectedTitle, expectedConfirmMsg, + expectedImpact); +}); + +// Test deleting certs from the "Servers" tab. +add_task(function* testDeleteServerCerts() { + const expectedTitle = "Delete Server Certificate Exceptions"; + const expectedConfirmMsg = + "Are you sure you want to delete these server exceptions?"; + const expectedImpact = + "If you delete a server exception, you restore the usual security checks " + + "for that server and require it uses a valid certificate."; + yield* testHelper("websites_tab", expectedTitle, expectedConfirmMsg, + expectedImpact); +}); + +// Test deleting certs from the "Authorities" tab. +add_task(function* testDeleteCACerts() { + const expectedTitle = "Delete or Distrust CA Certificates"; + const expectedConfirmMsg = + "You have requested to delete these CA certificates. For built-in " + + "certificates all trust will be removed, which has the same effect. Are " + + "you sure you want to delete or distrust?"; + const expectedImpact = + "If you delete or distrust a certificate authority (CA) certificate, " + + "this application will no longer trust any certificates issued by that CA."; + yield* testHelper("ca_tab", expectedTitle, expectedConfirmMsg, + expectedImpact); +}); + +// Test deleting certs from the "Other" tab. +add_task(function* testDeleteOtherCerts() { + const expectedTitle = "Delete Certificates"; + const expectedConfirmMsg = + "Are you sure you want to delete these certificates?"; + const expectedImpact = ""; + yield* testHelper("orphan_tab", expectedTitle, expectedConfirmMsg, + expectedImpact); +}); + +// Test that the right values are returned when the dialog is accepted. +add_task(function* testAcceptDialogReturnValues() { + let [win, retVals] = yield openDeleteCertConfirmDialog("ca_tab" /*arbitrary*/); + info("Accepting dialog"); + win.document.getElementById("deleteCertificate").acceptDialog(); + yield BrowserTestUtils.windowClosed(win); + + Assert.ok(retVals.deleteConfirmed, + "Return value should signal user accepted"); +}); + +// Test that the right values are returned when the dialog is canceled. +add_task(function* testCancelDialogReturnValues() { + let [win, retVals] = yield openDeleteCertConfirmDialog("ca_tab" /*arbitrary*/); + info("Canceling dialog"); + win.document.getElementById("deleteCertificate").cancelDialog(); + yield BrowserTestUtils.windowClosed(win); + + Assert.ok(!retVals.deleteConfirmed, + "Return value should signal user did not accept"); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js b/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js new file mode 100644 index 000000000..cbd59f883 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js @@ -0,0 +1,150 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the cert download/import UI correctly identifies the cert being +// downloaded, and allows the trust of the cert to be specified. + +const { MockRegistrar } = + Cu.import("resource://testing-common/MockRegistrar.jsm", {}); + +/** + * @typedef {TestCase} + * @type Object + * @property {String} certFilename + * Filename of the cert for this test case. + * @property {String} expectedDisplayString + * The string we expect the UI to display to represent the given cert. + * @property {nsIX509Cert} cert + * Handle to the cert once read in setup(). + */ + +/** + * A list of test cases representing certs that get "downloaded". + * @type TestCase[] + */ +const TEST_CASES = [ + { certFilename: "has-cn.pem", + expectedDisplayString: "Foo", + cert: null }, + { certFilename: "has-empty-subject.pem", + expectedDisplayString: "Certificate Authority (unnamed)", + cert: null }, +]; + +/** + * Opens the cert download dialog. + * + * @param {nsIX509Cert} cert + * The cert to pass to the dialog for display. + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * an array consisting of: + * 1. The window of the opened dialog. + * 2. The return value nsIWritablePropertyBag2 passed to the dialog. + */ +function openCertDownloadDialog(cert) { + let returnVals = Cc["@mozilla.org/hash-property-bag;1"] + .createInstance(Ci.nsIWritablePropertyBag2); + let win = window.openDialog("chrome://pippki/content/downloadcert.xul", "", + "", cert, returnVals); + return new Promise((resolve, reject) => { + win.addEventListener("load", function onLoad() { + win.removeEventListener("load", onLoad); + resolve([win, returnVals]); + }); + }); +} + +// Mock implementation of nsICertificateDialogs. +const gCertificateDialogs = { + expectedCert: null, + viewCertCallCount: 0, + confirmDownloadCACert(ctx, cert, trust) { + Assert.ok(false, "confirmDownloadCACert() should not have been called"); + }, + setPKCS12FilePassword(ctx, password) { + Assert.ok(false, "setPKCS12FilePassword() should not have been called"); + }, + getPKCS12FilePassword(ctx, password) { + Assert.ok(false, "getPKCS12FilePassword() should not have been called"); + }, + viewCert(ctx, cert) { + this.viewCertCallCount++; + Assert.notEqual(cert, null, "Cert to view should not be null"); + Assert.equal(cert, this.expectedCert, + "Actual and expected cert should match"); + }, + + QueryInterface: XPCOMUtils.generateQI([Ci.nsICertificateDialogs]) +}; + +add_task(function* setup() { + for (let testCase of TEST_CASES) { + testCase.cert = yield readCertificate(testCase.certFilename, ",,"); + Assert.notEqual(testCase.cert, null, + `'${testCase.certFilename}' should have been read`); + } + + let certificateDialogsCID = + MockRegistrar.register("@mozilla.org/nsCertificateDialogs;1", + gCertificateDialogs); + registerCleanupFunction(() => { + MockRegistrar.unregister(certificateDialogsCID); + }); +}); + +// Test that the trust header message corresponds to the provided cert, and that +// the View Cert button launches the cert viewer for the provided cert. +add_task(function* testTrustHeaderAndViewCertButton() { + for (let testCase of TEST_CASES) { + let [win, retVals] = yield openCertDownloadDialog(testCase.cert); + let expectedTrustHeaderString = + `Do you want to trust \u201C${testCase.expectedDisplayString}\u201D ` + + "for the following purposes?"; + Assert.equal(win.document.getElementById("trustHeader").textContent, + expectedTrustHeaderString, + "Actual and expected trust header text should match for " + + `${testCase.certFilename}`); + + gCertificateDialogs.viewCertCallCount = 0; + gCertificateDialogs.expectedCert = testCase.cert; + info("Pressing View Cert button"); + win.document.getElementById("viewC-button").doCommand(); + Assert.equal(gCertificateDialogs.viewCertCallCount, 1, + "viewCert() should've been called once"); + + yield BrowserTestUtils.closeWindow(win); + } +}); + +// Test that the right values are returned when the dialog is accepted. +add_task(function* testAcceptDialogReturnValues() { + let [win, retVals] = yield openCertDownloadDialog(TEST_CASES[0].cert); + win.document.getElementById("trustSSL").checked = true; + win.document.getElementById("trustEmail").checked = false; + win.document.getElementById("trustObjSign").checked = true; + info("Accepting dialog"); + win.document.getElementById("download_cert").acceptDialog(); + yield BrowserTestUtils.windowClosed(win); + + Assert.ok(retVals.get("importConfirmed"), + "Return value should signal user chose to import the cert"); + Assert.ok(retVals.get("trustForSSL"), + "Return value should signal SSL trust checkbox was checked"); + Assert.ok(!retVals.get("trustForEmail"), + "Return value should signal E-mail trust checkbox was unchecked"); + Assert.ok(retVals.get("trustForObjSign"), + "Return value should signal Obj Sign trust checkbox was checked"); +}); + +// Test that the right values are returned when the dialog is canceled. +add_task(function* testCancelDialogReturnValues() { + let [win, retVals] = yield openCertDownloadDialog(TEST_CASES[0].cert); + info("Canceling dialog"); + win.document.getElementById("download_cert").cancelDialog(); + yield BrowserTestUtils.windowClosed(win); + + Assert.ok(!retVals.get("importConfirmed"), + "Return value should signal user chose not to import the cert"); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js b/security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js new file mode 100644 index 000000000..bc87732a5 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js @@ -0,0 +1,119 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the UI for editing the trust of a CA certificate correctly +// reflects trust in the cert DB, and correctly updates trust in the cert DB +// when requested. + +var gCertDB = Cc["@mozilla.org/security/x509certdb;1"] + .getService(Ci.nsIX509CertDB); + +/** + * The cert we're editing the trust of. + * @type nsIX509Cert + */ +var gCert; + +/** + * Opens the cert trust editing dialog. + * + * @returns {Promise} + * A promise that resolves when the dialog has finished loading with + * the window of the opened dialog. + */ +function openEditCertTrustDialog() { + let win = window.openDialog("chrome://pippki/content/editcacert.xul", "", "", + gCert); + return new Promise((resolve, reject) => { + win.addEventListener("load", function onLoad() { + win.removeEventListener("load", onLoad); + resolve(win); + }); + }); +} + +add_task(function* setup() { + // Initially trust ca.pem for SSL, but not e-mail or object signing. + gCert = yield readCertificate("ca.pem", "CT,,"); + Assert.ok(gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL), + "Sanity check: ca.pem should be trusted for SSL"); + Assert.ok(!gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_EMAIL), + "Sanity check: ca.pem should not be trusted for e-mail"); + Assert.ok(!gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_OBJSIGN), + "Sanity check: ca.pem should not be trusted for object signing"); +}); + +// Tests the following: +// 1. The checkboxes correctly reflect the trust set in setup(). +// 2. Accepting the dialog after flipping some of the checkboxes results in the +// correct trust being set in the cert DB. +add_task(function* testAcceptDialog() { + let win = yield openEditCertTrustDialog(); + + let sslCheckbox = win.document.getElementById("trustSSL"); + let emailCheckbox = win.document.getElementById("trustEmail"); + let objSignCheckbox = win.document.getElementById("trustObjSign"); + Assert.ok(sslCheckbox.checked, + "Cert should be trusted for SSL in UI"); + Assert.ok(!emailCheckbox.checked, + "Cert should not be trusted for e-mail in UI"); + Assert.ok(!objSignCheckbox.checked, + "Cert should not be trusted for object signing in UI"); + + sslCheckbox.checked = false; + emailCheckbox.checked = true; + + info("Accepting dialog"); + win.document.getElementById("editCaCert").acceptDialog(); + yield BrowserTestUtils.windowClosed(win); + + Assert.ok(!gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL), + "Cert should no longer be trusted for SSL"); + Assert.ok(gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_EMAIL), + "Cert should now be trusted for e-mail"); + Assert.ok(!gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_OBJSIGN), + "Cert should still not be trusted for object signing"); +}); + +// Tests the following: +// 1. The checkboxes correctly reflect the trust set in testAcceptDialog(). +// 2. Canceling the dialog even after flipping the checkboxes doesn't result in +// a change of trust in the cert DB. +add_task(function* testCancelDialog() { + let win = yield openEditCertTrustDialog(); + + let sslCheckbox = win.document.getElementById("trustSSL"); + let emailCheckbox = win.document.getElementById("trustEmail"); + let objSignCheckbox = win.document.getElementById("trustObjSign"); + Assert.ok(!sslCheckbox.checked, + "Cert should not be trusted for SSL in UI"); + Assert.ok(emailCheckbox.checked, + "Cert should be trusted for e-mail in UI"); + Assert.ok(!objSignCheckbox.checked, + "Cert should not be trusted for object signing in UI"); + + sslCheckbox.checked = true; + emailCheckbox.checked = false; + objSignCheckbox.checked = true; + + info("Canceling dialog"); + win.document.getElementById("editCaCert").cancelDialog(); + yield BrowserTestUtils.windowClosed(win); + + Assert.ok(!gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL), + "Cert should still not be trusted for SSL"); + Assert.ok(gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_EMAIL), + "Cert should still be trusted for e-mail"); + Assert.ok(!gCertDB.isCertTrusted(gCert, Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_OBJSIGN), + "Cert should still not be trusted for object signing"); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js b/security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js new file mode 100644 index 000000000..fc7591ece --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js @@ -0,0 +1,142 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the UI for setting the password on a to be exported PKCS #12 file: +// 1. Correctly requires the password to be typed in twice as confirmation. +// 2. Calculates and displays the strength of said password. + +/** + * @typedef {TestCase} + * @type Object + * @property {String} name + * The name of the test case for display purposes. + * @property {String} password1 + * The password to enter into the first password textbox. + * @property {String} password2 + * The password to enter into the second password textbox. + * @property {String} strength + * The expected strength of the password in the range [0, 100]. + */ + +/** + * A list of test cases representing various inputs to the password textboxes. + * @type TestCase[] + */ +const TEST_CASES = [ + { name: "empty", + password1: "", + password2: "", + strength: "0" }, + { name: "match-weak", + password1: "foo", + password2: "foo", + strength: "10" }, + { name: "match-medium", + password1: "foo123", + password2: "foo123", + strength: "60" }, + { name: "match-strong", + password1: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三", + password2: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三", + strength: "100" }, + { name: "mismatch-weak", + password1: "foo", + password2: "bar", + strength: "10" }, + { name: "mismatch-medium", + password1: "foo123", + password2: "bar", + strength: "60" }, + { name: "mismatch-strong", + password1: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三", + password2: "bar", + strength: "100" }, +]; + +/** + * Opens the dialog shown to set the password on a PKCS #12 file being exported. + * + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * an array consisting of: + * 1. The window of the opened dialog. + * 2. The return value nsIWritablePropertyBag2 passed to the dialog. + */ +function openSetP12PasswordDialog() { + let returnVals = Cc["@mozilla.org/hash-property-bag;1"] + .createInstance(Ci.nsIWritablePropertyBag2); + let win = window.openDialog("chrome://pippki/content/setp12password.xul", "", + "", returnVals); + return new Promise((resolve, reject) => { + win.addEventListener("load", function onLoad() { + win.removeEventListener("load", onLoad); + resolve([win, returnVals]); + }); + }); +} + +// Tests that the first password textbox is the element that is initially +// focused. +add_task(function* testFocus() { + let [win, retVals] = yield openSetP12PasswordDialog(); + Assert.equal(win.document.activeElement, + win.document.getElementById("pw1").inputField, + "First password textbox should have focus"); + yield BrowserTestUtils.closeWindow(win); +}); + +// Tests that the password strength algorithm used is reasonable, and that the +// Accept button is only enabled if the two passwords match. +add_task(function* testPasswordStrengthAndEquality() { + let [win, retVals] = yield openSetP12PasswordDialog(); + let password1Textbox = win.document.getElementById("pw1"); + let password2Textbox = win.document.getElementById("pw2"); + let strengthProgressBar = win.document.getElementById("pwmeter"); + + for (let testCase of TEST_CASES) { + password1Textbox.value = testCase.password1; + password2Textbox.value = testCase.password2; + // Setting the value of the password textboxes via |.value| apparently + // doesn't cause the oninput handlers to be called, so we do it here. + password1Textbox.oninput(); + password2Textbox.oninput(); + + Assert.equal(win.document.documentElement.getButton("accept").disabled, + password1Textbox.value != password2Textbox.value, + "Actual and expected accept button disable state should " + + `match for ${testCase.name}`); + Assert.equal(strengthProgressBar.value, testCase.strength, + "Actual and expected strength value should match for" + + `${testCase.name}`); + } + + yield BrowserTestUtils.closeWindow(win); +}); + +// Test that the right values are returned when the dialog is accepted. +add_task(function* testAcceptDialogReturnValues() { + let [win, retVals] = yield openSetP12PasswordDialog(); + const password = "fooBAR 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三"; + win.document.getElementById("pw1").value = password; + win.document.getElementById("pw2").value = password; + info("Accepting dialog"); + win.document.getElementById("setp12password").acceptDialog(); + yield BrowserTestUtils.windowClosed(win); + + Assert.ok(retVals.get("confirmedPassword"), + "Return value should signal user confirmed a password"); + Assert.equal(retVals.get("password"), password, + "Actual and expected password should match"); +}); + +// Test that the right values are returned when the dialog is canceled. +add_task(function* testCancelDialogReturnValues() { + let [win, retVals] = yield openSetP12PasswordDialog(); + info("Canceling dialog"); + win.document.getElementById("setp12password").cancelDialog(); + yield BrowserTestUtils.windowClosed(win); + + Assert.ok(!retVals.get("confirmedPassword"), + "Return value should signal user didn't confirm a password"); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/ca.pem b/security/manager/ssl/tests/mochitest/browser/ca.pem new file mode 100644 index 000000000..1a18e2bf0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxTCCAa+gAwIBAgIUL5zykZEc2ro5d6th43aWGfm735cwCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMA0xCzAJBgNVBAMMAmNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu +Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO +7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf +qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt +HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx +uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1Ud +DwQEAwIBBjALBgkqhkiG9w0BAQsDggEBAHPYBjNnv//Ssc8Elepb8SWIXRdahKbL +/dcPoMR+7yhJVaelUaxdwUytJWJAGdkkuv+P+G4b82RVYEXT+9k1S/aAfByFyR9q +vS7POfdy/ZPfGTXltlnmYX/84a6QeYQa4Nl4JpIOXBCesLxmErBhczka6D26iqsz +GeseKRSjVPgF3mXc2CRGZnTDRhUmd7wOABLmj7GtuFvOm96363M3IUByMohvoj1G +dic3s5D0seXwTKnEc5B27lJt7Q0oIXEldL+UW8Mo1hfGWQeXzqTZbpOVLnVWvHBH +H8yYs5hyH01qFJZbztJ1JJ3F2NpYLlr4P5I6fW2e9w5MG/VMQRU3wzQ= +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/ca.pem.certspec new file mode 100644 index 000000000..6660f5d47 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/mochitest/browser/code-ee.pem b/security/manager/ssl/tests/mochitest/browser/code-ee.pem new file mode 100644 index 000000000..a4fdfaed7 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/code-ee.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxDCCAa6gAwIBAgIUSbYQoLY1s6wWqgbKhxQZ3XME7ukwCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMBIxEDAOBgNVBAMMB2NvZGUtZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9 +sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5 +TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7 +xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd +tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l +8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsG +AQUFBwMDMAsGCSqGSIb3DQEBCwOCAQEAV69uBbyc/d1eBdZlT7eAw4onQzkdndd8 +kEXdmP3hd+jJm1+/F733IflLLqE5mmUL9l7q7EJ+TgdZa19T6JHEaVjdJcIuwJO/ +kKSJXXqADQXoxHOZADDWjAFStiR3xd78BzYfuUANgozG6hq7QuVh0cYBx/8Q9gx/ +pGtuCJiN0d2Mknu0SoQzIZlXTuqmnFj7G/88O5Yh5MaFZxbvIJJSIWQoS396GrI6 +yXAdqHNoVM9mwwaMcnG5QeeKSIPuvEkZncQsxFc0zqIjeOVx/zEx2Bocx71dLuVB +fqrIrAXLpwparoSxLzNqq8UgtXF8NQOuAcUu7ok0r1VbdMbSZHZ3Gg== +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/code-ee.pem.certspec b/security/manager/ssl/tests/mochitest/browser/code-ee.pem.certspec new file mode 100644 index 000000000..93f9a8426 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/code-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:code-ee +extension:extKeyUsage:codeSigning diff --git a/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem b/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem new file mode 100644 index 000000000..5b2cfd940 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvjCCAaigAwIBAgIUGzSP8KEmmRm3sIPiyQW35sazlHEwCwYJKoZIhvcNAQEL +MBUxEzARBgNVBAMMCmV4cGlyZWQtY2EwIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4 +MDIwNTAwMDAwMFowHTEbMBkGA1UEAwwSZWUtZnJvbS1leHBpcmVkLWNhMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +MAsGCSqGSIb3DQEBCwOCAQEAZ6Nrb/1fit8cALMhcbmuZ5kd3J34d0o9p3g3E7m7 +8RsTbYLA4xp9UmSzpO/10x9q4TUZ8jxW1dotoCVf7OqYYxQewrU2x3qoxKvP/Fvf +8ssWSIang91w+app+fv7QYDySymT6DJMLWyCmxyhaFjYnmr67GKldcgK9hbyjfDB +Rj382czI/HMSvw/vCB6rRKchzr5hsDGl+YN0MMI4M7/3b5wvMUmxlXqKu1VlslDZ +8Ez6ONuMdPJD3aQZMxmEph05pEMvhjFhLh+0n7kfLR+9n0D7IR9paVc6LgHLLxsP +ENoZLGOwJYNdAwwkd6fIa9E6KCpaRgyvWslm+iFCg3XxoA== +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem.certspec new file mode 100644 index 000000000..3e280fc4f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem.certspec @@ -0,0 +1,2 @@ +issuer:expired-ca +subject:ee-from-expired-ca diff --git a/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem b/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem new file mode 100644 index 000000000..ad2d988e0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwjCCAaygAwIBAgIUI/4Y+KSEZo8YGQK6Ptrdmev5FO0wCwYJKoZIhvcNAQEL +MBcxFTATBgNVBAMMDHVudHJ1c3RlZC1jYTAiGA8yMDE1MTEyODAwMDAwMFoYDzIw +MTgwMjA1MDAwMDAwWjAfMR0wGwYDVQQDDBRlZS1mcm9tLXVudHJ1c3RlZC1jYTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAATALBgkqhkiG9w0BAQsDggEBAJqsDDoJqxrmV4Mlt815HmJwhr/SuYhPwhoQ +RyU56Ci5kY/8fYa3F1uxSrpzuiYBX4bq6g8keXmltPZGN9gexPP2QJDAecNt0NKW ++04ZKSiz6Tbu+MEyBaXCINDKaAHVPRnbMWR1eCyHzYpZRKZW2Sb2NinWGebzq0mI +wt5l7veMkL5ZbeYF8u8bNFsdvhl1PM7/AfAZLJL4+fncaqQeDRyVffxrl4mCooS9 +DYajnw7AhFvN0XtXb5vK3HYiz9mv/OnXeoeWxYcWI6aY6LR0OwHHQQptKQSIOP87 +2mo64IbAwzuBrhxNrdrQKCnf1mtyDZig+2r6R4TP3EM3sCNAoiU= +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem.certspec new file mode 100644 index 000000000..833e1a23a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem.certspec @@ -0,0 +1,2 @@ +issuer:untrusted-ca +subject:ee-from-untrusted-ca diff --git a/security/manager/ssl/tests/mochitest/browser/email-ee.pem b/security/manager/ssl/tests/mochitest/browser/email-ee.pem new file mode 100644 index 000000000..4211ef27d --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/email-ee.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxTCCAa+gAwIBAgIUJctkeS6qP+WqsgOLbjATJuPlN40wCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMBMxETAPBgNVBAMMCGVtYWlsLWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoxcwFTATBgNVHSUEDDAKBggr +BgEFBQcDBDALBgkqhkiG9w0BAQsDggEBAIFmRk4ZfcxWjetAoyYp0bIFLr5AjGqv +ecmc0khsRkW7NR23ywJsRsCU1u82JIGrE0bpDu/KQPAMJsi6QMc9hZEOzO1t1QmG +OJFLhCNTe+wf+5X+UKHKo01lEp7vDcO7DjuZIgEZSyOp9qbV88AtEiqESIzRBWYp +dL15cS1PDH8fa5k7MHCAh0C/HeDRD5EP8derIWWrFIesEdJAhwzMRzJrCWIqzLPP +Lv2gsXhehXCN7U14zkoGU97sSE09k5BopHd4fgqZesSApJrd2OenQAzdRIs3+UQy +iCs7oLH16lOl/yeRxVjcHRWaSRM47eGpn5+YOnGkoE/lqfux+jjB3rc= +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/email-ee.pem.certspec b/security/manager/ssl/tests/mochitest/browser/email-ee.pem.certspec new file mode 100644 index 000000000..82e329670 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/email-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:email-ee +extension:extKeyUsage:emailProtection diff --git a/security/manager/ssl/tests/mochitest/browser/expired-ca.pem b/security/manager/ssl/tests/mochitest/browser/expired-ca.pem new file mode 100644 index 000000000..2da553a56 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/expired-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzTCCAbegAwIBAgIUAfElDw37NeFULPHd+G2eoaHpvEYwCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTAwMTAxMDAwMDAwWhgPMjAxMTAxMDEwMDAw +MDBaMBUxEzARBgNVBAMMCmV4cGlyZWQtY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg +2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ +5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ +PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj +DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W +iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMB +Af8wCwYDVR0PBAQDAgEGMAsGCSqGSIb3DQEBCwOCAQEAde8CQNB8dVo5ly7Lu8x9 +5yDz2hpzAqqPDxP3+UqxzEgXeA4vfv1Bzvmxx69XEd+884M9Lkt2WBTrc+OrAgqX +pCCt4X8bjV2t+mG1shtYEGKk5BtRVnorHhZyf6+5xtOfpV9DeWkf/aA1SJK1Kpt3 +cNSDW10PwaGuaNiUMEtIFLD/MYZCM98RFOSVDWjqafbfUBn4ZSeoyRi1C2d3lg0C +jRFmOc1I4DQOUezp3C0WyCumJ0SLTIoYJGdAshMbDWPr0OOaB4GmI8miKhS6LM59 +o6C3fU8MJrRYKctYj0k9gW0DI6KuEFZj2AY8brv6Ufx1TKy5Z2pqIPeUbuJInCXM +qA== +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/expired-ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/expired-ca.pem.certspec new file mode 100644 index 000000000..15bdcd7d7 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/expired-ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:expired-ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +validity:20100101-20110101 diff --git a/security/manager/ssl/tests/mochitest/browser/has-cn.pem b/security/manager/ssl/tests/mochitest/browser/has-cn.pem new file mode 100644 index 000000000..8e7c479ae --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-cn.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0DCCAbqgAwIBAgIUfQIwxuYCoWiJuu/qTiEf7fbljnswCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMDcxDDAKBgNVBAMMA0ZvbzEMMAoGA1UECwwDQmFyMQwwCgYDVQQKDANCYXox +CzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohR +qESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+Kv +WnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+ +rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPv +JxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5 +Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6 +clHEMdUDrNoYCjXtjQIDAQABMAsGCSqGSIb3DQEBCwOCAQEAJ2fIigbkc2Lh5Z/s +Y7s4o0D9UnzttXjjEqKYhttk6PJnmVYG3zn3MBmyWPhDcXYW9fJwx7IOcC0woVdJ +yjkVZUIlJY6xAqIC6kVNtbI3PJ+mji8qQk/ecXCwhTGk0H2lZXrUtc6WMmD3GUIP +yNQGN/qAniRLnXzzVY3MJPLKKSlWSJEJCY4F4uDwBtwudPc+1yRIR6XblEL3dazS +H2kuIzGwIu6/i3AN2WIFWFhcuRTfLZINlNeH9gYEaUrwI3MS0aMPqGXtOHz+imZl +RwNng0xaiDxZXcEPjrRw5HEZcIEGBc6X8WtSzbWufiWBqMue1ltEpc1AkvUamuB3 +KJxYPA== +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/has-cn.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-cn.pem.certspec new file mode 100644 index 000000000..a4a0fcb5f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-cn.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:/CN=Foo/OU=Bar/O=Baz/C=US diff --git a/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem b/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem new file mode 100644 index 000000000..8800bfb73 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIChjCCAXCgAwIBAgIBCjALBgkqhkiG9w0BAQswDTELMAkGA1UEAwwCY2EwIhgP +MjAxNTExMjgwMDAwMDBaGA8yMDE4MDIwNTAwMDAwMFowADCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATALBgkqhkiG +9w0BAQsDggEBAF/OD4h9UNl2afVbw/Hv2dCV5uMyDV3T8iEUI9eiCvYDMAOElkAN +NZbDfGfQdg8rNLKG6r7Vz8VBu0T/Vn2lswtKYPll63ANv9qZVtKGsDTGzN8JSC0k +xgMbtVsj+OsJs81hmNnW6xw7wehpPw3l1UakAEb6dbYuYCanR/p/u/hvTz7phe9D +AsJyRAo4a+QDyeqgAPKrzTatawshNnz9O4QhNzUqj53fMkpUq2ebOyIGMOvbh/N5 +nT6AVT2wn95mWawnS5v2VTRPALyMkgbl+0bb/VzXHN6CjDHO+n239lL2uQlAZFHe +8pKr4lmb82dLU9qUFbY7exLyV1aUyYSXSNU= +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem.certspec new file mode 100644 index 000000000..6346f7b83 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject: +serialNumber:10 diff --git a/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem b/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem new file mode 100644 index 000000000..16964b1c0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpjCCAZCgAwIBAgIUCwPRyN8HCSE5XEIq7e2eEEe1OdIwCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMA0xCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu +Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO +7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf +qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt +HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx +uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMAsGCSqGSIb3DQEBCwOCAQEAt2CF0E7d +QYnfn/kc8hb6GF6sYpCFA6egEzr6OsYMYE7jt5mKlMJdbIxw57L8jg8IZ1fjH5AQ +KA5cchGcgjCkHoJ7jOYfMZCubCBdrsNKx2YYWcna8WIAZjwOIfNC0Ajs3IDiRDWm +vlBrFP9Z6bGuzNrvLFAB0lU2dM2b99DqzaYNZeQP5DcP6ZjaPkSvqOWr3Lf6ZAvO +tU70OcTelx74Hj9bI75bxVYd71Vorv5qB77zrl7GHb36f2pkludDOKeZ6XhRgy9e +vN6DLctM0v6fJprG50xrILDhqsTydTdjhETLaIWhF9aUHzFybpFArp8TLoWbXiX1 +eAVaASutFVprhA== +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem.certspec new file mode 100644 index 000000000..cc1b668a6 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:/C=US diff --git a/security/manager/ssl/tests/mochitest/browser/has-o.pem b/security/manager/ssl/tests/mochitest/browser/has-o.pem new file mode 100644 index 000000000..755d3cdae --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-o.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtDCCAZ6gAwIBAgIUeXeYs5jw41bNt0btBeEFNbUQonAwCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMBsxDDAKBgNVBAoMA0JhejELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk +e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg +KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI +YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi +lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL +HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJKoZIhvcN +AQELA4IBAQAs60sU1VqjaVQbGBHvBNyiQn9oTugmuEx9ogwVKhnmgRK+hYw+wgBn +H4yYZF1gF4xG7Rt+ut+EruSd4ht8vY9ZMvKrbgMrZ6HbNIZg9oIX+u0i9Bba2lh7 +p87mCePS5L7U1gPbg/fZ8jd0FvW8EusC/TX5tOeeUnawXWE4ciqPZfIVriU0iCP1 +nKzvFtawYzWwgN+QZ1ruzBi7qqrHNDAhgLu9+3g+9QyBd40XV7/EhDQ18kViaTSj +WmaUX7jJD1FUkGBkxjqHfgGkaYnt7UXGMDTeQ8vFeja11PJJIdRT8hSu0oTMdE6M +WCEw02+Fc+qsYH5I6vp3MOV8wyBqIqYc +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/has-o.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-o.pem.certspec new file mode 100644 index 000000000..f7cc3ffc7 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-o.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:/O=Baz/C=US diff --git a/security/manager/ssl/tests/mochitest/browser/has-ou.pem b/security/manager/ssl/tests/mochitest/browser/has-ou.pem new file mode 100644 index 000000000..06f663b3f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-ou.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwjCCAaygAwIBAgIUU/td7MxWYwvdFLfgNUraIpy3GP8wCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMCkxDDAKBgNVBAsMA0JhcjEMMAoGA1UECgwDQmF6MQswCQYDVQQGEwJVUzCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAATALBgkqhkiG9w0BAQsDggEBAGbVHQ19S6R62HovLt9Ltir1z9KJ4QXWNAEu +FKicntKaId+jJY42y1+iAqQHy3FpjfLfx5eVKPW8vHbyTQSL/y0jJ9bPKepYsSay +5McWggOxMxVFazUCOntZN282WYIg3H/OFaeRarjeHlraZjwmNxrfHKzyBJ6bBqBJ +2vtmDez/+h+f0reutgnY1v4bJ02x/5YuG39+i08uRI0Vc+lrDiqDPYMxlmzwVvJM +xqo9TZu9gU4XFbK8c8EUsPjMMO1gKyroiBhthtEZ8a9Q4jdeD92cOZRcPrHtYyvR +qw9VhFLJRgLJ0DVOWqCHqYXUFfYngFezem1eeNxrz2eAbaURdCs= +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/has-ou.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-ou.pem.certspec new file mode 100644 index 000000000..8879dabf5 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-ou.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:/OU=Bar/O=Baz/C=US diff --git a/security/manager/ssl/tests/mochitest/browser/head.js b/security/manager/ssl/tests/mochitest/browser/head.js new file mode 100644 index 000000000..d488e6eeb --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/head.js @@ -0,0 +1,59 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +var gCertDB = Cc["@mozilla.org/security/x509certdb;1"] + .getService(Ci.nsIX509CertDB); + +/** + * List of certs imported via readCertificate(). Certs in this list are + * automatically deleted from the cert DB when a test including this head file + * finishes. + * @type nsIX509Cert[] + */ +var gImportedCerts = []; + +registerCleanupFunction(() => { + for (let cert of gImportedCerts) { + gCertDB.deleteCertificate(cert); + } +}); + +/** + * This function serves the same purpose as the one defined in head_psm.js. + */ +function pemToBase64(pem) { + return pem.replace(/-----BEGIN CERTIFICATE-----/, "") + .replace(/-----END CERTIFICATE-----/, "") + .replace(/[\r\n]/g, ""); +} + +/** + * Given the filename of a certificate, returns a promise that will resolve with + * a handle to the certificate when that certificate has been read and imported + * with the given trust settings. + * + * Certs imported via this function will automatically be deleted from the cert + * DB once the calling test finishes. + * + * @param {String} filename + * The filename of the certificate (assumed to be in the same directory). + * @param {String} trustString + * A string describing how the certificate should be trusted (see + * `certutil -A --help`). + * @return {Promise} + * A promise that will resolve with a handle to the certificate. + */ +function readCertificate(filename, trustString) { + return OS.File.read(getTestFilePath(filename)).then(data => { + let decoder = new TextDecoder(); + let pem = decoder.decode(data); + let certdb = Cc["@mozilla.org/security/x509certdb;1"] + .getService(Ci.nsIX509CertDB); + let base64 = pemToBase64(pem); + certdb.addCertFromBase64(base64, trustString, "unused"); + let cert = certdb.constructX509FromBase64(base64); + gImportedCerts.push(cert); + return cert; + }, error => { throw error; }); +} diff --git a/security/manager/ssl/tests/mochitest/browser/invalid.pem b/security/manager/ssl/tests/mochitest/browser/invalid.pem new file mode 100644 index 000000000..1911098ef --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/invalid.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvDCCAaagAwIBAgIUcy9NBl2j6kWrXfJ6Na36AnwN2Q8wCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMBIxEDAOBgNVBAMMB2ludmFsaWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9 +sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5 +TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7 +xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd +tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l +8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjDzANMAsGA1UdDwQEAwIBBjAL +BgkqhkiG9w0BAQsDggEBAHw1PeRKbGVaiNBPlshPnuEjJ5XN+ls3Lv8CVplvuFgM +uvOAfuXNcLcQmqU4QZm9PvIboCAe2FTFMJ+szDbCIFaBzzJ4RnuJ0FnBZDf1fKJm +/Nj4XikPePo5DnsqSs53aNKM7Nf5dcdCCA8kfpMm50Nw6ufWrr8HAEqQbDixecv1 +6as6xc458UU8AXKZb30VfLFAm0uPz2Y/ZjROnSqrNSB5ZRx9m4MqS3/4H7fSnlFU +yMcetH5ovGk3xJg65qWhaRlaoeExco9E5x1nUr+eK4OmP3MXlGbxxMQx1R43Ea11 +zSyaqlhGUs06uDOl4rk4b2FmkPgGV+A26gtjMYD005k= +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/invalid.pem.certspec b/security/manager/ssl/tests/mochitest/browser/invalid.pem.certspec new file mode 100644 index 000000000..71a1707c3 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/invalid.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:invalid +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/mochitest/browser/md5-ee.pem b/security/manager/ssl/tests/mochitest/browser/md5-ee.pem new file mode 100644 index 000000000..27bf90085 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/md5-ee.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICqjCCAZSgAwIBAgIURZ4xXpmcV9oh3RekbTwkCGv62NowCwYJKoZIhvcNAQEE +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMBExDzANBgNVBAMMBm1kNS1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x +nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM +wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF +4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20 +yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx +j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATALBgkqhkiG9w0BAQQDggEBAKs7 +7/g5m901xqDth2t0tDTFWlfh/h94KLk8d8JAAa8AMdVwpMUMc2IKPk+H+f7JkBeE +hhJ/r4ZEbQkjZuoLSkAR6aKRprE97Ddw1LJLVish39DitEXxpyDemCIl8V6E8FpW +CWqbOZtvUScOQOlJ2uJfPwHkh93RJbzP9EY8Hd2arFYKuExi5z8Z465feZ53mdOe +17WG9IKKIQirr4OAxD+ab1EdMuPuXKQ9qfg4fSW/LDsb97x0/ElRfHwFDxsbEiVi +zR/gGMW9AQhc+eW2qchjYkO0v/ps7dzjDQFDJzLAd/mlb90cK1cpUz6XVn/HagvZ +0MRczu3MnE6KRPVpW8Y= +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/md5-ee.pem.certspec b/security/manager/ssl/tests/mochitest/browser/md5-ee.pem.certspec new file mode 100644 index 000000000..279c15802 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/md5-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:md5-ee +signature:md5WithRSAEncryption diff --git a/security/manager/ssl/tests/mochitest/browser/moz.build b/security/manager/ssl/tests/mochitest/browser/moz.build new file mode 100644 index 000000000..49d7d5a11 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/moz.build @@ -0,0 +1,35 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +BROWSER_CHROME_MANIFESTS += ['browser.ini'] + +# Temporarily disabled. See bug 1256495. +# (Note that when this gets enabled, some extra work will have to happen so +# that the mochitest harness knows where to get the generated certificates - +# right now it assumes they're in the source directory, which isn't the case +# when they're automatically generated.) +#test_certificates = ( +# 'ca.pem', +# 'code-ee.pem', +# 'ee-from-expired-ca.pem', +# 'ee-from-untrusted-ca.pem', +# 'email-ee.pem', +# 'expired-ca.pem', +# 'has-cn.pem', +# 'has-empty-subject.pem', +# 'has-non-empty-subject.pem', +# 'has-o.pem', +# 'has-ou.pem', +# 'invalid.pem', +# 'md5-ee.pem', +# 'revoked.pem', +# 'ssl-ee.pem', +# 'unknown-issuer.pem', +# 'untrusted-ca.pem', +#) +# +#for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/mochitest/browser/revoked.pem b/security/manager/ssl/tests/mochitest/browser/revoked.pem new file mode 100644 index 000000000..b212e8250 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/revoked.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICqzCCAZWgAwIBAgIUD1t15yWPBLIhosAm9w9++t/F/fkwCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMBIxEDAOBgNVBAMMB3Jldm9rZWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9 +sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5 +TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7 +xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd +tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l +8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJKoZIhvcNAQELA4IBAQCy +eobd3+MhGhQvhKQax5XNBqAEmogtsv6G1ZCoAx0kKU83r3Oj9ha4VfGN0syP8NQV +nmkecZ630QXQcyCD3RRiiLqU07N3nC5djm8v+vM5RhuDADkIwddH3WNWB+8KUJEd +3Sym1EN6xAYdQEAwWdPno73sUsFebuoL/c4gpTjD7PF+/vPzN0c3KVanlrMhayKe +3PLq8jST2OSdLvooa8qMYsFFG2S4A+gmp9Cx30moMG2+w1GBKZdtY2tlFx5DppIU +AoQzUl9pvT6AFDcY2RO6UvsWF9Pzr4dTjjgk8SO05jKcmj2GnBm480ZezDx5N5zm ++XVGgonJZRAucaVuJY79 +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/revoked.pem.certspec b/security/manager/ssl/tests/mochitest/browser/revoked.pem.certspec new file mode 100644 index 000000000..daf75c670 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/revoked.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:revoked diff --git a/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem b/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem new file mode 100644 index 000000000..76a688034 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzTCCAbegAwIBAgIUYfe94xSwDUoffRodCo1TPdV/PaswCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMBExDzANBgNVBAMMBnNzbC1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x +nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM +wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF +4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20 +yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx +j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMhMB8wHQYDVR0lBBYwFAYIKwYB +BQUHAwEGCCsGAQUFBwMCMAsGCSqGSIb3DQEBCwOCAQEAprVI8tGWBHIN2SV66ZnC +vOfWcQguUQg8QO3Al+O4X5U18hzgsmCjqt99b+oJCJD0qWBnPPBgqY52pckCgmTY +w73TZ5w3Rnr3v+BlQ5xPTyAQoUeutm1LMxY/Ju7m1XV44tyDnq6GZbOZLVWtRLXe +W4UEqVex4qbCw3GOvFyHmubSNUk81v4Iexe1SmIJN8glZsVmWJdaC2Xo7qhz+vvq +HljfO+/ejiBtZOJSf9qG6HcGW/Rf15Io0e+IA6jbZWrlAzIjBcYKumZF8LjRONHZ +vwiCwWit/IP6KvmsHAb7wj5c0U/p1TuyGdvu/ccp6nCdx8Ya7/QKfAEQTZXnloBG +4w== +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem.certspec b/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem.certspec new file mode 100644 index 000000000..c4037675f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ssl-ee +extension:extKeyUsage:serverAuth,clientAuth diff --git a/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem b/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem new file mode 100644 index 000000000..d8e750551 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtzCCAaGgAwIBAgIUEfR3vHTQuzModYBSMepORIL++2gwCwYJKoZIhvcNAQEL +MBIxEDAOBgNVBAMMB3Vua25vd24wIhgPMjAxNTExMjgwMDAwMDBaGA8yMDE4MDIw +NTAwMDAwMFowGTEXMBUGA1UEAwwOdW5rbm93bi1pc3N1ZXIwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJKoZI +hvcNAQELA4IBAQB4pRQvglUpzNZ2fH0oj5bcqfcTjE3dwEzGg7WaMD2t50zKgCRp +2sDObvEB1Nv5SHSkebxDeS9xQ6Dghf+TvuCnkapi/6q9etP51lkIOhl6okAGUwdZ +vO3duIvXCVUWbut3ATQghKovDYuJXKMx1OYapxyLKKCsdvTQ8LNQpPcwbpVtqWKC +jLYpa1i/vtn4Pv8xs/ceOf10z5AdydpFBgZ8JpY0CbRI73WHR5fr1yYI7tfzaAA8 +d+OBZ7nqlg81khD/Oepl/h6/IJ3L2eB+lUZx6+yWML9jRD0HX1xRje19u2vxCuQ+ +tNo6lQr9fTRG76Md1d4fdg9+F9LGqDd+yBBv +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem.certspec b/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem.certspec new file mode 100644 index 000000000..c76a4e2c7 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem.certspec @@ -0,0 +1,2 @@ +issuer:unknown +subject:unknown-issuer diff --git a/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem b/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem new file mode 100644 index 000000000..0f874d9a9 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzzCCAbmgAwIBAgIUT/T//UMr8YnbQBWj+61OMGPKRC4wCwYJKoZIhvcNAQEL +MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAw +MDBaMBcxFTATBgNVBAMMDHVudHJ1c3RlZC1jYTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwCwYJKoZIhvcNAQELA4IBAQCiDFgskGRygaarkruu +gTwsX59ULb7yhXyYKZLTdsUitHi8Zk4KUmsbkBHGaek30Ud9A1GyLzuP3hb1/M7M +FdARYO8qrl414tW3hiON36R47qtw5cO6a2YZfvxU79esuoa6uxChhHLUugqNotJb +bbGwSMszKzkGtOQ5ZTFNc8+t1kWeQfFoPMznjg5WC2oq9Pl45Rt9lFrU3SD8MkVA +8fLAGR5TEOY2ZvjDDMKg+ceJNIaA3SPXDTVSXWNIakJU2vsdUXThTyfnoCw0sMQG +ZwkmKbCXioYXDB/nrjoVBgJh85JSc4KX137y5m2FK+wHzkKMgf4yn6Ql2eg/yTen +CaeK +-----END CERTIFICATE-----
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem.certspec new file mode 100644 index 000000000..04f443057 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:untrusted-ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/.eslintrc.js b/security/manager/ssl/tests/mochitest/mixedcontent/.eslintrc.js new file mode 100644 index 000000000..d61bb2044 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/.eslintrc.js @@ -0,0 +1,5 @@ +"use strict"; + +module.exports = { // eslint-disable-line no-undef + "extends": "../../../../../../testing/mochitest/mochitest.eslintrc.js" +}; diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/alloworigin.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/alloworigin.sjs new file mode 100644 index 000000000..8e9afb098 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/alloworigin.sjs @@ -0,0 +1,6 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Access-Control-Allow-Origin", "*"); + response.write("<html><body>hello!</body></html>"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/backward.html b/security/manager/ssl/tests/mochitest/mixedcontent/backward.html new file mode 100644 index 000000000..825c2aa80 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/backward.html @@ -0,0 +1,18 @@ +<!DOCTYPE HTML> +<html> +<head> + <script type="text/javascript"> + "use strict"; + window.onload = function() + { + window.setTimeout(function() + { + SpecialPowers.wrap(window).QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) + .getInterface(SpecialPowers.Ci.nsIWebNavigation) + .goBack(); + }, 100); + }; + + </script> +</head> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/bug329869.js b/security/manager/ssl/tests/mochitest/mixedcontent/bug329869.js new file mode 100644 index 000000000..fd888504a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/bug329869.js @@ -0,0 +1,7 @@ +/* import-globals-from mixedContentTest.js */ +"use strict"; + +document.open(); +document.write("This is insecure XSS script " + document.cookie); +isSecurityState("broken", "security broken after document write from unsecure script"); +finish(); diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step2.html b/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step2.html new file mode 100644 index 000000000..c2ebce364 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step2.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 383369 test, step 2</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/does_not_exist.css"> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + window.onload = function runTest() { + window.setTimeout(function () { + window.location = + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step3.html?runtest"; + }, 0); + }; + + function afterNavigationTest() + { + } + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step3.html b/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step3.html new file mode 100644 index 000000000..1acafcd2f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step3.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 383369 test, final step</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + isSecurityState("secure", "secure page after insecure download and insecure subcontent still secure"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("secure", "still secure after back/forward"); + finish(); + } + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/download.auto b/security/manager/ssl/tests/mochitest/mixedcontent/download.auto new file mode 100644 index 000000000..4d2fb7d5a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/download.auto @@ -0,0 +1 @@ +Temporary file for security/mixedconent tests
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/download.auto^headers^ b/security/manager/ssl/tests/mochitest/mixedcontent/download.auto^headers^ new file mode 100644 index 000000000..9c3159e15 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/download.auto^headers^ @@ -0,0 +1,2 @@ +Content-disposition: "attachment" +Content-type: application/x-auto-download diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/emptyimage.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/emptyimage.sjs new file mode 100644 index 000000000..5cce2826f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/emptyimage.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 200, "OK"); + //response.setHeader("Content-type", "image/gif"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs new file mode 100644 index 000000000..20d9dea82 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs @@ -0,0 +1,13 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-type", "image/bitmap"); + + let bmpheader = "\x42\x4D\x36\x10\x0E\x00\x00\x00\x00\x00\x36\x00\x00\x00\x28\x00\x00\x00\x80\x02\x00\x00\xE0\x01\x00\x00\x01\x00\x18\x00\x00\x00\x00\x00\x00\x10\x0E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + let bmpdatapiece = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + + response.bodyOutputStream.write(bmpheader, 54); + // Fill 640*480*3 nulls + for (let i = 0; i < (640 * 480 * 3) / 64; ++i) + response.bodyOutputStream.write(bmpdatapiece, 64); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html b/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html new file mode 100644 index 000000000..d67eb6a7a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html @@ -0,0 +1,13 @@ +<!DOCTYPE HTML> +<html> +<head> +</head> + +<body> + This is frame 1: + <script> + "use strict"; + document.write(location.href); + </script> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html b/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html new file mode 100644 index 000000000..048ed811b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html @@ -0,0 +1,14 @@ +<!DOCTYPE HTML> +<html> +<head> +</head> + +<body> + This is frame 2: + <script> + "use strict"; + document.write(location.href); + </script> + <iframe src="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"></iframe> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframeMetaRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/iframeMetaRedirect.html new file mode 100644 index 000000000..d033f5b00 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframeMetaRedirect.html @@ -0,0 +1,8 @@ +<!DOCTYPE HTML> +<META http-equiv="Refresh" + Content="0; URL=http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"> +<html> + <body> + Redirecting by meta tag... + </body> +</html>
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframesecredirect.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/iframesecredirect.sjs new file mode 100644 index 000000000..ea93b80b7 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframesecredirect.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs new file mode 100644 index 000000000..937e29954 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/imgsecredirect.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/imgsecredirect.sjs new file mode 100644 index 000000000..7af6116e1 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/imgsecredirect.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs new file mode 100644 index 000000000..a8eb26642 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js b/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js new file mode 100644 index 000000000..74c592e59 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js @@ -0,0 +1,204 @@ +"use strict"; + +/** + * Helper script for mixed content testing. It opens a new top-level window + * from a secure origin and '?runtest' query. That tells us to run the test + * body, function runTest(). Then we wait for call of finish(). On its first + * call it loads helper page 'backward.html' that immediately navigates + * back to the test secure test. This checks the bfcache. We got second call + * to onload and this time we call afterNavigationTest() function to let the + * test check security state after re-navigation back. Then we again wait for + * finish() call, that this time finishes completelly the test. + */ + +// Tells the framework if to load the test in an insecure page (http://) +var loadAsInsecure = false; +// Set true to bypass the navigation forward/back test +var bypassNavigationTest = false; +// Set true to do forward/back navigation over an http:// page, test state leaks +var navigateToInsecure = false; +// Open the test in two separate windows, test requests sharing among windows +var openTwoWindows = false; +// Override the name of the test page to load, useful e.g. to prevent load +// of images or other content before the test starts; this is actually +// a 'redirect' to a different test page. +var testPage = ""; +// Assign a function to this variable to have a clean up at the end +var testCleanUp = null; +// Contains mixed active content that needs to load to run the test +var hasMixedActiveContent = false; + + +// Internal variables +var _windowCount = 0; + +window.onload = function onLoad() { + if (location.search == "?runtest") { + try { + if (history.length == 1) { + // Each test that includes this helper file is supposed to define + // runTest(). See the top level comment. + runTest(); // eslint-disable-line no-undef + } else { + // Each test that includes this helper file is supposed to define + // afterNavigationTest(). See the top level comment. + afterNavigationTest(); // eslint-disable-line no-undef + } + } catch (ex) { + ok(false, "Exception thrown during test: " + ex); + finish(); + } + } else { + window.addEventListener("message", onMessageReceived, false); + + let secureTestLocation = loadAsInsecure ? "http://example.com" + : "https://example.com"; + secureTestLocation += location.pathname; + if (testPage != "") { + let array = secureTestLocation.split("/"); + array.pop(); + array.push(testPage); + secureTestLocation = array.join("/"); + } + secureTestLocation += "?runtest"; + + if (hasMixedActiveContent) { + SpecialPowers.pushPrefEnv( + {"set": [["security.mixed_content.block_active_content", false]]}, + null); + } + if (openTwoWindows) { + _windowCount = 2; + window.open(secureTestLocation, "_new1", ""); + window.open(secureTestLocation, "_new2", ""); + } else { + _windowCount = 1; + window.open(secureTestLocation); + } + } +}; + +function onMessageReceived(event) +{ + switch (event.data) { + // Indication of all test parts finish (from any of the frames) + case "done": + if (--_windowCount == 0) { + if (testCleanUp) { + testCleanUp(); + } + if (hasMixedActiveContent) { + SpecialPowers.popPrefEnv(null); + } + + SimpleTest.finish(); + } + break; + + // Any other message is an error or success message of a test. + default: + SimpleTest.ok(!event.data.match(/^FAILURE/), event.data); + break; + } +} + +function postMsg(message) +{ + opener.postMessage(message, "http://mochi.test:8888"); +} + +function finish() +{ + if (history.length == 1 && !bypassNavigationTest) { + window.setTimeout(() => { + window.location.assign(navigateToInsecure ? + "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/backward.html" : + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/backward.html"); + }, 0); + } else { + postMsg("done"); + window.close(); + } +} + +function ok(a, message) +{ + if (!a) { + postMsg("FAILURE: " + message); + } else { + postMsg(message); + } +} + +function is(a, b, message) +{ + if (a != b) { + postMsg(`FAILURE: ${message}, expected ${b} got ${a}`); + } else { + postMsg(`${message}, expected ${b} got ${a}`); + } +} + +function isSecurityState(expectedState, message, test) +{ + if (!test) { + test = ok; + } + + let ui = SpecialPowers.wrap(window) + .QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) + .getInterface(SpecialPowers.Ci.nsIWebNavigation) + .QueryInterface(SpecialPowers.Ci.nsIDocShell) + .securityUI; + + let isInsecure = !ui || + (ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_IS_INSECURE); + let isBroken = ui && + (ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_IS_BROKEN); + let isEV = ui && + (ui.state & SpecialPowers.Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL); + + let gotState = "secure"; + if (isInsecure) { + gotState = "insecure"; + } else if (isBroken) { + gotState = "broken"; + } else if (isEV) { + gotState = "EV"; + } + + test(gotState == expectedState, (message || "") + ", " + "expected " + expectedState + " got " + gotState); + + switch (expectedState) { + case "insecure": + test(isInsecure && !isBroken && !isEV, "for 'insecure' excpected flags [1,0,0], " + (message || "")); + break; + case "broken": + test(ui && !isInsecure && isBroken && !isEV, "for 'broken' expected flags [0,1,0], " + (message || "")); + break; + case "secure": + test(ui && !isInsecure && !isBroken && !isEV, "for 'secure' expected flags [0,0,0], " + (message || "")); + break; + case "EV": + test(ui && !isInsecure && !isBroken && isEV, "for 'EV' expected flags [0,0,1], " + (message || "")); + break; + default: + throw new Error("Invalid isSecurityState state"); + } +} + +function waitForSecurityState(expectedState, callback) +{ + let roundsLeft = 200; // Wait for 20 seconds (=200*100ms) + let interval = window.setInterval(() => { + isSecurityState(expectedState, "", isok => { + if (isok) { + roundsLeft = 0; + } + }); + if (!roundsLeft--) { + window.clearInterval(interval); + callback(); + } + }, 100); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/mochitest.ini b/security/manager/ssl/tests/mochitest/mixedcontent/mochitest.ini new file mode 100644 index 000000000..c7a352eb8 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/mochitest.ini @@ -0,0 +1,62 @@ +[DEFAULT] +skip-if = toolkit == 'android' #TIMED_OUT +support-files = + alloworigin.sjs + backward.html + bug329869.js + bug383369step2.html + bug383369step3.html + download.auto + download.auto^headers^ + emptyimage.sjs + hugebmp.sjs + iframe.html + iframe2.html + iframeMetaRedirect.html + iframesecredirect.sjs + iframeunsecredirect.sjs + imgsecredirect.sjs + imgunsecredirect.sjs + mixedContentTest.js + moonsurface.jpg + nocontent.sjs + redirecttoemptyimage.sjs + somestyle.css + unsecureIframe.html + unsecurePictureDup.html + +[test_bug329869.html] +[test_bug383369.html] +[test_bug455367.html] +[test_bug472986.html] +[test_bug477118.html] +[test_bug521461.html] +[test_cssBefore1.html] +[test_cssContent1.html] +[test_cssContent2.html] +[test_documentWrite1.html] +[test_documentWrite2.html] +[test_dynDelayedUnsecurePicture.html] +[test_dynDelayedUnsecureXHR.html] +[test_dynUnsecureBackground.html] +[test_dynUnsecureIframeRedirect.html] +[test_dynUnsecurePicture.html] +[test_dynUnsecurePicturePreload.html] +# [test_dynUnsecureRedirect.html] +# intermitently fails, quite often, bug 487402 +[test_innerHtmlDelayedUnsecurePicture.html] +[test_innerHtmlUnsecurePicture.html] +[test_javascriptPicture.html] +[test_secureAll.html] +[test_securePicture.html] +[test_unsecureBackground.html] +[test_unsecureCSS.html] +[test_unsecureIframe.html] +[test_unsecureIframe2.html] +# [test_unsecureIframeMetaRedirect.html] +# intermittently fails, less often, bug 487632 +[test_unsecureIframeRedirect.html] +[test_unsecurePicture.html] +[test_unsecurePictureDup.html] +[test_unsecurePictureInIframe.html] +[test_unsecureRedirect.html] diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg b/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg Binary files differnew file mode 100644 index 000000000..c0ffca256 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/moz.build b/security/manager/ssl/tests/mochitest/mixedcontent/moz.build new file mode 100644 index 000000000..8e5cb5d71 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/moz.build @@ -0,0 +1,8 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +MOCHITEST_MANIFESTS += ['mochitest.ini'] + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/nocontent.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/nocontent.sjs new file mode 100644 index 000000000..53fa4bc0c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/nocontent.sjs @@ -0,0 +1,4 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 204, "No Content"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/redirecttoemptyimage.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/redirecttoemptyimage.sjs new file mode 100644 index 000000000..4d85e1658 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/redirecttoemptyimage.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/emptyimage.sjs"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css b/security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css new file mode 100644 index 000000000..9867e3c41 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css @@ -0,0 +1,4 @@ +body +{ + background-color: lightBlue; +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html new file mode 100644 index 000000000..3b8fae25e --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>dymanic script load</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + hasMixedActiveContent = true; + + function runTest() + { + isSecurityState("secure"); + window.setTimeout(function () { + let newElement = document.createElement("script"); + newElement.src = "http://example.org/tests/security/manager/ssl/tests/" + + "mochitest/mixedcontent/bug329869.js"; + document.body.appendChild(newElement); + }, 0); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html new file mode 100644 index 000000000..b68546d0a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html @@ -0,0 +1,102 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 383369 test</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* sendAsyncMessage isn't actually a global - this just mollifies eslint */ + /* global sendAsyncMessage */ + /* import-globals-from mixedContentTest.js */ + "use strict"; + + // We want to start this test from an insecure context + loadAsInsecure = true; + // We don't want to go through the navigation back/forward test + bypassNavigationTest = true; + + function runTest() { + let script = SpecialPowers.loadChromeScript(function() { + const { classes: Cc, interfaces: Ci, utils: Cu } = Components; + // Force download to be w/o user assistance for our testing mime type + const mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService); + let handlerInfo = + mimeSvc.getFromTypeAndExtension("application/x-auto-download", "auto"); + handlerInfo.preferredAction = Ci.nsIHandlerInfo.saveToDisk; + handlerInfo.alwaysAskBeforeHandling = false; + handlerInfo.preferredApplicationHandler = null; + + const handlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"] + .getService(Ci.nsIHandlerService); + handlerSvc.store(handlerInfo); + + let dirProvider = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties); + let profileDir = dirProvider.get("ProfDS", Ci.nsIFile); + profileDir.append("downloads"); + + let prefs = Cc["@mozilla.org/preferences-service;1"] + .getService(Ci.nsIPrefService); + let prefBranch = prefs.getBranch("browser.download."); + + prefBranch.setCharPref("dir", profileDir.path); + prefBranch.setBoolPref("useDownloadDir", true); + prefBranch.setIntPref("folderList", 2); + prefBranch.setBoolPref("manager.closeWhenDone", true); + prefBranch.setBoolPref("manager.showWhenStarting", false); + + const { Downloads } = + Cu.import("resource://gre/modules/Downloads.jsm", {}); + Downloads.getList(Downloads.PUBLIC).then(list => { + list.addView({ + onDownloadAdded: function (aDownload) { + list.removeView(this); + aDownload.whenSucceeded().then(() => { + list.removeFinished(); + sendAsyncMessage("navigate", "bug383369step2.html"); + }); + }, + }); + sendAsyncMessage("navigate", "download.auto"); + }).then(null, Cu.reportError); + }); + script.addMessageListener("navigate", function(url) { + window.location = url; + }); + } + + function afterNavigationTest() {} + + testCleanUp = function cleanup() { + SpecialPowers.loadChromeScript(function() { + const { classes: Cc, interfaces: Ci } = Components; + const mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService); + let handlerInfo = + mimeSvc.getFromTypeAndExtension("application/x-auto-download", "auto"); + + const handlerSvc = Cc["@mozilla.org/uriloader/handler-service;1"] + .getService(Ci.nsIHandlerService); + handlerSvc.remove(handlerInfo); + + let prefs = Cc["@mozilla.org/preferences-service;1"] + .getService(Ci.nsIPrefService); + let prefBranch = prefs.getBranch("browser.download."); + + const prefKeys = ["dir", "useDownloadDir", "folderList", + "manager.closeWhenDone", "manager.showWhenStarting"]; + for (let prefKey of prefKeys) { + if (prefBranch.prefHasUserValue(prefKey)) { + prefBranch.clearUserPref(prefKey); + } + } + }); + }; + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug455367.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug455367.html new file mode 100644 index 000000000..ec2b8590a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug455367.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>No content image doesn't break security</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + isSecurityState("broken", "broken"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/redirecttoemptyimage.sjs" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug472986.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug472986.html new file mode 100644 index 000000000..b95cfcf65 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug472986.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>img.src replace</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + SimpleTest.expectAssertions(0, 4); + + // Clear the default onload assigned to test start because we must + // wait for replaced image to load and only after that test the security state + var onLoadFunction = window.onload; + window.onload = function() + { + let img1 = document.getElementById("img1"); + img1.addEventListener("load", onLoadFunction, false); + img1.src = "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"; + }; + + function runTest() + { + isSecurityState("secure", "secure"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("secure", "secure after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img id="img1" src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug477118.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug477118.html new file mode 100644 index 000000000..51a13a4b8 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug477118.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 477118</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + isSecurityState("secure", "data <img> doesn't break security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("secure", "still secure after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB9kBDxIAOdxBIbcAAAI+SURBVDjLxZO7TxRhFMV/M/PN7EPYhS02yytggo+ERAgxERsNhYnGzsQojaHT3r9F0cTaUjs6NUQLBRKDi4I8FEwkLMgO+5rdeX3XAoVYiZWnP797cu69Bv8gqZ+0QTqIdRpl1VHGvnV884CJwQgwicVtoB/ku/H4ycOnURgP/Q1g21Fw4+r0RjbbNmaq4ayO35UkXp9S2UzHxK2bE4QNl82FVwD0D49jn+hERBCRgwTiIX7pvGUGYF/BlO327d3ENfV7wuL0AyjPICIsfPvAmev3qdVqlMtlCoUCGxurDPT1kEnPomQKkRTFpXOjh4DN4kvGLuSJ/JC38y/ouXyXYrGIiBDHMVtbu1SrvXTlbfp6HcQcoVwp5hRAaWedPXFYfL+E1lAKswSRy+joKEEQICLkcjm01hiGgRcksW0b4SMKYHb+OSt6ma+VffxWRF3S5OeeMX7pHkqpwy5EBK31H90ogFODF1lbm8OtlEhloDORpbdnhDAMaTabhwbbtkkkEkRRhGVZR4BCfojJO4+o1VwQAItEIolpmliWRVtbG7s/dlDKotGo47U8CvkuAEwA3/eJoxhE0WyGuO4+nucRBAHVahXDMKg3agRhQBAGVKsVtNZHCRzHwTAMcrnc0eX9it3e3g7A6cGzhx0AKHWwQOV5jdXXb2ZOaa3BOP5ffF5ZptVqflG+3xpbWv5kh2FolEo7dnmv7Lium6zXG0nf95MiguM4QTqd9jPZTCvX2eF393QHqVRKZ7KZkP+unzPGLX8Jr7F8AAAAAElFTkSuQmCC" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug521461.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug521461.html new file mode 100644 index 000000000..523b97f59 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug521461.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 521461</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + loadAsInsecure = true; + + function runTest() + { + window.location = "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/nocontent.sjs"; + window.setTimeout(function() { + isSecurityState("insecure", "location.href doesn't effect the security state"); + is(document.body.innerHTML, "This is an unsecure page!", "Document has not changed content"); + finish(); + }, 1000); + } + + function afterNavigationTest() + { + isSecurityState("insecure", "still not secure after navigation"); + is(document.body.innerHTML, "This is an unsecure page!", "Document has not changed content"); + finish(); + } + + </script> +</head> + +<body>This is an unsecure page!</body></html>
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_cssBefore1.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssBefore1.html new file mode 100644 index 000000000..72046e032 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssBefore1.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>CSS :before styling 1</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <style type="text/css"> + p:before + { + content: url(http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg); + } + </style> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + isSecurityState("broken", "insecure content added by :before styling breaks security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <p> + There is a moon surface left to this text + </p> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent1.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent1.html new file mode 100644 index 000000000..364d652f4 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent1.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>CSS conent styling 1</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <style type="text/css"> + p + { + content: url(http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg); + } + </style> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + isSecurityState("broken", "insecure content added by :before styling breaks security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <p></p> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent2.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent2.html new file mode 100644 index 000000000..c57410b74 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent2.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>CSS conent styling 2</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + if (navigator.platform.startsWith("Mac")) { + SimpleTest.expectAssertions(0, 1); + } + + function runTest() + { + isSecurityState("secure"); + document.getElementById("para").style.content = + "url('http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg')"; + + waitForSecurityState("broken", function() + { + isSecurityState("broken", "insecure content added by styling breaks security"); + finish(); + }); + } + + function afterNavigationTest() + { + is(document.getElementById("para").style.content, ""); + isSecurityState("secure", "security full after navigation"); + finish(); + } + + </script> +</head> + +<body> + <p id="para"></p> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite1.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite1.html new file mode 100644 index 000000000..64eec0890 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite1.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>document.write('<img src="http://">')</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + isSecurityState("broken", "insecure <img> written dynamically breaks security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <script class="testbody" type="text/javascript"> + document.write( + "<img src='http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg' />"); + </script> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite2.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite2.html new file mode 100644 index 000000000..41878d292 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite2.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>document.write('<iframe src="http://">')</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + hasMixedActiveContent = true; + + function runTest() + { + isSecurityState("broken", "insecure iframe written dynamically breaks security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <script class="testbody" type="text/javascript"> + document.write( + "<iframe src='http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html'></iframe>"); + </script> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecurePicture.html new file mode 100644 index 000000000..4f7305f41 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecurePicture.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>img.src changes to unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + isSecurityState("secure"); + window.setTimeout(function() { + // Don't do this synchronously from onload handler + document.getElementById("image1").src = + "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"; + }, 0); + + waitForSecurityState("broken", function() + { + isSecurityState("broken", "src='http://...' changed to broken"); + finish(); + }); + } + + function afterNavigationTest() + { + is(document.getElementById("image1").src, + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg", + "img.src secure again"); + isSecurityState("secure", "security full after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img id="image1" src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecureXHR.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecureXHR.html new file mode 100644 index 000000000..7dbfdf4da --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecureXHR.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>unsecure XHR test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + hasMixedActiveContent = true; + + function runTest() + { + isSecurityState("secure"); + window.setTimeout(() => { + try { + let req = new XMLHttpRequest(); + req.open("GET", "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/alloworigin.sjs", false); + req.send(null); + + // Change should be immediate, the request was sent synchronously + isSecurityState("broken", "security broken after insecure XHR"); + } catch (ex) { + ok(false, ex); + } + + finish(); + }, 0); + } + + function afterNavigationTest() + { + isSecurityState("secure", "security full after navigation"); + finish(); + } + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureBackground.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureBackground.html new file mode 100644 index 000000000..6d06f1a64 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureBackground.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>body.background changes to unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + // This test, as is, equals to https://kuix.de/misc/test17/358438.php + + function runTest() + { + isSecurityState("secure"); + document.body.background = + "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"; + + waitForSecurityState("broken", function () { + isSecurityState("broken", "document.body.background='http://...' changed to broken"); + finish(); + }); + } + + function afterNavigationTest() + { + is(document.body.background, + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg", + "document backround secure again"); + isSecurityState("secure", "secure after re-navigation"); + finish(); + } + + </script> +</head> + +<body background="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureIframeRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureIframeRedirect.html new file mode 100644 index 000000000..f846f8919 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureIframeRedirect.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>iframe.src changes to unsecure redirect test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + hasMixedActiveContent = true; + + function runTest() + { + isSecurityState("secure"); + let self = window; + let iframe = document.getElementById("iframe1"); + iframe.onload = function() { + self.isSecurityState("broken", "src='redirect to unsecure' changed to broken"); + self.finish(); + }; + + iframe.src = + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs"; + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <iframe id="iframe1" src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"></iframe> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicture.html new file mode 100644 index 000000000..cbb5dccf8 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicture.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>img.src changes to unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + // This test, as is, equals to https://kuix.de/misc/test17/358438.php + + function runTest() + { + isSecurityState("secure"); + document.getElementById("image1").src = + "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"; + + window.setTimeout(function() { + isSecurityState("broken", "src='http://...' changed to broken"); + finish(); + }, 500); + } + + function afterNavigationTest() + { + is(document.getElementById("image1").src, + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg", + "img.src secure again"); + isSecurityState("secure", "security full after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img id="image1" src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicturePreload.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicturePreload.html new file mode 100644 index 000000000..64a7a4abe --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicturePreload.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>img.src changes to unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + (new Image()).src = + "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"; + + function runTest() + { + isSecurityState("broken", "(new Image()).src='http://...' changed to broken"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security broken after navigation"); + finish(); + } + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureRedirect.html new file mode 100644 index 000000000..c1af7b29d --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureRedirect.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>img.src changes to unsecure redirect test</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + isSecurityState("secure"); + document.getElementById("image1").src = + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs"; + + window.setTimeout(function() { + isSecurityState("broken", "src='redirect to unsecure' changed to broken"); + finish(); + }, 500); + } + + function afterNavigationTest() + { + is(document.getElementById("image1").src, + "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg", + "img.src secure again"); + isSecurityState("secure", "security full after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img id="image1" src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlDelayedUnsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlDelayedUnsecurePicture.html new file mode 100644 index 000000000..5e408b2aa --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlDelayedUnsecurePicture.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>innerHTML changes to unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + isSecurityState("secure"); + + window.setTimeout(function () { + document.getElementById("buddy").innerHTML = + "<img id='image1' src='http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg' />"; + }, 1); + + waitForSecurityState("broken", function () { + isSecurityState("broken", "innerHTML loading insecure changed to broken"); + finish(); + }); + } + + function afterNavigationTest() + { + is(document.getElementById("buddy").innerHTML, "", "innerHTML back to previous"); + isSecurityState("secure"); + finish(); + } + + </script> +</head> + +<body id="buddy"></body></html>
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlUnsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlUnsecurePicture.html new file mode 100644 index 000000000..ff3592542 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlUnsecurePicture.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>innerHTML changes to unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + isSecurityState("secure"); + + document.getElementById("buddy").innerHTML = + "<img id='image1' src='http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg' />"; + + window.setTimeout(function() { + isSecurityState("broken", "innerHTML loading insecure changed to broken"); + finish(); + }, 500); + } + + function afterNavigationTest() + { + is(document.getElementById("buddy").innerHTML, "", "innerHTML back to previous"); + isSecurityState("secure"); + finish(); + } + + </script> +</head> + +<body id="buddy"></body></html>
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_javascriptPicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_javascriptPicture.html new file mode 100644 index 000000000..1efbe4d73 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_javascriptPicture.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Secure img load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + isSecurityState("secure", "javascript: <img> should not break security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("secure", "Still secure after renavigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="javascript:'Random data'" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_secureAll.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_secureAll.html new file mode 100644 index 000000000..cd9f1d0d7 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_secureAll.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>All secure anti-regression check</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <link rel="stylesheet" type="text/css" + href="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + // Navigation test goes over an insecure page, test state leak + navigateToInsecure = true; + + function runTest() + { + isSecurityState("secure", "insecure <img> load breaks security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("secure", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> + <img src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/imgsecredirect.sjs" /> + <iframe src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframesecredirect.sjs" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_securePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_securePicture.html new file mode 100644 index 000000000..96ef9a3c7 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_securePicture.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Secure img load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + loadAsInsecure = true; + + function runTest() + { + isSecurityState("insecure", "left insecure"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("insecure", "left insecure after renavigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureBackground.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureBackground.html new file mode 100644 index 000000000..0f741f9b8 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureBackground.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>background unsecure test</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + // This test, as is, equals to https://kuix.de/misc/test17/358438.php + + function runTest() + { + isSecurityState("broken", "security broken"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security after navigation"); + finish(); + } + + </script> +</head> + +<body background="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureCSS.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureCSS.html new file mode 100644 index 000000000..19d1379ea --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureCSS.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure css load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <link rel="stylesheet" type="text/css" + href="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + hasMixedActiveContent = true; + + function runTest() + { + isSecurityState("broken", "insecure <img> load breaks security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe.html new file mode 100644 index 000000000..dd4bd2d8f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure iframe load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + hasMixedActiveContent = true; + + function runTest() + { + isSecurityState("broken", "insecure <iframe> load breaks security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <iframe src="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"></iframe> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe2.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe2.html new file mode 100644 index 000000000..cdd59ce15 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe2.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure iframe load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + hasMixedActiveContent = true; + + function runTest() + { + isSecurityState("broken", "insecure <iframe> load breaks security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <iframe src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html"></iframe> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeMetaRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeMetaRedirect.html new file mode 100644 index 000000000..288526437 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeMetaRedirect.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure redirect iframe load</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + window.setTimeout(function() + { + isSecurityState("broken", "insecure meta-tag <iframe> load breaks security"); + finish(); + }, 500); + } + + function afterNavigationTest() + { + window.setTimeout(function() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + }, 500); + } + + </script> +</head> + +<body> + <iframe src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframeMetaRedirect.html"></iframe> +</body> +</html> +
\ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeRedirect.html new file mode 100644 index 000000000..1095c769f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeRedirect.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure redirect iframe load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + hasMixedActiveContent = true; + + function runTest() + { + isSecurityState("broken", "insecure <iframe> load breaks security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <iframe src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs"></iframe> +</body> +</html> + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePicture.html new file mode 100644 index 000000000..dc18efa29 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePicture.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure img load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + isSecurityState("broken", "insecure <img> load breaks security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureDup.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureDup.html new file mode 100644 index 000000000..5d02de95c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureDup.html @@ -0,0 +1,21 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure img load in two windows</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + openTwoWindows = true; + testPage = "unsecurePictureDup.html"; + + </script> +</head> + +<body> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureInIframe.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureInIframe.html new file mode 100644 index 000000000..2ece07342 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureInIframe.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure img in iframe load</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + hasMixedActiveContent = true; + + function runTest() + { + isSecurityState("broken", "insecure <img> in an <iframe> load breaks security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <iframe src="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/unsecureIframe.html"></iframe> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureRedirect.html new file mode 100644 index 000000000..a796b41b5 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureRedirect.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Redirect from secure to unsecure img</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + hasMixedActiveContent = true; + + function runTest() + { + isSecurityState("broken", "insecure <img> load breaks security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/unsecureIframe.html b/security/manager/ssl/tests/mochitest/mixedcontent/unsecureIframe.html new file mode 100644 index 000000000..228267741 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/unsecureIframe.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<head> +</head> + +<body> + <img src="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/unsecurePictureDup.html b/security/manager/ssl/tests/mochitest/mixedcontent/unsecurePictureDup.html new file mode 100644 index 000000000..f53fb4830 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/unsecurePictureDup.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Unsecure img load in two windows</title> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/MochiKit/Signal.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="mixedContentTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + /* import-globals-from mixedContentTest.js */ + "use strict"; + + function runTest() + { + isSecurityState("broken", "insecure <img> load breaks security"); + finish(); + } + + function afterNavigationTest() + { + isSecurityState("broken", "security still broken after navigation"); + finish(); + } + + </script> +</head> + +<body> + <img src="http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs" /> +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/moz.build b/security/manager/ssl/tests/mochitest/moz.build new file mode 100644 index 000000000..05c6b7906 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/moz.build @@ -0,0 +1,11 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +TEST_DIRS += [ + 'browser', + 'mixedcontent', + 'stricttransportsecurity', +] diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/.eslintrc.js b/security/manager/ssl/tests/mochitest/stricttransportsecurity/.eslintrc.js new file mode 100644 index 000000000..74b7a1a07 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/.eslintrc.js @@ -0,0 +1,9 @@ +"use strict"; + +module.exports = { // eslint-disable-line no-undef + // mochitest-chrome tests also exist in this directory, but don't appear to + // use anything not also available to plain mochitests. Since plain mochitests + // are the majority, we take the safer option and only extend the + // mochitest-plain eslintrc file. + "extends": "../../../../../../testing/mochitest/mochitest.eslintrc.js" +}; diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/chrome.ini b/security/manager/ssl/tests/mochitest/stricttransportsecurity/chrome.ini new file mode 100644 index 000000000..b2ce8fef0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/chrome.ini @@ -0,0 +1,6 @@ +[DEFAULT] +tags = psm +skip-if = os == 'android' +support-files = page_blank.html + +[test_sts_privatebrowsing_perwindowpb.html] diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/mochitest.ini b/security/manager/ssl/tests/mochitest/stricttransportsecurity/mochitest.ini new file mode 100644 index 000000000..100f45840 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/mochitest.ini @@ -0,0 +1,13 @@ +[DEFAULT] +tags = psm +support-files = + nosts_bootstrap.html + nosts_bootstrap.html^headers^ + plain_bootstrap.html + plain_bootstrap.html^headers^ + subdom_bootstrap.html + subdom_bootstrap.html^headers^ + verify.sjs + +[test_stricttransportsecurity.html] +skip-if = toolkit == 'android' #TIMED_OUT diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/moz.build b/security/manager/ssl/tests/mochitest/stricttransportsecurity/moz.build new file mode 100644 index 000000000..cd73f7716 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/moz.build @@ -0,0 +1,10 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +MOCHITEST_MANIFESTS += ['mochitest.ini'] + +MOCHITEST_CHROME_MANIFESTS += ['chrome.ini'] + diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html new file mode 100644 index 000000000..f9b0f9381 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html @@ -0,0 +1,26 @@ +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<!DOCTYPE HTML> +<html> + <head> + <title>STS test iframe</title> + <script> + "use strict"; + let windowRef = window; + window.addEventListener("load", function() { + windowRef.parent.postMessage("BOOTSTRAP plain", + "http://mochi.test:8888"); + }, false); + </script> + </head> + <body> + <!-- This frame should be loaded over HTTPS to set the STS header. --> + This frame was loaded using + <script> + document.write(document.location.protocol); + </script> + and set the STS header to force this site and allow subdomain upgrading. + </body> +</html> diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html^headers^ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html^headers^ new file mode 100644 index 000000000..9e23c73b7 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html^headers^ @@ -0,0 +1 @@ +Cache-Control: no-cache diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/page_blank.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/page_blank.html new file mode 100644 index 000000000..db5d31a96 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/page_blank.html @@ -0,0 +1,5 @@ +<html> +<body> + PAGE BLANK +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html new file mode 100644 index 000000000..f9b0f9381 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html @@ -0,0 +1,26 @@ +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<!DOCTYPE HTML> +<html> + <head> + <title>STS test iframe</title> + <script> + "use strict"; + let windowRef = window; + window.addEventListener("load", function() { + windowRef.parent.postMessage("BOOTSTRAP plain", + "http://mochi.test:8888"); + }, false); + </script> + </head> + <body> + <!-- This frame should be loaded over HTTPS to set the STS header. --> + This frame was loaded using + <script> + document.write(document.location.protocol); + </script> + and set the STS header to force this site and allow subdomain upgrading. + </body> +</html> diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html^headers^ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html^headers^ new file mode 100644 index 000000000..a46bf65bd --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html^headers^ @@ -0,0 +1,2 @@ +Cache-Control: no-cache +Strict-Transport-Security: max-age=60 diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html new file mode 100644 index 000000000..24a364158 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html @@ -0,0 +1,26 @@ +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<!DOCTYPE HTML> +<html> + <head> + <title>STS test iframe</title> + <script> + "use strict"; + let windowRef = window; + window.addEventListener("load", function() { + windowRef.parent.postMessage("BOOTSTRAP subdom", + "http://mochi.test:8888"); + }, false); + </script> + </head> + <body> + <!-- This frame should be loaded over HTTPS to set the STS header. --> + This frame was loaded using + <script> + document.write(document.location.protocol); + </script> + and set the STS header to force this site and allow subdomain upgrading. + </body> +</html> diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html^headers^ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html^headers^ new file mode 100644 index 000000000..e54fc6a1d --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html^headers^ @@ -0,0 +1,2 @@ +Cache-Control: no-cache +Strict-Transport-Security: max-age=60; includeSubDomains diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_stricttransportsecurity.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_stricttransportsecurity.html new file mode 100644 index 000000000..675688638 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_stricttransportsecurity.html @@ -0,0 +1,120 @@ +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<!DOCTYPE HTML> +<html> +<head> + <title>opens additional content that should be converted to https</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <script class="testbody" type="text/javascript"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + const STSPATH = "/tests/security/manager/ssl/tests/mochitest/stricttransportsecurity"; + + // initialized manually here + var testsleft = {'plain': 4, 'subdom': 4}; + var roundsLeft = 2; + + var testframes = { + 'samedom': + {'url': "http://example.com" + STSPATH + "/verify.sjs", + 'expected': {'plain': 'SECURE', 'subdom': 'SECURE'}}, + 'subdom': + {'url': "http://test1.example.com" + STSPATH + "/verify.sjs", + 'expected': {'plain': 'INSECURE', 'subdom': 'SECURE'}}, + 'otherdom': + {'url': "http://example.org" + STSPATH + "/verify.sjs", + 'expected': {'plain': 'INSECURE', 'subdom': 'INSECURE'}}, + 'alreadysecure': + {'url': "https://test2.example.com" + STSPATH + "/verify.sjs", + 'expected': {'plain': 'SECURE', 'subdom': 'SECURE'}}, + }; + + function startRound(round) { + let frame = document.createElement("iframe"); + frame.setAttribute('id', 'ifr_bootstrap'); + frame.setAttribute('src', "https://example.com" + STSPATH + "/" + round + "_bootstrap.html"); + document.body.appendChild(frame); + } + + function endRound(round) { + // remove all the iframes in the document + document.body.removeChild(document.getElementById('ifr_bootstrap')); + for (let test in testframes) { + document.body.removeChild(document.getElementById('ifr_' + test)); + } + + // clean up the STS state + SpecialPowers.cleanUpSTSData("http://example.com"); + } + + function loadVerifyFrames(round) { + for (let test in testframes) { + let frame = document.createElement("iframe"); + frame.setAttribute('id', 'ifr_' + test); + frame.setAttribute('src', testframes[test].url + '?id=' + test); + document.body.appendChild(frame); + } + } + + /* Messages received are in this format: + * (BOOTSTRAP|SECURE|INSECURE) testid + * For example: "BOOTSTRAP plain" + * or: "INSECURE otherdom" + */ + function onMessageReceived(event) { + let result = event.data.split(/\s+/); + if (result.length != 2) { + SimpleTest.ok(false, event.data); + return; + } + + // figure out which round of tests we're in + let round = (roundsLeft == 2) ? "plain" : "subdom"; + + if (result[0] === "BOOTSTRAP") { + loadVerifyFrames(round); + return; + } + + // check if the result (SECURE/INSECURE) is expected for this round/test combo + SimpleTest.is(result[0], testframes[result[1]].expected[round], + "in ROUND " + round + ", test " + result[1]); + testsleft[round]--; + + // check if there are more tests to run. + if (testsleft[round] < 1) { + // if not, advance to next round + endRound(round); + roundsLeft--; + + // defer this so it doesn't muck with the stack too much. + if (roundsLeft == 1) { + setTimeout(function () { + startRound("subdom"); + }, 0); + } + } + + if (roundsLeft < 1) { + SimpleTest.finish(); + } + } + + // listen for calls back from the sts-setting iframe and then + // the verification frames. + window.addEventListener("message", onMessageReceived, false); + window.addEventListener("load", () => { startRound("plain"); }, false); + </script> +</head> + +<body> + This test will load some iframes and do some tests. + +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_sts_privatebrowsing_perwindowpb.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_sts_privatebrowsing_perwindowpb.html new file mode 100644 index 000000000..882030b67 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_sts_privatebrowsing_perwindowpb.html @@ -0,0 +1,275 @@ +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + +<!DOCTYPE HTML> +<html> +<head> + <title>opens additional content that should be converted to https</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" + href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + + <script class="testbody" type="text/javascript"> + "use strict"; + + // We define |content| as a global as a hack to prevent use of |content| + // inside a ContentTask tripping ESLint no-undef checks. + /* global content */ + + SimpleTest.waitForExplicitFinish(); + + const Cc = Components.classes; + const Ci = Components.interfaces; + const Cu = Components.utils; + const STSPATH = "/tests/security/manager/ssl/tests/mochitest/stricttransportsecurity"; + const NUM_TEST_FRAMES = 4; + const CONTENT_PAGE = + "http://mochi.test:8888/chrome/security/manager/ssl/tests/mochitest/stricttransportsecurity/page_blank.html"; + + Cu.import("resource://testing-common/BrowserTestUtils.jsm"); + Cu.import("resource://testing-common/ContentTask.jsm"); + Cu.import("resource://gre/modules/Task.jsm"); + + // This is how many sub-tests (testframes) in each round. + // When the round begins, this will be initialized. + var testsleftinround = 0; + var currentround = ""; + var mainWindow = + window.QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShellTreeItem). + rootTreeItem.QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIDOMWindow); + + SpecialPowers.Services.prefs.setIntPref("browser.startup.page", 0); + + var testframes = { + 'samedom': + {'url': "http://example.com" + STSPATH + "/verify.sjs", + 'expected': {'plain': 'SECURE', + 'subdom': 'SECURE', + 'nosts': 'INSECURE'}}, + 'subdom': + {'url': "http://test1.example.com" + STSPATH + "/verify.sjs", + 'expected': {'plain': 'INSECURE', + 'subdom': 'SECURE', + 'nosts': 'INSECURE'}}, + 'otherdom': + {'url': "http://example.org" + STSPATH + "/verify.sjs", + 'expected': {'plain': 'INSECURE', + 'subdom': 'INSECURE', + 'nosts': 'INSECURE'}}, + 'alreadysecure': + {'url': "https://test2.example.com" + STSPATH + "/verify.sjs", + 'expected': {'plain': 'SECURE', + 'subdom': 'SECURE', + 'nosts': 'SECURE'}}, + }; + + function whenDelayedStartupFinished(aWindow, aCallback) { + SpecialPowers.Services.obs.addObserver(function observer(aSubject, aTopic) { + if (aWindow == aSubject) { + SpecialPowers.Services.obs.removeObserver(observer, aTopic); + SimpleTest.executeSoon(aCallback); + } + }, "browser-delayed-startup-finished", false); + } + + function testOnWindow(aIsPrivate, aCallback) { + let win = mainWindow.OpenBrowserWindow({private: aIsPrivate}); + + Task.spawn(function* () { + yield new Promise(resolve => whenDelayedStartupFinished(win, resolve)); + + let browser = win.gBrowser.selectedBrowser; + yield BrowserTestUtils.loadURI(browser, CONTENT_PAGE); + yield BrowserTestUtils.browserLoaded(browser); + + aCallback(win); + }); + } + + function startRound(win, isPrivate, round) { + currentround = round; + testsleftinround = NUM_TEST_FRAMES; + SimpleTest.info("TESTS LEFT IN ROUND " + currentround + ": " + testsleftinround); + + let browser = win.gBrowser.selectedBrowser; + let src = "https://example.com" + STSPATH + "/" + round + "_bootstrap.html"; + + ContentTask.spawn(browser, src, function* (contentSrc) { + let frame = content.document.createElement("iframe"); + frame.setAttribute('id', 'ifr_bootstrap'); + frame.setAttribute('src', contentSrc); + + return new Promise(resolve => { + frame.addEventListener("load", resolve); + content.document.body.appendChild(frame); + }); + }).then(() => { + onMessageReceived(win, isPrivate, "BOOTSTRAP " + round); + }); + } + + function loadVerifyFrames(win, isPrivate, round) { + loadVerifyFrame(win, isPrivate, testframes.samedom, 'samedom', function() { + loadVerifyFrame(win, isPrivate, testframes.subdom, 'subdom', function() { + loadVerifyFrame(win, isPrivate, testframes.otherdom, 'otherdom', function() { + loadVerifyFrame(win, isPrivate, testframes.alreadysecure, 'alreadysecure'); + }); + }); + }); + } + + function loadVerifyFrame(win, isPrivate, test, testName, aCallback) { + let id = 'ifr_' + testName; + let src = test.url + '?id=' + testName; + let browser = win.gBrowser.selectedBrowser; + + ContentTask.spawn(browser, [id, src], function* ([contentId, contentSrc]) { + let frame = content.document.createElement("iframe"); + frame.setAttribute('id', contentId); + frame.setAttribute('src', contentSrc); + + return new Promise(resolve => { + frame.addEventListener("load", () => { + resolve(frame.contentDocument.location.protocol); + }); + + content.document.body.appendChild(frame); + }); + }).then(scheme => { + if (scheme == 'https:') { + onMessageReceived(win, isPrivate, "SECURE " + testName); + } else { + onMessageReceived(win, isPrivate, "INSECURE " + testName); + } + + if (aCallback) { + aCallback(); + } + }); + } + + /** + * Messages received are in this format: + * (BOOTSTRAP|SECURE|INSECURE) testid + * For example: "BOOTSTRAP subdom" + * or: "INSECURE otherdom" + */ + function onMessageReceived(win, isPrivate, data) { + let result = data.split(/\s+/); + if (result.length != 2) { + SimpleTest.ok(false, data); + return; + } + + if (result[0] === "BOOTSTRAP") { + loadVerifyFrames(win, isPrivate, currentround); + return; + } + + // check if the result (SECURE/INSECURE) is expected for this round/test + // combo + dump_STSState(isPrivate); + SimpleTest.is(result[0], testframes[result[1]].expected[currentround], + "in ROUND " + currentround + + ", test " + result[1]); + testsleftinround--; + + // if this round is complete... + if (testsleftinround < 1) { + SimpleTest.info("DONE WITH ROUND " + currentround); + // remove all the iframes in the document + let browser = win.gBrowser.selectedBrowser; + ContentTask.spawn(browser, testframes, function* (contentTestFrames) { + content.document.body.removeChild( + content.document.getElementById('ifr_bootstrap')); + for (let test in contentTestFrames) { + content.document.body.removeChild( + content.document.getElementById('ifr_' + test)); + } + }).then(() => { + currentround = ""; + + if (!isPrivate) { + clean_up_sts_state(isPrivate); + } + // Close test window. + win.close(); + // And advance to the next test. + // Defer this so it doesn't muck with the stack too much. + SimpleTest.executeSoon(nextTest); + }); + } + } + + function test_sts_before_private_mode() { + testOnWindow(false, function(win) { + SimpleTest.info("In public window"); + dump_STSState(false); + startRound(win, false, 'plain'); + }); + } + + function test_sts_in_private_mode() { + testOnWindow(true, function(win) { + SimpleTest.info("In private window"); + dump_STSState(true); + startRound(win, true, 'subdom'); + }); + } + + function test_sts_after_exiting_private_mode() { + testOnWindow(false, function(win) { + SimpleTest.info("In a new public window"); + dump_STSState(false); + startRound(win, false, 'nosts'); + }); + } + + function clean_up_sts_state(isPrivate) { + // erase all signs that this test ran. + SimpleTest.info("Cleaning up STS data"); + let flags = isPrivate ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0; + SpecialPowers.cleanUpSTSData("http://example.com", flags); + dump_STSState(isPrivate); + } + + function dump_STSState(isPrivate) { + let sss = Cc["@mozilla.org/ssservice;1"] + .getService(Ci.nsISiteSecurityService); + let flags = isPrivate ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0; + SimpleTest.info("State of example.com: " + sss.isSecureHost(Ci.nsISiteSecurityService.HEADER_HSTS, "example.com", flags)); + } + + // These are executed in the order presented. + // 0. test that STS works before entering private browsing mode. + // (load sts-bootstrapped "plain" tests) + // ... clear any STS data ... + // 1. test that STS works in private browsing mode + // (load sts-bootstrapped "subdomain" tests) + // 2. test that after exiting private browsing, STS data is forgotten + // (verified with non-sts-bootstrapped pages) + // ... clear any STS data ... + var tests = [ + test_sts_before_private_mode, + test_sts_in_private_mode, + test_sts_after_exiting_private_mode + ]; + + function finish() { + SpecialPowers.Services.prefs.clearUserPref("browser.startup.page"); + SimpleTest.finish(); + } + function nextTest() { + SimpleTest.executeSoon(tests.length ? tests.shift() : finish); + } + window.addEventListener('load', nextTest, false); + </script> +</head> + +<body> + This test will load some iframes and do some tests. +</body> +</html> diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/verify.sjs b/security/manager/ssl/tests/mochitest/stricttransportsecurity/verify.sjs new file mode 100644 index 000000000..e5e4eb5f6 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/verify.sjs @@ -0,0 +1,47 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// SJS file that serves un-cacheable responses for STS tests that postMessage +// to the parent saying whether or not they were loaded securely. + +function handleRequest(request, response) +{ + var query = {}; + request.queryString.split('&').forEach(function (val) { + var [name, value] = val.split('='); + query[name] = unescape(value); + }); + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + + if ('id' in query) { + var outstr = [ + " <!DOCTYPE html>", + " <html> <head> <title>subframe for STS</title>", + " <script type='text/javascript'>", + " var self = window;", + " window.addEventListener('load', function() {", + " if (document.location.protocol === 'https:') {", + " self.parent.postMessage('SECURE " + query['id'] + "',", + " 'http://mochi.test:8888');", + " } else {", + " self.parent.postMessage('INSECURE " + query['id'] + "',", + " 'http://mochi.test:8888');", + " }", + " }, false);", + " </script>", + " </head>", + " <body>", + " STS state verification frame loaded via", + " <script>", + " document.write(document.location.protocol);", + " </script>", + " </body>", + " </html>"].join("\n"); + response.write(outstr); + } else { + response.write("ERROR: no id provided"); + } +} |