зеркало из https://github.com/mozilla/gecko-dev.git
Bug 535649 - Implement UI around CVE-2009-3555 and draft-rescorla-tls-renegotiation, r=rrelyea
== NSS 3.12.6 will block some renegotiation attempts on SSL sockets by default == This patch does not yet implement new UI by default, but adds 4 new prefs to get fine grained control (blocking/allowing, displaying broken state) == One of the prefs is a temporary pref that is supposed to go away at some point in the future
This commit is contained in:
Родитель
2bfab230a2
Коммит
62caa75f94
|
@ -5,6 +5,11 @@ pref("security.enable_ssl3", true);
|
|||
pref("security.enable_tls", true);
|
||||
pref("security.enable_tls_session_tickets", true);
|
||||
|
||||
pref("security.ssl.allow_unrestricted_renego_everywhere__temporarily_available_pref", false);
|
||||
pref("security.ssl.renego_unrestricted_hosts", "");
|
||||
pref("security.ssl.treat_unsafe_negotiation_as_broken", false);
|
||||
pref("security.ssl.require_safe_negotiation", false);
|
||||
|
||||
pref("security.ssl2.rc4_128", false);
|
||||
pref("security.ssl2.rc2_128", false);
|
||||
pref("security.ssl2.des_ede3_192", false);
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsIConsoleService.h"
|
||||
|
||||
#include "ssl.h"
|
||||
#include "cert.h"
|
||||
|
@ -871,6 +872,28 @@ void PR_CALLBACK HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
|||
secStatus = (nsIWebProgressListener::STATE_IS_SECURE |
|
||||
nsIWebProgressListener::STATE_SECURE_LOW);
|
||||
|
||||
PRBool siteSupportsSafeRenego;
|
||||
if (SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn, &siteSupportsSafeRenego) != SECSuccess
|
||||
|| !siteSupportsSafeRenego) {
|
||||
|
||||
nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
|
||||
nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
||||
if (infoObject && console) {
|
||||
nsXPIDLCString hostName;
|
||||
infoObject->GetHostName(getter_Copies(hostName));
|
||||
|
||||
nsAutoString msg;
|
||||
msg.Append(NS_ConvertASCIItoUTF16(hostName));
|
||||
msg.Append(NS_LITERAL_STRING(" : potentially vulnerable to CVE-2009-3555"));
|
||||
|
||||
console->LogStringMessage(msg.get());
|
||||
}
|
||||
if (nsSSLIOLayerHelpers::treatUnsafeNegotiationAsBroken()) {
|
||||
secStatus = nsIWebProgressListener::STATE_IS_BROKEN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CERTCertificate *peerCert = SSL_PeerCertificate(fd);
|
||||
const char* caName = nsnull; // caName is a pointer only, no ownership
|
||||
char* certOrgName = CERT_GetOrgName(&peerCert->issuer);
|
||||
|
|
|
@ -1693,6 +1693,15 @@ nsNSSComponent::InitializeNSS(PRBool showWarningBox)
|
|||
mPrefBranch->GetBoolPref("security.enable_tls_session_tickets", &enabled);
|
||||
SSL_OptionSetDefault(SSL_ENABLE_SESSION_TICKETS, enabled);
|
||||
|
||||
mPrefBranch->GetBoolPref("security.ssl.require_safe_negotiation", &enabled);
|
||||
SSL_OptionSetDefault(SSL_REQUIRE_SAFE_NEGOTIATION, enabled);
|
||||
|
||||
mPrefBranch->GetBoolPref(
|
||||
"security.ssl.allow_unrestricted_renego_everywhere__temporarily_available_pref",
|
||||
&enabled);
|
||||
SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION,
|
||||
enabled ? SSL_RENEGOTIATE_UNRESTRICTED : SSL_RENEGOTIATE_REQUIRES_XTN);
|
||||
|
||||
// Disable any ciphers that NSS might have enabled by default
|
||||
for (PRUint16 i = 0; i < SSL_NumImplementedCiphers; ++i)
|
||||
{
|
||||
|
@ -1853,7 +1862,18 @@ nsNSSComponent::Init()
|
|||
}
|
||||
|
||||
nsSSLIOLayerHelpers::Init();
|
||||
char *unrestricted_hosts=nsnull;
|
||||
mPrefBranch->GetCharPref("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts);
|
||||
if (unrestricted_hosts) {
|
||||
nsSSLIOLayerHelpers::setRenegoUnrestrictedSites(nsDependentCString(unrestricted_hosts));
|
||||
nsMemory::Free(unrestricted_hosts);
|
||||
unrestricted_hosts=nsnull;
|
||||
}
|
||||
|
||||
PRBool enabled = PR_FALSE;
|
||||
mPrefBranch->GetBoolPref("security.ssl.treat_unsafe_negotiation_as_broken", &enabled);
|
||||
nsSSLIOLayerHelpers::setTreatUnsafeNegotiationAsBroken(enabled);
|
||||
|
||||
mClientAuthRememberService = new nsClientAuthRememberService;
|
||||
if (mClientAuthRememberService)
|
||||
mClientAuthRememberService->Init();
|
||||
|
@ -2184,6 +2204,23 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic,
|
|||
} else if (prefName.Equals("security.enable_tls_session_tickets")) {
|
||||
mPrefBranch->GetBoolPref("security.enable_tls_session_tickets", &enabled);
|
||||
SSL_OptionSetDefault(SSL_ENABLE_SESSION_TICKETS, enabled);
|
||||
} else if (prefName.Equals("security.ssl.require_safe_negotiation")) {
|
||||
mPrefBranch->GetBoolPref("security.ssl.require_safe_negotiation", &enabled);
|
||||
SSL_OptionSetDefault(SSL_REQUIRE_SAFE_NEGOTIATION, enabled);
|
||||
} else if (prefName.Equals("security.ssl.allow_unrestricted_renego_everywhere__temporarily_available_pref")) {
|
||||
mPrefBranch->GetBoolPref("security.ssl.allow_unrestricted_renego_everywhere__temporarily_available_pref", &enabled);
|
||||
SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION,
|
||||
enabled ? SSL_RENEGOTIATE_UNRESTRICTED : SSL_RENEGOTIATE_REQUIRES_XTN);
|
||||
} else if (prefName.Equals("security.ssl.renego_unrestricted_hosts")) {
|
||||
char *unrestricted_hosts=nsnull;
|
||||
mPrefBranch->GetCharPref("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts);
|
||||
if (unrestricted_hosts) {
|
||||
nsSSLIOLayerHelpers::setRenegoUnrestrictedSites(nsDependentCString(unrestricted_hosts));
|
||||
nsMemory::Free(unrestricted_hosts);
|
||||
}
|
||||
} else if (prefName.Equals("security.ssl.treat_unsafe_negotiation_as_broken")) {
|
||||
mPrefBranch->GetBoolPref("security.ssl.treat_unsafe_negotiation_as_broken", &enabled);
|
||||
nsSSLIOLayerHelpers::setTreatUnsafeNegotiationAsBroken(enabled);
|
||||
} else if (prefName.Equals("security.OCSP.enabled")
|
||||
|| prefName.Equals("security.OCSP.require")) {
|
||||
setOCSPOptions(mPrefBranch);
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
#include "nsIClassInfoImpl.h"
|
||||
#include "nsIProgrammingLanguage.h"
|
||||
#include "nsIArray.h"
|
||||
#include "nsCommaSeparatedTokenizer.h"
|
||||
|
||||
#include "ssl.h"
|
||||
#include "secerr.h"
|
||||
|
@ -837,6 +838,11 @@ void nsSSLIOLayerHelpers::Cleanup()
|
|||
mTLSTolerantSites = nsnull;
|
||||
}
|
||||
|
||||
if (mRenegoUnrestrictedSites) {
|
||||
delete mRenegoUnrestrictedSites;
|
||||
mRenegoUnrestrictedSites = nsnull;
|
||||
}
|
||||
|
||||
if (mSharedPollableEvent)
|
||||
PR_DestroyPollableEvent(mSharedPollableEvent);
|
||||
|
||||
|
@ -1986,6 +1992,8 @@ PRLock *nsSSLIOLayerHelpers::mutex = nsnull;
|
|||
nsCStringHashSet *nsSSLIOLayerHelpers::mTLSIntolerantSites = nsnull;
|
||||
nsCStringHashSet *nsSSLIOLayerHelpers::mTLSTolerantSites = nsnull;
|
||||
nsPSMRememberCertErrorsTable *nsSSLIOLayerHelpers::mHostsWithCertErrors = nsnull;
|
||||
nsCStringHashSet *nsSSLIOLayerHelpers::mRenegoUnrestrictedSites = nsnull;
|
||||
PRBool nsSSLIOLayerHelpers::mTreatUnsafeNegotiationAsBroken = PR_FALSE;
|
||||
PRFileDesc *nsSSLIOLayerHelpers::mSharedPollableEvent = nsnull;
|
||||
nsNSSSocketInfo *nsSSLIOLayerHelpers::mSocketOwningPollableEvent = nsnull;
|
||||
PRBool nsSSLIOLayerHelpers::mPollableEventCurrentlySet = PR_FALSE;
|
||||
|
@ -2204,6 +2212,14 @@ nsresult nsSSLIOLayerHelpers::Init()
|
|||
// the rate of hashtable array reallocation.
|
||||
mTLSTolerantSites->Init(16);
|
||||
|
||||
mRenegoUnrestrictedSites = new nsCStringHashSet();
|
||||
if (!mRenegoUnrestrictedSites)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mRenegoUnrestrictedSites->Init(1);
|
||||
|
||||
mTreatUnsafeNegotiationAsBroken = PR_FALSE;
|
||||
|
||||
mHostsWithCertErrors = new nsPSMRememberCertErrorsTable();
|
||||
if (!mHostsWithCertErrors || !mHostsWithCertErrors->mErrorHosts.IsInitialized())
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -2231,6 +2247,49 @@ PRBool nsSSLIOLayerHelpers::isKnownAsIntolerantSite(const nsCString &str)
|
|||
return mTLSIntolerantSites->Contains(str);
|
||||
}
|
||||
|
||||
void nsSSLIOLayerHelpers::setRenegoUnrestrictedSites(const nsCString &str)
|
||||
{
|
||||
nsAutoLock lock(mutex);
|
||||
|
||||
if (mRenegoUnrestrictedSites) {
|
||||
delete mRenegoUnrestrictedSites;
|
||||
mRenegoUnrestrictedSites = nsnull;
|
||||
}
|
||||
|
||||
mRenegoUnrestrictedSites = new nsCStringHashSet();
|
||||
if (!mRenegoUnrestrictedSites)
|
||||
return;
|
||||
|
||||
mRenegoUnrestrictedSites->Init(1);
|
||||
|
||||
nsCCommaSeparatedTokenizer toker(str);
|
||||
|
||||
while (toker.hasMoreTokens()) {
|
||||
const nsCSubstring &host = toker.nextToken();
|
||||
if (!host.IsEmpty()) {
|
||||
mRenegoUnrestrictedSites->Put(host);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsSSLIOLayerHelpers::isRenegoUnrestrictedSite(const nsCString &str)
|
||||
{
|
||||
nsAutoLock lock(mutex);
|
||||
return mRenegoUnrestrictedSites->Contains(str);
|
||||
}
|
||||
|
||||
void nsSSLIOLayerHelpers::setTreatUnsafeNegotiationAsBroken(PRBool broken)
|
||||
{
|
||||
nsAutoLock lock(mutex);
|
||||
mTreatUnsafeNegotiationAsBroken = broken;
|
||||
}
|
||||
|
||||
PRBool nsSSLIOLayerHelpers::treatUnsafeNegotiationAsBroken()
|
||||
{
|
||||
nsAutoLock lock(mutex);
|
||||
return mTreatUnsafeNegotiationAsBroken;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSSLIOLayerNewSocket(PRInt32 family,
|
||||
const char *host,
|
||||
|
@ -3523,6 +3582,15 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, PRBool forSTARTTLS,
|
|||
infoObject)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (nsSSLIOLayerHelpers::isRenegoUnrestrictedSite(nsDependentCString(host))) {
|
||||
if (SECSuccess != SSL_OptionSet(fd, SSL_REQUIRE_SAFE_NEGOTIATION, PR_FALSE)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the Peer ID so that SSL proxy connections work properly.
|
||||
char *peerId;
|
||||
|
|
|
@ -286,7 +286,13 @@ public:
|
|||
static nsCStringHashSet *mTLSIntolerantSites;
|
||||
static nsCStringHashSet *mTLSTolerantSites;
|
||||
static nsPSMRememberCertErrorsTable* mHostsWithCertErrors;
|
||||
|
||||
|
||||
static nsCStringHashSet *mRenegoUnrestrictedSites;
|
||||
static PRBool mTreatUnsafeNegotiationAsBroken;
|
||||
|
||||
static void setTreatUnsafeNegotiationAsBroken(PRBool broken);
|
||||
static PRBool treatUnsafeNegotiationAsBroken();
|
||||
|
||||
static void getSiteKey(nsNSSSocketInfo *socketInfo, nsCSubstring &key);
|
||||
static PRBool rememberPossibleTLSProblemSite(PRFileDesc* fd, nsNSSSocketInfo *socketInfo);
|
||||
static void rememberTolerantSite(PRFileDesc* ssl_layer_fd, nsNSSSocketInfo *socketInfo);
|
||||
|
@ -294,7 +300,10 @@ public:
|
|||
static void addIntolerantSite(const nsCString &str);
|
||||
static void removeIntolerantSite(const nsCString &str);
|
||||
static PRBool isKnownAsIntolerantSite(const nsCString &str);
|
||||
|
||||
|
||||
static void setRenegoUnrestrictedSites(const nsCString &str);
|
||||
static PRBool isRenegoUnrestrictedSite(const nsCString &str);
|
||||
|
||||
static PRFileDesc *mSharedPollableEvent;
|
||||
static nsNSSSocketInfo *mSocketOwningPollableEvent;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче