mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 658222 - Enable TLS False Start (PSM) r=bsmith
--HG-- extra : rebase_source : ac9f77ba73a0a902f4b6aa8d52add7d52efb1b53
This commit is contained in:
parent
4bb2b60348
commit
9c44286c03
@ -12,8 +12,10 @@ pref("security.ssl.renego_unrestricted_hosts", "");
|
||||
pref("security.ssl.treat_unsafe_negotiation_as_broken", false);
|
||||
pref("security.ssl.require_safe_negotiation", false);
|
||||
pref("security.ssl.warn_missing_rfc5746", 1);
|
||||
pref("security.ssl.enable_false_start", false);
|
||||
pref("security.ssl.enable_ocsp_stapling", true);
|
||||
pref("security.ssl.enable_false_start", true);
|
||||
pref("security.ssl.false_start.require-npn", true);
|
||||
pref("security.ssl.false_start.require-forward-secrecy", false);
|
||||
|
||||
pref("security.ssl3.rsa_rc4_128_md5", true);
|
||||
pref("security.ssl3.rsa_rc4_128_sha", true);
|
||||
|
@ -127,8 +127,8 @@ nsHttpConnection::PrintDiagnostics(nsCString &log)
|
||||
{
|
||||
log.AppendPrintf(" CanDirectlyActivate = %d\n", CanDirectlyActivate());
|
||||
|
||||
log.AppendPrintf(" npncomplete = %d setupNPNCalled = %d\n",
|
||||
mNPNComplete, mSetupNPNCalled);
|
||||
log.AppendPrintf(" npncomplete = %d setupSSLCalled = %d\n",
|
||||
mNPNComplete, mSetupSSLCalled);
|
||||
|
||||
log.AppendPrintf(" spdyVersion = %d reportedSpdy = %d everspdy = %d\n",
|
||||
mUsingSpdyVersion, mReportedSpdy, mEverUsedSpdy);
|
||||
|
@ -58,6 +58,11 @@ typedef uint8_t nsHttpVersion;
|
||||
// group is currently blocking on some resources
|
||||
#define NS_HTTP_LOAD_UNBLOCKED (1<<8)
|
||||
|
||||
// These flags allow a transaction to use TLS false start with
|
||||
// weaker security profiles based on past history
|
||||
#define NS_HTTP_ALLOW_RSA_FALSESTART (1<<9)
|
||||
#define NS_HTTP_ALLOW_RC4_FALSESTART (1<<10)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// some default values
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -40,6 +40,14 @@
|
||||
#include "NullHttpTransaction.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/VisualEventTracer.h"
|
||||
#include "nsISSLSocketControl.h"
|
||||
#include "sslt.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsISSLStatus.h"
|
||||
#include "nsISSLStatusProvider.h"
|
||||
|
||||
namespace mozilla { namespace net {
|
||||
|
||||
@ -391,6 +399,7 @@ nsHttpChannel::Connect()
|
||||
return NS_ERROR_UNKNOWN_HOST;
|
||||
|
||||
// Consider opening a TCP connection right away
|
||||
RetrieveSSLOptions();
|
||||
SpeculativeConnect();
|
||||
|
||||
// Don't allow resuming when cache must be used
|
||||
@ -527,8 +536,9 @@ nsHttpChannel::SpeculativeConnect()
|
||||
|
||||
mConnectionInfo->SetAnonymous((mLoadFlags & LOAD_ANONYMOUS) != 0);
|
||||
mConnectionInfo->SetPrivate(mPrivateBrowsing);
|
||||
gHttpHandler->SpeculativeConnect(mConnectionInfo,
|
||||
callbacks);
|
||||
gHttpHandler->SpeculativeConnect(
|
||||
mConnectionInfo, callbacks,
|
||||
mCaps & (NS_HTTP_ALLOW_RSA_FALSESTART | NS_HTTP_ALLOW_RC4_FALSESTART | NS_HTTP_DISALLOW_SPDY));
|
||||
}
|
||||
|
||||
void
|
||||
@ -693,6 +703,37 @@ nsHttpChannel::SetupTransactionLoadGroupInfo()
|
||||
mTransaction->SetLoadGroupConnectionInfo(ci);
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpChannel::RetrieveSSLOptions()
|
||||
{
|
||||
if (!IsHTTPS() || mPrivateBrowsing)
|
||||
return;
|
||||
|
||||
nsIPrincipal *principal = GetPrincipal();
|
||||
if (!principal)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> permMgr =
|
||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
||||
if (!permMgr)
|
||||
return;
|
||||
|
||||
uint32_t perm;
|
||||
nsresult rv = permMgr->TestPermissionFromPrincipal(principal,
|
||||
"falsestart-rsa", &perm);
|
||||
if (NS_SUCCEEDED(rv) && perm == nsIPermissionManager::ALLOW_ACTION) {
|
||||
LOG(("nsHttpChannel::RetrieveSSLOptions [this=%p] "
|
||||
"falsestart-rsa permission found\n", this));
|
||||
mCaps |= NS_HTTP_ALLOW_RSA_FALSESTART;
|
||||
}
|
||||
rv = permMgr->TestPermissionFromPrincipal(principal, "falsestart-rc4", &perm);
|
||||
if (NS_SUCCEEDED(rv) && perm == nsIPermissionManager::ALLOW_ACTION) {
|
||||
LOG(("nsHttpChannel::RetrieveSSLOptions [this=%p] "
|
||||
"falsestart-rc4 permission found\n", this));
|
||||
mCaps |= NS_HTTP_ALLOW_RC4_FALSESTART;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHttpChannel::SetupTransaction()
|
||||
{
|
||||
@ -1160,6 +1201,89 @@ nsHttpChannel::ProcessSTSHeader()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsHttpChannel::IsHTTPS()
|
||||
{
|
||||
bool isHttps;
|
||||
if (NS_FAILED(mURI->SchemeIs("https", &isHttps)) || !isHttps)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpChannel::ProcessSSLInformation()
|
||||
{
|
||||
// If this is HTTPS, record any use of RSA so that Key Exchange Algorithm
|
||||
// can be whitelisted for TLS False Start in future sessions. We could
|
||||
// do the same for DH but its rarity doesn't justify the lookup.
|
||||
// Also do the same for RC4 symmetric ciphers.
|
||||
|
||||
if (mCanceled || NS_FAILED(mStatus) || !mSecurityInfo ||
|
||||
!IsHTTPS() || mPrivateBrowsing)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsISSLSocketControl> ssl = do_QueryInterface(mSecurityInfo);
|
||||
nsCOMPtr<nsISSLStatusProvider> statusProvider =
|
||||
do_QueryInterface(mSecurityInfo);
|
||||
if (!ssl || !statusProvider)
|
||||
return;
|
||||
nsCOMPtr<nsISSLStatus> sslstat;
|
||||
statusProvider->GetSSLStatus(getter_AddRefs(sslstat));
|
||||
if (!sslstat)
|
||||
return;
|
||||
|
||||
// If certificate exceptions are being used don't record this information
|
||||
// in the permission manager.
|
||||
bool trustCheck;
|
||||
if (NS_FAILED(sslstat->GetIsDomainMismatch(&trustCheck)) || trustCheck)
|
||||
return;
|
||||
if (NS_FAILED(sslstat->GetIsNotValidAtThisTime(&trustCheck)) || trustCheck)
|
||||
return;
|
||||
if (NS_FAILED(sslstat->GetIsUntrusted(&trustCheck)) || trustCheck)
|
||||
return;
|
||||
|
||||
int16_t kea = ssl->GetKEAUsed();
|
||||
int16_t symcipher = ssl->GetSymmetricCipherUsed();
|
||||
|
||||
nsIPrincipal *principal = GetPrincipal();
|
||||
if (!principal)
|
||||
return;
|
||||
|
||||
// set a permission manager flag that future transactions can
|
||||
// use via RetrieveSSLOptions(()
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> permMgr =
|
||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
||||
if (!permMgr)
|
||||
return;
|
||||
|
||||
// Allow this to stand for a week
|
||||
int64_t expireTime = (PR_Now() / PR_USEC_PER_MSEC) +
|
||||
(86400 * 7 * PR_MSEC_PER_SEC);
|
||||
|
||||
if (kea == ssl_kea_rsa) {
|
||||
permMgr->AddFromPrincipal(principal, "falsestart-rsa",
|
||||
nsIPermissionManager::ALLOW_ACTION,
|
||||
nsIPermissionManager::EXPIRE_TIME,
|
||||
expireTime);
|
||||
LOG(("nsHttpChannel::ProcessSSLInformation [this=%p] "
|
||||
"falsestart-rsa permission granted for this host\n", this));
|
||||
} else {
|
||||
permMgr->RemoveFromPrincipal(principal, "falsestart-rsa");
|
||||
}
|
||||
|
||||
if (symcipher == ssl_calg_rc4) {
|
||||
permMgr->AddFromPrincipal(principal, "falsestart-rc4",
|
||||
nsIPermissionManager::ALLOW_ACTION,
|
||||
nsIPermissionManager::EXPIRE_TIME,
|
||||
expireTime);
|
||||
LOG(("nsHttpChannel::ProcessSSLInformation [this=%p] "
|
||||
"falsestart-rc4 permission granted for this host\n", this));
|
||||
} else {
|
||||
permMgr->RemoveFromPrincipal(principal, "falsestart-rc4");
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHttpChannel::ProcessResponse()
|
||||
{
|
||||
@ -1192,6 +1316,8 @@ nsHttpChannel::ProcessResponse()
|
||||
|
||||
MOZ_ASSERT(!mCachedContentIsValid);
|
||||
|
||||
ProcessSSLInformation();
|
||||
|
||||
// notify "http-on-examine-response" observers
|
||||
gHttpHandler->OnExamineResponse(this);
|
||||
|
||||
@ -6037,6 +6163,30 @@ nsHttpChannel::ShouldSkipCache()
|
||||
return true;
|
||||
}
|
||||
|
||||
nsIPrincipal *
|
||||
nsHttpChannel::GetPrincipal()
|
||||
{
|
||||
if (mPrincipal)
|
||||
return mPrincipal;
|
||||
|
||||
nsIScriptSecurityManager *securityManager =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
|
||||
if (!securityManager)
|
||||
return nullptr;
|
||||
|
||||
securityManager->GetChannelPrincipal(this, getter_AddRefs(mPrincipal));
|
||||
if (!mPrincipal)
|
||||
return nullptr;
|
||||
|
||||
// principals with unknown app ids do not work with the permission manager
|
||||
if (mPrincipal->GetUnknownAppId())
|
||||
mPrincipal = nullptr;
|
||||
|
||||
return mPrincipal;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpChannel::SetLoadGroup(nsILoadGroup *aLoadGroup)
|
||||
{
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
class nsAHttpConnection;
|
||||
class nsIPrincipal;
|
||||
|
||||
namespace mozilla { namespace net {
|
||||
|
||||
@ -174,6 +175,9 @@ private:
|
||||
nsresult ContinueProcessFallback(nsresult);
|
||||
void HandleAsyncAbort();
|
||||
nsresult EnsureAssocReq();
|
||||
void ProcessSSLInformation();
|
||||
bool IsHTTPS();
|
||||
void RetrieveSSLOptions();
|
||||
|
||||
nsresult ContinueOnStartRequest1(nsresult);
|
||||
nsresult ContinueOnStartRequest2(nsresult);
|
||||
@ -373,6 +377,10 @@ protected:
|
||||
|
||||
private: // cache telemetry
|
||||
bool mDidReval;
|
||||
|
||||
private:
|
||||
nsIPrincipal *GetPrincipal();
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
||||
} } // namespace mozilla::net
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "nsISocketTransport.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISSLSocketControl.h"
|
||||
#include "sslt.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "netCore.h"
|
||||
#include "nsNetCID.h"
|
||||
@ -64,11 +65,12 @@ nsHttpConnection::nsHttpConnection()
|
||||
, mRemainingConnectionUses(0xffffffff)
|
||||
, mClassification(nsAHttpTransaction::CLASS_GENERAL)
|
||||
, mNPNComplete(false)
|
||||
, mSetupNPNCalled(false)
|
||||
, mSetupSSLCalled(false)
|
||||
, mUsingSpdyVersion(0)
|
||||
, mPriority(nsISupportsPriority::PRIORITY_NORMAL)
|
||||
, mReportedSpdy(false)
|
||||
, mEverUsedSpdy(false)
|
||||
, mTransactionCaps(0)
|
||||
{
|
||||
LOG(("Creating nsHttpConnection @%x\n", this));
|
||||
|
||||
@ -236,8 +238,6 @@ nsHttpConnection::StartSpdy(uint8_t spdyVersion)
|
||||
bool
|
||||
nsHttpConnection::EnsureNPNComplete()
|
||||
{
|
||||
// NPN is only used by SPDY right now.
|
||||
//
|
||||
// If for some reason the components to check on NPN aren't available,
|
||||
// this function will just return true to continue on and disable SPDY
|
||||
|
||||
@ -308,6 +308,7 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri
|
||||
LOG(("nsHttpConnection::Activate [this=%p trans=%x caps=%x]\n",
|
||||
this, trans, caps));
|
||||
|
||||
mTransactionCaps = caps;
|
||||
mPriority = pri;
|
||||
if (mTransaction && mUsingSpdyVersion)
|
||||
return AddTransaction(trans, pri);
|
||||
@ -323,7 +324,7 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri
|
||||
trans->GetSecurityCallbacks(getter_AddRefs(callbacks));
|
||||
SetSecurityCallbacks(callbacks);
|
||||
|
||||
SetupNPN(caps); // only for spdy
|
||||
SetupSSL(caps);
|
||||
|
||||
// take ownership of the transaction
|
||||
mTransaction = trans;
|
||||
@ -360,55 +361,70 @@ failed_activation:
|
||||
}
|
||||
|
||||
void
|
||||
nsHttpConnection::SetupNPN(uint32_t caps)
|
||||
nsHttpConnection::SetupSSL(uint32_t caps)
|
||||
{
|
||||
if (mSetupNPNCalled) /* do only once */
|
||||
LOG(("nsHttpConnection::SetupSSL %p caps=0x%X\n", this, caps));
|
||||
|
||||
if (mSetupSSLCalled) // do only once
|
||||
return;
|
||||
mSetupNPNCalled = true;
|
||||
mSetupSSLCalled = true;
|
||||
|
||||
// Setup NPN Negotiation if necessary (only for SPDY)
|
||||
if (!mNPNComplete) {
|
||||
if (mNPNComplete)
|
||||
return;
|
||||
|
||||
mNPNComplete = true;
|
||||
// we flip this back to false if SetNPNList succeeds at the end
|
||||
// of this function
|
||||
mNPNComplete = true;
|
||||
|
||||
if (mConnInfo->UsingSSL()) {
|
||||
LOG(("nsHttpConnection::SetupNPN Setting up "
|
||||
"Next Protocol Negotiation"));
|
||||
nsCOMPtr<nsISupports> securityInfo;
|
||||
nsresult rv =
|
||||
mSocketTransport->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
if (!mConnInfo->UsingSSL())
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsISSLSocketControl> ssl =
|
||||
do_QueryInterface(securityInfo, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
LOG(("nsHttpConnection::SetupSSL Setting up "
|
||||
"Next Protocol Negotiation"));
|
||||
nsCOMPtr<nsISupports> securityInfo;
|
||||
nsresult rv =
|
||||
mSocketTransport->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
nsTArray<nsCString> protocolArray;
|
||||
nsCOMPtr<nsISSLSocketControl> ssl = do_QueryInterface(securityInfo, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
// The first protocol is used as the fallback if none of the
|
||||
// protocols supported overlap with the server's list.
|
||||
// In the case of overlap, matching priority is driven by
|
||||
// the order of the server's advertisement.
|
||||
protocolArray.AppendElement(NS_LITERAL_CSTRING("http/1.1"));
|
||||
if (caps & NS_HTTP_ALLOW_RSA_FALSESTART) {
|
||||
LOG(("nsHttpConnection::SetupSSL %p "
|
||||
">= RSA Key Exchange Expected\n", this));
|
||||
ssl->SetKEAExpected(ssl_kea_rsa);
|
||||
}
|
||||
|
||||
if (gHttpHandler->IsSpdyEnabled() &&
|
||||
!(caps & NS_HTTP_DISALLOW_SPDY)) {
|
||||
LOG(("nsHttpConnection::SetupNPN Allow SPDY NPN selection"));
|
||||
if (gHttpHandler->SpdyInfo()->ProtocolEnabled(0))
|
||||
protocolArray.AppendElement(
|
||||
gHttpHandler->SpdyInfo()->VersionString[0]);
|
||||
if (gHttpHandler->SpdyInfo()->ProtocolEnabled(1))
|
||||
protocolArray.AppendElement(
|
||||
gHttpHandler->SpdyInfo()->VersionString[1]);
|
||||
}
|
||||
if (caps & NS_HTTP_ALLOW_RC4_FALSESTART) {
|
||||
LOG(("nsHttpConnection::SetupSSL %p "
|
||||
">= RC4 Key Exchange Expected\n", this));
|
||||
ssl->SetSymmetricCipherExpected(ssl_calg_rc4);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(ssl->SetNPNList(protocolArray))) {
|
||||
LOG(("nsHttpConnection::Init Setting up SPDY Negotiation OK"));
|
||||
mNPNComplete = false;
|
||||
}
|
||||
}
|
||||
nsTArray<nsCString> protocolArray;
|
||||
|
||||
// The first protocol is used as the fallback if none of the
|
||||
// protocols supported overlap with the server's list.
|
||||
// In the case of overlap, matching priority is driven by
|
||||
// the order of the server's advertisement.
|
||||
protocolArray.AppendElement(NS_LITERAL_CSTRING("http/1.1"));
|
||||
|
||||
if (gHttpHandler->IsSpdyEnabled() &&
|
||||
!(caps & NS_HTTP_DISALLOW_SPDY)) {
|
||||
LOG(("nsHttpConnection::SetupSSL Allow SPDY NPN selection"));
|
||||
if (gHttpHandler->SpdyInfo()->ProtocolEnabled(0))
|
||||
protocolArray.AppendElement(
|
||||
gHttpHandler->SpdyInfo()->VersionString[0]);
|
||||
if (gHttpHandler->SpdyInfo()->ProtocolEnabled(1))
|
||||
protocolArray.AppendElement(
|
||||
gHttpHandler->SpdyInfo()->VersionString[1]);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(ssl->SetNPNList(protocolArray))) {
|
||||
LOG(("nsHttpConnection::Init Setting up SPDY Negotiation OK"));
|
||||
mNPNComplete = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -596,7 +612,7 @@ nsHttpConnection::IsAlive()
|
||||
|
||||
// SocketTransport::IsAlive can run the SSL state machine, so make sure
|
||||
// the NPN options are set before that happens.
|
||||
SetupNPN(0);
|
||||
SetupSSL(mTransactionCaps);
|
||||
|
||||
bool alive;
|
||||
nsresult rv = mSocketTransport->IsAlive(&alive);
|
||||
|
@ -158,6 +158,7 @@ public:
|
||||
void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks);
|
||||
void PrintDiagnostics(nsCString &log);
|
||||
|
||||
void SetTransactionCaps(uint32_t aCaps) { mTransactionCaps = aCaps; }
|
||||
private:
|
||||
// called to cause the underlying socket to start speaking SSL
|
||||
nsresult ProxyStartSSL();
|
||||
@ -175,7 +176,7 @@ private:
|
||||
// Makes certain the SSL handshake is complete and NPN negotiation
|
||||
// has had a chance to happen
|
||||
bool EnsureNPNComplete();
|
||||
void SetupNPN(uint32_t caps);
|
||||
void SetupSSL(uint32_t caps);
|
||||
|
||||
// Start the Spdy transaction handler when NPN indicates spdy/*
|
||||
void StartSpdy(uint8_t versionLevel);
|
||||
@ -240,7 +241,7 @@ private:
|
||||
|
||||
// SPDY related
|
||||
bool mNPNComplete;
|
||||
bool mSetupNPNCalled;
|
||||
bool mSetupSSLCalled;
|
||||
|
||||
// version level in use, 0 if unused
|
||||
uint8_t mUsingSpdyVersion;
|
||||
@ -251,6 +252,9 @@ private:
|
||||
|
||||
// mUsingSpdyVersion is cleared when mSpdySession is freed, this is permanent
|
||||
bool mEverUsedSpdy;
|
||||
|
||||
// The capabailities associated with the most recent transaction
|
||||
uint32_t mTransactionCaps;
|
||||
};
|
||||
|
||||
#endif // nsHttpConnection_h__
|
||||
|
@ -326,7 +326,8 @@ nsHttpConnectionMgr::DoShiftReloadConnectionCleanup(nsHttpConnectionInfo *aCI)
|
||||
|
||||
nsresult
|
||||
nsHttpConnectionMgr::SpeculativeConnect(nsHttpConnectionInfo *ci,
|
||||
nsIInterfaceRequestor *callbacks)
|
||||
nsIInterfaceRequestor *callbacks,
|
||||
uint32_t caps)
|
||||
{
|
||||
LOG(("nsHttpConnectionMgr::SpeculativeConnect [ci=%s]\n",
|
||||
ci->HashKey().get()));
|
||||
@ -336,7 +337,7 @@ nsHttpConnectionMgr::SpeculativeConnect(nsHttpConnectionInfo *ci,
|
||||
nsCOMPtr<nsIInterfaceRequestor> wrappedCallbacks;
|
||||
NS_NewInterfaceRequestorAggregation(callbacks, nullptr, getter_AddRefs(wrappedCallbacks));
|
||||
|
||||
uint32_t caps = ci->GetAnonymous() ? NS_HTTP_LOAD_ANONYMOUS : 0;
|
||||
caps |= ci->GetAnonymous() ? NS_HTTP_LOAD_ANONYMOUS : 0;
|
||||
nsRefPtr<NullHttpTransaction> trans =
|
||||
new NullHttpTransaction(ci, wrappedCallbacks, caps);
|
||||
|
||||
@ -2814,6 +2815,10 @@ nsHalfOpenSocket::OnOutputStreamReady(nsIAsyncOutputStream *out)
|
||||
LOG(("nsHalfOpenSocket::OnOutputStreamReady "
|
||||
"Created new nshttpconnection %p\n", conn.get()));
|
||||
|
||||
// Some capabilities are needed before a transaciton actually gets
|
||||
// scheduled (e.g. how to negotiate false start)
|
||||
conn->SetTransactionCaps(mTransaction->Caps());
|
||||
|
||||
NetAddr peeraddr;
|
||||
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
||||
mTransaction->GetSecurityCallbacks(getter_AddRefs(callbacks));
|
||||
|
@ -113,7 +113,8 @@ public:
|
||||
// connection manager, nor is the submitter obligated to actually submit a
|
||||
// real transaction for this connectionInfo.
|
||||
nsresult SpeculativeConnect(nsHttpConnectionInfo *,
|
||||
nsIInterfaceRequestor *);
|
||||
nsIInterfaceRequestor *,
|
||||
uint32_t caps = 0);
|
||||
|
||||
// called when a connection is done processing a transaction. if the
|
||||
// connection can be reused then it will be added to the idle list, else
|
||||
|
@ -181,9 +181,10 @@ public:
|
||||
}
|
||||
|
||||
nsresult SpeculativeConnect(nsHttpConnectionInfo *ci,
|
||||
nsIInterfaceRequestor *callbacks)
|
||||
nsIInterfaceRequestor *callbacks,
|
||||
uint32_t caps = 0)
|
||||
{
|
||||
return mConnMgr->SpeculativeConnect(ci, callbacks);
|
||||
return mConnMgr->SpeculativeConnect(ci, callbacks, caps);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -14,7 +14,7 @@ class nsCString;
|
||||
%}
|
||||
[ref] native nsCStringTArrayRef(nsTArray<nsCString>);
|
||||
|
||||
[scriptable, uuid(bb2bb490-3ba4-4254-b8f5-8b43c7b714ea)]
|
||||
[scriptable, builtinclass, uuid(c5eb9af4-238c-4fc6-bdec-d5ab5e7dce68)]
|
||||
interface nsISSLSocketControl : nsISupports {
|
||||
attribute nsIInterfaceRequestor notificationCallbacks;
|
||||
|
||||
@ -52,6 +52,22 @@ interface nsISSLSocketControl : nsISupports {
|
||||
in ACString hostname,
|
||||
in long port);
|
||||
|
||||
/* The Key Exchange Algorithm and Symmetric Cipher
|
||||
is used when determining whether or not to do false start.
|
||||
After a handshake is complete it can be read from *Used,
|
||||
before a handshake is started it may be set through *Expected.
|
||||
The values correspond to the SSLKEAType and SSLCipherAlgorithm
|
||||
enums in NSS or the *_UNKNOWN constant defined below.
|
||||
*/
|
||||
|
||||
[infallible] readonly attribute short KEAUsed;
|
||||
[infallible] attribute short KEAExpected;
|
||||
[infallible] readonly attribute short SymmetricCipherUsed;
|
||||
[infallible] attribute short SymmetricCipherExpected;
|
||||
|
||||
const short KEY_EXCHANGE_UNKNOWN = -1;
|
||||
const short SYMMETRIC_CIPHER_UNKNOWN = -1;
|
||||
|
||||
/*
|
||||
* The original flags from the socket provider.
|
||||
*/
|
||||
|
@ -824,6 +824,186 @@ PK11PasswordPrompt(PK11SlotInfo* slot, PRBool retry, void* arg)
|
||||
return runnable->mResult;
|
||||
}
|
||||
|
||||
// call with shutdown prevention lock held
|
||||
static void
|
||||
PreliminaryHandshakeDone(PRFileDesc* fd)
|
||||
{
|
||||
nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
|
||||
if (!infoObject)
|
||||
return;
|
||||
|
||||
if (infoObject->IsPreliminaryHandshakeDone())
|
||||
return;
|
||||
|
||||
infoObject->SetPreliminaryHandshakeDone();
|
||||
infoObject->SetFirstServerHelloReceived();
|
||||
|
||||
// Get the NPN value.
|
||||
SSLNextProtoState state;
|
||||
unsigned char npnbuf[256];
|
||||
unsigned int npnlen;
|
||||
|
||||
if (SSL_GetNextProto(fd, &state, npnbuf, &npnlen, 256) == SECSuccess) {
|
||||
if (state == SSL_NEXT_PROTO_NEGOTIATED) {
|
||||
infoObject->SetNegotiatedNPN(reinterpret_cast<char *>(npnbuf), npnlen);
|
||||
}
|
||||
else {
|
||||
infoObject->SetNegotiatedNPN(nullptr, 0);
|
||||
}
|
||||
mozilla::Telemetry::Accumulate(Telemetry::SSL_NPN_TYPE, state);
|
||||
}
|
||||
else {
|
||||
infoObject->SetNegotiatedNPN(nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
SECStatus
|
||||
CanFalseStartCallback(PRFileDesc* fd, void* client_data, PRBool *canFalseStart)
|
||||
{
|
||||
*canFalseStart = false;
|
||||
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
||||
nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
|
||||
if (!infoObject) {
|
||||
PR_SetError(PR_INVALID_STATE_ERROR, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (infoObject->isAlreadyShutDown()) {
|
||||
MOZ_CRASH("SSL socket used after NSS shut down");
|
||||
PR_SetError(PR_INVALID_STATE_ERROR, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PreliminaryHandshakeDone(fd);
|
||||
|
||||
SSLChannelInfo channelInfo;
|
||||
if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) != SECSuccess) {
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SSLCipherSuiteInfo cipherInfo;
|
||||
if (SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
|
||||
sizeof (cipherInfo)) != SECSuccess) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CanFalseStartCallback [%p] failed - "
|
||||
" KEA %d\n", fd,
|
||||
static_cast<int32_t>(cipherInfo.keaType)));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
if (channelInfo.protocolVersion < SSL_LIBRARY_VERSION_TLS_1_0) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CanFalseStartCallback [%p] failed - "
|
||||
"SSL Version must be >= TLS1 %x\n", fd,
|
||||
static_cast<int32_t>(channelInfo.protocolVersion)));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
// never do false start without one of these key exchange algorithms
|
||||
if (cipherInfo.keaType != ssl_kea_rsa &&
|
||||
cipherInfo.keaType != ssl_kea_dh &&
|
||||
cipherInfo.keaType != ssl_kea_ecdh) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CanFalseStartCallback [%p] failed - "
|
||||
"unsupported KEA %d\n", fd,
|
||||
static_cast<int32_t>(cipherInfo.keaType)));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
// never do false start without at least 80 bits of key material. This should
|
||||
// be redundant to an NSS precondition
|
||||
if (cipherInfo.effectiveKeyBits < 80) {
|
||||
MOZ_CRASH("NSS is not enforcing the precondition that the effective "
|
||||
"key size must be >= 80 bits for false start");
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CanFalseStartCallback [%p] failed - "
|
||||
"key too small %d\n", fd,
|
||||
static_cast<int32_t>(cipherInfo.effectiveKeyBits)));
|
||||
PR_SetError(PR_INVALID_STATE_ERROR, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
// XXX: An attacker can choose which protocols are advertised in the
|
||||
// NPN extension. TODO(Bug 861311): We should restrict the ability
|
||||
// of an attacker leverage this capability by restricting false start
|
||||
// to the same protocol we previously saw for the server, after the
|
||||
// first successful connection to the server.
|
||||
|
||||
// Enforce NPN to do false start if policy requires it. Do this as an
|
||||
// indicator if server compatibility.
|
||||
nsSSLIOLayerHelpers& helpers = infoObject->SharedState().IOLayerHelpers();
|
||||
if (helpers.mFalseStartRequireNPN) {
|
||||
nsAutoCString negotiatedNPN;
|
||||
if (NS_FAILED(infoObject->GetNegotiatedNPN(negotiatedNPN)) ||
|
||||
!negotiatedNPN.Length()) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CanFalseStartCallback [%p] failed - "
|
||||
"NPN cannot be verified\n", fd));
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're not using eliptical curve kea then make sure we've seen the
|
||||
// same kea from this host in the past, to limit the potential for downgrade
|
||||
// attacks.
|
||||
if (cipherInfo.keaType != ssl_kea_ecdh) {
|
||||
|
||||
if (helpers.mFalseStartRequireForwardSecrecy) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CanFalseStartCallback [%p] failed - "
|
||||
"KEA used is %d, but "
|
||||
"require-forward-secrecy configured.\n",
|
||||
fd, static_cast<int32_t>(cipherInfo.keaType)));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
int16_t expected = infoObject->GetKEAExpected();
|
||||
if (cipherInfo.keaType != expected) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CanFalseStartCallback [%p] failed - "
|
||||
"KEA used is %d, expected %d\n", fd,
|
||||
static_cast<int32_t>(cipherInfo.keaType),
|
||||
static_cast<int32_t>(expected)));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
// whitelist the expected key exchange algorithms that are
|
||||
// acceptable for false start when seen before.
|
||||
if (expected != ssl_kea_rsa && expected != ssl_kea_dh &&
|
||||
expected != ssl_kea_ecdh) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CanFalseStartCallback [%p] failed - "
|
||||
"KEA used, %d, "
|
||||
"is not supported with False Start.\n",
|
||||
fd, static_cast<int32_t>(expected)));
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're not using AES then verify that this is the historically expected
|
||||
// symmetrical cipher for this host, to limit potential for downgrade attacks.
|
||||
if (cipherInfo.symCipher != ssl_calg_aes) {
|
||||
int16_t expected = infoObject->GetSymmetricCipherExpected();
|
||||
if (cipherInfo.symCipher != expected) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CanFalseStartCallback [%p] failed - "
|
||||
"Symmetric cipher used is %d, expected %d\n",
|
||||
fd, static_cast<int32_t>(cipherInfo.symCipher),
|
||||
static_cast<int32_t>(expected)));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
// whitelist the expected ciphers that are
|
||||
// acceptable for false start when seen before.
|
||||
if ((expected != ssl_calg_rc4) && (expected != ssl_calg_3des) &&
|
||||
(expected != ssl_calg_aes)) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CanFalseStartCallback [%p] failed - "
|
||||
"Symmetric cipher used, %d, "
|
||||
"is not supported with False Start.\n",
|
||||
fd, static_cast<int32_t>(expected)));
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
infoObject->NoteTimeUntilReady();
|
||||
*canFalseStart = true;
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CanFalseStartCallback [%p] ok\n", fd));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
int32_t sslStatus;
|
||||
@ -834,11 +1014,14 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
||||
nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
|
||||
|
||||
// certificate validation sets FirstServerHelloReceived, so if that flag
|
||||
// is absent at handshake time we have a resumed session.
|
||||
// is absent at handshake time we have a resumed session. Check this before
|
||||
// PreliminaryHandshakeDone() because that function also sets that flag.
|
||||
bool isResumedSession = !(infoObject->GetFirstServerHelloReceived());
|
||||
|
||||
// This is the first callback on resumption handshakes
|
||||
infoObject->SetFirstServerHelloReceived();
|
||||
// Do the bookkeeping that needs to be done after the
|
||||
// server's ServerHello...ServerHelloDone have been processed, but that doesn't
|
||||
// need the handshake to be completed.
|
||||
PreliminaryHandshakeDone(fd);
|
||||
|
||||
// If the handshake completed, then we know the site is TLS tolerant (if this
|
||||
// was a TLS connection).
|
||||
@ -930,21 +1113,6 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
||||
status->mSecretKeyLength = encryptBits;
|
||||
status->mCipherName.Assign(cipherName);
|
||||
|
||||
// Get the NPN value.
|
||||
SSLNextProtoState state;
|
||||
unsigned char npnbuf[256];
|
||||
unsigned int npnlen;
|
||||
|
||||
if (SSL_GetNextProto(fd, &state, npnbuf, &npnlen, 256) == SECSuccess) {
|
||||
if (state == SSL_NEXT_PROTO_NEGOTIATED)
|
||||
infoObject->SetNegotiatedNPN(reinterpret_cast<char *>(npnbuf), npnlen);
|
||||
else
|
||||
infoObject->SetNegotiatedNPN(nullptr, 0);
|
||||
mozilla::Telemetry::Accumulate(Telemetry::SSL_NPN_TYPE, state);
|
||||
}
|
||||
else
|
||||
infoObject->SetNegotiatedNPN(nullptr, 0);
|
||||
|
||||
SSLChannelInfo channelInfo;
|
||||
if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) == SECSuccess) {
|
||||
// Get the protocol version for telemetry
|
||||
@ -954,13 +1122,16 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
||||
|
||||
SSLCipherSuiteInfo cipherInfo;
|
||||
if (SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
|
||||
sizeof (cipherInfo)) == SECSuccess) {
|
||||
sizeof (cipherInfo)) == SECSuccess) {
|
||||
// keyExchange null=0, rsa=1, dh=2, fortezza=3, ecdh=4
|
||||
Telemetry::Accumulate(Telemetry::SSL_KEY_EXCHANGE_ALGORITHM,
|
||||
cipherInfo.keaType);
|
||||
infoObject->SetKEAUsed(cipherInfo.keaType);
|
||||
infoObject->SetSymmetricCipherUsed(cipherInfo.symCipher);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
infoObject->NoteTimeUntilReady();
|
||||
infoObject->SetHandshakeCompleted(isResumedSession);
|
||||
|
||||
PORT_Free(cipherName);
|
||||
|
@ -23,6 +23,8 @@ char*
|
||||
PK11PasswordPrompt(PK11SlotInfo *slot, PRBool retry, void* arg);
|
||||
|
||||
void HandshakeCallback(PRFileDesc *fd, void *client_data);
|
||||
SECStatus CanFalseStartCallback(PRFileDesc* fd, void* client_data,
|
||||
PRBool *canFalseStart);
|
||||
|
||||
SECStatus RegisterMyOCSPAIAInfoCallback();
|
||||
SECStatus UnregisterMyOCSPAIAInfoCallback();
|
||||
|
@ -83,12 +83,18 @@ nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags)
|
||||
mHandshakeInProgress(false),
|
||||
mAllowTLSIntoleranceTimeout(true),
|
||||
mRememberClientAuthCertificate(false),
|
||||
mPreliminaryHandshakeDone(false),
|
||||
mHandshakeStartTime(0),
|
||||
mFirstServerHelloReceived(false),
|
||||
mNPNCompleted(false),
|
||||
mHandshakeCompleted(false),
|
||||
mJoined(false),
|
||||
mSentClientCert(false),
|
||||
mNotedTimeUntilReady(false),
|
||||
mKEAUsed(nsISSLSocketControl::KEY_EXCHANGE_UNKNOWN),
|
||||
mKEAExpected(nsISSLSocketControl::KEY_EXCHANGE_UNKNOWN),
|
||||
mSymmetricCipherUsed(nsISSLSocketControl::SYMMETRIC_CIPHER_UNKNOWN),
|
||||
mSymmetricCipherExpected(nsISSLSocketControl::SYMMETRIC_CIPHER_UNKNOWN),
|
||||
mProviderFlags(providerFlags),
|
||||
mSocketCreationTimestamp(TimeStamp::Now()),
|
||||
mPlaintextBytesRead(0)
|
||||
@ -106,6 +112,48 @@ nsNSSSocketInfo::GetProviderFlags(uint32_t* aProviderFlags)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSSocketInfo::GetKEAUsed(int16_t *aKea)
|
||||
{
|
||||
*aKea = mKEAUsed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSSocketInfo::GetKEAExpected(int16_t *aKea)
|
||||
{
|
||||
*aKea = mKEAExpected;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSSocketInfo::SetKEAExpected(int16_t aKea)
|
||||
{
|
||||
mKEAExpected = aKea;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSSocketInfo::GetSymmetricCipherUsed(int16_t *aSymmetricCipher)
|
||||
{
|
||||
*aSymmetricCipher = mSymmetricCipherUsed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSSocketInfo::GetSymmetricCipherExpected(int16_t *aSymmetricCipher)
|
||||
{
|
||||
*aSymmetricCipher = mSymmetricCipherExpected;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSSocketInfo::SetSymmetricCipherExpected(int16_t aSymmetricCipher)
|
||||
{
|
||||
mSymmetricCipherExpected = aSymmetricCipher;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNSSSocketInfo::GetHandshakePending(bool *aHandshakePending)
|
||||
{
|
||||
@ -197,12 +245,27 @@ getSecureBrowserUI(nsIInterfaceRequestor * callbacks,
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nsNSSSocketInfo::NoteTimeUntilReady()
|
||||
{
|
||||
if (mNotedTimeUntilReady)
|
||||
return;
|
||||
|
||||
mNotedTimeUntilReady = true;
|
||||
|
||||
// This will include TCP and proxy tunnel wait time
|
||||
Telemetry::AccumulateTimeDelta(Telemetry::SSL_TIME_UNTIL_READY,
|
||||
mSocketCreationTimestamp, TimeStamp::Now());
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
|
||||
("[%p] nsNSSSocketInfo::NoteTimeUntilReady\n", mFd));
|
||||
}
|
||||
|
||||
void
|
||||
nsNSSSocketInfo::SetHandshakeCompleted(bool aResumedSession)
|
||||
{
|
||||
if (!mHandshakeCompleted) {
|
||||
// This will include TCP and proxy tunnel wait time
|
||||
Telemetry::AccumulateTimeDelta(Telemetry::SSL_TIME_UNTIL_READY,
|
||||
Telemetry::AccumulateTimeDelta(Telemetry::SSL_TIME_UNTIL_HANDSHAKE_FINISHED,
|
||||
mSocketCreationTimestamp, TimeStamp::Now());
|
||||
|
||||
// If the handshake is completed for the first time from just 1 callback
|
||||
@ -220,6 +283,9 @@ nsNSSSocketInfo::SetHandshakeCompleted(bool aResumedSession)
|
||||
}
|
||||
|
||||
mHandshakeCompleted = true;
|
||||
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
|
||||
("[%p] nsNSSSocketInfo::SetHandshakeCompleted\n", (void*)mFd));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1095,6 +1161,8 @@ nsSSLIOLayerHelpers::nsSSLIOLayerHelpers()
|
||||
, mRenegoUnrestrictedSites(nullptr)
|
||||
, mTreatUnsafeNegotiationAsBroken(false)
|
||||
, mWarnLevelMissingRFC5746(1)
|
||||
, mFalseStartRequireNPN(true)
|
||||
, mFalseStartRequireForwardSecrecy(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1285,6 +1353,12 @@ PrefObserver::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
int32_t warnLevel = 1;
|
||||
Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel);
|
||||
mOwner->setWarnLevelMissingRFC5746(warnLevel);
|
||||
} else if (prefName.Equals("security.ssl.false_start.require-npn")) {
|
||||
Preferences::GetBool("security.ssl.false_start.require-npn",
|
||||
&mOwner->mFalseStartRequireNPN);
|
||||
} else if (prefName.Equals("security.ssl.false_start.require-forward-secrecy")) {
|
||||
Preferences::GetBool("security.ssl.false_start.require-forward-secrecy",
|
||||
&mOwner->mFalseStartRequireForwardSecrecy);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
@ -1312,6 +1386,8 @@ 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");
|
||||
Preferences::RemoveObserver(mPrefObserver, "security.ssl.false_start.require-npn");
|
||||
Preferences::RemoveObserver(mPrefObserver, "security.ssl.false_start.require-forward-secrecy");
|
||||
}
|
||||
|
||||
nsresult nsSSLIOLayerHelpers::Init()
|
||||
@ -1386,6 +1462,11 @@ nsresult nsSSLIOLayerHelpers::Init()
|
||||
Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel);
|
||||
setWarnLevelMissingRFC5746(warnLevel);
|
||||
|
||||
Preferences::GetBool("security.ssl.false_start.require-npn",
|
||||
&mFalseStartRequireNPN);
|
||||
Preferences::GetBool("security.ssl.false_start.require-forward-secrecy",
|
||||
&mFalseStartRequireForwardSecrecy);
|
||||
|
||||
mPrefObserver = new PrefObserver(this);
|
||||
Preferences::AddStrongObserver(mPrefObserver,
|
||||
"security.ssl.renego_unrestricted_hosts");
|
||||
@ -1393,7 +1474,10 @@ nsresult nsSSLIOLayerHelpers::Init()
|
||||
"security.ssl.treat_unsafe_negotiation_as_broken");
|
||||
Preferences::AddStrongObserver(mPrefObserver,
|
||||
"security.ssl.warn_missing_rfc5746");
|
||||
|
||||
Preferences::AddStrongObserver(mPrefObserver,
|
||||
"security.ssl.false_start.require-npn");
|
||||
Preferences::AddStrongObserver(mPrefObserver,
|
||||
"security.ssl.false_start.require-forward-secrecy");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2479,6 +2563,7 @@ nsSSLIOLayerImportFD(PRFileDesc *fd,
|
||||
}
|
||||
SSL_SetPKCS11PinArg(sslSock, (nsIInterfaceRequestor*)infoObject);
|
||||
SSL_HandshakeCallback(sslSock, HandshakeCallback, infoObject);
|
||||
SSL_SetCanFalseStartCallback(sslSock, CanFalseStartCallback, infoObject);
|
||||
|
||||
// Disable this hook if we connect anonymously. See bug 466080.
|
||||
uint32_t flags = 0;
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
|
||||
void SetNegotiatedNPN(const char *value, uint32_t length);
|
||||
void SetHandshakeCompleted(bool aResumedSession);
|
||||
void NoteTimeUntilReady();
|
||||
|
||||
bool GetJoined() { return mJoined; }
|
||||
void SetSentClientCert() { mSentClientCert = true; }
|
||||
@ -93,6 +94,30 @@ public:
|
||||
void SetTLSEnabled(bool enabled) { mTLSEnabled = enabled; }
|
||||
|
||||
void AddPlaintextBytesRead(uint64_t val) { mPlaintextBytesRead += val; }
|
||||
|
||||
bool IsPreliminaryHandshakeDone() const { return mPreliminaryHandshakeDone; }
|
||||
void SetPreliminaryHandshakeDone() { mPreliminaryHandshakeDone = true; }
|
||||
|
||||
void SetKEAUsed(PRUint16 kea) { mKEAUsed = kea; }
|
||||
inline int16_t GetKEAExpected() // infallible in nsISSLSocketControl
|
||||
{
|
||||
int16_t result;
|
||||
mozilla::DebugOnly<nsresult> rv = GetKEAExpected(&result);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
return result;
|
||||
}
|
||||
void SetSymmetricCipherUsed(PRUint16 symmetricCipher)
|
||||
{
|
||||
mSymmetricCipherUsed = symmetricCipher;
|
||||
}
|
||||
inline int16_t GetSymmetricCipherExpected() // infallible in nsISSLSocketControl
|
||||
{
|
||||
int16_t result;
|
||||
mozilla::DebugOnly<nsresult> rv = GetSymmetricCipherExpected(&result);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
PRFileDesc* mFd;
|
||||
|
||||
@ -107,6 +132,7 @@ private:
|
||||
bool mHandshakeInProgress;
|
||||
bool mAllowTLSIntoleranceTimeout;
|
||||
bool mRememberClientAuthCertificate;
|
||||
bool mPreliminaryHandshakeDone; // after false start items are complete
|
||||
PRIntervalTime mHandshakeStartTime;
|
||||
bool mFirstServerHelloReceived;
|
||||
|
||||
@ -117,6 +143,14 @@ private:
|
||||
bool mHandshakeCompleted;
|
||||
bool mJoined;
|
||||
bool mSentClientCert;
|
||||
bool mNotedTimeUntilReady;
|
||||
|
||||
// mKEA* and mSymmetricCipher* are used in false start detetermination
|
||||
// values are from nsISSLSocketControl
|
||||
PRInt16 mKEAUsed;
|
||||
PRInt16 mKEAExpected;
|
||||
PRInt16 mSymmetricCipherUsed;
|
||||
PRInt16 mSymmetricCipherExpected;
|
||||
|
||||
uint32_t mProviderFlags;
|
||||
mozilla::TimeStamp mSocketCreationTimestamp;
|
||||
@ -164,6 +198,9 @@ public:
|
||||
bool isRenegoUnrestrictedSite(const nsCString &str);
|
||||
|
||||
void clearStoredData();
|
||||
|
||||
bool mFalseStartRequireNPN;
|
||||
bool mFalseStartRequireForwardSecrecy;
|
||||
private:
|
||||
nsCOMPtr<nsIObserver> mPrefObserver;
|
||||
};
|
||||
|
@ -843,6 +843,12 @@
|
||||
"extended_statistics_ok": true,
|
||||
"description": "ms of SSL wait time including TCP and proxy tunneling"
|
||||
},
|
||||
"SSL_TIME_UNTIL_HANDSHAKE_FINISHED": {
|
||||
"kind": "exponential",
|
||||
"high": "60000",
|
||||
"n_buckets": 200,
|
||||
"description": "ms of SSL wait time for full handshake including TCP and proxy tunneling"
|
||||
},
|
||||
"SSL_BYTES_BEFORE_CERT_CALLBACK": {
|
||||
"kind": "exponential",
|
||||
"high": "32000",
|
||||
|
Loading…
Reference in New Issue
Block a user