Merge mozilla-central into mozilla-inbound

This commit is contained in:
Ehsan Akhgari 2012-12-13 16:01:29 -05:00
Родитель 948e2b61cf 44f2db652e
Коммит b1cdb90cb6
27 изменённых файлов: 718 добавлений и 216 удалений

Просмотреть файл

@ -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"].

Просмотреть файл

@ -73,3 +73,4 @@ MOZ_EXTENSION_MANAGER=1
MOZ_APP_STATIC_INI=1
MOZ_WEBAPP_RUNTIME=1
MOZ_MEDIA_NAVIGATOR=1
MOZ_PER_WINDOW_PRIVATE_BROWSING=1

Просмотреть файл

@ -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
//

Просмотреть файл

@ -2214,6 +2214,7 @@ NS_IMETHODIMP
nsSocketTransport::SetConnectionFlags(uint32_t value)
{
mConnectionFlags = value;
mIsPrivate = value & nsISocketTransport::NO_PERMANENT_STORAGE;
return NS_OK;
}

Просмотреть файл

@ -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;
using namespace mozilla::net;
@ -470,6 +462,7 @@ nsSocketTransportService::Init()
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
if (obsSvc) {
obsSvc->AddObserver(this, "profile-initial-state", false);
obsSvc->AddObserver(this, "last-pb-context-exited", false);
}
mInitialized = true;
@ -517,6 +510,7 @@ nsSocketTransportService::Shutdown()
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
if (obsSvc) {
obsSvc->RemoveObserver(this, "profile-initial-state");
obsSvc->RemoveObserver(this, "last-pb-context-exited");
}
mozilla::net::NetworkActivityMonitor::Shutdown();
@ -884,9 +878,42 @@ nsSocketTransportService::Observe(nsISupports *subject,
return net::NetworkActivityMonitor::Init(blipInterval);
}
if (!strcmp(topic, "last-pb-context-exited")) {
nsCOMPtr<nsIRunnable> ev =
NS_NewRunnableMethod(this,
&nsSocketTransportService::ClosePrivateConnections);
nsresult rv = Dispatch(ev, nsIEventTarget::DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
void
nsSocketTransportService::ClosePrivateConnections()
{
// Must be called on the socket thread.
#ifdef DEBUG
bool onSTSThread;
IsOnCurrentThread(&onSTSThread);
MOZ_ASSERT(onSTSThread);
#endif
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)
{

Просмотреть файл

@ -190,6 +190,8 @@ private:
void AnalyzeConnection(nsTArray<mozilla::net::SocketInfo> *data,
SocketContext *context, bool aActive);
void ClosePrivateConnections();
};
extern nsSocketTransportService *gSocketTransportService;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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();
};

Просмотреть файл

@ -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

Просмотреть файл

@ -74,6 +74,7 @@ CPPSRCS = \
PSMRunnable.cpp \
nsNSSVersion.cpp \
nsCertificatePrincipal.cpp \
SharedSSLState.cpp \
$(NULL)
ifdef MOZ_XUL
@ -82,7 +83,6 @@ endif
CSRCS += md4.c
EXTRA_DEPS = $(NSS_DEP_LIBS)
DEFINES += \
@ -97,5 +97,11 @@ EXPORTS += \
ScopedNSSTypes.h \
$(NULL)
EXPORTS_NAMESPACES = mozilla
EXPORTS_mozilla += \
PublicSSL.h \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -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

Просмотреть файл

@ -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<nsISSLSocketControl> 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<nsIRecentBadCertsService> recentBadCertsService =
do_GetService(NS_RECENTBADCERTS_CONTRACTID);
nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
nsCOMPtr<nsIRecentBadCerts> 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<nsIX509Cert*>(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<TransportSecurityInfo> 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)
{
}
@ -825,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 &&
@ -911,37 +922,41 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert)
}
nsCOMPtr<nsINSSComponent> 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
@ -977,7 +992,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 +1003,8 @@ SSLServerCertVerificationJob::Dispatch(const void * fdForLogging,
}
RefPtr<SSLServerCertVerificationJob> job(
new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert));
new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert,
providerFlags));
nsresult nrv;
if (!gCertVerificationThreadPool) {
@ -1031,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<SSLServerCertVerificationResult> restart(
new SSLServerCertVerificationResult(mInfoObject, 0));
@ -1042,7 +1059,7 @@ SSLServerCertVerificationJob::Run()
error = PR_GetError();
if (error != 0) {
RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable(
error, mInfoObject, mCert, mFdForLogging));
error, mInfoObject, mCert, mFdForLogging, mProviderFlags));
if (!runnable) {
// CreateCertErrorRunnable set a new error code
error = PR_GetError();
@ -1135,15 +1152,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<const void *>(fd), socketInfo, serverCert);
static_cast<const void *>(fd), socketInfo, serverCert,
providerFlags);
return rv;
}
@ -1151,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;
}
@ -1160,7 +1182,7 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
if (error != 0) {
RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable(
error, socketInfo, serverCert,
static_cast<const void *>(fd)));
static_cast<const void *>(fd), providerFlags));
if (!runnable) {
// CreateCertErrorRunnable sets a new error code when it fails
error = PR_GetError();

Просмотреть файл

@ -0,0 +1,230 @@
/* -*- 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"
#include "nsServiceManagerUtils.h"
#include "nsRecentBadCerts.h"
#include "PSMRunnable.h"
#include "PublicSSL.h"
#include "ssl.h"
#include "nsNetCID.h"
#include "mozilla/unused.h"
using mozilla::psm::SyncRunnableBase;
using mozilla::unused;
namespace {
static PRInt32 sCertOverrideSvcExists = 0;
static PRInt32 sCertDBExists = 0;
class MainThreadClearer : public SyncRunnableBase
{
public:
MainThreadClearer() : mShouldClearSessionCache(false) {}
void RunOnTargetThread() {
// In some cases it's possible to cause PSM/NSS to initialize while XPCOM shutdown
// is in progress. We want to avoid this, since they do not handle the situation well,
// hence the flags to avoid instantiating the services if they don't already exist.
bool certOverrideSvcExists = (bool)PR_ATOMIC_SET(&sCertOverrideSvcExists, 0);
if (certOverrideSvcExists) {
unused << PR_ATOMIC_SET(&sCertOverrideSvcExists, 1);
nsCOMPtr<nsICertOverrideService> icos = do_GetService(NS_CERTOVERRIDE_CONTRACTID);
if (icos) {
icos->ClearValidityOverride(
NS_LITERAL_CSTRING("all:temporary-certificates"),
0);
}
}
bool certDBExists = (bool)PR_ATOMIC_SET(&sCertDBExists, 0);
if (certDBExists) {
unused << PR_ATOMIC_SET(&sCertDBExists, 1);
nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
if (certdb) {
nsCOMPtr<nsIRecentBadCerts> badCerts;
certdb->GetRecentBadCerts(true, getter_AddRefs(badCerts));
if (badCerts) {
badCerts->ResetStoredCerts();
}
}
}
// This needs to be checked on the main thread to avoid racing with NSS
// initialization.
mShouldClearSessionCache = mozilla::psm::PrivateSSLState() &&
mozilla::psm::PrivateSSLState()->SocketCreated();
}
bool mShouldClearSessionCache;
};
} // anonymous namespace
namespace mozilla {
void ClearPrivateSSLState()
{
// This only works if it is called on the socket transport
// service thread immediately after closing all private SSL
// connections.
#ifdef DEBUG
nsresult rv;
nsCOMPtr<nsIEventTarget> sts
= do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
MOZ_ASSERT(NS_SUCCEEDED(rv));
bool onSTSThread;
rv = sts->IsOnCurrentThread(&onSTSThread);
MOZ_ASSERT(NS_SUCCEEDED(rv) && onSTSThread);
#endif
RefPtr<MainThreadClearer> runnable = new MainThreadClearer;
runnable->DispatchToMainThreadAndWait();
// If NSS isn't initialized, this throws an assertion. We guard it by checking if
// the session cache might even have anything worth clearing.
if (runnable->mShouldClearSessionCache) {
SSL_ClearSessionCache();
}
}
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)
, mMutex("SharedSSLState::mMutex")
, mSocketCreated(false)
{
mIOLayerHelpers.Init();
mClientAuthRemember->Init();
}
SharedSSLState::~SharedSSLState()
{
}
void
SharedSSLState::NotePrivateBrowsingStatus()
{
MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
mObserver = new PrivateBrowsingObserver(this);
nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
obsSvc->AddObserver(mObserver, "last-pb-context-exited", false);
}
void
SharedSSLState::ResetStoredData()
{
MOZ_ASSERT(NS_IsMainThread(), "Not on main thread");
mClientAuthRemember->ClearRememberedDecisions();
mIOLayerHelpers.clearStoredData();
}
void
SharedSSLState::NoteSocketCreated()
{
MutexAutoLock lock(mMutex);
mSocketCreated = true;
}
bool
SharedSSLState::SocketCreated()
{
MutexAutoLock lock(mMutex);
return mSocketCreated;
}
/*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;
}
/*static*/ void
SharedSSLState::NoteCertOverrideServiceInstantiated()
{
unused << PR_ATOMIC_SET(&sCertOverrideSvcExists, 1);
}
/*static*/ void
SharedSSLState::NoteCertDBServiceInstantiated()
{
unused << PR_ATOMIC_SET(&sCertDBExists, 1);
}
void
SharedSSLState::Cleanup()
{
mIOLayerHelpers.Cleanup();
}
SharedSSLState*
PublicSSLState()
{
return gPublicState;
}
SharedSSLState*
PrivateSSLState()
{
return gPrivateState;
}
} // namespace psm
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,66 @@
/* -*- 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 nsIObserver;
namespace mozilla {
namespace psm {
class SharedSSLState {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedSSLState)
SharedSSLState();
~SharedSSLState();
static void GlobalInit();
static void GlobalCleanup();
nsClientAuthRememberService* GetClientAuthRememberService() {
return mClientAuthRemember;
}
nsSSLIOLayerHelpers& IOLayerHelpers() {
return mIOLayerHelpers;
}
// Main-thread only
void ResetStoredData();
void NotePrivateBrowsingStatus();
// The following methods may be called from any thread
bool SocketCreated();
void NoteSocketCreated();
static void NoteCertOverrideServiceInstantiated();
static void NoteCertDBServiceInstantiated();
private:
void Cleanup();
nsCOMPtr<nsIObserver> mObserver;
RefPtr<nsClientAuthRememberService> mClientAuthRemember;
nsSSLIOLayerHelpers mIOLayerHelpers;
// True if any sockets have been created that use this shared data.
// Requires synchronization between the socket and main threads for
// reading/writing.
Mutex mMutex;
bool mSocketCreated;
};
SharedSSLState* PublicSSLState();
SharedSSLState* PrivateSSLState();
} // namespace psm
} // namespace mozilla
#endif

Просмотреть файл

@ -19,6 +19,7 @@
#include "nsThreadUtils.h"
#include "nsStringBuffer.h"
#include "ScopedNSSTypes.h"
#include "SharedSSLState.h"
#include "nspr.h"
#include "pk11pub.h"
@ -27,6 +28,7 @@
#include "ssl.h" // For SSL_ClearSessionCache
using namespace mozilla;
using mozilla::psm::SharedSSLState;
static const char kCertOverrideFileName[] = "cert_override.txt";
@ -128,6 +130,7 @@ nsCertOverrideService::Init()
Observe(nullptr, "profile-do-change", nullptr);
}
SharedSSLState::NoteCertOverrideServiceInstantiated();
return NS_OK;
}

Просмотреть файл

@ -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<nsClientAuthRememberService> svc =
PublicSSLState()->GetClientAuthRememberService();
svc->ClearRememberedDecisions();
svc = PrivateSSLState()->GetClientAuthRememberService();
svc->ClearRememberedDecisions();
}
void
nsClientAuthRememberService::RemoveAllFromMemory()
{

Просмотреть файл

@ -128,6 +128,7 @@ public:
nsACString & aCertDBKey, bool *_retval);
void ClearRememberedDecisions();
static void ClearAllRememberedDecisions();
protected:
mozilla::ReentrantMonitor monitor;

Просмотреть файл

@ -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<nsIConsoleService> 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;
}
}

Просмотреть файл

@ -31,6 +31,9 @@
#include "nsIPrompt.h"
#include "nsThreadUtils.h"
#include "ScopedNSSTypes.h"
#include "nsIObserverService.h"
#include "nsRecentBadCerts.h"
#include "SharedSSLState.h"
#include "nspr.h"
#include "certdb.h"
@ -43,6 +46,7 @@
#include "plbase64.h"
using namespace mozilla;
using mozilla::psm::SharedSSLState;
#ifdef PR_LOGGING
extern PRLogModuleInfo* gPIPNSSLog;
@ -54,7 +58,9 @@ static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSCertificateDB, nsIX509CertDB, nsIX509CertDB2)
nsNSSCertificateDB::nsNSSCertificateDB()
: mBadCertsLock("nsNSSCertificateDB::mBadCertsLock")
{
SharedSSLState::NoteCertDBServiceInstantiated();
}
nsNSSCertificateDB::~nsNSSCertificateDB()
@ -1644,3 +1650,21 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval)
NS_ADDREF(*_retval);
return NS_OK;
}
NS_IMETHODIMP
nsNSSCertificateDB::GetRecentBadCerts(bool isPrivate, nsIRecentBadCerts** result)
{
MutexAutoLock lock(mBadCertsLock);
if (isPrivate) {
if (!mPrivateRecentBadCerts) {
mPrivateRecentBadCerts = new nsRecentBadCerts;
}
NS_ADDREF(*result = mPrivateRecentBadCerts);
} else {
if (!mPublicRecentBadCerts) {
mPublicRecentBadCerts = new nsRecentBadCerts;
}
NS_ADDREF(*result = mPublicRecentBadCerts);
}
return NS_OK;
}

Просмотреть файл

@ -7,10 +7,13 @@
#include "nsIX509CertDB.h"
#include "nsIX509CertDB2.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Mutex.h"
#include "certt.h"
class nsCString;
class nsIArray;
class nsRecentBadCerts;
class nsNSSCertificateDB : public nsIX509CertDB, public nsIX509CertDB2
{
@ -48,6 +51,10 @@ private:
uint32_t length);
nsresult handleCACertDownload(nsIArray *x509Certs,
nsIInterfaceRequestor *ctx);
mozilla::Mutex mBadCertsLock;
mozilla::RefPtr<nsRecentBadCerts> mPublicRecentBadCerts;
mozilla::RefPtr<nsRecentBadCerts> mPrivateRecentBadCerts;
};
#define NS_X509CERTDB_CID { /* fb0bbc5c-452e-4783-b32c-80124693d871 */ \

