зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1552333 - Move onCertErrorDetails from NetErrorChild.jsm to aboutNetError.js. r=johannh,flod,fluent-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D31901 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
beb8201a97
Коммит
b901cf9927
|
@ -17,44 +17,19 @@ XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]);
|
|||
XPCOMUtils.defineLazyGetter(this, "gPipNSSBundle", function() {
|
||||
return Services.strings.createBundle("chrome://pipnss/locale/pipnss.properties");
|
||||
});
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "mitmErrorPageEnabled",
|
||||
"browser.security.newcerterrorpage.mitm.enabled");
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "mitmPrimingEnabled",
|
||||
"security.certerrors.mitm.priming.enabled");
|
||||
XPCOMUtils.defineLazyGetter(this, "gNSSErrorsBundle", function() {
|
||||
return Services.strings.createBundle("chrome://pipnss/locale/nsserrors.properties");
|
||||
});
|
||||
|
||||
|
||||
const SEC_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE;
|
||||
const MOZILLA_PKIX_ERROR_BASE = Ci.nsINSSErrorsService.MOZILLA_PKIX_ERROR_BASE;
|
||||
|
||||
const SEC_ERROR_EXPIRED_CERTIFICATE = SEC_ERROR_BASE + 11;
|
||||
const SEC_ERROR_UNKNOWN_ISSUER = SEC_ERROR_BASE + 13;
|
||||
const SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE = SEC_ERROR_BASE + 30;
|
||||
const SEC_ERROR_REUSED_ISSUER_AND_SERIAL = SEC_ERROR_BASE + 138;
|
||||
const SEC_ERROR_OCSP_INVALID_SIGNING_CERT = SEC_ERROR_BASE + 144;
|
||||
const MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE = MOZILLA_PKIX_ERROR_BASE + 5;
|
||||
const MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE = MOZILLA_PKIX_ERROR_BASE + 6;
|
||||
const MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED = MOZILLA_PKIX_ERROR_BASE + 13;
|
||||
const MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT = MOZILLA_PKIX_ERROR_BASE + 14;
|
||||
const MOZILLA_PKIX_ERROR_MITM_DETECTED = MOZILLA_PKIX_ERROR_BASE + 15;
|
||||
|
||||
|
||||
const SSL_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SSL_ERROR_BASE;
|
||||
const SSL_ERROR_BAD_CERT_DOMAIN = SSL_ERROR_BASE + 12;
|
||||
const SSL_ERROR_SSL_DISABLED = SSL_ERROR_BASE + 20;
|
||||
const SSL_ERROR_SSL2_DISABLED = SSL_ERROR_BASE + 14;
|
||||
|
||||
const PREF_SERVICES_SETTINGS_CLOCK_SKEW_SECONDS = "services.settings.clock_skew_seconds";
|
||||
const PREF_SERVICES_SETTINGS_LAST_FETCHED = "services.settings.last_update_seconds";
|
||||
|
||||
const PREF_SSL_IMPACT_ROOTS = ["security.tls.version.", "security.ssl3."];
|
||||
|
||||
let formatter = new Services.intl.DateTimeFormat(undefined, {
|
||||
dateStyle: "long",
|
||||
});
|
||||
|
||||
function getSerializedSecurityInfo(docShell) {
|
||||
let serhelper = Cc["@mozilla.org/network/serialization-helper;1"]
|
||||
.getService(Ci.nsISerializationHelper);
|
||||
|
@ -86,287 +61,6 @@ class NetErrorChild extends ActorChild {
|
|||
};
|
||||
}
|
||||
|
||||
_getCertValidityRange(docShell) {
|
||||
let {securityInfo} = docShell.failedChannel;
|
||||
securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
|
||||
let notBefore = 0;
|
||||
let notAfter = Number.MAX_SAFE_INTEGER;
|
||||
for (let cert of securityInfo.failedCertChain.getEnumerator()) {
|
||||
notBefore = Math.max(notBefore, cert.validity.notBefore);
|
||||
notAfter = Math.min(notAfter, cert.validity.notAfter);
|
||||
}
|
||||
// nsIX509Cert reports in PR_Date terms, which uses microseconds. Convert:
|
||||
notBefore /= 1000;
|
||||
notAfter /= 1000;
|
||||
return {notBefore, notAfter};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
onCertErrorDetails(msg, docShell) {
|
||||
let doc = docShell.document;
|
||||
|
||||
// This function centers the error container after its content updates.
|
||||
// It is currently duplicated in aboutNetError.js to avoid having to do
|
||||
// async communication to the page that would result in flicker.
|
||||
// TODO(johannh): Get rid of this duplication.
|
||||
function updateContainerPosition() {
|
||||
let textContainer = doc.getElementById("text-container");
|
||||
// Using the vh CSS property our margin adapts nicely to window size changes.
|
||||
// Unfortunately, this doesn't work correctly in iframes, which is why we need
|
||||
// to manually compute the height there.
|
||||
if (doc.ownerGlobal.parent == doc.ownerGlobal) {
|
||||
textContainer.style.marginTop = `calc(50vh - ${textContainer.clientHeight / 2}px)`;
|
||||
} else {
|
||||
let offset = (doc.documentElement.clientHeight / 2) - (textContainer.clientHeight / 2);
|
||||
if (offset > 0) {
|
||||
textContainer.style.marginTop = `${offset}px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the connection is being man-in-the-middled. When the parent
|
||||
// detects an intercepted connection, the page may be reloaded with a new
|
||||
// error code (MOZILLA_PKIX_ERROR_MITM_DETECTED).
|
||||
if (mitmPrimingEnabled && msg.data.code == SEC_ERROR_UNKNOWN_ISSUER &&
|
||||
// Only do this check for top-level failures.
|
||||
doc.ownerGlobal.top === doc.ownerGlobal) {
|
||||
this.mm.sendAsyncMessage("Browser:PrimeMitm");
|
||||
}
|
||||
|
||||
let div = doc.getElementById("certificateErrorText");
|
||||
div.textContent = msg.data.info;
|
||||
let learnMoreLink = doc.getElementById("learnMoreLink");
|
||||
let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
|
||||
learnMoreLink.setAttribute("href", baseURL + "connection-not-secure");
|
||||
let errWhatToDo = doc.getElementById("es_nssBadCert_" + msg.data.codeString);
|
||||
let es = doc.getElementById("errorWhatToDoText");
|
||||
let errWhatToDoTitle = doc.getElementById("edd_nssBadCert");
|
||||
let est = doc.getElementById("errorWhatToDoTitleText");
|
||||
let searchParams = new URLSearchParams(doc.documentURI.split("?")[1]);
|
||||
let error = searchParams.get("e");
|
||||
|
||||
if (error == "sslv3Used") {
|
||||
learnMoreLink.setAttribute("href", baseURL + "sslv3-error-messages");
|
||||
}
|
||||
|
||||
if (error == "nssFailure2") {
|
||||
let shortDesc = doc.getElementById("errorShortDescText").textContent;
|
||||
// nssFailure2 also gets us other non-overrideable errors. Choose
|
||||
// a "learn more" link based on description:
|
||||
if (shortDesc.includes("MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE")) {
|
||||
learnMoreLink.setAttribute("href", baseURL + "certificate-pinning-reports");
|
||||
}
|
||||
}
|
||||
|
||||
// This is set to true later if the user's system clock is at fault for this error.
|
||||
let clockSkew = false;
|
||||
|
||||
doc.body.setAttribute("code", msg.data.codeString);
|
||||
|
||||
// Need to do this here (which is not exactly at load but a few ticks later),
|
||||
// because this is the first time we have access to the error code.
|
||||
this.recordLoadEvent(doc);
|
||||
|
||||
switch (msg.data.code) {
|
||||
case SSL_ERROR_BAD_CERT_DOMAIN:
|
||||
case SEC_ERROR_OCSP_INVALID_SIGNING_CERT:
|
||||
case SEC_ERROR_UNKNOWN_ISSUER:
|
||||
if (es) {
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
es.innerHTML = errWhatToDo.innerHTML;
|
||||
}
|
||||
if (est) {
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
est.innerHTML = errWhatToDoTitle.innerHTML;
|
||||
}
|
||||
updateContainerPosition();
|
||||
break;
|
||||
|
||||
// This error code currently only exists for the Symantec distrust
|
||||
// in Firefox 63, so we add copy explaining that to the user.
|
||||
// In case of future distrusts of that scale we might need to add
|
||||
// additional parameters that allow us to identify the affected party
|
||||
// without replicating the complex logic from certverifier code.
|
||||
case MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED:
|
||||
let description = gPipNSSBundle.formatStringFromName(
|
||||
"certErrorSymantecDistrustDescription1", [doc.location.hostname]);
|
||||
let descriptionContainer = doc.getElementById("errorShortDescText2");
|
||||
descriptionContainer.textContent = description;
|
||||
|
||||
let adminDescription = doc.createElement("p");
|
||||
adminDescription.textContent =
|
||||
gPipNSSBundle.GetStringFromName("certErrorSymantecDistrustAdministrator");
|
||||
descriptionContainer.append(adminDescription);
|
||||
|
||||
learnMoreLink.href = baseURL + "symantec-warning";
|
||||
|
||||
updateContainerPosition();
|
||||
break;
|
||||
case MOZILLA_PKIX_ERROR_MITM_DETECTED:
|
||||
if (mitmErrorPageEnabled) {
|
||||
let autoEnabledEnterpriseRoots =
|
||||
Services.prefs.getBoolPref("security.enterprise_roots.auto-enabled", false);
|
||||
if (mitmPrimingEnabled && autoEnabledEnterpriseRoots) {
|
||||
// If we automatically tried to import enterprise root certs but it didn't
|
||||
// fix the MITM, reset the pref.
|
||||
this.mm.sendAsyncMessage("Browser:ResetEnterpriseRootsPref");
|
||||
}
|
||||
|
||||
// We don't actually know what the MitM is called (since we don't
|
||||
// maintain a list), so we'll try and display the common name of the
|
||||
// root issuer to the user. In the worst case they are as clueless as
|
||||
// before, in the best case this gives them an actionable hint.
|
||||
// This may be revised in the future.
|
||||
let {securityInfo} = docShell.failedChannel;
|
||||
securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
|
||||
let mitmName = null;
|
||||
for (let cert of securityInfo.failedCertChain.getEnumerator()) {
|
||||
mitmName = cert.issuerCommonName;
|
||||
}
|
||||
for (let span of doc.querySelectorAll(".mitm-name")) {
|
||||
span.textContent = mitmName;
|
||||
}
|
||||
|
||||
learnMoreLink.href = baseURL + "security-error";
|
||||
|
||||
let title = doc.getElementById("et_mitm");
|
||||
let desc = doc.getElementById("ed_mitm");
|
||||
doc.querySelector(".title-text").textContent = title.textContent;
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
doc.getElementById("errorShortDescText").innerHTML = desc.innerHTML;
|
||||
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
es.innerHTML = errWhatToDo.innerHTML;
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
est.innerHTML = errWhatToDoTitle.innerHTML;
|
||||
|
||||
updateContainerPosition();
|
||||
break;
|
||||
}
|
||||
// If the condition is false, fall through...
|
||||
case MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT:
|
||||
learnMoreLink.href = baseURL + "security-error";
|
||||
break;
|
||||
|
||||
// In case the certificate expired we make sure the system clock
|
||||
// matches the remote-settings service (blocklist via Kinto) ping time
|
||||
// and is not before the build date.
|
||||
case SEC_ERROR_EXPIRED_CERTIFICATE:
|
||||
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
|
||||
case MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE:
|
||||
case MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE:
|
||||
|
||||
learnMoreLink.href = baseURL + "time-errors";
|
||||
// We check against the remote-settings server time first if available, because that allows us
|
||||
// to give the user an approximation of what the correct time is.
|
||||
let difference = Services.prefs.getIntPref(PREF_SERVICES_SETTINGS_CLOCK_SKEW_SECONDS, 0);
|
||||
let lastFetched = Services.prefs.getIntPref(PREF_SERVICES_SETTINGS_LAST_FETCHED, 0) * 1000;
|
||||
|
||||
let now = Date.now();
|
||||
let certRange = this._getCertValidityRange(docShell);
|
||||
|
||||
let approximateDate = now - difference * 1000;
|
||||
// If the difference is more than a day, we last fetched the date in the last 5 days,
|
||||
// and adjusting the date per the interval would make the cert valid, warn the user:
|
||||
if (Math.abs(difference) > 60 * 60 * 24 && (now - lastFetched) <= 60 * 60 * 24 * 5 &&
|
||||
certRange.notBefore < approximateDate && certRange.notAfter > approximateDate) {
|
||||
clockSkew = true;
|
||||
|
||||
// If there is no clock skew with Kinto servers, check against the build date.
|
||||
// (The Kinto ping could have happened when the time was still right, or not at all)
|
||||
} else {
|
||||
let appBuildID = Services.appinfo.appBuildID;
|
||||
|
||||
let year = parseInt(appBuildID.substr(0, 4), 10);
|
||||
let month = parseInt(appBuildID.substr(4, 2), 10) - 1;
|
||||
let day = parseInt(appBuildID.substr(6, 2), 10);
|
||||
|
||||
let buildDate = new Date(year, month, day);
|
||||
let systemDate = new Date();
|
||||
|
||||
// We don't check the notBefore of the cert with the build date,
|
||||
// as it is of course almost certain that it is now later than the build date,
|
||||
// so we shouldn't exclude the possibility that the cert has become valid
|
||||
// since the build date.
|
||||
if (buildDate > systemDate && new Date(certRange.notAfter) > buildDate) {
|
||||
clockSkew = true;
|
||||
}
|
||||
}
|
||||
|
||||
let systemDate = formatter.format(new Date());
|
||||
doc.getElementById("wrongSystemTime_systemDate1").textContent = systemDate;
|
||||
if (clockSkew) {
|
||||
doc.body.classList.add("illustrated", "clockSkewError");
|
||||
let clockErrTitle = doc.getElementById("et_clockSkewError");
|
||||
let clockErrDesc = doc.getElementById("ed_clockSkewError");
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
doc.querySelector(".title-text").textContent = clockErrTitle.textContent;
|
||||
let desc = doc.getElementById("errorShortDescText");
|
||||
doc.getElementById("errorShortDesc").style.display = "block";
|
||||
doc.getElementById("certificateErrorReporting").style.display = "none";
|
||||
if (desc) {
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
desc.innerHTML = clockErrDesc.innerHTML;
|
||||
}
|
||||
let errorPageContainer = doc.getElementById("errorPageContainer");
|
||||
let textContainer = doc.getElementById("text-container");
|
||||
errorPageContainer.style.backgroundPosition = `left top calc(50vh - ${textContainer.clientHeight / 2}px)`;
|
||||
} else {
|
||||
let targetElems = doc.querySelectorAll("#wrongSystemTime_systemDate2");
|
||||
for (let elem of targetElems) {
|
||||
elem.textContent = systemDate;
|
||||
}
|
||||
|
||||
let errDesc = doc.getElementById("ed_nssBadCert_SEC_ERROR_EXPIRED_CERTIFICATE");
|
||||
let sd = doc.getElementById("errorShortDescText");
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
sd.innerHTML = errDesc.innerHTML;
|
||||
|
||||
let span = sd.querySelector(".hostname");
|
||||
span.textContent = doc.location.hostname;
|
||||
|
||||
// The secondary description mentions expired certificates explicitly
|
||||
// and should only be shown if the certificate has actually expired
|
||||
// instead of being not yet valid.
|
||||
if (msg.data.code == SEC_ERROR_EXPIRED_CERTIFICATE) {
|
||||
let {cssClass} = this.getParams(doc);
|
||||
let stsSuffix = cssClass == "badStsCert" ? "_sts" : "";
|
||||
let errDesc2 = doc.getElementById(
|
||||
`ed2_nssBadCert_SEC_ERROR_EXPIRED_CERTIFICATE${stsSuffix}`);
|
||||
let sd2 = doc.getElementById("errorShortDescText2");
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
sd2.innerHTML = errDesc2.innerHTML;
|
||||
}
|
||||
|
||||
if (es) {
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
es.innerHTML = errWhatToDo.innerHTML;
|
||||
}
|
||||
if (est) {
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
est.textContent = errWhatToDoTitle.textContent;
|
||||
est.style.fontWeight = "bold";
|
||||
}
|
||||
updateContainerPosition();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Add slightly more alarming UI unless there are indicators that
|
||||
// show that the error is harmless or can not be skipped anyway.
|
||||
let {cssClass} = this.getParams(doc);
|
||||
// Don't alarm users when they can't continue to the website anyway...
|
||||
if (cssClass != "badStsCert" &&
|
||||
// Errors in iframes can't be skipped either...
|
||||
doc.ownerGlobal.parent == doc.ownerGlobal &&
|
||||
// Also don't bother if it's just the user's clock being off...
|
||||
!clockSkew &&
|
||||
// Symantec distrust is likely harmless as well.
|
||||
msg.data.code != MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED) {
|
||||
doc.body.classList.add("caution");
|
||||
}
|
||||
}
|
||||
|
||||
handleEvent(aEvent) {
|
||||
// Documents have a null ownerDocument.
|
||||
let doc = aEvent.originalTarget.ownerDocument || aEvent.originalTarget;
|
||||
|
@ -405,7 +99,10 @@ class NetErrorChild extends ActorChild {
|
|||
return;
|
||||
}
|
||||
|
||||
this.onCertErrorDetails(msg, frameDocShell);
|
||||
let data = msg.data;
|
||||
let win = frameDocShell.document.ownerGlobal;
|
||||
let event = Cu.cloneInto({ detail: data }, win);
|
||||
win.dispatchEvent(new win.CustomEvent("ShowCertErrorDetails", event));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -547,16 +244,6 @@ class NetErrorChild extends ActorChild {
|
|||
return searchParams.get("s");
|
||||
}
|
||||
|
||||
recordLoadEvent(doc) {
|
||||
let cssClass = this.getCSSClass(doc);
|
||||
// Telemetry values for events are max. 80 bytes.
|
||||
let errorCode = doc.body.getAttribute("code").substring(0, 40);
|
||||
Services.telemetry.recordEvent("security.ui.certerror", "load", "aboutcerterror", errorCode, {
|
||||
"has_sts": (cssClass == "badStsCert").toString(),
|
||||
"is_frame": (doc.ownerGlobal.parent != doc.ownerGlobal).toString(),
|
||||
});
|
||||
}
|
||||
|
||||
recordClick(element) {
|
||||
let telemetryId = element.dataset.telemetryId;
|
||||
if (!telemetryId) {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/* eslint-env mozilla/frame-script */
|
||||
|
||||
const formatter = new Intl.DateTimeFormat("default");
|
||||
|
||||
// The following parameters are parsed from the error URL:
|
||||
// e - the error code
|
||||
// s - custom CSS class to allow alternate styling/favicons
|
||||
|
@ -361,10 +363,248 @@ function initPageCertError() {
|
|||
}
|
||||
}, true, true);
|
||||
|
||||
let failedCertInfo = document.getFailedCertSecurityInfo();
|
||||
RPMSendAsyncMessage("RecordCertErrorLoad", {
|
||||
// Telemetry values for events are max. 80 bytes.
|
||||
errorCode: failedCertInfo.errorCodeString.substring(0, 40),
|
||||
has_sts: getCSSClass() == "badStsCert",
|
||||
is_frame: window.parent != window,
|
||||
});
|
||||
window.addEventListener("ShowCertErrorDetails", setCertErrorDetails);
|
||||
setTechnicalDetailsOnCertError();
|
||||
|
||||
let event = new CustomEvent("AboutNetErrorLoad", {bubbles: true});
|
||||
document.getElementById("advancedButton").dispatchEvent(event);
|
||||
}
|
||||
|
||||
setTechnicalDetailsOnCertError();
|
||||
function setCertErrorDetails(event) {
|
||||
// Check if the connection is being man-in-the-middled. When the parent
|
||||
// detects an intercepted connection, the page may be reloaded with a new
|
||||
// error code (MOZILLA_PKIX_ERROR_MITM_DETECTED).
|
||||
let failedCertInfo = document.getFailedCertSecurityInfo();
|
||||
let mitmPrimingEnabled = RPMGetBoolPref("security.certerrors.mitm.priming.enabled");
|
||||
if (mitmPrimingEnabled &&
|
||||
failedCertInfo.errorCodeString == "SEC_ERROR_UNKNOWN_ISSUER" &&
|
||||
// Only do this check for top-level failures.
|
||||
window.parent == window) {
|
||||
RPMSendAsyncMessage("Browser:PrimeMitm");
|
||||
}
|
||||
|
||||
let div = document.getElementById("certificateErrorText");
|
||||
div.textContent = event.detail.info;
|
||||
let learnMoreLink = document.getElementById("learnMoreLink");
|
||||
let baseURL = RPMGetFormatURLPref("app.support.baseURL");
|
||||
learnMoreLink.setAttribute("href", baseURL + "connection-not-secure");
|
||||
let errWhatToDo = document.getElementById("es_nssBadCert_" + failedCertInfo.errorCodeString);
|
||||
let es = document.getElementById("errorWhatToDoText");
|
||||
let errWhatToDoTitle = document.getElementById("edd_nssBadCert");
|
||||
let est = document.getElementById("errorWhatToDoTitleText");
|
||||
let error = getErrorCode();
|
||||
|
||||
if (error == "sslv3Used") {
|
||||
learnMoreLink.setAttribute("href", baseURL + "sslv3-error-messages");
|
||||
}
|
||||
|
||||
if (error == "nssFailure2") {
|
||||
let shortDesc = document.getElementById("errorShortDescText").textContent;
|
||||
// nssFailure2 also gets us other non-overrideable errors. Choose
|
||||
// a "learn more" link based on description:
|
||||
if (shortDesc.includes("MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE")) {
|
||||
learnMoreLink.setAttribute("href", baseURL + "certificate-pinning-reports");
|
||||
}
|
||||
}
|
||||
|
||||
// This is set to true later if the user's system clock is at fault for this error.
|
||||
let clockSkew = false;
|
||||
document.body.setAttribute("code", failedCertInfo.errorCodeString);
|
||||
|
||||
let desc;
|
||||
switch (failedCertInfo.errorCodeString) {
|
||||
case "SSL_ERROR_BAD_CERT_DOMAIN":
|
||||
case "SEC_ERROR_OCSP_INVALID_SIGNING_CERT":
|
||||
case "SEC_ERROR_UNKNOWN_ISSUER":
|
||||
if (es) {
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
es.innerHTML = errWhatToDo.innerHTML;
|
||||
}
|
||||
if (est) {
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
est.innerHTML = errWhatToDoTitle.innerHTML;
|
||||
}
|
||||
updateContainerPosition();
|
||||
break;
|
||||
|
||||
// This error code currently only exists for the Symantec distrust
|
||||
// in Firefox 63, so we add copy explaining that to the user.
|
||||
// In case of future distrusts of that scale we might need to add
|
||||
// additional parameters that allow us to identify the affected party
|
||||
// without replicating the complex logic from certverifier code.
|
||||
case "MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED":
|
||||
desc = document.getElementById("errorShortDescText2");
|
||||
let hostname = document.location.hostname;
|
||||
document.l10n.setAttributes(desc, "cert-error-symantec-distrust-description", {
|
||||
hostname,
|
||||
});
|
||||
|
||||
let adminDesc = document.createElement("p");
|
||||
document.l10n.setAttributes(adminDesc, "cert-error-symantec-distrust-admin");
|
||||
|
||||
learnMoreLink.href = baseURL + "symantec-warning";
|
||||
updateContainerPosition();
|
||||
break;
|
||||
|
||||
case "MOZILLA_PKIX_ERROR_MITM_DETECTED":
|
||||
let autoEnabledEnterpriseRoots = RPMGetBoolPref("security.enterprise_roots.auto-enabled");
|
||||
if (mitmPrimingEnabled && autoEnabledEnterpriseRoots) {
|
||||
RPMSendAsyncMessage("Browser:ResetEnterpriseRootsPref");
|
||||
}
|
||||
|
||||
// We don't actually know what the MitM is called (since we don't
|
||||
// maintain a list), so we'll try and display the common name of the
|
||||
// root issuer to the user. In the worst case they are as clueless as
|
||||
// before, in the best case this gives them an actionable hint.
|
||||
// This may be revised in the future.
|
||||
let names = document.querySelectorAll(".mitm-name");
|
||||
for (let span of names) {
|
||||
span.textContent = failedCertInfo.issuerCommonName;
|
||||
}
|
||||
|
||||
learnMoreLink.href = baseURL + "security-error";
|
||||
|
||||
let title = document.getElementById("et_mitm");
|
||||
desc = document.getElementById("ed_mitm");
|
||||
document.querySelector(".title-text").textContent = title.textContent;
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
document.getElementById("errorShortDescText").innerHTML = desc.innerHTML;
|
||||
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
es.innerHTML = errWhatToDo.innerHTML;
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
est.innerHTML = errWhatToDoTitle.innerHTML;
|
||||
|
||||
updateContainerPosition();
|
||||
break;
|
||||
|
||||
case "MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT":
|
||||
learnMoreLink.href = baseURL + "security-error";
|
||||
break;
|
||||
|
||||
// In case the certificate expired we make sure the system clock
|
||||
// matches the remote-settings service (blocklist via Kinto) ping time
|
||||
// and is not before the build date.
|
||||
case "SEC_ERROR_EXPIRED_CERTIFICATE":
|
||||
case "SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE":
|
||||
case "MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE":
|
||||
case "MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE":
|
||||
learnMoreLink.href = baseURL + "time-errors";
|
||||
// We check against the remote-settings server time first if available, because that allows us
|
||||
// to give the user an approximation of what the correct time is.
|
||||
let difference = event.detail.clockSkewDifference;
|
||||
let lastFetched = event.detail.settingsLastFetched * 1000;
|
||||
|
||||
let now = Date.now();
|
||||
let certRange = {
|
||||
notBefore: failedCertInfo.certValidityRangeNotBefore,
|
||||
notAfter: failedCertInfo.certValidityRangeNotAfter,
|
||||
};
|
||||
let approximateDate = now - difference * 1000;
|
||||
// If the difference is more than a day, we last fetched the date in the last 5 days,
|
||||
// and adjusting the date per the interval would make the cert valid, warn the user:
|
||||
if (Math.abs(difference) > 60 * 60 * 24 && (now - lastFetched) <= 60 * 60 * 24 * 5 &&
|
||||
certRange.notBefore < approximateDate && certRange.notAfter > approximateDate) {
|
||||
clockSkew = true;
|
||||
// If there is no clock skew with Kinto servers, check against the build date.
|
||||
// (The Kinto ping could have happened when the time was still right, or not at all)
|
||||
} else {
|
||||
let appBuildID = event.detail.appBuildID;
|
||||
let year = parseInt(appBuildID.substr(0, 4), 10);
|
||||
let month = parseInt(appBuildID.substr(4, 2), 10) - 1;
|
||||
let day = parseInt(appBuildID.substr(6, 2), 10);
|
||||
|
||||
let buildDate = new Date(year, month, day);
|
||||
let systemDate = new Date();
|
||||
|
||||
// We don't check the notBefore of the cert with the build date,
|
||||
// as it is of course almost certain that it is now later than the build date,
|
||||
// so we shouldn't exclude the possibility that the cert has become valid
|
||||
// since the build date.
|
||||
if (buildDate > systemDate && new Date(certRange.notAfter) > buildDate) {
|
||||
clockSkew = true;
|
||||
}
|
||||
}
|
||||
|
||||
let systemDate = formatter.format(new Date());
|
||||
document.getElementById("wrongSystemTime_systemDate1").textContent = systemDate;
|
||||
if (clockSkew) {
|
||||
document.body.classList.add("illustrated", "clockSkewError");
|
||||
let clockErrTitle = document.getElementById("et_clockSkewError");
|
||||
let clockErrDesc = document.getElementById("ed_clockSkewError");
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
document.querySelector(".title-text").textContent = clockErrTitle.textContent;
|
||||
desc = document.getElementById("errorShortDescText");
|
||||
document.getElementById("errorShortDesc").style.display = "block";
|
||||
document.getElementById("certificateErrorReporting").style.display = "none";
|
||||
if (desc) {
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
desc.innerHTML = clockErrDesc.innerHTML;
|
||||
}
|
||||
let errorPageContainer = document.getElementById("errorPageContainer");
|
||||
let textContainer = document.getElementById("text-container");
|
||||
errorPageContainer.style.backgroundPosition = `left top calc(50vh - ${textContainer.clientHeight / 2}px)`;
|
||||
} else {
|
||||
let targetElems = document.querySelectorAll("#wrongSystemTime_systemDate2");
|
||||
for (let elem of targetElems) {
|
||||
elem.textContent = systemDate;
|
||||
}
|
||||
|
||||
let errDesc = document.getElementById("ed_nssBadCert_SEC_ERROR_EXPIRED_CERTIFICATE");
|
||||
let sd = document.getElementById("errorShortDescText");
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
sd.innerHTML = errDesc.innerHTML;
|
||||
|
||||
let span = sd.querySelector(".hostname");
|
||||
span.textContent = document.location.hostname;
|
||||
|
||||
// The secondary description mentions expired certificates explicitly
|
||||
// and should only be shown if the certificate has actually expired
|
||||
// instead of being not yet valid.
|
||||
if (failedCertInfo.errorCodeString == "SEC_ERROR_EXPIRED_CERTIFICATE") {
|
||||
let cssClass = getCSSClass();
|
||||
let stsSuffix = cssClass == "badStsCert" ? "_sts" : "";
|
||||
let errDesc2 = document.getElementById(
|
||||
`ed2_nssBadCert_SEC_ERROR_EXPIRED_CERTIFICATE${stsSuffix}`);
|
||||
let sd2 = document.getElementById("errorShortDescText2");
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
sd2.innerHTML = errDesc2.innerHTML;
|
||||
}
|
||||
|
||||
if (es) {
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
es.innerHTML = errWhatToDo.innerHTML;
|
||||
}
|
||||
if (est) {
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
est.textContent = errWhatToDoTitle.textContent;
|
||||
est.style.fontWeight = "bold";
|
||||
}
|
||||
updateContainerPosition();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Add slightly more alarming UI unless there are indicators that
|
||||
// show that the error is harmless or can not be skipped anyway.
|
||||
let cssClass = getCSSClass();
|
||||
// Don't alarm users when they can't continue to the website anyway...
|
||||
if (cssClass != "badStsCert" &&
|
||||
// Errors in iframes can't be skipped either...
|
||||
window.parent == window &&
|
||||
// Also don't bother if it's just the user's clock being off...
|
||||
!clockSkew &&
|
||||
// Symantec distrust is likely harmless as well.
|
||||
failedCertInfo.erroCodeString != "MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED") {
|
||||
document.body.classList.add("caution");
|
||||
}
|
||||
}
|
||||
|
||||
function setTechnicalDetailsOnCertError() {
|
||||
|
@ -530,7 +770,6 @@ function setTechnicalDetailsOnCertError() {
|
|||
if (failedCertInfo.isNotValidAtThisTime) {
|
||||
let notBefore = failedCertInfo.validNotBefore;
|
||||
let notAfter = failedCertInfo.validNotAfter;
|
||||
let formatter = new Intl.DateTimeFormat("default");
|
||||
args = {
|
||||
hostname: hostString,
|
||||
};
|
||||
|
|
|
@ -3034,8 +3034,6 @@ var BrowserOnClick = {
|
|||
mm.addMessageListener("Browser:ResetSSLPreferences", this);
|
||||
mm.addMessageListener("Browser:SSLErrorReportTelemetry", this);
|
||||
mm.addMessageListener("Browser:SSLErrorGoBack", this);
|
||||
mm.addMessageListener("Browser:PrimeMitm", this);
|
||||
mm.addMessageListener("Browser:ResetEnterpriseRootsPref", this);
|
||||
},
|
||||
|
||||
uninit() {
|
||||
|
@ -3047,8 +3045,6 @@ var BrowserOnClick = {
|
|||
mm.removeMessageListener("Browser:ResetSSLPreferences", this);
|
||||
mm.removeMessageListener("Browser:SSLErrorReportTelemetry", this);
|
||||
mm.removeMessageListener("Browser:SSLErrorGoBack", this);
|
||||
mm.removeMessageListener("Browser:PrimeMitm", this);
|
||||
mm.removeMessageListener("Browser:ResetEnterpriseRootsPref", this);
|
||||
},
|
||||
|
||||
receiveMessage(msg) {
|
||||
|
@ -3096,76 +3092,9 @@ var BrowserOnClick = {
|
|||
case "Browser:SSLErrorGoBack":
|
||||
goBackFromErrorPage();
|
||||
break;
|
||||
case "Browser:PrimeMitm":
|
||||
this.primeMitm(msg.target);
|
||||
break;
|
||||
case "Browser:ResetEnterpriseRootsPref":
|
||||
Services.prefs.clearUserPref("security.enterprise_roots.enabled");
|
||||
Services.prefs.clearUserPref("security.enterprise_roots.auto-enabled");
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This function does a canary request to a reliable, maintained endpoint, in
|
||||
* order to help network code detect a system-wide man-in-the-middle.
|
||||
*/
|
||||
primeMitm(browser) {
|
||||
// If we already have a mitm canary issuer stored, then don't bother with the
|
||||
// extra request. This will be cleared on every update ping.
|
||||
if (Services.prefs.getStringPref("security.pki.mitm_canary_issuer", null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let url = Services.prefs.getStringPref("security.certerrors.mitm.priming.endpoint");
|
||||
let request = new XMLHttpRequest({mozAnon: true});
|
||||
request.open("HEAD", url);
|
||||
request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
|
||||
request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
|
||||
|
||||
request.addEventListener("error", event => {
|
||||
// Make sure the user is still on the cert error page.
|
||||
if (!browser.documentURI.spec.startsWith("about:certerror")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let secInfo = request.channel.securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
|
||||
if (secInfo.errorCode != SEC_ERROR_UNKNOWN_ISSUER) {
|
||||
return;
|
||||
}
|
||||
|
||||
// When we get to this point there's already something deeply wrong, it's very likely
|
||||
// that there is indeed a system-wide MitM.
|
||||
if (secInfo.serverCert && secInfo.serverCert.issuerName) {
|
||||
// Grab the issuer of the certificate used in the exchange and store it so that our
|
||||
// network-level MitM detection code has a comparison baseline.
|
||||
Services.prefs.setStringPref("security.pki.mitm_canary_issuer", secInfo.serverCert.issuerName);
|
||||
|
||||
// MitM issues are sometimes caused by software not registering their root certs in the
|
||||
// Firefox root store. We might opt for using third party roots from the system root store.
|
||||
if (Services.prefs.getBoolPref("security.certerrors.mitm.auto_enable_enterprise_roots")) {
|
||||
if (!Services.prefs.getBoolPref("security.enterprise_roots.enabled")) {
|
||||
// Loading enterprise roots happens on a background thread, so wait for import to finish.
|
||||
BrowserUtils.promiseObserved("psm:enterprise-certs-imported").then(() => {
|
||||
if (browser.documentURI.spec.startsWith("about:certerror")) {
|
||||
browser.reload();
|
||||
}
|
||||
});
|
||||
|
||||
Services.prefs.setBoolPref("security.enterprise_roots.enabled", true);
|
||||
// Record that this pref was automatically set.
|
||||
Services.prefs.setBoolPref("security.enterprise_roots.auto-enabled", true);
|
||||
}
|
||||
} else {
|
||||
// Need to reload the page to make sure network code picks up the canary issuer pref.
|
||||
browser.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
request.send(null);
|
||||
},
|
||||
|
||||
onCertError(browser, elementId, isTopFrame, location, securityInfoAsString, frameId) {
|
||||
let securityInfo;
|
||||
let cert;
|
||||
|
@ -3214,11 +3143,15 @@ var BrowserOnClick = {
|
|||
securityInfo = getSecurityInfo(securityInfoAsString);
|
||||
let errorInfo = getDetailedCertErrorInfo(location,
|
||||
securityInfo);
|
||||
let clockSkewDifference = Services.prefs.getIntPref("services.settings.clock_skew_seconds", 0);
|
||||
let settingsLastFetched = Services.prefs.getIntPref("services.settings.last_update_seconds", 0);
|
||||
let appBuildID = Services.appinfo.appBuildID;
|
||||
browser.messageManager.sendAsyncMessage("CertErrorDetails", {
|
||||
code: securityInfo.errorCode,
|
||||
info: errorInfo,
|
||||
codeString: securityInfo.errorCodeString,
|
||||
frameId,
|
||||
info: errorInfo,
|
||||
clockSkewDifference,
|
||||
settingsLastFetched,
|
||||
appBuildID,
|
||||
frameId,
|
||||
});
|
||||
break;
|
||||
|
||||
|
|
|
@ -40,9 +40,7 @@ add_task(async function checkWrongSystemTimeWarning() {
|
|||
// Pretend that we recently updated our kinto clock skew pref
|
||||
Services.prefs.setIntPref(PREF_SERVICES_SETTINGS_LAST_FETCHED, Math.floor(Date.now() / 1000));
|
||||
|
||||
let formatter = new Services.intl.DateTimeFormat(undefined, {
|
||||
dateStyle: "long",
|
||||
});
|
||||
let formatter = new Intl.DateTimeFormat("default");
|
||||
|
||||
// For this test, we want to trick Firefox into believing that
|
||||
// the local system time (as returned by Date.now()) is wrong.
|
||||
|
|
|
@ -64,7 +64,7 @@ add_task(async function checkTelemetryClickEvents() {
|
|||
|
||||
let loadEvents = await TestUtils.waitForCondition(() => {
|
||||
let events = Services.telemetry.snapshotEvents(
|
||||
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS, true).content;
|
||||
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS, true).parent;
|
||||
if (events && events.length) {
|
||||
events = events.filter(e => e[1] == "security.ui.certerror" && e[2] == "load");
|
||||
if (events.length == 1 && events[0][5].is_frame == useFrame.toString()) {
|
||||
|
|
|
@ -8,14 +8,23 @@ var EXPORTED_SYMBOLS = ["AboutNetErrorHandler"];
|
|||
|
||||
const {RemotePages} = ChromeUtils.import("resource://gre/modules/remotepagemanager/RemotePageManagerParent.jsm");
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "BrowserUtils", "resource://gre/modules/BrowserUtils.jsm");
|
||||
|
||||
var AboutNetErrorHandler = {
|
||||
_inited: false,
|
||||
_topics: [
|
||||
"Browser:OpenCaptivePortalPage",
|
||||
"Browser:PrimeMitm",
|
||||
"Browser:ResetEnterpriseRootsPref",
|
||||
"RecordCertErrorLoad",
|
||||
],
|
||||
|
||||
init() {
|
||||
this._boundReceiveMessage = this.receiveMessage.bind(this);
|
||||
this.pageListener = new RemotePages(["about:certerror", "about:neterror"]);
|
||||
this.pageListener.addMessageListener("Browser:OpenCaptivePortalPage", this._boundReceiveMessage);
|
||||
for (let topic of this._topics) {
|
||||
this.pageListener.addMessageListener(topic, this._boundReceiveMessage);
|
||||
}
|
||||
this._inited = true;
|
||||
|
||||
Services.obs.addObserver(this, "captive-portal-login-abort");
|
||||
|
@ -27,7 +36,9 @@ var AboutNetErrorHandler = {
|
|||
return;
|
||||
}
|
||||
|
||||
this.pageListener.removeMessageListener("Browser:OpenCaptivePortalPage", this._boundReceiveMessage);
|
||||
for (let topic of this._topics) {
|
||||
this.pageListener.removeMessageListener(topic, this._boundReceiveMessage);
|
||||
}
|
||||
this.pageListener.destroy();
|
||||
|
||||
Services.obs.removeObserver(this, "captive-portal-login-abort");
|
||||
|
@ -50,6 +61,79 @@ var AboutNetErrorHandler = {
|
|||
case "Browser:OpenCaptivePortalPage":
|
||||
Services.obs.notifyObservers(null, "ensure-captive-portal-tab");
|
||||
break;
|
||||
case "Browser:PrimeMitm":
|
||||
this.primeMitm(msg.target.browser);
|
||||
break;
|
||||
case "Browser:ResetEnterpriseRootsPref":
|
||||
Services.prefs.clearUserPref("security.enterprise_roots.enabled");
|
||||
Services.prefs.clearUserPref("security.enterprise_roots.auto-enabled");
|
||||
break;
|
||||
case "RecordCertErrorLoad":
|
||||
Services.telemetry.recordEvent("security.ui.certerror", "load", "aboutcerterror", msg.data.errorCode, {
|
||||
has_sts: msg.data.has_sts.toString(),
|
||||
is_frame: msg.data.is_frame.toString(),
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This function does a canary request to a reliable, maintained endpoint, in
|
||||
* order to help network code detect a system-wide man-in-the-middle.
|
||||
*/
|
||||
primeMitm(browser) {
|
||||
// If we already have a mitm canary issuer stored, then don't bother with the
|
||||
// extra request. This will be cleared on every update ping.
|
||||
if (Services.prefs.getStringPref("security.pki.mitm_canary_issuer", null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let url = Services.prefs.getStringPref("security.certerrors.mitm.priming.endpoint");
|
||||
let request = new XMLHttpRequest({mozAnon: true});
|
||||
request.open("HEAD", url);
|
||||
request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
|
||||
request.channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
|
||||
|
||||
request.addEventListener("error", event => {
|
||||
// Make sure the user is still on the cert error page.
|
||||
if (!browser.documentURI.spec.startsWith("about:certerror")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let secInfo = request.channel.securityInfo.QueryInterface(Ci.nsITransportSecurityInfo);
|
||||
if (secInfo.errorCodeString != "SEC_ERROR_UNKNOWN_ISSUER") {
|
||||
return;
|
||||
}
|
||||
|
||||
// When we get to this point there's already something deeply wrong, it's very likely
|
||||
// that there is indeed a system-wide MitM.
|
||||
if (secInfo.serverCert && secInfo.serverCert.issuerName) {
|
||||
// Grab the issuer of the certificate used in the exchange and store it so that our
|
||||
// network-level MitM detection code has a comparison baseline.
|
||||
Services.prefs.setStringPref("security.pki.mitm_canary_issuer", secInfo.serverCert.issuerName);
|
||||
|
||||
// MitM issues are sometimes caused by software not registering their root certs in the
|
||||
// Firefox root store. We might opt for using third party roots from the system root store.
|
||||
if (Services.prefs.getBoolPref("security.certerrors.mitm.auto_enable_enterprise_roots")) {
|
||||
if (!Services.prefs.getBoolPref("security.enterprise_roots.enabled")) {
|
||||
// Loading enterprise roots happens on a background thread, so wait for import to finish.
|
||||
BrowserUtils.promiseObserved("psm:enterprise-certs-imported").then(() => {
|
||||
if (browser.documentURI.spec.startsWith("about:certerror")) {
|
||||
browser.reload();
|
||||
}
|
||||
});
|
||||
|
||||
Services.prefs.setBoolPref("security.enterprise_roots.enabled", true);
|
||||
// Record that this pref was automatically set.
|
||||
Services.prefs.setBoolPref("security.enterprise_roots.auto-enabled", true);
|
||||
}
|
||||
} else {
|
||||
// Need to reload the page to make sure network code picks up the canary issuer pref.
|
||||
browser.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
request.send(null);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -64,3 +64,9 @@ cert-error-not-yet-valid-now = Websites prove their identity via certificates, w
|
|||
# $error (String) - NSS error code string that specifies type of cert error. e.g. unknown issuer, invalid cert, etc.
|
||||
cert-error-code-prefix-link = Error code: <a data-l10n-name="error-code-link">{ $error }</a>
|
||||
|
||||
# Variables:
|
||||
# $hostname (String) - Hostname of the website with cert error.
|
||||
cert-error-symantec-distrust-description = Websites prove their identity via certificates, which are issued by certificate authorities. Most browsers no longer trust certificates issued by GeoTrust, RapidSSL, Symantec, Thawte, and VeriSign. { $hostname } uses a certificate from one of these authorities and so the website’s identity cannot be proven.
|
||||
|
||||
cert-error-symantec-distrust-admin = You may notify the website’s administrator about this problem.
|
||||
|
||||
|
|
|
@ -247,10 +247,6 @@ body:not(.neterror) #advancedButton {
|
|||
display: none;
|
||||
}
|
||||
|
||||
#wrongSystemTimePanel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#wrongSystemTimeWithoutReferencePanel {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# coding=utf8
|
||||
|
||||
# Any copyright is dedicated to the Public Domain.
|
||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
from __future__ import absolute_import
|
||||
import fluent.syntax.ast as FTL
|
||||
from fluent.migrate.helpers import transforms_from
|
||||
from fluent.migrate.helpers import VARIABLE_REFERENCE
|
||||
from fluent.migrate import COPY, REPLACE
|
||||
|
||||
def migrate(ctx):
|
||||
"""Bug 1552333 - Migrate strings from pipnss.properties to aboutCertError.ftl"""
|
||||
ctx.add_transforms(
|
||||
'browser/browser/aboutCertError.ftl',
|
||||
'browser/browser/aboutCertError.ftl',
|
||||
transforms_from(
|
||||
"""
|
||||
cert-error-symantec-distrust-admin = { COPY(from_path, "certErrorSymantecDistrustAdministrator") }
|
||||
""", from_path="security/manager/chrome/pipnss/pipnss.properties"))
|
||||
ctx.add_transforms(
|
||||
'browser/browser/aboutCertError.ftl',
|
||||
'browser/browser/aboutCertError.ftl',
|
||||
[
|
||||
FTL.Message(
|
||||
id=FTL.Identifier('cert-error-symantec-distrust-description'),
|
||||
value=REPLACE(
|
||||
'security/manager/chrome/pipnss/pipnss.properties',
|
||||
'certErrorSymantecDistrustDescription1',
|
||||
{
|
||||
"%1$S": VARIABLE_REFERENCE("hostname"),
|
||||
},
|
||||
normalize_printf=True
|
||||
),
|
||||
),
|
||||
]
|
||||
)
|
|
@ -285,8 +285,6 @@ certErrorMitM2=%S is backed by the non-profit Mozilla, which administers a compl
|
|||
# LOCALIZATION NOTE (certErrorMitM3): %S is brandShortName
|
||||
certErrorMitM3=%S uses the Mozilla CA store to verify that a connection is secure, rather than certificates supplied by the user’s operating system. So, if an antivirus program or a network is intercepting a connection with a security certificate issued by a CA that is not in the Mozilla CA store, the connection is considered unsafe.
|
||||
|
||||
# LOCALIZATION NOTE (certErrorSymantecDistrustDescription1): %S will be replaced by the domain for which the certificate is valid.
|
||||
certErrorSymantecDistrustDescription1=Websites prove their identity via certificates, which are issued by certificate authorities. Most browsers no longer trust certificates issued by GeoTrust, RapidSSL, Symantec, Thawte, and VeriSign. %S uses a certificate from one of these authorities and so the website’s identity cannot be proven.
|
||||
certErrorSymantecDistrustAdministrator=You may notify the website’s administrator about this problem.
|
||||
|
||||
# LOCALIZATION NOTE (certErrorCodePrefix3): %S is replaced by the error code.
|
||||
|
|
|
@ -25,6 +25,11 @@ ChromeUtils.defineModuleGetter(this, "UpdateUtils",
|
|||
*/
|
||||
let RPMAccessManager = {
|
||||
accessMap: {
|
||||
"about:certerror": {
|
||||
"getFormatURLPref": ["app.support.baseURL"],
|
||||
"getBoolPref": ["security.certerrors.mitm.priming.enabled",
|
||||
"security.enterprise_roots.auto-enabled"],
|
||||
},
|
||||
"about:privatebrowsing": {
|
||||
// "sendAsyncMessage": handled within AboutPrivateBrowsingHandler.jsm
|
||||
"getFormatURLPref": ["app.support.baseURL"],
|
||||
|
@ -41,7 +46,11 @@ let RPMAccessManager = {
|
|||
if (!aPrincipal || !aPrincipal.URI) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let uri = aPrincipal.URI.asciiSpec;
|
||||
if (uri.startsWith("about:certerror")) {
|
||||
uri = "about:certerror";
|
||||
}
|
||||
|
||||
// check if there is an entry for that requestying URI in the accessMap;
|
||||
// if not, deny access.
|
||||
|
|
|
@ -1052,7 +1052,7 @@ security.ui.certerror:
|
|||
- rtestard@mozilla.com
|
||||
- seceng-telemetry@mozilla.com
|
||||
release_channel_collection: opt-out
|
||||
record_in_processes: ["content"]
|
||||
record_in_processes: ["main", "content"]
|
||||
products:
|
||||
- firefox
|
||||
extra_keys:
|
||||
|
|
Загрузка…
Ссылка в новой задаче