Bug 1388925 - Add an opaque flags to have a fine-grained control over TLS configurations. r=mcmanus, r=keeler

This flags is added in the http channel interface by which developers can control the TLS
connections from JavaScript code (e.g. Add-ons). Basically, all the changes accounted for
plumbing this TLS flags from JavaScript level to C++ code responsible for calling NSS
module. We also added a unit test to make sure that separate connections are created if we
use different tlsFlags. Basically we used a concrete set of flag values that covers the
edge cases and check the hashkey generated in the connection info.

--HG--
rename : netwerk/test/unit/test_separate_connections.js => netwerk/test/unit/test_tls_flags_separate_connections.js
This commit is contained in:
Sajjad Arshad 2017-08-16 12:41:16 -07:00
parent 9b038447f4
commit 404facfbbc
27 changed files with 273 additions and 20 deletions

View File

@ -237,6 +237,13 @@ interface nsISocketTransport : nsITransport
*/
const unsigned long BE_CONSERVATIVE = (1 << 7);
/**
* An opaque flags for non-standard behavior of the TLS system.
* It is unlikely this will need to be set outside of telemetry studies
* relating to the TLS implementation.
*/
attribute unsigned long tlsFlags;
/**
* Socket QoS/ToS markings. Valid values are IPTOS_DSCP_AFxx or
* IPTOS_CLASS_CSx (or IPTOS_DSCP_EF, but currently no supported

View File

@ -775,6 +775,7 @@ nsSocketTransport::nsSocketTransport()
, mProxyTransparentResolvesHost(false)
, mHttpsProxy(false)
, mConnectionFlags(0)
, mTlsFlags(0)
, mReuseAddrPort(false)
, mState(STATE_CLOSED)
, mAttached(false)
@ -1225,7 +1226,7 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us
mHttpsProxy ? mProxyHost.get() : host,
mHttpsProxy ? mProxyPort : port,
proxyInfo, mOriginAttributes,
controlFlags, &fd,
controlFlags, mTlsFlags, &fd,
getter_AddRefs(secinfo));
if (NS_SUCCEEDED(rv) && !fd) {
@ -1239,7 +1240,7 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us
// to the stack (such as pushing an io layer)
rv = provider->AddToSocket(mNetAddr.raw.family,
host, port, proxyInfo,
mOriginAttributes, controlFlags, fd,
mOriginAttributes, controlFlags, mTlsFlags, fd,
getter_AddRefs(secinfo));
}
@ -2996,6 +2997,20 @@ nsSocketTransport::SetConnectionFlags(uint32_t value)
return NS_OK;
}
NS_IMETHODIMP
nsSocketTransport::GetTlsFlags(uint32_t *value)
{
*value = mTlsFlags;
return NS_OK;
}
NS_IMETHODIMP
nsSocketTransport::SetTlsFlags(uint32_t value)
{
mTlsFlags = value;
return NS_OK;
}
void
nsSocketTransport::OnKeepaliveEnabledPrefChange(bool aEnabled)
{

View File

@ -308,6 +308,7 @@ private:
bool mProxyTransparentResolvesHost;
bool mHttpsProxy;
uint32_t mConnectionFlags;
uint32_t mTlsFlags;
bool mReuseAddrPort;
// The origin attributes are used to create sockets. The first party domain

View File

@ -128,6 +128,7 @@ struct HttpChannelOpenArgs
bool allowSpdy;
bool allowAltSvc;
bool beConservative;
uint32_t tlsFlags;
OptionalLoadInfoArgs loadInfo;
OptionalHttpResponseHead synthesizedResponseHead;
nsCString synthesizedSecurityInfoSerialization;

View File

@ -183,6 +183,7 @@ HttpBaseChannel::HttpBaseChannel()
, mResponseCouldBeSynthesized(false)
, mBlockAuthPrompt(false)
, mAllowStaleCacheContent(false)
, mTlsFlags(0)
, mSuspendCount(0)
, mInitialRwin(0)
, mProxyResolveFlags(0)
@ -2613,6 +2614,22 @@ HttpBaseChannel::SetBeConservative(bool aBeConservative)
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetTlsFlags(uint32_t *aTlsFlags)
{
NS_ENSURE_ARG_POINTER(aTlsFlags);
*aTlsFlags = mTlsFlags;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::SetTlsFlags(uint32_t aTlsFlags)
{
mTlsFlags = aTlsFlags;
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::GetApiRedirectToURI(nsIURI ** aResult)
{
@ -3420,6 +3437,8 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
MOZ_ASSERT(NS_SUCCEEDED(rv));
rv = httpInternal->SetBeConservative(mBeConservative);
MOZ_ASSERT(NS_SUCCEEDED(rv));
rv = httpInternal->SetTlsFlags(mTlsFlags);
MOZ_ASSERT(NS_SUCCEEDED(rv));
RefPtr<nsHttpChannel> realChannel;
CallQueryInterface(newChannel, realChannel.StartAssignment());

View File

@ -235,6 +235,8 @@ public:
NS_IMETHOD SetAllowAltSvc(bool aAllowAltSvc) override;
NS_IMETHOD GetBeConservative(bool *aBeConservative) override;
NS_IMETHOD SetBeConservative(bool aBeConservative) override;
NS_IMETHOD GetTlsFlags(uint32_t *aTlsFlags) override;
NS_IMETHOD SetTlsFlags(uint32_t aTlsFlags) override;
NS_IMETHOD GetApiRedirectToURI(nsIURI * *aApiRedirectToURI) override;
virtual MOZ_MUST_USE nsresult AddSecurityMessage(const nsAString &aMessageTag, const nsAString &aMessageCategory);
NS_IMETHOD TakeAllSecurityMessages(nsCOMArray<nsISecurityConsoleMessage> &aMessages) override;
@ -541,6 +543,11 @@ protected:
// Used to enforce that flag's behavior but not expose it externally.
uint32_t mAllowStaleCacheContent : 1;
// An opaque flags for non-standard behavior of the TLS system.
// It is unlikely this will need to be set outside of telemetry studies
// relating to the TLS implementation.
uint32_t mTlsFlags;
// Current suspension depth for this channel object
uint32_t mSuspendCount;

View File

@ -2563,6 +2563,7 @@ HttpChannelChild::ContinueAsyncOpen()
openArgs.allowSpdy() = mAllowSpdy;
openArgs.allowAltSvc() = mAllowAltSvc;
openArgs.beConservative() = mBeConservative;
openArgs.tlsFlags() = mTlsFlags;
openArgs.initialRwin() = mInitialRwin;
uint32_t cacheKey = 0;

View File

@ -136,7 +136,7 @@ HttpChannelParent::Init(const HttpChannelCreationArgs& aArgs)
a.thirdPartyFlags(), a.resumeAt(), a.startPos(),
a.entityID(), a.chooseApplicationCache(),
a.appCacheClientID(), a.allowSpdy(), a.allowAltSvc(), a.beConservative(),
a.loadInfo(), a.synthesizedResponseHead(),
a.tlsFlags(), a.loadInfo(), a.synthesizedResponseHead(),
a.synthesizedSecurityInfoSerialization(),
a.cacheKey(), a.requestContextID(), a.preflightArgs(),
a.initialRwin(), a.blockAuthPrompt(),
@ -457,6 +457,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
const bool& allowSpdy,
const bool& allowAltSvc,
const bool& beConservative,
const uint32_t& tlsFlags,
const OptionalLoadInfoArgs& aLoadInfoArgs,
const OptionalHttpResponseHead& aSynthesizedResponseHead,
const nsCString& aSecurityInfoSerialization,
@ -683,6 +684,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
httpChannel->SetAllowSpdy(allowSpdy);
httpChannel->SetAllowAltSvc(allowAltSvc);
httpChannel->SetBeConservative(beConservative);
httpChannel->SetTlsFlags(tlsFlags);
httpChannel->SetInitialRwin(aInitialRwin);
httpChannel->SetBlockAuthPrompt(aBlockAuthPrompt);

View File

@ -151,6 +151,7 @@ protected:
const bool& allowSpdy,
const bool& allowAltSvc,
const bool& beConservative,
const uint32_t& tlsFlags,
const OptionalLoadInfoArgs& aLoadInfoArgs,
const OptionalHttpResponseHead& aSynthesizedResponseHead,
const nsCString& aSecurityInfoSerialization,

View File

@ -80,7 +80,7 @@ TLSFilterTransaction::TLSFilterTransaction(nsAHttpTransaction *aWrapped,
if (provider && mFD) {
mFD->secret = reinterpret_cast<PRFilePrivate *>(this);
provider->AddToSocket(PR_AF_INET, aTLSHost, aTLSPort, nullptr,
OriginAttributes(), 0, mFD,
OriginAttributes(), 0, 0, mFD,
getter_AddRefs(mSecInfo));
}
@ -1547,6 +1547,8 @@ FWD_TS_ADDREF(GetSecurityCallbacks, nsIInterfaceRequestor);
FWD_TS_PTR(IsAlive, bool);
FWD_TS_PTR(GetConnectionFlags, uint32_t);
FWD_TS(SetConnectionFlags, uint32_t);
FWD_TS_PTR(GetTlsFlags, uint32_t);
FWD_TS(SetTlsFlags, uint32_t);
FWD_TS_PTR(GetRecvBufferSize, uint32_t);
FWD_TS(SetRecvBufferSize, uint32_t);

View File

@ -497,6 +497,7 @@ nsHttpChannel::Connect()
mConnectionInfo->SetPrivate(mPrivateBrowsing);
mConnectionInfo->SetNoSpdy(mCaps & NS_HTTP_DISALLOW_SPDY);
mConnectionInfo->SetBeConservative((mCaps & NS_HTTP_BE_CONSERVATIVE) || mBeConservative);
mConnectionInfo->SetTlsFlags(mTlsFlags);
// Consider opening a TCP connection right away.
SpeculativeConnect();

View File

@ -92,6 +92,7 @@ nsHttpConnectionInfo::Init(const nsACString &host, int32_t port,
mUsingConnect = false;
mNPNToken = npnToken;
mOriginAttributes = originAttributes;
mTlsFlags = 0x0;
mUsingHttpsProxy = (proxyInfo && proxyInfo->IsHTTPS());
mUsingHttpProxy = mUsingHttpsProxy || (proxyInfo && proxyInfo->IsHTTP());
@ -147,7 +148,8 @@ void nsHttpConnectionInfo::BuildHashKey()
// byte 5 is X/. X is for disallow_spdy flag
// byte 6 is C/. C is for be Conservative
mHashKey.AssignLiteral(".......");
mHashKey.AssignLiteral(".......[tlsflags0x00000000]");
mHashKey.Append(keyHost);
if (!mNetworkInterfaceId.IsEmpty()) {
mHashKey.Append('(');
@ -259,6 +261,7 @@ nsHttpConnectionInfo::Clone() const
clone->SetInsecureScheme(GetInsecureScheme());
clone->SetNoSpdy(GetNoSpdy());
clone->SetBeConservative(GetBeConservative());
clone->SetTlsFlags(GetTlsFlags());
MOZ_ASSERT(clone->Equals(this));
return clone;
@ -282,6 +285,7 @@ nsHttpConnectionInfo::CloneAsDirectRoute(nsHttpConnectionInfo **outCI)
clone->SetInsecureScheme(GetInsecureScheme());
clone->SetNoSpdy(GetNoSpdy());
clone->SetBeConservative(GetBeConservative());
clone->SetTlsFlags(GetTlsFlags());
if (!mNetworkInterfaceId.IsEmpty()) {
clone->SetNetworkInterfaceId(mNetworkInterfaceId);
}
@ -310,6 +314,13 @@ nsHttpConnectionInfo::CreateWildCard(nsHttpConnectionInfo **outParam)
return NS_OK;
}
void
nsHttpConnectionInfo::SetTlsFlags(uint32_t aTlsFlags) {
mTlsFlags = aTlsFlags;
mHashKey.Replace(18, 8, nsPrintfCString("%08x", mTlsFlags));
}
bool
nsHttpConnectionInfo::UsingProxy()
{

View File

@ -122,6 +122,9 @@ public:
{ mHashKey.SetCharAt(aBeConservative ? 'C' : '.', 6); }
bool GetBeConservative() const { return mHashKey.CharAt(6) == 'C'; }
void SetTlsFlags(uint32_t aTlsFlags);
uint32_t GetTlsFlags() const { return mTlsFlags; }
const nsCString &GetNetworkInterfaceId() const { return mNetworkInterfaceId; }
const nsCString &GetNPNToken() { return mNPNToken; }
@ -176,6 +179,8 @@ private:
nsCString mNPNToken;
OriginAttributes mOriginAttributes;
uint32_t mTlsFlags;
// for RefPtr
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHttpConnectionInfo)
};

View File

@ -3853,6 +3853,7 @@ nsHalfOpenSocket::SetupStreams(nsISocketTransport **transport,
}
socketTransport->SetConnectionFlags(tmpFlags);
socketTransport->SetTlsFlags(ci->GetTlsFlags());
const OriginAttributes& originAttributes = mEnt->mConnInfo->GetOriginAttributes();
if (originAttributes != OriginAttributes()) {

View File

@ -216,6 +216,13 @@ interface nsIHttpChannelInternal : nsISupports
*/
[must_use] attribute boolean beConservative;
/**
* An opaque flags for non-standard behavior of the TLS system.
* It is unlikely this will need to be set outside of telemetry studies
* relating to the TLS implementation.
*/
[must_use] attribute unsigned long tlsFlags;
[must_use] readonly attribute PRTime lastModifiedTime;
/**

View File

@ -102,6 +102,11 @@ interface nsISSLSocketControl : nsISupports {
*/
readonly attribute uint32_t providerFlags;
/*
* The original TLS flags from the socket provider.
*/
readonly attribute uint32_t providerTlsFlags;
/* These values are defined by TLS. */
const short SSL_VERSION_3 = 0x0300;
const short TLS_VERSION_1 = 0x0301;

