From b90f244f8b7c1702da2c4c695ab66a950c9e7de1 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Fri, 7 Dec 2012 11:44:11 -0800 Subject: [PATCH 01/35] Bug 818649 - Ensure mach logs are written to log file; r=jhammel DONTBUILD (NPOTB) --- python/mach/mach/logging.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/python/mach/mach/logging.py b/python/mach/mach/logging.py index dc8f3346971b..ec90f2f5b9ba 100644 --- a/python/mach/mach/logging.py +++ b/python/mach/mach/logging.py @@ -112,11 +112,10 @@ class StructuredTerminalFormatter(StructuredHumanFormatter): class LoggingManager(object): """Holds and controls global logging state. - A mozbuild application should instantiate one of these and configure it - as needed. + An application should instantiate one of these and configure it as needed. This class provides a mechanism to configure the output of logging data - both from mozbuild and from the overall logging system (e.g. from other + both from mach and from the overall logging system (e.g. from other modules). """ @@ -135,12 +134,12 @@ class LoggingManager(object): # complaining about "no handlers could be found for logger XXX." self.root_logger.addHandler(logging.NullHandler()) - self.mozbuild_logger = logging.getLogger('mozbuild') - self.mozbuild_logger.setLevel(logging.DEBUG) + self.mach_logger = logging.getLogger('mach') + self.mach_logger.setLevel(logging.DEBUG) self.structured_filter = ConvertToStructuredFilter() - self.structured_loggers = [self.mozbuild_logger] + self.structured_loggers = [self.mach_logger] self._terminal = None @@ -227,6 +226,6 @@ class LoggingManager(object): """Register a structured logger. This needs to be called for all structured loggers that don't chain up - to the mozbuild logger in order for their output to be captured. + to the mach logger in order for their output to be captured. """ self.structured_loggers.append(logger) From a27514f324a8f217f0ed4a458af8b86988e86eda Mon Sep 17 00:00:00 2001 From: Doug Turner Date: Fri, 7 Dec 2012 16:02:48 -0800 Subject: [PATCH 02/35] Bug 808262- Otoro/unagi sometimes start up in landscape and can't be switched to portrait. The working theory is that, for some reason, we can not access the fb. If that happens, just abort and try again later. r=dhylands a=blocking-basecamp --- widget/gonk/Framebuffer.cpp | 2 +- widget/gonk/nsWindow.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/widget/gonk/Framebuffer.cpp b/widget/gonk/Framebuffer.cpp index 1f474ae0b6f3..177785b62b80 100644 --- a/widget/gonk/Framebuffer.cpp +++ b/widget/gonk/Framebuffer.cpp @@ -133,7 +133,7 @@ Open() bool GetSize(nsIntSize *aScreenSize) { // If the framebuffer has been opened, we should always have the size. - if (0 <= sFd || sScreenSize) { + if (sScreenSize) { *aScreenSize = *sScreenSize; return true; } diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp index 2ab8a8344e6b..d472d07a665d 100644 --- a/widget/gonk/nsWindow.cpp +++ b/widget/gonk/nsWindow.cpp @@ -151,8 +151,10 @@ nsWindow::nsWindow() } nsIntSize screenSize; - mozilla::DebugOnly gotFB = Framebuffer::GetSize(&screenSize); - MOZ_ASSERT(gotFB); + bool gotFB = Framebuffer::GetSize(&screenSize); + if (!gotFB) { + NS_RUNTIMEABORT("Failed to get size from framebuffer, aborting..."); + } gScreenBounds = nsIntRect(nsIntPoint(0, 0), screenSize); char propValue[PROPERTY_VALUE_MAX]; From 1aa569d5fdff04f720acc60e5c248a90871b5e39 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:09:41 -0500 Subject: [PATCH 03/35] Bug 769288 - Part 1: Make PSM more amenable to storing concurrent private and non-private data. r=bsmith --- .../pki/resources/content/exceptionDialog.js | 7 +- .../ssl/public/nsIRecentBadCertsService.idl | 10 +- security/manager/ssl/public/nsIX509CertDB.idl | 13 +- security/manager/ssl/src/Makefile.in | 1 + .../ssl/src/SSLServerCertVerification.cpp | 57 ++++--- security/manager/ssl/src/SharedSSLState.cpp | 111 ++++++++++++++ security/manager/ssl/src/SharedSSLState.h | 54 +++++++ .../manager/ssl/src/nsClientAuthRemember.cpp | 12 ++ .../manager/ssl/src/nsClientAuthRemember.h | 1 + security/manager/ssl/src/nsNSSCallbacks.cpp | 8 +- .../manager/ssl/src/nsNSSCertificateDB.cpp | 21 +++ security/manager/ssl/src/nsNSSCertificateDB.h | 5 + security/manager/ssl/src/nsNSSComponent.cpp | 53 +------ security/manager/ssl/src/nsNSSComponent.h | 4 - security/manager/ssl/src/nsNSSIOLayer.cpp | 144 ++++++++++++++---- security/manager/ssl/src/nsNSSIOLayer.h | 58 ++++--- security/manager/ssl/src/nsNSSModule.cpp | 5 - security/manager/ssl/src/nsRecentBadCerts.cpp | 45 ++++-- security/manager/ssl/src/nsRecentBadCerts.h | 13 +- 19 files changed, 471 insertions(+), 151 deletions(-) create mode 100644 security/manager/ssl/src/SharedSSLState.cpp create mode 100644 security/manager/ssl/src/SharedSSLState.h diff --git a/security/manager/pki/resources/content/exceptionDialog.js b/security/manager/pki/resources/content/exceptionDialog.js index e6cae8415859..6d4eb89eacf9 100644 --- a/security/manager/pki/resources/content/exceptionDialog.js +++ b/security/manager/pki/resources/content/exceptionDialog.js @@ -88,8 +88,11 @@ function initExceptionDialog() { // returns true if found and global status could be set function findRecentBadCert(uri) { try { - var recentCertsSvc = Components.classes["@mozilla.org/security/recentbadcerts;1"] - .getService(Components.interfaces.nsIRecentBadCertsService); + var certDB = Components.classes["@mozilla.org/security/x509certdb;1"] + .getService(Components.interfaces.nsIX509CertDB); + if (!certDB) + return false; + var recentCertsSvc = certDB.getRecentBadCertsService(inPrivateBrowsingMode()); if (!recentCertsSvc) return false; diff --git a/security/manager/ssl/public/nsIRecentBadCertsService.idl b/security/manager/ssl/public/nsIRecentBadCertsService.idl index 398b792e4cc1..c221aa1dbd93 100644 --- a/security/manager/ssl/public/nsIRecentBadCertsService.idl +++ b/security/manager/ssl/public/nsIRecentBadCertsService.idl @@ -20,9 +20,8 @@ interface nsISSLStatus; * The implementation will decide how many entries it will hold, * the number is expected to be small. */ -[scriptable, uuid(a5ae8b05-a76e-408f-b0ba-02a831265749)] -interface nsIRecentBadCertsService : nsISupports { - +[scriptable, uuid(0fed7784-d152-44d6-95a7-67a59024de0f)] +interface nsIRecentBadCerts : nsISupports { /** * Retrieve the recently seen bad ssl status for the given hostname:port. * If no SSL cert was recently seen for the given hostname:port, return null. @@ -43,4 +42,9 @@ interface nsIRecentBadCertsService : nsISupports { */ void addBadCert(in AString aHostNameWithPort, in nsISSLStatus aStatus); + + /** + * Clear all stored cert data. + */ + void resetStoredCerts(); }; diff --git a/security/manager/ssl/public/nsIX509CertDB.idl b/security/manager/ssl/public/nsIX509CertDB.idl index cedbb2644473..aec9964a1fab 100644 --- a/security/manager/ssl/public/nsIX509CertDB.idl +++ b/security/manager/ssl/public/nsIX509CertDB.idl @@ -12,6 +12,7 @@ interface nsIX509Cert3; interface nsIFile; interface nsIInterfaceRequestor; interface nsIZipReader; +interface nsIRecentBadCerts; %{C++ #define NS_X509CERTDB_CONTRACTID "@mozilla.org/security/x509certdb;1" @@ -29,7 +30,7 @@ interface nsIOpenSignedJARFileCallback : nsISupports * This represents a service to access and manipulate * X.509 certificates stored in a database. */ -[scriptable, uuid(735d0363-e219-4387-b5c6-72e800c3ea0b)] +[scriptable, uuid(a18df2a5-84a9-46cd-9140-3fdb3879d9ff)] interface nsIX509CertDB : nsISupports { /** @@ -264,6 +265,16 @@ interface nsIX509CertDB : nsISupports { */ nsIX509Cert constructX509FromBase64(in string base64); + /* + * Obtain a reference to the appropriate service for recent + * bad certificates. May only be called on the main thread. + * + * @param isPrivate True if the service for certs for private connections + * is desired, false otherwise. + * @return The requested service. + */ + nsIRecentBadCerts getRecentBadCerts(in boolean isPrivate); + /** * Verifies the signature on the given JAR file to verify that it has a * valid signature. To be considered valid, there must be exactly one diff --git a/security/manager/ssl/src/Makefile.in b/security/manager/ssl/src/Makefile.in index 1ea14e33748b..86028d2e646c 100644 --- a/security/manager/ssl/src/Makefile.in +++ b/security/manager/ssl/src/Makefile.in @@ -74,6 +74,7 @@ CPPSRCS = \ PSMRunnable.cpp \ nsNSSVersion.cpp \ nsCertificatePrincipal.cpp \ + SharedSSLState.cpp \ $(NULL) ifdef MOZ_XUL diff --git a/security/manager/ssl/src/SSLServerCertVerification.cpp b/security/manager/ssl/src/SSLServerCertVerification.cpp index ae09139f1010..6bac3a3abfc6 100644 --- a/security/manager/ssl/src/SSLServerCertVerification.cpp +++ b/security/manager/ssl/src/SSLServerCertVerification.cpp @@ -112,6 +112,7 @@ #include "nsIConsoleService.h" #include "PSMRunnable.h" #include "ScopedNSSTypes.h" +#include "SharedSSLState.h" #include "ssl.h" #include "secerr.h" @@ -238,13 +239,15 @@ class CertErrorRunnable : public SyncRunnableBase uint32_t collectedErrors, PRErrorCode errorCodeTrust, PRErrorCode errorCodeMismatch, - PRErrorCode errorCodeExpired) + PRErrorCode errorCodeExpired, + uint32_t providerFlags) : mFdForLogging(fdForLogging), mCert(cert), mInfoObject(infoObject), mDefaultErrorCodeToReport(defaultErrorCodeToReport), mCollectedErrors(collectedErrors), mErrorCodeTrust(errorCodeTrust), mErrorCodeMismatch(errorCodeMismatch), - mErrorCodeExpired(errorCodeExpired) + mErrorCodeExpired(errorCodeExpired), + mProviderFlags(providerFlags) { } @@ -261,6 +264,7 @@ private: const PRErrorCode mErrorCodeTrust; const PRErrorCode mErrorCodeMismatch; const PRErrorCode mErrorCodeExpired; + const uint32_t mProviderFlags; }; SSLServerCertVerificationResult * @@ -296,12 +300,8 @@ CertErrorRunnable::CheckCertOverrides() if (NS_SUCCEEDED(nsrv)) { nsCOMPtr sslSocketControl = do_QueryInterface( NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject)); - uint32_t flags = 0; - if (sslSocketControl) { - sslSocketControl->GetProviderFlags(&flags); - } nsrv = stss->IsStsHost(mInfoObject->GetHostName(), - flags, + mProviderFlags, &strictTransportSecurityEnabled); } if (NS_FAILED(nsrv)) { @@ -371,8 +371,12 @@ CertErrorRunnable::CheckCertOverrides() } } - nsCOMPtr recentBadCertsService = - do_GetService(NS_RECENTBADCERTS_CONTRACTID); + nsCOMPtr certdb = do_GetService(NS_X509CERTDB_CONTRACTID); + nsCOMPtr recentBadCertsService; + if (certdb) { + bool isPrivate = mProviderFlags & nsISocketProvider::NO_PERMANENT_STORAGE; + certdb->GetRecentBadCerts(isPrivate, getter_AddRefs(recentBadCertsService)); + } if (recentBadCertsService) { NS_ConvertUTF8toUTF16 hostWithPortStringUTF16(hostWithPortString); @@ -418,7 +422,8 @@ CertErrorRunnable * CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport, TransportSecurityInfo * infoObject, CERTCertificate * cert, - const void * fdForLogging) + const void * fdForLogging, + uint32_t providerFlags) { MOZ_ASSERT(infoObject); MOZ_ASSERT(cert); @@ -567,7 +572,8 @@ CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport, static_cast(nssCert.get()), infoObject, defaultErrorCodeToReport, collected_errors, errorCodeTrust, - errorCodeMismatch, errorCodeExpired); + errorCodeMismatch, errorCodeExpired, + providerFlags); } // When doing async cert processing, we dispatch one of these runnables to the @@ -607,25 +613,29 @@ public: // Must be called only on the socket transport thread static SECStatus Dispatch(const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * serverCert); + CERTCertificate * serverCert, + uint32_t providerFlags); private: NS_DECL_NSIRUNNABLE // Must be called only on the socket transport thread SSLServerCertVerificationJob(const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * cert); + CERTCertificate * cert, + uint32_t providerFlags); const void * const mFdForLogging; const RefPtr mInfoObject; const ScopedCERTCertificate mCert; + const uint32_t mProviderFlags; }; SSLServerCertVerificationJob::SSLServerCertVerificationJob( const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * cert) + CERTCertificate * cert, uint32_t providerFlags) : mFdForLogging(fdForLogging) , mInfoObject(infoObject) , mCert(CERT_DupCertificate(cert)) + , mProviderFlags(providerFlags) { } @@ -977,7 +987,8 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert) /*static*/ SECStatus SSLServerCertVerificationJob::Dispatch(const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * serverCert) + CERTCertificate * serverCert, + uint32_t providerFlags) { // Runs on the socket transport thread if (!infoObject || !serverCert) { @@ -987,7 +998,8 @@ SSLServerCertVerificationJob::Dispatch(const void * fdForLogging, } RefPtr job( - new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert)); + new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert, + providerFlags)); nsresult nrv; if (!gCertVerificationThreadPool) { @@ -1042,7 +1054,7 @@ SSLServerCertVerificationJob::Run() error = PR_GetError(); if (error != 0) { RefPtr runnable(CreateCertErrorRunnable( - error, mInfoObject, mCert, mFdForLogging)); + error, mInfoObject, mCert, mFdForLogging, mProviderFlags)); if (!runnable) { // CreateCertErrorRunnable set a new error code error = PR_GetError(); @@ -1135,15 +1147,20 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) PR_SetError(PR_UNKNOWN_ERROR, 0); return SECFailure; } - + + uint32_t providerFlags = 0; + socketInfo->GetProviderFlags(&providerFlags); + if (onSTSThread) { + // We *must* do certificate verification on a background thread because // we need the socket transport thread to be free for our OCSP requests, // and we *want* to do certificate verification on a background thread // because of the performance benefits of doing so. socketInfo->SetCertVerificationWaiting(); SECStatus rv = SSLServerCertVerificationJob::Dispatch( - static_cast(fd), socketInfo, serverCert); + static_cast(fd), socketInfo, serverCert, + providerFlags); return rv; } @@ -1160,7 +1177,7 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) if (error != 0) { RefPtr runnable(CreateCertErrorRunnable( error, socketInfo, serverCert, - static_cast(fd))); + static_cast(fd), providerFlags)); if (!runnable) { // CreateCertErrorRunnable sets a new error code when it fails error = PR_GetError(); diff --git a/security/manager/ssl/src/SharedSSLState.cpp b/security/manager/ssl/src/SharedSSLState.cpp new file mode 100644 index 000000000000..6a4e7b1a493a --- /dev/null +++ b/security/manager/ssl/src/SharedSSLState.cpp @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "SharedSSLState.h" +#include "nsClientAuthRemember.h" +#include "nsComponentManagerUtils.h" +#include "nsICertOverrideService.h" +#include "nsIObserverService.h" +#include "mozilla/Services.h" +#include "nsThreadUtils.h" +#include "nsCRT.h" + +namespace mozilla { +namespace psm { + +namespace { +class PrivateBrowsingObserver : public nsIObserver { +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + PrivateBrowsingObserver(SharedSSLState* aOwner) : mOwner(aOwner) {} + virtual ~PrivateBrowsingObserver() {} +private: + SharedSSLState* mOwner; +}; + +SharedSSLState* gPublicState; +SharedSSLState* gPrivateState; +} // anonymous namespace + +NS_IMPL_ISUPPORTS1(PrivateBrowsingObserver, nsIObserver) + +NS_IMETHODIMP +PrivateBrowsingObserver::Observe(nsISupports *aSubject, + const char *aTopic, + const PRUnichar *aData) +{ + if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { + mOwner->ResetStoredData(); + } + return NS_OK; +} + +SharedSSLState::SharedSSLState() +: mClientAuthRemember(new nsClientAuthRememberService) +{ + mIOLayerHelpers.Init(); + mClientAuthRemember->Init(); +} + +void +SharedSSLState::NotePrivateBrowsingStatus() +{ + mObserver = new PrivateBrowsingObserver(this); + nsCOMPtr obsSvc = mozilla::services::GetObserverService(); + obsSvc->AddObserver(mObserver, "last-pb-context-exited", false); +} + +void +SharedSSLState::ResetStoredData() +{ + mClientAuthRemember->ClearRememberedDecisions(); + mIOLayerHelpers.clearStoredData(); +} + +/*static*/ void +SharedSSLState::GlobalInit() +{ + MOZ_ASSERT(NS_IsMainThread(), "Not on main thread"); + gPublicState = new SharedSSLState(); + gPrivateState = new SharedSSLState(); + gPrivateState->NotePrivateBrowsingStatus(); +} + +/*static*/ void +SharedSSLState::GlobalCleanup() +{ + MOZ_ASSERT(NS_IsMainThread(), "Not on main thread"); + + gPrivateState->Cleanup(); + delete gPrivateState; + gPrivateState = nullptr; + + gPublicState->Cleanup(); + delete gPublicState; + gPublicState = nullptr; +} + +void +SharedSSLState::Cleanup() +{ + mIOLayerHelpers.Cleanup(); +} + +SharedSSLState* +PublicSSLState() +{ + return gPublicState; +} + +SharedSSLState* +PrivateSSLState() +{ + return gPrivateState; +} + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/src/SharedSSLState.h b/security/manager/ssl/src/SharedSSLState.h new file mode 100644 index 000000000000..7a89fbca243b --- /dev/null +++ b/security/manager/ssl/src/SharedSSLState.h @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef SharedSSLState_h +#define SharedSSLState_h + +#include "mozilla/RefPtr.h" +#include "nsNSSIOLayer.h" + +class nsClientAuthRememberService; +class nsIRecentBadCertsService; +class nsICertOverrideService; +class nsIObserver; + +namespace mozilla { +namespace psm { + +class SharedSSLState { +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedSSLState) + SharedSSLState(); + + static void GlobalInit(); + static void GlobalCleanup(); + + nsClientAuthRememberService* GetClientAuthRememberService() { + return mClientAuthRemember; + } + + nsSSLIOLayerHelpers& IOLayerHelpers() { + return mIOLayerHelpers; + } + + void ResetStoredData(); + void NotePrivateBrowsingStatus(); + +private: + void Cleanup(); + + nsCOMPtr mObserver; + RefPtr mClientAuthRemember; + nsSSLIOLayerHelpers mIOLayerHelpers; +}; + +SharedSSLState* PublicSSLState(); +SharedSSLState* PrivateSSLState(); + +} // namespace psm +} // namespace mozilla + +#endif diff --git a/security/manager/ssl/src/nsClientAuthRemember.cpp b/security/manager/ssl/src/nsClientAuthRemember.cpp index b3ac013b4e26..ad595810da3a 100644 --- a/security/manager/ssl/src/nsClientAuthRemember.cpp +++ b/security/manager/ssl/src/nsClientAuthRemember.cpp @@ -21,8 +21,10 @@ #include "pk11pub.h" #include "certdb.h" #include "sechash.h" +#include "SharedSSLState.h" using namespace mozilla; +using namespace mozilla::psm; NS_IMPL_THREADSAFE_ISUPPORTS2(nsClientAuthRememberService, nsIObserver, @@ -80,6 +82,16 @@ void nsClientAuthRememberService::ClearRememberedDecisions() RemoveAllFromMemory(); } +void nsClientAuthRememberService::ClearAllRememberedDecisions() +{ + RefPtr svc = + PublicSSLState()->GetClientAuthRememberService(); + svc->ClearRememberedDecisions(); + + svc = PrivateSSLState()->GetClientAuthRememberService(); + svc->ClearRememberedDecisions(); +} + void nsClientAuthRememberService::RemoveAllFromMemory() { diff --git a/security/manager/ssl/src/nsClientAuthRemember.h b/security/manager/ssl/src/nsClientAuthRemember.h index 35a8a21b47a5..161303f07576 100644 --- a/security/manager/ssl/src/nsClientAuthRemember.h +++ b/security/manager/ssl/src/nsClientAuthRemember.h @@ -128,6 +128,7 @@ public: nsACString & aCertDBKey, bool *_retval); void ClearRememberedDecisions(); + static void ClearAllRememberedDecisions(); protected: mozilla::ReentrantMonitor monitor; diff --git a/security/manager/ssl/src/nsNSSCallbacks.cpp b/security/manager/ssl/src/nsNSSCallbacks.cpp index d7809989c7a6..02188b78493d 100644 --- a/security/manager/ssl/src/nsNSSCallbacks.cpp +++ b/security/manager/ssl/src/nsNSSCallbacks.cpp @@ -23,6 +23,7 @@ #include "nsIConsoleService.h" #include "nsIHttpChannelInternal.h" #include "nsCRT.h" +#include "SharedSSLState.h" #include "ssl.h" #include "sslproto.h" @@ -841,7 +842,8 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { // If the handshake completed, then we know the site is TLS tolerant (if this // was a TLS connection). - nsSSLIOLayerHelpers::rememberTolerantSite(infoObject); + nsSSLIOLayerHelpers& ioLayerHelpers = infoObject->SharedState().IOLayerHelpers(); + ioLayerHelpers.rememberTolerantSite(infoObject); if (SECSuccess != SSL_SecurityStatus(fd, &sslStatus, &cipherName, &keyLength, &encryptBits, &signer, nullptr)) { @@ -859,7 +861,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { if (SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn, &siteSupportsSafeRenego) != SECSuccess || !siteSupportsSafeRenego) { - bool wantWarning = (nsSSLIOLayerHelpers::getWarnLevelMissingRFC5746() > 0); + bool wantWarning = (ioLayerHelpers.getWarnLevelMissingRFC5746() > 0); nsCOMPtr console; if (infoObject && wantWarning) { @@ -875,7 +877,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { console->LogStringMessage(msg.get()); } } - if (nsSSLIOLayerHelpers::treatUnsafeNegotiationAsBroken()) { + if (ioLayerHelpers.treatUnsafeNegotiationAsBroken()) { secStatus = nsIWebProgressListener::STATE_IS_BROKEN; } } diff --git a/security/manager/ssl/src/nsNSSCertificateDB.cpp b/security/manager/ssl/src/nsNSSCertificateDB.cpp index 912ced9a8d68..b3314216a320 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.cpp +++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp @@ -31,6 +31,8 @@ #include "nsIPrompt.h" #include "nsThreadUtils.h" #include "ScopedNSSTypes.h" +#include "nsIObserverService.h" +#include "nsRecentBadCerts.h" #include "nspr.h" #include "certdb.h" @@ -1644,3 +1646,22 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval) NS_ADDREF(*_retval); return NS_OK; } + +NS_IMETHODIMP +nsNSSCertificateDB::GetRecentBadCerts(bool isPrivate, nsIRecentBadCerts** result) +{ + MOZ_ASSERT(NS_IsMainThread(), "RecentBadCerts should only be obtained on the main thread"); + if (isPrivate) { + if (!mPrivateRecentBadCerts) { + mPrivateRecentBadCerts = new nsRecentBadCerts; + mPrivateRecentBadCerts->InitPrivateBrowsingObserver(); + } + NS_ADDREF(*result = mPrivateRecentBadCerts); + } else { + if (!mPublicRecentBadCerts) { + mPublicRecentBadCerts = new nsRecentBadCerts; + } + NS_ADDREF(*result = mPublicRecentBadCerts); + } + return NS_OK; +} diff --git a/security/manager/ssl/src/nsNSSCertificateDB.h b/security/manager/ssl/src/nsNSSCertificateDB.h index efdbff80d339..c821322fbcb4 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.h +++ b/security/manager/ssl/src/nsNSSCertificateDB.h @@ -7,10 +7,12 @@ #include "nsIX509CertDB.h" #include "nsIX509CertDB2.h" +#include "mozilla/RefPtr.h" #include "certt.h" class nsCString; class nsIArray; +class nsRecentBadCerts; class nsNSSCertificateDB : public nsIX509CertDB, public nsIX509CertDB2 { @@ -48,6 +50,9 @@ private: uint32_t length); nsresult handleCACertDownload(nsIArray *x509Certs, nsIInterfaceRequestor *ctx); + + mozilla::RefPtr mPublicRecentBadCerts; + mozilla::RefPtr mPrivateRecentBadCerts; }; #define NS_X509CERTDB_CID { /* fb0bbc5c-452e-4783-b32c-80124693d871 */ \ diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index 486a3e1f907b..aabe6fab9789 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -60,6 +60,7 @@ #include "nsSmartCardEvent.h" #include "nsIKeyModule.h" #include "ScopedNSSTypes.h" +#include "SharedSSLState.h" #include "nss.h" #include "pk11func.h" @@ -400,7 +401,7 @@ nsNSSComponent::~nsNSSComponent() // All cleanup code requiring services needs to happen in xpcom_shutdown ShutdownNSS(); - nsSSLIOLayerHelpers::Cleanup(); + SharedSSLState::GlobalCleanup(); RememberCertErrorsTable::Cleanup(); --mInstanceCount; delete mShutdownObjectList; @@ -1860,9 +1861,6 @@ nsNSSComponent::ShutdownNSS() ShutdownSmartCardThreads(); SSL_ClearSessionCache(); - if (mClientAuthRememberService) { - mClientAuthRememberService->ClearRememberedDecisions(); - } UnloadLoadableRoots(); CleanupIdentityInfo(); PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("evaporating psm resources\n")); @@ -1933,27 +1931,8 @@ nsNSSComponent::Init() } RememberCertErrorsTable::Init(); - nsSSLIOLayerHelpers::Init(); - char *unrestricted_hosts=nullptr; - mPrefBranch->GetCharPref("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts); - if (unrestricted_hosts) { - nsSSLIOLayerHelpers::setRenegoUnrestrictedSites(nsDependentCString(unrestricted_hosts)); - nsMemory::Free(unrestricted_hosts); - unrestricted_hosts=nullptr; - } - - bool enabled = false; - mPrefBranch->GetBoolPref("security.ssl.treat_unsafe_negotiation_as_broken", &enabled); - nsSSLIOLayerHelpers::setTreatUnsafeNegotiationAsBroken(enabled); - - int32_t warnLevel = 1; - mPrefBranch->GetIntPref("security.ssl.warn_missing_rfc5746", &warnLevel); - nsSSLIOLayerHelpers::setWarnLevelMissingRFC5746(warnLevel); + SharedSSLState::GlobalInit(); - mClientAuthRememberService = new nsClientAuthRememberService; - if (mClientAuthRememberService) - mClientAuthRememberService->Init(); - createBackgroundThreads(); if (!mCertVerificationThread) { @@ -2271,20 +2250,6 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, 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=nullptr; - 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.ssl.warn_missing_rfc5746")) { - int32_t warnLevel = 1; - mPrefBranch->GetIntPref("security.ssl.warn_missing_rfc5746", &warnLevel); - nsSSLIOLayerHelpers::setWarnLevelMissingRFC5746(warnLevel); #ifdef SSL_ENABLE_FALSE_START // Requires NSS 3.12.8 } else if (prefName.Equals("security.ssl.enable_false_start")) { mPrefBranch->GetBoolPref("security.ssl.enable_false_start", &enabled); @@ -2387,9 +2352,7 @@ nsresult nsNSSComponent::LogoutAuthenticatedPK11() 0); } - if (mClientAuthRememberService) { - mClientAuthRememberService->ClearRememberedDecisions(); - } + nsClientAuthRememberService::ClearAllRememberedDecisions(); return mShutdownObjectList->doPK11Logout(); } @@ -2568,14 +2531,6 @@ nsNSSComponent::DoProfileChangeNetRestore() mIsNetworkDown = false; } -NS_IMETHODIMP -nsNSSComponent::GetClientAuthRememberService(nsClientAuthRememberService **cars) -{ - NS_ENSURE_ARG_POINTER(cars); - NS_IF_ADDREF(*cars = mClientAuthRememberService); - return NS_OK; -} - NS_IMETHODIMP nsNSSComponent::IsNSSInitialized(bool *initialized) { diff --git a/security/manager/ssl/src/nsNSSComponent.h b/security/manager/ssl/src/nsNSSComponent.h index 2391d95565d2..b47b989c21f5 100644 --- a/security/manager/ssl/src/nsNSSComponent.h +++ b/security/manager/ssl/src/nsNSSComponent.h @@ -154,8 +154,6 @@ class NS_NO_VTABLE nsINSSComponent : public nsISupports { NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token) = 0; - NS_IMETHOD GetClientAuthRememberService(nsClientAuthRememberService **cars) = 0; - NS_IMETHOD EnsureIdentityInfoLoaded() = 0; NS_IMETHOD IsNSSInitialized(bool *initialized) = 0; @@ -259,7 +257,6 @@ public: NS_IMETHOD ShutdownSmartCardThread(SECMODModule *module); NS_IMETHOD PostEvent(const nsAString &eventType, const nsAString &token); NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token); - NS_IMETHOD GetClientAuthRememberService(nsClientAuthRememberService **cars); NS_IMETHOD EnsureIdentityInfoLoaded(); NS_IMETHOD IsNSSInitialized(bool *initialized); @@ -327,7 +324,6 @@ private: nsCertVerificationThread *mCertVerificationThread; nsNSSHttpInterface mHttpForNSS; - mozilla::RefPtr mClientAuthRememberService; mozilla::RefPtr mDefaultCERTValInParam; mozilla::RefPtr mDefaultCERTValInParamLocalOnly; diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index 7f52d25af224..8e84c9647b2b 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -28,6 +28,8 @@ #include "nsIConsoleService.h" #include "PSMRunnable.h" #include "ScopedNSSTypes.h" +#include "SharedSSLState.h" +#include "mozilla/Preferences.h" #include "ssl.h" #include "secerr.h" @@ -63,9 +65,10 @@ typedef enum {ASK, AUTO} SSM_UserCertChoice; extern PRLogModuleInfo* gPIPNSSLog; #endif -nsNSSSocketInfo::nsNSSSocketInfo(uint32_t providerFlags) +nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags) : mFd(nullptr), mCertVerificationState(before_cert_verification), + mSharedState(aState), mForSTARTTLS(false), mSSL3Enabled(false), mTLSEnabled(false), @@ -457,6 +460,11 @@ void nsNSSSocketInfo::SetAllowTLSIntoleranceTimeout(bool aAllow) mAllowTLSIntoleranceTimeout = aAllow; } +SharedSSLState& nsNSSSocketInfo::SharedState() +{ + return mSharedState; +} + bool nsNSSSocketInfo::HandshakeTimeout() { if (!mAllowTLSIntoleranceTimeout) @@ -914,7 +922,8 @@ int32_t checkHandshake(int32_t bytesTransfered, bool wasReading, if (!wantRetry // no decision yet && isTLSIntoleranceError(err, socketInfo->GetHasCleartextPhase())) { - wantRetry = nsSSLIOLayerHelpers::rememberPossibleTLSProblemSite(socketInfo); + nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers(); + wantRetry = helpers.rememberPossibleTLSProblemSite(socketInfo); } } @@ -942,8 +951,8 @@ int32_t checkHandshake(int32_t bytesTransfered, bool wasReading, if (!wantRetry // no decision yet && !socketInfo->GetHasCleartextPhase()) // mirror PR_CONNECT_RESET_ERROR treament { - wantRetry = - nsSSLIOLayerHelpers::rememberPossibleTLSProblemSite(socketInfo); + nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers(); + wantRetry = helpers.rememberPossibleTLSProblemSite(socketInfo); } } } @@ -1031,12 +1040,16 @@ nsSSLIOLayerPoll(PRFileDesc * fd, int16_t in_flags, int16_t *out_flags) bool nsSSLIOLayerHelpers::nsSSLIOLayerInitialized = false; PRDescIdentity nsSSLIOLayerHelpers::nsSSLIOLayerIdentity; PRIOMethods nsSSLIOLayerHelpers::nsSSLIOLayerMethods; -Mutex *nsSSLIOLayerHelpers::mutex = nullptr; -nsTHashtable *nsSSLIOLayerHelpers::mTLSIntolerantSites = nullptr; -nsTHashtable *nsSSLIOLayerHelpers::mTLSTolerantSites = nullptr; -nsTHashtable *nsSSLIOLayerHelpers::mRenegoUnrestrictedSites = nullptr; -bool nsSSLIOLayerHelpers::mTreatUnsafeNegotiationAsBroken = false; -int32_t nsSSLIOLayerHelpers::mWarnLevelMissingRFC5746 = 1; + +nsSSLIOLayerHelpers::nsSSLIOLayerHelpers() +: mutex(nullptr) +, mTLSIntolerantSites(nullptr) +, mTLSTolerantSites(nullptr) +, mRenegoUnrestrictedSites(nullptr) +, mTreatUnsafeNegotiationAsBroken(false) +, mWarnLevelMissingRFC5746(1) +{ +} static int _PSM_InvalidInt(void) { @@ -1190,6 +1203,53 @@ static int64_t PSMAvailable64(void) return -1; } +namespace { +class PrefObserver : public nsIObserver { +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + PrefObserver(nsSSLIOLayerHelpers* aOwner) : mOwner(aOwner) {} + virtual ~PrefObserver() {} +private: + nsSSLIOLayerHelpers* mOwner; +}; +} // namespace anonymous + +NS_IMPL_THREADSAFE_ISUPPORTS1(PrefObserver, nsIObserver) + +NS_IMETHODIMP +PrefObserver::Observe(nsISupports *aSubject, const char *aTopic, + const PRUnichar *someData) +{ + if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) { + NS_ConvertUTF16toUTF8 prefName(someData); + + if (prefName.Equals("security.ssl.renego_unrestricted_hosts")) { + nsCString unrestricted_hosts; + Preferences::GetCString("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts); + if (!unrestricted_hosts.IsEmpty()) { + mOwner->setRenegoUnrestrictedSites(unrestricted_hosts); + } + } else if (prefName.Equals("security.ssl.treat_unsafe_negotiation_as_broken")) { + bool enabled; + Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", &enabled); + mOwner->setTreatUnsafeNegotiationAsBroken(enabled); + } else if (prefName.Equals("security.ssl.warn_missing_rfc5746")) { + int32_t warnLevel = 1; + Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel); + mOwner->setWarnLevelMissingRFC5746(warnLevel); + } + } + return NS_OK; +} + +nsSSLIOLayerHelpers::~nsSSLIOLayerHelpers() +{ + Preferences::RemoveObserver(mPrefObserver, "security.ssl.renego_unrestricted_hosts"); + Preferences::RemoveObserver(mPrefObserver, "security.ssl.treat_unsafe_negotiation_as_broken"); + Preferences::RemoveObserver(mPrefObserver, "security.ssl.warn_missing_rfc5746"); +} + nsresult nsSSLIOLayerHelpers::Init() { if (!nsSSLIOLayerInitialized) { @@ -1244,23 +1304,50 @@ nsresult nsSSLIOLayerHelpers::Init() mRenegoUnrestrictedSites = new nsTHashtable(); mRenegoUnrestrictedSites->Init(1); - mTreatUnsafeNegotiationAsBroken = false; - + nsCString unrestricted_hosts; + Preferences::GetCString("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts); + if (!unrestricted_hosts.IsEmpty()) { + setRenegoUnrestrictedSites(unrestricted_hosts); + } + + bool enabled = false; + Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", &enabled); + setTreatUnsafeNegotiationAsBroken(enabled); + + int32_t warnLevel = 1; + Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel); + setWarnLevelMissingRFC5746(warnLevel); + + mPrefObserver = new PrefObserver(this); + Preferences::AddStrongObserver(mPrefObserver, + "security.ssl.renego_unrestricted_hosts"); + Preferences::AddStrongObserver(mPrefObserver, + "security.ssl.treat_unsafe_negotiation_as_broken"); + Preferences::AddStrongObserver(mPrefObserver, + "security.ssl.warn_missing_rfc5746"); + return NS_OK; } +void nsSSLIOLayerHelpers::clearStoredData() +{ + mRenegoUnrestrictedSites->Clear(); + mTLSTolerantSites->Clear(); + mTLSIntolerantSites->Clear(); +} + void nsSSLIOLayerHelpers::addIntolerantSite(const nsCString &str) { MutexAutoLock lock(*mutex); // Remember intolerant site only if it is not known as tolerant if (!mTLSTolerantSites->Contains(str)) - nsSSLIOLayerHelpers::mTLSIntolerantSites->PutEntry(str); + mTLSIntolerantSites->PutEntry(str); } void nsSSLIOLayerHelpers::removeIntolerantSite(const nsCString &str) { MutexAutoLock lock(*mutex); - nsSSLIOLayerHelpers::mTLSIntolerantSites->RemoveEntry(str); + mTLSIntolerantSites->RemoveEntry(str); } bool nsSSLIOLayerHelpers::isKnownAsIntolerantSite(const nsCString &str) @@ -1923,6 +2010,7 @@ void ClientAuthDataRunnable::RunOnTargetThread() SSM_UserCertChoice certChoice; int32_t NumberOfCerts = 0; void * wincx = mSocketInfo; + nsresult rv; /* create caNameStrings */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); @@ -2024,19 +2112,14 @@ void ClientAuthDataRunnable::RunOnTargetThread() nsXPIDLCString hostname; mSocketInfo->GetHostName(getter_Copies(hostname)); - nsresult rv; - NS_DEFINE_CID(nssComponentCID, NS_NSSCOMPONENT_CID); - nsCOMPtr nssComponent(do_GetService(nssComponentCID, &rv)); - RefPtr cars; - if (nssComponent) { - nssComponent->GetClientAuthRememberService(byRef(cars)); - } + RefPtr cars = + mSocketInfo->SharedState().GetClientAuthRememberService(); bool hasRemembered = false; nsCString rememberedDBKey; if (cars) { bool found; - nsresult rv = cars->HasRememberedDecision(hostname, mServerCert, + rv = cars->HasRememberedDecision(hostname, mServerCert, rememberedDBKey, &found); if (NS_SUCCEEDED(rv) && found) { hasRemembered = true; @@ -2219,9 +2302,9 @@ if (!hasRemembered) } /* Throw up the client auth dialog and get back the index of the selected cert */ - rv = getNSSDialogs((void**)&dialogs, - NS_GET_IID(nsIClientAuthDialogs), - NS_CLIENTAUTHDIALOGS_CONTRACTID); + nsresult rv = getNSSDialogs((void**)&dialogs, + NS_GET_IID(nsIClientAuthDialogs), + NS_CLIENTAUTHDIALOGS_CONTRACTID); if (NS_FAILED(rv)) { NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList); @@ -2380,7 +2463,7 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, nsAutoCString key; key = nsDependentCString(host) + NS_LITERAL_CSTRING(":") + nsPrintfCString("%d", port); - if (nsSSLIOLayerHelpers::isKnownAsIntolerantSite(key)) { + if (infoObject->SharedState().IOLayerHelpers().isKnownAsIntolerantSite(key)) { if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_TLS, false)) return NS_ERROR_FAILURE; @@ -2407,8 +2490,9 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, if (SECSuccess != SSL_OptionSet(fd, SSL_HANDSHAKE_AS_CLIENT, true)) { return NS_ERROR_FAILURE; } - - if (nsSSLIOLayerHelpers::isRenegoUnrestrictedSite(nsDependentCString(host))) { + + nsSSLIOLayerHelpers& ioHelpers = infoObject->SharedState().IOLayerHelpers(); + if (ioHelpers.isRenegoUnrestrictedSite(nsDependentCString(host))) { if (SECSuccess != SSL_OptionSet(fd, SSL_REQUIRE_SAFE_NEGOTIATION, false)) { return NS_ERROR_FAILURE; } @@ -2450,7 +2534,9 @@ nsSSLIOLayerAddToSocket(int32_t family, nsresult rv; PRStatus stat; - nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(providerFlags); + SharedSSLState* sharedState = + providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE ? PrivateSSLState() : PublicSSLState(); + nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(*sharedState, providerFlags); if (!infoObject) return NS_ERROR_FAILURE; NS_ADDREF(infoObject); diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h index 4ee3bd9b8aac..2f25e71d04c8 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.h +++ b/security/manager/ssl/src/nsNSSIOLayer.h @@ -15,12 +15,20 @@ #include "nsTHashtable.h" #include "mozilla/TimeStamp.h" +namespace mozilla { +namespace psm { +class SharedSSLState; +} +} + +class nsIObserver; + class nsNSSSocketInfo : public mozilla::psm::TransportSecurityInfo, public nsISSLSocketControl, public nsIClientAuthUserDecision { public: - nsNSSSocketInfo(uint32_t providerFlags); + nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags); NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSISSLSOCKETCONTROL @@ -56,6 +64,8 @@ public: bool GetJoined() { return mJoined; } void SetSentClientCert() { mSentClientCert = true; } + mozilla::psm::SharedSSLState& SharedState(); + // XXX: These are only used on for diagnostic purposes enum CertVerificationState { before_cert_verification, @@ -83,6 +93,7 @@ private: CertVerificationState mCertVerificationState; + mozilla::psm::SharedSSLState& mSharedState; bool mForSTARTTLS; bool mSSL3Enabled; bool mTLSEnabled; @@ -109,37 +120,44 @@ private: class nsSSLIOLayerHelpers { public: - static nsresult Init(); - static void Cleanup(); + nsSSLIOLayerHelpers(); + ~nsSSLIOLayerHelpers(); + + nsresult Init(); + void Cleanup(); static bool nsSSLIOLayerInitialized; static PRDescIdentity nsSSLIOLayerIdentity; static PRIOMethods nsSSLIOLayerMethods; - static mozilla::Mutex *mutex; - static nsTHashtable *mTLSIntolerantSites; - static nsTHashtable *mTLSTolerantSites; + mozilla::Mutex *mutex; + nsTHashtable *mTLSIntolerantSites; + nsTHashtable *mTLSTolerantSites; - static nsTHashtable *mRenegoUnrestrictedSites; - static bool mTreatUnsafeNegotiationAsBroken; - static int32_t mWarnLevelMissingRFC5746; + nsTHashtable *mRenegoUnrestrictedSites; + bool mTreatUnsafeNegotiationAsBroken; + int32_t mWarnLevelMissingRFC5746; - static void setTreatUnsafeNegotiationAsBroken(bool broken); - static bool treatUnsafeNegotiationAsBroken(); + void setTreatUnsafeNegotiationAsBroken(bool broken); + bool treatUnsafeNegotiationAsBroken(); - static void setWarnLevelMissingRFC5746(int32_t level); - static int32_t getWarnLevelMissingRFC5746(); + void setWarnLevelMissingRFC5746(int32_t level); + int32_t getWarnLevelMissingRFC5746(); static void getSiteKey(nsNSSSocketInfo *socketInfo, nsCSubstring &key); - static bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo); - static void rememberTolerantSite(nsNSSSocketInfo *socketInfo); + bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo); + void rememberTolerantSite(nsNSSSocketInfo *socketInfo); - static void addIntolerantSite(const nsCString &str); - static void removeIntolerantSite(const nsCString &str); - static bool isKnownAsIntolerantSite(const nsCString &str); + void addIntolerantSite(const nsCString &str); + void removeIntolerantSite(const nsCString &str); + bool isKnownAsIntolerantSite(const nsCString &str); - static void setRenegoUnrestrictedSites(const nsCString &str); - static bool isRenegoUnrestrictedSite(const nsCString &str); + void setRenegoUnrestrictedSites(const nsCString &str); + bool isRenegoUnrestrictedSite(const nsCString &str); + + void clearStoredData(); +private: + nsCOMPtr mPrefObserver; }; nsresult nsSSLIOLayerNewSocket(int32_t family, diff --git a/security/manager/ssl/src/nsNSSModule.cpp b/security/manager/ssl/src/nsNSSModule.cpp index 90debb592819..568c2be52ae5 100644 --- a/security/manager/ssl/src/nsNSSModule.cpp +++ b/security/manager/ssl/src/nsNSSModule.cpp @@ -38,7 +38,6 @@ #include "nsDataSignatureVerifier.h" #include "nsCertOverrideService.h" #include "nsRandomGenerator.h" -#include "nsRecentBadCerts.h" #include "nsSSLStatus.h" #include "TransportSecurityInfo.h" #include "NSSErrorsService.h" @@ -204,7 +203,6 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsKeyObjectFactory) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsDataSignatureVerifier) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsCertOverrideService, Init) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsRandomGenerator) -NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsRecentBadCertsService, Init) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, nsSSLStatus) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, TransportSecurityInfo) @@ -243,7 +241,6 @@ NS_DEFINE_NAMED_CID(NS_KEYMODULEOBJECTFACTORY_CID); NS_DEFINE_NAMED_CID(NS_DATASIGNATUREVERIFIER_CID); NS_DEFINE_NAMED_CID(NS_CERTOVERRIDE_CID); NS_DEFINE_NAMED_CID(NS_RANDOMGENERATOR_CID); -NS_DEFINE_NAMED_CID(NS_RECENTBADCERTS_CID); NS_DEFINE_NAMED_CID(NS_SSLSTATUS_CID); NS_DEFINE_NAMED_CID(TRANSPORTSECURITYINFO_CID); NS_DEFINE_NAMED_CID(NS_NSSERRORSSERVICE_CID); @@ -281,7 +278,6 @@ static const mozilla::Module::CIDEntry kNSSCIDs[] = { { &kNS_DATASIGNATUREVERIFIER_CID, false, nullptr, nsDataSignatureVerifierConstructor }, { &kNS_CERTOVERRIDE_CID, false, nullptr, nsCertOverrideServiceConstructor }, { &kNS_RANDOMGENERATOR_CID, false, nullptr, nsRandomGeneratorConstructor }, - { &kNS_RECENTBADCERTS_CID, false, nullptr, nsRecentBadCertsServiceConstructor }, { &kNS_SSLSTATUS_CID, false, nullptr, nsSSLStatusConstructor }, { &kTRANSPORTSECURITYINFO_CID, false, nullptr, TransportSecurityInfoConstructor }, { &kNS_NSSERRORSSERVICE_CID, false, nullptr, NSSErrorsServiceConstructor }, @@ -324,7 +320,6 @@ static const mozilla::Module::ContractIDEntry kNSSContracts[] = { { NS_DATASIGNATUREVERIFIER_CONTRACTID, &kNS_DATASIGNATUREVERIFIER_CID }, { NS_CERTOVERRIDE_CONTRACTID, &kNS_CERTOVERRIDE_CID }, { NS_RANDOMGENERATOR_CONTRACTID, &kNS_RANDOMGENERATOR_CID }, - { NS_RECENTBADCERTS_CONTRACTID, &kNS_RECENTBADCERTS_CID }, { nullptr } }; diff --git a/security/manager/ssl/src/nsRecentBadCerts.cpp b/security/manager/ssl/src/nsRecentBadCerts.cpp index de378b9e9bb5..cae4fd1fb61c 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.cpp +++ b/security/manager/ssl/src/nsRecentBadCerts.cpp @@ -6,7 +6,9 @@ #include "nsRecentBadCerts.h" #include "nsIX509Cert.h" +#include "nsIObserverService.h" #include "mozilla/RefPtr.h" +#include "mozilla/Services.h" #include "nsSSLStatus.h" #include "nsCOMPtr.h" #include "nsNSSCertificate.h" @@ -20,28 +22,41 @@ using namespace mozilla; -NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCertsService, - nsIRecentBadCertsService) +NS_IMPL_THREADSAFE_ISUPPORTS2(nsRecentBadCerts, + nsIRecentBadCerts, + nsIObserver) -nsRecentBadCertsService::nsRecentBadCertsService() -:monitor("nsRecentBadCertsService.monitor") +nsRecentBadCerts::nsRecentBadCerts() +:monitor("nsRecentBadCerts.monitor") ,mNextStorePosition(0) { } -nsRecentBadCertsService::~nsRecentBadCertsService() +nsRecentBadCerts::~nsRecentBadCerts() { } -nsresult -nsRecentBadCertsService::Init() +void +nsRecentBadCerts::InitPrivateBrowsingObserver() { + nsCOMPtr obsSvc = mozilla::services::GetObserverService(); + obsSvc->AddObserver(this, "last-pb-context-exited", false); +} + +NS_IMETHODIMP +nsRecentBadCerts::Observe(nsISupports *aSubject, + const char *aTopic, + const PRUnichar *aData) +{ + if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { + ResetStoredCerts(); + } return NS_OK; } NS_IMETHODIMP -nsRecentBadCertsService::GetRecentBadCert(const nsAString & aHostNameWithPort, - nsISSLStatus **aStatus) +nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort, + nsISSLStatus **aStatus) { NS_ENSURE_ARG_POINTER(aStatus); if (!aHostNameWithPort.Length()) @@ -101,7 +116,7 @@ nsRecentBadCertsService::GetRecentBadCert(const nsAString & aHostNameWithPort, } NS_IMETHODIMP -nsRecentBadCertsService::AddBadCert(const nsAString &hostWithPort, +nsRecentBadCerts::AddBadCert(const nsAString &hostWithPort, nsISSLStatus *aStatus) { NS_ENSURE_ARG(aStatus); @@ -146,3 +161,13 @@ nsRecentBadCertsService::AddBadCert(const nsAString &hostWithPort, return NS_OK; } + +NS_IMETHODIMP +nsRecentBadCerts::ResetStoredCerts() +{ + for (size_t i = 0; i < const_recently_seen_list_size; ++i) { + RecentBadCert &entry = mCerts[i]; + entry.Clear(); + } + return NS_OK; +} diff --git a/security/manager/ssl/src/nsRecentBadCerts.h b/security/manager/ssl/src/nsRecentBadCerts.h index e82f780c252a..d815482d3794 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.h +++ b/security/manager/ssl/src/nsRecentBadCerts.h @@ -11,6 +11,7 @@ #include "mozilla/ReentrantMonitor.h" #include "nsIRecentBadCertsService.h" +#include "nsIObserver.h" #include "nsTHashtable.h" #include "nsString.h" #include "cert.h" @@ -54,16 +55,18 @@ private: RecentBadCert &operator=(const RecentBadCert &other) MOZ_DELETE; }; -class nsRecentBadCertsService MOZ_FINAL : public nsIRecentBadCertsService +class nsRecentBadCerts MOZ_FINAL : public nsIRecentBadCerts + , public nsIObserver { public: NS_DECL_ISUPPORTS - NS_DECL_NSIRECENTBADCERTSSERVICE + NS_DECL_NSIRECENTBADCERTS + NS_DECL_NSIOBSERVER - nsRecentBadCertsService(); - ~nsRecentBadCertsService(); + nsRecentBadCerts(); + ~nsRecentBadCerts(); - nsresult Init(); + void InitPrivateBrowsingObserver(); protected: mozilla::ReentrantMonitor monitor; From 765b806377a49ec9d1d6ce90c78cbe080b917c93 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:09:48 -0500 Subject: [PATCH 04/35] Bug 769288 - Part 2: Avoid storing intermediate cert data for private contexts. r=bsmith sr=mayhemer --- .../ssl/src/SSLServerCertVerification.cpp | 65 ++++++++++--------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/security/manager/ssl/src/SSLServerCertVerification.cpp b/security/manager/ssl/src/SSLServerCertVerification.cpp index 6bac3a3abfc6..c03f003b30e3 100644 --- a/security/manager/ssl/src/SSLServerCertVerification.cpp +++ b/security/manager/ssl/src/SSLServerCertVerification.cpp @@ -835,7 +835,8 @@ BlockServerCertChangeForSpdy(nsNSSSocketInfo *infoObject, } SECStatus -AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert) +AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert, + uint32_t providerFlags) { if (cert->serialNumber.data && cert->issuerName && @@ -921,37 +922,41 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert) } nsCOMPtr nssComponent; - - for (CERTCertListNode *node = CERT_LIST_HEAD(certList); - !CERT_LIST_END(node, certList); - node = CERT_LIST_NEXT(node)) { - if (node->cert->slot) { - // This cert was found on a token, no need to remember it in the temp db. - continue; - } + // We want to avoid storing any intermediate cert information when browsing + // in private, transient contexts. + if (!(providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE)) { + for (CERTCertListNode *node = CERT_LIST_HEAD(certList); + !CERT_LIST_END(node, certList); + node = CERT_LIST_NEXT(node)) { - if (node->cert->isperm) { - // We don't need to remember certs already stored in perm db. - continue; - } - - if (node->cert == cert) { - // We don't want to remember the server cert, - // the code that cares for displaying page info does this already. - continue; - } - - // We have found a signer cert that we want to remember. - char* nickname = nsNSSCertificate::defaultServerNickname(node->cert); - if (nickname && *nickname) { - ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); - if (slot) { - PK11_ImportCert(slot, node->cert, CK_INVALID_HANDLE, - nickname, false); + if (node->cert->slot) { + // This cert was found on a token, no need to remember it in the temp db. + continue; } + + if (node->cert->isperm) { + // We don't need to remember certs already stored in perm db. + continue; + } + + if (node->cert == cert) { + // We don't want to remember the server cert, + // the code that cares for displaying page info does this already. + continue; + } + + // We have found a signer cert that we want to remember. + char* nickname = nsNSSCertificate::defaultServerNickname(node->cert); + if (nickname && *nickname) { + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (slot) { + PK11_ImportCert(slot, node->cert, CK_INVALID_HANDLE, + nickname, false); + } + } + PR_FREEIF(nickname); } - PR_FREEIF(nickname); } // The connection may get terminated, for example, if the server requires @@ -1043,7 +1048,7 @@ SSLServerCertVerificationJob::Run() // Reset the error code here so we can detect if AuthCertificate fails to // set the error code if/when it fails. PR_SetError(0, 0); - SECStatus rv = AuthCertificate(mInfoObject, mCert); + SECStatus rv = AuthCertificate(mInfoObject, mCert, mProviderFlags); if (rv == SECSuccess) { RefPtr restart( new SSLServerCertVerificationResult(mInfoObject, 0)); @@ -1168,7 +1173,7 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) // thread doing the network I/O may not interrupt its network I/O on receipt // of our SSLServerCertVerificationResult event, and/or it might not even be // a non-blocking socket. - SECStatus rv = AuthCertificate(socketInfo, serverCert); + SECStatus rv = AuthCertificate(socketInfo, serverCert, providerFlags); if (rv == SECSuccess) { return SECSuccess; } From ef458d3ee12e5d949551f0d2fb0ae2bfe37978ed Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:09:52 -0500 Subject: [PATCH 05/35] Bug 769288 - Part 3: Clear all temporary cert overrides upon leaving private browsing. r=bsmith --- security/manager/ssl/src/nsCertOverrideService.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/security/manager/ssl/src/nsCertOverrideService.cpp b/security/manager/ssl/src/nsCertOverrideService.cpp index 456564bd8b8a..e2db1ce91dee 100644 --- a/security/manager/ssl/src/nsCertOverrideService.cpp +++ b/security/manager/ssl/src/nsCertOverrideService.cpp @@ -124,6 +124,7 @@ nsCertOverrideService::Init() if (observerService) { observerService->AddObserver(this, "profile-before-change", true); observerService->AddObserver(this, "profile-do-change", true); + observerService->AddObserver(this, "last-pb-context-exited", true); // simulate a profile change so we read the current profile's settings file Observe(nullptr, "profile-do-change", nullptr); } @@ -168,6 +169,10 @@ nsCertOverrideService::Observe(nsISupports *, } Read(); + } else if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { + ClearValidityOverride( + NS_LITERAL_CSTRING("all:temporary-certificates"), + 0); } return NS_OK; From 75850352cba1e76cebe47af22c396dbb76d20d18 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:09:59 -0500 Subject: [PATCH 06/35] Bug 769288 - Part 4: Clear SSL session cache upon leaving private browsing. r=bsmith --- security/manager/ssl/src/nsNSSComponent.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index aabe6fab9789..31d21ed90ac3 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -2138,6 +2138,7 @@ nsNSSComponent::RandomUpdate(void *entropy, int32_t bufLen) #define PROFILE_CHANGE_TEARDOWN_VETO_TOPIC "profile-change-teardown-veto" #define PROFILE_BEFORE_CHANGE_TOPIC "profile-before-change" #define PROFILE_DO_CHANGE_TOPIC "profile-do-change" +#define LEAVE_PRIVATE_BROWSING_TOPIC "last-pb-context-exited" NS_IMETHODIMP nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, @@ -2285,6 +2286,9 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network restore topic\n")); DoProfileChangeNetRestore(); } + else if (nsCRT::strcmp(aTopic, LEAVE_PRIVATE_BROWSING_TOPIC) == 0) { + SSL_ClearSessionCache(); + } return NS_OK; } @@ -2384,6 +2388,7 @@ nsNSSComponent::RegisterObservers() observerService->AddObserver(this, PROFILE_DO_CHANGE_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC, false); + observerService->AddObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC, false); } return NS_OK; } @@ -2409,6 +2414,7 @@ nsNSSComponent::DeregisterObservers() observerService->RemoveObserver(this, PROFILE_DO_CHANGE_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC); + observerService->RemoveObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC); } return NS_OK; } From 6a22249635a1de83918112f0482491509234d885 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:11:35 -0500 Subject: [PATCH 07/35] Bug 769288 - Part 5: Close private socket connections when the lsat private browsing instance dies. r=bsmith,mcmanus --- netwerk/base/public/nsASocketHandler.h | 3 ++ netwerk/base/src/nsSocketTransport2.cpp | 1 + .../base/src/nsSocketTransportService2.cpp | 38 +++++++++++++----- netwerk/base/src/nsSocketTransportService2.h | 2 + security/manager/ssl/src/Makefile.in | 6 +++ security/manager/ssl/src/SharedSSLState.cpp | 39 +++++++++++++++++++ security/manager/ssl/src/SharedSSLState.h | 2 - .../manager/ssl/src/nsCertOverrideService.cpp | 5 --- .../manager/ssl/src/nsNSSCertificateDB.cpp | 4 +- security/manager/ssl/src/nsNSSCertificateDB.h | 2 + security/manager/ssl/src/nsNSSComponent.cpp | 6 --- security/manager/ssl/src/nsRecentBadCerts.cpp | 23 +---------- security/manager/ssl/src/nsRecentBadCerts.h | 5 --- 13 files changed, 86 insertions(+), 50 deletions(-) diff --git a/netwerk/base/public/nsASocketHandler.h b/netwerk/base/public/nsASocketHandler.h index 3e2efe95231b..1f18ab1d7617 100644 --- a/netwerk/base/public/nsASocketHandler.h +++ b/netwerk/base/public/nsASocketHandler.h @@ -15,6 +15,7 @@ public: : mCondition(NS_OK) , mPollFlags(0) , mPollTimeout(UINT16_MAX) + , mIsPrivate(false) {} // @@ -42,6 +43,8 @@ public: // uint16_t mPollTimeout; + bool mIsPrivate; + // // called to service a socket // diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp index a348eb59b117..dd7eafc1f41a 100644 --- a/netwerk/base/src/nsSocketTransport2.cpp +++ b/netwerk/base/src/nsSocketTransport2.cpp @@ -2206,6 +2206,7 @@ NS_IMETHODIMP nsSocketTransport::SetConnectionFlags(uint32_t value) { mConnectionFlags = value; + mIsPrivate = value & nsISocketTransport::NO_PERMANENT_STORAGE; return NS_OK; } diff --git a/netwerk/base/src/nsSocketTransportService2.cpp b/netwerk/base/src/nsSocketTransportService2.cpp index 9807a150ccd3..be5c2f322492 100644 --- a/netwerk/base/src/nsSocketTransportService2.cpp +++ b/netwerk/base/src/nsSocketTransportService2.cpp @@ -23,15 +23,7 @@ #include "mozilla/Services.h" #include "mozilla/Preferences.h" #include "mozilla/Likely.h" - - -// XXX: There is no good header file to put these in. :( -namespace mozilla { namespace psm { - -void InitializeSSLServerCertVerificationThreads(); -void StopSSLServerCertVerificationThreads(); - -} } // namespace mozilla::psm +#include "mozilla/SSL.h" using namespace mozilla; @@ -469,6 +461,7 @@ nsSocketTransportService::Init() nsCOMPtr obsSvc = services::GetObserverService(); if (obsSvc) { obsSvc->AddObserver(this, "profile-initial-state", false); + obsSvc->AddObserver(this, "last-pb-context-exited", false); } mInitialized = true; @@ -516,6 +509,7 @@ nsSocketTransportService::Shutdown() nsCOMPtr obsSvc = services::GetObserverService(); if (obsSvc) { obsSvc->RemoveObserver(this, "profile-initial-state"); + obsSvc->RemoveObserver(this, "last-pb-context-exited"); } mozilla::net::NetworkActivityMonitor::Shutdown(); @@ -883,9 +877,35 @@ nsSocketTransportService::Observe(nsISupports *subject, return net::NetworkActivityMonitor::Init(blipInterval); } + + if (!strcmp(topic, "last-pb-context-exited")) { + nsCOMPtr ev = + NS_NewRunnableMethod(this, + &nsSocketTransportService::ClosePrivateConnections); + nsresult rv = Dispatch(ev, nsIEventTarget::DISPATCH_NORMAL); + NS_ENSURE_SUCCESS(rv, rv); + } + return NS_OK; } +void +nsSocketTransportService::ClosePrivateConnections() +{ + for (int32_t i = mActiveCount - 1; i >= 0; --i) { + if (mActiveList[i].mHandler->mIsPrivate) { + DetachSocket(mActiveList, &mActiveList[i]); + } + } + for (int32_t i = mIdleCount - 1; i >= 0; --i) { + if (mIdleList[i].mHandler->mIsPrivate) { + DetachSocket(mIdleList, &mIdleList[i]); + } + } + + mozilla::ClearPrivateSSLState(); +} + NS_IMETHODIMP nsSocketTransportService::GetSendBufferSize(int32_t *value) { diff --git a/netwerk/base/src/nsSocketTransportService2.h b/netwerk/base/src/nsSocketTransportService2.h index 7fdec908169e..737ab9889964 100644 --- a/netwerk/base/src/nsSocketTransportService2.h +++ b/netwerk/base/src/nsSocketTransportService2.h @@ -183,6 +183,8 @@ private: void ProbeMaxCount(); #endif bool mProbedMaxCount; + + void ClosePrivateConnections(); }; extern nsSocketTransportService *gSocketTransportService; diff --git a/security/manager/ssl/src/Makefile.in b/security/manager/ssl/src/Makefile.in index 86028d2e646c..b150ca6caf65 100644 --- a/security/manager/ssl/src/Makefile.in +++ b/security/manager/ssl/src/Makefile.in @@ -98,5 +98,11 @@ EXPORTS += \ ScopedNSSTypes.h \ $(NULL) +EXPORTS_NAMESPACES = mozilla + +EXPORTS_mozilla += \ + SSL.h \ + $(NULL) + include $(topsrcdir)/config/rules.mk diff --git a/security/manager/ssl/src/SharedSSLState.cpp b/security/manager/ssl/src/SharedSSLState.cpp index 6a4e7b1a493a..d9b8de86cfec 100644 --- a/security/manager/ssl/src/SharedSSLState.cpp +++ b/security/manager/ssl/src/SharedSSLState.cpp @@ -12,8 +12,47 @@ #include "mozilla/Services.h" #include "nsThreadUtils.h" #include "nsCRT.h" +#include "nsServiceManagerUtils.h" +#include "nsRecentBadCerts.h" +#include "PSMRunnable.h" +#include "ssl.h" + +using mozilla::psm::SyncRunnableBase; + +namespace { + +class CertOverrideClearer : public SyncRunnableBase +{ +public: + void RunOnTargetThread() { + nsCOMPtr icos = do_GetService(NS_CERTOVERRIDE_CONTRACTID); + if (icos) { + icos->ClearValidityOverride(NS_LITERAL_CSTRING("all:temporary-certificates"), 0); + } + } +}; + +} // anonymous namespace namespace mozilla { + +void ClearPrivateSSLState() +{ + SSL_ClearSessionCache(); + + nsCOMPtr certdb = do_GetService(NS_X509CERTDB_CONTRACTID); + if (certdb) { + nsCOMPtr badCerts; + certdb->GetRecentBadCerts(true, getter_AddRefs(badCerts)); + if (badCerts) { + badCerts->ResetStoredCerts(); + } + } + + RefPtr runnable = new CertOverrideClearer; + runnable->DispatchToMainThreadAndWait(); +} + namespace psm { namespace { diff --git a/security/manager/ssl/src/SharedSSLState.h b/security/manager/ssl/src/SharedSSLState.h index 7a89fbca243b..d5b3a8bdec34 100644 --- a/security/manager/ssl/src/SharedSSLState.h +++ b/security/manager/ssl/src/SharedSSLState.h @@ -11,8 +11,6 @@ #include "nsNSSIOLayer.h" class nsClientAuthRememberService; -class nsIRecentBadCertsService; -class nsICertOverrideService; class nsIObserver; namespace mozilla { diff --git a/security/manager/ssl/src/nsCertOverrideService.cpp b/security/manager/ssl/src/nsCertOverrideService.cpp index e2db1ce91dee..456564bd8b8a 100644 --- a/security/manager/ssl/src/nsCertOverrideService.cpp +++ b/security/manager/ssl/src/nsCertOverrideService.cpp @@ -124,7 +124,6 @@ nsCertOverrideService::Init() if (observerService) { observerService->AddObserver(this, "profile-before-change", true); observerService->AddObserver(this, "profile-do-change", true); - observerService->AddObserver(this, "last-pb-context-exited", true); // simulate a profile change so we read the current profile's settings file Observe(nullptr, "profile-do-change", nullptr); } @@ -169,10 +168,6 @@ nsCertOverrideService::Observe(nsISupports *, } Read(); - } else if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { - ClearValidityOverride( - NS_LITERAL_CSTRING("all:temporary-certificates"), - 0); } return NS_OK; diff --git a/security/manager/ssl/src/nsNSSCertificateDB.cpp b/security/manager/ssl/src/nsNSSCertificateDB.cpp index b3314216a320..65b3fd77373a 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.cpp +++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp @@ -56,6 +56,7 @@ static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSCertificateDB, nsIX509CertDB, nsIX509CertDB2) nsNSSCertificateDB::nsNSSCertificateDB() +: mBadCertsLock("nsNSSCertificateDB::mBadCertsLock") { } @@ -1650,11 +1651,10 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval) NS_IMETHODIMP nsNSSCertificateDB::GetRecentBadCerts(bool isPrivate, nsIRecentBadCerts** result) { - MOZ_ASSERT(NS_IsMainThread(), "RecentBadCerts should only be obtained on the main thread"); + MutexAutoLock lock(mBadCertsLock); if (isPrivate) { if (!mPrivateRecentBadCerts) { mPrivateRecentBadCerts = new nsRecentBadCerts; - mPrivateRecentBadCerts->InitPrivateBrowsingObserver(); } NS_ADDREF(*result = mPrivateRecentBadCerts); } else { diff --git a/security/manager/ssl/src/nsNSSCertificateDB.h b/security/manager/ssl/src/nsNSSCertificateDB.h index c821322fbcb4..5ef5015598d1 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.h +++ b/security/manager/ssl/src/nsNSSCertificateDB.h @@ -8,6 +8,7 @@ #include "nsIX509CertDB.h" #include "nsIX509CertDB2.h" #include "mozilla/RefPtr.h" +#include "mozilla/Mutex.h" #include "certt.h" class nsCString; @@ -51,6 +52,7 @@ private: nsresult handleCACertDownload(nsIArray *x509Certs, nsIInterfaceRequestor *ctx); + mozilla::Mutex mBadCertsLock; mozilla::RefPtr mPublicRecentBadCerts; mozilla::RefPtr mPrivateRecentBadCerts; }; diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index 31d21ed90ac3..aabe6fab9789 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -2138,7 +2138,6 @@ nsNSSComponent::RandomUpdate(void *entropy, int32_t bufLen) #define PROFILE_CHANGE_TEARDOWN_VETO_TOPIC "profile-change-teardown-veto" #define PROFILE_BEFORE_CHANGE_TOPIC "profile-before-change" #define PROFILE_DO_CHANGE_TOPIC "profile-do-change" -#define LEAVE_PRIVATE_BROWSING_TOPIC "last-pb-context-exited" NS_IMETHODIMP nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, @@ -2286,9 +2285,6 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network restore topic\n")); DoProfileChangeNetRestore(); } - else if (nsCRT::strcmp(aTopic, LEAVE_PRIVATE_BROWSING_TOPIC) == 0) { - SSL_ClearSessionCache(); - } return NS_OK; } @@ -2388,7 +2384,6 @@ nsNSSComponent::RegisterObservers() observerService->AddObserver(this, PROFILE_DO_CHANGE_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC, false); - observerService->AddObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC, false); } return NS_OK; } @@ -2414,7 +2409,6 @@ nsNSSComponent::DeregisterObservers() observerService->RemoveObserver(this, PROFILE_DO_CHANGE_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC); - observerService->RemoveObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC); } return NS_OK; } diff --git a/security/manager/ssl/src/nsRecentBadCerts.cpp b/security/manager/ssl/src/nsRecentBadCerts.cpp index cae4fd1fb61c..1b121cc767d7 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.cpp +++ b/security/manager/ssl/src/nsRecentBadCerts.cpp @@ -22,9 +22,8 @@ using namespace mozilla; -NS_IMPL_THREADSAFE_ISUPPORTS2(nsRecentBadCerts, - nsIRecentBadCerts, - nsIObserver) +NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCerts, + nsIRecentBadCerts) nsRecentBadCerts::nsRecentBadCerts() :monitor("nsRecentBadCerts.monitor") @@ -36,24 +35,6 @@ nsRecentBadCerts::~nsRecentBadCerts() { } -void -nsRecentBadCerts::InitPrivateBrowsingObserver() -{ - nsCOMPtr obsSvc = mozilla::services::GetObserverService(); - obsSvc->AddObserver(this, "last-pb-context-exited", false); -} - -NS_IMETHODIMP -nsRecentBadCerts::Observe(nsISupports *aSubject, - const char *aTopic, - const PRUnichar *aData) -{ - if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { - ResetStoredCerts(); - } - return NS_OK; -} - NS_IMETHODIMP nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort, nsISSLStatus **aStatus) diff --git a/security/manager/ssl/src/nsRecentBadCerts.h b/security/manager/ssl/src/nsRecentBadCerts.h index d815482d3794..064cb46cd1e8 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.h +++ b/security/manager/ssl/src/nsRecentBadCerts.h @@ -11,7 +11,6 @@ #include "mozilla/ReentrantMonitor.h" #include "nsIRecentBadCertsService.h" -#include "nsIObserver.h" #include "nsTHashtable.h" #include "nsString.h" #include "cert.h" @@ -56,18 +55,14 @@ private: }; class nsRecentBadCerts MOZ_FINAL : public nsIRecentBadCerts - , public nsIObserver { public: NS_DECL_ISUPPORTS NS_DECL_NSIRECENTBADCERTS - NS_DECL_NSIOBSERVER nsRecentBadCerts(); ~nsRecentBadCerts(); - void InitPrivateBrowsingObserver(); - protected: mozilla::ReentrantMonitor monitor; From c88ef7aade17ca7b41d85b0a7453e3c03bf77d95 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:12:16 -0500 Subject: [PATCH 08/35] Bug 769288 - Part 6: Remove global private browsing NSS cleanup on exit. r=ehsan --- .../privatebrowsing/src/nsPrivateBrowsingService.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js index 47c2f6d8f72f..21d85fa004cf 100644 --- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js +++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js @@ -439,11 +439,6 @@ PrivateBrowsingService.prototype = { this._unload(); break; case "private-browsing": - // clear all auth tokens - let sdr = Cc["@mozilla.org/security/sdr;1"]. - getService(Ci.nsISecretDecoderRing); - sdr.logoutAndTeardown(); - if (!this._inPrivateBrowsing) { // Clear the error console let consoleService = Cc["@mozilla.org/consoleservice;1"]. From ab1ce4e14c4dbaaa1f38bbd9a4339db9d541b5bf Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:12:26 -0500 Subject: [PATCH 09/35] Bug 769288 - Part 7: Use separate SSL session cache entries for private connections. r=mayhemer --- security/manager/ssl/src/nsNSSIOLayer.cpp | 29 ++++++++++++----------- security/manager/ssl/src/nsNSSIOLayer.h | 4 +++- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index 8e84c9647b2b..a1ad8690a00c 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -2448,7 +2448,7 @@ loser: static nsresult nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, const char *proxyHost, const char *host, int32_t port, - bool anonymousLoad, nsNSSSocketInfo *infoObject) + nsNSSSocketInfo *infoObject) { nsNSSShutDownPreventionLock locker; if (forSTARTTLS || proxyHost) { @@ -2501,20 +2501,23 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, } } - // Set the Peer ID so that SSL proxy connections work properly. - char *peerId; - if (anonymousLoad) { // See bug #466080. Separate the caches. - peerId = PR_smprintf("anon:%s:%d", host, port); - } else { - peerId = PR_smprintf("%s:%d", host, port); + // Set the Peer ID so that SSL proxy connections work properly and to + // separate anonymous and/or private browsing connections. + uint32_t flags = infoObject->GetProviderFlags(); + nsAutoCString peerId; + if (flags & nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080 + peerId.Append("anon:"); } - - if (SECSuccess != SSL_SetSockPeerID(fd, peerId)) { - PR_smprintf_free(peerId); + if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) { + peerId.Append("private:"); + } + peerId.Append(host); + peerId.Append(':'); + peerId.AppendInt(port); + if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) { return NS_ERROR_FAILURE; } - PR_smprintf_free(peerId); return NS_OK; } @@ -2544,7 +2547,6 @@ nsSSLIOLayerAddToSocket(int32_t family, infoObject->SetHostName(host); infoObject->SetPort(port); - bool anonymousLoad = providerFlags & nsISocketProvider::ANONYMOUS_CONNECT; PRFileDesc *sslSock = nsSSLIOLayerImportFD(fd, infoObject, host); if (!sslSock) { NS_ASSERTION(false, "NSS: Error importing socket"); @@ -2553,8 +2555,7 @@ nsSSLIOLayerAddToSocket(int32_t family, infoObject->SetFileDescPtr(sslSock); - rv = nsSSLIOLayerSetOptions(sslSock, - forSTARTTLS, proxyHost, host, port, anonymousLoad, + rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, proxyHost, host, port, infoObject); if (NS_FAILED(rv)) diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h index 2f25e71d04c8..abdf8d430051 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.h +++ b/security/manager/ssl/src/nsNSSIOLayer.h @@ -63,7 +63,9 @@ public: bool GetJoined() { return mJoined; } void SetSentClientCert() { mSentClientCert = true; } - + + uint32_t GetProviderFlags() const { return mProviderFlags; } + mozilla::psm::SharedSSLState& SharedState(); // XXX: These are only used on for diagnostic purposes From 6e8d00ced1d389392e4904bc83222984e06704db Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:25:32 -0500 Subject: [PATCH 10/35] Bug 769288 - Add missing SSL.h. r=burning --- security/manager/ssl/src/SSL.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 security/manager/ssl/src/SSL.h diff --git a/security/manager/ssl/src/SSL.h b/security/manager/ssl/src/SSL.h new file mode 100644 index 000000000000..738a6e1f12d1 --- /dev/null +++ b/security/manager/ssl/src/SSL.h @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef mozilla_SSL_h +#define mozilla_SSL_h + +namespace mozilla { + +void ClearPrivateSSLState(); + +namespace psm { + +void InitializeSSLServerCertVerificationThreads(); +void StopSSLServerCertVerificationThreads(); + +} //namespace psm +} // namespace mozilla + +#endif + From cc1a6166fd1a50677be3ad7bdeb7b3d92881e5f4 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:45:48 -0500 Subject: [PATCH 11/35] Backed out changeset 3990b431f138 (bug 769288) --- security/manager/ssl/src/SSL.h | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 security/manager/ssl/src/SSL.h diff --git a/security/manager/ssl/src/SSL.h b/security/manager/ssl/src/SSL.h deleted file mode 100644 index 738a6e1f12d1..000000000000 --- a/security/manager/ssl/src/SSL.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef mozilla_SSL_h -#define mozilla_SSL_h - -namespace mozilla { - -void ClearPrivateSSLState(); - -namespace psm { - -void InitializeSSLServerCertVerificationThreads(); -void StopSSLServerCertVerificationThreads(); - -} //namespace psm -} // namespace mozilla - -#endif - From dd792dcc7398884fcbc99ae96ca41b6ee5369155 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:45:50 -0500 Subject: [PATCH 12/35] Backed out changeset d0f828b1cd26 (bug 769288) --- security/manager/ssl/src/nsNSSIOLayer.cpp | 29 +++++++++++------------ security/manager/ssl/src/nsNSSIOLayer.h | 4 +--- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index a1ad8690a00c..8e84c9647b2b 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -2448,7 +2448,7 @@ loser: static nsresult nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, const char *proxyHost, const char *host, int32_t port, - nsNSSSocketInfo *infoObject) + bool anonymousLoad, nsNSSSocketInfo *infoObject) { nsNSSShutDownPreventionLock locker; if (forSTARTTLS || proxyHost) { @@ -2501,23 +2501,20 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, } } - // Set the Peer ID so that SSL proxy connections work properly and to - // separate anonymous and/or private browsing connections. - uint32_t flags = infoObject->GetProviderFlags(); - nsAutoCString peerId; - if (flags & nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080 - peerId.Append("anon:"); + // Set the Peer ID so that SSL proxy connections work properly. + char *peerId; + if (anonymousLoad) { // See bug #466080. Separate the caches. + peerId = PR_smprintf("anon:%s:%d", host, port); + } else { + peerId = PR_smprintf("%s:%d", host, port); } - if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) { - peerId.Append("private:"); - } - peerId.Append(host); - peerId.Append(':'); - peerId.AppendInt(port); - if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) { + + if (SECSuccess != SSL_SetSockPeerID(fd, peerId)) { + PR_smprintf_free(peerId); return NS_ERROR_FAILURE; } + PR_smprintf_free(peerId); return NS_OK; } @@ -2547,6 +2544,7 @@ nsSSLIOLayerAddToSocket(int32_t family, infoObject->SetHostName(host); infoObject->SetPort(port); + bool anonymousLoad = providerFlags & nsISocketProvider::ANONYMOUS_CONNECT; PRFileDesc *sslSock = nsSSLIOLayerImportFD(fd, infoObject, host); if (!sslSock) { NS_ASSERTION(false, "NSS: Error importing socket"); @@ -2555,7 +2553,8 @@ nsSSLIOLayerAddToSocket(int32_t family, infoObject->SetFileDescPtr(sslSock); - rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, proxyHost, host, port, + rv = nsSSLIOLayerSetOptions(sslSock, + forSTARTTLS, proxyHost, host, port, anonymousLoad, infoObject); if (NS_FAILED(rv)) diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h index abdf8d430051..2f25e71d04c8 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.h +++ b/security/manager/ssl/src/nsNSSIOLayer.h @@ -63,9 +63,7 @@ public: bool GetJoined() { return mJoined; } void SetSentClientCert() { mSentClientCert = true; } - - uint32_t GetProviderFlags() const { return mProviderFlags; } - + mozilla::psm::SharedSSLState& SharedState(); // XXX: These are only used on for diagnostic purposes From 3026ede1bd4ff07e3f7863e7329f83b7d38aa865 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:45:51 -0500 Subject: [PATCH 13/35] Backed out changeset 3b25f7b4a9ce (bug 769288) --- .../privatebrowsing/src/nsPrivateBrowsingService.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js index 21d85fa004cf..47c2f6d8f72f 100644 --- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js +++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js @@ -439,6 +439,11 @@ PrivateBrowsingService.prototype = { this._unload(); break; case "private-browsing": + // clear all auth tokens + let sdr = Cc["@mozilla.org/security/sdr;1"]. + getService(Ci.nsISecretDecoderRing); + sdr.logoutAndTeardown(); + if (!this._inPrivateBrowsing) { // Clear the error console let consoleService = Cc["@mozilla.org/consoleservice;1"]. From e04efc855127bd28ab3deb4b46f57ffb2bd21ff2 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:45:52 -0500 Subject: [PATCH 14/35] Backed out changeset 09639e16d3cb (bug 769288) --- netwerk/base/public/nsASocketHandler.h | 3 -- netwerk/base/src/nsSocketTransport2.cpp | 1 - .../base/src/nsSocketTransportService2.cpp | 38 +++++------------- netwerk/base/src/nsSocketTransportService2.h | 2 - security/manager/ssl/src/Makefile.in | 6 --- security/manager/ssl/src/SharedSSLState.cpp | 39 ------------------- security/manager/ssl/src/SharedSSLState.h | 2 + .../manager/ssl/src/nsCertOverrideService.cpp | 5 +++ .../manager/ssl/src/nsNSSCertificateDB.cpp | 4 +- security/manager/ssl/src/nsNSSCertificateDB.h | 2 - security/manager/ssl/src/nsNSSComponent.cpp | 6 +++ security/manager/ssl/src/nsRecentBadCerts.cpp | 23 ++++++++++- security/manager/ssl/src/nsRecentBadCerts.h | 5 +++ 13 files changed, 50 insertions(+), 86 deletions(-) diff --git a/netwerk/base/public/nsASocketHandler.h b/netwerk/base/public/nsASocketHandler.h index 1f18ab1d7617..3e2efe95231b 100644 --- a/netwerk/base/public/nsASocketHandler.h +++ b/netwerk/base/public/nsASocketHandler.h @@ -15,7 +15,6 @@ public: : mCondition(NS_OK) , mPollFlags(0) , mPollTimeout(UINT16_MAX) - , mIsPrivate(false) {} // @@ -43,8 +42,6 @@ public: // uint16_t mPollTimeout; - bool mIsPrivate; - // // called to service a socket // diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp index dd7eafc1f41a..a348eb59b117 100644 --- a/netwerk/base/src/nsSocketTransport2.cpp +++ b/netwerk/base/src/nsSocketTransport2.cpp @@ -2206,7 +2206,6 @@ NS_IMETHODIMP nsSocketTransport::SetConnectionFlags(uint32_t value) { mConnectionFlags = value; - mIsPrivate = value & nsISocketTransport::NO_PERMANENT_STORAGE; return NS_OK; } diff --git a/netwerk/base/src/nsSocketTransportService2.cpp b/netwerk/base/src/nsSocketTransportService2.cpp index be5c2f322492..9807a150ccd3 100644 --- a/netwerk/base/src/nsSocketTransportService2.cpp +++ b/netwerk/base/src/nsSocketTransportService2.cpp @@ -23,7 +23,15 @@ #include "mozilla/Services.h" #include "mozilla/Preferences.h" #include "mozilla/Likely.h" -#include "mozilla/SSL.h" + + +// XXX: There is no good header file to put these in. :( +namespace mozilla { namespace psm { + +void InitializeSSLServerCertVerificationThreads(); +void StopSSLServerCertVerificationThreads(); + +} } // namespace mozilla::psm using namespace mozilla; @@ -461,7 +469,6 @@ nsSocketTransportService::Init() nsCOMPtr obsSvc = services::GetObserverService(); if (obsSvc) { obsSvc->AddObserver(this, "profile-initial-state", false); - obsSvc->AddObserver(this, "last-pb-context-exited", false); } mInitialized = true; @@ -509,7 +516,6 @@ nsSocketTransportService::Shutdown() nsCOMPtr obsSvc = services::GetObserverService(); if (obsSvc) { obsSvc->RemoveObserver(this, "profile-initial-state"); - obsSvc->RemoveObserver(this, "last-pb-context-exited"); } mozilla::net::NetworkActivityMonitor::Shutdown(); @@ -877,35 +883,9 @@ nsSocketTransportService::Observe(nsISupports *subject, return net::NetworkActivityMonitor::Init(blipInterval); } - - if (!strcmp(topic, "last-pb-context-exited")) { - nsCOMPtr ev = - NS_NewRunnableMethod(this, - &nsSocketTransportService::ClosePrivateConnections); - nsresult rv = Dispatch(ev, nsIEventTarget::DISPATCH_NORMAL); - NS_ENSURE_SUCCESS(rv, rv); - } - return NS_OK; } -void -nsSocketTransportService::ClosePrivateConnections() -{ - for (int32_t i = mActiveCount - 1; i >= 0; --i) { - if (mActiveList[i].mHandler->mIsPrivate) { - DetachSocket(mActiveList, &mActiveList[i]); - } - } - for (int32_t i = mIdleCount - 1; i >= 0; --i) { - if (mIdleList[i].mHandler->mIsPrivate) { - DetachSocket(mIdleList, &mIdleList[i]); - } - } - - mozilla::ClearPrivateSSLState(); -} - NS_IMETHODIMP nsSocketTransportService::GetSendBufferSize(int32_t *value) { diff --git a/netwerk/base/src/nsSocketTransportService2.h b/netwerk/base/src/nsSocketTransportService2.h index 737ab9889964..7fdec908169e 100644 --- a/netwerk/base/src/nsSocketTransportService2.h +++ b/netwerk/base/src/nsSocketTransportService2.h @@ -183,8 +183,6 @@ private: void ProbeMaxCount(); #endif bool mProbedMaxCount; - - void ClosePrivateConnections(); }; extern nsSocketTransportService *gSocketTransportService; diff --git a/security/manager/ssl/src/Makefile.in b/security/manager/ssl/src/Makefile.in index b150ca6caf65..86028d2e646c 100644 --- a/security/manager/ssl/src/Makefile.in +++ b/security/manager/ssl/src/Makefile.in @@ -98,11 +98,5 @@ EXPORTS += \ ScopedNSSTypes.h \ $(NULL) -EXPORTS_NAMESPACES = mozilla - -EXPORTS_mozilla += \ - SSL.h \ - $(NULL) - include $(topsrcdir)/config/rules.mk diff --git a/security/manager/ssl/src/SharedSSLState.cpp b/security/manager/ssl/src/SharedSSLState.cpp index d9b8de86cfec..6a4e7b1a493a 100644 --- a/security/manager/ssl/src/SharedSSLState.cpp +++ b/security/manager/ssl/src/SharedSSLState.cpp @@ -12,47 +12,8 @@ #include "mozilla/Services.h" #include "nsThreadUtils.h" #include "nsCRT.h" -#include "nsServiceManagerUtils.h" -#include "nsRecentBadCerts.h" -#include "PSMRunnable.h" -#include "ssl.h" - -using mozilla::psm::SyncRunnableBase; - -namespace { - -class CertOverrideClearer : public SyncRunnableBase -{ -public: - void RunOnTargetThread() { - nsCOMPtr icos = do_GetService(NS_CERTOVERRIDE_CONTRACTID); - if (icos) { - icos->ClearValidityOverride(NS_LITERAL_CSTRING("all:temporary-certificates"), 0); - } - } -}; - -} // anonymous namespace namespace mozilla { - -void ClearPrivateSSLState() -{ - SSL_ClearSessionCache(); - - nsCOMPtr certdb = do_GetService(NS_X509CERTDB_CONTRACTID); - if (certdb) { - nsCOMPtr badCerts; - certdb->GetRecentBadCerts(true, getter_AddRefs(badCerts)); - if (badCerts) { - badCerts->ResetStoredCerts(); - } - } - - RefPtr runnable = new CertOverrideClearer; - runnable->DispatchToMainThreadAndWait(); -} - namespace psm { namespace { diff --git a/security/manager/ssl/src/SharedSSLState.h b/security/manager/ssl/src/SharedSSLState.h index d5b3a8bdec34..7a89fbca243b 100644 --- a/security/manager/ssl/src/SharedSSLState.h +++ b/security/manager/ssl/src/SharedSSLState.h @@ -11,6 +11,8 @@ #include "nsNSSIOLayer.h" class nsClientAuthRememberService; +class nsIRecentBadCertsService; +class nsICertOverrideService; class nsIObserver; namespace mozilla { diff --git a/security/manager/ssl/src/nsCertOverrideService.cpp b/security/manager/ssl/src/nsCertOverrideService.cpp index 456564bd8b8a..e2db1ce91dee 100644 --- a/security/manager/ssl/src/nsCertOverrideService.cpp +++ b/security/manager/ssl/src/nsCertOverrideService.cpp @@ -124,6 +124,7 @@ nsCertOverrideService::Init() if (observerService) { observerService->AddObserver(this, "profile-before-change", true); observerService->AddObserver(this, "profile-do-change", true); + observerService->AddObserver(this, "last-pb-context-exited", true); // simulate a profile change so we read the current profile's settings file Observe(nullptr, "profile-do-change", nullptr); } @@ -168,6 +169,10 @@ nsCertOverrideService::Observe(nsISupports *, } Read(); + } else if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { + ClearValidityOverride( + NS_LITERAL_CSTRING("all:temporary-certificates"), + 0); } return NS_OK; diff --git a/security/manager/ssl/src/nsNSSCertificateDB.cpp b/security/manager/ssl/src/nsNSSCertificateDB.cpp index 65b3fd77373a..b3314216a320 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.cpp +++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp @@ -56,7 +56,6 @@ static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSCertificateDB, nsIX509CertDB, nsIX509CertDB2) nsNSSCertificateDB::nsNSSCertificateDB() -: mBadCertsLock("nsNSSCertificateDB::mBadCertsLock") { } @@ -1651,10 +1650,11 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval) NS_IMETHODIMP nsNSSCertificateDB::GetRecentBadCerts(bool isPrivate, nsIRecentBadCerts** result) { - MutexAutoLock lock(mBadCertsLock); + MOZ_ASSERT(NS_IsMainThread(), "RecentBadCerts should only be obtained on the main thread"); if (isPrivate) { if (!mPrivateRecentBadCerts) { mPrivateRecentBadCerts = new nsRecentBadCerts; + mPrivateRecentBadCerts->InitPrivateBrowsingObserver(); } NS_ADDREF(*result = mPrivateRecentBadCerts); } else { diff --git a/security/manager/ssl/src/nsNSSCertificateDB.h b/security/manager/ssl/src/nsNSSCertificateDB.h index 5ef5015598d1..c821322fbcb4 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.h +++ b/security/manager/ssl/src/nsNSSCertificateDB.h @@ -8,7 +8,6 @@ #include "nsIX509CertDB.h" #include "nsIX509CertDB2.h" #include "mozilla/RefPtr.h" -#include "mozilla/Mutex.h" #include "certt.h" class nsCString; @@ -52,7 +51,6 @@ private: nsresult handleCACertDownload(nsIArray *x509Certs, nsIInterfaceRequestor *ctx); - mozilla::Mutex mBadCertsLock; mozilla::RefPtr mPublicRecentBadCerts; mozilla::RefPtr mPrivateRecentBadCerts; }; diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index aabe6fab9789..31d21ed90ac3 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -2138,6 +2138,7 @@ nsNSSComponent::RandomUpdate(void *entropy, int32_t bufLen) #define PROFILE_CHANGE_TEARDOWN_VETO_TOPIC "profile-change-teardown-veto" #define PROFILE_BEFORE_CHANGE_TOPIC "profile-before-change" #define PROFILE_DO_CHANGE_TOPIC "profile-do-change" +#define LEAVE_PRIVATE_BROWSING_TOPIC "last-pb-context-exited" NS_IMETHODIMP nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, @@ -2285,6 +2286,9 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network restore topic\n")); DoProfileChangeNetRestore(); } + else if (nsCRT::strcmp(aTopic, LEAVE_PRIVATE_BROWSING_TOPIC) == 0) { + SSL_ClearSessionCache(); + } return NS_OK; } @@ -2384,6 +2388,7 @@ nsNSSComponent::RegisterObservers() observerService->AddObserver(this, PROFILE_DO_CHANGE_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC, false); + observerService->AddObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC, false); } return NS_OK; } @@ -2409,6 +2414,7 @@ nsNSSComponent::DeregisterObservers() observerService->RemoveObserver(this, PROFILE_DO_CHANGE_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC); + observerService->RemoveObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC); } return NS_OK; } diff --git a/security/manager/ssl/src/nsRecentBadCerts.cpp b/security/manager/ssl/src/nsRecentBadCerts.cpp index 1b121cc767d7..cae4fd1fb61c 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.cpp +++ b/security/manager/ssl/src/nsRecentBadCerts.cpp @@ -22,8 +22,9 @@ using namespace mozilla; -NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCerts, - nsIRecentBadCerts) +NS_IMPL_THREADSAFE_ISUPPORTS2(nsRecentBadCerts, + nsIRecentBadCerts, + nsIObserver) nsRecentBadCerts::nsRecentBadCerts() :monitor("nsRecentBadCerts.monitor") @@ -35,6 +36,24 @@ nsRecentBadCerts::~nsRecentBadCerts() { } +void +nsRecentBadCerts::InitPrivateBrowsingObserver() +{ + nsCOMPtr obsSvc = mozilla::services::GetObserverService(); + obsSvc->AddObserver(this, "last-pb-context-exited", false); +} + +NS_IMETHODIMP +nsRecentBadCerts::Observe(nsISupports *aSubject, + const char *aTopic, + const PRUnichar *aData) +{ + if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { + ResetStoredCerts(); + } + return NS_OK; +} + NS_IMETHODIMP nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort, nsISSLStatus **aStatus) diff --git a/security/manager/ssl/src/nsRecentBadCerts.h b/security/manager/ssl/src/nsRecentBadCerts.h index 064cb46cd1e8..d815482d3794 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.h +++ b/security/manager/ssl/src/nsRecentBadCerts.h @@ -11,6 +11,7 @@ #include "mozilla/ReentrantMonitor.h" #include "nsIRecentBadCertsService.h" +#include "nsIObserver.h" #include "nsTHashtable.h" #include "nsString.h" #include "cert.h" @@ -55,14 +56,18 @@ private: }; class nsRecentBadCerts MOZ_FINAL : public nsIRecentBadCerts + , public nsIObserver { public: NS_DECL_ISUPPORTS NS_DECL_NSIRECENTBADCERTS + NS_DECL_NSIOBSERVER nsRecentBadCerts(); ~nsRecentBadCerts(); + void InitPrivateBrowsingObserver(); + protected: mozilla::ReentrantMonitor monitor; From a2821426b2d583b52e204947dde0f7de939f34aa Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:45:54 -0500 Subject: [PATCH 15/35] Backed out changeset bc166c758a17 (bug 769288) --- security/manager/ssl/src/nsNSSComponent.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index 31d21ed90ac3..aabe6fab9789 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -2138,7 +2138,6 @@ nsNSSComponent::RandomUpdate(void *entropy, int32_t bufLen) #define PROFILE_CHANGE_TEARDOWN_VETO_TOPIC "profile-change-teardown-veto" #define PROFILE_BEFORE_CHANGE_TOPIC "profile-before-change" #define PROFILE_DO_CHANGE_TOPIC "profile-do-change" -#define LEAVE_PRIVATE_BROWSING_TOPIC "last-pb-context-exited" NS_IMETHODIMP nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, @@ -2286,9 +2285,6 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network restore topic\n")); DoProfileChangeNetRestore(); } - else if (nsCRT::strcmp(aTopic, LEAVE_PRIVATE_BROWSING_TOPIC) == 0) { - SSL_ClearSessionCache(); - } return NS_OK; } @@ -2388,7 +2384,6 @@ nsNSSComponent::RegisterObservers() observerService->AddObserver(this, PROFILE_DO_CHANGE_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC, false); - observerService->AddObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC, false); } return NS_OK; } @@ -2414,7 +2409,6 @@ nsNSSComponent::DeregisterObservers() observerService->RemoveObserver(this, PROFILE_DO_CHANGE_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC); - observerService->RemoveObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC); } return NS_OK; } From 221b4ed023c96fdab772a8ec8f041e99dc108639 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:45:55 -0500 Subject: [PATCH 16/35] Backed out changeset 653fc39e223e (bug 769288) --- security/manager/ssl/src/nsCertOverrideService.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/security/manager/ssl/src/nsCertOverrideService.cpp b/security/manager/ssl/src/nsCertOverrideService.cpp index e2db1ce91dee..456564bd8b8a 100644 --- a/security/manager/ssl/src/nsCertOverrideService.cpp +++ b/security/manager/ssl/src/nsCertOverrideService.cpp @@ -124,7 +124,6 @@ nsCertOverrideService::Init() if (observerService) { observerService->AddObserver(this, "profile-before-change", true); observerService->AddObserver(this, "profile-do-change", true); - observerService->AddObserver(this, "last-pb-context-exited", true); // simulate a profile change so we read the current profile's settings file Observe(nullptr, "profile-do-change", nullptr); } @@ -169,10 +168,6 @@ nsCertOverrideService::Observe(nsISupports *, } Read(); - } else if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { - ClearValidityOverride( - NS_LITERAL_CSTRING("all:temporary-certificates"), - 0); } return NS_OK; From 0c6fefa3baa3954e026d46d042f60c7135ed38e3 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:45:56 -0500 Subject: [PATCH 17/35] Backed out changeset 499bd31197a1 (bug 769288) --- .../ssl/src/SSLServerCertVerification.cpp | 69 +++++++++---------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/security/manager/ssl/src/SSLServerCertVerification.cpp b/security/manager/ssl/src/SSLServerCertVerification.cpp index c03f003b30e3..6bac3a3abfc6 100644 --- a/security/manager/ssl/src/SSLServerCertVerification.cpp +++ b/security/manager/ssl/src/SSLServerCertVerification.cpp @@ -835,8 +835,7 @@ BlockServerCertChangeForSpdy(nsNSSSocketInfo *infoObject, } SECStatus -AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert, - uint32_t providerFlags) +AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert) { if (cert->serialNumber.data && cert->issuerName && @@ -922,41 +921,37 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert, } nsCOMPtr nssComponent; + + for (CERTCertListNode *node = CERT_LIST_HEAD(certList); + !CERT_LIST_END(node, certList); + node = CERT_LIST_NEXT(node)) { - // We want to avoid storing any intermediate cert information when browsing - // in private, transient contexts. - if (!(providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE)) { - for (CERTCertListNode *node = CERT_LIST_HEAD(certList); - !CERT_LIST_END(node, certList); - node = CERT_LIST_NEXT(node)) { - - if (node->cert->slot) { - // This cert was found on a token, no need to remember it in the temp db. - continue; - } - - if (node->cert->isperm) { - // We don't need to remember certs already stored in perm db. - continue; - } - - if (node->cert == cert) { - // We don't want to remember the server cert, - // the code that cares for displaying page info does this already. - continue; - } - - // We have found a signer cert that we want to remember. - char* nickname = nsNSSCertificate::defaultServerNickname(node->cert); - if (nickname && *nickname) { - ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); - if (slot) { - PK11_ImportCert(slot, node->cert, CK_INVALID_HANDLE, - nickname, false); - } - } - PR_FREEIF(nickname); + if (node->cert->slot) { + // This cert was found on a token, no need to remember it in the temp db. + continue; } + + if (node->cert->isperm) { + // We don't need to remember certs already stored in perm db. + continue; + } + + if (node->cert == cert) { + // We don't want to remember the server cert, + // the code that cares for displaying page info does this already. + continue; + } + + // We have found a signer cert that we want to remember. + char* nickname = nsNSSCertificate::defaultServerNickname(node->cert); + if (nickname && *nickname) { + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (slot) { + PK11_ImportCert(slot, node->cert, CK_INVALID_HANDLE, + nickname, false); + } + } + PR_FREEIF(nickname); } // The connection may get terminated, for example, if the server requires @@ -1048,7 +1043,7 @@ SSLServerCertVerificationJob::Run() // Reset the error code here so we can detect if AuthCertificate fails to // set the error code if/when it fails. PR_SetError(0, 0); - SECStatus rv = AuthCertificate(mInfoObject, mCert, mProviderFlags); + SECStatus rv = AuthCertificate(mInfoObject, mCert); if (rv == SECSuccess) { RefPtr restart( new SSLServerCertVerificationResult(mInfoObject, 0)); @@ -1173,7 +1168,7 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) // thread doing the network I/O may not interrupt its network I/O on receipt // of our SSLServerCertVerificationResult event, and/or it might not even be // a non-blocking socket. - SECStatus rv = AuthCertificate(socketInfo, serverCert, providerFlags); + SECStatus rv = AuthCertificate(socketInfo, serverCert); if (rv == SECSuccess) { return SECSuccess; } From 753a9e6a62be17824266f473f6fd1a52b13ebbe9 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 19:45:57 -0500 Subject: [PATCH 18/35] Backed out changeset 3008e6e5476f (bug 769288) --- .../pki/resources/content/exceptionDialog.js | 7 +- .../ssl/public/nsIRecentBadCertsService.idl | 10 +- security/manager/ssl/public/nsIX509CertDB.idl | 13 +- security/manager/ssl/src/Makefile.in | 1 - .../ssl/src/SSLServerCertVerification.cpp | 57 +++---- security/manager/ssl/src/SharedSSLState.cpp | 111 -------------- security/manager/ssl/src/SharedSSLState.h | 54 ------- .../manager/ssl/src/nsClientAuthRemember.cpp | 12 -- .../manager/ssl/src/nsClientAuthRemember.h | 1 - security/manager/ssl/src/nsNSSCallbacks.cpp | 8 +- .../manager/ssl/src/nsNSSCertificateDB.cpp | 21 --- security/manager/ssl/src/nsNSSCertificateDB.h | 5 - security/manager/ssl/src/nsNSSComponent.cpp | 53 ++++++- security/manager/ssl/src/nsNSSComponent.h | 4 + security/manager/ssl/src/nsNSSIOLayer.cpp | 144 ++++-------------- security/manager/ssl/src/nsNSSIOLayer.h | 58 +++---- security/manager/ssl/src/nsNSSModule.cpp | 5 + security/manager/ssl/src/nsRecentBadCerts.cpp | 45 ++---- security/manager/ssl/src/nsRecentBadCerts.h | 13 +- 19 files changed, 151 insertions(+), 471 deletions(-) delete mode 100644 security/manager/ssl/src/SharedSSLState.cpp delete mode 100644 security/manager/ssl/src/SharedSSLState.h diff --git a/security/manager/pki/resources/content/exceptionDialog.js b/security/manager/pki/resources/content/exceptionDialog.js index 6d4eb89eacf9..e6cae8415859 100644 --- a/security/manager/pki/resources/content/exceptionDialog.js +++ b/security/manager/pki/resources/content/exceptionDialog.js @@ -88,11 +88,8 @@ function initExceptionDialog() { // returns true if found and global status could be set function findRecentBadCert(uri) { try { - var certDB = Components.classes["@mozilla.org/security/x509certdb;1"] - .getService(Components.interfaces.nsIX509CertDB); - if (!certDB) - return false; - var recentCertsSvc = certDB.getRecentBadCertsService(inPrivateBrowsingMode()); + var recentCertsSvc = Components.classes["@mozilla.org/security/recentbadcerts;1"] + .getService(Components.interfaces.nsIRecentBadCertsService); if (!recentCertsSvc) return false; diff --git a/security/manager/ssl/public/nsIRecentBadCertsService.idl b/security/manager/ssl/public/nsIRecentBadCertsService.idl index c221aa1dbd93..398b792e4cc1 100644 --- a/security/manager/ssl/public/nsIRecentBadCertsService.idl +++ b/security/manager/ssl/public/nsIRecentBadCertsService.idl @@ -20,8 +20,9 @@ interface nsISSLStatus; * The implementation will decide how many entries it will hold, * the number is expected to be small. */ -[scriptable, uuid(0fed7784-d152-44d6-95a7-67a59024de0f)] -interface nsIRecentBadCerts : nsISupports { +[scriptable, uuid(a5ae8b05-a76e-408f-b0ba-02a831265749)] +interface nsIRecentBadCertsService : nsISupports { + /** * Retrieve the recently seen bad ssl status for the given hostname:port. * If no SSL cert was recently seen for the given hostname:port, return null. @@ -42,9 +43,4 @@ interface nsIRecentBadCerts : nsISupports { */ void addBadCert(in AString aHostNameWithPort, in nsISSLStatus aStatus); - - /** - * Clear all stored cert data. - */ - void resetStoredCerts(); }; diff --git a/security/manager/ssl/public/nsIX509CertDB.idl b/security/manager/ssl/public/nsIX509CertDB.idl index aec9964a1fab..cedbb2644473 100644 --- a/security/manager/ssl/public/nsIX509CertDB.idl +++ b/security/manager/ssl/public/nsIX509CertDB.idl @@ -12,7 +12,6 @@ interface nsIX509Cert3; interface nsIFile; interface nsIInterfaceRequestor; interface nsIZipReader; -interface nsIRecentBadCerts; %{C++ #define NS_X509CERTDB_CONTRACTID "@mozilla.org/security/x509certdb;1" @@ -30,7 +29,7 @@ interface nsIOpenSignedJARFileCallback : nsISupports * This represents a service to access and manipulate * X.509 certificates stored in a database. */ -[scriptable, uuid(a18df2a5-84a9-46cd-9140-3fdb3879d9ff)] +[scriptable, uuid(735d0363-e219-4387-b5c6-72e800c3ea0b)] interface nsIX509CertDB : nsISupports { /** @@ -265,16 +264,6 @@ interface nsIX509CertDB : nsISupports { */ nsIX509Cert constructX509FromBase64(in string base64); - /* - * Obtain a reference to the appropriate service for recent - * bad certificates. May only be called on the main thread. - * - * @param isPrivate True if the service for certs for private connections - * is desired, false otherwise. - * @return The requested service. - */ - nsIRecentBadCerts getRecentBadCerts(in boolean isPrivate); - /** * Verifies the signature on the given JAR file to verify that it has a * valid signature. To be considered valid, there must be exactly one diff --git a/security/manager/ssl/src/Makefile.in b/security/manager/ssl/src/Makefile.in index 86028d2e646c..1ea14e33748b 100644 --- a/security/manager/ssl/src/Makefile.in +++ b/security/manager/ssl/src/Makefile.in @@ -74,7 +74,6 @@ CPPSRCS = \ PSMRunnable.cpp \ nsNSSVersion.cpp \ nsCertificatePrincipal.cpp \ - SharedSSLState.cpp \ $(NULL) ifdef MOZ_XUL diff --git a/security/manager/ssl/src/SSLServerCertVerification.cpp b/security/manager/ssl/src/SSLServerCertVerification.cpp index 6bac3a3abfc6..ae09139f1010 100644 --- a/security/manager/ssl/src/SSLServerCertVerification.cpp +++ b/security/manager/ssl/src/SSLServerCertVerification.cpp @@ -112,7 +112,6 @@ #include "nsIConsoleService.h" #include "PSMRunnable.h" #include "ScopedNSSTypes.h" -#include "SharedSSLState.h" #include "ssl.h" #include "secerr.h" @@ -239,15 +238,13 @@ class CertErrorRunnable : public SyncRunnableBase uint32_t collectedErrors, PRErrorCode errorCodeTrust, PRErrorCode errorCodeMismatch, - PRErrorCode errorCodeExpired, - uint32_t providerFlags) + PRErrorCode errorCodeExpired) : mFdForLogging(fdForLogging), mCert(cert), mInfoObject(infoObject), mDefaultErrorCodeToReport(defaultErrorCodeToReport), mCollectedErrors(collectedErrors), mErrorCodeTrust(errorCodeTrust), mErrorCodeMismatch(errorCodeMismatch), - mErrorCodeExpired(errorCodeExpired), - mProviderFlags(providerFlags) + mErrorCodeExpired(errorCodeExpired) { } @@ -264,7 +261,6 @@ private: const PRErrorCode mErrorCodeTrust; const PRErrorCode mErrorCodeMismatch; const PRErrorCode mErrorCodeExpired; - const uint32_t mProviderFlags; }; SSLServerCertVerificationResult * @@ -300,8 +296,12 @@ CertErrorRunnable::CheckCertOverrides() if (NS_SUCCEEDED(nsrv)) { nsCOMPtr sslSocketControl = do_QueryInterface( NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject)); + uint32_t flags = 0; + if (sslSocketControl) { + sslSocketControl->GetProviderFlags(&flags); + } nsrv = stss->IsStsHost(mInfoObject->GetHostName(), - mProviderFlags, + flags, &strictTransportSecurityEnabled); } if (NS_FAILED(nsrv)) { @@ -371,12 +371,8 @@ CertErrorRunnable::CheckCertOverrides() } } - nsCOMPtr certdb = do_GetService(NS_X509CERTDB_CONTRACTID); - nsCOMPtr recentBadCertsService; - if (certdb) { - bool isPrivate = mProviderFlags & nsISocketProvider::NO_PERMANENT_STORAGE; - certdb->GetRecentBadCerts(isPrivate, getter_AddRefs(recentBadCertsService)); - } + nsCOMPtr recentBadCertsService = + do_GetService(NS_RECENTBADCERTS_CONTRACTID); if (recentBadCertsService) { NS_ConvertUTF8toUTF16 hostWithPortStringUTF16(hostWithPortString); @@ -422,8 +418,7 @@ CertErrorRunnable * CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport, TransportSecurityInfo * infoObject, CERTCertificate * cert, - const void * fdForLogging, - uint32_t providerFlags) + const void * fdForLogging) { MOZ_ASSERT(infoObject); MOZ_ASSERT(cert); @@ -572,8 +567,7 @@ CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport, static_cast(nssCert.get()), infoObject, defaultErrorCodeToReport, collected_errors, errorCodeTrust, - errorCodeMismatch, errorCodeExpired, - providerFlags); + errorCodeMismatch, errorCodeExpired); } // When doing async cert processing, we dispatch one of these runnables to the @@ -613,29 +607,25 @@ public: // Must be called only on the socket transport thread static SECStatus Dispatch(const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * serverCert, - uint32_t providerFlags); + CERTCertificate * serverCert); private: NS_DECL_NSIRUNNABLE // Must be called only on the socket transport thread SSLServerCertVerificationJob(const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * cert, - uint32_t providerFlags); + CERTCertificate * cert); const void * const mFdForLogging; const RefPtr mInfoObject; const ScopedCERTCertificate mCert; - const uint32_t mProviderFlags; }; SSLServerCertVerificationJob::SSLServerCertVerificationJob( const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * cert, uint32_t providerFlags) + CERTCertificate * cert) : mFdForLogging(fdForLogging) , mInfoObject(infoObject) , mCert(CERT_DupCertificate(cert)) - , mProviderFlags(providerFlags) { } @@ -987,8 +977,7 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert) /*static*/ SECStatus SSLServerCertVerificationJob::Dispatch(const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * serverCert, - uint32_t providerFlags) + CERTCertificate * serverCert) { // Runs on the socket transport thread if (!infoObject || !serverCert) { @@ -998,8 +987,7 @@ SSLServerCertVerificationJob::Dispatch(const void * fdForLogging, } RefPtr job( - new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert, - providerFlags)); + new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert)); nsresult nrv; if (!gCertVerificationThreadPool) { @@ -1054,7 +1042,7 @@ SSLServerCertVerificationJob::Run() error = PR_GetError(); if (error != 0) { RefPtr runnable(CreateCertErrorRunnable( - error, mInfoObject, mCert, mFdForLogging, mProviderFlags)); + error, mInfoObject, mCert, mFdForLogging)); if (!runnable) { // CreateCertErrorRunnable set a new error code error = PR_GetError(); @@ -1147,20 +1135,15 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) PR_SetError(PR_UNKNOWN_ERROR, 0); return SECFailure; } - - uint32_t providerFlags = 0; - socketInfo->GetProviderFlags(&providerFlags); - + if (onSTSThread) { - // We *must* do certificate verification on a background thread because // we need the socket transport thread to be free for our OCSP requests, // and we *want* to do certificate verification on a background thread // because of the performance benefits of doing so. socketInfo->SetCertVerificationWaiting(); SECStatus rv = SSLServerCertVerificationJob::Dispatch( - static_cast(fd), socketInfo, serverCert, - providerFlags); + static_cast(fd), socketInfo, serverCert); return rv; } @@ -1177,7 +1160,7 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) if (error != 0) { RefPtr runnable(CreateCertErrorRunnable( error, socketInfo, serverCert, - static_cast(fd), providerFlags)); + static_cast(fd))); if (!runnable) { // CreateCertErrorRunnable sets a new error code when it fails error = PR_GetError(); diff --git a/security/manager/ssl/src/SharedSSLState.cpp b/security/manager/ssl/src/SharedSSLState.cpp deleted file mode 100644 index 6a4e7b1a493a..000000000000 --- a/security/manager/ssl/src/SharedSSLState.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "SharedSSLState.h" -#include "nsClientAuthRemember.h" -#include "nsComponentManagerUtils.h" -#include "nsICertOverrideService.h" -#include "nsIObserverService.h" -#include "mozilla/Services.h" -#include "nsThreadUtils.h" -#include "nsCRT.h" - -namespace mozilla { -namespace psm { - -namespace { -class PrivateBrowsingObserver : public nsIObserver { -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - PrivateBrowsingObserver(SharedSSLState* aOwner) : mOwner(aOwner) {} - virtual ~PrivateBrowsingObserver() {} -private: - SharedSSLState* mOwner; -}; - -SharedSSLState* gPublicState; -SharedSSLState* gPrivateState; -} // anonymous namespace - -NS_IMPL_ISUPPORTS1(PrivateBrowsingObserver, nsIObserver) - -NS_IMETHODIMP -PrivateBrowsingObserver::Observe(nsISupports *aSubject, - const char *aTopic, - const PRUnichar *aData) -{ - if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { - mOwner->ResetStoredData(); - } - return NS_OK; -} - -SharedSSLState::SharedSSLState() -: mClientAuthRemember(new nsClientAuthRememberService) -{ - mIOLayerHelpers.Init(); - mClientAuthRemember->Init(); -} - -void -SharedSSLState::NotePrivateBrowsingStatus() -{ - mObserver = new PrivateBrowsingObserver(this); - nsCOMPtr obsSvc = mozilla::services::GetObserverService(); - obsSvc->AddObserver(mObserver, "last-pb-context-exited", false); -} - -void -SharedSSLState::ResetStoredData() -{ - mClientAuthRemember->ClearRememberedDecisions(); - mIOLayerHelpers.clearStoredData(); -} - -/*static*/ void -SharedSSLState::GlobalInit() -{ - MOZ_ASSERT(NS_IsMainThread(), "Not on main thread"); - gPublicState = new SharedSSLState(); - gPrivateState = new SharedSSLState(); - gPrivateState->NotePrivateBrowsingStatus(); -} - -/*static*/ void -SharedSSLState::GlobalCleanup() -{ - MOZ_ASSERT(NS_IsMainThread(), "Not on main thread"); - - gPrivateState->Cleanup(); - delete gPrivateState; - gPrivateState = nullptr; - - gPublicState->Cleanup(); - delete gPublicState; - gPublicState = nullptr; -} - -void -SharedSSLState::Cleanup() -{ - mIOLayerHelpers.Cleanup(); -} - -SharedSSLState* -PublicSSLState() -{ - return gPublicState; -} - -SharedSSLState* -PrivateSSLState() -{ - return gPrivateState; -} - -} // namespace psm -} // namespace mozilla diff --git a/security/manager/ssl/src/SharedSSLState.h b/security/manager/ssl/src/SharedSSLState.h deleted file mode 100644 index 7a89fbca243b..000000000000 --- a/security/manager/ssl/src/SharedSSLState.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef SharedSSLState_h -#define SharedSSLState_h - -#include "mozilla/RefPtr.h" -#include "nsNSSIOLayer.h" - -class nsClientAuthRememberService; -class nsIRecentBadCertsService; -class nsICertOverrideService; -class nsIObserver; - -namespace mozilla { -namespace psm { - -class SharedSSLState { -public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedSSLState) - SharedSSLState(); - - static void GlobalInit(); - static void GlobalCleanup(); - - nsClientAuthRememberService* GetClientAuthRememberService() { - return mClientAuthRemember; - } - - nsSSLIOLayerHelpers& IOLayerHelpers() { - return mIOLayerHelpers; - } - - void ResetStoredData(); - void NotePrivateBrowsingStatus(); - -private: - void Cleanup(); - - nsCOMPtr mObserver; - RefPtr mClientAuthRemember; - nsSSLIOLayerHelpers mIOLayerHelpers; -}; - -SharedSSLState* PublicSSLState(); -SharedSSLState* PrivateSSLState(); - -} // namespace psm -} // namespace mozilla - -#endif diff --git a/security/manager/ssl/src/nsClientAuthRemember.cpp b/security/manager/ssl/src/nsClientAuthRemember.cpp index ad595810da3a..b3ac013b4e26 100644 --- a/security/manager/ssl/src/nsClientAuthRemember.cpp +++ b/security/manager/ssl/src/nsClientAuthRemember.cpp @@ -21,10 +21,8 @@ #include "pk11pub.h" #include "certdb.h" #include "sechash.h" -#include "SharedSSLState.h" using namespace mozilla; -using namespace mozilla::psm; NS_IMPL_THREADSAFE_ISUPPORTS2(nsClientAuthRememberService, nsIObserver, @@ -82,16 +80,6 @@ void nsClientAuthRememberService::ClearRememberedDecisions() RemoveAllFromMemory(); } -void nsClientAuthRememberService::ClearAllRememberedDecisions() -{ - RefPtr svc = - PublicSSLState()->GetClientAuthRememberService(); - svc->ClearRememberedDecisions(); - - svc = PrivateSSLState()->GetClientAuthRememberService(); - svc->ClearRememberedDecisions(); -} - void nsClientAuthRememberService::RemoveAllFromMemory() { diff --git a/security/manager/ssl/src/nsClientAuthRemember.h b/security/manager/ssl/src/nsClientAuthRemember.h index 161303f07576..35a8a21b47a5 100644 --- a/security/manager/ssl/src/nsClientAuthRemember.h +++ b/security/manager/ssl/src/nsClientAuthRemember.h @@ -128,7 +128,6 @@ public: nsACString & aCertDBKey, bool *_retval); void ClearRememberedDecisions(); - static void ClearAllRememberedDecisions(); protected: mozilla::ReentrantMonitor monitor; diff --git a/security/manager/ssl/src/nsNSSCallbacks.cpp b/security/manager/ssl/src/nsNSSCallbacks.cpp index 02188b78493d..d7809989c7a6 100644 --- a/security/manager/ssl/src/nsNSSCallbacks.cpp +++ b/security/manager/ssl/src/nsNSSCallbacks.cpp @@ -23,7 +23,6 @@ #include "nsIConsoleService.h" #include "nsIHttpChannelInternal.h" #include "nsCRT.h" -#include "SharedSSLState.h" #include "ssl.h" #include "sslproto.h" @@ -842,8 +841,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { // If the handshake completed, then we know the site is TLS tolerant (if this // was a TLS connection). - nsSSLIOLayerHelpers& ioLayerHelpers = infoObject->SharedState().IOLayerHelpers(); - ioLayerHelpers.rememberTolerantSite(infoObject); + nsSSLIOLayerHelpers::rememberTolerantSite(infoObject); if (SECSuccess != SSL_SecurityStatus(fd, &sslStatus, &cipherName, &keyLength, &encryptBits, &signer, nullptr)) { @@ -861,7 +859,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { if (SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn, &siteSupportsSafeRenego) != SECSuccess || !siteSupportsSafeRenego) { - bool wantWarning = (ioLayerHelpers.getWarnLevelMissingRFC5746() > 0); + bool wantWarning = (nsSSLIOLayerHelpers::getWarnLevelMissingRFC5746() > 0); nsCOMPtr console; if (infoObject && wantWarning) { @@ -877,7 +875,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { console->LogStringMessage(msg.get()); } } - if (ioLayerHelpers.treatUnsafeNegotiationAsBroken()) { + if (nsSSLIOLayerHelpers::treatUnsafeNegotiationAsBroken()) { secStatus = nsIWebProgressListener::STATE_IS_BROKEN; } } diff --git a/security/manager/ssl/src/nsNSSCertificateDB.cpp b/security/manager/ssl/src/nsNSSCertificateDB.cpp index b3314216a320..912ced9a8d68 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.cpp +++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp @@ -31,8 +31,6 @@ #include "nsIPrompt.h" #include "nsThreadUtils.h" #include "ScopedNSSTypes.h" -#include "nsIObserverService.h" -#include "nsRecentBadCerts.h" #include "nspr.h" #include "certdb.h" @@ -1646,22 +1644,3 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval) NS_ADDREF(*_retval); return NS_OK; } - -NS_IMETHODIMP -nsNSSCertificateDB::GetRecentBadCerts(bool isPrivate, nsIRecentBadCerts** result) -{ - MOZ_ASSERT(NS_IsMainThread(), "RecentBadCerts should only be obtained on the main thread"); - if (isPrivate) { - if (!mPrivateRecentBadCerts) { - mPrivateRecentBadCerts = new nsRecentBadCerts; - mPrivateRecentBadCerts->InitPrivateBrowsingObserver(); - } - NS_ADDREF(*result = mPrivateRecentBadCerts); - } else { - if (!mPublicRecentBadCerts) { - mPublicRecentBadCerts = new nsRecentBadCerts; - } - NS_ADDREF(*result = mPublicRecentBadCerts); - } - return NS_OK; -} diff --git a/security/manager/ssl/src/nsNSSCertificateDB.h b/security/manager/ssl/src/nsNSSCertificateDB.h index c821322fbcb4..efdbff80d339 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.h +++ b/security/manager/ssl/src/nsNSSCertificateDB.h @@ -7,12 +7,10 @@ #include "nsIX509CertDB.h" #include "nsIX509CertDB2.h" -#include "mozilla/RefPtr.h" #include "certt.h" class nsCString; class nsIArray; -class nsRecentBadCerts; class nsNSSCertificateDB : public nsIX509CertDB, public nsIX509CertDB2 { @@ -50,9 +48,6 @@ private: uint32_t length); nsresult handleCACertDownload(nsIArray *x509Certs, nsIInterfaceRequestor *ctx); - - mozilla::RefPtr mPublicRecentBadCerts; - mozilla::RefPtr mPrivateRecentBadCerts; }; #define NS_X509CERTDB_CID { /* fb0bbc5c-452e-4783-b32c-80124693d871 */ \ diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index aabe6fab9789..486a3e1f907b 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -60,7 +60,6 @@ #include "nsSmartCardEvent.h" #include "nsIKeyModule.h" #include "ScopedNSSTypes.h" -#include "SharedSSLState.h" #include "nss.h" #include "pk11func.h" @@ -401,7 +400,7 @@ nsNSSComponent::~nsNSSComponent() // All cleanup code requiring services needs to happen in xpcom_shutdown ShutdownNSS(); - SharedSSLState::GlobalCleanup(); + nsSSLIOLayerHelpers::Cleanup(); RememberCertErrorsTable::Cleanup(); --mInstanceCount; delete mShutdownObjectList; @@ -1861,6 +1860,9 @@ nsNSSComponent::ShutdownNSS() ShutdownSmartCardThreads(); SSL_ClearSessionCache(); + if (mClientAuthRememberService) { + mClientAuthRememberService->ClearRememberedDecisions(); + } UnloadLoadableRoots(); CleanupIdentityInfo(); PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("evaporating psm resources\n")); @@ -1931,8 +1933,27 @@ nsNSSComponent::Init() } RememberCertErrorsTable::Init(); - SharedSSLState::GlobalInit(); + nsSSLIOLayerHelpers::Init(); + char *unrestricted_hosts=nullptr; + mPrefBranch->GetCharPref("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts); + if (unrestricted_hosts) { + nsSSLIOLayerHelpers::setRenegoUnrestrictedSites(nsDependentCString(unrestricted_hosts)); + nsMemory::Free(unrestricted_hosts); + unrestricted_hosts=nullptr; + } + + bool enabled = false; + mPrefBranch->GetBoolPref("security.ssl.treat_unsafe_negotiation_as_broken", &enabled); + nsSSLIOLayerHelpers::setTreatUnsafeNegotiationAsBroken(enabled); + + int32_t warnLevel = 1; + mPrefBranch->GetIntPref("security.ssl.warn_missing_rfc5746", &warnLevel); + nsSSLIOLayerHelpers::setWarnLevelMissingRFC5746(warnLevel); + mClientAuthRememberService = new nsClientAuthRememberService; + if (mClientAuthRememberService) + mClientAuthRememberService->Init(); + createBackgroundThreads(); if (!mCertVerificationThread) { @@ -2250,6 +2271,20 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, 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=nullptr; + 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.ssl.warn_missing_rfc5746")) { + int32_t warnLevel = 1; + mPrefBranch->GetIntPref("security.ssl.warn_missing_rfc5746", &warnLevel); + nsSSLIOLayerHelpers::setWarnLevelMissingRFC5746(warnLevel); #ifdef SSL_ENABLE_FALSE_START // Requires NSS 3.12.8 } else if (prefName.Equals("security.ssl.enable_false_start")) { mPrefBranch->GetBoolPref("security.ssl.enable_false_start", &enabled); @@ -2352,7 +2387,9 @@ nsresult nsNSSComponent::LogoutAuthenticatedPK11() 0); } - nsClientAuthRememberService::ClearAllRememberedDecisions(); + if (mClientAuthRememberService) { + mClientAuthRememberService->ClearRememberedDecisions(); + } return mShutdownObjectList->doPK11Logout(); } @@ -2531,6 +2568,14 @@ nsNSSComponent::DoProfileChangeNetRestore() mIsNetworkDown = false; } +NS_IMETHODIMP +nsNSSComponent::GetClientAuthRememberService(nsClientAuthRememberService **cars) +{ + NS_ENSURE_ARG_POINTER(cars); + NS_IF_ADDREF(*cars = mClientAuthRememberService); + return NS_OK; +} + NS_IMETHODIMP nsNSSComponent::IsNSSInitialized(bool *initialized) { diff --git a/security/manager/ssl/src/nsNSSComponent.h b/security/manager/ssl/src/nsNSSComponent.h index b47b989c21f5..2391d95565d2 100644 --- a/security/manager/ssl/src/nsNSSComponent.h +++ b/security/manager/ssl/src/nsNSSComponent.h @@ -154,6 +154,8 @@ class NS_NO_VTABLE nsINSSComponent : public nsISupports { NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token) = 0; + NS_IMETHOD GetClientAuthRememberService(nsClientAuthRememberService **cars) = 0; + NS_IMETHOD EnsureIdentityInfoLoaded() = 0; NS_IMETHOD IsNSSInitialized(bool *initialized) = 0; @@ -257,6 +259,7 @@ public: NS_IMETHOD ShutdownSmartCardThread(SECMODModule *module); NS_IMETHOD PostEvent(const nsAString &eventType, const nsAString &token); NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token); + NS_IMETHOD GetClientAuthRememberService(nsClientAuthRememberService **cars); NS_IMETHOD EnsureIdentityInfoLoaded(); NS_IMETHOD IsNSSInitialized(bool *initialized); @@ -324,6 +327,7 @@ private: nsCertVerificationThread *mCertVerificationThread; nsNSSHttpInterface mHttpForNSS; + mozilla::RefPtr mClientAuthRememberService; mozilla::RefPtr mDefaultCERTValInParam; mozilla::RefPtr mDefaultCERTValInParamLocalOnly; diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index 8e84c9647b2b..7f52d25af224 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -28,8 +28,6 @@ #include "nsIConsoleService.h" #include "PSMRunnable.h" #include "ScopedNSSTypes.h" -#include "SharedSSLState.h" -#include "mozilla/Preferences.h" #include "ssl.h" #include "secerr.h" @@ -65,10 +63,9 @@ typedef enum {ASK, AUTO} SSM_UserCertChoice; extern PRLogModuleInfo* gPIPNSSLog; #endif -nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags) +nsNSSSocketInfo::nsNSSSocketInfo(uint32_t providerFlags) : mFd(nullptr), mCertVerificationState(before_cert_verification), - mSharedState(aState), mForSTARTTLS(false), mSSL3Enabled(false), mTLSEnabled(false), @@ -460,11 +457,6 @@ void nsNSSSocketInfo::SetAllowTLSIntoleranceTimeout(bool aAllow) mAllowTLSIntoleranceTimeout = aAllow; } -SharedSSLState& nsNSSSocketInfo::SharedState() -{ - return mSharedState; -} - bool nsNSSSocketInfo::HandshakeTimeout() { if (!mAllowTLSIntoleranceTimeout) @@ -922,8 +914,7 @@ int32_t checkHandshake(int32_t bytesTransfered, bool wasReading, if (!wantRetry // no decision yet && isTLSIntoleranceError(err, socketInfo->GetHasCleartextPhase())) { - nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers(); - wantRetry = helpers.rememberPossibleTLSProblemSite(socketInfo); + wantRetry = nsSSLIOLayerHelpers::rememberPossibleTLSProblemSite(socketInfo); } } @@ -951,8 +942,8 @@ int32_t checkHandshake(int32_t bytesTransfered, bool wasReading, if (!wantRetry // no decision yet && !socketInfo->GetHasCleartextPhase()) // mirror PR_CONNECT_RESET_ERROR treament { - nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers(); - wantRetry = helpers.rememberPossibleTLSProblemSite(socketInfo); + wantRetry = + nsSSLIOLayerHelpers::rememberPossibleTLSProblemSite(socketInfo); } } } @@ -1040,16 +1031,12 @@ nsSSLIOLayerPoll(PRFileDesc * fd, int16_t in_flags, int16_t *out_flags) bool nsSSLIOLayerHelpers::nsSSLIOLayerInitialized = false; PRDescIdentity nsSSLIOLayerHelpers::nsSSLIOLayerIdentity; PRIOMethods nsSSLIOLayerHelpers::nsSSLIOLayerMethods; - -nsSSLIOLayerHelpers::nsSSLIOLayerHelpers() -: mutex(nullptr) -, mTLSIntolerantSites(nullptr) -, mTLSTolerantSites(nullptr) -, mRenegoUnrestrictedSites(nullptr) -, mTreatUnsafeNegotiationAsBroken(false) -, mWarnLevelMissingRFC5746(1) -{ -} +Mutex *nsSSLIOLayerHelpers::mutex = nullptr; +nsTHashtable *nsSSLIOLayerHelpers::mTLSIntolerantSites = nullptr; +nsTHashtable *nsSSLIOLayerHelpers::mTLSTolerantSites = nullptr; +nsTHashtable *nsSSLIOLayerHelpers::mRenegoUnrestrictedSites = nullptr; +bool nsSSLIOLayerHelpers::mTreatUnsafeNegotiationAsBroken = false; +int32_t nsSSLIOLayerHelpers::mWarnLevelMissingRFC5746 = 1; static int _PSM_InvalidInt(void) { @@ -1203,53 +1190,6 @@ static int64_t PSMAvailable64(void) return -1; } -namespace { -class PrefObserver : public nsIObserver { -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - PrefObserver(nsSSLIOLayerHelpers* aOwner) : mOwner(aOwner) {} - virtual ~PrefObserver() {} -private: - nsSSLIOLayerHelpers* mOwner; -}; -} // namespace anonymous - -NS_IMPL_THREADSAFE_ISUPPORTS1(PrefObserver, nsIObserver) - -NS_IMETHODIMP -PrefObserver::Observe(nsISupports *aSubject, const char *aTopic, - const PRUnichar *someData) -{ - if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) { - NS_ConvertUTF16toUTF8 prefName(someData); - - if (prefName.Equals("security.ssl.renego_unrestricted_hosts")) { - nsCString unrestricted_hosts; - Preferences::GetCString("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts); - if (!unrestricted_hosts.IsEmpty()) { - mOwner->setRenegoUnrestrictedSites(unrestricted_hosts); - } - } else if (prefName.Equals("security.ssl.treat_unsafe_negotiation_as_broken")) { - bool enabled; - Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", &enabled); - mOwner->setTreatUnsafeNegotiationAsBroken(enabled); - } else if (prefName.Equals("security.ssl.warn_missing_rfc5746")) { - int32_t warnLevel = 1; - Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel); - mOwner->setWarnLevelMissingRFC5746(warnLevel); - } - } - return NS_OK; -} - -nsSSLIOLayerHelpers::~nsSSLIOLayerHelpers() -{ - Preferences::RemoveObserver(mPrefObserver, "security.ssl.renego_unrestricted_hosts"); - Preferences::RemoveObserver(mPrefObserver, "security.ssl.treat_unsafe_negotiation_as_broken"); - Preferences::RemoveObserver(mPrefObserver, "security.ssl.warn_missing_rfc5746"); -} - nsresult nsSSLIOLayerHelpers::Init() { if (!nsSSLIOLayerInitialized) { @@ -1304,50 +1244,23 @@ nsresult nsSSLIOLayerHelpers::Init() mRenegoUnrestrictedSites = new nsTHashtable(); mRenegoUnrestrictedSites->Init(1); - nsCString unrestricted_hosts; - Preferences::GetCString("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts); - if (!unrestricted_hosts.IsEmpty()) { - setRenegoUnrestrictedSites(unrestricted_hosts); - } - - bool enabled = false; - Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", &enabled); - setTreatUnsafeNegotiationAsBroken(enabled); - - int32_t warnLevel = 1; - Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel); - setWarnLevelMissingRFC5746(warnLevel); - - mPrefObserver = new PrefObserver(this); - Preferences::AddStrongObserver(mPrefObserver, - "security.ssl.renego_unrestricted_hosts"); - Preferences::AddStrongObserver(mPrefObserver, - "security.ssl.treat_unsafe_negotiation_as_broken"); - Preferences::AddStrongObserver(mPrefObserver, - "security.ssl.warn_missing_rfc5746"); - + mTreatUnsafeNegotiationAsBroken = false; + return NS_OK; } -void nsSSLIOLayerHelpers::clearStoredData() -{ - mRenegoUnrestrictedSites->Clear(); - mTLSTolerantSites->Clear(); - mTLSIntolerantSites->Clear(); -} - void nsSSLIOLayerHelpers::addIntolerantSite(const nsCString &str) { MutexAutoLock lock(*mutex); // Remember intolerant site only if it is not known as tolerant if (!mTLSTolerantSites->Contains(str)) - mTLSIntolerantSites->PutEntry(str); + nsSSLIOLayerHelpers::mTLSIntolerantSites->PutEntry(str); } void nsSSLIOLayerHelpers::removeIntolerantSite(const nsCString &str) { MutexAutoLock lock(*mutex); - mTLSIntolerantSites->RemoveEntry(str); + nsSSLIOLayerHelpers::mTLSIntolerantSites->RemoveEntry(str); } bool nsSSLIOLayerHelpers::isKnownAsIntolerantSite(const nsCString &str) @@ -2010,7 +1923,6 @@ void ClientAuthDataRunnable::RunOnTargetThread() SSM_UserCertChoice certChoice; int32_t NumberOfCerts = 0; void * wincx = mSocketInfo; - nsresult rv; /* create caNameStrings */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); @@ -2112,14 +2024,19 @@ void ClientAuthDataRunnable::RunOnTargetThread() nsXPIDLCString hostname; mSocketInfo->GetHostName(getter_Copies(hostname)); - RefPtr cars = - mSocketInfo->SharedState().GetClientAuthRememberService(); + nsresult rv; + NS_DEFINE_CID(nssComponentCID, NS_NSSCOMPONENT_CID); + nsCOMPtr nssComponent(do_GetService(nssComponentCID, &rv)); + RefPtr cars; + if (nssComponent) { + nssComponent->GetClientAuthRememberService(byRef(cars)); + } bool hasRemembered = false; nsCString rememberedDBKey; if (cars) { bool found; - rv = cars->HasRememberedDecision(hostname, mServerCert, + nsresult rv = cars->HasRememberedDecision(hostname, mServerCert, rememberedDBKey, &found); if (NS_SUCCEEDED(rv) && found) { hasRemembered = true; @@ -2302,9 +2219,9 @@ if (!hasRemembered) } /* Throw up the client auth dialog and get back the index of the selected cert */ - nsresult rv = getNSSDialogs((void**)&dialogs, - NS_GET_IID(nsIClientAuthDialogs), - NS_CLIENTAUTHDIALOGS_CONTRACTID); + rv = getNSSDialogs((void**)&dialogs, + NS_GET_IID(nsIClientAuthDialogs), + NS_CLIENTAUTHDIALOGS_CONTRACTID); if (NS_FAILED(rv)) { NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList); @@ -2463,7 +2380,7 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, nsAutoCString key; key = nsDependentCString(host) + NS_LITERAL_CSTRING(":") + nsPrintfCString("%d", port); - if (infoObject->SharedState().IOLayerHelpers().isKnownAsIntolerantSite(key)) { + if (nsSSLIOLayerHelpers::isKnownAsIntolerantSite(key)) { if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_TLS, false)) return NS_ERROR_FAILURE; @@ -2490,9 +2407,8 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, if (SECSuccess != SSL_OptionSet(fd, SSL_HANDSHAKE_AS_CLIENT, true)) { return NS_ERROR_FAILURE; } - - nsSSLIOLayerHelpers& ioHelpers = infoObject->SharedState().IOLayerHelpers(); - if (ioHelpers.isRenegoUnrestrictedSite(nsDependentCString(host))) { + + if (nsSSLIOLayerHelpers::isRenegoUnrestrictedSite(nsDependentCString(host))) { if (SECSuccess != SSL_OptionSet(fd, SSL_REQUIRE_SAFE_NEGOTIATION, false)) { return NS_ERROR_FAILURE; } @@ -2534,9 +2450,7 @@ nsSSLIOLayerAddToSocket(int32_t family, nsresult rv; PRStatus stat; - SharedSSLState* sharedState = - providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE ? PrivateSSLState() : PublicSSLState(); - nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(*sharedState, providerFlags); + nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(providerFlags); if (!infoObject) return NS_ERROR_FAILURE; NS_ADDREF(infoObject); diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h index 2f25e71d04c8..4ee3bd9b8aac 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.h +++ b/security/manager/ssl/src/nsNSSIOLayer.h @@ -15,20 +15,12 @@ #include "nsTHashtable.h" #include "mozilla/TimeStamp.h" -namespace mozilla { -namespace psm { -class SharedSSLState; -} -} - -class nsIObserver; - class nsNSSSocketInfo : public mozilla::psm::TransportSecurityInfo, public nsISSLSocketControl, public nsIClientAuthUserDecision { public: - nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags); + nsNSSSocketInfo(uint32_t providerFlags); NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSISSLSOCKETCONTROL @@ -64,8 +56,6 @@ public: bool GetJoined() { return mJoined; } void SetSentClientCert() { mSentClientCert = true; } - mozilla::psm::SharedSSLState& SharedState(); - // XXX: These are only used on for diagnostic purposes enum CertVerificationState { before_cert_verification, @@ -93,7 +83,6 @@ private: CertVerificationState mCertVerificationState; - mozilla::psm::SharedSSLState& mSharedState; bool mForSTARTTLS; bool mSSL3Enabled; bool mTLSEnabled; @@ -120,44 +109,37 @@ private: class nsSSLIOLayerHelpers { public: - nsSSLIOLayerHelpers(); - ~nsSSLIOLayerHelpers(); - - nsresult Init(); - void Cleanup(); + static nsresult Init(); + static void Cleanup(); static bool nsSSLIOLayerInitialized; static PRDescIdentity nsSSLIOLayerIdentity; static PRIOMethods nsSSLIOLayerMethods; - mozilla::Mutex *mutex; - nsTHashtable *mTLSIntolerantSites; - nsTHashtable *mTLSTolerantSites; + static mozilla::Mutex *mutex; + static nsTHashtable *mTLSIntolerantSites; + static nsTHashtable *mTLSTolerantSites; - nsTHashtable *mRenegoUnrestrictedSites; - bool mTreatUnsafeNegotiationAsBroken; - int32_t mWarnLevelMissingRFC5746; + static nsTHashtable *mRenegoUnrestrictedSites; + static bool mTreatUnsafeNegotiationAsBroken; + static int32_t mWarnLevelMissingRFC5746; - void setTreatUnsafeNegotiationAsBroken(bool broken); - bool treatUnsafeNegotiationAsBroken(); + static void setTreatUnsafeNegotiationAsBroken(bool broken); + static bool treatUnsafeNegotiationAsBroken(); - void setWarnLevelMissingRFC5746(int32_t level); - int32_t getWarnLevelMissingRFC5746(); + static void setWarnLevelMissingRFC5746(int32_t level); + static int32_t getWarnLevelMissingRFC5746(); static void getSiteKey(nsNSSSocketInfo *socketInfo, nsCSubstring &key); - bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo); - void rememberTolerantSite(nsNSSSocketInfo *socketInfo); + static bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo); + static void rememberTolerantSite(nsNSSSocketInfo *socketInfo); - void addIntolerantSite(const nsCString &str); - void removeIntolerantSite(const nsCString &str); - bool isKnownAsIntolerantSite(const nsCString &str); + static void addIntolerantSite(const nsCString &str); + static void removeIntolerantSite(const nsCString &str); + static bool isKnownAsIntolerantSite(const nsCString &str); - void setRenegoUnrestrictedSites(const nsCString &str); - bool isRenegoUnrestrictedSite(const nsCString &str); - - void clearStoredData(); -private: - nsCOMPtr mPrefObserver; + static void setRenegoUnrestrictedSites(const nsCString &str); + static bool isRenegoUnrestrictedSite(const nsCString &str); }; nsresult nsSSLIOLayerNewSocket(int32_t family, diff --git a/security/manager/ssl/src/nsNSSModule.cpp b/security/manager/ssl/src/nsNSSModule.cpp index 568c2be52ae5..90debb592819 100644 --- a/security/manager/ssl/src/nsNSSModule.cpp +++ b/security/manager/ssl/src/nsNSSModule.cpp @@ -38,6 +38,7 @@ #include "nsDataSignatureVerifier.h" #include "nsCertOverrideService.h" #include "nsRandomGenerator.h" +#include "nsRecentBadCerts.h" #include "nsSSLStatus.h" #include "TransportSecurityInfo.h" #include "NSSErrorsService.h" @@ -203,6 +204,7 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsKeyObjectFactory) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsDataSignatureVerifier) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsCertOverrideService, Init) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsRandomGenerator) +NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsRecentBadCertsService, Init) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, nsSSLStatus) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, TransportSecurityInfo) @@ -241,6 +243,7 @@ NS_DEFINE_NAMED_CID(NS_KEYMODULEOBJECTFACTORY_CID); NS_DEFINE_NAMED_CID(NS_DATASIGNATUREVERIFIER_CID); NS_DEFINE_NAMED_CID(NS_CERTOVERRIDE_CID); NS_DEFINE_NAMED_CID(NS_RANDOMGENERATOR_CID); +NS_DEFINE_NAMED_CID(NS_RECENTBADCERTS_CID); NS_DEFINE_NAMED_CID(NS_SSLSTATUS_CID); NS_DEFINE_NAMED_CID(TRANSPORTSECURITYINFO_CID); NS_DEFINE_NAMED_CID(NS_NSSERRORSSERVICE_CID); @@ -278,6 +281,7 @@ static const mozilla::Module::CIDEntry kNSSCIDs[] = { { &kNS_DATASIGNATUREVERIFIER_CID, false, nullptr, nsDataSignatureVerifierConstructor }, { &kNS_CERTOVERRIDE_CID, false, nullptr, nsCertOverrideServiceConstructor }, { &kNS_RANDOMGENERATOR_CID, false, nullptr, nsRandomGeneratorConstructor }, + { &kNS_RECENTBADCERTS_CID, false, nullptr, nsRecentBadCertsServiceConstructor }, { &kNS_SSLSTATUS_CID, false, nullptr, nsSSLStatusConstructor }, { &kTRANSPORTSECURITYINFO_CID, false, nullptr, TransportSecurityInfoConstructor }, { &kNS_NSSERRORSSERVICE_CID, false, nullptr, NSSErrorsServiceConstructor }, @@ -320,6 +324,7 @@ static const mozilla::Module::ContractIDEntry kNSSContracts[] = { { NS_DATASIGNATUREVERIFIER_CONTRACTID, &kNS_DATASIGNATUREVERIFIER_CID }, { NS_CERTOVERRIDE_CONTRACTID, &kNS_CERTOVERRIDE_CID }, { NS_RANDOMGENERATOR_CONTRACTID, &kNS_RANDOMGENERATOR_CID }, + { NS_RECENTBADCERTS_CONTRACTID, &kNS_RECENTBADCERTS_CID }, { nullptr } }; diff --git a/security/manager/ssl/src/nsRecentBadCerts.cpp b/security/manager/ssl/src/nsRecentBadCerts.cpp index cae4fd1fb61c..de378b9e9bb5 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.cpp +++ b/security/manager/ssl/src/nsRecentBadCerts.cpp @@ -6,9 +6,7 @@ #include "nsRecentBadCerts.h" #include "nsIX509Cert.h" -#include "nsIObserverService.h" #include "mozilla/RefPtr.h" -#include "mozilla/Services.h" #include "nsSSLStatus.h" #include "nsCOMPtr.h" #include "nsNSSCertificate.h" @@ -22,41 +20,28 @@ using namespace mozilla; -NS_IMPL_THREADSAFE_ISUPPORTS2(nsRecentBadCerts, - nsIRecentBadCerts, - nsIObserver) +NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCertsService, + nsIRecentBadCertsService) -nsRecentBadCerts::nsRecentBadCerts() -:monitor("nsRecentBadCerts.monitor") +nsRecentBadCertsService::nsRecentBadCertsService() +:monitor("nsRecentBadCertsService.monitor") ,mNextStorePosition(0) { } -nsRecentBadCerts::~nsRecentBadCerts() +nsRecentBadCertsService::~nsRecentBadCertsService() { } -void -nsRecentBadCerts::InitPrivateBrowsingObserver() +nsresult +nsRecentBadCertsService::Init() { - nsCOMPtr obsSvc = mozilla::services::GetObserverService(); - obsSvc->AddObserver(this, "last-pb-context-exited", false); -} - -NS_IMETHODIMP -nsRecentBadCerts::Observe(nsISupports *aSubject, - const char *aTopic, - const PRUnichar *aData) -{ - if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { - ResetStoredCerts(); - } return NS_OK; } NS_IMETHODIMP -nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort, - nsISSLStatus **aStatus) +nsRecentBadCertsService::GetRecentBadCert(const nsAString & aHostNameWithPort, + nsISSLStatus **aStatus) { NS_ENSURE_ARG_POINTER(aStatus); if (!aHostNameWithPort.Length()) @@ -116,7 +101,7 @@ nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort, } NS_IMETHODIMP -nsRecentBadCerts::AddBadCert(const nsAString &hostWithPort, +nsRecentBadCertsService::AddBadCert(const nsAString &hostWithPort, nsISSLStatus *aStatus) { NS_ENSURE_ARG(aStatus); @@ -161,13 +146,3 @@ nsRecentBadCerts::AddBadCert(const nsAString &hostWithPort, return NS_OK; } - -NS_IMETHODIMP -nsRecentBadCerts::ResetStoredCerts() -{ - for (size_t i = 0; i < const_recently_seen_list_size; ++i) { - RecentBadCert &entry = mCerts[i]; - entry.Clear(); - } - return NS_OK; -} diff --git a/security/manager/ssl/src/nsRecentBadCerts.h b/security/manager/ssl/src/nsRecentBadCerts.h index d815482d3794..e82f780c252a 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.h +++ b/security/manager/ssl/src/nsRecentBadCerts.h @@ -11,7 +11,6 @@ #include "mozilla/ReentrantMonitor.h" #include "nsIRecentBadCertsService.h" -#include "nsIObserver.h" #include "nsTHashtable.h" #include "nsString.h" #include "cert.h" @@ -55,18 +54,16 @@ private: RecentBadCert &operator=(const RecentBadCert &other) MOZ_DELETE; }; -class nsRecentBadCerts MOZ_FINAL : public nsIRecentBadCerts - , public nsIObserver +class nsRecentBadCertsService MOZ_FINAL : public nsIRecentBadCertsService { public: NS_DECL_ISUPPORTS - NS_DECL_NSIRECENTBADCERTS - NS_DECL_NSIOBSERVER + NS_DECL_NSIRECENTBADCERTSSERVICE - nsRecentBadCerts(); - ~nsRecentBadCerts(); + nsRecentBadCertsService(); + ~nsRecentBadCertsService(); - void InitPrivateBrowsingObserver(); + nsresult Init(); protected: mozilla::ReentrantMonitor monitor; From b5f51a281f82b4a2fcc424e546fc0b2faa6f6af9 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 6 Dec 2012 22:05:27 -0500 Subject: [PATCH 19/35] Bug 769288 - Part 1: Make PSM more amenable to storing concurrent private and non-private data. r=bsmith --- .../pki/resources/content/exceptionDialog.js | 7 +- .../ssl/public/nsIRecentBadCertsService.idl | 10 +- security/manager/ssl/public/nsIX509CertDB.idl | 13 +- security/manager/ssl/src/Makefile.in | 1 + .../ssl/src/SSLServerCertVerification.cpp | 57 ++++--- security/manager/ssl/src/SharedSSLState.cpp | 111 ++++++++++++++ security/manager/ssl/src/SharedSSLState.h | 54 +++++++ .../manager/ssl/src/nsClientAuthRemember.cpp | 12 ++ .../manager/ssl/src/nsClientAuthRemember.h | 1 + security/manager/ssl/src/nsNSSCallbacks.cpp | 8 +- .../manager/ssl/src/nsNSSCertificateDB.cpp | 21 +++ security/manager/ssl/src/nsNSSCertificateDB.h | 5 + security/manager/ssl/src/nsNSSComponent.cpp | 53 +------ security/manager/ssl/src/nsNSSComponent.h | 4 - security/manager/ssl/src/nsNSSIOLayer.cpp | 144 ++++++++++++++---- security/manager/ssl/src/nsNSSIOLayer.h | 58 ++++--- security/manager/ssl/src/nsNSSModule.cpp | 5 - security/manager/ssl/src/nsRecentBadCerts.cpp | 45 ++++-- security/manager/ssl/src/nsRecentBadCerts.h | 13 +- 19 files changed, 471 insertions(+), 151 deletions(-) create mode 100644 security/manager/ssl/src/SharedSSLState.cpp create mode 100644 security/manager/ssl/src/SharedSSLState.h diff --git a/security/manager/pki/resources/content/exceptionDialog.js b/security/manager/pki/resources/content/exceptionDialog.js index e6cae8415859..6d4eb89eacf9 100644 --- a/security/manager/pki/resources/content/exceptionDialog.js +++ b/security/manager/pki/resources/content/exceptionDialog.js @@ -88,8 +88,11 @@ function initExceptionDialog() { // returns true if found and global status could be set function findRecentBadCert(uri) { try { - var recentCertsSvc = Components.classes["@mozilla.org/security/recentbadcerts;1"] - .getService(Components.interfaces.nsIRecentBadCertsService); + var certDB = Components.classes["@mozilla.org/security/x509certdb;1"] + .getService(Components.interfaces.nsIX509CertDB); + if (!certDB) + return false; + var recentCertsSvc = certDB.getRecentBadCertsService(inPrivateBrowsingMode()); if (!recentCertsSvc) return false; diff --git a/security/manager/ssl/public/nsIRecentBadCertsService.idl b/security/manager/ssl/public/nsIRecentBadCertsService.idl index 398b792e4cc1..c221aa1dbd93 100644 --- a/security/manager/ssl/public/nsIRecentBadCertsService.idl +++ b/security/manager/ssl/public/nsIRecentBadCertsService.idl @@ -20,9 +20,8 @@ interface nsISSLStatus; * The implementation will decide how many entries it will hold, * the number is expected to be small. */ -[scriptable, uuid(a5ae8b05-a76e-408f-b0ba-02a831265749)] -interface nsIRecentBadCertsService : nsISupports { - +[scriptable, uuid(0fed7784-d152-44d6-95a7-67a59024de0f)] +interface nsIRecentBadCerts : nsISupports { /** * Retrieve the recently seen bad ssl status for the given hostname:port. * If no SSL cert was recently seen for the given hostname:port, return null. @@ -43,4 +42,9 @@ interface nsIRecentBadCertsService : nsISupports { */ void addBadCert(in AString aHostNameWithPort, in nsISSLStatus aStatus); + + /** + * Clear all stored cert data. + */ + void resetStoredCerts(); }; diff --git a/security/manager/ssl/public/nsIX509CertDB.idl b/security/manager/ssl/public/nsIX509CertDB.idl index cedbb2644473..aec9964a1fab 100644 --- a/security/manager/ssl/public/nsIX509CertDB.idl +++ b/security/manager/ssl/public/nsIX509CertDB.idl @@ -12,6 +12,7 @@ interface nsIX509Cert3; interface nsIFile; interface nsIInterfaceRequestor; interface nsIZipReader; +interface nsIRecentBadCerts; %{C++ #define NS_X509CERTDB_CONTRACTID "@mozilla.org/security/x509certdb;1" @@ -29,7 +30,7 @@ interface nsIOpenSignedJARFileCallback : nsISupports * This represents a service to access and manipulate * X.509 certificates stored in a database. */ -[scriptable, uuid(735d0363-e219-4387-b5c6-72e800c3ea0b)] +[scriptable, uuid(a18df2a5-84a9-46cd-9140-3fdb3879d9ff)] interface nsIX509CertDB : nsISupports { /** @@ -264,6 +265,16 @@ interface nsIX509CertDB : nsISupports { */ nsIX509Cert constructX509FromBase64(in string base64); + /* + * Obtain a reference to the appropriate service for recent + * bad certificates. May only be called on the main thread. + * + * @param isPrivate True if the service for certs for private connections + * is desired, false otherwise. + * @return The requested service. + */ + nsIRecentBadCerts getRecentBadCerts(in boolean isPrivate); + /** * Verifies the signature on the given JAR file to verify that it has a * valid signature. To be considered valid, there must be exactly one diff --git a/security/manager/ssl/src/Makefile.in b/security/manager/ssl/src/Makefile.in index 1ea14e33748b..86028d2e646c 100644 --- a/security/manager/ssl/src/Makefile.in +++ b/security/manager/ssl/src/Makefile.in @@ -74,6 +74,7 @@ CPPSRCS = \ PSMRunnable.cpp \ nsNSSVersion.cpp \ nsCertificatePrincipal.cpp \ + SharedSSLState.cpp \ $(NULL) ifdef MOZ_XUL diff --git a/security/manager/ssl/src/SSLServerCertVerification.cpp b/security/manager/ssl/src/SSLServerCertVerification.cpp index ae09139f1010..6bac3a3abfc6 100644 --- a/security/manager/ssl/src/SSLServerCertVerification.cpp +++ b/security/manager/ssl/src/SSLServerCertVerification.cpp @@ -112,6 +112,7 @@ #include "nsIConsoleService.h" #include "PSMRunnable.h" #include "ScopedNSSTypes.h" +#include "SharedSSLState.h" #include "ssl.h" #include "secerr.h" @@ -238,13 +239,15 @@ class CertErrorRunnable : public SyncRunnableBase uint32_t collectedErrors, PRErrorCode errorCodeTrust, PRErrorCode errorCodeMismatch, - PRErrorCode errorCodeExpired) + PRErrorCode errorCodeExpired, + uint32_t providerFlags) : mFdForLogging(fdForLogging), mCert(cert), mInfoObject(infoObject), mDefaultErrorCodeToReport(defaultErrorCodeToReport), mCollectedErrors(collectedErrors), mErrorCodeTrust(errorCodeTrust), mErrorCodeMismatch(errorCodeMismatch), - mErrorCodeExpired(errorCodeExpired) + mErrorCodeExpired(errorCodeExpired), + mProviderFlags(providerFlags) { } @@ -261,6 +264,7 @@ private: const PRErrorCode mErrorCodeTrust; const PRErrorCode mErrorCodeMismatch; const PRErrorCode mErrorCodeExpired; + const uint32_t mProviderFlags; }; SSLServerCertVerificationResult * @@ -296,12 +300,8 @@ CertErrorRunnable::CheckCertOverrides() if (NS_SUCCEEDED(nsrv)) { nsCOMPtr sslSocketControl = do_QueryInterface( NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject)); - uint32_t flags = 0; - if (sslSocketControl) { - sslSocketControl->GetProviderFlags(&flags); - } nsrv = stss->IsStsHost(mInfoObject->GetHostName(), - flags, + mProviderFlags, &strictTransportSecurityEnabled); } if (NS_FAILED(nsrv)) { @@ -371,8 +371,12 @@ CertErrorRunnable::CheckCertOverrides() } } - nsCOMPtr recentBadCertsService = - do_GetService(NS_RECENTBADCERTS_CONTRACTID); + nsCOMPtr certdb = do_GetService(NS_X509CERTDB_CONTRACTID); + nsCOMPtr recentBadCertsService; + if (certdb) { + bool isPrivate = mProviderFlags & nsISocketProvider::NO_PERMANENT_STORAGE; + certdb->GetRecentBadCerts(isPrivate, getter_AddRefs(recentBadCertsService)); + } if (recentBadCertsService) { NS_ConvertUTF8toUTF16 hostWithPortStringUTF16(hostWithPortString); @@ -418,7 +422,8 @@ CertErrorRunnable * CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport, TransportSecurityInfo * infoObject, CERTCertificate * cert, - const void * fdForLogging) + const void * fdForLogging, + uint32_t providerFlags) { MOZ_ASSERT(infoObject); MOZ_ASSERT(cert); @@ -567,7 +572,8 @@ CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport, static_cast(nssCert.get()), infoObject, defaultErrorCodeToReport, collected_errors, errorCodeTrust, - errorCodeMismatch, errorCodeExpired); + errorCodeMismatch, errorCodeExpired, + providerFlags); } // When doing async cert processing, we dispatch one of these runnables to the @@ -607,25 +613,29 @@ public: // Must be called only on the socket transport thread static SECStatus Dispatch(const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * serverCert); + CERTCertificate * serverCert, + uint32_t providerFlags); private: NS_DECL_NSIRUNNABLE // Must be called only on the socket transport thread SSLServerCertVerificationJob(const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * cert); + CERTCertificate * cert, + uint32_t providerFlags); const void * const mFdForLogging; const RefPtr mInfoObject; const ScopedCERTCertificate mCert; + const uint32_t mProviderFlags; }; SSLServerCertVerificationJob::SSLServerCertVerificationJob( const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * cert) + CERTCertificate * cert, uint32_t providerFlags) : mFdForLogging(fdForLogging) , mInfoObject(infoObject) , mCert(CERT_DupCertificate(cert)) + , mProviderFlags(providerFlags) { } @@ -977,7 +987,8 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert) /*static*/ SECStatus SSLServerCertVerificationJob::Dispatch(const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * serverCert) + CERTCertificate * serverCert, + uint32_t providerFlags) { // Runs on the socket transport thread if (!infoObject || !serverCert) { @@ -987,7 +998,8 @@ SSLServerCertVerificationJob::Dispatch(const void * fdForLogging, } RefPtr job( - new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert)); + new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert, + providerFlags)); nsresult nrv; if (!gCertVerificationThreadPool) { @@ -1042,7 +1054,7 @@ SSLServerCertVerificationJob::Run() error = PR_GetError(); if (error != 0) { RefPtr runnable(CreateCertErrorRunnable( - error, mInfoObject, mCert, mFdForLogging)); + error, mInfoObject, mCert, mFdForLogging, mProviderFlags)); if (!runnable) { // CreateCertErrorRunnable set a new error code error = PR_GetError(); @@ -1135,15 +1147,20 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) PR_SetError(PR_UNKNOWN_ERROR, 0); return SECFailure; } - + + uint32_t providerFlags = 0; + socketInfo->GetProviderFlags(&providerFlags); + if (onSTSThread) { + // We *must* do certificate verification on a background thread because // we need the socket transport thread to be free for our OCSP requests, // and we *want* to do certificate verification on a background thread // because of the performance benefits of doing so. socketInfo->SetCertVerificationWaiting(); SECStatus rv = SSLServerCertVerificationJob::Dispatch( - static_cast(fd), socketInfo, serverCert); + static_cast(fd), socketInfo, serverCert, + providerFlags); return rv; } @@ -1160,7 +1177,7 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) if (error != 0) { RefPtr runnable(CreateCertErrorRunnable( error, socketInfo, serverCert, - static_cast(fd))); + static_cast(fd), providerFlags)); if (!runnable) { // CreateCertErrorRunnable sets a new error code when it fails error = PR_GetError(); diff --git a/security/manager/ssl/src/SharedSSLState.cpp b/security/manager/ssl/src/SharedSSLState.cpp new file mode 100644 index 000000000000..6a4e7b1a493a --- /dev/null +++ b/security/manager/ssl/src/SharedSSLState.cpp @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "SharedSSLState.h" +#include "nsClientAuthRemember.h" +#include "nsComponentManagerUtils.h" +#include "nsICertOverrideService.h" +#include "nsIObserverService.h" +#include "mozilla/Services.h" +#include "nsThreadUtils.h" +#include "nsCRT.h" + +namespace mozilla { +namespace psm { + +namespace { +class PrivateBrowsingObserver : public nsIObserver { +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + PrivateBrowsingObserver(SharedSSLState* aOwner) : mOwner(aOwner) {} + virtual ~PrivateBrowsingObserver() {} +private: + SharedSSLState* mOwner; +}; + +SharedSSLState* gPublicState; +SharedSSLState* gPrivateState; +} // anonymous namespace + +NS_IMPL_ISUPPORTS1(PrivateBrowsingObserver, nsIObserver) + +NS_IMETHODIMP +PrivateBrowsingObserver::Observe(nsISupports *aSubject, + const char *aTopic, + const PRUnichar *aData) +{ + if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { + mOwner->ResetStoredData(); + } + return NS_OK; +} + +SharedSSLState::SharedSSLState() +: mClientAuthRemember(new nsClientAuthRememberService) +{ + mIOLayerHelpers.Init(); + mClientAuthRemember->Init(); +} + +void +SharedSSLState::NotePrivateBrowsingStatus() +{ + mObserver = new PrivateBrowsingObserver(this); + nsCOMPtr obsSvc = mozilla::services::GetObserverService(); + obsSvc->AddObserver(mObserver, "last-pb-context-exited", false); +} + +void +SharedSSLState::ResetStoredData() +{ + mClientAuthRemember->ClearRememberedDecisions(); + mIOLayerHelpers.clearStoredData(); +} + +/*static*/ void +SharedSSLState::GlobalInit() +{ + MOZ_ASSERT(NS_IsMainThread(), "Not on main thread"); + gPublicState = new SharedSSLState(); + gPrivateState = new SharedSSLState(); + gPrivateState->NotePrivateBrowsingStatus(); +} + +/*static*/ void +SharedSSLState::GlobalCleanup() +{ + MOZ_ASSERT(NS_IsMainThread(), "Not on main thread"); + + gPrivateState->Cleanup(); + delete gPrivateState; + gPrivateState = nullptr; + + gPublicState->Cleanup(); + delete gPublicState; + gPublicState = nullptr; +} + +void +SharedSSLState::Cleanup() +{ + mIOLayerHelpers.Cleanup(); +} + +SharedSSLState* +PublicSSLState() +{ + return gPublicState; +} + +SharedSSLState* +PrivateSSLState() +{ + return gPrivateState; +} + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/src/SharedSSLState.h b/security/manager/ssl/src/SharedSSLState.h new file mode 100644 index 000000000000..7a89fbca243b --- /dev/null +++ b/security/manager/ssl/src/SharedSSLState.h @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef SharedSSLState_h +#define SharedSSLState_h + +#include "mozilla/RefPtr.h" +#include "nsNSSIOLayer.h" + +class nsClientAuthRememberService; +class nsIRecentBadCertsService; +class nsICertOverrideService; +class nsIObserver; + +namespace mozilla { +namespace psm { + +class SharedSSLState { +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedSSLState) + SharedSSLState(); + + static void GlobalInit(); + static void GlobalCleanup(); + + nsClientAuthRememberService* GetClientAuthRememberService() { + return mClientAuthRemember; + } + + nsSSLIOLayerHelpers& IOLayerHelpers() { + return mIOLayerHelpers; + } + + void ResetStoredData(); + void NotePrivateBrowsingStatus(); + +private: + void Cleanup(); + + nsCOMPtr mObserver; + RefPtr mClientAuthRemember; + nsSSLIOLayerHelpers mIOLayerHelpers; +}; + +SharedSSLState* PublicSSLState(); +SharedSSLState* PrivateSSLState(); + +} // namespace psm +} // namespace mozilla + +#endif diff --git a/security/manager/ssl/src/nsClientAuthRemember.cpp b/security/manager/ssl/src/nsClientAuthRemember.cpp index b3ac013b4e26..ad595810da3a 100644 --- a/security/manager/ssl/src/nsClientAuthRemember.cpp +++ b/security/manager/ssl/src/nsClientAuthRemember.cpp @@ -21,8 +21,10 @@ #include "pk11pub.h" #include "certdb.h" #include "sechash.h" +#include "SharedSSLState.h" using namespace mozilla; +using namespace mozilla::psm; NS_IMPL_THREADSAFE_ISUPPORTS2(nsClientAuthRememberService, nsIObserver, @@ -80,6 +82,16 @@ void nsClientAuthRememberService::ClearRememberedDecisions() RemoveAllFromMemory(); } +void nsClientAuthRememberService::ClearAllRememberedDecisions() +{ + RefPtr svc = + PublicSSLState()->GetClientAuthRememberService(); + svc->ClearRememberedDecisions(); + + svc = PrivateSSLState()->GetClientAuthRememberService(); + svc->ClearRememberedDecisions(); +} + void nsClientAuthRememberService::RemoveAllFromMemory() { diff --git a/security/manager/ssl/src/nsClientAuthRemember.h b/security/manager/ssl/src/nsClientAuthRemember.h index 35a8a21b47a5..161303f07576 100644 --- a/security/manager/ssl/src/nsClientAuthRemember.h +++ b/security/manager/ssl/src/nsClientAuthRemember.h @@ -128,6 +128,7 @@ public: nsACString & aCertDBKey, bool *_retval); void ClearRememberedDecisions(); + static void ClearAllRememberedDecisions(); protected: mozilla::ReentrantMonitor monitor; diff --git a/security/manager/ssl/src/nsNSSCallbacks.cpp b/security/manager/ssl/src/nsNSSCallbacks.cpp index d7809989c7a6..02188b78493d 100644 --- a/security/manager/ssl/src/nsNSSCallbacks.cpp +++ b/security/manager/ssl/src/nsNSSCallbacks.cpp @@ -23,6 +23,7 @@ #include "nsIConsoleService.h" #include "nsIHttpChannelInternal.h" #include "nsCRT.h" +#include "SharedSSLState.h" #include "ssl.h" #include "sslproto.h" @@ -841,7 +842,8 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { // If the handshake completed, then we know the site is TLS tolerant (if this // was a TLS connection). - nsSSLIOLayerHelpers::rememberTolerantSite(infoObject); + nsSSLIOLayerHelpers& ioLayerHelpers = infoObject->SharedState().IOLayerHelpers(); + ioLayerHelpers.rememberTolerantSite(infoObject); if (SECSuccess != SSL_SecurityStatus(fd, &sslStatus, &cipherName, &keyLength, &encryptBits, &signer, nullptr)) { @@ -859,7 +861,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { if (SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn, &siteSupportsSafeRenego) != SECSuccess || !siteSupportsSafeRenego) { - bool wantWarning = (nsSSLIOLayerHelpers::getWarnLevelMissingRFC5746() > 0); + bool wantWarning = (ioLayerHelpers.getWarnLevelMissingRFC5746() > 0); nsCOMPtr console; if (infoObject && wantWarning) { @@ -875,7 +877,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { console->LogStringMessage(msg.get()); } } - if (nsSSLIOLayerHelpers::treatUnsafeNegotiationAsBroken()) { + if (ioLayerHelpers.treatUnsafeNegotiationAsBroken()) { secStatus = nsIWebProgressListener::STATE_IS_BROKEN; } } diff --git a/security/manager/ssl/src/nsNSSCertificateDB.cpp b/security/manager/ssl/src/nsNSSCertificateDB.cpp index 912ced9a8d68..b3314216a320 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.cpp +++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp @@ -31,6 +31,8 @@ #include "nsIPrompt.h" #include "nsThreadUtils.h" #include "ScopedNSSTypes.h" +#include "nsIObserverService.h" +#include "nsRecentBadCerts.h" #include "nspr.h" #include "certdb.h" @@ -1644,3 +1646,22 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval) NS_ADDREF(*_retval); return NS_OK; } + +NS_IMETHODIMP +nsNSSCertificateDB::GetRecentBadCerts(bool isPrivate, nsIRecentBadCerts** result) +{ + MOZ_ASSERT(NS_IsMainThread(), "RecentBadCerts should only be obtained on the main thread"); + if (isPrivate) { + if (!mPrivateRecentBadCerts) { + mPrivateRecentBadCerts = new nsRecentBadCerts; + mPrivateRecentBadCerts->InitPrivateBrowsingObserver(); + } + NS_ADDREF(*result = mPrivateRecentBadCerts); + } else { + if (!mPublicRecentBadCerts) { + mPublicRecentBadCerts = new nsRecentBadCerts; + } + NS_ADDREF(*result = mPublicRecentBadCerts); + } + return NS_OK; +} diff --git a/security/manager/ssl/src/nsNSSCertificateDB.h b/security/manager/ssl/src/nsNSSCertificateDB.h index efdbff80d339..c821322fbcb4 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.h +++ b/security/manager/ssl/src/nsNSSCertificateDB.h @@ -7,10 +7,12 @@ #include "nsIX509CertDB.h" #include "nsIX509CertDB2.h" +#include "mozilla/RefPtr.h" #include "certt.h" class nsCString; class nsIArray; +class nsRecentBadCerts; class nsNSSCertificateDB : public nsIX509CertDB, public nsIX509CertDB2 { @@ -48,6 +50,9 @@ private: uint32_t length); nsresult handleCACertDownload(nsIArray *x509Certs, nsIInterfaceRequestor *ctx); + + mozilla::RefPtr mPublicRecentBadCerts; + mozilla::RefPtr mPrivateRecentBadCerts; }; #define NS_X509CERTDB_CID { /* fb0bbc5c-452e-4783-b32c-80124693d871 */ \ diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index 486a3e1f907b..aabe6fab9789 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -60,6 +60,7 @@ #include "nsSmartCardEvent.h" #include "nsIKeyModule.h" #include "ScopedNSSTypes.h" +#include "SharedSSLState.h" #include "nss.h" #include "pk11func.h" @@ -400,7 +401,7 @@ nsNSSComponent::~nsNSSComponent() // All cleanup code requiring services needs to happen in xpcom_shutdown ShutdownNSS(); - nsSSLIOLayerHelpers::Cleanup(); + SharedSSLState::GlobalCleanup(); RememberCertErrorsTable::Cleanup(); --mInstanceCount; delete mShutdownObjectList; @@ -1860,9 +1861,6 @@ nsNSSComponent::ShutdownNSS() ShutdownSmartCardThreads(); SSL_ClearSessionCache(); - if (mClientAuthRememberService) { - mClientAuthRememberService->ClearRememberedDecisions(); - } UnloadLoadableRoots(); CleanupIdentityInfo(); PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("evaporating psm resources\n")); @@ -1933,27 +1931,8 @@ nsNSSComponent::Init() } RememberCertErrorsTable::Init(); - nsSSLIOLayerHelpers::Init(); - char *unrestricted_hosts=nullptr; - mPrefBranch->GetCharPref("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts); - if (unrestricted_hosts) { - nsSSLIOLayerHelpers::setRenegoUnrestrictedSites(nsDependentCString(unrestricted_hosts)); - nsMemory::Free(unrestricted_hosts); - unrestricted_hosts=nullptr; - } - - bool enabled = false; - mPrefBranch->GetBoolPref("security.ssl.treat_unsafe_negotiation_as_broken", &enabled); - nsSSLIOLayerHelpers::setTreatUnsafeNegotiationAsBroken(enabled); - - int32_t warnLevel = 1; - mPrefBranch->GetIntPref("security.ssl.warn_missing_rfc5746", &warnLevel); - nsSSLIOLayerHelpers::setWarnLevelMissingRFC5746(warnLevel); + SharedSSLState::GlobalInit(); - mClientAuthRememberService = new nsClientAuthRememberService; - if (mClientAuthRememberService) - mClientAuthRememberService->Init(); - createBackgroundThreads(); if (!mCertVerificationThread) { @@ -2271,20 +2250,6 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, 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=nullptr; - 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.ssl.warn_missing_rfc5746")) { - int32_t warnLevel = 1; - mPrefBranch->GetIntPref("security.ssl.warn_missing_rfc5746", &warnLevel); - nsSSLIOLayerHelpers::setWarnLevelMissingRFC5746(warnLevel); #ifdef SSL_ENABLE_FALSE_START // Requires NSS 3.12.8 } else if (prefName.Equals("security.ssl.enable_false_start")) { mPrefBranch->GetBoolPref("security.ssl.enable_false_start", &enabled); @@ -2387,9 +2352,7 @@ nsresult nsNSSComponent::LogoutAuthenticatedPK11() 0); } - if (mClientAuthRememberService) { - mClientAuthRememberService->ClearRememberedDecisions(); - } + nsClientAuthRememberService::ClearAllRememberedDecisions(); return mShutdownObjectList->doPK11Logout(); } @@ -2568,14 +2531,6 @@ nsNSSComponent::DoProfileChangeNetRestore() mIsNetworkDown = false; } -NS_IMETHODIMP -nsNSSComponent::GetClientAuthRememberService(nsClientAuthRememberService **cars) -{ - NS_ENSURE_ARG_POINTER(cars); - NS_IF_ADDREF(*cars = mClientAuthRememberService); - return NS_OK; -} - NS_IMETHODIMP nsNSSComponent::IsNSSInitialized(bool *initialized) { diff --git a/security/manager/ssl/src/nsNSSComponent.h b/security/manager/ssl/src/nsNSSComponent.h index 2391d95565d2..b47b989c21f5 100644 --- a/security/manager/ssl/src/nsNSSComponent.h +++ b/security/manager/ssl/src/nsNSSComponent.h @@ -154,8 +154,6 @@ class NS_NO_VTABLE nsINSSComponent : public nsISupports { NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token) = 0; - NS_IMETHOD GetClientAuthRememberService(nsClientAuthRememberService **cars) = 0; - NS_IMETHOD EnsureIdentityInfoLoaded() = 0; NS_IMETHOD IsNSSInitialized(bool *initialized) = 0; @@ -259,7 +257,6 @@ public: NS_IMETHOD ShutdownSmartCardThread(SECMODModule *module); NS_IMETHOD PostEvent(const nsAString &eventType, const nsAString &token); NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token); - NS_IMETHOD GetClientAuthRememberService(nsClientAuthRememberService **cars); NS_IMETHOD EnsureIdentityInfoLoaded(); NS_IMETHOD IsNSSInitialized(bool *initialized); @@ -327,7 +324,6 @@ private: nsCertVerificationThread *mCertVerificationThread; nsNSSHttpInterface mHttpForNSS; - mozilla::RefPtr mClientAuthRememberService; mozilla::RefPtr mDefaultCERTValInParam; mozilla::RefPtr mDefaultCERTValInParamLocalOnly; diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index 7f52d25af224..8e84c9647b2b 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -28,6 +28,8 @@ #include "nsIConsoleService.h" #include "PSMRunnable.h" #include "ScopedNSSTypes.h" +#include "SharedSSLState.h" +#include "mozilla/Preferences.h" #include "ssl.h" #include "secerr.h" @@ -63,9 +65,10 @@ typedef enum {ASK, AUTO} SSM_UserCertChoice; extern PRLogModuleInfo* gPIPNSSLog; #endif -nsNSSSocketInfo::nsNSSSocketInfo(uint32_t providerFlags) +nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags) : mFd(nullptr), mCertVerificationState(before_cert_verification), + mSharedState(aState), mForSTARTTLS(false), mSSL3Enabled(false), mTLSEnabled(false), @@ -457,6 +460,11 @@ void nsNSSSocketInfo::SetAllowTLSIntoleranceTimeout(bool aAllow) mAllowTLSIntoleranceTimeout = aAllow; } +SharedSSLState& nsNSSSocketInfo::SharedState() +{ + return mSharedState; +} + bool nsNSSSocketInfo::HandshakeTimeout() { if (!mAllowTLSIntoleranceTimeout) @@ -914,7 +922,8 @@ int32_t checkHandshake(int32_t bytesTransfered, bool wasReading, if (!wantRetry // no decision yet && isTLSIntoleranceError(err, socketInfo->GetHasCleartextPhase())) { - wantRetry = nsSSLIOLayerHelpers::rememberPossibleTLSProblemSite(socketInfo); + nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers(); + wantRetry = helpers.rememberPossibleTLSProblemSite(socketInfo); } } @@ -942,8 +951,8 @@ int32_t checkHandshake(int32_t bytesTransfered, bool wasReading, if (!wantRetry // no decision yet && !socketInfo->GetHasCleartextPhase()) // mirror PR_CONNECT_RESET_ERROR treament { - wantRetry = - nsSSLIOLayerHelpers::rememberPossibleTLSProblemSite(socketInfo); + nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers(); + wantRetry = helpers.rememberPossibleTLSProblemSite(socketInfo); } } } @@ -1031,12 +1040,16 @@ nsSSLIOLayerPoll(PRFileDesc * fd, int16_t in_flags, int16_t *out_flags) bool nsSSLIOLayerHelpers::nsSSLIOLayerInitialized = false; PRDescIdentity nsSSLIOLayerHelpers::nsSSLIOLayerIdentity; PRIOMethods nsSSLIOLayerHelpers::nsSSLIOLayerMethods; -Mutex *nsSSLIOLayerHelpers::mutex = nullptr; -nsTHashtable *nsSSLIOLayerHelpers::mTLSIntolerantSites = nullptr; -nsTHashtable *nsSSLIOLayerHelpers::mTLSTolerantSites = nullptr; -nsTHashtable *nsSSLIOLayerHelpers::mRenegoUnrestrictedSites = nullptr; -bool nsSSLIOLayerHelpers::mTreatUnsafeNegotiationAsBroken = false; -int32_t nsSSLIOLayerHelpers::mWarnLevelMissingRFC5746 = 1; + +nsSSLIOLayerHelpers::nsSSLIOLayerHelpers() +: mutex(nullptr) +, mTLSIntolerantSites(nullptr) +, mTLSTolerantSites(nullptr) +, mRenegoUnrestrictedSites(nullptr) +, mTreatUnsafeNegotiationAsBroken(false) +, mWarnLevelMissingRFC5746(1) +{ +} static int _PSM_InvalidInt(void) { @@ -1190,6 +1203,53 @@ static int64_t PSMAvailable64(void) return -1; } +namespace { +class PrefObserver : public nsIObserver { +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + PrefObserver(nsSSLIOLayerHelpers* aOwner) : mOwner(aOwner) {} + virtual ~PrefObserver() {} +private: + nsSSLIOLayerHelpers* mOwner; +}; +} // namespace anonymous + +NS_IMPL_THREADSAFE_ISUPPORTS1(PrefObserver, nsIObserver) + +NS_IMETHODIMP +PrefObserver::Observe(nsISupports *aSubject, const char *aTopic, + const PRUnichar *someData) +{ + if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) { + NS_ConvertUTF16toUTF8 prefName(someData); + + if (prefName.Equals("security.ssl.renego_unrestricted_hosts")) { + nsCString unrestricted_hosts; + Preferences::GetCString("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts); + if (!unrestricted_hosts.IsEmpty()) { + mOwner->setRenegoUnrestrictedSites(unrestricted_hosts); + } + } else if (prefName.Equals("security.ssl.treat_unsafe_negotiation_as_broken")) { + bool enabled; + Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", &enabled); + mOwner->setTreatUnsafeNegotiationAsBroken(enabled); + } else if (prefName.Equals("security.ssl.warn_missing_rfc5746")) { + int32_t warnLevel = 1; + Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel); + mOwner->setWarnLevelMissingRFC5746(warnLevel); + } + } + return NS_OK; +} + +nsSSLIOLayerHelpers::~nsSSLIOLayerHelpers() +{ + Preferences::RemoveObserver(mPrefObserver, "security.ssl.renego_unrestricted_hosts"); + Preferences::RemoveObserver(mPrefObserver, "security.ssl.treat_unsafe_negotiation_as_broken"); + Preferences::RemoveObserver(mPrefObserver, "security.ssl.warn_missing_rfc5746"); +} + nsresult nsSSLIOLayerHelpers::Init() { if (!nsSSLIOLayerInitialized) { @@ -1244,23 +1304,50 @@ nsresult nsSSLIOLayerHelpers::Init() mRenegoUnrestrictedSites = new nsTHashtable(); mRenegoUnrestrictedSites->Init(1); - mTreatUnsafeNegotiationAsBroken = false; - + nsCString unrestricted_hosts; + Preferences::GetCString("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts); + if (!unrestricted_hosts.IsEmpty()) { + setRenegoUnrestrictedSites(unrestricted_hosts); + } + + bool enabled = false; + Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", &enabled); + setTreatUnsafeNegotiationAsBroken(enabled); + + int32_t warnLevel = 1; + Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel); + setWarnLevelMissingRFC5746(warnLevel); + + mPrefObserver = new PrefObserver(this); + Preferences::AddStrongObserver(mPrefObserver, + "security.ssl.renego_unrestricted_hosts"); + Preferences::AddStrongObserver(mPrefObserver, + "security.ssl.treat_unsafe_negotiation_as_broken"); + Preferences::AddStrongObserver(mPrefObserver, + "security.ssl.warn_missing_rfc5746"); + return NS_OK; } +void nsSSLIOLayerHelpers::clearStoredData() +{ + mRenegoUnrestrictedSites->Clear(); + mTLSTolerantSites->Clear(); + mTLSIntolerantSites->Clear(); +} + void nsSSLIOLayerHelpers::addIntolerantSite(const nsCString &str) { MutexAutoLock lock(*mutex); // Remember intolerant site only if it is not known as tolerant if (!mTLSTolerantSites->Contains(str)) - nsSSLIOLayerHelpers::mTLSIntolerantSites->PutEntry(str); + mTLSIntolerantSites->PutEntry(str); } void nsSSLIOLayerHelpers::removeIntolerantSite(const nsCString &str) { MutexAutoLock lock(*mutex); - nsSSLIOLayerHelpers::mTLSIntolerantSites->RemoveEntry(str); + mTLSIntolerantSites->RemoveEntry(str); } bool nsSSLIOLayerHelpers::isKnownAsIntolerantSite(const nsCString &str) @@ -1923,6 +2010,7 @@ void ClientAuthDataRunnable::RunOnTargetThread() SSM_UserCertChoice certChoice; int32_t NumberOfCerts = 0; void * wincx = mSocketInfo; + nsresult rv; /* create caNameStrings */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); @@ -2024,19 +2112,14 @@ void ClientAuthDataRunnable::RunOnTargetThread() nsXPIDLCString hostname; mSocketInfo->GetHostName(getter_Copies(hostname)); - nsresult rv; - NS_DEFINE_CID(nssComponentCID, NS_NSSCOMPONENT_CID); - nsCOMPtr nssComponent(do_GetService(nssComponentCID, &rv)); - RefPtr cars; - if (nssComponent) { - nssComponent->GetClientAuthRememberService(byRef(cars)); - } + RefPtr cars = + mSocketInfo->SharedState().GetClientAuthRememberService(); bool hasRemembered = false; nsCString rememberedDBKey; if (cars) { bool found; - nsresult rv = cars->HasRememberedDecision(hostname, mServerCert, + rv = cars->HasRememberedDecision(hostname, mServerCert, rememberedDBKey, &found); if (NS_SUCCEEDED(rv) && found) { hasRemembered = true; @@ -2219,9 +2302,9 @@ if (!hasRemembered) } /* Throw up the client auth dialog and get back the index of the selected cert */ - rv = getNSSDialogs((void**)&dialogs, - NS_GET_IID(nsIClientAuthDialogs), - NS_CLIENTAUTHDIALOGS_CONTRACTID); + nsresult rv = getNSSDialogs((void**)&dialogs, + NS_GET_IID(nsIClientAuthDialogs), + NS_CLIENTAUTHDIALOGS_CONTRACTID); if (NS_FAILED(rv)) { NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList); @@ -2380,7 +2463,7 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, nsAutoCString key; key = nsDependentCString(host) + NS_LITERAL_CSTRING(":") + nsPrintfCString("%d", port); - if (nsSSLIOLayerHelpers::isKnownAsIntolerantSite(key)) { + if (infoObject->SharedState().IOLayerHelpers().isKnownAsIntolerantSite(key)) { if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_TLS, false)) return NS_ERROR_FAILURE; @@ -2407,8 +2490,9 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, if (SECSuccess != SSL_OptionSet(fd, SSL_HANDSHAKE_AS_CLIENT, true)) { return NS_ERROR_FAILURE; } - - if (nsSSLIOLayerHelpers::isRenegoUnrestrictedSite(nsDependentCString(host))) { + + nsSSLIOLayerHelpers& ioHelpers = infoObject->SharedState().IOLayerHelpers(); + if (ioHelpers.isRenegoUnrestrictedSite(nsDependentCString(host))) { if (SECSuccess != SSL_OptionSet(fd, SSL_REQUIRE_SAFE_NEGOTIATION, false)) { return NS_ERROR_FAILURE; } @@ -2450,7 +2534,9 @@ nsSSLIOLayerAddToSocket(int32_t family, nsresult rv; PRStatus stat; - nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(providerFlags); + SharedSSLState* sharedState = + providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE ? PrivateSSLState() : PublicSSLState(); + nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(*sharedState, providerFlags); if (!infoObject) return NS_ERROR_FAILURE; NS_ADDREF(infoObject); diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h index 4ee3bd9b8aac..2f25e71d04c8 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.h +++ b/security/manager/ssl/src/nsNSSIOLayer.h @@ -15,12 +15,20 @@ #include "nsTHashtable.h" #include "mozilla/TimeStamp.h" +namespace mozilla { +namespace psm { +class SharedSSLState; +} +} + +class nsIObserver; + class nsNSSSocketInfo : public mozilla::psm::TransportSecurityInfo, public nsISSLSocketControl, public nsIClientAuthUserDecision { public: - nsNSSSocketInfo(uint32_t providerFlags); + nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags); NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSISSLSOCKETCONTROL @@ -56,6 +64,8 @@ public: bool GetJoined() { return mJoined; } void SetSentClientCert() { mSentClientCert = true; } + mozilla::psm::SharedSSLState& SharedState(); + // XXX: These are only used on for diagnostic purposes enum CertVerificationState { before_cert_verification, @@ -83,6 +93,7 @@ private: CertVerificationState mCertVerificationState; + mozilla::psm::SharedSSLState& mSharedState; bool mForSTARTTLS; bool mSSL3Enabled; bool mTLSEnabled; @@ -109,37 +120,44 @@ private: class nsSSLIOLayerHelpers { public: - static nsresult Init(); - static void Cleanup(); + nsSSLIOLayerHelpers(); + ~nsSSLIOLayerHelpers(); + + nsresult Init(); + void Cleanup(); static bool nsSSLIOLayerInitialized; static PRDescIdentity nsSSLIOLayerIdentity; static PRIOMethods nsSSLIOLayerMethods; - static mozilla::Mutex *mutex; - static nsTHashtable *mTLSIntolerantSites; - static nsTHashtable *mTLSTolerantSites; + mozilla::Mutex *mutex; + nsTHashtable *mTLSIntolerantSites; + nsTHashtable *mTLSTolerantSites; - static nsTHashtable *mRenegoUnrestrictedSites; - static bool mTreatUnsafeNegotiationAsBroken; - static int32_t mWarnLevelMissingRFC5746; + nsTHashtable *mRenegoUnrestrictedSites; + bool mTreatUnsafeNegotiationAsBroken; + int32_t mWarnLevelMissingRFC5746; - static void setTreatUnsafeNegotiationAsBroken(bool broken); - static bool treatUnsafeNegotiationAsBroken(); + void setTreatUnsafeNegotiationAsBroken(bool broken); + bool treatUnsafeNegotiationAsBroken(); - static void setWarnLevelMissingRFC5746(int32_t level); - static int32_t getWarnLevelMissingRFC5746(); + void setWarnLevelMissingRFC5746(int32_t level); + int32_t getWarnLevelMissingRFC5746(); static void getSiteKey(nsNSSSocketInfo *socketInfo, nsCSubstring &key); - static bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo); - static void rememberTolerantSite(nsNSSSocketInfo *socketInfo); + bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo); + void rememberTolerantSite(nsNSSSocketInfo *socketInfo); - static void addIntolerantSite(const nsCString &str); - static void removeIntolerantSite(const nsCString &str); - static bool isKnownAsIntolerantSite(const nsCString &str); + void addIntolerantSite(const nsCString &str); + void removeIntolerantSite(const nsCString &str); + bool isKnownAsIntolerantSite(const nsCString &str); - static void setRenegoUnrestrictedSites(const nsCString &str); - static bool isRenegoUnrestrictedSite(const nsCString &str); + void setRenegoUnrestrictedSites(const nsCString &str); + bool isRenegoUnrestrictedSite(const nsCString &str); + + void clearStoredData(); +private: + nsCOMPtr mPrefObserver; }; nsresult nsSSLIOLayerNewSocket(int32_t family, diff --git a/security/manager/ssl/src/nsNSSModule.cpp b/security/manager/ssl/src/nsNSSModule.cpp index 90debb592819..568c2be52ae5 100644 --- a/security/manager/ssl/src/nsNSSModule.cpp +++ b/security/manager/ssl/src/nsNSSModule.cpp @@ -38,7 +38,6 @@ #include "nsDataSignatureVerifier.h" #include "nsCertOverrideService.h" #include "nsRandomGenerator.h" -#include "nsRecentBadCerts.h" #include "nsSSLStatus.h" #include "TransportSecurityInfo.h" #include "NSSErrorsService.h" @@ -204,7 +203,6 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsKeyObjectFactory) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsDataSignatureVerifier) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsCertOverrideService, Init) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsRandomGenerator) -NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsRecentBadCertsService, Init) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, nsSSLStatus) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, TransportSecurityInfo) @@ -243,7 +241,6 @@ NS_DEFINE_NAMED_CID(NS_KEYMODULEOBJECTFACTORY_CID); NS_DEFINE_NAMED_CID(NS_DATASIGNATUREVERIFIER_CID); NS_DEFINE_NAMED_CID(NS_CERTOVERRIDE_CID); NS_DEFINE_NAMED_CID(NS_RANDOMGENERATOR_CID); -NS_DEFINE_NAMED_CID(NS_RECENTBADCERTS_CID); NS_DEFINE_NAMED_CID(NS_SSLSTATUS_CID); NS_DEFINE_NAMED_CID(TRANSPORTSECURITYINFO_CID); NS_DEFINE_NAMED_CID(NS_NSSERRORSSERVICE_CID); @@ -281,7 +278,6 @@ static const mozilla::Module::CIDEntry kNSSCIDs[] = { { &kNS_DATASIGNATUREVERIFIER_CID, false, nullptr, nsDataSignatureVerifierConstructor }, { &kNS_CERTOVERRIDE_CID, false, nullptr, nsCertOverrideServiceConstructor }, { &kNS_RANDOMGENERATOR_CID, false, nullptr, nsRandomGeneratorConstructor }, - { &kNS_RECENTBADCERTS_CID, false, nullptr, nsRecentBadCertsServiceConstructor }, { &kNS_SSLSTATUS_CID, false, nullptr, nsSSLStatusConstructor }, { &kTRANSPORTSECURITYINFO_CID, false, nullptr, TransportSecurityInfoConstructor }, { &kNS_NSSERRORSSERVICE_CID, false, nullptr, NSSErrorsServiceConstructor }, @@ -324,7 +320,6 @@ static const mozilla::Module::ContractIDEntry kNSSContracts[] = { { NS_DATASIGNATUREVERIFIER_CONTRACTID, &kNS_DATASIGNATUREVERIFIER_CID }, { NS_CERTOVERRIDE_CONTRACTID, &kNS_CERTOVERRIDE_CID }, { NS_RANDOMGENERATOR_CONTRACTID, &kNS_RANDOMGENERATOR_CID }, - { NS_RECENTBADCERTS_CONTRACTID, &kNS_RECENTBADCERTS_CID }, { nullptr } }; diff --git a/security/manager/ssl/src/nsRecentBadCerts.cpp b/security/manager/ssl/src/nsRecentBadCerts.cpp index de378b9e9bb5..cae4fd1fb61c 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.cpp +++ b/security/manager/ssl/src/nsRecentBadCerts.cpp @@ -6,7 +6,9 @@ #include "nsRecentBadCerts.h" #include "nsIX509Cert.h" +#include "nsIObserverService.h" #include "mozilla/RefPtr.h" +#include "mozilla/Services.h" #include "nsSSLStatus.h" #include "nsCOMPtr.h" #include "nsNSSCertificate.h" @@ -20,28 +22,41 @@ using namespace mozilla; -NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCertsService, - nsIRecentBadCertsService) +NS_IMPL_THREADSAFE_ISUPPORTS2(nsRecentBadCerts, + nsIRecentBadCerts, + nsIObserver) -nsRecentBadCertsService::nsRecentBadCertsService() -:monitor("nsRecentBadCertsService.monitor") +nsRecentBadCerts::nsRecentBadCerts() +:monitor("nsRecentBadCerts.monitor") ,mNextStorePosition(0) { } -nsRecentBadCertsService::~nsRecentBadCertsService() +nsRecentBadCerts::~nsRecentBadCerts() { } -nsresult -nsRecentBadCertsService::Init() +void +nsRecentBadCerts::InitPrivateBrowsingObserver() { + nsCOMPtr obsSvc = mozilla::services::GetObserverService(); + obsSvc->AddObserver(this, "last-pb-context-exited", false); +} + +NS_IMETHODIMP +nsRecentBadCerts::Observe(nsISupports *aSubject, + const char *aTopic, + const PRUnichar *aData) +{ + if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { + ResetStoredCerts(); + } return NS_OK; } NS_IMETHODIMP -nsRecentBadCertsService::GetRecentBadCert(const nsAString & aHostNameWithPort, - nsISSLStatus **aStatus) +nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort, + nsISSLStatus **aStatus) { NS_ENSURE_ARG_POINTER(aStatus); if (!aHostNameWithPort.Length()) @@ -101,7 +116,7 @@ nsRecentBadCertsService::GetRecentBadCert(const nsAString & aHostNameWithPort, } NS_IMETHODIMP -nsRecentBadCertsService::AddBadCert(const nsAString &hostWithPort, +nsRecentBadCerts::AddBadCert(const nsAString &hostWithPort, nsISSLStatus *aStatus) { NS_ENSURE_ARG(aStatus); @@ -146,3 +161,13 @@ nsRecentBadCertsService::AddBadCert(const nsAString &hostWithPort, return NS_OK; } + +NS_IMETHODIMP +nsRecentBadCerts::ResetStoredCerts() +{ + for (size_t i = 0; i < const_recently_seen_list_size; ++i) { + RecentBadCert &entry = mCerts[i]; + entry.Clear(); + } + return NS_OK; +} diff --git a/security/manager/ssl/src/nsRecentBadCerts.h b/security/manager/ssl/src/nsRecentBadCerts.h index e82f780c252a..d815482d3794 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.h +++ b/security/manager/ssl/src/nsRecentBadCerts.h @@ -11,6 +11,7 @@ #include "mozilla/ReentrantMonitor.h" #include "nsIRecentBadCertsService.h" +#include "nsIObserver.h" #include "nsTHashtable.h" #include "nsString.h" #include "cert.h" @@ -54,16 +55,18 @@ private: RecentBadCert &operator=(const RecentBadCert &other) MOZ_DELETE; }; -class nsRecentBadCertsService MOZ_FINAL : public nsIRecentBadCertsService +class nsRecentBadCerts MOZ_FINAL : public nsIRecentBadCerts + , public nsIObserver { public: NS_DECL_ISUPPORTS - NS_DECL_NSIRECENTBADCERTSSERVICE + NS_DECL_NSIRECENTBADCERTS + NS_DECL_NSIOBSERVER - nsRecentBadCertsService(); - ~nsRecentBadCertsService(); + nsRecentBadCerts(); + ~nsRecentBadCerts(); - nsresult Init(); + void InitPrivateBrowsingObserver(); protected: mozilla::ReentrantMonitor monitor; From 316eb8148dfeb700ece41abb252ff5d45f01436d Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 6 Dec 2012 22:05:34 -0500 Subject: [PATCH 20/35] Bug 769288 - Part 2: Avoid storing intermediate cert data for private contexts. r=bsmith sr=mayhemer --- .../ssl/src/SSLServerCertVerification.cpp | 65 ++++++++++--------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/security/manager/ssl/src/SSLServerCertVerification.cpp b/security/manager/ssl/src/SSLServerCertVerification.cpp index 6bac3a3abfc6..c03f003b30e3 100644 --- a/security/manager/ssl/src/SSLServerCertVerification.cpp +++ b/security/manager/ssl/src/SSLServerCertVerification.cpp @@ -835,7 +835,8 @@ BlockServerCertChangeForSpdy(nsNSSSocketInfo *infoObject, } SECStatus -AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert) +AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert, + uint32_t providerFlags) { if (cert->serialNumber.data && cert->issuerName && @@ -921,37 +922,41 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert) } nsCOMPtr nssComponent; - - for (CERTCertListNode *node = CERT_LIST_HEAD(certList); - !CERT_LIST_END(node, certList); - node = CERT_LIST_NEXT(node)) { - if (node->cert->slot) { - // This cert was found on a token, no need to remember it in the temp db. - continue; - } + // We want to avoid storing any intermediate cert information when browsing + // in private, transient contexts. + if (!(providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE)) { + for (CERTCertListNode *node = CERT_LIST_HEAD(certList); + !CERT_LIST_END(node, certList); + node = CERT_LIST_NEXT(node)) { - if (node->cert->isperm) { - // We don't need to remember certs already stored in perm db. - continue; - } - - if (node->cert == cert) { - // We don't want to remember the server cert, - // the code that cares for displaying page info does this already. - continue; - } - - // We have found a signer cert that we want to remember. - char* nickname = nsNSSCertificate::defaultServerNickname(node->cert); - if (nickname && *nickname) { - ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); - if (slot) { - PK11_ImportCert(slot, node->cert, CK_INVALID_HANDLE, - nickname, false); + if (node->cert->slot) { + // This cert was found on a token, no need to remember it in the temp db. + continue; } + + if (node->cert->isperm) { + // We don't need to remember certs already stored in perm db. + continue; + } + + if (node->cert == cert) { + // We don't want to remember the server cert, + // the code that cares for displaying page info does this already. + continue; + } + + // We have found a signer cert that we want to remember. + char* nickname = nsNSSCertificate::defaultServerNickname(node->cert); + if (nickname && *nickname) { + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (slot) { + PK11_ImportCert(slot, node->cert, CK_INVALID_HANDLE, + nickname, false); + } + } + PR_FREEIF(nickname); } - PR_FREEIF(nickname); } // The connection may get terminated, for example, if the server requires @@ -1043,7 +1048,7 @@ SSLServerCertVerificationJob::Run() // Reset the error code here so we can detect if AuthCertificate fails to // set the error code if/when it fails. PR_SetError(0, 0); - SECStatus rv = AuthCertificate(mInfoObject, mCert); + SECStatus rv = AuthCertificate(mInfoObject, mCert, mProviderFlags); if (rv == SECSuccess) { RefPtr restart( new SSLServerCertVerificationResult(mInfoObject, 0)); @@ -1168,7 +1173,7 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) // thread doing the network I/O may not interrupt its network I/O on receipt // of our SSLServerCertVerificationResult event, and/or it might not even be // a non-blocking socket. - SECStatus rv = AuthCertificate(socketInfo, serverCert); + SECStatus rv = AuthCertificate(socketInfo, serverCert, providerFlags); if (rv == SECSuccess) { return SECSuccess; } From 2ccabeb0aac5d6dbcb859881a1a8228c5d6f8b23 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 6 Dec 2012 22:05:34 -0500 Subject: [PATCH 21/35] Bug 769288 - Part 3: Clear all temporary cert overrides upon leaving private browsing. r=bsmith --- security/manager/ssl/src/nsCertOverrideService.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/security/manager/ssl/src/nsCertOverrideService.cpp b/security/manager/ssl/src/nsCertOverrideService.cpp index 456564bd8b8a..e2db1ce91dee 100644 --- a/security/manager/ssl/src/nsCertOverrideService.cpp +++ b/security/manager/ssl/src/nsCertOverrideService.cpp @@ -124,6 +124,7 @@ nsCertOverrideService::Init() if (observerService) { observerService->AddObserver(this, "profile-before-change", true); observerService->AddObserver(this, "profile-do-change", true); + observerService->AddObserver(this, "last-pb-context-exited", true); // simulate a profile change so we read the current profile's settings file Observe(nullptr, "profile-do-change", nullptr); } @@ -168,6 +169,10 @@ nsCertOverrideService::Observe(nsISupports *, } Read(); + } else if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { + ClearValidityOverride( + NS_LITERAL_CSTRING("all:temporary-certificates"), + 0); } return NS_OK; From 07384b6096e858e5288a50f90622cdfe0cc1c75b Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 6 Dec 2012 22:05:34 -0500 Subject: [PATCH 22/35] Bug 769288 - Part 4: Clear SSL session cache upon leaving private browsing. r=bsmith --- security/manager/ssl/src/nsNSSComponent.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index aabe6fab9789..31d21ed90ac3 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -2138,6 +2138,7 @@ nsNSSComponent::RandomUpdate(void *entropy, int32_t bufLen) #define PROFILE_CHANGE_TEARDOWN_VETO_TOPIC "profile-change-teardown-veto" #define PROFILE_BEFORE_CHANGE_TOPIC "profile-before-change" #define PROFILE_DO_CHANGE_TOPIC "profile-do-change" +#define LEAVE_PRIVATE_BROWSING_TOPIC "last-pb-context-exited" NS_IMETHODIMP nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, @@ -2285,6 +2286,9 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network restore topic\n")); DoProfileChangeNetRestore(); } + else if (nsCRT::strcmp(aTopic, LEAVE_PRIVATE_BROWSING_TOPIC) == 0) { + SSL_ClearSessionCache(); + } return NS_OK; } @@ -2384,6 +2388,7 @@ nsNSSComponent::RegisterObservers() observerService->AddObserver(this, PROFILE_DO_CHANGE_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC, false); + observerService->AddObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC, false); } return NS_OK; } @@ -2409,6 +2414,7 @@ nsNSSComponent::DeregisterObservers() observerService->RemoveObserver(this, PROFILE_DO_CHANGE_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC); + observerService->RemoveObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC); } return NS_OK; } From 74cb691b442d57926fa8a8891cdc1bab7f4e314a Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 17:50:43 -0500 Subject: [PATCH 23/35] Bug 769288 - Part 5: Close private socket connections when the lsat private browsing instance dies. r=bsmith,mcmanus --- netwerk/base/public/nsASocketHandler.h | 3 ++ netwerk/base/src/nsSocketTransport2.cpp | 1 + .../base/src/nsSocketTransportService2.cpp | 38 +++++++++++++---- netwerk/base/src/nsSocketTransportService2.h | 2 + security/manager/ssl/src/Makefile.in | 6 +++ security/manager/ssl/src/PublicSSL.h | 23 ++++++++++ security/manager/ssl/src/SharedSSLState.cpp | 42 +++++++++++++++++++ security/manager/ssl/src/SharedSSLState.h | 2 - .../manager/ssl/src/nsCertOverrideService.cpp | 5 --- .../manager/ssl/src/nsNSSCertificateDB.cpp | 4 +- security/manager/ssl/src/nsNSSCertificateDB.h | 3 ++ security/manager/ssl/src/nsNSSComponent.cpp | 6 --- security/manager/ssl/src/nsRecentBadCerts.cpp | 23 +--------- security/manager/ssl/src/nsRecentBadCerts.h | 5 --- 14 files changed, 113 insertions(+), 50 deletions(-) create mode 100644 security/manager/ssl/src/PublicSSL.h diff --git a/netwerk/base/public/nsASocketHandler.h b/netwerk/base/public/nsASocketHandler.h index 3e2efe95231b..1f18ab1d7617 100644 --- a/netwerk/base/public/nsASocketHandler.h +++ b/netwerk/base/public/nsASocketHandler.h @@ -15,6 +15,7 @@ public: : mCondition(NS_OK) , mPollFlags(0) , mPollTimeout(UINT16_MAX) + , mIsPrivate(false) {} // @@ -42,6 +43,8 @@ public: // uint16_t mPollTimeout; + bool mIsPrivate; + // // called to service a socket // diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp index a348eb59b117..dd7eafc1f41a 100644 --- a/netwerk/base/src/nsSocketTransport2.cpp +++ b/netwerk/base/src/nsSocketTransport2.cpp @@ -2206,6 +2206,7 @@ NS_IMETHODIMP nsSocketTransport::SetConnectionFlags(uint32_t value) { mConnectionFlags = value; + mIsPrivate = value & nsISocketTransport::NO_PERMANENT_STORAGE; return NS_OK; } diff --git a/netwerk/base/src/nsSocketTransportService2.cpp b/netwerk/base/src/nsSocketTransportService2.cpp index 9807a150ccd3..b8ef26c9b76e 100644 --- a/netwerk/base/src/nsSocketTransportService2.cpp +++ b/netwerk/base/src/nsSocketTransportService2.cpp @@ -23,15 +23,7 @@ #include "mozilla/Services.h" #include "mozilla/Preferences.h" #include "mozilla/Likely.h" - - -// XXX: There is no good header file to put these in. :( -namespace mozilla { namespace psm { - -void InitializeSSLServerCertVerificationThreads(); -void StopSSLServerCertVerificationThreads(); - -} } // namespace mozilla::psm +#include "mozilla/PublicSSL.h" using namespace mozilla; @@ -469,6 +461,7 @@ nsSocketTransportService::Init() nsCOMPtr obsSvc = services::GetObserverService(); if (obsSvc) { obsSvc->AddObserver(this, "profile-initial-state", false); + obsSvc->AddObserver(this, "last-pb-context-exited", false); } mInitialized = true; @@ -516,6 +509,7 @@ nsSocketTransportService::Shutdown() nsCOMPtr obsSvc = services::GetObserverService(); if (obsSvc) { obsSvc->RemoveObserver(this, "profile-initial-state"); + obsSvc->RemoveObserver(this, "last-pb-context-exited"); } mozilla::net::NetworkActivityMonitor::Shutdown(); @@ -883,9 +877,35 @@ nsSocketTransportService::Observe(nsISupports *subject, return net::NetworkActivityMonitor::Init(blipInterval); } + + if (!strcmp(topic, "last-pb-context-exited")) { + nsCOMPtr ev = + NS_NewRunnableMethod(this, + &nsSocketTransportService::ClosePrivateConnections); + nsresult rv = Dispatch(ev, nsIEventTarget::DISPATCH_NORMAL); + NS_ENSURE_SUCCESS(rv, rv); + } + return NS_OK; } +void +nsSocketTransportService::ClosePrivateConnections() +{ + for (int32_t i = mActiveCount - 1; i >= 0; --i) { + if (mActiveList[i].mHandler->mIsPrivate) { + DetachSocket(mActiveList, &mActiveList[i]); + } + } + for (int32_t i = mIdleCount - 1; i >= 0; --i) { + if (mIdleList[i].mHandler->mIsPrivate) { + DetachSocket(mIdleList, &mIdleList[i]); + } + } + + mozilla::ClearPrivateSSLState(); +} + NS_IMETHODIMP nsSocketTransportService::GetSendBufferSize(int32_t *value) { diff --git a/netwerk/base/src/nsSocketTransportService2.h b/netwerk/base/src/nsSocketTransportService2.h index 7fdec908169e..737ab9889964 100644 --- a/netwerk/base/src/nsSocketTransportService2.h +++ b/netwerk/base/src/nsSocketTransportService2.h @@ -183,6 +183,8 @@ private: void ProbeMaxCount(); #endif bool mProbedMaxCount; + + void ClosePrivateConnections(); }; extern nsSocketTransportService *gSocketTransportService; diff --git a/security/manager/ssl/src/Makefile.in b/security/manager/ssl/src/Makefile.in index 86028d2e646c..46d26e0b8fad 100644 --- a/security/manager/ssl/src/Makefile.in +++ b/security/manager/ssl/src/Makefile.in @@ -98,5 +98,11 @@ EXPORTS += \ ScopedNSSTypes.h \ $(NULL) +EXPORTS_NAMESPACES = mozilla + +EXPORTS_mozilla += \ + PublicSSL.h \ + $(NULL) + include $(topsrcdir)/config/rules.mk diff --git a/security/manager/ssl/src/PublicSSL.h b/security/manager/ssl/src/PublicSSL.h new file mode 100644 index 000000000000..738a6e1f12d1 --- /dev/null +++ b/security/manager/ssl/src/PublicSSL.h @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef mozilla_SSL_h +#define mozilla_SSL_h + +namespace mozilla { + +void ClearPrivateSSLState(); + +namespace psm { + +void InitializeSSLServerCertVerificationThreads(); +void StopSSLServerCertVerificationThreads(); + +} //namespace psm +} // namespace mozilla + +#endif + diff --git a/security/manager/ssl/src/SharedSSLState.cpp b/security/manager/ssl/src/SharedSSLState.cpp index 6a4e7b1a493a..90dc5e22adc6 100644 --- a/security/manager/ssl/src/SharedSSLState.cpp +++ b/security/manager/ssl/src/SharedSSLState.cpp @@ -12,8 +12,50 @@ #include "mozilla/Services.h" #include "nsThreadUtils.h" #include "nsCRT.h" +#include "nsServiceManagerUtils.h" +#include "nsRecentBadCerts.h" +#include "PSMRunnable.h" +#include "PublicSSL.h" +#include "ssl.h" + +using mozilla::psm::SyncRunnableBase; + +namespace { + +class CertOverrideClearer : public SyncRunnableBase +{ +public: + void RunOnTargetThread() { + nsCOMPtr icos = do_GetService(NS_CERTOVERRIDE_CONTRACTID); + if (icos) { + icos->ClearValidityOverride( + NS_LITERAL_CSTRING("all:temporary-certificates"), + 0); + } + } +}; + +} // anonymous namespace namespace mozilla { + +void ClearPrivateSSLState() +{ + SSL_ClearSessionCache(); + + nsCOMPtr certdb = do_GetService(NS_X509CERTDB_CONTRACTID); + if (certdb) { + nsCOMPtr badCerts; + certdb->GetRecentBadCerts(true, getter_AddRefs(badCerts)); + if (badCerts) { + badCerts->ResetStoredCerts(); + } + } + + RefPtr runnable = new CertOverrideClearer; + runnable->DispatchToMainThreadAndWait(); +} + namespace psm { namespace { diff --git a/security/manager/ssl/src/SharedSSLState.h b/security/manager/ssl/src/SharedSSLState.h index 7a89fbca243b..d5b3a8bdec34 100644 --- a/security/manager/ssl/src/SharedSSLState.h +++ b/security/manager/ssl/src/SharedSSLState.h @@ -11,8 +11,6 @@ #include "nsNSSIOLayer.h" class nsClientAuthRememberService; -class nsIRecentBadCertsService; -class nsICertOverrideService; class nsIObserver; namespace mozilla { diff --git a/security/manager/ssl/src/nsCertOverrideService.cpp b/security/manager/ssl/src/nsCertOverrideService.cpp index e2db1ce91dee..456564bd8b8a 100644 --- a/security/manager/ssl/src/nsCertOverrideService.cpp +++ b/security/manager/ssl/src/nsCertOverrideService.cpp @@ -124,7 +124,6 @@ nsCertOverrideService::Init() if (observerService) { observerService->AddObserver(this, "profile-before-change", true); observerService->AddObserver(this, "profile-do-change", true); - observerService->AddObserver(this, "last-pb-context-exited", true); // simulate a profile change so we read the current profile's settings file Observe(nullptr, "profile-do-change", nullptr); } @@ -169,10 +168,6 @@ nsCertOverrideService::Observe(nsISupports *, } Read(); - } else if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { - ClearValidityOverride( - NS_LITERAL_CSTRING("all:temporary-certificates"), - 0); } return NS_OK; diff --git a/security/manager/ssl/src/nsNSSCertificateDB.cpp b/security/manager/ssl/src/nsNSSCertificateDB.cpp index b3314216a320..65b3fd77373a 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.cpp +++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp @@ -56,6 +56,7 @@ static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSCertificateDB, nsIX509CertDB, nsIX509CertDB2) nsNSSCertificateDB::nsNSSCertificateDB() +: mBadCertsLock("nsNSSCertificateDB::mBadCertsLock") { } @@ -1650,11 +1651,10 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval) NS_IMETHODIMP nsNSSCertificateDB::GetRecentBadCerts(bool isPrivate, nsIRecentBadCerts** result) { - MOZ_ASSERT(NS_IsMainThread(), "RecentBadCerts should only be obtained on the main thread"); + MutexAutoLock lock(mBadCertsLock); if (isPrivate) { if (!mPrivateRecentBadCerts) { mPrivateRecentBadCerts = new nsRecentBadCerts; - mPrivateRecentBadCerts->InitPrivateBrowsingObserver(); } NS_ADDREF(*result = mPrivateRecentBadCerts); } else { diff --git a/security/manager/ssl/src/nsNSSCertificateDB.h b/security/manager/ssl/src/nsNSSCertificateDB.h index c821322fbcb4..e591b359f88b 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.h +++ b/security/manager/ssl/src/nsNSSCertificateDB.h @@ -8,6 +8,7 @@ #include "nsIX509CertDB.h" #include "nsIX509CertDB2.h" #include "mozilla/RefPtr.h" +#include "mozilla/Mutex.h" #include "certt.h" class nsCString; @@ -16,6 +17,7 @@ class nsRecentBadCerts; class nsNSSCertificateDB : public nsIX509CertDB, public nsIX509CertDB2 { + typedef mozilla::Mutex Mutex; public: NS_DECL_ISUPPORTS NS_DECL_NSIX509CERTDB @@ -51,6 +53,7 @@ private: nsresult handleCACertDownload(nsIArray *x509Certs, nsIInterfaceRequestor *ctx); + Mutex mBadCertsLock; mozilla::RefPtr mPublicRecentBadCerts; mozilla::RefPtr mPrivateRecentBadCerts; }; diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index 31d21ed90ac3..aabe6fab9789 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -2138,7 +2138,6 @@ nsNSSComponent::RandomUpdate(void *entropy, int32_t bufLen) #define PROFILE_CHANGE_TEARDOWN_VETO_TOPIC "profile-change-teardown-veto" #define PROFILE_BEFORE_CHANGE_TOPIC "profile-before-change" #define PROFILE_DO_CHANGE_TOPIC "profile-do-change" -#define LEAVE_PRIVATE_BROWSING_TOPIC "last-pb-context-exited" NS_IMETHODIMP nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, @@ -2286,9 +2285,6 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network restore topic\n")); DoProfileChangeNetRestore(); } - else if (nsCRT::strcmp(aTopic, LEAVE_PRIVATE_BROWSING_TOPIC) == 0) { - SSL_ClearSessionCache(); - } return NS_OK; } @@ -2388,7 +2384,6 @@ nsNSSComponent::RegisterObservers() observerService->AddObserver(this, PROFILE_DO_CHANGE_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC, false); - observerService->AddObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC, false); } return NS_OK; } @@ -2414,7 +2409,6 @@ nsNSSComponent::DeregisterObservers() observerService->RemoveObserver(this, PROFILE_DO_CHANGE_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC); - observerService->RemoveObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC); } return NS_OK; } diff --git a/security/manager/ssl/src/nsRecentBadCerts.cpp b/security/manager/ssl/src/nsRecentBadCerts.cpp index cae4fd1fb61c..1b121cc767d7 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.cpp +++ b/security/manager/ssl/src/nsRecentBadCerts.cpp @@ -22,9 +22,8 @@ using namespace mozilla; -NS_IMPL_THREADSAFE_ISUPPORTS2(nsRecentBadCerts, - nsIRecentBadCerts, - nsIObserver) +NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCerts, + nsIRecentBadCerts) nsRecentBadCerts::nsRecentBadCerts() :monitor("nsRecentBadCerts.monitor") @@ -36,24 +35,6 @@ nsRecentBadCerts::~nsRecentBadCerts() { } -void -nsRecentBadCerts::InitPrivateBrowsingObserver() -{ - nsCOMPtr obsSvc = mozilla::services::GetObserverService(); - obsSvc->AddObserver(this, "last-pb-context-exited", false); -} - -NS_IMETHODIMP -nsRecentBadCerts::Observe(nsISupports *aSubject, - const char *aTopic, - const PRUnichar *aData) -{ - if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { - ResetStoredCerts(); - } - return NS_OK; -} - NS_IMETHODIMP nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort, nsISSLStatus **aStatus) diff --git a/security/manager/ssl/src/nsRecentBadCerts.h b/security/manager/ssl/src/nsRecentBadCerts.h index d815482d3794..064cb46cd1e8 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.h +++ b/security/manager/ssl/src/nsRecentBadCerts.h @@ -11,7 +11,6 @@ #include "mozilla/ReentrantMonitor.h" #include "nsIRecentBadCertsService.h" -#include "nsIObserver.h" #include "nsTHashtable.h" #include "nsString.h" #include "cert.h" @@ -56,18 +55,14 @@ private: }; class nsRecentBadCerts MOZ_FINAL : public nsIRecentBadCerts - , public nsIObserver { public: NS_DECL_ISUPPORTS NS_DECL_NSIRECENTBADCERTS - NS_DECL_NSIOBSERVER nsRecentBadCerts(); ~nsRecentBadCerts(); - void InitPrivateBrowsingObserver(); - protected: mozilla::ReentrantMonitor monitor; From ca107c17547d9995a9828c12b4bc7d7015940b09 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 6 Dec 2012 22:35:26 -0500 Subject: [PATCH 24/35] Bug 769288 - Part 6: Remove global private browsing NSS cleanup on exit. r=ehsan --- .../privatebrowsing/src/nsPrivateBrowsingService.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js index 47c2f6d8f72f..21d85fa004cf 100644 --- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js +++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js @@ -439,11 +439,6 @@ PrivateBrowsingService.prototype = { this._unload(); break; case "private-browsing": - // clear all auth tokens - let sdr = Cc["@mozilla.org/security/sdr;1"]. - getService(Ci.nsISecretDecoderRing); - sdr.logoutAndTeardown(); - if (!this._inPrivateBrowsing) { // Clear the error console let consoleService = Cc["@mozilla.org/consoleservice;1"]. From 95c262c0d4e57ab7abffe0042be4711e6003e922 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 7 Dec 2012 17:57:53 -0500 Subject: [PATCH 25/35] Bug 769288 - Part 7: Use separate SSL session cache entries for private connections. r=mayhemer --- security/manager/ssl/src/nsNSSIOLayer.cpp | 29 ++++++++++++----------- security/manager/ssl/src/nsNSSIOLayer.h | 4 +++- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index 8e84c9647b2b..a1ad8690a00c 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -2448,7 +2448,7 @@ loser: static nsresult nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, const char *proxyHost, const char *host, int32_t port, - bool anonymousLoad, nsNSSSocketInfo *infoObject) + nsNSSSocketInfo *infoObject) { nsNSSShutDownPreventionLock locker; if (forSTARTTLS || proxyHost) { @@ -2501,20 +2501,23 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, } } - // Set the Peer ID so that SSL proxy connections work properly. - char *peerId; - if (anonymousLoad) { // See bug #466080. Separate the caches. - peerId = PR_smprintf("anon:%s:%d", host, port); - } else { - peerId = PR_smprintf("%s:%d", host, port); + // Set the Peer ID so that SSL proxy connections work properly and to + // separate anonymous and/or private browsing connections. + uint32_t flags = infoObject->GetProviderFlags(); + nsAutoCString peerId; + if (flags & nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080 + peerId.Append("anon:"); } - - if (SECSuccess != SSL_SetSockPeerID(fd, peerId)) { - PR_smprintf_free(peerId); + if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) { + peerId.Append("private:"); + } + peerId.Append(host); + peerId.Append(':'); + peerId.AppendInt(port); + if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) { return NS_ERROR_FAILURE; } - PR_smprintf_free(peerId); return NS_OK; } @@ -2544,7 +2547,6 @@ nsSSLIOLayerAddToSocket(int32_t family, infoObject->SetHostName(host); infoObject->SetPort(port); - bool anonymousLoad = providerFlags & nsISocketProvider::ANONYMOUS_CONNECT; PRFileDesc *sslSock = nsSSLIOLayerImportFD(fd, infoObject, host); if (!sslSock) { NS_ASSERTION(false, "NSS: Error importing socket"); @@ -2553,8 +2555,7 @@ nsSSLIOLayerAddToSocket(int32_t family, infoObject->SetFileDescPtr(sslSock); - rv = nsSSLIOLayerSetOptions(sslSock, - forSTARTTLS, proxyHost, host, port, anonymousLoad, + rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, proxyHost, host, port, infoObject); if (NS_FAILED(rv)) diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h index 2f25e71d04c8..abdf8d430051 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.h +++ b/security/manager/ssl/src/nsNSSIOLayer.h @@ -63,7 +63,9 @@ public: bool GetJoined() { return mJoined; } void SetSentClientCert() { mSentClientCert = true; } - + + uint32_t GetProviderFlags() const { return mProviderFlags; } + mozilla::psm::SharedSSLState& SharedState(); // XXX: These are only used on for diagnostic purposes From 5a9c8601c0d0d9b18ccf633400b7b3fbfeb35315 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sat, 8 Dec 2012 00:21:47 -0500 Subject: [PATCH 26/35] Backed out changeset 9d37e0f7a2fc (bug 769288) --- security/manager/ssl/src/nsNSSIOLayer.cpp | 29 +++++++++++------------ security/manager/ssl/src/nsNSSIOLayer.h | 4 +--- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index a1ad8690a00c..8e84c9647b2b 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -2448,7 +2448,7 @@ loser: static nsresult nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, const char *proxyHost, const char *host, int32_t port, - nsNSSSocketInfo *infoObject) + bool anonymousLoad, nsNSSSocketInfo *infoObject) { nsNSSShutDownPreventionLock locker; if (forSTARTTLS || proxyHost) { @@ -2501,23 +2501,20 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, } } - // Set the Peer ID so that SSL proxy connections work properly and to - // separate anonymous and/or private browsing connections. - uint32_t flags = infoObject->GetProviderFlags(); - nsAutoCString peerId; - if (flags & nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080 - peerId.Append("anon:"); + // Set the Peer ID so that SSL proxy connections work properly. + char *peerId; + if (anonymousLoad) { // See bug #466080. Separate the caches. + peerId = PR_smprintf("anon:%s:%d", host, port); + } else { + peerId = PR_smprintf("%s:%d", host, port); } - if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) { - peerId.Append("private:"); - } - peerId.Append(host); - peerId.Append(':'); - peerId.AppendInt(port); - if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) { + + if (SECSuccess != SSL_SetSockPeerID(fd, peerId)) { + PR_smprintf_free(peerId); return NS_ERROR_FAILURE; } + PR_smprintf_free(peerId); return NS_OK; } @@ -2547,6 +2544,7 @@ nsSSLIOLayerAddToSocket(int32_t family, infoObject->SetHostName(host); infoObject->SetPort(port); + bool anonymousLoad = providerFlags & nsISocketProvider::ANONYMOUS_CONNECT; PRFileDesc *sslSock = nsSSLIOLayerImportFD(fd, infoObject, host); if (!sslSock) { NS_ASSERTION(false, "NSS: Error importing socket"); @@ -2555,7 +2553,8 @@ nsSSLIOLayerAddToSocket(int32_t family, infoObject->SetFileDescPtr(sslSock); - rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, proxyHost, host, port, + rv = nsSSLIOLayerSetOptions(sslSock, + forSTARTTLS, proxyHost, host, port, anonymousLoad, infoObject); if (NS_FAILED(rv)) diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h index abdf8d430051..2f25e71d04c8 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.h +++ b/security/manager/ssl/src/nsNSSIOLayer.h @@ -63,9 +63,7 @@ public: bool GetJoined() { return mJoined; } void SetSentClientCert() { mSentClientCert = true; } - - uint32_t GetProviderFlags() const { return mProviderFlags; } - + mozilla::psm::SharedSSLState& SharedState(); // XXX: These are only used on for diagnostic purposes From b1cbd8980825b041712361e152bd090f3332b51f Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sat, 8 Dec 2012 00:21:49 -0500 Subject: [PATCH 27/35] Backed out changeset 34eb0961da2c (bug 769288) --- .../privatebrowsing/src/nsPrivateBrowsingService.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js index 21d85fa004cf..47c2f6d8f72f 100644 --- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js +++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js @@ -439,6 +439,11 @@ PrivateBrowsingService.prototype = { this._unload(); break; case "private-browsing": + // clear all auth tokens + let sdr = Cc["@mozilla.org/security/sdr;1"]. + getService(Ci.nsISecretDecoderRing); + sdr.logoutAndTeardown(); + if (!this._inPrivateBrowsing) { // Clear the error console let consoleService = Cc["@mozilla.org/consoleservice;1"]. From 4d7f30e2f8f265d943a3dae8b3a7c83f85464969 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sat, 8 Dec 2012 00:21:51 -0500 Subject: [PATCH 28/35] Backed out changeset 4bae3ec53322 (bug 769288) --- netwerk/base/public/nsASocketHandler.h | 3 -- netwerk/base/src/nsSocketTransport2.cpp | 1 - .../base/src/nsSocketTransportService2.cpp | 38 ++++------------- netwerk/base/src/nsSocketTransportService2.h | 2 - security/manager/ssl/src/Makefile.in | 6 --- security/manager/ssl/src/PublicSSL.h | 23 ---------- security/manager/ssl/src/SharedSSLState.cpp | 42 ------------------- security/manager/ssl/src/SharedSSLState.h | 2 + .../manager/ssl/src/nsCertOverrideService.cpp | 5 +++ .../manager/ssl/src/nsNSSCertificateDB.cpp | 4 +- security/manager/ssl/src/nsNSSCertificateDB.h | 3 -- security/manager/ssl/src/nsNSSComponent.cpp | 6 +++ security/manager/ssl/src/nsRecentBadCerts.cpp | 23 +++++++++- security/manager/ssl/src/nsRecentBadCerts.h | 5 +++ 14 files changed, 50 insertions(+), 113 deletions(-) delete mode 100644 security/manager/ssl/src/PublicSSL.h diff --git a/netwerk/base/public/nsASocketHandler.h b/netwerk/base/public/nsASocketHandler.h index 1f18ab1d7617..3e2efe95231b 100644 --- a/netwerk/base/public/nsASocketHandler.h +++ b/netwerk/base/public/nsASocketHandler.h @@ -15,7 +15,6 @@ public: : mCondition(NS_OK) , mPollFlags(0) , mPollTimeout(UINT16_MAX) - , mIsPrivate(false) {} // @@ -43,8 +42,6 @@ public: // uint16_t mPollTimeout; - bool mIsPrivate; - // // called to service a socket // diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp index dd7eafc1f41a..a348eb59b117 100644 --- a/netwerk/base/src/nsSocketTransport2.cpp +++ b/netwerk/base/src/nsSocketTransport2.cpp @@ -2206,7 +2206,6 @@ NS_IMETHODIMP nsSocketTransport::SetConnectionFlags(uint32_t value) { mConnectionFlags = value; - mIsPrivate = value & nsISocketTransport::NO_PERMANENT_STORAGE; return NS_OK; } diff --git a/netwerk/base/src/nsSocketTransportService2.cpp b/netwerk/base/src/nsSocketTransportService2.cpp index b8ef26c9b76e..9807a150ccd3 100644 --- a/netwerk/base/src/nsSocketTransportService2.cpp +++ b/netwerk/base/src/nsSocketTransportService2.cpp @@ -23,7 +23,15 @@ #include "mozilla/Services.h" #include "mozilla/Preferences.h" #include "mozilla/Likely.h" -#include "mozilla/PublicSSL.h" + + +// XXX: There is no good header file to put these in. :( +namespace mozilla { namespace psm { + +void InitializeSSLServerCertVerificationThreads(); +void StopSSLServerCertVerificationThreads(); + +} } // namespace mozilla::psm using namespace mozilla; @@ -461,7 +469,6 @@ nsSocketTransportService::Init() nsCOMPtr obsSvc = services::GetObserverService(); if (obsSvc) { obsSvc->AddObserver(this, "profile-initial-state", false); - obsSvc->AddObserver(this, "last-pb-context-exited", false); } mInitialized = true; @@ -509,7 +516,6 @@ nsSocketTransportService::Shutdown() nsCOMPtr obsSvc = services::GetObserverService(); if (obsSvc) { obsSvc->RemoveObserver(this, "profile-initial-state"); - obsSvc->RemoveObserver(this, "last-pb-context-exited"); } mozilla::net::NetworkActivityMonitor::Shutdown(); @@ -877,35 +883,9 @@ nsSocketTransportService::Observe(nsISupports *subject, return net::NetworkActivityMonitor::Init(blipInterval); } - - if (!strcmp(topic, "last-pb-context-exited")) { - nsCOMPtr ev = - NS_NewRunnableMethod(this, - &nsSocketTransportService::ClosePrivateConnections); - nsresult rv = Dispatch(ev, nsIEventTarget::DISPATCH_NORMAL); - NS_ENSURE_SUCCESS(rv, rv); - } - return NS_OK; } -void -nsSocketTransportService::ClosePrivateConnections() -{ - for (int32_t i = mActiveCount - 1; i >= 0; --i) { - if (mActiveList[i].mHandler->mIsPrivate) { - DetachSocket(mActiveList, &mActiveList[i]); - } - } - for (int32_t i = mIdleCount - 1; i >= 0; --i) { - if (mIdleList[i].mHandler->mIsPrivate) { - DetachSocket(mIdleList, &mIdleList[i]); - } - } - - mozilla::ClearPrivateSSLState(); -} - NS_IMETHODIMP nsSocketTransportService::GetSendBufferSize(int32_t *value) { diff --git a/netwerk/base/src/nsSocketTransportService2.h b/netwerk/base/src/nsSocketTransportService2.h index 737ab9889964..7fdec908169e 100644 --- a/netwerk/base/src/nsSocketTransportService2.h +++ b/netwerk/base/src/nsSocketTransportService2.h @@ -183,8 +183,6 @@ private: void ProbeMaxCount(); #endif bool mProbedMaxCount; - - void ClosePrivateConnections(); }; extern nsSocketTransportService *gSocketTransportService; diff --git a/security/manager/ssl/src/Makefile.in b/security/manager/ssl/src/Makefile.in index 46d26e0b8fad..86028d2e646c 100644 --- a/security/manager/ssl/src/Makefile.in +++ b/security/manager/ssl/src/Makefile.in @@ -98,11 +98,5 @@ EXPORTS += \ ScopedNSSTypes.h \ $(NULL) -EXPORTS_NAMESPACES = mozilla - -EXPORTS_mozilla += \ - PublicSSL.h \ - $(NULL) - include $(topsrcdir)/config/rules.mk diff --git a/security/manager/ssl/src/PublicSSL.h b/security/manager/ssl/src/PublicSSL.h deleted file mode 100644 index 738a6e1f12d1..000000000000 --- a/security/manager/ssl/src/PublicSSL.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef mozilla_SSL_h -#define mozilla_SSL_h - -namespace mozilla { - -void ClearPrivateSSLState(); - -namespace psm { - -void InitializeSSLServerCertVerificationThreads(); -void StopSSLServerCertVerificationThreads(); - -} //namespace psm -} // namespace mozilla - -#endif - diff --git a/security/manager/ssl/src/SharedSSLState.cpp b/security/manager/ssl/src/SharedSSLState.cpp index 90dc5e22adc6..6a4e7b1a493a 100644 --- a/security/manager/ssl/src/SharedSSLState.cpp +++ b/security/manager/ssl/src/SharedSSLState.cpp @@ -12,50 +12,8 @@ #include "mozilla/Services.h" #include "nsThreadUtils.h" #include "nsCRT.h" -#include "nsServiceManagerUtils.h" -#include "nsRecentBadCerts.h" -#include "PSMRunnable.h" -#include "PublicSSL.h" -#include "ssl.h" - -using mozilla::psm::SyncRunnableBase; - -namespace { - -class CertOverrideClearer : public SyncRunnableBase -{ -public: - void RunOnTargetThread() { - nsCOMPtr icos = do_GetService(NS_CERTOVERRIDE_CONTRACTID); - if (icos) { - icos->ClearValidityOverride( - NS_LITERAL_CSTRING("all:temporary-certificates"), - 0); - } - } -}; - -} // anonymous namespace namespace mozilla { - -void ClearPrivateSSLState() -{ - SSL_ClearSessionCache(); - - nsCOMPtr certdb = do_GetService(NS_X509CERTDB_CONTRACTID); - if (certdb) { - nsCOMPtr badCerts; - certdb->GetRecentBadCerts(true, getter_AddRefs(badCerts)); - if (badCerts) { - badCerts->ResetStoredCerts(); - } - } - - RefPtr runnable = new CertOverrideClearer; - runnable->DispatchToMainThreadAndWait(); -} - namespace psm { namespace { diff --git a/security/manager/ssl/src/SharedSSLState.h b/security/manager/ssl/src/SharedSSLState.h index d5b3a8bdec34..7a89fbca243b 100644 --- a/security/manager/ssl/src/SharedSSLState.h +++ b/security/manager/ssl/src/SharedSSLState.h @@ -11,6 +11,8 @@ #include "nsNSSIOLayer.h" class nsClientAuthRememberService; +class nsIRecentBadCertsService; +class nsICertOverrideService; class nsIObserver; namespace mozilla { diff --git a/security/manager/ssl/src/nsCertOverrideService.cpp b/security/manager/ssl/src/nsCertOverrideService.cpp index 456564bd8b8a..e2db1ce91dee 100644 --- a/security/manager/ssl/src/nsCertOverrideService.cpp +++ b/security/manager/ssl/src/nsCertOverrideService.cpp @@ -124,6 +124,7 @@ nsCertOverrideService::Init() if (observerService) { observerService->AddObserver(this, "profile-before-change", true); observerService->AddObserver(this, "profile-do-change", true); + observerService->AddObserver(this, "last-pb-context-exited", true); // simulate a profile change so we read the current profile's settings file Observe(nullptr, "profile-do-change", nullptr); } @@ -168,6 +169,10 @@ nsCertOverrideService::Observe(nsISupports *, } Read(); + } else if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { + ClearValidityOverride( + NS_LITERAL_CSTRING("all:temporary-certificates"), + 0); } return NS_OK; diff --git a/security/manager/ssl/src/nsNSSCertificateDB.cpp b/security/manager/ssl/src/nsNSSCertificateDB.cpp index 65b3fd77373a..b3314216a320 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.cpp +++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp @@ -56,7 +56,6 @@ static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSCertificateDB, nsIX509CertDB, nsIX509CertDB2) nsNSSCertificateDB::nsNSSCertificateDB() -: mBadCertsLock("nsNSSCertificateDB::mBadCertsLock") { } @@ -1651,10 +1650,11 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval) NS_IMETHODIMP nsNSSCertificateDB::GetRecentBadCerts(bool isPrivate, nsIRecentBadCerts** result) { - MutexAutoLock lock(mBadCertsLock); + MOZ_ASSERT(NS_IsMainThread(), "RecentBadCerts should only be obtained on the main thread"); if (isPrivate) { if (!mPrivateRecentBadCerts) { mPrivateRecentBadCerts = new nsRecentBadCerts; + mPrivateRecentBadCerts->InitPrivateBrowsingObserver(); } NS_ADDREF(*result = mPrivateRecentBadCerts); } else { diff --git a/security/manager/ssl/src/nsNSSCertificateDB.h b/security/manager/ssl/src/nsNSSCertificateDB.h index e591b359f88b..c821322fbcb4 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.h +++ b/security/manager/ssl/src/nsNSSCertificateDB.h @@ -8,7 +8,6 @@ #include "nsIX509CertDB.h" #include "nsIX509CertDB2.h" #include "mozilla/RefPtr.h" -#include "mozilla/Mutex.h" #include "certt.h" class nsCString; @@ -17,7 +16,6 @@ class nsRecentBadCerts; class nsNSSCertificateDB : public nsIX509CertDB, public nsIX509CertDB2 { - typedef mozilla::Mutex Mutex; public: NS_DECL_ISUPPORTS NS_DECL_NSIX509CERTDB @@ -53,7 +51,6 @@ private: nsresult handleCACertDownload(nsIArray *x509Certs, nsIInterfaceRequestor *ctx); - Mutex mBadCertsLock; mozilla::RefPtr mPublicRecentBadCerts; mozilla::RefPtr mPrivateRecentBadCerts; }; diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index aabe6fab9789..31d21ed90ac3 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -2138,6 +2138,7 @@ nsNSSComponent::RandomUpdate(void *entropy, int32_t bufLen) #define PROFILE_CHANGE_TEARDOWN_VETO_TOPIC "profile-change-teardown-veto" #define PROFILE_BEFORE_CHANGE_TOPIC "profile-before-change" #define PROFILE_DO_CHANGE_TOPIC "profile-do-change" +#define LEAVE_PRIVATE_BROWSING_TOPIC "last-pb-context-exited" NS_IMETHODIMP nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, @@ -2285,6 +2286,9 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network restore topic\n")); DoProfileChangeNetRestore(); } + else if (nsCRT::strcmp(aTopic, LEAVE_PRIVATE_BROWSING_TOPIC) == 0) { + SSL_ClearSessionCache(); + } return NS_OK; } @@ -2384,6 +2388,7 @@ nsNSSComponent::RegisterObservers() observerService->AddObserver(this, PROFILE_DO_CHANGE_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC, false); + observerService->AddObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC, false); } return NS_OK; } @@ -2409,6 +2414,7 @@ nsNSSComponent::DeregisterObservers() observerService->RemoveObserver(this, PROFILE_DO_CHANGE_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC); + observerService->RemoveObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC); } return NS_OK; } diff --git a/security/manager/ssl/src/nsRecentBadCerts.cpp b/security/manager/ssl/src/nsRecentBadCerts.cpp index 1b121cc767d7..cae4fd1fb61c 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.cpp +++ b/security/manager/ssl/src/nsRecentBadCerts.cpp @@ -22,8 +22,9 @@ using namespace mozilla; -NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCerts, - nsIRecentBadCerts) +NS_IMPL_THREADSAFE_ISUPPORTS2(nsRecentBadCerts, + nsIRecentBadCerts, + nsIObserver) nsRecentBadCerts::nsRecentBadCerts() :monitor("nsRecentBadCerts.monitor") @@ -35,6 +36,24 @@ nsRecentBadCerts::~nsRecentBadCerts() { } +void +nsRecentBadCerts::InitPrivateBrowsingObserver() +{ + nsCOMPtr obsSvc = mozilla::services::GetObserverService(); + obsSvc->AddObserver(this, "last-pb-context-exited", false); +} + +NS_IMETHODIMP +nsRecentBadCerts::Observe(nsISupports *aSubject, + const char *aTopic, + const PRUnichar *aData) +{ + if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { + ResetStoredCerts(); + } + return NS_OK; +} + NS_IMETHODIMP nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort, nsISSLStatus **aStatus) diff --git a/security/manager/ssl/src/nsRecentBadCerts.h b/security/manager/ssl/src/nsRecentBadCerts.h index 064cb46cd1e8..d815482d3794 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.h +++ b/security/manager/ssl/src/nsRecentBadCerts.h @@ -11,6 +11,7 @@ #include "mozilla/ReentrantMonitor.h" #include "nsIRecentBadCertsService.h" +#include "nsIObserver.h" #include "nsTHashtable.h" #include "nsString.h" #include "cert.h" @@ -55,14 +56,18 @@ private: }; class nsRecentBadCerts MOZ_FINAL : public nsIRecentBadCerts + , public nsIObserver { public: NS_DECL_ISUPPORTS NS_DECL_NSIRECENTBADCERTS + NS_DECL_NSIOBSERVER nsRecentBadCerts(); ~nsRecentBadCerts(); + void InitPrivateBrowsingObserver(); + protected: mozilla::ReentrantMonitor monitor; From 225707a88d91bdaaf3c678c1501a6d8e5ddfbc2a Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sat, 8 Dec 2012 00:21:52 -0500 Subject: [PATCH 29/35] Backed out changeset cf30abd71492 (bug 769288) --- security/manager/ssl/src/nsNSSComponent.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index 31d21ed90ac3..aabe6fab9789 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -2138,7 +2138,6 @@ nsNSSComponent::RandomUpdate(void *entropy, int32_t bufLen) #define PROFILE_CHANGE_TEARDOWN_VETO_TOPIC "profile-change-teardown-veto" #define PROFILE_BEFORE_CHANGE_TOPIC "profile-before-change" #define PROFILE_DO_CHANGE_TOPIC "profile-do-change" -#define LEAVE_PRIVATE_BROWSING_TOPIC "last-pb-context-exited" NS_IMETHODIMP nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, @@ -2286,9 +2285,6 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("receiving network restore topic\n")); DoProfileChangeNetRestore(); } - else if (nsCRT::strcmp(aTopic, LEAVE_PRIVATE_BROWSING_TOPIC) == 0) { - SSL_ClearSessionCache(); - } return NS_OK; } @@ -2388,7 +2384,6 @@ nsNSSComponent::RegisterObservers() observerService->AddObserver(this, PROFILE_DO_CHANGE_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC, false); observerService->AddObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC, false); - observerService->AddObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC, false); } return NS_OK; } @@ -2414,7 +2409,6 @@ nsNSSComponent::DeregisterObservers() observerService->RemoveObserver(this, PROFILE_DO_CHANGE_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_TEARDOWN_TOPIC); observerService->RemoveObserver(this, PROFILE_CHANGE_NET_RESTORE_TOPIC); - observerService->RemoveObserver(this, LEAVE_PRIVATE_BROWSING_TOPIC); } return NS_OK; } From 0cdbc06d09253fcd6bc715f4d3e98b4b71074898 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sat, 8 Dec 2012 00:21:54 -0500 Subject: [PATCH 30/35] Backed out changeset 8ad08c64a89c (bug 769288) --- security/manager/ssl/src/nsCertOverrideService.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/security/manager/ssl/src/nsCertOverrideService.cpp b/security/manager/ssl/src/nsCertOverrideService.cpp index e2db1ce91dee..456564bd8b8a 100644 --- a/security/manager/ssl/src/nsCertOverrideService.cpp +++ b/security/manager/ssl/src/nsCertOverrideService.cpp @@ -124,7 +124,6 @@ nsCertOverrideService::Init() if (observerService) { observerService->AddObserver(this, "profile-before-change", true); observerService->AddObserver(this, "profile-do-change", true); - observerService->AddObserver(this, "last-pb-context-exited", true); // simulate a profile change so we read the current profile's settings file Observe(nullptr, "profile-do-change", nullptr); } @@ -169,10 +168,6 @@ nsCertOverrideService::Observe(nsISupports *, } Read(); - } else if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { - ClearValidityOverride( - NS_LITERAL_CSTRING("all:temporary-certificates"), - 0); } return NS_OK; From cf7ddeaae2a59badcb9db40db170855607f07f68 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sat, 8 Dec 2012 00:21:56 -0500 Subject: [PATCH 31/35] Backed out changeset 4cca693b7579 (bug 769288) --- .../ssl/src/SSLServerCertVerification.cpp | 69 +++++++++---------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/security/manager/ssl/src/SSLServerCertVerification.cpp b/security/manager/ssl/src/SSLServerCertVerification.cpp index c03f003b30e3..6bac3a3abfc6 100644 --- a/security/manager/ssl/src/SSLServerCertVerification.cpp +++ b/security/manager/ssl/src/SSLServerCertVerification.cpp @@ -835,8 +835,7 @@ BlockServerCertChangeForSpdy(nsNSSSocketInfo *infoObject, } SECStatus -AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert, - uint32_t providerFlags) +AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert) { if (cert->serialNumber.data && cert->issuerName && @@ -922,41 +921,37 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert, } nsCOMPtr nssComponent; + + for (CERTCertListNode *node = CERT_LIST_HEAD(certList); + !CERT_LIST_END(node, certList); + node = CERT_LIST_NEXT(node)) { - // We want to avoid storing any intermediate cert information when browsing - // in private, transient contexts. - if (!(providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE)) { - for (CERTCertListNode *node = CERT_LIST_HEAD(certList); - !CERT_LIST_END(node, certList); - node = CERT_LIST_NEXT(node)) { - - if (node->cert->slot) { - // This cert was found on a token, no need to remember it in the temp db. - continue; - } - - if (node->cert->isperm) { - // We don't need to remember certs already stored in perm db. - continue; - } - - if (node->cert == cert) { - // We don't want to remember the server cert, - // the code that cares for displaying page info does this already. - continue; - } - - // We have found a signer cert that we want to remember. - char* nickname = nsNSSCertificate::defaultServerNickname(node->cert); - if (nickname && *nickname) { - ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); - if (slot) { - PK11_ImportCert(slot, node->cert, CK_INVALID_HANDLE, - nickname, false); - } - } - PR_FREEIF(nickname); + if (node->cert->slot) { + // This cert was found on a token, no need to remember it in the temp db. + continue; } + + if (node->cert->isperm) { + // We don't need to remember certs already stored in perm db. + continue; + } + + if (node->cert == cert) { + // We don't want to remember the server cert, + // the code that cares for displaying page info does this already. + continue; + } + + // We have found a signer cert that we want to remember. + char* nickname = nsNSSCertificate::defaultServerNickname(node->cert); + if (nickname && *nickname) { + ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (slot) { + PK11_ImportCert(slot, node->cert, CK_INVALID_HANDLE, + nickname, false); + } + } + PR_FREEIF(nickname); } // The connection may get terminated, for example, if the server requires @@ -1048,7 +1043,7 @@ SSLServerCertVerificationJob::Run() // Reset the error code here so we can detect if AuthCertificate fails to // set the error code if/when it fails. PR_SetError(0, 0); - SECStatus rv = AuthCertificate(mInfoObject, mCert, mProviderFlags); + SECStatus rv = AuthCertificate(mInfoObject, mCert); if (rv == SECSuccess) { RefPtr restart( new SSLServerCertVerificationResult(mInfoObject, 0)); @@ -1173,7 +1168,7 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) // thread doing the network I/O may not interrupt its network I/O on receipt // of our SSLServerCertVerificationResult event, and/or it might not even be // a non-blocking socket. - SECStatus rv = AuthCertificate(socketInfo, serverCert, providerFlags); + SECStatus rv = AuthCertificate(socketInfo, serverCert); if (rv == SECSuccess) { return SECSuccess; } From 94a15456b14adcc45d0d3b25c811e42951461847 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sat, 8 Dec 2012 00:21:58 -0500 Subject: [PATCH 32/35] Backed out changeset fca88031cd47 (bug 769288) --- .../pki/resources/content/exceptionDialog.js | 7 +- .../ssl/public/nsIRecentBadCertsService.idl | 10 +- security/manager/ssl/public/nsIX509CertDB.idl | 13 +- security/manager/ssl/src/Makefile.in | 1 - .../ssl/src/SSLServerCertVerification.cpp | 57 +++---- security/manager/ssl/src/SharedSSLState.cpp | 111 -------------- security/manager/ssl/src/SharedSSLState.h | 54 ------- .../manager/ssl/src/nsClientAuthRemember.cpp | 12 -- .../manager/ssl/src/nsClientAuthRemember.h | 1 - security/manager/ssl/src/nsNSSCallbacks.cpp | 8 +- .../manager/ssl/src/nsNSSCertificateDB.cpp | 21 --- security/manager/ssl/src/nsNSSCertificateDB.h | 5 - security/manager/ssl/src/nsNSSComponent.cpp | 53 ++++++- security/manager/ssl/src/nsNSSComponent.h | 4 + security/manager/ssl/src/nsNSSIOLayer.cpp | 144 ++++-------------- security/manager/ssl/src/nsNSSIOLayer.h | 58 +++---- security/manager/ssl/src/nsNSSModule.cpp | 5 + security/manager/ssl/src/nsRecentBadCerts.cpp | 45 ++---- security/manager/ssl/src/nsRecentBadCerts.h | 13 +- 19 files changed, 151 insertions(+), 471 deletions(-) delete mode 100644 security/manager/ssl/src/SharedSSLState.cpp delete mode 100644 security/manager/ssl/src/SharedSSLState.h diff --git a/security/manager/pki/resources/content/exceptionDialog.js b/security/manager/pki/resources/content/exceptionDialog.js index 6d4eb89eacf9..e6cae8415859 100644 --- a/security/manager/pki/resources/content/exceptionDialog.js +++ b/security/manager/pki/resources/content/exceptionDialog.js @@ -88,11 +88,8 @@ function initExceptionDialog() { // returns true if found and global status could be set function findRecentBadCert(uri) { try { - var certDB = Components.classes["@mozilla.org/security/x509certdb;1"] - .getService(Components.interfaces.nsIX509CertDB); - if (!certDB) - return false; - var recentCertsSvc = certDB.getRecentBadCertsService(inPrivateBrowsingMode()); + var recentCertsSvc = Components.classes["@mozilla.org/security/recentbadcerts;1"] + .getService(Components.interfaces.nsIRecentBadCertsService); if (!recentCertsSvc) return false; diff --git a/security/manager/ssl/public/nsIRecentBadCertsService.idl b/security/manager/ssl/public/nsIRecentBadCertsService.idl index c221aa1dbd93..398b792e4cc1 100644 --- a/security/manager/ssl/public/nsIRecentBadCertsService.idl +++ b/security/manager/ssl/public/nsIRecentBadCertsService.idl @@ -20,8 +20,9 @@ interface nsISSLStatus; * The implementation will decide how many entries it will hold, * the number is expected to be small. */ -[scriptable, uuid(0fed7784-d152-44d6-95a7-67a59024de0f)] -interface nsIRecentBadCerts : nsISupports { +[scriptable, uuid(a5ae8b05-a76e-408f-b0ba-02a831265749)] +interface nsIRecentBadCertsService : nsISupports { + /** * Retrieve the recently seen bad ssl status for the given hostname:port. * If no SSL cert was recently seen for the given hostname:port, return null. @@ -42,9 +43,4 @@ interface nsIRecentBadCerts : nsISupports { */ void addBadCert(in AString aHostNameWithPort, in nsISSLStatus aStatus); - - /** - * Clear all stored cert data. - */ - void resetStoredCerts(); }; diff --git a/security/manager/ssl/public/nsIX509CertDB.idl b/security/manager/ssl/public/nsIX509CertDB.idl index aec9964a1fab..cedbb2644473 100644 --- a/security/manager/ssl/public/nsIX509CertDB.idl +++ b/security/manager/ssl/public/nsIX509CertDB.idl @@ -12,7 +12,6 @@ interface nsIX509Cert3; interface nsIFile; interface nsIInterfaceRequestor; interface nsIZipReader; -interface nsIRecentBadCerts; %{C++ #define NS_X509CERTDB_CONTRACTID "@mozilla.org/security/x509certdb;1" @@ -30,7 +29,7 @@ interface nsIOpenSignedJARFileCallback : nsISupports * This represents a service to access and manipulate * X.509 certificates stored in a database. */ -[scriptable, uuid(a18df2a5-84a9-46cd-9140-3fdb3879d9ff)] +[scriptable, uuid(735d0363-e219-4387-b5c6-72e800c3ea0b)] interface nsIX509CertDB : nsISupports { /** @@ -265,16 +264,6 @@ interface nsIX509CertDB : nsISupports { */ nsIX509Cert constructX509FromBase64(in string base64); - /* - * Obtain a reference to the appropriate service for recent - * bad certificates. May only be called on the main thread. - * - * @param isPrivate True if the service for certs for private connections - * is desired, false otherwise. - * @return The requested service. - */ - nsIRecentBadCerts getRecentBadCerts(in boolean isPrivate); - /** * Verifies the signature on the given JAR file to verify that it has a * valid signature. To be considered valid, there must be exactly one diff --git a/security/manager/ssl/src/Makefile.in b/security/manager/ssl/src/Makefile.in index 86028d2e646c..1ea14e33748b 100644 --- a/security/manager/ssl/src/Makefile.in +++ b/security/manager/ssl/src/Makefile.in @@ -74,7 +74,6 @@ CPPSRCS = \ PSMRunnable.cpp \ nsNSSVersion.cpp \ nsCertificatePrincipal.cpp \ - SharedSSLState.cpp \ $(NULL) ifdef MOZ_XUL diff --git a/security/manager/ssl/src/SSLServerCertVerification.cpp b/security/manager/ssl/src/SSLServerCertVerification.cpp index 6bac3a3abfc6..ae09139f1010 100644 --- a/security/manager/ssl/src/SSLServerCertVerification.cpp +++ b/security/manager/ssl/src/SSLServerCertVerification.cpp @@ -112,7 +112,6 @@ #include "nsIConsoleService.h" #include "PSMRunnable.h" #include "ScopedNSSTypes.h" -#include "SharedSSLState.h" #include "ssl.h" #include "secerr.h" @@ -239,15 +238,13 @@ class CertErrorRunnable : public SyncRunnableBase uint32_t collectedErrors, PRErrorCode errorCodeTrust, PRErrorCode errorCodeMismatch, - PRErrorCode errorCodeExpired, - uint32_t providerFlags) + PRErrorCode errorCodeExpired) : mFdForLogging(fdForLogging), mCert(cert), mInfoObject(infoObject), mDefaultErrorCodeToReport(defaultErrorCodeToReport), mCollectedErrors(collectedErrors), mErrorCodeTrust(errorCodeTrust), mErrorCodeMismatch(errorCodeMismatch), - mErrorCodeExpired(errorCodeExpired), - mProviderFlags(providerFlags) + mErrorCodeExpired(errorCodeExpired) { } @@ -264,7 +261,6 @@ private: const PRErrorCode mErrorCodeTrust; const PRErrorCode mErrorCodeMismatch; const PRErrorCode mErrorCodeExpired; - const uint32_t mProviderFlags; }; SSLServerCertVerificationResult * @@ -300,8 +296,12 @@ CertErrorRunnable::CheckCertOverrides() if (NS_SUCCEEDED(nsrv)) { nsCOMPtr sslSocketControl = do_QueryInterface( NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject)); + uint32_t flags = 0; + if (sslSocketControl) { + sslSocketControl->GetProviderFlags(&flags); + } nsrv = stss->IsStsHost(mInfoObject->GetHostName(), - mProviderFlags, + flags, &strictTransportSecurityEnabled); } if (NS_FAILED(nsrv)) { @@ -371,12 +371,8 @@ CertErrorRunnable::CheckCertOverrides() } } - nsCOMPtr certdb = do_GetService(NS_X509CERTDB_CONTRACTID); - nsCOMPtr recentBadCertsService; - if (certdb) { - bool isPrivate = mProviderFlags & nsISocketProvider::NO_PERMANENT_STORAGE; - certdb->GetRecentBadCerts(isPrivate, getter_AddRefs(recentBadCertsService)); - } + nsCOMPtr recentBadCertsService = + do_GetService(NS_RECENTBADCERTS_CONTRACTID); if (recentBadCertsService) { NS_ConvertUTF8toUTF16 hostWithPortStringUTF16(hostWithPortString); @@ -422,8 +418,7 @@ CertErrorRunnable * CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport, TransportSecurityInfo * infoObject, CERTCertificate * cert, - const void * fdForLogging, - uint32_t providerFlags) + const void * fdForLogging) { MOZ_ASSERT(infoObject); MOZ_ASSERT(cert); @@ -572,8 +567,7 @@ CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport, static_cast(nssCert.get()), infoObject, defaultErrorCodeToReport, collected_errors, errorCodeTrust, - errorCodeMismatch, errorCodeExpired, - providerFlags); + errorCodeMismatch, errorCodeExpired); } // When doing async cert processing, we dispatch one of these runnables to the @@ -613,29 +607,25 @@ public: // Must be called only on the socket transport thread static SECStatus Dispatch(const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * serverCert, - uint32_t providerFlags); + CERTCertificate * serverCert); private: NS_DECL_NSIRUNNABLE // Must be called only on the socket transport thread SSLServerCertVerificationJob(const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * cert, - uint32_t providerFlags); + CERTCertificate * cert); const void * const mFdForLogging; const RefPtr mInfoObject; const ScopedCERTCertificate mCert; - const uint32_t mProviderFlags; }; SSLServerCertVerificationJob::SSLServerCertVerificationJob( const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * cert, uint32_t providerFlags) + CERTCertificate * cert) : mFdForLogging(fdForLogging) , mInfoObject(infoObject) , mCert(CERT_DupCertificate(cert)) - , mProviderFlags(providerFlags) { } @@ -987,8 +977,7 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert) /*static*/ SECStatus SSLServerCertVerificationJob::Dispatch(const void * fdForLogging, TransportSecurityInfo * infoObject, - CERTCertificate * serverCert, - uint32_t providerFlags) + CERTCertificate * serverCert) { // Runs on the socket transport thread if (!infoObject || !serverCert) { @@ -998,8 +987,7 @@ SSLServerCertVerificationJob::Dispatch(const void * fdForLogging, } RefPtr job( - new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert, - providerFlags)); + new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert)); nsresult nrv; if (!gCertVerificationThreadPool) { @@ -1054,7 +1042,7 @@ SSLServerCertVerificationJob::Run() error = PR_GetError(); if (error != 0) { RefPtr runnable(CreateCertErrorRunnable( - error, mInfoObject, mCert, mFdForLogging, mProviderFlags)); + error, mInfoObject, mCert, mFdForLogging)); if (!runnable) { // CreateCertErrorRunnable set a new error code error = PR_GetError(); @@ -1147,20 +1135,15 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) PR_SetError(PR_UNKNOWN_ERROR, 0); return SECFailure; } - - uint32_t providerFlags = 0; - socketInfo->GetProviderFlags(&providerFlags); - + if (onSTSThread) { - // We *must* do certificate verification on a background thread because // we need the socket transport thread to be free for our OCSP requests, // and we *want* to do certificate verification on a background thread // because of the performance benefits of doing so. socketInfo->SetCertVerificationWaiting(); SECStatus rv = SSLServerCertVerificationJob::Dispatch( - static_cast(fd), socketInfo, serverCert, - providerFlags); + static_cast(fd), socketInfo, serverCert); return rv; } @@ -1177,7 +1160,7 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) if (error != 0) { RefPtr runnable(CreateCertErrorRunnable( error, socketInfo, serverCert, - static_cast(fd), providerFlags)); + static_cast(fd))); if (!runnable) { // CreateCertErrorRunnable sets a new error code when it fails error = PR_GetError(); diff --git a/security/manager/ssl/src/SharedSSLState.cpp b/security/manager/ssl/src/SharedSSLState.cpp deleted file mode 100644 index 6a4e7b1a493a..000000000000 --- a/security/manager/ssl/src/SharedSSLState.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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/. */ - -#include "SharedSSLState.h" -#include "nsClientAuthRemember.h" -#include "nsComponentManagerUtils.h" -#include "nsICertOverrideService.h" -#include "nsIObserverService.h" -#include "mozilla/Services.h" -#include "nsThreadUtils.h" -#include "nsCRT.h" - -namespace mozilla { -namespace psm { - -namespace { -class PrivateBrowsingObserver : public nsIObserver { -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - PrivateBrowsingObserver(SharedSSLState* aOwner) : mOwner(aOwner) {} - virtual ~PrivateBrowsingObserver() {} -private: - SharedSSLState* mOwner; -}; - -SharedSSLState* gPublicState; -SharedSSLState* gPrivateState; -} // anonymous namespace - -NS_IMPL_ISUPPORTS1(PrivateBrowsingObserver, nsIObserver) - -NS_IMETHODIMP -PrivateBrowsingObserver::Observe(nsISupports *aSubject, - const char *aTopic, - const PRUnichar *aData) -{ - if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { - mOwner->ResetStoredData(); - } - return NS_OK; -} - -SharedSSLState::SharedSSLState() -: mClientAuthRemember(new nsClientAuthRememberService) -{ - mIOLayerHelpers.Init(); - mClientAuthRemember->Init(); -} - -void -SharedSSLState::NotePrivateBrowsingStatus() -{ - mObserver = new PrivateBrowsingObserver(this); - nsCOMPtr obsSvc = mozilla::services::GetObserverService(); - obsSvc->AddObserver(mObserver, "last-pb-context-exited", false); -} - -void -SharedSSLState::ResetStoredData() -{ - mClientAuthRemember->ClearRememberedDecisions(); - mIOLayerHelpers.clearStoredData(); -} - -/*static*/ void -SharedSSLState::GlobalInit() -{ - MOZ_ASSERT(NS_IsMainThread(), "Not on main thread"); - gPublicState = new SharedSSLState(); - gPrivateState = new SharedSSLState(); - gPrivateState->NotePrivateBrowsingStatus(); -} - -/*static*/ void -SharedSSLState::GlobalCleanup() -{ - MOZ_ASSERT(NS_IsMainThread(), "Not on main thread"); - - gPrivateState->Cleanup(); - delete gPrivateState; - gPrivateState = nullptr; - - gPublicState->Cleanup(); - delete gPublicState; - gPublicState = nullptr; -} - -void -SharedSSLState::Cleanup() -{ - mIOLayerHelpers.Cleanup(); -} - -SharedSSLState* -PublicSSLState() -{ - return gPublicState; -} - -SharedSSLState* -PrivateSSLState() -{ - return gPrivateState; -} - -} // namespace psm -} // namespace mozilla diff --git a/security/manager/ssl/src/SharedSSLState.h b/security/manager/ssl/src/SharedSSLState.h deleted file mode 100644 index 7a89fbca243b..000000000000 --- a/security/manager/ssl/src/SharedSSLState.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef SharedSSLState_h -#define SharedSSLState_h - -#include "mozilla/RefPtr.h" -#include "nsNSSIOLayer.h" - -class nsClientAuthRememberService; -class nsIRecentBadCertsService; -class nsICertOverrideService; -class nsIObserver; - -namespace mozilla { -namespace psm { - -class SharedSSLState { -public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedSSLState) - SharedSSLState(); - - static void GlobalInit(); - static void GlobalCleanup(); - - nsClientAuthRememberService* GetClientAuthRememberService() { - return mClientAuthRemember; - } - - nsSSLIOLayerHelpers& IOLayerHelpers() { - return mIOLayerHelpers; - } - - void ResetStoredData(); - void NotePrivateBrowsingStatus(); - -private: - void Cleanup(); - - nsCOMPtr mObserver; - RefPtr mClientAuthRemember; - nsSSLIOLayerHelpers mIOLayerHelpers; -}; - -SharedSSLState* PublicSSLState(); -SharedSSLState* PrivateSSLState(); - -} // namespace psm -} // namespace mozilla - -#endif diff --git a/security/manager/ssl/src/nsClientAuthRemember.cpp b/security/manager/ssl/src/nsClientAuthRemember.cpp index ad595810da3a..b3ac013b4e26 100644 --- a/security/manager/ssl/src/nsClientAuthRemember.cpp +++ b/security/manager/ssl/src/nsClientAuthRemember.cpp @@ -21,10 +21,8 @@ #include "pk11pub.h" #include "certdb.h" #include "sechash.h" -#include "SharedSSLState.h" using namespace mozilla; -using namespace mozilla::psm; NS_IMPL_THREADSAFE_ISUPPORTS2(nsClientAuthRememberService, nsIObserver, @@ -82,16 +80,6 @@ void nsClientAuthRememberService::ClearRememberedDecisions() RemoveAllFromMemory(); } -void nsClientAuthRememberService::ClearAllRememberedDecisions() -{ - RefPtr svc = - PublicSSLState()->GetClientAuthRememberService(); - svc->ClearRememberedDecisions(); - - svc = PrivateSSLState()->GetClientAuthRememberService(); - svc->ClearRememberedDecisions(); -} - void nsClientAuthRememberService::RemoveAllFromMemory() { diff --git a/security/manager/ssl/src/nsClientAuthRemember.h b/security/manager/ssl/src/nsClientAuthRemember.h index 161303f07576..35a8a21b47a5 100644 --- a/security/manager/ssl/src/nsClientAuthRemember.h +++ b/security/manager/ssl/src/nsClientAuthRemember.h @@ -128,7 +128,6 @@ public: nsACString & aCertDBKey, bool *_retval); void ClearRememberedDecisions(); - static void ClearAllRememberedDecisions(); protected: mozilla::ReentrantMonitor monitor; diff --git a/security/manager/ssl/src/nsNSSCallbacks.cpp b/security/manager/ssl/src/nsNSSCallbacks.cpp index 02188b78493d..d7809989c7a6 100644 --- a/security/manager/ssl/src/nsNSSCallbacks.cpp +++ b/security/manager/ssl/src/nsNSSCallbacks.cpp @@ -23,7 +23,6 @@ #include "nsIConsoleService.h" #include "nsIHttpChannelInternal.h" #include "nsCRT.h" -#include "SharedSSLState.h" #include "ssl.h" #include "sslproto.h" @@ -842,8 +841,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { // If the handshake completed, then we know the site is TLS tolerant (if this // was a TLS connection). - nsSSLIOLayerHelpers& ioLayerHelpers = infoObject->SharedState().IOLayerHelpers(); - ioLayerHelpers.rememberTolerantSite(infoObject); + nsSSLIOLayerHelpers::rememberTolerantSite(infoObject); if (SECSuccess != SSL_SecurityStatus(fd, &sslStatus, &cipherName, &keyLength, &encryptBits, &signer, nullptr)) { @@ -861,7 +859,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { if (SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn, &siteSupportsSafeRenego) != SECSuccess || !siteSupportsSafeRenego) { - bool wantWarning = (ioLayerHelpers.getWarnLevelMissingRFC5746() > 0); + bool wantWarning = (nsSSLIOLayerHelpers::getWarnLevelMissingRFC5746() > 0); nsCOMPtr console; if (infoObject && wantWarning) { @@ -877,7 +875,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { console->LogStringMessage(msg.get()); } } - if (ioLayerHelpers.treatUnsafeNegotiationAsBroken()) { + if (nsSSLIOLayerHelpers::treatUnsafeNegotiationAsBroken()) { secStatus = nsIWebProgressListener::STATE_IS_BROKEN; } } diff --git a/security/manager/ssl/src/nsNSSCertificateDB.cpp b/security/manager/ssl/src/nsNSSCertificateDB.cpp index b3314216a320..912ced9a8d68 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.cpp +++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp @@ -31,8 +31,6 @@ #include "nsIPrompt.h" #include "nsThreadUtils.h" #include "ScopedNSSTypes.h" -#include "nsIObserverService.h" -#include "nsRecentBadCerts.h" #include "nspr.h" #include "certdb.h" @@ -1646,22 +1644,3 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval) NS_ADDREF(*_retval); return NS_OK; } - -NS_IMETHODIMP -nsNSSCertificateDB::GetRecentBadCerts(bool isPrivate, nsIRecentBadCerts** result) -{ - MOZ_ASSERT(NS_IsMainThread(), "RecentBadCerts should only be obtained on the main thread"); - if (isPrivate) { - if (!mPrivateRecentBadCerts) { - mPrivateRecentBadCerts = new nsRecentBadCerts; - mPrivateRecentBadCerts->InitPrivateBrowsingObserver(); - } - NS_ADDREF(*result = mPrivateRecentBadCerts); - } else { - if (!mPublicRecentBadCerts) { - mPublicRecentBadCerts = new nsRecentBadCerts; - } - NS_ADDREF(*result = mPublicRecentBadCerts); - } - return NS_OK; -} diff --git a/security/manager/ssl/src/nsNSSCertificateDB.h b/security/manager/ssl/src/nsNSSCertificateDB.h index c821322fbcb4..efdbff80d339 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.h +++ b/security/manager/ssl/src/nsNSSCertificateDB.h @@ -7,12 +7,10 @@ #include "nsIX509CertDB.h" #include "nsIX509CertDB2.h" -#include "mozilla/RefPtr.h" #include "certt.h" class nsCString; class nsIArray; -class nsRecentBadCerts; class nsNSSCertificateDB : public nsIX509CertDB, public nsIX509CertDB2 { @@ -50,9 +48,6 @@ private: uint32_t length); nsresult handleCACertDownload(nsIArray *x509Certs, nsIInterfaceRequestor *ctx); - - mozilla::RefPtr mPublicRecentBadCerts; - mozilla::RefPtr mPrivateRecentBadCerts; }; #define NS_X509CERTDB_CID { /* fb0bbc5c-452e-4783-b32c-80124693d871 */ \ diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index aabe6fab9789..486a3e1f907b 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -60,7 +60,6 @@ #include "nsSmartCardEvent.h" #include "nsIKeyModule.h" #include "ScopedNSSTypes.h" -#include "SharedSSLState.h" #include "nss.h" #include "pk11func.h" @@ -401,7 +400,7 @@ nsNSSComponent::~nsNSSComponent() // All cleanup code requiring services needs to happen in xpcom_shutdown ShutdownNSS(); - SharedSSLState::GlobalCleanup(); + nsSSLIOLayerHelpers::Cleanup(); RememberCertErrorsTable::Cleanup(); --mInstanceCount; delete mShutdownObjectList; @@ -1861,6 +1860,9 @@ nsNSSComponent::ShutdownNSS() ShutdownSmartCardThreads(); SSL_ClearSessionCache(); + if (mClientAuthRememberService) { + mClientAuthRememberService->ClearRememberedDecisions(); + } UnloadLoadableRoots(); CleanupIdentityInfo(); PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("evaporating psm resources\n")); @@ -1931,8 +1933,27 @@ nsNSSComponent::Init() } RememberCertErrorsTable::Init(); - SharedSSLState::GlobalInit(); + nsSSLIOLayerHelpers::Init(); + char *unrestricted_hosts=nullptr; + mPrefBranch->GetCharPref("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts); + if (unrestricted_hosts) { + nsSSLIOLayerHelpers::setRenegoUnrestrictedSites(nsDependentCString(unrestricted_hosts)); + nsMemory::Free(unrestricted_hosts); + unrestricted_hosts=nullptr; + } + + bool enabled = false; + mPrefBranch->GetBoolPref("security.ssl.treat_unsafe_negotiation_as_broken", &enabled); + nsSSLIOLayerHelpers::setTreatUnsafeNegotiationAsBroken(enabled); + + int32_t warnLevel = 1; + mPrefBranch->GetIntPref("security.ssl.warn_missing_rfc5746", &warnLevel); + nsSSLIOLayerHelpers::setWarnLevelMissingRFC5746(warnLevel); + mClientAuthRememberService = new nsClientAuthRememberService; + if (mClientAuthRememberService) + mClientAuthRememberService->Init(); + createBackgroundThreads(); if (!mCertVerificationThread) { @@ -2250,6 +2271,20 @@ nsNSSComponent::Observe(nsISupports *aSubject, const char *aTopic, 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=nullptr; + 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.ssl.warn_missing_rfc5746")) { + int32_t warnLevel = 1; + mPrefBranch->GetIntPref("security.ssl.warn_missing_rfc5746", &warnLevel); + nsSSLIOLayerHelpers::setWarnLevelMissingRFC5746(warnLevel); #ifdef SSL_ENABLE_FALSE_START // Requires NSS 3.12.8 } else if (prefName.Equals("security.ssl.enable_false_start")) { mPrefBranch->GetBoolPref("security.ssl.enable_false_start", &enabled); @@ -2352,7 +2387,9 @@ nsresult nsNSSComponent::LogoutAuthenticatedPK11() 0); } - nsClientAuthRememberService::ClearAllRememberedDecisions(); + if (mClientAuthRememberService) { + mClientAuthRememberService->ClearRememberedDecisions(); + } return mShutdownObjectList->doPK11Logout(); } @@ -2531,6 +2568,14 @@ nsNSSComponent::DoProfileChangeNetRestore() mIsNetworkDown = false; } +NS_IMETHODIMP +nsNSSComponent::GetClientAuthRememberService(nsClientAuthRememberService **cars) +{ + NS_ENSURE_ARG_POINTER(cars); + NS_IF_ADDREF(*cars = mClientAuthRememberService); + return NS_OK; +} + NS_IMETHODIMP nsNSSComponent::IsNSSInitialized(bool *initialized) { diff --git a/security/manager/ssl/src/nsNSSComponent.h b/security/manager/ssl/src/nsNSSComponent.h index b47b989c21f5..2391d95565d2 100644 --- a/security/manager/ssl/src/nsNSSComponent.h +++ b/security/manager/ssl/src/nsNSSComponent.h @@ -154,6 +154,8 @@ class NS_NO_VTABLE nsINSSComponent : public nsISupports { NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token) = 0; + NS_IMETHOD GetClientAuthRememberService(nsClientAuthRememberService **cars) = 0; + NS_IMETHOD EnsureIdentityInfoLoaded() = 0; NS_IMETHOD IsNSSInitialized(bool *initialized) = 0; @@ -257,6 +259,7 @@ public: NS_IMETHOD ShutdownSmartCardThread(SECMODModule *module); NS_IMETHOD PostEvent(const nsAString &eventType, const nsAString &token); NS_IMETHOD DispatchEvent(const nsAString &eventType, const nsAString &token); + NS_IMETHOD GetClientAuthRememberService(nsClientAuthRememberService **cars); NS_IMETHOD EnsureIdentityInfoLoaded(); NS_IMETHOD IsNSSInitialized(bool *initialized); @@ -324,6 +327,7 @@ private: nsCertVerificationThread *mCertVerificationThread; nsNSSHttpInterface mHttpForNSS; + mozilla::RefPtr mClientAuthRememberService; mozilla::RefPtr mDefaultCERTValInParam; mozilla::RefPtr mDefaultCERTValInParamLocalOnly; diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index 8e84c9647b2b..7f52d25af224 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -28,8 +28,6 @@ #include "nsIConsoleService.h" #include "PSMRunnable.h" #include "ScopedNSSTypes.h" -#include "SharedSSLState.h" -#include "mozilla/Preferences.h" #include "ssl.h" #include "secerr.h" @@ -65,10 +63,9 @@ typedef enum {ASK, AUTO} SSM_UserCertChoice; extern PRLogModuleInfo* gPIPNSSLog; #endif -nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags) +nsNSSSocketInfo::nsNSSSocketInfo(uint32_t providerFlags) : mFd(nullptr), mCertVerificationState(before_cert_verification), - mSharedState(aState), mForSTARTTLS(false), mSSL3Enabled(false), mTLSEnabled(false), @@ -460,11 +457,6 @@ void nsNSSSocketInfo::SetAllowTLSIntoleranceTimeout(bool aAllow) mAllowTLSIntoleranceTimeout = aAllow; } -SharedSSLState& nsNSSSocketInfo::SharedState() -{ - return mSharedState; -} - bool nsNSSSocketInfo::HandshakeTimeout() { if (!mAllowTLSIntoleranceTimeout) @@ -922,8 +914,7 @@ int32_t checkHandshake(int32_t bytesTransfered, bool wasReading, if (!wantRetry // no decision yet && isTLSIntoleranceError(err, socketInfo->GetHasCleartextPhase())) { - nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers(); - wantRetry = helpers.rememberPossibleTLSProblemSite(socketInfo); + wantRetry = nsSSLIOLayerHelpers::rememberPossibleTLSProblemSite(socketInfo); } } @@ -951,8 +942,8 @@ int32_t checkHandshake(int32_t bytesTransfered, bool wasReading, if (!wantRetry // no decision yet && !socketInfo->GetHasCleartextPhase()) // mirror PR_CONNECT_RESET_ERROR treament { - nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers(); - wantRetry = helpers.rememberPossibleTLSProblemSite(socketInfo); + wantRetry = + nsSSLIOLayerHelpers::rememberPossibleTLSProblemSite(socketInfo); } } } @@ -1040,16 +1031,12 @@ nsSSLIOLayerPoll(PRFileDesc * fd, int16_t in_flags, int16_t *out_flags) bool nsSSLIOLayerHelpers::nsSSLIOLayerInitialized = false; PRDescIdentity nsSSLIOLayerHelpers::nsSSLIOLayerIdentity; PRIOMethods nsSSLIOLayerHelpers::nsSSLIOLayerMethods; - -nsSSLIOLayerHelpers::nsSSLIOLayerHelpers() -: mutex(nullptr) -, mTLSIntolerantSites(nullptr) -, mTLSTolerantSites(nullptr) -, mRenegoUnrestrictedSites(nullptr) -, mTreatUnsafeNegotiationAsBroken(false) -, mWarnLevelMissingRFC5746(1) -{ -} +Mutex *nsSSLIOLayerHelpers::mutex = nullptr; +nsTHashtable *nsSSLIOLayerHelpers::mTLSIntolerantSites = nullptr; +nsTHashtable *nsSSLIOLayerHelpers::mTLSTolerantSites = nullptr; +nsTHashtable *nsSSLIOLayerHelpers::mRenegoUnrestrictedSites = nullptr; +bool nsSSLIOLayerHelpers::mTreatUnsafeNegotiationAsBroken = false; +int32_t nsSSLIOLayerHelpers::mWarnLevelMissingRFC5746 = 1; static int _PSM_InvalidInt(void) { @@ -1203,53 +1190,6 @@ static int64_t PSMAvailable64(void) return -1; } -namespace { -class PrefObserver : public nsIObserver { -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - PrefObserver(nsSSLIOLayerHelpers* aOwner) : mOwner(aOwner) {} - virtual ~PrefObserver() {} -private: - nsSSLIOLayerHelpers* mOwner; -}; -} // namespace anonymous - -NS_IMPL_THREADSAFE_ISUPPORTS1(PrefObserver, nsIObserver) - -NS_IMETHODIMP -PrefObserver::Observe(nsISupports *aSubject, const char *aTopic, - const PRUnichar *someData) -{ - if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) { - NS_ConvertUTF16toUTF8 prefName(someData); - - if (prefName.Equals("security.ssl.renego_unrestricted_hosts")) { - nsCString unrestricted_hosts; - Preferences::GetCString("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts); - if (!unrestricted_hosts.IsEmpty()) { - mOwner->setRenegoUnrestrictedSites(unrestricted_hosts); - } - } else if (prefName.Equals("security.ssl.treat_unsafe_negotiation_as_broken")) { - bool enabled; - Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", &enabled); - mOwner->setTreatUnsafeNegotiationAsBroken(enabled); - } else if (prefName.Equals("security.ssl.warn_missing_rfc5746")) { - int32_t warnLevel = 1; - Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel); - mOwner->setWarnLevelMissingRFC5746(warnLevel); - } - } - return NS_OK; -} - -nsSSLIOLayerHelpers::~nsSSLIOLayerHelpers() -{ - Preferences::RemoveObserver(mPrefObserver, "security.ssl.renego_unrestricted_hosts"); - Preferences::RemoveObserver(mPrefObserver, "security.ssl.treat_unsafe_negotiation_as_broken"); - Preferences::RemoveObserver(mPrefObserver, "security.ssl.warn_missing_rfc5746"); -} - nsresult nsSSLIOLayerHelpers::Init() { if (!nsSSLIOLayerInitialized) { @@ -1304,50 +1244,23 @@ nsresult nsSSLIOLayerHelpers::Init() mRenegoUnrestrictedSites = new nsTHashtable(); mRenegoUnrestrictedSites->Init(1); - nsCString unrestricted_hosts; - Preferences::GetCString("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts); - if (!unrestricted_hosts.IsEmpty()) { - setRenegoUnrestrictedSites(unrestricted_hosts); - } - - bool enabled = false; - Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", &enabled); - setTreatUnsafeNegotiationAsBroken(enabled); - - int32_t warnLevel = 1; - Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel); - setWarnLevelMissingRFC5746(warnLevel); - - mPrefObserver = new PrefObserver(this); - Preferences::AddStrongObserver(mPrefObserver, - "security.ssl.renego_unrestricted_hosts"); - Preferences::AddStrongObserver(mPrefObserver, - "security.ssl.treat_unsafe_negotiation_as_broken"); - Preferences::AddStrongObserver(mPrefObserver, - "security.ssl.warn_missing_rfc5746"); - + mTreatUnsafeNegotiationAsBroken = false; + return NS_OK; } -void nsSSLIOLayerHelpers::clearStoredData() -{ - mRenegoUnrestrictedSites->Clear(); - mTLSTolerantSites->Clear(); - mTLSIntolerantSites->Clear(); -} - void nsSSLIOLayerHelpers::addIntolerantSite(const nsCString &str) { MutexAutoLock lock(*mutex); // Remember intolerant site only if it is not known as tolerant if (!mTLSTolerantSites->Contains(str)) - mTLSIntolerantSites->PutEntry(str); + nsSSLIOLayerHelpers::mTLSIntolerantSites->PutEntry(str); } void nsSSLIOLayerHelpers::removeIntolerantSite(const nsCString &str) { MutexAutoLock lock(*mutex); - mTLSIntolerantSites->RemoveEntry(str); + nsSSLIOLayerHelpers::mTLSIntolerantSites->RemoveEntry(str); } bool nsSSLIOLayerHelpers::isKnownAsIntolerantSite(const nsCString &str) @@ -2010,7 +1923,6 @@ void ClientAuthDataRunnable::RunOnTargetThread() SSM_UserCertChoice certChoice; int32_t NumberOfCerts = 0; void * wincx = mSocketInfo; - nsresult rv; /* create caNameStrings */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); @@ -2112,14 +2024,19 @@ void ClientAuthDataRunnable::RunOnTargetThread() nsXPIDLCString hostname; mSocketInfo->GetHostName(getter_Copies(hostname)); - RefPtr cars = - mSocketInfo->SharedState().GetClientAuthRememberService(); + nsresult rv; + NS_DEFINE_CID(nssComponentCID, NS_NSSCOMPONENT_CID); + nsCOMPtr nssComponent(do_GetService(nssComponentCID, &rv)); + RefPtr cars; + if (nssComponent) { + nssComponent->GetClientAuthRememberService(byRef(cars)); + } bool hasRemembered = false; nsCString rememberedDBKey; if (cars) { bool found; - rv = cars->HasRememberedDecision(hostname, mServerCert, + nsresult rv = cars->HasRememberedDecision(hostname, mServerCert, rememberedDBKey, &found); if (NS_SUCCEEDED(rv) && found) { hasRemembered = true; @@ -2302,9 +2219,9 @@ if (!hasRemembered) } /* Throw up the client auth dialog and get back the index of the selected cert */ - nsresult rv = getNSSDialogs((void**)&dialogs, - NS_GET_IID(nsIClientAuthDialogs), - NS_CLIENTAUTHDIALOGS_CONTRACTID); + rv = getNSSDialogs((void**)&dialogs, + NS_GET_IID(nsIClientAuthDialogs), + NS_CLIENTAUTHDIALOGS_CONTRACTID); if (NS_FAILED(rv)) { NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList); @@ -2463,7 +2380,7 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, nsAutoCString key; key = nsDependentCString(host) + NS_LITERAL_CSTRING(":") + nsPrintfCString("%d", port); - if (infoObject->SharedState().IOLayerHelpers().isKnownAsIntolerantSite(key)) { + if (nsSSLIOLayerHelpers::isKnownAsIntolerantSite(key)) { if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_TLS, false)) return NS_ERROR_FAILURE; @@ -2490,9 +2407,8 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS, if (SECSuccess != SSL_OptionSet(fd, SSL_HANDSHAKE_AS_CLIENT, true)) { return NS_ERROR_FAILURE; } - - nsSSLIOLayerHelpers& ioHelpers = infoObject->SharedState().IOLayerHelpers(); - if (ioHelpers.isRenegoUnrestrictedSite(nsDependentCString(host))) { + + if (nsSSLIOLayerHelpers::isRenegoUnrestrictedSite(nsDependentCString(host))) { if (SECSuccess != SSL_OptionSet(fd, SSL_REQUIRE_SAFE_NEGOTIATION, false)) { return NS_ERROR_FAILURE; } @@ -2534,9 +2450,7 @@ nsSSLIOLayerAddToSocket(int32_t family, nsresult rv; PRStatus stat; - SharedSSLState* sharedState = - providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE ? PrivateSSLState() : PublicSSLState(); - nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(*sharedState, providerFlags); + nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(providerFlags); if (!infoObject) return NS_ERROR_FAILURE; NS_ADDREF(infoObject); diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h index 2f25e71d04c8..4ee3bd9b8aac 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.h +++ b/security/manager/ssl/src/nsNSSIOLayer.h @@ -15,20 +15,12 @@ #include "nsTHashtable.h" #include "mozilla/TimeStamp.h" -namespace mozilla { -namespace psm { -class SharedSSLState; -} -} - -class nsIObserver; - class nsNSSSocketInfo : public mozilla::psm::TransportSecurityInfo, public nsISSLSocketControl, public nsIClientAuthUserDecision { public: - nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags); + nsNSSSocketInfo(uint32_t providerFlags); NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSISSLSOCKETCONTROL @@ -64,8 +56,6 @@ public: bool GetJoined() { return mJoined; } void SetSentClientCert() { mSentClientCert = true; } - mozilla::psm::SharedSSLState& SharedState(); - // XXX: These are only used on for diagnostic purposes enum CertVerificationState { before_cert_verification, @@ -93,7 +83,6 @@ private: CertVerificationState mCertVerificationState; - mozilla::psm::SharedSSLState& mSharedState; bool mForSTARTTLS; bool mSSL3Enabled; bool mTLSEnabled; @@ -120,44 +109,37 @@ private: class nsSSLIOLayerHelpers { public: - nsSSLIOLayerHelpers(); - ~nsSSLIOLayerHelpers(); - - nsresult Init(); - void Cleanup(); + static nsresult Init(); + static void Cleanup(); static bool nsSSLIOLayerInitialized; static PRDescIdentity nsSSLIOLayerIdentity; static PRIOMethods nsSSLIOLayerMethods; - mozilla::Mutex *mutex; - nsTHashtable *mTLSIntolerantSites; - nsTHashtable *mTLSTolerantSites; + static mozilla::Mutex *mutex; + static nsTHashtable *mTLSIntolerantSites; + static nsTHashtable *mTLSTolerantSites; - nsTHashtable *mRenegoUnrestrictedSites; - bool mTreatUnsafeNegotiationAsBroken; - int32_t mWarnLevelMissingRFC5746; + static nsTHashtable *mRenegoUnrestrictedSites; + static bool mTreatUnsafeNegotiationAsBroken; + static int32_t mWarnLevelMissingRFC5746; - void setTreatUnsafeNegotiationAsBroken(bool broken); - bool treatUnsafeNegotiationAsBroken(); + static void setTreatUnsafeNegotiationAsBroken(bool broken); + static bool treatUnsafeNegotiationAsBroken(); - void setWarnLevelMissingRFC5746(int32_t level); - int32_t getWarnLevelMissingRFC5746(); + static void setWarnLevelMissingRFC5746(int32_t level); + static int32_t getWarnLevelMissingRFC5746(); static void getSiteKey(nsNSSSocketInfo *socketInfo, nsCSubstring &key); - bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo); - void rememberTolerantSite(nsNSSSocketInfo *socketInfo); + static bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo); + static void rememberTolerantSite(nsNSSSocketInfo *socketInfo); - void addIntolerantSite(const nsCString &str); - void removeIntolerantSite(const nsCString &str); - bool isKnownAsIntolerantSite(const nsCString &str); + static void addIntolerantSite(const nsCString &str); + static void removeIntolerantSite(const nsCString &str); + static bool isKnownAsIntolerantSite(const nsCString &str); - void setRenegoUnrestrictedSites(const nsCString &str); - bool isRenegoUnrestrictedSite(const nsCString &str); - - void clearStoredData(); -private: - nsCOMPtr mPrefObserver; + static void setRenegoUnrestrictedSites(const nsCString &str); + static bool isRenegoUnrestrictedSite(const nsCString &str); }; nsresult nsSSLIOLayerNewSocket(int32_t family, diff --git a/security/manager/ssl/src/nsNSSModule.cpp b/security/manager/ssl/src/nsNSSModule.cpp index 568c2be52ae5..90debb592819 100644 --- a/security/manager/ssl/src/nsNSSModule.cpp +++ b/security/manager/ssl/src/nsNSSModule.cpp @@ -38,6 +38,7 @@ #include "nsDataSignatureVerifier.h" #include "nsCertOverrideService.h" #include "nsRandomGenerator.h" +#include "nsRecentBadCerts.h" #include "nsSSLStatus.h" #include "TransportSecurityInfo.h" #include "NSSErrorsService.h" @@ -203,6 +204,7 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsKeyObjectFactory) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsDataSignatureVerifier) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsCertOverrideService, Init) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsRandomGenerator) +NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsRecentBadCertsService, Init) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, nsSSLStatus) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, TransportSecurityInfo) @@ -241,6 +243,7 @@ NS_DEFINE_NAMED_CID(NS_KEYMODULEOBJECTFACTORY_CID); NS_DEFINE_NAMED_CID(NS_DATASIGNATUREVERIFIER_CID); NS_DEFINE_NAMED_CID(NS_CERTOVERRIDE_CID); NS_DEFINE_NAMED_CID(NS_RANDOMGENERATOR_CID); +NS_DEFINE_NAMED_CID(NS_RECENTBADCERTS_CID); NS_DEFINE_NAMED_CID(NS_SSLSTATUS_CID); NS_DEFINE_NAMED_CID(TRANSPORTSECURITYINFO_CID); NS_DEFINE_NAMED_CID(NS_NSSERRORSSERVICE_CID); @@ -278,6 +281,7 @@ static const mozilla::Module::CIDEntry kNSSCIDs[] = { { &kNS_DATASIGNATUREVERIFIER_CID, false, nullptr, nsDataSignatureVerifierConstructor }, { &kNS_CERTOVERRIDE_CID, false, nullptr, nsCertOverrideServiceConstructor }, { &kNS_RANDOMGENERATOR_CID, false, nullptr, nsRandomGeneratorConstructor }, + { &kNS_RECENTBADCERTS_CID, false, nullptr, nsRecentBadCertsServiceConstructor }, { &kNS_SSLSTATUS_CID, false, nullptr, nsSSLStatusConstructor }, { &kTRANSPORTSECURITYINFO_CID, false, nullptr, TransportSecurityInfoConstructor }, { &kNS_NSSERRORSSERVICE_CID, false, nullptr, NSSErrorsServiceConstructor }, @@ -320,6 +324,7 @@ static const mozilla::Module::ContractIDEntry kNSSContracts[] = { { NS_DATASIGNATUREVERIFIER_CONTRACTID, &kNS_DATASIGNATUREVERIFIER_CID }, { NS_CERTOVERRIDE_CONTRACTID, &kNS_CERTOVERRIDE_CID }, { NS_RANDOMGENERATOR_CONTRACTID, &kNS_RANDOMGENERATOR_CID }, + { NS_RECENTBADCERTS_CONTRACTID, &kNS_RECENTBADCERTS_CID }, { nullptr } }; diff --git a/security/manager/ssl/src/nsRecentBadCerts.cpp b/security/manager/ssl/src/nsRecentBadCerts.cpp index cae4fd1fb61c..de378b9e9bb5 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.cpp +++ b/security/manager/ssl/src/nsRecentBadCerts.cpp @@ -6,9 +6,7 @@ #include "nsRecentBadCerts.h" #include "nsIX509Cert.h" -#include "nsIObserverService.h" #include "mozilla/RefPtr.h" -#include "mozilla/Services.h" #include "nsSSLStatus.h" #include "nsCOMPtr.h" #include "nsNSSCertificate.h" @@ -22,41 +20,28 @@ using namespace mozilla; -NS_IMPL_THREADSAFE_ISUPPORTS2(nsRecentBadCerts, - nsIRecentBadCerts, - nsIObserver) +NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCertsService, + nsIRecentBadCertsService) -nsRecentBadCerts::nsRecentBadCerts() -:monitor("nsRecentBadCerts.monitor") +nsRecentBadCertsService::nsRecentBadCertsService() +:monitor("nsRecentBadCertsService.monitor") ,mNextStorePosition(0) { } -nsRecentBadCerts::~nsRecentBadCerts() +nsRecentBadCertsService::~nsRecentBadCertsService() { } -void -nsRecentBadCerts::InitPrivateBrowsingObserver() +nsresult +nsRecentBadCertsService::Init() { - nsCOMPtr obsSvc = mozilla::services::GetObserverService(); - obsSvc->AddObserver(this, "last-pb-context-exited", false); -} - -NS_IMETHODIMP -nsRecentBadCerts::Observe(nsISupports *aSubject, - const char *aTopic, - const PRUnichar *aData) -{ - if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { - ResetStoredCerts(); - } return NS_OK; } NS_IMETHODIMP -nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort, - nsISSLStatus **aStatus) +nsRecentBadCertsService::GetRecentBadCert(const nsAString & aHostNameWithPort, + nsISSLStatus **aStatus) { NS_ENSURE_ARG_POINTER(aStatus); if (!aHostNameWithPort.Length()) @@ -116,7 +101,7 @@ nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort, } NS_IMETHODIMP -nsRecentBadCerts::AddBadCert(const nsAString &hostWithPort, +nsRecentBadCertsService::AddBadCert(const nsAString &hostWithPort, nsISSLStatus *aStatus) { NS_ENSURE_ARG(aStatus); @@ -161,13 +146,3 @@ nsRecentBadCerts::AddBadCert(const nsAString &hostWithPort, return NS_OK; } - -NS_IMETHODIMP -nsRecentBadCerts::ResetStoredCerts() -{ - for (size_t i = 0; i < const_recently_seen_list_size; ++i) { - RecentBadCert &entry = mCerts[i]; - entry.Clear(); - } - return NS_OK; -} diff --git a/security/manager/ssl/src/nsRecentBadCerts.h b/security/manager/ssl/src/nsRecentBadCerts.h index d815482d3794..e82f780c252a 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.h +++ b/security/manager/ssl/src/nsRecentBadCerts.h @@ -11,7 +11,6 @@ #include "mozilla/ReentrantMonitor.h" #include "nsIRecentBadCertsService.h" -#include "nsIObserver.h" #include "nsTHashtable.h" #include "nsString.h" #include "cert.h" @@ -55,18 +54,16 @@ private: RecentBadCert &operator=(const RecentBadCert &other) MOZ_DELETE; }; -class nsRecentBadCerts MOZ_FINAL : public nsIRecentBadCerts - , public nsIObserver +class nsRecentBadCertsService MOZ_FINAL : public nsIRecentBadCertsService { public: NS_DECL_ISUPPORTS - NS_DECL_NSIRECENTBADCERTS - NS_DECL_NSIOBSERVER + NS_DECL_NSIRECENTBADCERTSSERVICE - nsRecentBadCerts(); - ~nsRecentBadCerts(); + nsRecentBadCertsService(); + ~nsRecentBadCertsService(); - void InitPrivateBrowsingObserver(); + nsresult Init(); protected: mozilla::ReentrantMonitor monitor; From acf076f0216a05d80372d00daab98aea6c3a383e Mon Sep 17 00:00:00 2001 From: ffxbld Date: Sat, 8 Dec 2012 03:37:29 -0800 Subject: [PATCH 33/35] No bug, Automated blocklist update from host bld-linux64-ec2-388 - a=blocklist-update --- browser/app/blocklist.xml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/browser/app/blocklist.xml b/browser/app/blocklist.xml index 3b1f11d44876..fa1d63a724d9 100644 --- a/browser/app/blocklist.xml +++ b/browser/app/blocklist.xml @@ -1,5 +1,5 @@ - + @@ -45,6 +45,10 @@ + + + + @@ -61,6 +65,13 @@ + + + + + + + From 34ff2e18cd61c7abdd3d5552c8c1b6f9ccab1d32 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sun, 9 Dec 2012 09:33:34 +0100 Subject: [PATCH 34/35] Backout changeset 3bb2d53dde34 now that bug 818903 is figured out --- toolkit/crashreporter/tools/symbolstore.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/toolkit/crashreporter/tools/symbolstore.py b/toolkit/crashreporter/tools/symbolstore.py index 238e3091c717..353facdd38b7 100755 --- a/toolkit/crashreporter/tools/symbolstore.py +++ b/toolkit/crashreporter/tools/symbolstore.py @@ -611,21 +611,17 @@ class Dumper_Linux(Dumper): return False def CopyDebug(self, file, debug_file, guid): - import zlib, struct, hashlib # We want to strip out the debug info, and add a # .gnu_debuglink section to the object, so the debugger can # actually load our debug info later. file_dbg = file + ".dbg" - if subprocess.call([self.objcopy, '--only-keep-debug', file, file_dbg], stdout=sys.stderr) == 0 and \ - subprocess.call([self.objcopy, '--add-gnu-debuglink=%s' % file_dbg, file], stdout=sys.stderr) == 0: + if subprocess.call([self.objcopy, '--only-keep-debug', file, file_dbg]) == 0 and \ + subprocess.call([self.objcopy, '--add-gnu-debuglink=%s' % file_dbg, file]) == 0: rel_path = os.path.join(debug_file, guid, debug_file + ".dbg") full_path = os.path.normpath(os.path.join(self.symbol_path, rel_path)) - # Temporary debug information - print >>sys.stderr, read_output('objdump', '-j', '.gnu_debuglink', '-s', file) - print >>sys.stderr, "%s crc: %08x" % (file_dbg, 0xffffffff & zlib.crc32(open(file_dbg).read())) shutil.move(file_dbg, full_path) # gzip the shipped debug files os.system("gzip %s" % full_path) From f96ed5a637d088fe42c0345de6367a283fa097a0 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sun, 9 Dec 2012 09:34:01 +0100 Subject: [PATCH 35/35] Bug 818903 - Link with --build-id when available. r=ted --- configure.in | 7 +++++++ js/src/configure.in | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/configure.in b/configure.in index 9add9089b5c9..6daefd1227c0 100644 --- a/configure.in +++ b/configure.in @@ -1426,6 +1426,13 @@ if test "$GNU_CC"; then AC_TRY_LINK(,,AC_MSG_RESULT([yes]), AC_MSG_RESULT([no]) LDFLAGS=$_SAVE_LDFLAGS) + AC_MSG_CHECKING([for --build-id option to ld]) + _SAVE_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,--build-id" + AC_TRY_LINK(,,AC_MSG_RESULT([yes]), + AC_MSG_RESULT([no]) + LDFLAGS=$_SAVE_LDFLAGS) + # Check for -mssse3 on $CC AC_MSG_CHECKING([if toolchain supports -mssse3 option]) diff --git a/js/src/configure.in b/js/src/configure.in index a379941cf731..4bf9d8996d3b 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -1194,6 +1194,13 @@ if test "$GNU_CC"; then DSO_PIC_CFLAGS='-fPIC' ASFLAGS="$ASFLAGS -fPIC" + AC_MSG_CHECKING([for --build-id option to ld]) + _SAVE_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,--build-id" + AC_TRY_LINK(,,AC_MSG_RESULT([yes]), + AC_MSG_RESULT([no]) + LDFLAGS=$_SAVE_LDFLAGS) + # Turn on GNU-specific warnings: # -Wall - turn on a lot of warnings # -pedantic - this is turned on below