зеркало из https://github.com/mozilla/gecko-dev.git
Bug 769288 - Part 1: Make PSM more amenable to storing concurrent private and non-private data. r=bsmith
This commit is contained in:
Родитель
63188c06e1
Коммит
b36633903e
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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<SSLServerCertVerificationJob> 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<CertErrorRunnable> runnable(CreateCertErrorRunnable(
|
||||
error, mInfoObject, mCert, mFdForLogging));
|
||||
error, mInfoObject, mCert, mFdForLogging, mProviderFlags));
|
||||
if (!runnable) {
|
||||
// CreateCertErrorRunnable set a new error code
|
||||
error = PR_GetError();
|
||||
|
@ -1136,14 +1148,19 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -1160,7 +1177,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,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<nsIObserverService> 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
|
|
@ -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<nsIObserver> mObserver;
|
||||
RefPtr<nsClientAuthRememberService> mClientAuthRemember;
|
||||
nsSSLIOLayerHelpers mIOLayerHelpers;
|
||||
};
|
||||
|
||||
SharedSSLState* PublicSSLState();
|
||||
SharedSSLState* PrivateSSLState();
|
||||
|
||||
} // namespace psm
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -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,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;
|
||||
}
|
||||
|
|
|
@ -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<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,26 +1931,7 @@ 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);
|
||||
|
||||
mClientAuthRememberService = new nsClientAuthRememberService;
|
||||
if (mClientAuthRememberService)
|
||||
mClientAuthRememberService->Init();
|
||||
SharedSSLState::GlobalInit();
|
||||
|
||||
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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -2408,7 +2491,8 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
|
|||
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);
|
||||
|
|
|
@ -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<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,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<nsIObserverService> 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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче