bug 1254667 - change certificate verification SHA1 policy to "allow for locally-installed roots" r=jcj

Before this patch, the default policy for the use of SHA1 in certificate
signatures was "allow all" due to compatibility concerns.
After gathering telemetry, we are confident that we can enforce the policy of
"allow for locally-installed roots" (or certificates valid before 2016) without
too much breakage.

MozReview-Commit-ID: 8GxtgdbaS3P

--HG--
extra : rebase_source : d1bed911f2d5d40229ea06556fee0848668e98b6
This commit is contained in:
David Keeler 2016-03-28 12:52:40 -07:00
parent 0fbb1c8d67
commit 581a304acb
6 changed files with 21 additions and 25 deletions

View File

@ -1443,11 +1443,6 @@ pref("security.insecure_password.ui.enabled", false);
// 1 = allow MITM for certificate pinning checks.
pref("security.cert_pinning.enforcement_level", 1);
// NB: Changes to this pref affect CERT_CHAIN_SHA1_POLICY_STATUS telemetry.
// See the comment in CertVerifier.cpp.
// 0 = allow SHA-1
pref("security.pki.sha1_enforcement_level", 0);
// Required blocklist freshness for OneCRL OCSP bypass
// (default is 1.25x extensions.blocklist.interval, or 30 hours)
pref("security.onecrl.maximum_staleness_in_seconds", 108000);

View File

@ -518,11 +518,6 @@ pref("security.mixed_content.block_active_content", true);
// Enable pinning
pref("security.cert_pinning.enforcement_level", 1);
// NB: Changes to this pref affect CERT_CHAIN_SHA1_POLICY_STATUS telemetry.
// See the comment in CertVerifier.cpp.
// Allow SHA-1 certificates
pref("security.pki.sha1_enforcement_level", 0);
// Required blocklist freshness for OneCRL OCSP bypass
// (default is 1.25x extensions.blocklist.interval, or 30 hours)
pref("security.onecrl.maximum_staleness_in_seconds", 108000);

View File

@ -44,6 +44,10 @@ pref("security.OCSP.require", false);
pref("security.OCSP.GET.enabled", false);
pref("security.pki.cert_short_lifetime_in_days", 10);
// NB: Changes to this pref affect CERT_CHAIN_SHA1_POLICY_STATUS telemetry.
// See the comment in CertVerifier.cpp.
// 3 = allow SHA-1 for certificates issued before 2016 or by an imported root.
pref("security.pki.sha1_enforcement_level", 3);
pref("security.webauth.u2f", false);
pref("security.webauth.u2f.softtoken", false);

View File

@ -323,11 +323,6 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
for (size_t i = 0;
i < sha1ModeConfigurationsCount && rv != Success && srv == SECSuccess;
i++) {
// Because of the try-strict and fallback approach, we have to clear any
// previously noted telemetry information
if (pinningTelemetryInfo) {
pinningTelemetryInfo->Reset();
}
// Don't attempt verification if the SHA1 mode set by preferences
// (mSHA1Mode) is more restrictive than the SHA1 mode option we're on.
// (To put it another way, only attempt verification if the SHA1 mode
@ -337,6 +332,13 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
if (SHA1ModeMoreRestrictiveThanGivenMode(sha1ModeConfigurations[i])) {
continue;
}
// Because of the try-strict and fallback approach, we have to clear any
// previously noted telemetry information
if (pinningTelemetryInfo) {
pinningTelemetryInfo->Reset();
}
NSSCertDBTrustDomain
trustDomain(trustSSL, evOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
@ -412,11 +414,6 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
for (size_t i = 0; i < keySizeOptionsCount && rv != Success; i++) {
for (size_t j = 0; j < sha1ModeConfigurationsCount && rv != Success;
j++) {
// invalidate any telemetry info relating to failed chains
if (pinningTelemetryInfo) {
pinningTelemetryInfo->Reset();
}
// Don't attempt verification if the SHA1 mode set by preferences
// (mSHA1Mode) is more restrictive than the SHA1 mode option we're on.
// (To put it another way, only attempt verification if the SHA1 mode
@ -427,6 +424,11 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
continue;
}
// invalidate any telemetry info relating to failed chains
if (pinningTelemetryInfo) {
pinningTelemetryInfo->Reset();
}
NSSCertDBTrustDomain trustDomain(trustSSL, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
@ -484,7 +486,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
// Only collect CERT_CHAIN_SHA1_POLICY_STATUS telemetry indicating a
// failure when mSHA1Mode is the default.
// NB: When we change the default, we have to change this.
if (sha1ModeResult && mSHA1Mode == SHA1Mode::Allowed) {
if (sha1ModeResult && mSHA1Mode == SHA1Mode::ImportedRoot) {
*sha1ModeResult = SHA1ModeResult::Failed;
}

View File

@ -62,6 +62,7 @@ function run_test() {
do_get_profile();
Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true);
Services.prefs.setIntPref("security.OCSP.enabled", 1);
Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 3);
add_tls_server_setup("OCSPStaplingServer", "ocsp_certs");
let ocspResponder = new HttpServer();
@ -136,8 +137,6 @@ function add_tests() {
respondWithError,
respondWithError,
respondWithError,
respondWithError,
respondWithError,
],
"No stapled response -> a fetch should have been attempted");

View File

@ -31,6 +31,7 @@ function add_ocsp_test(aHost, aExpectedResult, aOCSPResponseToServe,
do_get_profile();
Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true);
Services.prefs.setIntPref("security.OCSP.enabled", 1);
Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 3);
var args = [["good", "default-ee", "unused"],
["expiredresponse", "default-ee", "unused"],
["oldvalidperiod", "default-ee", "unused"],
@ -53,9 +54,9 @@ var ocspResponseUnknown = ocspResponses[4];
var willNotRetry = 1;
// but sometimes, since a bad response is in the cache, OCSP fetch will be
// attempted for each validation - in practice, for these test certs, this
// means 8 requests because various hash algorithm and key size combinations
// means 6 requests because various hash algorithm and key size combinations
// are tried.
var willRetry = 8;
var willRetry = 6;
function run_test() {
let ocspResponder = new HttpServer();