View File

@ -35,6 +35,10 @@ interface nsISocketProvider : nsISupports
* The proxy port for this connection.
* @param aFlags
* Control flags that govern this connection (see below.)
* @param aTlsFlags
* An opaque flags for non-standard behavior of the TLS system.
* It is unlikely this will need to be set outside of telemetry
* studies relating to the TLS implementation.
* @param aFileDesc
* The resulting PRFileDesc.
* @param aSecurityInfo
@ -48,6 +52,7 @@ interface nsISocketProvider : nsISupports
in nsIProxyInfo aProxy,
in const_OriginAttributesRef aOriginAttributes,
in unsigned long aFlags,
in unsigned long aTlsFlags,
out PRFileDescStar aFileDesc,
out nsISupports aSecurityInfo);
@ -68,6 +73,7 @@ interface nsISocketProvider : nsISupports
in nsIProxyInfo aProxy,
in const_OriginAttributesRef aOriginAttributes,
in unsigned long aFlags,
in unsigned long aTlsFlags,
in PRFileDescStar aFileDesc,
out nsISupports aSecurityInfo);

View File

@ -78,7 +78,8 @@ public:
int32_t family,
nsIProxyInfo *proxy,
const char *destinationHost,
uint32_t flags);
uint32_t flags,
uint32_t tlsFlags);
void SetConnectTimeout(PRIntervalTime to);
PRStatus DoHandshake(PRFileDesc *fd, int16_t oflags = -1);
@ -216,6 +217,7 @@ private:
int32_t mVersion; // SOCKS version 4 or 5
int32_t mDestinationFamily;
uint32_t mFlags;
uint32_t mTlsFlags;
NetAddr mInternalProxyAddr;
NetAddr mExternalProxyAddr;
NetAddr mDestinationAddr;
@ -232,6 +234,7 @@ nsSOCKSSocketInfo::nsSOCKSSocketInfo()
, mVersion(-1)
, mDestinationFamily(AF_INET)
, mFlags(0)
, mTlsFlags(0)
, mTimeout(PR_INTERVAL_NO_TIMEOUT)
{
mData = new uint8_t[BUFFER_SIZE];
@ -359,13 +362,14 @@ private:
void
nsSOCKSSocketInfo::Init(int32_t version, int32_t family, nsIProxyInfo *proxy, const char *host, uint32_t flags)
nsSOCKSSocketInfo::Init(int32_t version, int32_t family, nsIProxyInfo *proxy, const char *host, uint32_t flags, uint32_t tlsFlags)
{
mVersion = version;
mDestinationFamily = family;
mProxy = proxy;
mDestinationHost = host;
mFlags = flags;
mTlsFlags = tlsFlags;
mProxy->GetUsername(mProxyUsername); // cache
}
@ -1518,6 +1522,7 @@ nsSOCKSIOLayerAddToSocket(int32_t family,
nsIProxyInfo *proxy,
int32_t socksVersion,
uint32_t flags,
uint32_t tlsFlags,
PRFileDesc *fd,
nsISupports** info)
{
@ -1577,7 +1582,7 @@ nsSOCKSIOLayerAddToSocket(int32_t family,
}
NS_ADDREF(infoObject);
infoObject->Init(socksVersion, family, proxy, host, flags);
infoObject->Init(socksVersion, family, proxy, host, flags, tlsFlags);
layer->secret = (PRFilePrivate*) infoObject;
PRDescIdentity fdIdentity = PR_GetLayersIdentity(fd);

View File

@ -17,6 +17,7 @@ nsresult nsSOCKSIOLayerAddToSocket(int32_t family,
nsIProxyInfo *proxyInfo,
int32_t socksVersion,
uint32_t flags,
uint32_t tlsFlags,
PRFileDesc *fd,
nsISupports **info);

View File

@ -50,6 +50,7 @@ nsSOCKSSocketProvider::NewSocket(int32_t family,
nsIProxyInfo *proxy,
const OriginAttributes &originAttributes,
uint32_t flags,
uint32_t tlsFlags,
PRFileDesc **result,
nsISupports **socksInfo)
{
@ -75,6 +76,7 @@ nsSOCKSSocketProvider::NewSocket(int32_t family,
proxy,
mVersion,
flags,
tlsFlags,
sock,
socksInfo);
if (NS_SUCCEEDED(rv)) {
@ -92,6 +94,7 @@ nsSOCKSSocketProvider::AddToSocket(int32_t family,
nsIProxyInfo *proxy,
const OriginAttributes &originAttributes,
uint32_t flags,
uint32_t tlsFlags,
PRFileDesc *sock,
nsISupports **socksInfo)
{
@ -101,6 +104,7 @@ nsSOCKSSocketProvider::AddToSocket(int32_t family,
proxy,
mVersion,
flags,
tlsFlags,
sock,
socksInfo);

View File

@ -21,6 +21,7 @@ nsUDPSocketProvider::NewSocket(int32_t aFamily,
nsIProxyInfo *aProxy,
const OriginAttributes &originAttributes,
uint32_t aFlags,
uint32_t aTlsFlags,
PRFileDesc * *aFileDesc,
nsISupports **aSecurityInfo)
{
@ -41,6 +42,7 @@ nsUDPSocketProvider::AddToSocket(int32_t aFamily,
nsIProxyInfo *aProxy,
const OriginAttributes &originAttributes,
uint32_t aFlags,
uint32_t aTlsFlags,
struct PRFileDesc * aFileDesc,
nsISupports **aSecurityInfo)
{

View File

@ -0,0 +1,119 @@
Cu.import("resource://testing-common/httpd.js");
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "URL", function() {
return "http://localhost:" + httpserv.identity.primaryPort;
});
// This unit test ensures connections with different tlsFlags have their own
// connection pool. We verify this behavior by opening channels with different
// tlsFlags, and their connection info's hash keys should be different.
// In the first round of this test, we record the hash key for each connection.
// In the second round, we check if each connection's hash key is consistent
// and different from other connection's hash key.
let httpserv = null;
let gSecondRoundStarted = false;
let randomFlagValues = [
0x00000000,
0xFFFFFFFF,
0x12345678,
0x12345678,
0x11111111,
0x22222222,
0xAAAAAAAA,
0x77777777,
0xBBBBBBBB,
0xCCCCCCCC
];
function handler(metadata, response) {
response.setHeader("Content-Type", "text/plain", false);
response.setHeader("Cache-Control", "no-cache", false);
response.setStatusLine(metadata.httpVersion, 200, "OK");
let body = "0123456789";
response.bodyOutputStream.write(body, body.length);
}
function makeChan(url, tlsFlags) {
let chan = NetUtil.newChannel({ uri: url, loadUsingSystemPrincipal: true });
chan.QueryInterface(Ci.nsIHttpChannelInternal);
chan.tlsFlags = tlsFlags;
return chan;
}
let previousHashKeys = {};
function Listener(tlsFlags) {
this.tlsFlags = tlsFlags;
}
let gTestsRun = 0;
Listener.prototype = {
onStartRequest: function(request, context) {
request.QueryInterface(Ci.nsIHttpChannel)
.QueryInterface(Ci.nsIHttpChannelInternal);
do_check_eq(request.tlsFlags, this.tlsFlags);
let hashKey = request.connectionInfoHashKey;
if (gSecondRoundStarted) {
// Compare the hash keys with the previous set ones.
// Hash keys should match if and only if their tlsFlags are the same.
for (let tlsFlags of randomFlagValues) {
if (tlsFlags == this.tlsFlags) {
do_check_eq(hashKey, previousHashKeys[tlsFlags]);
} else {
do_check_neq(hashKey, previousHashKeys[tlsFlags]);
}
}
} else {
// Set the hash keys in the first round.
previousHashKeys[this.tlsFlags] = hashKey;
}
},
onDataAvailable: function(request, ctx, stream, off, cnt) {
read_stream(stream, cnt);
},
onStopRequest: function() {
gTestsRun++;
if (gTestsRun == randomFlagValues.length) {
gTestsRun = 0;
if (gSecondRoundStarted) {
// The second round finishes.
httpserv.stop(do_test_finished);
} else {
// The first round finishes. Do the second round.
gSecondRoundStarted = true;
doTest();
}
}
},
};
function doTest() {
for (let tlsFlags of randomFlagValues) {
let chan = makeChan(URL, tlsFlags);
let listener = new Listener(tlsFlags);
chan.asyncOpen2(listener);
}
}
function run_test() {
do_test_pending();
httpserv = new HttpServer();
httpserv.registerPathHandler("/", handler);
httpserv.start(-1);
doTest();
}

View File

@ -396,3 +396,4 @@ skip-if = os == "android"
[test_bug1312782_http1.js]
[test_bug1355539_http1.js]
[test_bug1378385_http1.js]
[test_tls_flags_separate_connections.js]

View File

@ -75,7 +75,8 @@ getSiteKey(const nsACString& hostName, uint16_t port,
extern LazyLogModule gPIPNSSLog;
nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags)
nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags,
uint32_t providerTlsFlags)
: mFd(nullptr),
mCertVerificationState(before_cert_verification),
mSharedState(aState),
@ -99,6 +100,7 @@ nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags)
mMACAlgorithmUsed(nsISSLSocketControl::SSL_MAC_UNKNOWN),
mBypassAuthentication(false),
mProviderFlags(providerFlags),
mProviderTlsFlags(providerTlsFlags),
mSocketCreationTimestamp(TimeStamp::Now()),
mPlaintextBytesRead(0),
mClientCert(nullptr)
@ -122,6 +124,13 @@ nsNSSSocketInfo::GetProviderFlags(uint32_t* aProviderFlags)
return NS_OK;
}
NS_IMETHODIMP
nsNSSSocketInfo::GetProviderTlsFlags(uint32_t* aProviderTlsFlags)
{
*aProviderTlsFlags = mProviderTlsFlags;
return NS_OK;
}
NS_IMETHODIMP
nsNSSSocketInfo::GetKEAUsed(int16_t* aKea)
{
@ -1813,7 +1822,8 @@ nsSSLIOLayerNewSocket(int32_t family,
PRFileDesc** fd,
nsISupports** info,
bool forSTARTTLS,
uint32_t flags)
uint32_t flags,
uint32_t tlsFlags)
{
PRFileDesc* sock = PR_OpenTCPSocket(family);
@ -1821,7 +1831,7 @@ nsSSLIOLayerNewSocket(int32_t family,
nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxy,
originAttributes, sock, info,
forSTARTTLS, flags);
forSTARTTLS, flags, tlsFlags);
if (NS_FAILED(rv)) {
PR_Close(sock);
return rv;
@ -2425,6 +2435,8 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS,
return NS_ERROR_FAILURE;
}
// Use infoObject->GetProviderTlsFlags() to get the TLS flags
if ((infoObject->GetProviderFlags() & nsISocketProvider::BE_CONSERVATIVE) &&
(range.max > SSL_LIBRARY_VERSION_TLS_1_2)) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
@ -2522,6 +2534,9 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS,
if (flags & nsISocketProvider::BE_CONSERVATIVE) {
peerId.AppendLiteral("beConservative:");
}
peerId.AppendPrintf("tlsflags0x%08x:", infoObject->GetProviderTlsFlags());
peerId.Append(host);
peerId.Append(':');
peerId.AppendInt(port);
@ -2544,7 +2559,8 @@ nsSSLIOLayerAddToSocket(int32_t family,
PRFileDesc* fd,
nsISupports** info,
bool forSTARTTLS,
uint32_t providerFlags)
uint32_t providerFlags,
uint32_t providerTlsFlags)
{
nsNSSShutDownPreventionLock locker;
PRFileDesc* layer = nullptr;
@ -2554,7 +2570,7 @@ nsSSLIOLayerAddToSocket(int32_t family,
SharedSSLState* sharedState =
providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE ? PrivateSSLState() : PublicSSLState();
nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(*sharedState, providerFlags);
nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(*sharedState, providerFlags, providerTlsFlags);
if (!infoObject) return NS_ERROR_FAILURE;
NS_ADDREF(infoObject);

View File

@ -35,7 +35,8 @@ class nsNSSSocketInfo final : public mozilla::psm::TransportSecurityInfo,
public nsIClientAuthUserDecision
{
public:
nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags);
nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags,
uint32_t providerTlsFlags);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSISSLSOCKETCONTROL
@ -75,6 +76,7 @@ public:
void SetSentClientCert() { mSentClientCert = true; }
uint32_t GetProviderFlags() const { return mProviderFlags; }
uint32_t GetProviderTlsFlags() const { return mProviderTlsFlags; }
mozilla::psm::SharedSSLState& SharedState();
@ -156,6 +158,7 @@ private:
bool mBypassAuthentication;
uint32_t mProviderFlags;
uint32_t mProviderTlsFlags;
mozilla::TimeStamp mSocketCreationTimestamp;
uint64_t mPlaintextBytesRead;
@ -233,7 +236,8 @@ nsresult nsSSLIOLayerNewSocket(int32_t family,
PRFileDesc** fd,
nsISupports** securityInfo,
bool forSTARTTLS,
uint32_t flags);
uint32_t flags,
uint32_t tlsFlags);
nsresult nsSSLIOLayerAddToSocket(int32_t family,
const char* host,
@ -243,7 +247,8 @@ nsresult nsSSLIOLayerAddToSocket(int32_t family,
PRFileDesc* fd,
nsISupports** securityInfo,
bool forSTARTTLS,
uint32_t flags);
uint32_t flags,
uint32_t tlsFlags);
nsresult nsSSLIOLayerFreeTLSIntolerantSites();
nsresult displayUnknownCertErrorAlert(nsNSSSocketInfo* infoObject, int error);

View File

@ -28,6 +28,7 @@ nsSSLSocketProvider::NewSocket(int32_t family,
nsIProxyInfo *proxy,
const OriginAttributes &originAttributes,
uint32_t flags,
uint32_t tlsFlags,
PRFileDesc **_result,
nsISupports **securityInfo)
{
@ -39,7 +40,8 @@ nsSSLSocketProvider::NewSocket(int32_t family,
_result,
securityInfo,
false,
flags);
flags,
tlsFlags);
return (NS_FAILED(rv)) ? NS_ERROR_SOCKET_CREATE_FAILED : NS_OK;
}
@ -51,6 +53,7 @@ nsSSLSocketProvider::AddToSocket(int32_t family,
nsIProxyInfo *proxy,
const OriginAttributes &originAttributes,
uint32_t flags,
uint32_t tlsFlags,
PRFileDesc *aSocket,
nsISupports **securityInfo)
{
@ -62,7 +65,8 @@ nsSSLSocketProvider::AddToSocket(int32_t family,
aSocket,
securityInfo,
false,
flags);
flags,
tlsFlags);
return (NS_FAILED(rv)) ? NS_ERROR_SOCKET_CREATE_FAILED : NS_OK;
}

View File

@ -28,6 +28,7 @@ nsTLSSocketProvider::NewSocket(int32_t family,
nsIProxyInfo *proxy,
const OriginAttributes &originAttributes,
uint32_t flags,
uint32_t tlsFlags,
PRFileDesc **_result,
nsISupports **securityInfo)
{
@ -39,7 +40,8 @@ nsTLSSocketProvider::NewSocket(int32_t family,
_result,
securityInfo,
true,
flags);
flags,
tlsFlags);
return (NS_FAILED(rv)) ? NS_ERROR_SOCKET_CREATE_FAILED : NS_OK;
}
@ -52,6 +54,7 @@ nsTLSSocketProvider::AddToSocket(int32_t family,
nsIProxyInfo *proxy,
const OriginAttributes &originAttributes,
uint32_t flags,
uint32_t tlsFlags,
PRFileDesc *aSocket,
nsISupports **securityInfo)
{
@ -63,7 +66,8 @@ nsTLSSocketProvider::AddToSocket(int32_t family,
aSocket,
securityInfo,
true,
flags);
flags,
tlsFlags);
return (NS_FAILED(rv)) ? NS_ERROR_SOCKET_CREATE_FAILED : NS_OK;
}