Bug 1288246 - Don't disable fallback cipher suites globally. r?keeler
The PSM fallback logic should not affect outside PSM. This was not a problem when RC4 was the fallback cipher because DTLS prohibited RC4 from day one.
MozReview-Commit-ID: 84oDlufmhLp
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -1314,23 +1314,23 @@ static_assert(MOZ_ARRAY_LENGTH(sCipherPr
/*static*/ bool
nsNSSComponent::AreAnyFallbackCiphersEnabled()
{
return !!sEnabledFallbackCiphers;
}
/*static*/ void
-nsNSSComponent::UseFallbackCiphersOnSocket(PRFileDesc* fd)
+nsNSSComponent::UseFallbackCiphersOnSocket(PRFileDesc* fd, bool use)
{
const uint32_t enabledFallbackCiphers = sEnabledFallbackCiphers;
const CipherPref* const cp = sCipherPrefs;
for (size_t i = 0; cp[i].pref; ++i) {
if (enabledFallbackCiphers & ((uint32_t)1 << i)) {
- SSL_CipherPrefSet(fd, cp[i].id, true);
+ SSL_CipherPrefSet(fd, cp[i].id, use);
}
}
}
// This function will convert from pref values like 1, 2, ...
// to the internal values of SSL_LIBRARY_VERSION_TLS_1_0,
// SSL_LIBRARY_VERSION_TLS_1_1, ...
/*static*/ void
@@ -1433,31 +1433,26 @@ CipherSuiteChangeObserver::Observe(nsISu
NS_ConvertUTF16toUTF8 prefName(someData);
// Look through the cipher table and set according to pref setting
const CipherPref* const cp = sCipherPrefs;
for (size_t i = 0; cp[i].pref; ++i) {
if (prefName.Equals(cp[i].pref)) {
bool cipherEnabled = Preferences::GetBool(cp[i].pref,
cp[i].enabledByDefault);
if (cp[i].fallback) {
- // Fallback ciphers will not be used by default even if they
- // are enabled in prefs. They are only used on specific
- // sockets as a part of a fallback mechanism.
- // Only the main thread will change sEnabledFallbackCiphers.
uint32_t enabledFallbackCiphers = sEnabledFallbackCiphers;
if (cipherEnabled) {
enabledFallbackCiphers |= ((uint32_t)1 << i);
} else {
enabledFallbackCiphers &= ~((uint32_t)1 << i);
}
sEnabledFallbackCiphers = enabledFallbackCiphers;
- } else {
- SSL_CipherPrefSetDefault(cp[i].id, cipherEnabled);
- SSL_ClearSessionCache();
}
+ SSL_CipherPrefSetDefault(cp[i].id, cipherEnabled);
+ SSL_ClearSessionCache();
break;
}
}
} else if (nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
Preferences::RemoveObserver(this, "security.");
MOZ_ASSERT(sObserver.get() == this);
sObserver = nullptr;
nsCOMPtr<nsIObserverService> observerService =
@@ -2292,25 +2287,20 @@ InitializeCipherSuite()
}
// Now only set SSL/TLS ciphers we knew about at compile time
uint32_t enabledFallbackCiphers = 0;
const CipherPref* const cp = sCipherPrefs;
for (size_t i = 0; cp[i].pref; ++i) {
bool cipherEnabled = Preferences::GetBool(cp[i].pref,
cp[i].enabledByDefault);
- if (cp[i].fallback) {
- // Fallback ciphers are not used by default. See the comment
- // in CipherSuiteChangeObserver::Observe for details.
- if (cipherEnabled) {
- enabledFallbackCiphers |= ((uint32_t)1 << i);
- }
- } else {
- SSL_CipherPrefSetDefault(cp[i].id, cipherEnabled);
+ if (cp[i].fallback && cipherEnabled) {
+ enabledFallbackCiphers |= ((uint32_t)1 << i);
}
+ SSL_CipherPrefSetDefault(cp[i].id, cipherEnabled);
}
sEnabledFallbackCiphers = enabledFallbackCiphers;
// Enable ciphers for PKCS#12
SEC_PKCS12EnableCipher(PKCS12_RC4_40, 1);
SEC_PKCS12EnableCipher(PKCS12_RC4_128, 1);
SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1);
SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1);
--- a/security/manager/ssl/nsNSSComponent.h
+++ b/security/manager/ssl/nsNSSComponent.h
@@ -155,17 +155,17 @@ public:
NS_IMETHOD GetEnterpriseRoots(nsIX509CertList** enterpriseRoots) override;
#endif
::already_AddRefed<mozilla::psm::SharedCertVerifier>
GetDefaultCertVerifier() override;
// The following two methods are thread-safe.
static bool AreAnyFallbackCiphersEnabled();
- static void UseFallbackCiphersOnSocket(PRFileDesc* fd);
+ static void UseFallbackCiphersOnSocket(PRFileDesc* fd, bool use);
static void FillTLSVersionRange(SSLVersionRange& rangeOut,
uint32_t minFromPrefs,
uint32_t maxFromPrefs,
SSLVersionRange defaults);
protected:
virtual ~nsNSSComponent();
--- a/security/manager/ssl/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/nsNSSIOLayer.cpp
@@ -2402,18 +2402,18 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, b
static_cast<unsigned int>(range.max),
strongCiphersStatus == StrongCiphersFailed ? " with fallback ciphers" : ""));
if (SSL_VersionRangeSet(fd, &range) != SECSuccess) {
return NS_ERROR_FAILURE;
}
infoObject->SetTLSVersionRange(range);
- if (strongCiphersStatus == StrongCiphersFailed) {
- nsNSSComponent::UseFallbackCiphersOnSocket(fd);
+ if (strongCiphersStatus != StrongCiphersFailed) {
+ nsNSSComponent::UseFallbackCiphersOnSocket(fd, false);
}
// when adjustForTLSIntolerance tweaks the maximum version downward,
// we tell the server using this SCSV so they can detect a downgrade attack
if (range.max < maxEnabledVersion) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
("[%p] nsSSLIOLayerSetOptions: enabling TLS_FALLBACK_SCSV\n", fd));
// Some servers will choke if we send the fallback SCSV with TLS 1.2.