diff --git a/dom/locales/en-US/chrome/security/security.properties b/dom/locales/en-US/chrome/security/security.properties index 20918c85e0f2..076229c0c71b 100644 --- a/dom/locales/en-US/chrome/security/security.properties +++ b/dom/locales/en-US/chrome/security/security.properties @@ -19,3 +19,8 @@ LoadingMixedActiveContent=Loading mixed (insecure) active content on a secure pa LoadingMixedDisplayContent=Loading mixed (insecure) display content on a secure page "%1$S" # LOCALIZATION NOTE: Do not translate "allow-scripts", "allow-same-origin", "sandbox" or "iframe" BothAllowScriptsAndSameOriginPresent=An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can remove its sandboxing. + +# LOCALIZATION NOTE: Do not translate "SSL 3.0". +WeakProtocolVersionWarning=This site uses the protocol SSL 3.0 for encryption, which is deprecated and insecure. +# LOCALIZATION NOTE: Do not translate "RC4". +WeakCipherSuiteWarning=This site uses the cipher RC4 for encryption, which is deprecated and insecure. diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 943e9781205b..9b63b0169b7d 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -48,6 +48,8 @@ #include "nsIScriptSecurityManager.h" #include "nsISSLStatus.h" #include "nsISSLStatusProvider.h" +#include "nsITransportSecurityInfo.h" +#include "nsIWebProgressListener.h" #include "LoadContextInfo.h" #include "netCore.h" #include "nsHttpTransaction.h" @@ -1216,6 +1218,25 @@ nsHttpChannel::ProcessSSLInformation() if (!sslstat) return; + nsCOMPtr securityInfo = + do_QueryInterface(mSecurityInfo); + uint32_t state; + if (securityInfo && + NS_SUCCEEDED(securityInfo->GetSecurityState(&state)) && + (state & nsIWebProgressListener::STATE_IS_BROKEN)) { + // Send weak crypto warnings to the web console + if (state & nsIWebProgressListener::STATE_USES_SSL_3) { + nsString consoleErrorTag = NS_LITERAL_STRING("WeakProtocolVersionWarning"); + nsString consoleErrorCategory = NS_LITERAL_STRING("SSL"); + AddSecurityMessage(consoleErrorTag, consoleErrorCategory); + } + if (state & nsIWebProgressListener::STATE_USES_WEAK_CRYPTO) { + nsString consoleErrorTag = NS_LITERAL_STRING("WeakCipherSuiteWarning"); + nsString consoleErrorCategory = NS_LITERAL_STRING("SSL"); + AddSecurityMessage(consoleErrorTag, consoleErrorCategory); + } + } + // Send (SHA-1) signature algorithm errors to the web console nsCOMPtr cert; sslstat->GetServerCert(getter_AddRefs(cert)); diff --git a/security/manager/ssl/src/nsNSSCallbacks.cpp b/security/manager/ssl/src/nsNSSCallbacks.cpp index 75b3935b1b33..50a09400d75b 100644 --- a/security/manager/ssl/src/nsNSSCallbacks.cpp +++ b/security/manager/ssl/src/nsNSSCallbacks.cpp @@ -1172,7 +1172,8 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { infoObject->GetPort(), versions.max); - bool weakEncryption = false; + bool usesWeakProtocol = false; + bool usesWeakCipher = false; SSLChannelInfo channelInfo; rv = SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)); MOZ_ASSERT(rv == SECSuccess); @@ -1191,9 +1192,9 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { sizeof cipherInfo); MOZ_ASSERT(rv == SECSuccess); if (rv == SECSuccess) { - weakEncryption = - (channelInfo.protocolVersion <= SSL_LIBRARY_VERSION_3_0) || - (cipherInfo.symCipher == ssl_calg_rc4); + usesWeakProtocol = + channelInfo.protocolVersion <= SSL_LIBRARY_VERSION_3_0; + usesWeakCipher = cipherInfo.symCipher == ssl_calg_rc4; // keyExchange null=0, rsa=1, dh=2, fortezza=3, ecdh=4 Telemetry::Accumulate( @@ -1265,15 +1266,23 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { if (rv != SECSuccess) { siteSupportsSafeRenego = false; } + bool renegotiationUnsafe = !siteSupportsSafeRenego && + ioLayerHelpers.treatUnsafeNegotiationAsBroken(); - if (!weakEncryption && - (siteSupportsSafeRenego || - !ioLayerHelpers.treatUnsafeNegotiationAsBroken())) { - infoObject->SetSecurityState(nsIWebProgressListener::STATE_IS_SECURE | - nsIWebProgressListener::STATE_SECURE_HIGH); + uint32_t state; + if (usesWeakProtocol || usesWeakCipher || renegotiationUnsafe) { + state = nsIWebProgressListener::STATE_IS_BROKEN; + if (usesWeakProtocol) { + state |= nsIWebProgressListener::STATE_USES_SSL_3; + } + if (usesWeakCipher) { + state |= nsIWebProgressListener::STATE_USES_WEAK_CRYPTO; + } } else { - infoObject->SetSecurityState(nsIWebProgressListener::STATE_IS_BROKEN); + state = nsIWebProgressListener::STATE_IS_SECURE | + nsIWebProgressListener::STATE_SECURE_HIGH; } + infoObject->SetSecurityState(state); // XXX Bug 883674: We shouldn't be formatting messages here in PSM; instead, // we should set a flag on the channel that higher (UI) level code can check diff --git a/uriloader/base/nsIWebProgressListener.idl b/uriloader/base/nsIWebProgressListener.idl index 6bb6811cd2bc..a055cfb9e8af 100644 --- a/uriloader/base/nsIWebProgressListener.idl +++ b/uriloader/base/nsIWebProgressListener.idl @@ -252,6 +252,20 @@ interface nsIWebProgressListener : nsISupports const unsigned long STATE_IDENTITY_EV_TOPLEVEL = 0x00100000; + /** + * Broken state flags + * + * These flags describe the reason of the broken state. + * + * STATE_USES_SSL_3 + * The topmost document uses SSL 3.0. + * + * STATE_USES_WEAK_CRYPTO + * The topmost document uses a weak cipher suite such as RC4. + */ + const unsigned long STATE_USES_SSL_3 = 0x01000000; + const unsigned long STATE_USES_WEAK_CRYPTO = 0x02000000; + /** * Notification indicating the state has changed for one of the requests * associated with aWebProgress.