Просмотреть файл

@ -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)
{

Просмотреть файл

@ -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<nsClientAuthRememberService> mClientAuthRememberService;
mozilla::RefPtr<nsCERTValInParamWrapper> mDefaultCERTValInParam;
mozilla::RefPtr<nsCERTValInParamWrapper> mDefaultCERTValInParamLocalOnly;

Просмотреть файл

@ -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<nsCStringHashKey> *nsSSLIOLayerHelpers::mTLSIntolerantSites = nullptr;
nsTHashtable<nsCStringHashKey> *nsSSLIOLayerHelpers::mTLSTolerantSites = nullptr;
nsTHashtable<nsCStringHashKey> *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<nsCStringHashKey>();
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<nsINSSComponent> nssComponent(do_GetService(nssComponentCID, &rv));
RefPtr<nsClientAuthRememberService> cars;
if (nssComponent) {
nssComponent->GetClientAuthRememberService(byRef(cars));
}
RefPtr<nsClientAuthRememberService> 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);
@ -2365,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) {
@ -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;
}
@ -2417,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;
}
@ -2450,7 +2537,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);
@ -2458,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");
@ -2467,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))
@ -2497,6 +2584,8 @@ nsSSLIOLayerAddToSocket(int32_t family,
infoObject->SetHandshakePending(false);
}
infoObject->SharedState().NoteSocketCreated();
return NS_OK;
loser:
NS_IF_RELEASE(infoObject);

