bug 1328718 - implement system add-on to facilitate rollout of disabling SHA-1 r?jcj,felipe data-review=bsmedberg
MozReview-Commit-ID: L5Q5VGr6UPU
new file mode 100644
--- /dev/null
+++ b/browser/extensions/disableSHA1rollout/README.md
@@ -0,0 +1,99 @@
+This system add-on is a follow-up to the MITM prevalence experiment. The purpose
+is to facilitate rolling out the disabling of SHA-1 in signatures on
+certificates issued by publicly-trusted roots. When installed, this add-on will
+perform a number of checks to determine if it should change the preference that
+controls the SHA-1 policy. First, this should only apply to users on the beta
+update channel. It should also only apply to users who have not otherwise
+changed the policy to always allow or always forbid SHA-1. Additionally, it
+must double-check that the user is not affected by a TLS intercepting proxy
+using a publicly-trusted root. If these checks pass, the add-on will divide the
+population into a test group and a control group (starting on a 10%/90% split).
+The test group will have the policy changed. After doing this, a telemetry
+payload is reported with the following values:
+
+* cohortName -- the name of the group this user is in:
+ 1. "notSafeToDisableSHA1" if the user is behind a MITM proxy using a
+ publicly-trusted root
+ 2. "optedOut" if the user already set the SHA-1 policy to always allow or
+ always forbid
+ 3. "optedIn" if the user already set the SHA-1 policy to only allow for
+ non-built-in roots
+ 4. "test" if the user is in the test cohort (and SHA-1 will be disabled)
+ 5. "control" if the user is not in the test cohort
+* errorCode -- 0 for successful connections, some PR error code otherwise
+* error -- a short description of one of four error conditions encountered, if
+ applicable, and an empty string otherwise:
+ 1. "timeout" if the connection to telemetry.mozilla.org timed out
+ 2. "user override" if the user has stored a permanent certificate exception
+ override for telemetry.mozilla.org (due to technical limitations, we can't
+ gather much information in this situation)
+ 3. "certificate reverification" if re-building the certificate chain after
+ connecting failed for some reason (unfortunately this step is necessary
+ due to technical limitations)
+ 4. "connection error" if the connection to telemetry.mozilla.org failed for
+ another reason
+* chain -- a list of dictionaries each corresponding to a certificate in the
+ verified certificate chain, if it was successfully constructed. The first
+ entry is the end-entity certificate. The last entry is the root certificate.
+ This will be empty if the connection failed or if reverification failed. Each
+ element in the list contains the following values:
+ * sha256Fingerprint -- a hex string representing the SHA-256 hash of the
+ certificate
+ * isBuiltInRoot -- true if the certificate is a trust anchor in the web PKI,
+ false otherwise
+ * signatureAlgorithm -- a description of the algorithm used to sign the
+ certificate. Will be one of "md2WithRSAEncryption", "md5WithRSAEncryption",
+ "sha1WithRSAEncryption", "sha256WithRSAEncryption",
+ "sha384WithRSAEncryption", "sha512WithRSAEncryption", "ecdsaWithSHA1",
+ "ecdsaWithSHA224", "ecdsaWithSHA256", "ecdsaWithSHA384", "ecdsaWithSHA512",
+ or "unknown".
+* disabledSHA1 -- true if SHA-1 was disabled, false otherwise
+* didNotDisableSHA1Because -- a short string describing why SHA-1 could not be
+ disabled, if applicable. Reasons are limited to:
+ 1. "MITM" if the user is behind a TLS intercepting proxy using a
+ publicly-trusted root
+ 2. "connection error" if there was an error connecting to
+ telemetry.mozilla.org
+ 3. "code error" if some inconsistent state was detected, and it was
+ determined that the experiment should not attempt to change the
+ preference
+ 4. "preference:userReset" if the user reset the SHA-1 policy after it had
+ been changed by this add-on
+ 5. "preference:allow" if the user had already configured Firefox to always
+ accept SHA-1 signatures
+ 6. "preference:forbid" if the user had already configured Firefox to always
+ forbid SHA-1 signatures
+
+For a connection not intercepted by a TLS proxy and where the user is in the
+test cohort, the expected result will be:
+
+ { "cohortName": "test",
+ "errorCode": 0,
+ "error": "",
+ "chain": [
+ { "sha256Fingerprint": "197feaf3faa0f0ad637a89c97cb91336bfc114b6b3018203cbd9c3d10c7fa86c",
+ "isBuiltInRoot": false,
+ "signatureAlgorithm": "sha256WithRSAEncryption"
+ },
+ { "sha256Fingerprint": "154c433c491929c5ef686e838e323664a00e6a0d822ccc958fb4dab03e49a08f",
+ "isBuiltInRoot": false,
+ "signatureAlgorithm": "sha256WithRSAEncryption"
+ },
+ { "sha256Fingerprint": "4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161",
+ "isBuiltInRoot": true,
+ "signatureAlgorithm": "sha1WithRSAEncryption"
+ }
+ ],
+ "disabledSHA1": true,
+ "didNotDisableSHA1Because": ""
+ }
+
+When this result is encountered, the user's preferences are updated to disable
+SHA-1 in signatures on certificates issued by publicly-trusted roots.
+Similarly, if the user is behind a TLS intercepting proxy but the root
+certificate is not part of the public web PKI, we can also disable SHA-1 in
+signatures on certificates issued by publicly-trusted roots.
+
+If the user has already indicated in their preferences that they will always
+accept SHA-1 in signatures or that they will never accept SHA-1 in signatures,
+then the preference is not changed.
copy from browser/extensions/e10srollout/bootstrap.js
copy to browser/extensions/disableSHA1rollout/bootstrap.js
--- a/browser/extensions/e10srollout/bootstrap.js
+++ b/browser/extensions/disableSHA1rollout/bootstrap.js
@@ -4,171 +4,303 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/UpdateUtils.jsm");
+Cu.import("resource://gre/modules/TelemetryController.jsm");
- // The amount of people to be part of e10s
+ // Percentage of the population to attempt to disable SHA-1 for, by channel.
const TEST_THRESHOLD = {
- "beta" : 0.5, // 50%
- "release" : 1.0, // 100%
-};
-
-const ADDON_ROLLOUT_POLICY = {
- "beta" : "51alladdons", // Any WebExtension or addon except with mpc = false
- "release" : "51set1",
+ beta: 0.1, // 10%
};
-const PREF_COHORT_SAMPLE = "e10s.rollout.cohortSample";
-const PREF_COHORT_NAME = "e10s.rollout.cohort";
-const PREF_E10S_OPTED_IN = "browser.tabs.remote.autostart";
-const PREF_E10S_FORCE_ENABLED = "browser.tabs.remote.force-enable";
-const PREF_E10S_FORCE_DISABLED = "browser.tabs.remote.force-disable";
-const PREF_TOGGLE_E10S = "browser.tabs.remote.autostart.2";
-const PREF_E10S_ADDON_POLICY = "extensions.e10s.rollout.policy";
-const PREF_E10S_ADDON_BLOCKLIST = "extensions.e10s.rollout.blocklist";
-const PREF_E10S_HAS_NONEXEMPT_ADDON = "extensions.e10s.rollout.hasAddon";
+const PREF_COHORT_SAMPLE = "disableSHA1.rollout.cohortSample";
+const PREF_COHORT_NAME = "disableSHA1.rollout.cohort";
+const PREF_SHA1_POLICY = "security.pki.sha1_enforcement_level";
+const PREF_SHA1_POLICY_SET_BY_ADDON = "disableSHA1.rollout.policySetByAddOn";
+const PREF_SHA1_POLICY_RESET_BY_USER = "disableSHA1.rollout.userResetPref";
+
+const SHA1_MODE_ALLOW = 0;
+const SHA1_MODE_FORBID = 1;
+const SHA1_MODE_IMPORTED_ROOTS_ONLY = 3;
+const SHA1_MODE_CURRENT_DEFAULT = 4;
function startup() {
- // In theory we only need to run this once (on install()), but
- // it's better to also run it on every startup. If the user has
- // made manual changes to the prefs, this will keep the data
- // reported more accurate.
- // It's also fine (and preferred) to just do it here on startup
- // (instead of observing prefs), because e10s takes a restart
- // to take effect, so we keep the data based on how it was when
- // the session started.
- defineCohort();
+ Preferences.observe(PREF_SHA1_POLICY, policyPreferenceChanged);
}
function install() {
- defineCohort();
+ let updateChannel = UpdateUtils.getUpdateChannel(false);
+ if (updateChannel in TEST_THRESHOLD) {
+ makeRequest().then(defineCohort).catch((e) => console.error(e));
+ }
}
-let cohortDefinedOnThisSession = false;
-
-function defineCohort() {
- // Avoid running twice when it was called by install() first
- if (cohortDefinedOnThisSession) {
- return;
- }
- cohortDefinedOnThisSession = true;
-
- let updateChannel = UpdateUtils.getUpdateChannel(false);
- if (!(updateChannel in TEST_THRESHOLD)) {
- setCohort("unsupportedChannel");
- return;
- }
-
- let addonPolicy = "unknown";
- if (updateChannel in ADDON_ROLLOUT_POLICY) {
- addonPolicy = ADDON_ROLLOUT_POLICY[updateChannel];
- Preferences.set(PREF_E10S_ADDON_POLICY, addonPolicy);
- // This is also the proper place to set the blocklist pref
- // in case it is necessary.
-
- // Tab Mix Plus exception tracked at bug 1185672.
- Preferences.set(PREF_E10S_ADDON_BLOCKLIST,
- "{dc572301-7619-498c-a57d-39143191b318}");
- } else {
- Preferences.reset(PREF_E10S_ADDON_POLICY);
- }
-
- let userOptedOut = optedOut();
- let userOptedIn = optedIn();
- let disqualified = (Services.appinfo.multiprocessBlockPolicy != 0);
- let testGroup = (getUserSample() < TEST_THRESHOLD[updateChannel]);
- let hasNonExemptAddon = Preferences.get(PREF_E10S_HAS_NONEXEMPT_ADDON, false);
- let temporaryDisqualification = getTemporaryDisqualification();
-
- let cohortPrefix = "";
- if (disqualified) {
- cohortPrefix = "disqualified-";
- } else if (hasNonExemptAddon) {
- cohortPrefix = `addons-set${addonPolicy}-`;
- }
-
- if (userOptedOut) {
- setCohort("optedOut");
- } else if (userOptedIn) {
- setCohort("optedIn");
- } else if (temporaryDisqualification != "") {
- // Users who are disqualified by the backend (from multiprocessBlockPolicy)
- // can be put into either the test or control groups, because e10s will
- // still be denied by the backend, which is useful so that the E10S_STATUS
- // telemetry probe can be correctly set.
-
- // For these volatile disqualification reasons, however, we must not try
- // to activate e10s because the backend doesn't know about it. E10S_STATUS
- // here will be accumulated as "2 - Disabled", which is fine too.
- setCohort(`temp-disqualified-${temporaryDisqualification}`);
- Preferences.reset(PREF_TOGGLE_E10S);
- } else if (testGroup) {
- setCohort(`${cohortPrefix}test`);
- Preferences.set(PREF_TOGGLE_E10S, true);
- } else {
- setCohort(`${cohortPrefix}control`);
- Preferences.reset(PREF_TOGGLE_E10S);
+function policyPreferenceChanged() {
+ let currentPrefValue = Preferences.get(PREF_SHA1_POLICY,
+ SHA1_MODE_CURRENT_DEFAULT);
+ Preferences.reset(PREF_SHA1_POLICY_RESET_BY_USER);
+ if (currentPrefValue == SHA1_MODE_CURRENT_DEFAULT) {
+ Preferences.set(PREF_SHA1_POLICY_RESET_BY_USER, true);
}
}
+function defineCohort(result) {
+ let userOptedOut = optedOut();
+ let userOptedIn = optedIn();
+ let shouldNotDisableSHA1Because = reasonToNotDisableSHA1(result);
+ let safeToDisableSHA1 = shouldNotDisableSHA1Because.length == 0;
+ let updateChannel = UpdateUtils.getUpdateChannel(false);
+ let testGroup = getUserSample() < TEST_THRESHOLD[updateChannel];
+
+ let cohortName;
+ if (!safeToDisableSHA1) {
+ cohortName = "notSafeToDisableSHA1";
+ } else if (userOptedOut) {
+ cohortName = "optedOut";
+ } else if (userOptedIn) {
+ cohortName = "optedIn";
+ } else if (testGroup) {
+ cohortName = "test";
+ Preferences.ignore(PREF_SHA1_POLICY, policyPreferenceChanged);
+ Preferences.set(PREF_SHA1_POLICY, SHA1_MODE_IMPORTED_ROOTS_ONLY);
+ Preferences.observe(PREF_SHA1_POLICY, policyPreferenceChanged);
+ Preferences.set(PREF_SHA1_POLICY_SET_BY_ADDON, true);
+ } else {
+ cohortName = "control";
+ }
+ Preferences.set(PREF_COHORT_NAME, cohortName);
+ reportTelemetry(result, cohortName, shouldNotDisableSHA1Because,
+ cohortName == "test");
+}
+
function shutdown(data, reason) {
+ Preferences.ignore(PREF_SHA1_POLICY, policyPreferenceChanged);
}
function uninstall() {
}
function getUserSample() {
let prefValue = Preferences.get(PREF_COHORT_SAMPLE, undefined);
let value = 0.0;
if (typeof(prefValue) == "string") {
value = parseFloat(prefValue, 10);
return value;
}
- if (typeof(prefValue) == "number") {
- // convert old integer value
- value = prefValue / 100;
- } else {
- value = Math.random();
- }
+ value = Math.random();
Preferences.set(PREF_COHORT_SAMPLE, value.toString().substr(0, 8));
return value;
}
-function setCohort(cohortName) {
- Preferences.set(PREF_COHORT_NAME, cohortName);
- try {
- if (Ci.nsICrashReporter) {
- Services.appinfo.QueryInterface(Ci.nsICrashReporter).annotateCrashReport("E10SCohort", cohortName);
+function reportTelemetry(result, cohortName, didNotDisableSHA1Because,
+ disabledSHA1) {
+ result.cohortName = cohortName;
+ result.disabledSHA1 = disabledSHA1;
+ if (cohortName == "optedOut") {
+ let userResetPref = Preferences.get(PREF_SHA1_POLICY_RESET_BY_USER, false);
+ let currentPrefValue = Preferences.get(PREF_SHA1_POLICY,
+ SHA1_MODE_CURRENT_DEFAULT);
+ if (userResetPref) {
+ didNotDisableSHA1Because = "preference:userReset";
+ } else if (currentPrefValue == SHA1_MODE_ALLOW) {
+ didNotDisableSHA1Because = "preference:allow";
+ } else {
+ didNotDisableSHA1Because = "preference:forbid";
}
- } catch (e) {}
+ }
+ result.didNotDisableSHA1Because = didNotDisableSHA1Because;
+ return TelemetryController.submitExternalPing("disableSHA1rollout", result,
+ {});
}
function optedIn() {
- return Preferences.get(PREF_E10S_OPTED_IN, false) ||
- Preferences.get(PREF_E10S_FORCE_ENABLED, false);
+ let policySetByAddOn = Preferences.get(PREF_SHA1_POLICY_SET_BY_ADDON, false);
+ let currentPrefValue = Preferences.get(PREF_SHA1_POLICY,
+ SHA1_MODE_CURRENT_DEFAULT);
+ return currentPrefValue == SHA1_MODE_IMPORTED_ROOTS_ONLY && !policySetByAddOn;
}
function optedOut() {
- // Users can also opt-out by toggling back the pref to false.
- // If they reset the pref instead they might be re-enabled if
- // they are still part of the threshold.
- return Preferences.get(PREF_E10S_FORCE_DISABLED, false) ||
- (Preferences.isSet(PREF_TOGGLE_E10S) &&
- Preferences.get(PREF_TOGGLE_E10S) == false);
+ // Users can also opt-out by setting the policy to always allow or always
+ // forbid SHA-1, or by resetting the preference after this add-on has changed
+ // it (in that case, this will be reported the next time this add-on is
+ // updated).
+ let currentPrefValue = Preferences.get(PREF_SHA1_POLICY,
+ SHA1_MODE_CURRENT_DEFAULT);
+ let userResetPref = Preferences.get(PREF_SHA1_POLICY_RESET_BY_USER, false);
+ return currentPrefValue == SHA1_MODE_ALLOW ||
+ currentPrefValue == SHA1_MODE_FORBID ||
+ userResetPref;
+}
+
+function delocalizeAlgorithm(localizedString) {
+ let bundle = Services.strings.createBundle(
+ "chrome://pipnss/locale/pipnss.properties");
+ let algorithmStringIdsToOIDDescriptionMap = {
+ "CertDumpMD2WithRSA": "md2WithRSAEncryption",
+ "CertDumpMD5WithRSA": "md5WithRSAEncryption",
+ "CertDumpSHA1WithRSA": "sha1WithRSAEncryption",
+ "CertDumpSHA256WithRSA": "sha256WithRSAEncryption",
+ "CertDumpSHA384WithRSA": "sha384WithRSAEncryption",
+ "CertDumpSHA512WithRSA": "sha512WithRSAEncryption",
+ "CertDumpAnsiX962ECDsaSignatureWithSha1": "ecdsaWithSHA1",
+ "CertDumpAnsiX962ECDsaSignatureWithSha224": "ecdsaWithSHA224",
+ "CertDumpAnsiX962ECDsaSignatureWithSha256": "ecdsaWithSHA256",
+ "CertDumpAnsiX962ECDsaSignatureWithSha384": "ecdsaWithSHA384",
+ "CertDumpAnsiX962ECDsaSignatureWithSha512": "ecdsaWithSHA512",
+ };
+
+ let description;
+ Object.keys(algorithmStringIdsToOIDDescriptionMap).forEach((l10nID) => {
+ let candidateLocalizedString = bundle.GetStringFromName(l10nID);
+ if (localizedString == candidateLocalizedString) {
+ description = algorithmStringIdsToOIDDescriptionMap[l10nID];
+ }
+ });
+ if (!description) {
+ return "unknown";
+ }
+ return description;
+}
+
+function getSignatureAlgorithm(cert) {
+ // Certificate ::= SEQUENCE {
+ // tbsCertificate TBSCertificate,
+ // signatureAlgorithm AlgorithmIdentifier,
+ // signatureValue BIT STRING }
+ let certificate = cert.ASN1Structure.QueryInterface(Ci.nsIASN1Sequence);
+ let signatureAlgorithm = certificate.ASN1Objects
+ .queryElementAt(1, Ci.nsIASN1Sequence);
+ // AlgorithmIdentifier ::= SEQUENCE {
+ // algorithm OBJECT IDENTIFIER,
+ // parameters ANY DEFINED BY algorithm OPTIONAL }
+
+ // If parameters is NULL (or empty), signatureAlgorithm won't be a container
+ // under this implementation. Just get its displayValue.
+ if (!signatureAlgorithm.isValidContainer) {
+ return signatureAlgorithm.displayValue;
+ }
+ let oid = signatureAlgorithm.ASN1Objects.queryElementAt(0, Ci.nsIASN1Object);
+ return oid.displayValue;
+}
+
+function processCertChain(chain) {
+ let output = [];
+ let enumerator = chain.getEnumerator();
+ while (enumerator.hasMoreElements()) {
+ let cert = enumerator.getNext().QueryInterface(Ci.nsIX509Cert);
+ output.push({
+ sha256Fingerprint: cert.sha256Fingerprint.replace(/:/g, "").toLowerCase(),
+ isBuiltInRoot: cert.isBuiltInRoot,
+ signatureAlgorithm: delocalizeAlgorithm(getSignatureAlgorithm(cert)),
+ });
+ }
+ return output;
}
-/* If this function returns a non-empty string, it
- * means that this particular user should be temporarily
- * disqualified due to some particular reason.
- * If a user shouldn't be disqualified, then an empty
- * string must be returned.
- */
-function getTemporaryDisqualification() {
+class CertificateVerificationResult {
+ constructor(resolve) {
+ this.resolve = resolve;
+ }
+
+ verifyCertFinished(aPRErrorCode, aVerifiedChain, aEVStatus) {
+ let result = { errorCode: aPRErrorCode, error: "", chain: [] };
+ if (aPRErrorCode == 0) {
+ result.chain = processCertChain(aVerifiedChain);
+ } else {
+ result.error = "certificate reverification";
+ }
+ this.resolve(result);
+ }
+}
+
+function makeRequest() {
+ return new Promise((resolve) => {
+ let hostname = "telemetry.mozilla.org";
+ let req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
+ .createInstance(Ci.nsIXMLHttpRequest);
+ req.open("GET", "https://" + hostname);
+ req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
+ req.timeout = 30000;
+ req.addEventListener("error", (evt) => {
+ // If we can't connect to telemetry.mozilla.org, then how did we even
+ // download the experiment? In any case, we may still be able to get some
+ // information.
+ let result = { error: "connection error" };
+ if (evt.target.channel && evt.target.channel.securityInfo) {
+ let securityInfo = evt.target.channel.securityInfo
+ .QueryInterface(Ci.nsITransportSecurityInfo);
+ if (securityInfo) {
+ result.errorCode = securityInfo.errorCode;
+ }
+ if (securityInfo && securityInfo.failedCertChain) {
+ result.chain = processCertChain(securityInfo.failedCertChain);
+ }
+ }
+ resolve(result);
+ });
+ req.addEventListener("timeout", (evt) => {
+ resolve({ error: "timeout" });
+ });
+ req.addEventListener("load", (evt) => {
+ let securityInfo = evt.target.channel.securityInfo
+ .QueryInterface(Ci.nsITransportSecurityInfo);
+ if (securityInfo.securityState &
+ Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN) {
+ resolve({ error: "user override" });
+ return;
+ }
+ let sslStatus = securityInfo.QueryInterface(Ci.nsISSLStatusProvider)
+ .SSLStatus;
+ let certdb = Cc["@mozilla.org/security/x509certdb;1"]
+ .getService(Ci.nsIX509CertDB);
+ let result = new CertificateVerificationResult(resolve);
+ // Unfortunately, we don't have direct access to the verified certificate
+ // chain as built by the AuthCertificate hook, so we have to re-build it
+ // here. In theory we are likely to get the same result.
+ certdb.asyncVerifyCertAtTime(sslStatus.serverCert,
+ 2, // certificateUsageSSLServer
+ 0, // flags
+ hostname,
+ Date.now() / 1000,
+ result);
+ });
+ req.send();
+ });
+}
+
+// As best we know, it is safe to disable SHA1 if the connection was successful
+// and either the connection was MITM'd by a root not in the public PKI or the
+// chain is part of the public PKI and is the one served by the real
+// telemetry.mozilla.org.
+// This will return a short string description of why it might not be safe to
+// disable SHA1 or an empty string if it is safe to disable SHA1.
+function reasonToNotDisableSHA1(result) {
+ if (!("errorCode" in result) || result.errorCode != 0) {
+ return "connection error";
+ }
+ if (!("chain" in result)) {
+ return "code error";
+ }
+ if (!result.chain[result.chain.length - 1].isBuiltInRoot) {
+ return "";
+ }
+ if (result.chain.length != 3) {
+ return "MITM";
+ }
+ const kEndEntityFingerprint = "197feaf3faa0f0ad637a89c97cb91336bfc114b6b3018203cbd9c3d10c7fa86c";
+ const kIntermediateFingerprint = "154c433c491929c5ef686e838e323664a00e6a0d822ccc958fb4dab03e49a08f";
+ const kRootFingerprint = "4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161";
+ if (result.chain[0].sha256Fingerprint != kEndEntityFingerprint ||
+ result.chain[1].sha256Fingerprint != kIntermediateFingerprint ||
+ result.chain[2].sha256Fingerprint != kRootFingerprint) {
+ return "MITM";
+ }
return "";
}
copy from browser/extensions/e10srollout/install.rdf.in
copy to browser/extensions/disableSHA1rollout/install.rdf.in
--- a/browser/extensions/e10srollout/install.rdf.in
+++ b/browser/extensions/disableSHA1rollout/install.rdf.in
@@ -4,29 +4,29 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
#filter substitution
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
- <em:id>e10srollout@mozilla.org</em:id>
- <em:version>1.7</em:version>
+ <em:id>disableSHA1rollout@mozilla.org</em:id>
+ <em:version>1.0</em:version>
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<!-- Target Application this theme can install into,
with minimum and maximum supported versions. -->
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>@MOZ_APP_VERSION@</em:minVersion>
<em:maxVersion>@MOZ_APP_MAXVERSION@</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
- <em:name>Multi-process staged rollout</em:name>
- <em:description>Staged rollout of Firefox multi-process feature.</em:description>
+ <em:name>SHA-1 deprecation staged rollout</em:name>
+ <em:description>Staged rollout deprecating SHA-1 in certificate signatures.</em:description>
</Description>
</RDF>
copy from browser/extensions/e10srollout/moz.build
copy to browser/extensions/disableSHA1rollout/moz.build
--- a/browser/extensions/e10srollout/moz.build
+++ b/browser/extensions/disableSHA1rollout/moz.build
@@ -2,15 +2,15 @@
# 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/.
DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION']
-FINAL_TARGET_FILES.features['e10srollout@mozilla.org'] += [
+FINAL_TARGET_FILES.features['disableSHA1rollout@mozilla.org'] += [
'bootstrap.js'
]
-FINAL_TARGET_PP_FILES.features['e10srollout@mozilla.org'] += [
+FINAL_TARGET_PP_FILES.features['disableSHA1rollout@mozilla.org'] += [
'install.rdf.in'
]
--- a/browser/extensions/moz.build
+++ b/browser/extensions/moz.build
@@ -1,16 +1,17 @@
# -*- 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/.
DIRS += [
'aushelper',
+ 'disableSHA1rollout',
'e10srollout',
'pdfjs',
'pocket',
'webcompat',
'shield-recipe-client',
]
# Only include the following system add-ons if building Aurora or Nightly
--- a/testing/talos/talos/xtalos/xperf_whitelist.json
+++ b/testing/talos/talos/xtalos/xperf_whitelist.json
@@ -2,16 +2,17 @@
"C:\\$Mft": {"ignore": true},
"C:\\$Extend\\$UsnJrnl:$J": {"ignore": true},
"C:\\Windows\\Prefetch\\{prefetch}.pf": {"ignore": true},
"C:\\$Secure": {"ignore": true},
"C:\\$logfile": {"ignore": true},
"{firefox}\\omni.ja": {"mincount": 0, "maxcount": 46, "minbytes": 0, "maxbytes": 3014656},
"{firefox}\\browser\\omni.ja": {"mincount": 0, "maxcount": 28, "minbytes": 0, "maxbytes": 1835008},
"{firefox}\\browser\\features\\aushelper@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
+ "{firefox}\\browser\\features\\disableSHA1rollout@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\e10srollout@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\flyweb@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\formautofill@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\loop@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\firefox@getpocket.com.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\presentation@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\webcompat@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},
"{firefox}\\browser\\features\\shield-recipe-client@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000},