/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; const BAD_CERT = "https://expired.example.com/"; const BAD_STS_CERT = "https://badchain.include-subdomains.pinning.example.com:443"; const PREF_PERMANENT_OVERRIDE = "security.certerrors.permanentOverride"; add_task(async function checkExceptionDialogButton() { info( "Loading a bad cert page and making sure the exceptionDialogButton directly adds an exception" ); let tab = await openErrorPage(BAD_CERT); let browser = tab.linkedBrowser; let loaded = BrowserTestUtils.browserLoaded(browser, false, BAD_CERT); info("Clicking the exceptionDialogButton in advanced panel"); await SpecialPowers.spawn(browser, [], async function () { let doc = content.document; let exceptionButton = doc.getElementById("exceptionDialogButton"); exceptionButton.click(); }); info("Loading the url after adding exception"); await loaded; await SpecialPowers.spawn(browser, [], async function () { let doc = content.document; ok( !doc.documentURI.startsWith("about:certerror"), "Exception has been added" ); }); let certOverrideService = Cc[ "@mozilla.org/security/certoverride;1" ].getService(Ci.nsICertOverrideService); certOverrideService.clearValidityOverride("expired.example.com", -1, {}); BrowserTestUtils.removeTab(gBrowser.selectedTab); }); add_task(async function checkPermanentExceptionPref() { info( "Loading a bad cert page and making sure the permanent state of exceptions can be controlled via pref" ); for (let permanentOverride of [false, true]) { Services.prefs.setBoolPref(PREF_PERMANENT_OVERRIDE, permanentOverride); let tab = await openErrorPage(BAD_CERT); let browser = tab.linkedBrowser; let loaded = BrowserTestUtils.browserLoaded(browser, false, BAD_CERT); info("Clicking the exceptionDialogButton in advanced panel"); let serverCertBytes = await SpecialPowers.spawn( browser, [], async function () { let doc = content.document; let exceptionButton = doc.getElementById("exceptionDialogButton"); exceptionButton.click(); return content.docShell.failedChannel.securityInfo.serverCert.getRawDER(); } ); info("Loading the url after adding exception"); await loaded; await SpecialPowers.spawn(browser, [], async function () { let doc = content.document; ok( !doc.documentURI.startsWith("about:certerror"), "Exception has been added" ); }); let certOverrideService = Cc[ "@mozilla.org/security/certoverride;1" ].getService(Ci.nsICertOverrideService); let isTemporary = {}; let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( Ci.nsIX509CertDB ); let cert = certdb.constructX509(serverCertBytes); let hasException = certOverrideService.hasMatchingOverride( "expired.example.com", -1, {}, cert, isTemporary ); ok(hasException, "Has stored an exception for the page."); is( isTemporary.value, !permanentOverride, `Has stored a ${ permanentOverride ? "permanent" : "temporary" } exception for the page.` ); certOverrideService.clearValidityOverride("expired.example.com", -1, {}); BrowserTestUtils.removeTab(gBrowser.selectedTab); } Services.prefs.clearUserPref(PREF_PERMANENT_OVERRIDE); }); add_task(async function checkBadStsCert() { info("Loading a badStsCert and making sure exception button doesn't show up"); for (let useFrame of [false, true]) { let tab = await openErrorPage(BAD_STS_CERT, useFrame); let browser = tab.linkedBrowser; await SpecialPowers.spawn( browser, [{ frame: useFrame }], async function ({ frame }) { let doc = frame ? content.document.querySelector("iframe").contentDocument : content.document; let exceptionButton = doc.getElementById("exceptionDialogButton"); ok( ContentTaskUtils.is_hidden(exceptionButton), "Exception button is hidden." ); } ); let message = await SpecialPowers.spawn( browser, [{ frame: useFrame }], async function ({ frame }) { let doc = frame ? content.document.querySelector("iframe").contentDocument : content.document; let advancedButton = doc.getElementById("advancedButton"); advancedButton.click(); // aboutNetError.mjs is using async localization to format several // messages and in result the translation may be applied later. // We want to return the textContent of the element only after // the translation completes, so let's wait for it here. let elements = [doc.getElementById("badCertTechnicalInfo")]; await ContentTaskUtils.waitForCondition(() => { return elements.every(elem => !!elem.textContent.trim().length); }); return doc.getElementById("badCertTechnicalInfo").textContent; } ); ok( message.includes("SSL_ERROR_BAD_CERT_DOMAIN"), "Didn't find SSL_ERROR_BAD_CERT_DOMAIN." ); ok( message.includes("The certificate is only valid for"), "Didn't find error message." ); ok( message.includes("a certificate that is not valid for"), "Didn't find error message." ); ok( message.includes("badchain.include-subdomains.pinning.example.com"), "Didn't find domain in error message." ); BrowserTestUtils.removeTab(gBrowser.selectedTab); } }); add_task(async function checkhideAddExceptionButtonViaPref() { info( "Loading a bad cert page and verifying the pref security.certerror.hideAddException" ); Services.prefs.setBoolPref("security.certerror.hideAddException", true); for (let useFrame of [false, true]) { let tab = await openErrorPage(BAD_CERT, useFrame); let browser = tab.linkedBrowser; await SpecialPowers.spawn( browser, [{ frame: useFrame }], async function ({ frame }) { let doc = frame ? content.document.querySelector("iframe").contentDocument : content.document; let exceptionButton = doc.getElementById("exceptionDialogButton"); ok( ContentTaskUtils.is_hidden(exceptionButton), "Exception button is hidden." ); } ); BrowserTestUtils.removeTab(gBrowser.selectedTab); } Services.prefs.clearUserPref("security.certerror.hideAddException"); }); add_task(async function checkhideAddExceptionButtonInFrames() { info("Loading a bad cert page in a frame and verifying it's hidden."); let tab = await openErrorPage(BAD_CERT, true); let browser = tab.linkedBrowser; await SpecialPowers.spawn(browser, [], async function () { let doc = content.document.querySelector("iframe").contentDocument; let exceptionButton = doc.getElementById("exceptionDialogButton"); ok( ContentTaskUtils.is_hidden(exceptionButton), "Exception button is hidden." ); }); BrowserTestUtils.removeTab(gBrowser.selectedTab); });