Просмотреть файл

@ -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
@ -55,7 +63,11 @@ 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
enum CertVerificationState {
before_cert_verification,
@ -83,6 +95,7 @@ private:
CertVerificationState mCertVerificationState;
mozilla::psm::SharedSSLState& mSharedState;
bool mForSTARTTLS;
bool mSSL3Enabled;
bool mTLSEnabled;
@ -109,37 +122,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<nsCStringHashKey> *mTLSIntolerantSites;
static nsTHashtable<nsCStringHashKey> *mTLSTolerantSites;
mozilla::Mutex *mutex;
nsTHashtable<nsCStringHashKey> *mTLSIntolerantSites;
nsTHashtable<nsCStringHashKey> *mTLSTolerantSites;
static nsTHashtable<nsCStringHashKey> *mRenegoUnrestrictedSites;
static bool mTreatUnsafeNegotiationAsBroken;
static int32_t mWarnLevelMissingRFC5746;
nsTHashtable<nsCStringHashKey> *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<nsIObserver> mPrefObserver;
};
nsresult nsSSLIOLayerNewSocket(int32_t family,

Просмотреть файл

@ -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 }
};

Просмотреть файл

@ -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,22 @@
using namespace mozilla;
NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCertsService,
nsIRecentBadCertsService)
NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCerts,
nsIRecentBadCerts)
nsRecentBadCertsService::nsRecentBadCertsService()
:monitor("nsRecentBadCertsService.monitor")
nsRecentBadCerts::nsRecentBadCerts()
:monitor("nsRecentBadCerts.monitor")
,mNextStorePosition(0)
{
}
nsRecentBadCertsService::~nsRecentBadCertsService()
nsRecentBadCerts::~nsRecentBadCerts()
{
}
nsresult
nsRecentBadCertsService::Init()
{
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 +97,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 +142,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;
}

Просмотреть файл

@ -54,16 +54,14 @@ private:
RecentBadCert &operator=(const RecentBadCert &other) MOZ_DELETE;
};
class nsRecentBadCertsService MOZ_FINAL : public nsIRecentBadCertsService
class nsRecentBadCerts MOZ_FINAL : public nsIRecentBadCerts
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIRECENTBADCERTSSERVICE
NS_DECL_NSIRECENTBADCERTS
nsRecentBadCertsService();
~nsRecentBadCertsService();
nsresult Init();
nsRecentBadCerts();
~nsRecentBadCerts();
protected:
mozilla::ReentrantMonitor monitor;