зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central into mozilla-inbound
This commit is contained in:
Коммит
b1cdb90cb6
|
@ -439,11 +439,6 @@ PrivateBrowsingService.prototype = {
|
||||||
this._unload();
|
this._unload();
|
||||||
break;
|
break;
|
||||||
case "private-browsing":
|
case "private-browsing":
|
||||||
// clear all auth tokens
|
|
||||||
let sdr = Cc["@mozilla.org/security/sdr;1"].
|
|
||||||
getService(Ci.nsISecretDecoderRing);
|
|
||||||
sdr.logoutAndTeardown();
|
|
||||||
|
|
||||||
if (!this._inPrivateBrowsing) {
|
if (!this._inPrivateBrowsing) {
|
||||||
// Clear the error console
|
// Clear the error console
|
||||||
let consoleService = Cc["@mozilla.org/consoleservice;1"].
|
let consoleService = Cc["@mozilla.org/consoleservice;1"].
|
||||||
|
|
|
@ -73,3 +73,4 @@ MOZ_EXTENSION_MANAGER=1
|
||||||
MOZ_APP_STATIC_INI=1
|
MOZ_APP_STATIC_INI=1
|
||||||
MOZ_WEBAPP_RUNTIME=1
|
MOZ_WEBAPP_RUNTIME=1
|
||||||
MOZ_MEDIA_NAVIGATOR=1
|
MOZ_MEDIA_NAVIGATOR=1
|
||||||
|
MOZ_PER_WINDOW_PRIVATE_BROWSING=1
|
||||||
|
|
|
@ -15,6 +15,7 @@ public:
|
||||||
: mCondition(NS_OK)
|
: mCondition(NS_OK)
|
||||||
, mPollFlags(0)
|
, mPollFlags(0)
|
||||||
, mPollTimeout(UINT16_MAX)
|
, mPollTimeout(UINT16_MAX)
|
||||||
|
, mIsPrivate(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -42,6 +43,8 @@ public:
|
||||||
//
|
//
|
||||||
uint16_t mPollTimeout;
|
uint16_t mPollTimeout;
|
||||||
|
|
||||||
|
bool mIsPrivate;
|
||||||
|
|
||||||
//
|
//
|
||||||
// called to service a socket
|
// called to service a socket
|
||||||
//
|
//
|
||||||
|
|
|
@ -2214,6 +2214,7 @@ NS_IMETHODIMP
|
||||||
nsSocketTransport::SetConnectionFlags(uint32_t value)
|
nsSocketTransport::SetConnectionFlags(uint32_t value)
|
||||||
{
|
{
|
||||||
mConnectionFlags = value;
|
mConnectionFlags = value;
|
||||||
|
mIsPrivate = value & nsISocketTransport::NO_PERMANENT_STORAGE;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,15 +23,7 @@
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/Likely.h"
|
#include "mozilla/Likely.h"
|
||||||
|
#include "mozilla/PublicSSL.h"
|
||||||
|
|
||||||
// XXX: There is no good header file to put these in. :(
|
|
||||||
namespace mozilla { namespace psm {
|
|
||||||
|
|
||||||
void InitializeSSLServerCertVerificationThreads();
|
|
||||||
void StopSSLServerCertVerificationThreads();
|
|
||||||
|
|
||||||
} } // namespace mozilla::psm
|
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::net;
|
using namespace mozilla::net;
|
||||||
|
@ -470,6 +462,7 @@ nsSocketTransportService::Init()
|
||||||
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
|
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
|
||||||
if (obsSvc) {
|
if (obsSvc) {
|
||||||
obsSvc->AddObserver(this, "profile-initial-state", false);
|
obsSvc->AddObserver(this, "profile-initial-state", false);
|
||||||
|
obsSvc->AddObserver(this, "last-pb-context-exited", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
mInitialized = true;
|
mInitialized = true;
|
||||||
|
@ -517,6 +510,7 @@ nsSocketTransportService::Shutdown()
|
||||||
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
|
nsCOMPtr<nsIObserverService> obsSvc = services::GetObserverService();
|
||||||
if (obsSvc) {
|
if (obsSvc) {
|
||||||
obsSvc->RemoveObserver(this, "profile-initial-state");
|
obsSvc->RemoveObserver(this, "profile-initial-state");
|
||||||
|
obsSvc->RemoveObserver(this, "last-pb-context-exited");
|
||||||
}
|
}
|
||||||
|
|
||||||
mozilla::net::NetworkActivityMonitor::Shutdown();
|
mozilla::net::NetworkActivityMonitor::Shutdown();
|
||||||
|
@ -884,9 +878,42 @@ nsSocketTransportService::Observe(nsISupports *subject,
|
||||||
|
|
||||||
return net::NetworkActivityMonitor::Init(blipInterval);
|
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;
|
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
|
NS_IMETHODIMP
|
||||||
nsSocketTransportService::GetSendBufferSize(int32_t *value)
|
nsSocketTransportService::GetSendBufferSize(int32_t *value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -190,6 +190,8 @@ private:
|
||||||
|
|
||||||
void AnalyzeConnection(nsTArray<mozilla::net::SocketInfo> *data,
|
void AnalyzeConnection(nsTArray<mozilla::net::SocketInfo> *data,
|
||||||
SocketContext *context, bool aActive);
|
SocketContext *context, bool aActive);
|
||||||
|
|
||||||
|
void ClosePrivateConnections();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern nsSocketTransportService *gSocketTransportService;
|
extern nsSocketTransportService *gSocketTransportService;
|
||||||
|
|
|
@ -88,8 +88,11 @@ function initExceptionDialog() {
|
||||||
// returns true if found and global status could be set
|
// returns true if found and global status could be set
|
||||||
function findRecentBadCert(uri) {
|
function findRecentBadCert(uri) {
|
||||||
try {
|
try {
|
||||||
var recentCertsSvc = Components.classes["@mozilla.org/security/recentbadcerts;1"]
|
var certDB = Components.classes["@mozilla.org/security/x509certdb;1"]
|
||||||
.getService(Components.interfaces.nsIRecentBadCertsService);
|
.getService(Components.interfaces.nsIX509CertDB);
|
||||||
|
if (!certDB)
|
||||||
|
return false;
|
||||||
|
var recentCertsSvc = certDB.getRecentBadCertsService(inPrivateBrowsingMode());
|
||||||
if (!recentCertsSvc)
|
if (!recentCertsSvc)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,8 @@ interface nsISSLStatus;
|
||||||
* The implementation will decide how many entries it will hold,
|
* The implementation will decide how many entries it will hold,
|
||||||
* the number is expected to be small.
|
* the number is expected to be small.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(a5ae8b05-a76e-408f-b0ba-02a831265749)]
|
[scriptable, uuid(0fed7784-d152-44d6-95a7-67a59024de0f)]
|
||||||
interface nsIRecentBadCertsService : nsISupports {
|
interface nsIRecentBadCerts : nsISupports {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the recently seen bad ssl status for the given hostname:port.
|
* 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.
|
* 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,
|
void addBadCert(in AString aHostNameWithPort,
|
||||||
in nsISSLStatus aStatus);
|
in nsISSLStatus aStatus);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all stored cert data.
|
||||||
|
*/
|
||||||
|
void resetStoredCerts();
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,6 +12,7 @@ interface nsIX509Cert3;
|
||||||
interface nsIFile;
|
interface nsIFile;
|
||||||
interface nsIInterfaceRequestor;
|
interface nsIInterfaceRequestor;
|
||||||
interface nsIZipReader;
|
interface nsIZipReader;
|
||||||
|
interface nsIRecentBadCerts;
|
||||||
|
|
||||||
%{C++
|
%{C++
|
||||||
#define NS_X509CERTDB_CONTRACTID "@mozilla.org/security/x509certdb;1"
|
#define NS_X509CERTDB_CONTRACTID "@mozilla.org/security/x509certdb;1"
|
||||||
|
@ -29,7 +30,7 @@ interface nsIOpenSignedJARFileCallback : nsISupports
|
||||||
* This represents a service to access and manipulate
|
* This represents a service to access and manipulate
|
||||||
* X.509 certificates stored in a database.
|
* X.509 certificates stored in a database.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(735d0363-e219-4387-b5c6-72e800c3ea0b)]
|
[scriptable, uuid(a18df2a5-84a9-46cd-9140-3fdb3879d9ff)]
|
||||||
interface nsIX509CertDB : nsISupports {
|
interface nsIX509CertDB : nsISupports {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -264,6 +265,16 @@ interface nsIX509CertDB : nsISupports {
|
||||||
*/
|
*/
|
||||||
nsIX509Cert constructX509FromBase64(in string base64);
|
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
|
* 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
|
* valid signature. To be considered valid, there must be exactly one
|
||||||
|
|
|
@ -74,6 +74,7 @@ CPPSRCS = \
|
||||||
PSMRunnable.cpp \
|
PSMRunnable.cpp \
|
||||||
nsNSSVersion.cpp \
|
nsNSSVersion.cpp \
|
||||||
nsCertificatePrincipal.cpp \
|
nsCertificatePrincipal.cpp \
|
||||||
|
SharedSSLState.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
ifdef MOZ_XUL
|
ifdef MOZ_XUL
|
||||||
|
@ -82,7 +83,6 @@ endif
|
||||||
|
|
||||||
CSRCS += md4.c
|
CSRCS += md4.c
|
||||||
|
|
||||||
|
|
||||||
EXTRA_DEPS = $(NSS_DEP_LIBS)
|
EXTRA_DEPS = $(NSS_DEP_LIBS)
|
||||||
|
|
||||||
DEFINES += \
|
DEFINES += \
|
||||||
|
@ -97,5 +97,11 @@ EXPORTS += \
|
||||||
ScopedNSSTypes.h \
|
ScopedNSSTypes.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
EXPORTS_NAMESPACES = mozilla
|
||||||
|
|
||||||
|
EXPORTS_mozilla += \
|
||||||
|
PublicSSL.h \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
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 "nsIConsoleService.h"
|
||||||
#include "PSMRunnable.h"
|
#include "PSMRunnable.h"
|
||||||
#include "ScopedNSSTypes.h"
|
#include "ScopedNSSTypes.h"
|
||||||
|
#include "SharedSSLState.h"
|
||||||
|
|
||||||
#include "ssl.h"
|
#include "ssl.h"
|
||||||
#include "secerr.h"
|
#include "secerr.h"
|
||||||
|
@ -238,13 +239,15 @@ class CertErrorRunnable : public SyncRunnableBase
|
||||||
uint32_t collectedErrors,
|
uint32_t collectedErrors,
|
||||||
PRErrorCode errorCodeTrust,
|
PRErrorCode errorCodeTrust,
|
||||||
PRErrorCode errorCodeMismatch,
|
PRErrorCode errorCodeMismatch,
|
||||||
PRErrorCode errorCodeExpired)
|
PRErrorCode errorCodeExpired,
|
||||||
|
uint32_t providerFlags)
|
||||||
: mFdForLogging(fdForLogging), mCert(cert), mInfoObject(infoObject),
|
: mFdForLogging(fdForLogging), mCert(cert), mInfoObject(infoObject),
|
||||||
mDefaultErrorCodeToReport(defaultErrorCodeToReport),
|
mDefaultErrorCodeToReport(defaultErrorCodeToReport),
|
||||||
mCollectedErrors(collectedErrors),
|
mCollectedErrors(collectedErrors),
|
||||||
mErrorCodeTrust(errorCodeTrust),
|
mErrorCodeTrust(errorCodeTrust),
|
||||||
mErrorCodeMismatch(errorCodeMismatch),
|
mErrorCodeMismatch(errorCodeMismatch),
|
||||||
mErrorCodeExpired(errorCodeExpired)
|
mErrorCodeExpired(errorCodeExpired),
|
||||||
|
mProviderFlags(providerFlags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,6 +264,7 @@ private:
|
||||||
const PRErrorCode mErrorCodeTrust;
|
const PRErrorCode mErrorCodeTrust;
|
||||||
const PRErrorCode mErrorCodeMismatch;
|
const PRErrorCode mErrorCodeMismatch;
|
||||||
const PRErrorCode mErrorCodeExpired;
|
const PRErrorCode mErrorCodeExpired;
|
||||||
|
const uint32_t mProviderFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
SSLServerCertVerificationResult *
|
SSLServerCertVerificationResult *
|
||||||
|
@ -296,12 +300,8 @@ CertErrorRunnable::CheckCertOverrides()
|
||||||
if (NS_SUCCEEDED(nsrv)) {
|
if (NS_SUCCEEDED(nsrv)) {
|
||||||
nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface(
|
nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface(
|
||||||
NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject));
|
NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject));
|
||||||
uint32_t flags = 0;
|
|
||||||
if (sslSocketControl) {
|
|
||||||
sslSocketControl->GetProviderFlags(&flags);
|
|
||||||
}
|
|
||||||
nsrv = stss->IsStsHost(mInfoObject->GetHostName(),
|
nsrv = stss->IsStsHost(mInfoObject->GetHostName(),
|
||||||
flags,
|
mProviderFlags,
|
||||||
&strictTransportSecurityEnabled);
|
&strictTransportSecurityEnabled);
|
||||||
}
|
}
|
||||||
if (NS_FAILED(nsrv)) {
|
if (NS_FAILED(nsrv)) {
|
||||||
|
@ -371,8 +371,12 @@ CertErrorRunnable::CheckCertOverrides()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIRecentBadCertsService> recentBadCertsService =
|
nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
|
||||||
do_GetService(NS_RECENTBADCERTS_CONTRACTID);
|
nsCOMPtr<nsIRecentBadCerts> recentBadCertsService;
|
||||||
|
if (certdb) {
|
||||||
|
bool isPrivate = mProviderFlags & nsISocketProvider::NO_PERMANENT_STORAGE;
|
||||||
|
certdb->GetRecentBadCerts(isPrivate, getter_AddRefs(recentBadCertsService));
|
||||||
|
}
|
||||||
|
|
||||||
if (recentBadCertsService) {
|
if (recentBadCertsService) {
|
||||||
NS_ConvertUTF8toUTF16 hostWithPortStringUTF16(hostWithPortString);
|
NS_ConvertUTF8toUTF16 hostWithPortStringUTF16(hostWithPortString);
|
||||||
|
@ -418,7 +422,8 @@ CertErrorRunnable *
|
||||||
CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport,
|
CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport,
|
||||||
TransportSecurityInfo * infoObject,
|
TransportSecurityInfo * infoObject,
|
||||||
CERTCertificate * cert,
|
CERTCertificate * cert,
|
||||||
const void * fdForLogging)
|
const void * fdForLogging,
|
||||||
|
uint32_t providerFlags)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(infoObject);
|
MOZ_ASSERT(infoObject);
|
||||||
MOZ_ASSERT(cert);
|
MOZ_ASSERT(cert);
|
||||||
|
@ -567,7 +572,8 @@ CreateCertErrorRunnable(PRErrorCode defaultErrorCodeToReport,
|
||||||
static_cast<nsIX509Cert*>(nssCert.get()),
|
static_cast<nsIX509Cert*>(nssCert.get()),
|
||||||
infoObject, defaultErrorCodeToReport,
|
infoObject, defaultErrorCodeToReport,
|
||||||
collected_errors, errorCodeTrust,
|
collected_errors, errorCodeTrust,
|
||||||
errorCodeMismatch, errorCodeExpired);
|
errorCodeMismatch, errorCodeExpired,
|
||||||
|
providerFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When doing async cert processing, we dispatch one of these runnables to the
|
// 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
|
// Must be called only on the socket transport thread
|
||||||
static SECStatus Dispatch(const void * fdForLogging,
|
static SECStatus Dispatch(const void * fdForLogging,
|
||||||
TransportSecurityInfo * infoObject,
|
TransportSecurityInfo * infoObject,
|
||||||
CERTCertificate * serverCert);
|
CERTCertificate * serverCert,
|
||||||
|
uint32_t providerFlags);
|
||||||
private:
|
private:
|
||||||
NS_DECL_NSIRUNNABLE
|
NS_DECL_NSIRUNNABLE
|
||||||
|
|
||||||
// Must be called only on the socket transport thread
|
// Must be called only on the socket transport thread
|
||||||
SSLServerCertVerificationJob(const void * fdForLogging,
|
SSLServerCertVerificationJob(const void * fdForLogging,
|
||||||
TransportSecurityInfo * infoObject,
|
TransportSecurityInfo * infoObject,
|
||||||
CERTCertificate * cert);
|
CERTCertificate * cert,
|
||||||
|
uint32_t providerFlags);
|
||||||
const void * const mFdForLogging;
|
const void * const mFdForLogging;
|
||||||
const RefPtr<TransportSecurityInfo> mInfoObject;
|
const RefPtr<TransportSecurityInfo> mInfoObject;
|
||||||
const ScopedCERTCertificate mCert;
|
const ScopedCERTCertificate mCert;
|
||||||
|
const uint32_t mProviderFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
SSLServerCertVerificationJob::SSLServerCertVerificationJob(
|
SSLServerCertVerificationJob::SSLServerCertVerificationJob(
|
||||||
const void * fdForLogging, TransportSecurityInfo * infoObject,
|
const void * fdForLogging, TransportSecurityInfo * infoObject,
|
||||||
CERTCertificate * cert)
|
CERTCertificate * cert, uint32_t providerFlags)
|
||||||
: mFdForLogging(fdForLogging)
|
: mFdForLogging(fdForLogging)
|
||||||
, mInfoObject(infoObject)
|
, mInfoObject(infoObject)
|
||||||
, mCert(CERT_DupCertificate(cert))
|
, mCert(CERT_DupCertificate(cert))
|
||||||
|
, mProviderFlags(providerFlags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,7 +835,8 @@ BlockServerCertChangeForSpdy(nsNSSSocketInfo *infoObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert)
|
AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert,
|
||||||
|
uint32_t providerFlags)
|
||||||
{
|
{
|
||||||
if (cert->serialNumber.data &&
|
if (cert->serialNumber.data &&
|
||||||
cert->issuerName &&
|
cert->issuerName &&
|
||||||
|
@ -911,37 +922,41 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert)
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsINSSComponent> nssComponent;
|
nsCOMPtr<nsINSSComponent> nssComponent;
|
||||||
|
|
||||||
for (CERTCertListNode *node = CERT_LIST_HEAD(certList);
|
|
||||||
!CERT_LIST_END(node, certList);
|
|
||||||
node = CERT_LIST_NEXT(node)) {
|
|
||||||
|
|
||||||
if (node->cert->slot) {
|
// We want to avoid storing any intermediate cert information when browsing
|
||||||
// This cert was found on a token, no need to remember it in the temp db.
|
// in private, transient contexts.
|
||||||
continue;
|
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) {
|
if (node->cert->slot) {
|
||||||
// We don't need to remember certs already stored in perm db.
|
// This cert was found on a token, no need to remember it in the temp db.
|
||||||
continue;
|
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->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
|
// The connection may get terminated, for example, if the server requires
|
||||||
|
@ -977,7 +992,8 @@ AuthCertificate(TransportSecurityInfo * infoObject, CERTCertificate * cert)
|
||||||
/*static*/ SECStatus
|
/*static*/ SECStatus
|
||||||
SSLServerCertVerificationJob::Dispatch(const void * fdForLogging,
|
SSLServerCertVerificationJob::Dispatch(const void * fdForLogging,
|
||||||
TransportSecurityInfo * infoObject,
|
TransportSecurityInfo * infoObject,
|
||||||
CERTCertificate * serverCert)
|
CERTCertificate * serverCert,
|
||||||
|
uint32_t providerFlags)
|
||||||
{
|
{
|
||||||
// Runs on the socket transport thread
|
// Runs on the socket transport thread
|
||||||
if (!infoObject || !serverCert) {
|
if (!infoObject || !serverCert) {
|
||||||
|
@ -987,7 +1003,8 @@ SSLServerCertVerificationJob::Dispatch(const void * fdForLogging,
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<SSLServerCertVerificationJob> job(
|
RefPtr<SSLServerCertVerificationJob> job(
|
||||||
new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert));
|
new SSLServerCertVerificationJob(fdForLogging, infoObject, serverCert,
|
||||||
|
providerFlags));
|
||||||
|
|
||||||
nsresult nrv;
|
nsresult nrv;
|
||||||
if (!gCertVerificationThreadPool) {
|
if (!gCertVerificationThreadPool) {
|
||||||
|
@ -1031,7 +1048,7 @@ SSLServerCertVerificationJob::Run()
|
||||||
// Reset the error code here so we can detect if AuthCertificate fails to
|
// Reset the error code here so we can detect if AuthCertificate fails to
|
||||||
// set the error code if/when it fails.
|
// set the error code if/when it fails.
|
||||||
PR_SetError(0, 0);
|
PR_SetError(0, 0);
|
||||||
SECStatus rv = AuthCertificate(mInfoObject, mCert);
|
SECStatus rv = AuthCertificate(mInfoObject, mCert, mProviderFlags);
|
||||||
if (rv == SECSuccess) {
|
if (rv == SECSuccess) {
|
||||||
RefPtr<SSLServerCertVerificationResult> restart(
|
RefPtr<SSLServerCertVerificationResult> restart(
|
||||||
new SSLServerCertVerificationResult(mInfoObject, 0));
|
new SSLServerCertVerificationResult(mInfoObject, 0));
|
||||||
|
@ -1042,7 +1059,7 @@ SSLServerCertVerificationJob::Run()
|
||||||
error = PR_GetError();
|
error = PR_GetError();
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable(
|
RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable(
|
||||||
error, mInfoObject, mCert, mFdForLogging));
|
error, mInfoObject, mCert, mFdForLogging, mProviderFlags));
|
||||||
if (!runnable) {
|
if (!runnable) {
|
||||||
// CreateCertErrorRunnable set a new error code
|
// CreateCertErrorRunnable set a new error code
|
||||||
error = PR_GetError();
|
error = PR_GetError();
|
||||||
|
@ -1135,15 +1152,20 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
|
||||||
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
PR_SetError(PR_UNKNOWN_ERROR, 0);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t providerFlags = 0;
|
||||||
|
socketInfo->GetProviderFlags(&providerFlags);
|
||||||
|
|
||||||
if (onSTSThread) {
|
if (onSTSThread) {
|
||||||
|
|
||||||
// We *must* do certificate verification on a background thread because
|
// We *must* do certificate verification on a background thread because
|
||||||
// we need the socket transport thread to be free for our OCSP requests,
|
// we need the socket transport thread to be free for our OCSP requests,
|
||||||
// and we *want* to do certificate verification on a background thread
|
// and we *want* to do certificate verification on a background thread
|
||||||
// because of the performance benefits of doing so.
|
// because of the performance benefits of doing so.
|
||||||
socketInfo->SetCertVerificationWaiting();
|
socketInfo->SetCertVerificationWaiting();
|
||||||
SECStatus rv = SSLServerCertVerificationJob::Dispatch(
|
SECStatus rv = SSLServerCertVerificationJob::Dispatch(
|
||||||
static_cast<const void *>(fd), socketInfo, serverCert);
|
static_cast<const void *>(fd), socketInfo, serverCert,
|
||||||
|
providerFlags);
|
||||||
return rv;
|
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
|
// 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
|
// of our SSLServerCertVerificationResult event, and/or it might not even be
|
||||||
// a non-blocking socket.
|
// a non-blocking socket.
|
||||||
SECStatus rv = AuthCertificate(socketInfo, serverCert);
|
SECStatus rv = AuthCertificate(socketInfo, serverCert, providerFlags);
|
||||||
if (rv == SECSuccess) {
|
if (rv == SECSuccess) {
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
@ -1160,7 +1182,7 @@ AuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable(
|
RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable(
|
||||||
error, socketInfo, serverCert,
|
error, socketInfo, serverCert,
|
||||||
static_cast<const void *>(fd)));
|
static_cast<const void *>(fd), providerFlags));
|
||||||
if (!runnable) {
|
if (!runnable) {
|
||||||
// CreateCertErrorRunnable sets a new error code when it fails
|
// CreateCertErrorRunnable sets a new error code when it fails
|
||||||
error = PR_GetError();
|
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 "nsThreadUtils.h"
|
||||||
#include "nsStringBuffer.h"
|
#include "nsStringBuffer.h"
|
||||||
#include "ScopedNSSTypes.h"
|
#include "ScopedNSSTypes.h"
|
||||||
|
#include "SharedSSLState.h"
|
||||||
|
|
||||||
#include "nspr.h"
|
#include "nspr.h"
|
||||||
#include "pk11pub.h"
|
#include "pk11pub.h"
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
#include "ssl.h" // For SSL_ClearSessionCache
|
#include "ssl.h" // For SSL_ClearSessionCache
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
using mozilla::psm::SharedSSLState;
|
||||||
|
|
||||||
static const char kCertOverrideFileName[] = "cert_override.txt";
|
static const char kCertOverrideFileName[] = "cert_override.txt";
|
||||||
|
|
||||||
|
@ -128,6 +130,7 @@ nsCertOverrideService::Init()
|
||||||
Observe(nullptr, "profile-do-change", nullptr);
|
Observe(nullptr, "profile-do-change", nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SharedSSLState::NoteCertOverrideServiceInstantiated();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,10 @@
|
||||||
#include "pk11pub.h"
|
#include "pk11pub.h"
|
||||||
#include "certdb.h"
|
#include "certdb.h"
|
||||||
#include "sechash.h"
|
#include "sechash.h"
|
||||||
|
#include "SharedSSLState.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
using namespace mozilla::psm;
|
||||||
|
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsClientAuthRememberService,
|
NS_IMPL_THREADSAFE_ISUPPORTS2(nsClientAuthRememberService,
|
||||||
nsIObserver,
|
nsIObserver,
|
||||||
|
@ -80,6 +82,16 @@ void nsClientAuthRememberService::ClearRememberedDecisions()
|
||||||
RemoveAllFromMemory();
|
RemoveAllFromMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsClientAuthRememberService::ClearAllRememberedDecisions()
|
||||||
|
{
|
||||||
|
RefPtr<nsClientAuthRememberService> svc =
|
||||||
|
PublicSSLState()->GetClientAuthRememberService();
|
||||||
|
svc->ClearRememberedDecisions();
|
||||||
|
|
||||||
|
svc = PrivateSSLState()->GetClientAuthRememberService();
|
||||||
|
svc->ClearRememberedDecisions();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsClientAuthRememberService::RemoveAllFromMemory()
|
nsClientAuthRememberService::RemoveAllFromMemory()
|
||||||
{
|
{
|
||||||
|
|
|
@ -128,6 +128,7 @@ public:
|
||||||
nsACString & aCertDBKey, bool *_retval);
|
nsACString & aCertDBKey, bool *_retval);
|
||||||
|
|
||||||
void ClearRememberedDecisions();
|
void ClearRememberedDecisions();
|
||||||
|
static void ClearAllRememberedDecisions();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mozilla::ReentrantMonitor monitor;
|
mozilla::ReentrantMonitor monitor;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "nsIConsoleService.h"
|
#include "nsIConsoleService.h"
|
||||||
#include "nsIHttpChannelInternal.h"
|
#include "nsIHttpChannelInternal.h"
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
|
#include "SharedSSLState.h"
|
||||||
|
|
||||||
#include "ssl.h"
|
#include "ssl.h"
|
||||||
#include "sslproto.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
|
// If the handshake completed, then we know the site is TLS tolerant (if this
|
||||||
// was a TLS connection).
|
// was a TLS connection).
|
||||||
nsSSLIOLayerHelpers::rememberTolerantSite(infoObject);
|
nsSSLIOLayerHelpers& ioLayerHelpers = infoObject->SharedState().IOLayerHelpers();
|
||||||
|
ioLayerHelpers.rememberTolerantSite(infoObject);
|
||||||
|
|
||||||
if (SECSuccess != SSL_SecurityStatus(fd, &sslStatus, &cipherName, &keyLength,
|
if (SECSuccess != SSL_SecurityStatus(fd, &sslStatus, &cipherName, &keyLength,
|
||||||
&encryptBits, &signer, nullptr)) {
|
&encryptBits, &signer, nullptr)) {
|
||||||
|
@ -859,7 +861,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
||||||
if (SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn, &siteSupportsSafeRenego) != SECSuccess
|
if (SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn, &siteSupportsSafeRenego) != SECSuccess
|
||||||
|| !siteSupportsSafeRenego) {
|
|| !siteSupportsSafeRenego) {
|
||||||
|
|
||||||
bool wantWarning = (nsSSLIOLayerHelpers::getWarnLevelMissingRFC5746() > 0);
|
bool wantWarning = (ioLayerHelpers.getWarnLevelMissingRFC5746() > 0);
|
||||||
|
|
||||||
nsCOMPtr<nsIConsoleService> console;
|
nsCOMPtr<nsIConsoleService> console;
|
||||||
if (infoObject && wantWarning) {
|
if (infoObject && wantWarning) {
|
||||||
|
@ -875,7 +877,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
||||||
console->LogStringMessage(msg.get());
|
console->LogStringMessage(msg.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nsSSLIOLayerHelpers::treatUnsafeNegotiationAsBroken()) {
|
if (ioLayerHelpers.treatUnsafeNegotiationAsBroken()) {
|
||||||
secStatus = nsIWebProgressListener::STATE_IS_BROKEN;
|
secStatus = nsIWebProgressListener::STATE_IS_BROKEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,9 @@
|
||||||
#include "nsIPrompt.h"
|
#include "nsIPrompt.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "ScopedNSSTypes.h"
|
#include "ScopedNSSTypes.h"
|
||||||
|
#include "nsIObserverService.h"
|
||||||
|
#include "nsRecentBadCerts.h"
|
||||||
|
#include "SharedSSLState.h"
|
||||||
|
|
||||||
#include "nspr.h"
|
#include "nspr.h"
|
||||||
#include "certdb.h"
|
#include "certdb.h"
|
||||||
|
@ -43,6 +46,7 @@
|
||||||
#include "plbase64.h"
|
#include "plbase64.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
using mozilla::psm::SharedSSLState;
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
extern PRLogModuleInfo* gPIPNSSLog;
|
extern PRLogModuleInfo* gPIPNSSLog;
|
||||||
|
@ -54,7 +58,9 @@ static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSCertificateDB, nsIX509CertDB, nsIX509CertDB2)
|
NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSCertificateDB, nsIX509CertDB, nsIX509CertDB2)
|
||||||
|
|
||||||
nsNSSCertificateDB::nsNSSCertificateDB()
|
nsNSSCertificateDB::nsNSSCertificateDB()
|
||||||
|
: mBadCertsLock("nsNSSCertificateDB::mBadCertsLock")
|
||||||
{
|
{
|
||||||
|
SharedSSLState::NoteCertDBServiceInstantiated();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsNSSCertificateDB::~nsNSSCertificateDB()
|
nsNSSCertificateDB::~nsNSSCertificateDB()
|
||||||
|
@ -1644,3 +1650,21 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval)
|
||||||
NS_ADDREF(*_retval);
|
NS_ADDREF(*_retval);
|
||||||
return NS_OK;
|
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 "nsIX509CertDB.h"
|
||||||
#include "nsIX509CertDB2.h"
|
#include "nsIX509CertDB2.h"
|
||||||
|
#include "mozilla/RefPtr.h"
|
||||||
|
#include "mozilla/Mutex.h"
|
||||||
#include "certt.h"
|
#include "certt.h"
|
||||||
|
|
||||||
class nsCString;
|
class nsCString;
|
||||||
class nsIArray;
|
class nsIArray;
|
||||||
|
class nsRecentBadCerts;
|
||||||
|
|
||||||
class nsNSSCertificateDB : public nsIX509CertDB, public nsIX509CertDB2
|
class nsNSSCertificateDB : public nsIX509CertDB, public nsIX509CertDB2
|
||||||
{
|
{
|
||||||
|
@ -48,6 +51,10 @@ private:
|
||||||
uint32_t length);
|
uint32_t length);
|
||||||
nsresult handleCACertDownload(nsIArray *x509Certs,
|
nsresult handleCACertDownload(nsIArray *x509Certs,
|
||||||
nsIInterfaceRequestor *ctx);
|
nsIInterfaceRequestor *ctx);
|
||||||
|
|
||||||
|
mozilla::Mutex mBadCertsLock;
|
||||||
|
mozilla::RefPtr<nsRecentBadCerts> mPublicRecentBadCerts;
|
||||||
|
mozilla::RefPtr<nsRecentBadCerts> mPrivateRecentBadCerts;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NS_X509CERTDB_CID { /* fb0bbc5c-452e-4783-b32c-80124693d871 */ \
|
#define NS_X509CERTDB_CID { /* fb0bbc5c-452e-4783-b32c-80124693d871 */ \
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
#include "nsSmartCardEvent.h"
|
#include "nsSmartCardEvent.h"
|
||||||
#include "nsIKeyModule.h"
|
#include "nsIKeyModule.h"
|
||||||
#include "ScopedNSSTypes.h"
|
#include "ScopedNSSTypes.h"
|
||||||
|
#include "SharedSSLState.h"
|
||||||
|
|
||||||
#include "nss.h"
|
#include "nss.h"
|
||||||
#include "pk11func.h"
|
#include "pk11func.h"
|
||||||
|
@ -400,7 +401,7 @@ nsNSSComponent::~nsNSSComponent()
|
||||||
// All cleanup code requiring services needs to happen in xpcom_shutdown
|
// All cleanup code requiring services needs to happen in xpcom_shutdown
|
||||||
|
|
||||||
ShutdownNSS();
|
ShutdownNSS();
|
||||||
nsSSLIOLayerHelpers::Cleanup();
|
SharedSSLState::GlobalCleanup();
|
||||||
RememberCertErrorsTable::Cleanup();
|
RememberCertErrorsTable::Cleanup();
|
||||||
--mInstanceCount;
|
--mInstanceCount;
|
||||||
delete mShutdownObjectList;
|
delete mShutdownObjectList;
|
||||||
|
@ -1860,9 +1861,6 @@ nsNSSComponent::ShutdownNSS()
|
||||||
|
|
||||||
ShutdownSmartCardThreads();
|
ShutdownSmartCardThreads();
|
||||||
SSL_ClearSessionCache();
|
SSL_ClearSessionCache();
|
||||||
if (mClientAuthRememberService) {
|
|
||||||
mClientAuthRememberService->ClearRememberedDecisions();
|
|
||||||
}
|
|
||||||
UnloadLoadableRoots();
|
UnloadLoadableRoots();
|
||||||
CleanupIdentityInfo();
|
CleanupIdentityInfo();
|
||||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("evaporating psm resources\n"));
|
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("evaporating psm resources\n"));
|
||||||
|
@ -1933,27 +1931,8 @@ nsNSSComponent::Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
RememberCertErrorsTable::Init();
|
RememberCertErrorsTable::Init();
|
||||||
nsSSLIOLayerHelpers::Init();
|
SharedSSLState::GlobalInit();
|
||||||
char *unrestricted_hosts=nullptr;
|
|
||||||
mPrefBranch->GetCharPref("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts);
|
|
||||||
if (unrestricted_hosts) {
|
|
||||||
nsSSLIOLayerHelpers::setRenegoUnrestrictedSites(nsDependentCString(unrestricted_hosts));
|
|
||||||
nsMemory::Free(unrestricted_hosts);
|
|
||||||
unrestricted_hosts=nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool enabled = false;
|
|
||||||
mPrefBranch->GetBoolPref("security.ssl.treat_unsafe_negotiation_as_broken", &enabled);
|
|
||||||
nsSSLIOLayerHelpers::setTreatUnsafeNegotiationAsBroken(enabled);
|
|
||||||
|
|
||||||
int32_t warnLevel = 1;
|
|
||||||
mPrefBranch->GetIntPref("security.ssl.warn_missing_rfc5746", &warnLevel);
|
|
||||||
nsSSLIOLayerHelpers::setWarnLevelMissingRFC5746(warnLevel);
|
|
||||||
|
|
||||||
mClientAuthRememberService = new nsClientAuthRememberService;
|
|
||||||
if (mClientAuthRememberService)
|
|
||||||
mClientAuthRememberService->Init();
|
|
||||||
|
|
||||||
createBackgroundThreads();
|
createBackgroundThreads();
|
||||||
if (!mCertVerificationThread)
|
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);
|
mPrefBranch->GetBoolPref("security.ssl.allow_unrestricted_renego_everywhere__temporarily_available_pref", &enabled);
|
||||||
SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION,
|
SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION,
|
||||||
enabled ? SSL_RENEGOTIATE_UNRESTRICTED : SSL_RENEGOTIATE_REQUIRES_XTN);
|
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
|
#ifdef SSL_ENABLE_FALSE_START // Requires NSS 3.12.8
|
||||||
} else if (prefName.Equals("security.ssl.enable_false_start")) {
|
} else if (prefName.Equals("security.ssl.enable_false_start")) {
|
||||||
mPrefBranch->GetBoolPref("security.ssl.enable_false_start", &enabled);
|
mPrefBranch->GetBoolPref("security.ssl.enable_false_start", &enabled);
|
||||||
|
@ -2387,9 +2352,7 @@ nsresult nsNSSComponent::LogoutAuthenticatedPK11()
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mClientAuthRememberService) {
|
nsClientAuthRememberService::ClearAllRememberedDecisions();
|
||||||
mClientAuthRememberService->ClearRememberedDecisions();
|
|
||||||
}
|
|
||||||
|
|
||||||
return mShutdownObjectList->doPK11Logout();
|
return mShutdownObjectList->doPK11Logout();
|
||||||
}
|
}
|
||||||
|
@ -2568,14 +2531,6 @@ nsNSSComponent::DoProfileChangeNetRestore()
|
||||||
mIsNetworkDown = false;
|
mIsNetworkDown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNSSComponent::GetClientAuthRememberService(nsClientAuthRememberService **cars)
|
|
||||||
{
|
|
||||||
NS_ENSURE_ARG_POINTER(cars);
|
|
||||||
NS_IF_ADDREF(*cars = mClientAuthRememberService);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsNSSComponent::IsNSSInitialized(bool *initialized)
|
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 DispatchEvent(const nsAString &eventType, const nsAString &token) = 0;
|
||||||
|
|
||||||
NS_IMETHOD GetClientAuthRememberService(nsClientAuthRememberService **cars) = 0;
|
|
||||||
|
|
||||||
NS_IMETHOD EnsureIdentityInfoLoaded() = 0;
|
NS_IMETHOD EnsureIdentityInfoLoaded() = 0;
|
||||||
|
|
||||||
NS_IMETHOD IsNSSInitialized(bool *initialized) = 0;
|
NS_IMETHOD IsNSSInitialized(bool *initialized) = 0;
|
||||||
|
@ -259,7 +257,6 @@ public:
|
||||||
NS_IMETHOD ShutdownSmartCardThread(SECMODModule *module);
|
NS_IMETHOD ShutdownSmartCardThread(SECMODModule *module);
|
||||||
NS_IMETHOD PostEvent(const nsAString &eventType, const nsAString &token);
|
NS_IMETHOD PostEvent(const nsAString &eventType, const nsAString &token);
|
||||||
NS_IMETHOD DispatchEvent(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 EnsureIdentityInfoLoaded();
|
||||||
NS_IMETHOD IsNSSInitialized(bool *initialized);
|
NS_IMETHOD IsNSSInitialized(bool *initialized);
|
||||||
|
|
||||||
|
@ -327,7 +324,6 @@ private:
|
||||||
nsCertVerificationThread *mCertVerificationThread;
|
nsCertVerificationThread *mCertVerificationThread;
|
||||||
|
|
||||||
nsNSSHttpInterface mHttpForNSS;
|
nsNSSHttpInterface mHttpForNSS;
|
||||||
mozilla::RefPtr<nsClientAuthRememberService> mClientAuthRememberService;
|
|
||||||
mozilla::RefPtr<nsCERTValInParamWrapper> mDefaultCERTValInParam;
|
mozilla::RefPtr<nsCERTValInParamWrapper> mDefaultCERTValInParam;
|
||||||
mozilla::RefPtr<nsCERTValInParamWrapper> mDefaultCERTValInParamLocalOnly;
|
mozilla::RefPtr<nsCERTValInParamWrapper> mDefaultCERTValInParamLocalOnly;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include "nsIConsoleService.h"
|
#include "nsIConsoleService.h"
|
||||||
#include "PSMRunnable.h"
|
#include "PSMRunnable.h"
|
||||||
#include "ScopedNSSTypes.h"
|
#include "ScopedNSSTypes.h"
|
||||||
|
#include "SharedSSLState.h"
|
||||||
|
#include "mozilla/Preferences.h"
|
||||||
|
|
||||||
#include "ssl.h"
|
#include "ssl.h"
|
||||||
#include "secerr.h"
|
#include "secerr.h"
|
||||||
|
@ -63,9 +65,10 @@ typedef enum {ASK, AUTO} SSM_UserCertChoice;
|
||||||
extern PRLogModuleInfo* gPIPNSSLog;
|
extern PRLogModuleInfo* gPIPNSSLog;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsNSSSocketInfo::nsNSSSocketInfo(uint32_t providerFlags)
|
nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags)
|
||||||
: mFd(nullptr),
|
: mFd(nullptr),
|
||||||
mCertVerificationState(before_cert_verification),
|
mCertVerificationState(before_cert_verification),
|
||||||
|
mSharedState(aState),
|
||||||
mForSTARTTLS(false),
|
mForSTARTTLS(false),
|
||||||
mSSL3Enabled(false),
|
mSSL3Enabled(false),
|
||||||
mTLSEnabled(false),
|
mTLSEnabled(false),
|
||||||
|
@ -457,6 +460,11 @@ void nsNSSSocketInfo::SetAllowTLSIntoleranceTimeout(bool aAllow)
|
||||||
mAllowTLSIntoleranceTimeout = aAllow;
|
mAllowTLSIntoleranceTimeout = aAllow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SharedSSLState& nsNSSSocketInfo::SharedState()
|
||||||
|
{
|
||||||
|
return mSharedState;
|
||||||
|
}
|
||||||
|
|
||||||
bool nsNSSSocketInfo::HandshakeTimeout()
|
bool nsNSSSocketInfo::HandshakeTimeout()
|
||||||
{
|
{
|
||||||
if (!mAllowTLSIntoleranceTimeout)
|
if (!mAllowTLSIntoleranceTimeout)
|
||||||
|
@ -914,7 +922,8 @@ int32_t checkHandshake(int32_t bytesTransfered, bool wasReading,
|
||||||
if (!wantRetry // no decision yet
|
if (!wantRetry // no decision yet
|
||||||
&& isTLSIntoleranceError(err, socketInfo->GetHasCleartextPhase()))
|
&& 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
|
if (!wantRetry // no decision yet
|
||||||
&& !socketInfo->GetHasCleartextPhase()) // mirror PR_CONNECT_RESET_ERROR treament
|
&& !socketInfo->GetHasCleartextPhase()) // mirror PR_CONNECT_RESET_ERROR treament
|
||||||
{
|
{
|
||||||
wantRetry =
|
nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers();
|
||||||
nsSSLIOLayerHelpers::rememberPossibleTLSProblemSite(socketInfo);
|
wantRetry = helpers.rememberPossibleTLSProblemSite(socketInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1031,12 +1040,16 @@ nsSSLIOLayerPoll(PRFileDesc * fd, int16_t in_flags, int16_t *out_flags)
|
||||||
bool nsSSLIOLayerHelpers::nsSSLIOLayerInitialized = false;
|
bool nsSSLIOLayerHelpers::nsSSLIOLayerInitialized = false;
|
||||||
PRDescIdentity nsSSLIOLayerHelpers::nsSSLIOLayerIdentity;
|
PRDescIdentity nsSSLIOLayerHelpers::nsSSLIOLayerIdentity;
|
||||||
PRIOMethods nsSSLIOLayerHelpers::nsSSLIOLayerMethods;
|
PRIOMethods nsSSLIOLayerHelpers::nsSSLIOLayerMethods;
|
||||||
Mutex *nsSSLIOLayerHelpers::mutex = nullptr;
|
|
||||||
nsTHashtable<nsCStringHashKey> *nsSSLIOLayerHelpers::mTLSIntolerantSites = nullptr;
|
nsSSLIOLayerHelpers::nsSSLIOLayerHelpers()
|
||||||
nsTHashtable<nsCStringHashKey> *nsSSLIOLayerHelpers::mTLSTolerantSites = nullptr;
|
: mutex(nullptr)
|
||||||
nsTHashtable<nsCStringHashKey> *nsSSLIOLayerHelpers::mRenegoUnrestrictedSites = nullptr;
|
, mTLSIntolerantSites(nullptr)
|
||||||
bool nsSSLIOLayerHelpers::mTreatUnsafeNegotiationAsBroken = false;
|
, mTLSTolerantSites(nullptr)
|
||||||
int32_t nsSSLIOLayerHelpers::mWarnLevelMissingRFC5746 = 1;
|
, mRenegoUnrestrictedSites(nullptr)
|
||||||
|
, mTreatUnsafeNegotiationAsBroken(false)
|
||||||
|
, mWarnLevelMissingRFC5746(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static int _PSM_InvalidInt(void)
|
static int _PSM_InvalidInt(void)
|
||||||
{
|
{
|
||||||
|
@ -1190,6 +1203,53 @@ static int64_t PSMAvailable64(void)
|
||||||
return -1;
|
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()
|
nsresult nsSSLIOLayerHelpers::Init()
|
||||||
{
|
{
|
||||||
if (!nsSSLIOLayerInitialized) {
|
if (!nsSSLIOLayerInitialized) {
|
||||||
|
@ -1244,23 +1304,50 @@ nsresult nsSSLIOLayerHelpers::Init()
|
||||||
mRenegoUnrestrictedSites = new nsTHashtable<nsCStringHashKey>();
|
mRenegoUnrestrictedSites = new nsTHashtable<nsCStringHashKey>();
|
||||||
mRenegoUnrestrictedSites->Init(1);
|
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;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsSSLIOLayerHelpers::clearStoredData()
|
||||||
|
{
|
||||||
|
mRenegoUnrestrictedSites->Clear();
|
||||||
|
mTLSTolerantSites->Clear();
|
||||||
|
mTLSIntolerantSites->Clear();
|
||||||
|
}
|
||||||
|
|
||||||
void nsSSLIOLayerHelpers::addIntolerantSite(const nsCString &str)
|
void nsSSLIOLayerHelpers::addIntolerantSite(const nsCString &str)
|
||||||
{
|
{
|
||||||
MutexAutoLock lock(*mutex);
|
MutexAutoLock lock(*mutex);
|
||||||
// Remember intolerant site only if it is not known as tolerant
|
// Remember intolerant site only if it is not known as tolerant
|
||||||
if (!mTLSTolerantSites->Contains(str))
|
if (!mTLSTolerantSites->Contains(str))
|
||||||
nsSSLIOLayerHelpers::mTLSIntolerantSites->PutEntry(str);
|
mTLSIntolerantSites->PutEntry(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsSSLIOLayerHelpers::removeIntolerantSite(const nsCString &str)
|
void nsSSLIOLayerHelpers::removeIntolerantSite(const nsCString &str)
|
||||||
{
|
{
|
||||||
MutexAutoLock lock(*mutex);
|
MutexAutoLock lock(*mutex);
|
||||||
nsSSLIOLayerHelpers::mTLSIntolerantSites->RemoveEntry(str);
|
mTLSIntolerantSites->RemoveEntry(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsSSLIOLayerHelpers::isKnownAsIntolerantSite(const nsCString &str)
|
bool nsSSLIOLayerHelpers::isKnownAsIntolerantSite(const nsCString &str)
|
||||||
|
@ -1923,6 +2010,7 @@ void ClientAuthDataRunnable::RunOnTargetThread()
|
||||||
SSM_UserCertChoice certChoice;
|
SSM_UserCertChoice certChoice;
|
||||||
int32_t NumberOfCerts = 0;
|
int32_t NumberOfCerts = 0;
|
||||||
void * wincx = mSocketInfo;
|
void * wincx = mSocketInfo;
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
/* create caNameStrings */
|
/* create caNameStrings */
|
||||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||||
|
@ -2024,19 +2112,14 @@ void ClientAuthDataRunnable::RunOnTargetThread()
|
||||||
nsXPIDLCString hostname;
|
nsXPIDLCString hostname;
|
||||||
mSocketInfo->GetHostName(getter_Copies(hostname));
|
mSocketInfo->GetHostName(getter_Copies(hostname));
|
||||||
|
|
||||||
nsresult rv;
|
RefPtr<nsClientAuthRememberService> cars =
|
||||||
NS_DEFINE_CID(nssComponentCID, NS_NSSCOMPONENT_CID);
|
mSocketInfo->SharedState().GetClientAuthRememberService();
|
||||||
nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(nssComponentCID, &rv));
|
|
||||||
RefPtr<nsClientAuthRememberService> cars;
|
|
||||||
if (nssComponent) {
|
|
||||||
nssComponent->GetClientAuthRememberService(byRef(cars));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasRemembered = false;
|
bool hasRemembered = false;
|
||||||
nsCString rememberedDBKey;
|
nsCString rememberedDBKey;
|
||||||
if (cars) {
|
if (cars) {
|
||||||
bool found;
|
bool found;
|
||||||
nsresult rv = cars->HasRememberedDecision(hostname, mServerCert,
|
rv = cars->HasRememberedDecision(hostname, mServerCert,
|
||||||
rememberedDBKey, &found);
|
rememberedDBKey, &found);
|
||||||
if (NS_SUCCEEDED(rv) && found) {
|
if (NS_SUCCEEDED(rv) && found) {
|
||||||
hasRemembered = true;
|
hasRemembered = true;
|
||||||
|
@ -2219,9 +2302,9 @@ if (!hasRemembered)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Throw up the client auth dialog and get back the index of the selected cert */
|
/* Throw up the client auth dialog and get back the index of the selected cert */
|
||||||
rv = getNSSDialogs((void**)&dialogs,
|
nsresult rv = getNSSDialogs((void**)&dialogs,
|
||||||
NS_GET_IID(nsIClientAuthDialogs),
|
NS_GET_IID(nsIClientAuthDialogs),
|
||||||
NS_CLIENTAUTHDIALOGS_CONTRACTID);
|
NS_CLIENTAUTHDIALOGS_CONTRACTID);
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList);
|
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList);
|
||||||
|
@ -2365,7 +2448,7 @@ loser:
|
||||||
static nsresult
|
static nsresult
|
||||||
nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
|
nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
|
||||||
const char *proxyHost, const char *host, int32_t port,
|
const char *proxyHost, const char *host, int32_t port,
|
||||||
bool anonymousLoad, nsNSSSocketInfo *infoObject)
|
nsNSSSocketInfo *infoObject)
|
||||||
{
|
{
|
||||||
nsNSSShutDownPreventionLock locker;
|
nsNSSShutDownPreventionLock locker;
|
||||||
if (forSTARTTLS || proxyHost) {
|
if (forSTARTTLS || proxyHost) {
|
||||||
|
@ -2380,7 +2463,7 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
|
||||||
nsAutoCString key;
|
nsAutoCString key;
|
||||||
key = nsDependentCString(host) + NS_LITERAL_CSTRING(":") + nsPrintfCString("%d", port);
|
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))
|
if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_TLS, false))
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
@ -2407,8 +2490,9 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
|
||||||
if (SECSuccess != SSL_OptionSet(fd, SSL_HANDSHAKE_AS_CLIENT, true)) {
|
if (SECSuccess != SSL_OptionSet(fd, SSL_HANDSHAKE_AS_CLIENT, true)) {
|
||||||
return NS_ERROR_FAILURE;
|
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)) {
|
if (SECSuccess != SSL_OptionSet(fd, SSL_REQUIRE_SAFE_NEGOTIATION, false)) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -2417,20 +2501,23 @@ nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the Peer ID so that SSL proxy connections work properly.
|
// Set the Peer ID so that SSL proxy connections work properly and to
|
||||||
char *peerId;
|
// separate anonymous and/or private browsing connections.
|
||||||
if (anonymousLoad) { // See bug #466080. Separate the caches.
|
uint32_t flags = infoObject->GetProviderFlags();
|
||||||
peerId = PR_smprintf("anon:%s:%d", host, port);
|
nsAutoCString peerId;
|
||||||
} else {
|
if (flags & nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080
|
||||||
peerId = PR_smprintf("%s:%d", host, port);
|
peerId.Append("anon:");
|
||||||
}
|
}
|
||||||
|
if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) {
|
||||||
if (SECSuccess != SSL_SetSockPeerID(fd, peerId)) {
|
peerId.Append("private:");
|
||||||
PR_smprintf_free(peerId);
|
}
|
||||||
|
peerId.Append(host);
|
||||||
|
peerId.Append(':');
|
||||||
|
peerId.AppendInt(port);
|
||||||
|
if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PR_smprintf_free(peerId);
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2450,7 +2537,9 @@ nsSSLIOLayerAddToSocket(int32_t family,
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
PRStatus stat;
|
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;
|
if (!infoObject) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
NS_ADDREF(infoObject);
|
NS_ADDREF(infoObject);
|
||||||
|
@ -2458,7 +2547,6 @@ nsSSLIOLayerAddToSocket(int32_t family,
|
||||||
infoObject->SetHostName(host);
|
infoObject->SetHostName(host);
|
||||||
infoObject->SetPort(port);
|
infoObject->SetPort(port);
|
||||||
|
|
||||||
bool anonymousLoad = providerFlags & nsISocketProvider::ANONYMOUS_CONNECT;
|
|
||||||
PRFileDesc *sslSock = nsSSLIOLayerImportFD(fd, infoObject, host);
|
PRFileDesc *sslSock = nsSSLIOLayerImportFD(fd, infoObject, host);
|
||||||
if (!sslSock) {
|
if (!sslSock) {
|
||||||
NS_ASSERTION(false, "NSS: Error importing socket");
|
NS_ASSERTION(false, "NSS: Error importing socket");
|
||||||
|
@ -2467,8 +2555,7 @@ nsSSLIOLayerAddToSocket(int32_t family,
|
||||||
|
|
||||||
infoObject->SetFileDescPtr(sslSock);
|
infoObject->SetFileDescPtr(sslSock);
|
||||||
|
|
||||||
rv = nsSSLIOLayerSetOptions(sslSock,
|
rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, proxyHost, host, port,
|
||||||
forSTARTTLS, proxyHost, host, port, anonymousLoad,
|
|
||||||
infoObject);
|
infoObject);
|
||||||
|
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
|
@ -2497,6 +2584,8 @@ nsSSLIOLayerAddToSocket(int32_t family,
|
||||||
infoObject->SetHandshakePending(false);
|
infoObject->SetHandshakePending(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
infoObject->SharedState().NoteSocketCreated();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
loser:
|
loser:
|
||||||
NS_IF_RELEASE(infoObject);
|
NS_IF_RELEASE(infoObject);
|
||||||
|
|
|
@ -15,12 +15,20 @@
|
||||||
#include "nsTHashtable.h"
|
#include "nsTHashtable.h"
|
||||||
#include "mozilla/TimeStamp.h"
|
#include "mozilla/TimeStamp.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace psm {
|
||||||
|
class SharedSSLState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class nsIObserver;
|
||||||
|
|
||||||
class nsNSSSocketInfo : public mozilla::psm::TransportSecurityInfo,
|
class nsNSSSocketInfo : public mozilla::psm::TransportSecurityInfo,
|
||||||
public nsISSLSocketControl,
|
public nsISSLSocketControl,
|
||||||
public nsIClientAuthUserDecision
|
public nsIClientAuthUserDecision
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsNSSSocketInfo(uint32_t providerFlags);
|
nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags);
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
NS_DECL_NSISSLSOCKETCONTROL
|
NS_DECL_NSISSLSOCKETCONTROL
|
||||||
|
@ -55,7 +63,11 @@ public:
|
||||||
|
|
||||||
bool GetJoined() { return mJoined; }
|
bool GetJoined() { return mJoined; }
|
||||||
void SetSentClientCert() { mSentClientCert = true; }
|
void SetSentClientCert() { mSentClientCert = true; }
|
||||||
|
|
||||||
|
uint32_t GetProviderFlags() const { return mProviderFlags; }
|
||||||
|
|
||||||
|
mozilla::psm::SharedSSLState& SharedState();
|
||||||
|
|
||||||
// XXX: These are only used on for diagnostic purposes
|
// XXX: These are only used on for diagnostic purposes
|
||||||
enum CertVerificationState {
|
enum CertVerificationState {
|
||||||
before_cert_verification,
|
before_cert_verification,
|
||||||
|
@ -83,6 +95,7 @@ private:
|
||||||
|
|
||||||
CertVerificationState mCertVerificationState;
|
CertVerificationState mCertVerificationState;
|
||||||
|
|
||||||
|
mozilla::psm::SharedSSLState& mSharedState;
|
||||||
bool mForSTARTTLS;
|
bool mForSTARTTLS;
|
||||||
bool mSSL3Enabled;
|
bool mSSL3Enabled;
|
||||||
bool mTLSEnabled;
|
bool mTLSEnabled;
|
||||||
|
@ -109,37 +122,44 @@ private:
|
||||||
class nsSSLIOLayerHelpers
|
class nsSSLIOLayerHelpers
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static nsresult Init();
|
nsSSLIOLayerHelpers();
|
||||||
static void Cleanup();
|
~nsSSLIOLayerHelpers();
|
||||||
|
|
||||||
|
nsresult Init();
|
||||||
|
void Cleanup();
|
||||||
|
|
||||||
static bool nsSSLIOLayerInitialized;
|
static bool nsSSLIOLayerInitialized;
|
||||||
static PRDescIdentity nsSSLIOLayerIdentity;
|
static PRDescIdentity nsSSLIOLayerIdentity;
|
||||||
static PRIOMethods nsSSLIOLayerMethods;
|
static PRIOMethods nsSSLIOLayerMethods;
|
||||||
|
|
||||||
static mozilla::Mutex *mutex;
|
mozilla::Mutex *mutex;
|
||||||
static nsTHashtable<nsCStringHashKey> *mTLSIntolerantSites;
|
nsTHashtable<nsCStringHashKey> *mTLSIntolerantSites;
|
||||||
static nsTHashtable<nsCStringHashKey> *mTLSTolerantSites;
|
nsTHashtable<nsCStringHashKey> *mTLSTolerantSites;
|
||||||
|
|
||||||
static nsTHashtable<nsCStringHashKey> *mRenegoUnrestrictedSites;
|
nsTHashtable<nsCStringHashKey> *mRenegoUnrestrictedSites;
|
||||||
static bool mTreatUnsafeNegotiationAsBroken;
|
bool mTreatUnsafeNegotiationAsBroken;
|
||||||
static int32_t mWarnLevelMissingRFC5746;
|
int32_t mWarnLevelMissingRFC5746;
|
||||||
|
|
||||||
static void setTreatUnsafeNegotiationAsBroken(bool broken);
|
void setTreatUnsafeNegotiationAsBroken(bool broken);
|
||||||
static bool treatUnsafeNegotiationAsBroken();
|
bool treatUnsafeNegotiationAsBroken();
|
||||||
|
|
||||||
static void setWarnLevelMissingRFC5746(int32_t level);
|
void setWarnLevelMissingRFC5746(int32_t level);
|
||||||
static int32_t getWarnLevelMissingRFC5746();
|
int32_t getWarnLevelMissingRFC5746();
|
||||||
|
|
||||||
static void getSiteKey(nsNSSSocketInfo *socketInfo, nsCSubstring &key);
|
static void getSiteKey(nsNSSSocketInfo *socketInfo, nsCSubstring &key);
|
||||||
static bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo);
|
bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo);
|
||||||
static void rememberTolerantSite(nsNSSSocketInfo *socketInfo);
|
void rememberTolerantSite(nsNSSSocketInfo *socketInfo);
|
||||||
|
|
||||||
static void addIntolerantSite(const nsCString &str);
|
void addIntolerantSite(const nsCString &str);
|
||||||
static void removeIntolerantSite(const nsCString &str);
|
void removeIntolerantSite(const nsCString &str);
|
||||||
static bool isKnownAsIntolerantSite(const nsCString &str);
|
bool isKnownAsIntolerantSite(const nsCString &str);
|
||||||
|
|
||||||
static void setRenegoUnrestrictedSites(const nsCString &str);
|
void setRenegoUnrestrictedSites(const nsCString &str);
|
||||||
static bool isRenegoUnrestrictedSite(const nsCString &str);
|
bool isRenegoUnrestrictedSite(const nsCString &str);
|
||||||
|
|
||||||
|
void clearStoredData();
|
||||||
|
private:
|
||||||
|
nsCOMPtr<nsIObserver> mPrefObserver;
|
||||||
};
|
};
|
||||||
|
|
||||||
nsresult nsSSLIOLayerNewSocket(int32_t family,
|
nsresult nsSSLIOLayerNewSocket(int32_t family,
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include "nsDataSignatureVerifier.h"
|
#include "nsDataSignatureVerifier.h"
|
||||||
#include "nsCertOverrideService.h"
|
#include "nsCertOverrideService.h"
|
||||||
#include "nsRandomGenerator.h"
|
#include "nsRandomGenerator.h"
|
||||||
#include "nsRecentBadCerts.h"
|
|
||||||
#include "nsSSLStatus.h"
|
#include "nsSSLStatus.h"
|
||||||
#include "TransportSecurityInfo.h"
|
#include "TransportSecurityInfo.h"
|
||||||
#include "NSSErrorsService.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(nssEnsure, nsDataSignatureVerifier)
|
||||||
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsCertOverrideService, Init)
|
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, nsCertOverrideService, Init)
|
||||||
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsRandomGenerator)
|
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, nsSSLStatus)
|
||||||
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsureOnChromeOnly, TransportSecurityInfo)
|
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_DATASIGNATUREVERIFIER_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_CERTOVERRIDE_CID);
|
NS_DEFINE_NAMED_CID(NS_CERTOVERRIDE_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_RANDOMGENERATOR_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(NS_SSLSTATUS_CID);
|
||||||
NS_DEFINE_NAMED_CID(TRANSPORTSECURITYINFO_CID);
|
NS_DEFINE_NAMED_CID(TRANSPORTSECURITYINFO_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_NSSERRORSSERVICE_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_DATASIGNATUREVERIFIER_CID, false, nullptr, nsDataSignatureVerifierConstructor },
|
||||||
{ &kNS_CERTOVERRIDE_CID, false, nullptr, nsCertOverrideServiceConstructor },
|
{ &kNS_CERTOVERRIDE_CID, false, nullptr, nsCertOverrideServiceConstructor },
|
||||||
{ &kNS_RANDOMGENERATOR_CID, false, nullptr, nsRandomGeneratorConstructor },
|
{ &kNS_RANDOMGENERATOR_CID, false, nullptr, nsRandomGeneratorConstructor },
|
||||||
{ &kNS_RECENTBADCERTS_CID, false, nullptr, nsRecentBadCertsServiceConstructor },
|
|
||||||
{ &kNS_SSLSTATUS_CID, false, nullptr, nsSSLStatusConstructor },
|
{ &kNS_SSLSTATUS_CID, false, nullptr, nsSSLStatusConstructor },
|
||||||
{ &kTRANSPORTSECURITYINFO_CID, false, nullptr, TransportSecurityInfoConstructor },
|
{ &kTRANSPORTSECURITYINFO_CID, false, nullptr, TransportSecurityInfoConstructor },
|
||||||
{ &kNS_NSSERRORSSERVICE_CID, false, nullptr, NSSErrorsServiceConstructor },
|
{ &kNS_NSSERRORSSERVICE_CID, false, nullptr, NSSErrorsServiceConstructor },
|
||||||
|
@ -324,7 +320,6 @@ static const mozilla::Module::ContractIDEntry kNSSContracts[] = {
|
||||||
{ NS_DATASIGNATUREVERIFIER_CONTRACTID, &kNS_DATASIGNATUREVERIFIER_CID },
|
{ NS_DATASIGNATUREVERIFIER_CONTRACTID, &kNS_DATASIGNATUREVERIFIER_CID },
|
||||||
{ NS_CERTOVERRIDE_CONTRACTID, &kNS_CERTOVERRIDE_CID },
|
{ NS_CERTOVERRIDE_CONTRACTID, &kNS_CERTOVERRIDE_CID },
|
||||||
{ NS_RANDOMGENERATOR_CONTRACTID, &kNS_RANDOMGENERATOR_CID },
|
{ NS_RANDOMGENERATOR_CONTRACTID, &kNS_RANDOMGENERATOR_CID },
|
||||||
{ NS_RECENTBADCERTS_CONTRACTID, &kNS_RECENTBADCERTS_CID },
|
|
||||||
{ nullptr }
|
{ nullptr }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
#include "nsRecentBadCerts.h"
|
#include "nsRecentBadCerts.h"
|
||||||
#include "nsIX509Cert.h"
|
#include "nsIX509Cert.h"
|
||||||
|
#include "nsIObserverService.h"
|
||||||
#include "mozilla/RefPtr.h"
|
#include "mozilla/RefPtr.h"
|
||||||
|
#include "mozilla/Services.h"
|
||||||
#include "nsSSLStatus.h"
|
#include "nsSSLStatus.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsNSSCertificate.h"
|
#include "nsNSSCertificate.h"
|
||||||
|
@ -20,28 +22,22 @@
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCertsService,
|
NS_IMPL_THREADSAFE_ISUPPORTS1(nsRecentBadCerts,
|
||||||
nsIRecentBadCertsService)
|
nsIRecentBadCerts)
|
||||||
|
|
||||||
nsRecentBadCertsService::nsRecentBadCertsService()
|
nsRecentBadCerts::nsRecentBadCerts()
|
||||||
:monitor("nsRecentBadCertsService.monitor")
|
:monitor("nsRecentBadCerts.monitor")
|
||||||
,mNextStorePosition(0)
|
,mNextStorePosition(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRecentBadCertsService::~nsRecentBadCertsService()
|
nsRecentBadCerts::~nsRecentBadCerts()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsRecentBadCertsService::Init()
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsRecentBadCertsService::GetRecentBadCert(const nsAString & aHostNameWithPort,
|
nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort,
|
||||||
nsISSLStatus **aStatus)
|
nsISSLStatus **aStatus)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(aStatus);
|
NS_ENSURE_ARG_POINTER(aStatus);
|
||||||
if (!aHostNameWithPort.Length())
|
if (!aHostNameWithPort.Length())
|
||||||
|
@ -101,7 +97,7 @@ nsRecentBadCertsService::GetRecentBadCert(const nsAString & aHostNameWithPort,
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsRecentBadCertsService::AddBadCert(const nsAString &hostWithPort,
|
nsRecentBadCerts::AddBadCert(const nsAString &hostWithPort,
|
||||||
nsISSLStatus *aStatus)
|
nsISSLStatus *aStatus)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG(aStatus);
|
NS_ENSURE_ARG(aStatus);
|
||||||
|
@ -146,3 +142,13 @@ nsRecentBadCertsService::AddBadCert(const nsAString &hostWithPort,
|
||||||
|
|
||||||
return NS_OK;
|
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;
|
RecentBadCert &operator=(const RecentBadCert &other) MOZ_DELETE;
|
||||||
};
|
};
|
||||||
|
|
||||||
class nsRecentBadCertsService MOZ_FINAL : public nsIRecentBadCertsService
|
class nsRecentBadCerts MOZ_FINAL : public nsIRecentBadCerts
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIRECENTBADCERTSSERVICE
|
NS_DECL_NSIRECENTBADCERTS
|
||||||
|
|
||||||
nsRecentBadCertsService();
|
nsRecentBadCerts();
|
||||||
~nsRecentBadCertsService();
|
~nsRecentBadCerts();
|
||||||
|
|
||||||
nsresult Init();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mozilla::ReentrantMonitor monitor;
|
mozilla::ReentrantMonitor monitor;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче