mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
bug 1050063 - consider tls client hello version in alpn/npn offer list r=hurley r=keeler
This commit is contained in:
parent
f7c74c5ba8
commit
300766f367
@ -64,6 +64,10 @@ ASpdySession::NewSpdySession(uint32_t version,
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
static bool SpdySessionTrue(nsISupports *securityInfo)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
SpdyInformation::SpdyInformation()
|
||||
{
|
||||
@ -71,16 +75,19 @@ SpdyInformation::SpdyInformation()
|
||||
// most preferred for ALPN negotiaton
|
||||
Version[0] = SPDY_VERSION_3;
|
||||
VersionString[0] = NS_LITERAL_CSTRING("spdy/3");
|
||||
ALPNCallbacks[0] = SpdySessionTrue;
|
||||
|
||||
Version[1] = SPDY_VERSION_31;
|
||||
VersionString[1] = NS_LITERAL_CSTRING("spdy/3.1");
|
||||
ALPNCallbacks[1] = SpdySessionTrue;
|
||||
|
||||
Version[2] = NS_HTTP2_DRAFT_VERSION;
|
||||
VersionString[2] = NS_LITERAL_CSTRING(NS_HTTP2_DRAFT_TOKEN);
|
||||
ALPNCallbacks[2] = Http2Session::ALPNCallback;
|
||||
}
|
||||
|
||||
bool
|
||||
SpdyInformation::ProtocolEnabled(uint32_t index)
|
||||
SpdyInformation::ProtocolEnabled(uint32_t index) const
|
||||
{
|
||||
MOZ_ASSERT(index < kCount, "index out of range");
|
||||
|
||||
@ -96,15 +103,15 @@ SpdyInformation::ProtocolEnabled(uint32_t index)
|
||||
}
|
||||
|
||||
nsresult
|
||||
SpdyInformation::GetNPNVersionIndex(const nsACString &npnString,
|
||||
uint8_t *result)
|
||||
SpdyInformation::GetNPNIndex(const nsACString &npnString,
|
||||
uint32_t *result) const
|
||||
{
|
||||
if (npnString.IsEmpty())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
for (uint32_t index = 0; index < kCount; ++index) {
|
||||
if (npnString.Equals(VersionString[index])) {
|
||||
*result = Version[index];
|
||||
*result = index;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef bool (*ALPNCallback) (nsISupports *); // nsISSLSocketControl is typical
|
||||
|
||||
// this is essentially a single instantiation as a member of nsHttpHandler.
|
||||
// It could be all static except using static ctors of XPCOM objects is a
|
||||
// bad idea.
|
||||
@ -72,15 +74,22 @@ public:
|
||||
|
||||
static const uint32_t kCount = 3;
|
||||
|
||||
// determine if a version of the protocol is enabled for index <= kCount
|
||||
bool ProtocolEnabled(uint32_t index);
|
||||
// determine the index (0..kCount-1) of the spdy information that
|
||||
// correlates to the npn string. NS_FAILED() if no match is found.
|
||||
nsresult GetNPNIndex(const nsACString &npnString, uint32_t *result) const;
|
||||
|
||||
// lookup a version enum based on an npn string. returns NS_OK if
|
||||
// string was known.
|
||||
nsresult GetNPNVersionIndex(const nsACString &npnString, uint8_t *result);
|
||||
// determine if a version of the protocol is enabled for index < kCount
|
||||
bool ProtocolEnabled(uint32_t index) const;
|
||||
|
||||
uint8_t Version[kCount];
|
||||
nsCString VersionString[kCount];
|
||||
uint8_t Version[kCount]; // telemetry enum e.g. SPDY_VERSION_31
|
||||
nsCString VersionString[kCount]; // npn string e.g. "spdy/3.1"
|
||||
|
||||
// the ALPNCallback function allows the protocol stack to decide whether or
|
||||
// not to offer a particular protocol based on the known TLS information
|
||||
// that we will offer in the client hello (such as version). There has
|
||||
// not been a Server Hello received yet, so not much else can be considered.
|
||||
// Stacks without restrictions can just use SpdySessionTrue()
|
||||
ALPNCallback ALPNCallbacks[kCount];
|
||||
};
|
||||
|
||||
}} // namespace mozilla::net
|
||||
|
@ -2947,6 +2947,21 @@ Http2Session::BufferOutput(const char *buf,
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool // static
|
||||
Http2Session::ALPNCallback(nsISupports *securityInfo)
|
||||
{
|
||||
nsCOMPtr<nsISSLSocketControl> ssl = do_QueryInterface(securityInfo);
|
||||
LOG3(("Http2Session::ALPNCallback sslsocketcontrol=%p\n", ssl.get()));
|
||||
if (ssl) {
|
||||
int16_t version = ssl->GetSSLVersionOffered();
|
||||
LOG3(("Http2Session::ALPNCallback version=%x\n", version));
|
||||
if (version >= nsISSLSocketControl::TLS_VERSION_1_2) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Http2Session::ConfirmTLSProfile()
|
||||
{
|
||||
|
@ -198,6 +198,7 @@ public:
|
||||
void MaybeDecrementConcurrent(Http2Stream *stream);
|
||||
|
||||
nsresult ConfirmTLSProfile();
|
||||
static bool ALPNCallback(nsISupports *securityInfo);
|
||||
|
||||
uint64_t Serial() { return mSerial; }
|
||||
|
||||
|
@ -310,21 +310,19 @@ nsHttpConnection::EnsureNPNComplete()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
goto npnComplete;
|
||||
}
|
||||
LOG(("nsHttpConnection::EnsureNPNComplete %p [%s] negotiated to '%s'%s\n",
|
||||
this, mConnInfo->HashKey().get(), negotiatedNPN.get(),
|
||||
mTLSFilter ? " [Double Tunnel]" : ""));
|
||||
|
||||
uint8_t spdyVersion;
|
||||
rv = gHttpHandler->SpdyInfo()->GetNPNVersionIndex(negotiatedNPN,
|
||||
&spdyVersion);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
StartSpdy(spdyVersion);
|
||||
}
|
||||
LOG(("nsHttpConnection::EnsureNPNComplete %p [%s] negotiated to '%s'%s\n",
|
||||
this, mConnInfo->HashKey().get(), negotiatedNPN.get(),
|
||||
mTLSFilter ? " [Double Tunnel]" : ""));
|
||||
|
||||
Telemetry::Accumulate(Telemetry::SPDY_NPN_CONNECT, UsingSpdy());
|
||||
uint32_t infoIndex;
|
||||
const SpdyInformation *info = gHttpHandler->SpdyInfo();
|
||||
if (NS_SUCCEEDED(info->GetNPNIndex(negotiatedNPN, &infoIndex))) {
|
||||
StartSpdy(info->Version[infoIndex]);
|
||||
}
|
||||
|
||||
Telemetry::Accumulate(Telemetry::SPDY_NPN_CONNECT, UsingSpdy());
|
||||
}
|
||||
|
||||
npnComplete:
|
||||
LOG(("nsHttpConnection::EnsureNPNComplete setting complete to true"));
|
||||
@ -475,6 +473,10 @@ nsHttpConnection::SetupSSL()
|
||||
}
|
||||
}
|
||||
|
||||
// The naming of NPN is historical - this function creates the basic
|
||||
// offer list for both NPN and ALPN. ALPN validation callbacks are made
|
||||
// now before the handshake is complete, and NPN validation callbacks
|
||||
// are made during the handshake.
|
||||
nsresult
|
||||
nsHttpConnection::SetupNPNList(nsISSLSocketControl *ssl, uint32_t caps)
|
||||
{
|
||||
@ -492,10 +494,12 @@ nsHttpConnection::SetupNPNList(nsISSLSocketControl *ssl, uint32_t caps)
|
||||
if (gHttpHandler->IsSpdyEnabled() &&
|
||||
!(caps & NS_HTTP_DISALLOW_SPDY)) {
|
||||
LOG(("nsHttpConnection::SetupSSL Allow SPDY NPN selection"));
|
||||
const SpdyInformation *info = gHttpHandler->SpdyInfo();
|
||||
for (uint32_t index = SpdyInformation::kCount; index > 0; --index) {
|
||||
if (gHttpHandler->SpdyInfo()->ProtocolEnabled(index - 1))
|
||||
protocolArray.AppendElement(
|
||||
gHttpHandler->SpdyInfo()->VersionString[index - 1]);
|
||||
if (info->ProtocolEnabled(index - 1) &&
|
||||
info->ALPNCallbacks[index - 1](ssl)) {
|
||||
protocolArray.AppendElement(info->VersionString[index - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ class nsCString;
|
||||
%}
|
||||
[ref] native nsCStringTArrayRef(nsTArray<nsCString>);
|
||||
|
||||
[scriptable, builtinclass, uuid(7836a872-e50c-4e43-8224-fd08a8d09699)]
|
||||
[scriptable, builtinclass, uuid(89b819dc-31b0-4d09-915a-66f8a3703483)]
|
||||
interface nsISSLSocketControl : nsISupports {
|
||||
attribute nsIInterfaceRequestor notificationCallbacks;
|
||||
|
||||
@ -83,6 +83,7 @@ interface nsISSLSocketControl : nsISupports {
|
||||
const short SSL_VERSION_UNKNOWN = -1;
|
||||
|
||||
[infallible] readonly attribute short SSLVersionUsed;
|
||||
[infallible] readonly attribute short SSLVersionOffered;
|
||||
|
||||
/* These values match the NSS defined values in sslt.h */
|
||||
const short SSL_MAC_UNKNOWN = -1;
|
||||
|
@ -197,6 +197,13 @@ nsNSSSocketInfo::GetSSLVersionUsed(int16_t* aSSLVersionUsed)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSSocketInfo::GetSSLVersionOffered(int16_t* aSSLVersionOffered)
|
||||
{
|
||||
*aSSLVersionOffered = mTLSVersionRange.max;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSSocketInfo::GetMACAlgorithmUsed(int16_t* aMac)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user