mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-06-08 05:29:36 +00:00
#590: TLS 1.3 support (consolidated) with locale workaround
This commit is contained in:
parent
91d1dfb59b
commit
fae264c819
|
@ -90,6 +90,9 @@ var security = {
|
||||||
case nsISSLStatus.TLS_VERSION_1_2:
|
case nsISSLStatus.TLS_VERSION_1_2:
|
||||||
retval.version = "TLS 1.2"
|
retval.version = "TLS 1.2"
|
||||||
break;
|
break;
|
||||||
|
case nsISSLStatus.TLS_VERSION_1_3:
|
||||||
|
retval.version = "TLS 1.3"
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
1
config/external/nss/Makefile.in
vendored
1
config/external/nss/Makefile.in
vendored
|
@ -122,6 +122,7 @@ DEFAULT_GMAKE_FLAGS += NSPR_LIB_DIR=$(NSPR_LIB_DIR)
|
||||||
DEFAULT_GMAKE_FLAGS += MOZILLA_CLIENT=1
|
DEFAULT_GMAKE_FLAGS += MOZILLA_CLIENT=1
|
||||||
DEFAULT_GMAKE_FLAGS += NO_MDUPDATE=1
|
DEFAULT_GMAKE_FLAGS += NO_MDUPDATE=1
|
||||||
DEFAULT_GMAKE_FLAGS += NSS_ENABLE_ECC=1
|
DEFAULT_GMAKE_FLAGS += NSS_ENABLE_ECC=1
|
||||||
|
DEFAULT_GMAKE_FLAGS += NSS_ENABLE_TLS_1_3=1
|
||||||
ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_1)
|
ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_1)
|
||||||
DEFAULT_GMAKE_FLAGS += OS_DLLFLAGS='-static-libgcc' NSPR31_LIB_PREFIX=lib
|
DEFAULT_GMAKE_FLAGS += OS_DLLFLAGS='-static-libgcc' NSPR31_LIB_PREFIX=lib
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -529,7 +529,7 @@ var NetworkHelper = {
|
||||||
* If state == broken:
|
* If state == broken:
|
||||||
* - errorMessage: full error message from nsITransportSecurityInfo.
|
* - errorMessage: full error message from nsITransportSecurityInfo.
|
||||||
* If state == secure:
|
* If state == secure:
|
||||||
* - protocolVersion: one of TLSv1, TLSv1.1, TLSv1.2.
|
* - protocolVersion: one of TLSv1, TLSv1.1, TLSv1.2, TLSv1.3.
|
||||||
* - cipherSuite: the cipher suite used in this connection.
|
* - cipherSuite: the cipher suite used in this connection.
|
||||||
* - cert: information about certificate used in this connection.
|
* - cert: information about certificate used in this connection.
|
||||||
* See parseCertificateInfo for the contents.
|
* See parseCertificateInfo for the contents.
|
||||||
|
@ -712,7 +712,7 @@ var NetworkHelper = {
|
||||||
* @param Number version
|
* @param Number version
|
||||||
* One of nsISSLStatus version constants.
|
* One of nsISSLStatus version constants.
|
||||||
* @return string
|
* @return string
|
||||||
* One of TLSv1, TLSv1.1, TLSv1.2 if @param version is valid,
|
* One of TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 if @param version is valid,
|
||||||
* Unknown otherwise.
|
* Unknown otherwise.
|
||||||
*/
|
*/
|
||||||
formatSecurityProtocol: function NH_formatSecurityProtocol(version) {
|
formatSecurityProtocol: function NH_formatSecurityProtocol(version) {
|
||||||
|
@ -723,6 +723,8 @@ var NetworkHelper = {
|
||||||
return "TLSv1.1";
|
return "TLSv1.1";
|
||||||
case Ci.nsISSLStatus.TLS_VERSION_1_2:
|
case Ci.nsISSLStatus.TLS_VERSION_1_2:
|
||||||
return "TLSv1.2";
|
return "TLSv1.2";
|
||||||
|
case Ci.nsISSLStatus.TLS_VERSION_1_3:
|
||||||
|
return "TLSv1.3";
|
||||||
default:
|
default:
|
||||||
DevToolsUtils.reportException("NetworkHelper.formatSecurityProtocol",
|
DevToolsUtils.reportException("NetworkHelper.formatSecurityProtocol",
|
||||||
"protocolVersion " + version + " is unknown.");
|
"protocolVersion " + version + " is unknown.");
|
||||||
|
|
|
@ -1116,6 +1116,8 @@ NS_IMETHODIMP nsWebBrowserPersist::OnStatus(
|
||||||
case NS_NET_STATUS_END_FTP_TRANSACTION:
|
case NS_NET_STATUS_END_FTP_TRANSACTION:
|
||||||
case NS_NET_STATUS_CONNECTING_TO:
|
case NS_NET_STATUS_CONNECTING_TO:
|
||||||
case NS_NET_STATUS_CONNECTED_TO:
|
case NS_NET_STATUS_CONNECTED_TO:
|
||||||
|
case NS_NET_STATUS_TLS_HANDSHAKE_STARTING:
|
||||||
|
case NS_NET_STATUS_TLS_HANDSHAKE_ENDED:
|
||||||
case NS_NET_STATUS_SENDING_TO:
|
case NS_NET_STATUS_SENDING_TO:
|
||||||
case NS_NET_STATUS_RECEIVING_FROM:
|
case NS_NET_STATUS_RECEIVING_FROM:
|
||||||
case NS_NET_STATUS_WAITING_FOR:
|
case NS_NET_STATUS_WAITING_FOR:
|
||||||
|
|
|
@ -454,6 +454,15 @@ TransportLayerDtls::SetVerificationDigest(const std::string digest_algorithm,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These are the named groups that we will allow.
|
||||||
|
static const SSLNamedGroup NamedGroupPreferences[] = {
|
||||||
|
ssl_grp_ec_curve25519,
|
||||||
|
ssl_grp_ec_secp256r1,
|
||||||
|
ssl_grp_ec_secp384r1,
|
||||||
|
ssl_grp_ffdhe_2048,
|
||||||
|
ssl_grp_ffdhe_3072
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: make sure this is called from STS. Otherwise
|
// TODO: make sure this is called from STS. Otherwise
|
||||||
// we have thread safety issues
|
// we have thread safety issues
|
||||||
bool TransportLayerDtls::Setup() {
|
bool TransportLayerDtls::Setup() {
|
||||||
|
@ -588,6 +597,13 @@ bool TransportLayerDtls::Setup() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rv = SSL_NamedGroupConfig(ssl_fd, NamedGroupPreferences,
|
||||||
|
mozilla::ArrayLength(NamedGroupPreferences));
|
||||||
|
if (rv != SECSuccess) {
|
||||||
|
MOZ_MTLOG(ML_ERROR, "Couldn't set named groups");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Certificate validation
|
// Certificate validation
|
||||||
rv = SSL_AuthCertificateHook(ssl_fd, AuthCertificateHook,
|
rv = SSL_AuthCertificateHook(ssl_fd, AuthCertificateHook,
|
||||||
reinterpret_cast<void *>(this));
|
reinterpret_cast<void *>(this));
|
||||||
|
@ -675,6 +691,7 @@ static const uint32_t EnabledCiphers[] = {
|
||||||
static const uint32_t DisabledCiphers[] = {
|
static const uint32_t DisabledCiphers[] = {
|
||||||
// ALL SHA384 ciphers are disabled per bug 1310061.
|
// ALL SHA384 ciphers are disabled per bug 1310061.
|
||||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||||
|
TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||||
|
|
||||||
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
|
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
|
||||||
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
|
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||||
|
@ -702,22 +719,14 @@ static const uint32_t DisabledCiphers[] = {
|
||||||
TLS_RSA_WITH_AES_256_CBC_SHA256,
|
TLS_RSA_WITH_AES_256_CBC_SHA256,
|
||||||
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
|
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
|
||||||
TLS_RSA_WITH_SEED_CBC_SHA,
|
TLS_RSA_WITH_SEED_CBC_SHA,
|
||||||
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,
|
|
||||||
TLS_RSA_WITH_3DES_EDE_CBC_SHA,
|
TLS_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||||
TLS_RSA_WITH_RC4_128_SHA,
|
TLS_RSA_WITH_RC4_128_SHA,
|
||||||
TLS_RSA_WITH_RC4_128_MD5,
|
TLS_RSA_WITH_RC4_128_MD5,
|
||||||
|
|
||||||
TLS_DHE_RSA_WITH_DES_CBC_SHA,
|
TLS_DHE_RSA_WITH_DES_CBC_SHA,
|
||||||
TLS_DHE_DSS_WITH_DES_CBC_SHA,
|
TLS_DHE_DSS_WITH_DES_CBC_SHA,
|
||||||
SSL_RSA_FIPS_WITH_DES_CBC_SHA,
|
|
||||||
TLS_RSA_WITH_DES_CBC_SHA,
|
TLS_RSA_WITH_DES_CBC_SHA,
|
||||||
|
|
||||||
TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
|
|
||||||
TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
|
|
||||||
|
|
||||||
TLS_RSA_EXPORT_WITH_RC4_40_MD5,
|
|
||||||
TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
|
|
||||||
|
|
||||||
TLS_ECDHE_ECDSA_WITH_NULL_SHA,
|
TLS_ECDHE_ECDSA_WITH_NULL_SHA,
|
||||||
TLS_ECDHE_RSA_WITH_NULL_SHA,
|
TLS_ECDHE_RSA_WITH_NULL_SHA,
|
||||||
TLS_ECDH_ECDSA_WITH_NULL_SHA,
|
TLS_ECDH_ECDSA_WITH_NULL_SHA,
|
||||||
|
|
|
@ -893,13 +893,15 @@ typedef struct
|
||||||
#define ERROR(key, val) {key, #key}
|
#define ERROR(key, val) {key, #key}
|
||||||
|
|
||||||
ErrorEntry socketTransportStatuses[] = {
|
ErrorEntry socketTransportStatuses[] = {
|
||||||
ERROR(NS_NET_STATUS_RESOLVING_HOST, FAILURE(3)),
|
ERROR(NS_NET_STATUS_RESOLVING_HOST, FAILURE(3)),
|
||||||
ERROR(NS_NET_STATUS_RESOLVED_HOST, FAILURE(11)),
|
ERROR(NS_NET_STATUS_RESOLVED_HOST, FAILURE(11)),
|
||||||
ERROR(NS_NET_STATUS_CONNECTING_TO, FAILURE(7)),
|
ERROR(NS_NET_STATUS_CONNECTING_TO, FAILURE(7)),
|
||||||
ERROR(NS_NET_STATUS_CONNECTED_TO, FAILURE(4)),
|
ERROR(NS_NET_STATUS_CONNECTED_TO, FAILURE(4)),
|
||||||
ERROR(NS_NET_STATUS_SENDING_TO, FAILURE(5)),
|
ERROR(NS_NET_STATUS_TLS_HANDSHAKE_STARTING, FAILURE(12)),
|
||||||
ERROR(NS_NET_STATUS_WAITING_FOR, FAILURE(10)),
|
ERROR(NS_NET_STATUS_TLS_HANDSHAKE_ENDED, FAILURE(13)),
|
||||||
ERROR(NS_NET_STATUS_RECEIVING_FROM, FAILURE(6)),
|
ERROR(NS_NET_STATUS_SENDING_TO, FAILURE(5)),
|
||||||
|
ERROR(NS_NET_STATUS_WAITING_FOR, FAILURE(10)),
|
||||||
|
ERROR(NS_NET_STATUS_RECEIVING_FROM, FAILURE(6)),
|
||||||
};
|
};
|
||||||
#undef ERROR
|
#undef ERROR
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ interface nsITLSClientStatus : nsISupports
|
||||||
const short TLS_VERSION_1 = 0x0301;
|
const short TLS_VERSION_1 = 0x0301;
|
||||||
const short TLS_VERSION_1_1 = 0x0302;
|
const short TLS_VERSION_1_1 = 0x0302;
|
||||||
const short TLS_VERSION_1_2 = 0x0303;
|
const short TLS_VERSION_1_2 = 0x0303;
|
||||||
|
const short TLS_VERSION_1_3 = 0x0304;
|
||||||
const short TLS_VERSION_UNKNOWN = -1;
|
const short TLS_VERSION_UNKNOWN = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
pref("security.tls.version.min", 1);
|
pref("security.tls.version.min", 1);
|
||||||
pref("security.tls.version.max", 3);
|
pref("security.tls.version.max", 4);
|
||||||
pref("security.tls.version.fallback-limit", 3);
|
pref("security.tls.version.fallback-limit", 3);
|
||||||
pref("security.tls.insecure_fallback_hosts", "");
|
pref("security.tls.insecure_fallback_hosts", "");
|
||||||
pref("security.tls.unrestricted_rc4_fallback", false);
|
pref("security.tls.unrestricted_rc4_fallback", false);
|
||||||
|
pref("security.tls.enable_0rtt_data", true);
|
||||||
|
|
||||||
pref("security.ssl.treat_unsafe_negotiation_as_broken", false);
|
pref("security.ssl.treat_unsafe_negotiation_as_broken", false);
|
||||||
pref("security.ssl.require_safe_negotiation", false);
|
pref("security.ssl.require_safe_negotiation", false);
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
9=Wrote %1$S
|
9=Wrote %1$S
|
||||||
10=Waiting for %1$S…
|
10=Waiting for %1$S…
|
||||||
11=Looked up %1$S…
|
11=Looked up %1$S…
|
||||||
|
12=Performing a TLS handshake to %1$S…
|
||||||
|
13=The TLS handshake finished for %1$S…
|
||||||
|
|
||||||
27=Beginning FTP transaction…
|
27=Beginning FTP transaction…
|
||||||
28=Finished FTP transaction
|
28=Finished FTP transaction
|
||||||
|
|
|
@ -2025,6 +2025,8 @@ nsFtpState::OnTransportStatus(nsITransport *transport, nsresult status,
|
||||||
case NS_NET_STATUS_RESOLVED_HOST:
|
case NS_NET_STATUS_RESOLVED_HOST:
|
||||||
case NS_NET_STATUS_CONNECTING_TO:
|
case NS_NET_STATUS_CONNECTING_TO:
|
||||||
case NS_NET_STATUS_CONNECTED_TO:
|
case NS_NET_STATUS_CONNECTED_TO:
|
||||||
|
case NS_NET_STATUS_TLS_HANDSHAKE_STARTING:
|
||||||
|
case NS_NET_STATUS_TLS_HANDSHAKE_ENDED:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -2240,6 +2240,8 @@ Http2Session::OnTransportStatus(nsITransport* aTransport,
|
||||||
case NS_NET_STATUS_RESOLVED_HOST:
|
case NS_NET_STATUS_RESOLVED_HOST:
|
||||||
case NS_NET_STATUS_CONNECTING_TO:
|
case NS_NET_STATUS_CONNECTING_TO:
|
||||||
case NS_NET_STATUS_CONNECTED_TO:
|
case NS_NET_STATUS_CONNECTED_TO:
|
||||||
|
case NS_NET_STATUS_TLS_HANDSHAKE_STARTING:
|
||||||
|
case NS_NET_STATUS_TLS_HANDSHAKE_ENDED:
|
||||||
{
|
{
|
||||||
Http2Stream *target = mStreamIDHash.Get(1);
|
Http2Stream *target = mStreamIDHash.Get(1);
|
||||||
nsAHttpTransaction *transaction = target ? target->Transaction() : nullptr;
|
nsAHttpTransaction *transaction = target ? target->Transaction() : nullptr;
|
||||||
|
@ -2306,7 +2308,13 @@ Http2Session::ReadSegmentsAgain(nsAHttpSegmentReader *reader,
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
LOG3(("Http2Session %p could not identify a stream to write; suspending.",
|
LOG3(("Http2Session %p could not identify a stream to write; suspending.",
|
||||||
this));
|
this));
|
||||||
|
uint32_t availBeforeFlush = mOutputQueueUsed - mOutputQueueSent;
|
||||||
FlushOutputQueue();
|
FlushOutputQueue();
|
||||||
|
uint32_t availAfterFlush = mOutputQueueUsed - mOutputQueueSent;
|
||||||
|
if (availBeforeFlush != availAfterFlush) {
|
||||||
|
LOG3(("Http2Session %p ResumeRecv After early flush in ReadSegments", this));
|
||||||
|
ResumeRecv();
|
||||||
|
}
|
||||||
SetWriteCallbacks();
|
SetWriteCallbacks();
|
||||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,6 +204,22 @@ public:
|
||||||
|
|
||||||
virtual void DisableSpdy() { }
|
virtual void DisableSpdy() { }
|
||||||
virtual void ReuseConnectionOnRestartOK(bool) { }
|
virtual void ReuseConnectionOnRestartOK(bool) { }
|
||||||
|
|
||||||
|
// Returns true if early-data is possible.
|
||||||
|
virtual bool Do0RTT() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// This function will be called when a tls handshake has been finished and
|
||||||
|
// we know whether early-data that was sent has been accepted or not, e.g.
|
||||||
|
// do we need to restart a transaction. This will be called only if Do0RTT
|
||||||
|
// returns true.
|
||||||
|
// If aRestart parameter is true we need to restart the transaction,
|
||||||
|
// otherwise the erly-data has been accepted and we can continue the
|
||||||
|
// transaction.
|
||||||
|
// The function will return success or failure of the transaction restart.
|
||||||
|
virtual nsresult Finish0RTT(bool aRestart) {
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpTransaction, NS_AHTTPTRANSACTION_IID)
|
NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpTransaction, NS_AHTTPTRANSACTION_IID)
|
||||||
|
|
|
@ -79,6 +79,9 @@ nsHttpConnection::nsHttpConnection()
|
||||||
, mResponseTimeoutEnabled(false)
|
, mResponseTimeoutEnabled(false)
|
||||||
, mTCPKeepaliveConfig(kTCPKeepaliveDisabled)
|
, mTCPKeepaliveConfig(kTCPKeepaliveDisabled)
|
||||||
, mForceSendPending(false)
|
, mForceSendPending(false)
|
||||||
|
, m0RTTChecked(false)
|
||||||
|
, mWaitingFor0RTTResponse(false)
|
||||||
|
, mContentBytesWritten0RTT(0)
|
||||||
{
|
{
|
||||||
LOG(("Creating nsHttpConnection @%p\n", this));
|
LOG(("Creating nsHttpConnection @%p\n", this));
|
||||||
|
|
||||||
|
@ -96,18 +99,22 @@ nsHttpConnection::~nsHttpConnection()
|
||||||
if (!mEverUsedSpdy) {
|
if (!mEverUsedSpdy) {
|
||||||
LOG(("nsHttpConnection %p performed %d HTTP/1.x transactions\n",
|
LOG(("nsHttpConnection %p performed %d HTTP/1.x transactions\n",
|
||||||
this, mHttp1xTransactionCount));
|
this, mHttp1xTransactionCount));
|
||||||
|
/*
|
||||||
Telemetry::Accumulate(Telemetry::HTTP_REQUEST_PER_CONN,
|
Telemetry::Accumulate(Telemetry::HTTP_REQUEST_PER_CONN,
|
||||||
mHttp1xTransactionCount);
|
mHttp1xTransactionCount);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTotalBytesRead) {
|
if (mTotalBytesRead) {
|
||||||
uint32_t totalKBRead = static_cast<uint32_t>(mTotalBytesRead >> 10);
|
uint32_t totalKBRead = static_cast<uint32_t>(mTotalBytesRead >> 10);
|
||||||
LOG(("nsHttpConnection %p read %dkb on connection spdy=%d\n",
|
LOG(("nsHttpConnection %p read %dkb on connection spdy=%d\n",
|
||||||
this, totalKBRead, mEverUsedSpdy));
|
this, totalKBRead, mEverUsedSpdy));
|
||||||
|
/*
|
||||||
Telemetry::Accumulate(mEverUsedSpdy ?
|
Telemetry::Accumulate(mEverUsedSpdy ?
|
||||||
Telemetry::SPDY_KBREAD_PER_CONN :
|
Telemetry::SPDY_KBREAD_PER_CONN :
|
||||||
Telemetry::HTTP_KBREAD_PER_CONN,
|
Telemetry::HTTP_KBREAD_PER_CONN,
|
||||||
totalKBRead);
|
totalKBRead);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
if (mForceSendTimer) {
|
if (mForceSendTimer) {
|
||||||
mForceSendTimer->Cancel();
|
mForceSendTimer->Cancel();
|
||||||
|
@ -268,8 +275,12 @@ nsHttpConnection::StartSpdy(uint8_t spdyVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsHttpConnection::EnsureNPNComplete()
|
nsHttpConnection::EnsureNPNComplete(nsresult &aOut0RTTWriteHandshakeValue,
|
||||||
|
uint32_t &aOut0RTTBytesWritten)
|
||||||
{
|
{
|
||||||
|
aOut0RTTWriteHandshakeValue = NS_OK;
|
||||||
|
aOut0RTTBytesWritten = 0;
|
||||||
|
|
||||||
// If for some reason the components to check on NPN aren't available,
|
// 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
|
// this function will just return true to continue on and disable SPDY
|
||||||
|
|
||||||
|
@ -294,16 +305,81 @@ nsHttpConnection::EnsureNPNComplete()
|
||||||
goto npnComplete;
|
goto npnComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m0RTTChecked) {
|
||||||
|
// We reuse m0RTTChecked. We want to send this status only once.
|
||||||
|
mTransaction->OnTransportStatus(mSocketTransport,
|
||||||
|
NS_NET_STATUS_TLS_HANDSHAKE_STARTING,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
ssl = do_QueryInterface(securityInfo, &rv);
|
ssl = do_QueryInterface(securityInfo, &rv);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
goto npnComplete;
|
goto npnComplete;
|
||||||
|
|
||||||
rv = ssl->GetNegotiatedNPN(negotiatedNPN);
|
rv = ssl->GetNegotiatedNPN(negotiatedNPN);
|
||||||
|
if (!m0RTTChecked && (rv == NS_ERROR_NOT_CONNECTED) &&
|
||||||
|
!mConnInfo->UsingProxy()) {
|
||||||
|
// There is no ALPN info (yet!). We need to consider doing 0RTT. We
|
||||||
|
// will do so if there is ALPN information from a previous session
|
||||||
|
// (AlpnEarlySelection), we are using HTTP/1, and the request data can
|
||||||
|
// be safely retried.
|
||||||
|
m0RTTChecked = true;
|
||||||
|
nsAutoCString earlyNegotiatedNPN;
|
||||||
|
nsresult rvEarlyAlpn = ssl->GetAlpnEarlySelection(earlyNegotiatedNPN);
|
||||||
|
if (NS_FAILED(rvEarlyAlpn)) {
|
||||||
|
// if ssl->DriveHandshake() has never been called the value
|
||||||
|
// for AlpnEarlySelection is still not set. So call it here and
|
||||||
|
// check again.
|
||||||
|
LOG(("nsHttpConnection::EnsureNPNComplete %p - "
|
||||||
|
"early selected alpn not available, we will try one more time.",
|
||||||
|
this));
|
||||||
|
// Let's do DriveHandshake again.
|
||||||
|
rv = ssl->DriveHandshake();
|
||||||
|
if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) {
|
||||||
|
goto npnComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check NegotiatedNPN first.
|
||||||
|
rv = ssl->GetNegotiatedNPN(negotiatedNPN);
|
||||||
|
if (rv == NS_ERROR_NOT_CONNECTED) {
|
||||||
|
rvEarlyAlpn = ssl->GetAlpnEarlySelection(earlyNegotiatedNPN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(rvEarlyAlpn)) {
|
||||||
|
LOG(("nsHttpConnection::EnsureNPNComplete %p - "
|
||||||
|
"early selected alpn not available", this));
|
||||||
|
} else {
|
||||||
|
LOG(("nsHttpConnection::EnsureNPNComplete %p -"
|
||||||
|
"early selected alpn: %s", this, earlyNegotiatedNPN.get()));
|
||||||
|
uint32_t infoIndex;
|
||||||
|
const SpdyInformation *info = gHttpHandler->SpdyInfo();
|
||||||
|
// We are doing 0RTT only with Http/1 right now!
|
||||||
|
if (NS_FAILED(info->GetNPNIndex(earlyNegotiatedNPN, &infoIndex))) {
|
||||||
|
// Check if early-data is allowed for this transaction.
|
||||||
|
if (mTransaction->Do0RTT()) {
|
||||||
|
LOG(("nsHttpConnection::EnsureNPNComplete [this=%p] - We "
|
||||||
|
"can do 0RTT!", this));
|
||||||
|
mWaitingFor0RTTResponse = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rv == NS_ERROR_NOT_CONNECTED) {
|
if (rv == NS_ERROR_NOT_CONNECTED) {
|
||||||
// By writing 0 bytes to the socket the SSL handshake machine is
|
if (mWaitingFor0RTTResponse) {
|
||||||
// pushed forward.
|
aOut0RTTWriteHandshakeValue = mTransaction->ReadSegments(this,
|
||||||
uint32_t count = 0;
|
nsIOService::gDefaultSegmentSize, &aOut0RTTBytesWritten);
|
||||||
rv = mSocketOut->Write("", 0, &count);
|
if (NS_FAILED(aOut0RTTWriteHandshakeValue) &&
|
||||||
|
aOut0RTTWriteHandshakeValue != NS_BASE_STREAM_WOULD_BLOCK) {
|
||||||
|
goto npnComplete;
|
||||||
|
}
|
||||||
|
LOG(("nsHttpConnection::EnsureNPNComplete [this=%p] - written %d "
|
||||||
|
"bytes during 0RTT", this, aOut0RTTBytesWritten));
|
||||||
|
mContentBytesWritten0RTT += aOut0RTTBytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = ssl->DriveHandshake();
|
||||||
if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) {
|
if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) {
|
||||||
goto npnComplete;
|
goto npnComplete;
|
||||||
}
|
}
|
||||||
|
@ -316,18 +392,49 @@ nsHttpConnection::EnsureNPNComplete()
|
||||||
this, mConnInfo->HashKey().get(), negotiatedNPN.get(),
|
this, mConnInfo->HashKey().get(), negotiatedNPN.get(),
|
||||||
mTLSFilter ? " [Double Tunnel]" : ""));
|
mTLSFilter ? " [Double Tunnel]" : ""));
|
||||||
|
|
||||||
uint32_t infoIndex;
|
bool ealyDataAccepted = false;
|
||||||
const SpdyInformation *info = gHttpHandler->SpdyInfo();
|
if (mWaitingFor0RTTResponse) {
|
||||||
if (NS_SUCCEEDED(info->GetNPNIndex(negotiatedNPN, &infoIndex))) {
|
mWaitingFor0RTTResponse = false;
|
||||||
StartSpdy(info->Version[infoIndex]);
|
// Check if early data has been accepted.
|
||||||
|
rv = ssl->GetEarlyDataAccepted(&ealyDataAccepted);
|
||||||
|
LOG(("nsHttpConnection::EnsureNPNComplete [this=%p] - early data "
|
||||||
|
"that was sent during 0RTT %s been accepted.",
|
||||||
|
this, ealyDataAccepted ? "has" : "has not"));
|
||||||
|
if (NS_FAILED(rv) ||
|
||||||
|
NS_FAILED(mTransaction->Finish0RTT(!ealyDataAccepted))) {
|
||||||
|
mTransaction->Close(NS_ERROR_NET_RESET);
|
||||||
|
goto npnComplete;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ealyDataAccepted) {
|
||||||
|
uint32_t infoIndex;
|
||||||
|
const SpdyInformation *info = gHttpHandler->SpdyInfo();
|
||||||
|
if (NS_SUCCEEDED(info->GetNPNIndex(negotiatedNPN, &infoIndex))) {
|
||||||
|
StartSpdy(info->Version[infoIndex]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG(("nsHttpConnection::EnsureNPNComplete [this=%p] - %d bytes "
|
||||||
|
"has been sent during 0RTT.", this, mContentBytesWritten0RTT));
|
||||||
|
mContentBytesWritten = mContentBytesWritten0RTT;
|
||||||
}
|
}
|
||||||
|
|
||||||
Telemetry::Accumulate(Telemetry::SPDY_NPN_CONNECT, UsingSpdy());
|
//Telemetry::Accumulate(Telemetry::SPDY_NPN_CONNECT, UsingSpdy());
|
||||||
}
|
}
|
||||||
|
|
||||||
npnComplete:
|
npnComplete:
|
||||||
LOG(("nsHttpConnection::EnsureNPNComplete setting complete to true"));
|
LOG(("nsHttpConnection::EnsureNPNComplete setting complete to true"));
|
||||||
mNPNComplete = true;
|
mNPNComplete = true;
|
||||||
|
|
||||||
|
mTransaction->OnTransportStatus(mSocketTransport,
|
||||||
|
NS_NET_STATUS_TLS_HANDSHAKE_ENDED,
|
||||||
|
0);
|
||||||
|
if (mWaitingFor0RTTResponse) {
|
||||||
|
mWaitingFor0RTTResponse = false;
|
||||||
|
if (NS_FAILED(mTransaction->Finish0RTT(true))) {
|
||||||
|
mTransaction->Close(NS_ERROR_NET_RESET);
|
||||||
|
}
|
||||||
|
mContentBytesWritten0RTT = 0;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1572,7 +1679,9 @@ nsHttpConnection::OnSocketWritable()
|
||||||
// request differently for http/1, http/2, spdy, etc.. and that is
|
// request differently for http/1, http/2, spdy, etc.. and that is
|
||||||
// negotiated with NPN/ALPN in the SSL handshake.
|
// negotiated with NPN/ALPN in the SSL handshake.
|
||||||
|
|
||||||
if (mConnInfo->UsingHttpsProxy() && !EnsureNPNComplete()) {
|
if (mConnInfo->UsingHttpsProxy() &&
|
||||||
|
!EnsureNPNComplete(rv, transactionBytes)) {
|
||||||
|
MOZ_ASSERT(!transactionBytes);
|
||||||
mSocketOutCondition = NS_BASE_STREAM_WOULD_BLOCK;
|
mSocketOutCondition = NS_BASE_STREAM_WOULD_BLOCK;
|
||||||
} else if (mProxyConnectStream) {
|
} else if (mProxyConnectStream) {
|
||||||
// If we're need an HTTP/1 CONNECT tunnel through a proxy
|
// If we're need an HTTP/1 CONNECT tunnel through a proxy
|
||||||
|
@ -1581,8 +1690,11 @@ nsHttpConnection::OnSocketWritable()
|
||||||
rv = mProxyConnectStream->ReadSegments(ReadFromStream, this,
|
rv = mProxyConnectStream->ReadSegments(ReadFromStream, this,
|
||||||
nsIOService::gDefaultSegmentSize,
|
nsIOService::gDefaultSegmentSize,
|
||||||
&transactionBytes);
|
&transactionBytes);
|
||||||
} else if (!EnsureNPNComplete()) {
|
} else if (!EnsureNPNComplete(rv, transactionBytes)) {
|
||||||
mSocketOutCondition = NS_BASE_STREAM_WOULD_BLOCK;
|
if (NS_SUCCEEDED(rv) && !transactionBytes &&
|
||||||
|
NS_SUCCEEDED(mSocketOutCondition)) {
|
||||||
|
mSocketOutCondition = NS_BASE_STREAM_WOULD_BLOCK;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// for non spdy sessions let the connection manager know
|
// for non spdy sessions let the connection manager know
|
||||||
|
@ -1630,7 +1742,7 @@ nsHttpConnection::OnSocketWritable()
|
||||||
} else if (!transactionBytes) {
|
} else if (!transactionBytes) {
|
||||||
rv = NS_OK;
|
rv = NS_OK;
|
||||||
|
|
||||||
if (mTransaction) { // in case the ReadSegments stack called CloseTransaction()
|
if (mTransaction && !mWaitingFor0RTTResponse) { // in case the ReadSegments stack called CloseTransaction()
|
||||||
//
|
//
|
||||||
// at this point we've written out the entire transaction, and now we
|
// at this point we've written out the entire transaction, and now we
|
||||||
// must wait for the server's response. we manufacture a status message
|
// must wait for the server's response. we manufacture a status message
|
||||||
|
|
|
@ -241,7 +241,8 @@ private:
|
||||||
|
|
||||||
// Makes certain the SSL handshake is complete and NPN negotiation
|
// Makes certain the SSL handshake is complete and NPN negotiation
|
||||||
// has had a chance to happen
|
// has had a chance to happen
|
||||||
bool EnsureNPNComplete();
|
bool EnsureNPNComplete(nsresult &aOut0RTTWriteHandshakeValue,
|
||||||
|
uint32_t &aOut0RTTBytesWritten);
|
||||||
void SetupSSL();
|
void SetupSSL();
|
||||||
|
|
||||||
// Start the Spdy transaction handler when NPN indicates spdy/*
|
// Start the Spdy transaction handler when NPN indicates spdy/*
|
||||||
|
@ -350,6 +351,17 @@ private:
|
||||||
uint32_t mTCPKeepaliveConfig;
|
uint32_t mTCPKeepaliveConfig;
|
||||||
nsCOMPtr<nsITimer> mTCPKeepaliveTransitionTimer;
|
nsCOMPtr<nsITimer> mTCPKeepaliveTransitionTimer;
|
||||||
|
|
||||||
|
// Helper variable for 0RTT handshake;
|
||||||
|
bool m0RTTChecked; // Possible 0RTT has been
|
||||||
|
// checked.
|
||||||
|
bool mWaitingFor0RTTResponse; // We have are
|
||||||
|
// sending 0RTT
|
||||||
|
// data and we
|
||||||
|
// are waiting
|
||||||
|
// for the end of
|
||||||
|
// the handsake.
|
||||||
|
int64_t mContentBytesWritten0RTT;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// For ForceSend()
|
// For ForceSend()
|
||||||
static void ForceSendIO(nsITimer *aTimer, void *aClosure);
|
static void ForceSendIO(nsITimer *aTimer, void *aClosure);
|
||||||
|
|
|
@ -142,6 +142,8 @@ nsHttpTransaction::nsHttpTransaction()
|
||||||
, mAppId(NECKO_NO_APP_ID)
|
, mAppId(NECKO_NO_APP_ID)
|
||||||
, mIsInBrowser(false)
|
, mIsInBrowser(false)
|
||||||
, mClassOfService(0)
|
, mClassOfService(0)
|
||||||
|
, m0RTTInProgress(false)
|
||||||
|
, mTransportStatus(NS_OK)
|
||||||
{
|
{
|
||||||
LOG(("Creating nsHttpTransaction @%p\n", this));
|
LOG(("Creating nsHttpTransaction @%p\n", this));
|
||||||
gHttpHandler->GetMaxPipelineObjectSize(&mMaxPipelineObjectSize);
|
gHttpHandler->GetMaxPipelineObjectSize(&mMaxPipelineObjectSize);
|
||||||
|
@ -532,6 +534,50 @@ nsHttpTransaction::OnTransportStatus(nsITransport* transport,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A transaction can given to multiple HalfOpen sockets (this is a bug in
|
||||||
|
// nsHttpConnectionMgr). We are going to fix it here as a work around to be
|
||||||
|
// able to uplift it.
|
||||||
|
switch(status) {
|
||||||
|
case NS_NET_STATUS_RESOLVING_HOST:
|
||||||
|
if (mTransportStatus != NS_OK) {
|
||||||
|
LOG(("nsHttpTransaction::OnSocketStatus - ignore socket events "
|
||||||
|
"from backup transport"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NS_NET_STATUS_RESOLVED_HOST:
|
||||||
|
if (mTransportStatus != NS_NET_STATUS_RESOLVING_HOST &&
|
||||||
|
mTransportStatus != NS_OK) {
|
||||||
|
LOG(("nsHttpTransaction::OnSocketStatus - ignore socket events "
|
||||||
|
"from backup transport"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NS_NET_STATUS_CONNECTING_TO:
|
||||||
|
if (mTransportStatus != NS_NET_STATUS_RESOLVING_HOST &&
|
||||||
|
mTransportStatus != NS_NET_STATUS_RESOLVED_HOST &&
|
||||||
|
mTransportStatus != NS_OK) {
|
||||||
|
LOG(("nsHttpTransaction::OnSocketStatus - ignore socket events "
|
||||||
|
"from backup transport"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NS_NET_STATUS_CONNECTED_TO:
|
||||||
|
if (mTransportStatus != NS_NET_STATUS_RESOLVING_HOST &&
|
||||||
|
mTransportStatus != NS_NET_STATUS_RESOLVED_HOST &&
|
||||||
|
mTransportStatus != NS_NET_STATUS_CONNECTING_TO &&
|
||||||
|
mTransportStatus != NS_OK) {
|
||||||
|
LOG(("nsHttpTransaction::OnSocketStatus - ignore socket events "
|
||||||
|
"from backup transport"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG(("nsHttpTransaction::OnSocketStatus - a new event"));
|
||||||
|
}
|
||||||
|
|
||||||
|
mTransportStatus = status;
|
||||||
|
|
||||||
// If the timing is enabled, and we are not using a persistent connection
|
// If the timing is enabled, and we are not using a persistent connection
|
||||||
// then the requestStart timestamp will be null, so we mark the timestamps
|
// then the requestStart timestamp will be null, so we mark the timestamps
|
||||||
// for domainLookupStart/End and connectStart/End
|
// for domainLookupStart/End and connectStart/End
|
||||||
|
@ -545,7 +591,9 @@ nsHttpTransaction::OnTransportStatus(nsITransport* transport,
|
||||||
} else if (status == NS_NET_STATUS_CONNECTING_TO) {
|
} else if (status == NS_NET_STATUS_CONNECTING_TO) {
|
||||||
SetConnectStart(TimeStamp::Now());
|
SetConnectStart(TimeStamp::Now());
|
||||||
} else if (status == NS_NET_STATUS_CONNECTED_TO) {
|
} else if (status == NS_NET_STATUS_CONNECTED_TO) {
|
||||||
SetConnectEnd(TimeStamp::Now());
|
SetConnectEnd(TimeStamp::Now(), true);
|
||||||
|
} else if (status == NS_NET_STATUS_TLS_HANDSHAKE_ENDED) {
|
||||||
|
SetConnectEnd(TimeStamp::Now(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,7 +738,7 @@ nsHttpTransaction::ReadSegments(nsAHttpSegmentReader *reader,
|
||||||
return mStatus;
|
return mStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mConnected) {
|
if (!mConnected && !m0RTTInProgress) {
|
||||||
mConnected = true;
|
mConnected = true;
|
||||||
mConnection->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
|
mConnection->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
|
||||||
}
|
}
|
||||||
|
@ -1274,6 +1322,8 @@ nsHttpTransaction::Restart()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTransportStatus = NS_OK;
|
||||||
|
|
||||||
return gHttpHandler->InitiateTransaction(this, mPriority);
|
return gHttpHandler->InitiateTransaction(this, mPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2307,5 +2357,38 @@ nsHttpTransaction::GetNetworkAddresses(NetAddr &self, NetAddr &peer)
|
||||||
peer = mPeerAddr;
|
peer = mPeerAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsHttpTransaction::Do0RTT()
|
||||||
|
{
|
||||||
|
if (mRequestHead->IsSafeMethod() &&
|
||||||
|
!mConnection->IsProxyConnectInProgress()) {
|
||||||
|
m0RTTInProgress = true;
|
||||||
|
}
|
||||||
|
return m0RTTInProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsHttpTransaction::Finish0RTT(bool aRestart)
|
||||||
|
{
|
||||||
|
LOG(("nsHttpTransaction::Finish0RTT %p %d\n", this, aRestart));
|
||||||
|
MOZ_ASSERT(m0RTTInProgress);
|
||||||
|
m0RTTInProgress = false;
|
||||||
|
if (aRestart) {
|
||||||
|
// Reset request headers to be sent again.
|
||||||
|
nsCOMPtr<nsISeekableStream> seekable =
|
||||||
|
do_QueryInterface(mRequestStream);
|
||||||
|
if (seekable) {
|
||||||
|
seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
|
||||||
|
} else {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
} else if (!mConnected) {
|
||||||
|
// this is code that was skipped in ::ReadSegments while in 0RTT
|
||||||
|
mConnected = true;
|
||||||
|
mConnection->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace net
|
} // namespace net
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -166,6 +166,8 @@ public:
|
||||||
|
|
||||||
int64_t GetTransferSize() { return mTransferSize; }
|
int64_t GetTransferSize() { return mTransferSize; }
|
||||||
|
|
||||||
|
bool Do0RTT() override;
|
||||||
|
nsresult Finish0RTT(bool aRestart) override;
|
||||||
private:
|
private:
|
||||||
friend class DeleteHttpTransaction;
|
friend class DeleteHttpTransaction;
|
||||||
virtual ~nsHttpTransaction();
|
virtual ~nsHttpTransaction();
|
||||||
|
@ -453,6 +455,10 @@ public:
|
||||||
private:
|
private:
|
||||||
RefPtr<ASpdySession> mTunnelProvider;
|
RefPtr<ASpdySession> mTunnelProvider;
|
||||||
|
|
||||||
|
bool m0RTTInProgress;
|
||||||
|
|
||||||
|
nsresult mTransportStatus;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void GetNetworkAddresses(NetAddr &self, NetAddr &peer);
|
void GetNetworkAddresses(NetAddr &self, NetAddr &peer);
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,22 @@ interface nsISSLSocketControl : nsISupports {
|
||||||
*/
|
*/
|
||||||
readonly attribute ACString negotiatedNPN;
|
readonly attribute ACString negotiatedNPN;
|
||||||
|
|
||||||
|
/* For 0RTT we need to know the alpn protocol selected for the last tls
|
||||||
|
* session. This function will return a value if applicable or an error
|
||||||
|
* NS_ERROR_NOT_AVAILABLE.
|
||||||
|
*/
|
||||||
|
ACString getAlpnEarlySelection();
|
||||||
|
|
||||||
|
/* If 0RTT handshake was applied and some data has been sent, as soon as
|
||||||
|
* the handshake finishes this attribute will be set to appropriate value.
|
||||||
|
*/
|
||||||
|
readonly attribute bool earlyDataAccepted;
|
||||||
|
|
||||||
|
/* When 0RTT is performed, PR_Write will not drive the handshake forward.
|
||||||
|
* It must be forced by calling this function.
|
||||||
|
*/
|
||||||
|
void driveHandshake();
|
||||||
|
|
||||||
/* Determine if a potential SSL connection to hostname:port with
|
/* Determine if a potential SSL connection to hostname:port with
|
||||||
* a desired NPN negotiated protocol of npnProtocol can use the socket
|
* a desired NPN negotiated protocol of npnProtocol can use the socket
|
||||||
* associated with this object instead of making a new one.
|
* associated with this object instead of making a new one.
|
||||||
|
@ -83,6 +99,7 @@ interface nsISSLSocketControl : nsISupports {
|
||||||
const short TLS_VERSION_1 = 0x0301;
|
const short TLS_VERSION_1 = 0x0301;
|
||||||
const short TLS_VERSION_1_1 = 0x0302;
|
const short TLS_VERSION_1_1 = 0x0302;
|
||||||
const short TLS_VERSION_1_2 = 0x0303;
|
const short TLS_VERSION_1_2 = 0x0303;
|
||||||
|
const short TLS_VERSION_1_3 = 0x0304;
|
||||||
const short SSL_VERSION_UNKNOWN = -1;
|
const short SSL_VERSION_UNKNOWN = -1;
|
||||||
|
|
||||||
[infallible] readonly attribute short SSLVersionUsed;
|
[infallible] readonly attribute short SSLVersionUsed;
|
||||||
|
|
|
@ -20,6 +20,7 @@ interface nsISSLStatus : nsISupports {
|
||||||
const short TLS_VERSION_1 = 1;
|
const short TLS_VERSION_1 = 1;
|
||||||
const short TLS_VERSION_1_1 = 2;
|
const short TLS_VERSION_1_1 = 2;
|
||||||
const short TLS_VERSION_1_2 = 3;
|
const short TLS_VERSION_1_2 = 3;
|
||||||
|
const short TLS_VERSION_1_3 = 4;
|
||||||
readonly attribute unsigned short protocolVersion;
|
readonly attribute unsigned short protocolVersion;
|
||||||
|
|
||||||
readonly attribute boolean isDomainMismatch;
|
readonly attribute boolean isDomainMismatch;
|
||||||
|
|
|
@ -891,6 +891,7 @@ PreliminaryHandshakeDone(PRFileDesc* fd)
|
||||||
SSLChannelInfo channelInfo;
|
SSLChannelInfo channelInfo;
|
||||||
if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) == SECSuccess) {
|
if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) == SECSuccess) {
|
||||||
infoObject->SetSSLVersionUsed(channelInfo.protocolVersion);
|
infoObject->SetSSLVersionUsed(channelInfo.protocolVersion);
|
||||||
|
infoObject->SetEarlyDataAccepted(channelInfo.earlyDataAccepted);
|
||||||
|
|
||||||
SSLCipherSuiteInfo cipherInfo;
|
SSLCipherSuiteInfo cipherInfo;
|
||||||
if (SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
|
if (SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
|
||||||
|
@ -905,7 +906,7 @@ PreliminaryHandshakeDone(PRFileDesc* fd)
|
||||||
status->mHaveCipherSuiteAndProtocol = true;
|
status->mHaveCipherSuiteAndProtocol = true;
|
||||||
status->mCipherSuite = channelInfo.cipherSuite;
|
status->mCipherSuite = channelInfo.cipherSuite;
|
||||||
status->mProtocolVersion = channelInfo.protocolVersion & 0xFF;
|
status->mProtocolVersion = channelInfo.protocolVersion & 0xFF;
|
||||||
infoObject->SetKEAUsed(cipherInfo.keaType);
|
infoObject->SetKEAUsed(channelInfo.keaType);
|
||||||
infoObject->SetKEAKeyBits(channelInfo.keaKeyBits);
|
infoObject->SetKEAKeyBits(channelInfo.keaKeyBits);
|
||||||
infoObject->SetMACAlgorithmUsed(cipherInfo.macAlgorithm);
|
infoObject->SetMACAlgorithmUsed(cipherInfo.macAlgorithm);
|
||||||
}
|
}
|
||||||
|
@ -966,7 +967,7 @@ CanFalseStartCallback(PRFileDesc* fd, void* client_data, PRBool *canFalseStart)
|
||||||
sizeof (cipherInfo)) != SECSuccess) {
|
sizeof (cipherInfo)) != SECSuccess) {
|
||||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("CanFalseStartCallback [%p] failed - "
|
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("CanFalseStartCallback [%p] failed - "
|
||||||
" KEA %d\n", fd,
|
" KEA %d\n", fd,
|
||||||
static_cast<int32_t>(cipherInfo.keaType)));
|
static_cast<int32_t>(channelInfo.keaType)));
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -982,10 +983,10 @@ CanFalseStartCallback(PRFileDesc* fd, void* client_data, PRBool *canFalseStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
// See bug 952863 for why ECDHE is allowed, but DHE (and RSA) are not.
|
// See bug 952863 for why ECDHE is allowed, but DHE (and RSA) are not.
|
||||||
if (cipherInfo.keaType != ssl_kea_ecdh) {
|
if (channelInfo.keaType != ssl_kea_ecdh) {
|
||||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("CanFalseStartCallback [%p] failed - "
|
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("CanFalseStartCallback [%p] failed - "
|
||||||
"unsupported KEA %d\n", fd,
|
"unsupported KEA %d\n", fd,
|
||||||
static_cast<int32_t>(cipherInfo.keaType)));
|
static_cast<int32_t>(channelInfo.keaType)));
|
||||||
reasonsForNotFalseStarting |= KEA_NOT_SUPPORTED;
|
reasonsForNotFalseStarting |= KEA_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1032,6 +1033,7 @@ CanFalseStartCallback(PRFileDesc* fd, void* client_data, PRBool *canFalseStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if(0) // TenFourFox issue 334
|
#if(0) // TenFourFox issue 334
|
||||||
|
#error this no longer has correct constants and should not be reenabled
|
||||||
static void
|
static void
|
||||||
AccumulateNonECCKeySize(Telemetry::ID probe, uint32_t bits)
|
AccumulateNonECCKeySize(Telemetry::ID probe, uint32_t bits)
|
||||||
{
|
{
|
||||||
|
@ -1156,7 +1158,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
||||||
if (rv == SECSuccess) {
|
if (rv == SECSuccess) {
|
||||||
#if(0) // TenFourFox issue 334
|
#if(0) // TenFourFox issue 334
|
||||||
// Get the protocol version for telemetry
|
// Get the protocol version for telemetry
|
||||||
// 1=tls1, 2=tls1.1, 3=tls1.2
|
// 1=tls1, 2=tls1.1, 3=tls1.2, 4=tls1.3
|
||||||
unsigned int versionEnum = channelInfo.protocolVersion & 0xFF;
|
unsigned int versionEnum = channelInfo.protocolVersion & 0xFF;
|
||||||
MOZ_ASSERT(versionEnum > 0);
|
MOZ_ASSERT(versionEnum > 0);
|
||||||
Telemetry::Accumulate(Telemetry::SSL_HANDSHAKE_VERSION, versionEnum);
|
Telemetry::Accumulate(Telemetry::SSL_HANDSHAKE_VERSION, versionEnum);
|
||||||
|
@ -1179,16 +1181,16 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
||||||
infoObject->IsFullHandshake()
|
infoObject->IsFullHandshake()
|
||||||
? Telemetry::SSL_KEY_EXCHANGE_ALGORITHM_FULL
|
? Telemetry::SSL_KEY_EXCHANGE_ALGORITHM_FULL
|
||||||
: Telemetry::SSL_KEY_EXCHANGE_ALGORITHM_RESUMED,
|
: Telemetry::SSL_KEY_EXCHANGE_ALGORITHM_RESUMED,
|
||||||
cipherInfo.keaType);
|
channelInfo.keaType);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DebugOnly<int16_t> KEAUsed;
|
DebugOnly<int16_t> KEAUsed;
|
||||||
MOZ_ASSERT(NS_SUCCEEDED(infoObject->GetKEAUsed(&KEAUsed)) &&
|
MOZ_ASSERT(NS_SUCCEEDED(infoObject->GetKEAUsed(&KEAUsed)) &&
|
||||||
(KEAUsed == cipherInfo.keaType));
|
(KEAUsed == channelInfo.keaType));
|
||||||
|
|
||||||
#if(0)
|
#if(0)
|
||||||
if (infoObject->IsFullHandshake()) {
|
if (infoObject->IsFullHandshake()) {
|
||||||
switch (cipherInfo.keaType) {
|
switch (channelInfo.keaType) {
|
||||||
case ssl_kea_rsa:
|
case ssl_kea_rsa:
|
||||||
AccumulateNonECCKeySize(Telemetry::SSL_KEA_RSA_KEY_SIZE_FULL,
|
AccumulateNonECCKeySize(Telemetry::SSL_KEA_RSA_KEY_SIZE_FULL,
|
||||||
channelInfo.keaKeyBits);
|
channelInfo.keaKeyBits);
|
||||||
|
@ -1210,7 +1212,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
||||||
cipherInfo.authAlgorithm);
|
cipherInfo.authAlgorithm);
|
||||||
|
|
||||||
// RSA key exchange doesn't use a signature for auth.
|
// RSA key exchange doesn't use a signature for auth.
|
||||||
if (cipherInfo.keaType != ssl_kea_rsa) {
|
if (channelInfo.keaType != ssl_kea_rsa) {
|
||||||
switch (cipherInfo.authAlgorithm) {
|
switch (cipherInfo.authAlgorithm) {
|
||||||
case ssl_auth_rsa:
|
case ssl_auth_rsa:
|
||||||
AccumulateNonECCKeySize(Telemetry::SSL_AUTH_RSA_KEY_SIZE_FULL,
|
AccumulateNonECCKeySize(Telemetry::SSL_AUTH_RSA_KEY_SIZE_FULL,
|
||||||
|
@ -1241,11 +1243,16 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool siteSupportsSafeRenego;
|
PRBool siteSupportsSafeRenego;
|
||||||
rv = SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn,
|
if (channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||||
&siteSupportsSafeRenego);
|
rv = SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn,
|
||||||
MOZ_ASSERT(rv == SECSuccess);
|
&siteSupportsSafeRenego);
|
||||||
if (rv != SECSuccess) {
|
MOZ_ASSERT(rv == SECSuccess);
|
||||||
siteSupportsSafeRenego = false;
|
if (rv != SECSuccess) {
|
||||||
|
siteSupportsSafeRenego = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TLS 1.3 dropped support for renegotiation.
|
||||||
|
siteSupportsSafeRenego = true;
|
||||||
}
|
}
|
||||||
bool renegotiationUnsafe = !siteSupportsSafeRenego &&
|
bool renegotiationUnsafe = !siteSupportsSafeRenego &&
|
||||||
ioLayerHelpers.treatUnsafeNegotiationAsBroken();
|
ioLayerHelpers.treatUnsafeNegotiationAsBroken();
|
||||||
|
|
|
@ -646,6 +646,13 @@ static const CipherPref sCipherPrefs[] = {
|
||||||
{ "security.ssl3.dhe_rsa_aes_256_sha",
|
{ "security.ssl3.dhe_rsa_aes_256_sha",
|
||||||
TLS_DHE_RSA_WITH_AES_256_CBC_SHA, true },
|
TLS_DHE_RSA_WITH_AES_256_CBC_SHA, true },
|
||||||
|
|
||||||
|
{ "security.tls13.aes_128_gcm_sha256",
|
||||||
|
TLS_AES_128_GCM_SHA256, true },
|
||||||
|
{ "security.tls13.chacha20_poly1305_sha256",
|
||||||
|
TLS_CHACHA20_POLY1305_SHA256, true },
|
||||||
|
{ "security.tls13.aes_256_gcm_sha384",
|
||||||
|
TLS_AES_256_GCM_SHA384, true },
|
||||||
|
|
||||||
{ "security.ssl3.ecdhe_rsa_rc4_128_sha",
|
{ "security.ssl3.ecdhe_rsa_rc4_128_sha",
|
||||||
TLS_ECDHE_RSA_WITH_RC4_128_SHA, true, true }, // deprecated (RC4)
|
TLS_ECDHE_RSA_WITH_RC4_128_SHA, true, true }, // deprecated (RC4)
|
||||||
{ "security.ssl3.ecdhe_ecdsa_rc4_128_sha",
|
{ "security.ssl3.ecdhe_ecdsa_rc4_128_sha",
|
||||||
|
@ -730,6 +737,7 @@ static const bool REQUIRE_SAFE_NEGOTIATION_DEFAULT = false;
|
||||||
static const bool FALSE_START_ENABLED_DEFAULT = true;
|
static const bool FALSE_START_ENABLED_DEFAULT = true;
|
||||||
static const bool NPN_ENABLED_DEFAULT = true;
|
static const bool NPN_ENABLED_DEFAULT = true;
|
||||||
static const bool ALPN_ENABLED_DEFAULT = false;
|
static const bool ALPN_ENABLED_DEFAULT = false;
|
||||||
|
static const bool ENABLED_0RTT_DATA_DEFAULT = false;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ConfigureTLSSessionIdentifiers()
|
ConfigureTLSSessionIdentifiers()
|
||||||
|
@ -899,7 +907,7 @@ nsNSSComponent::setEnabledTLSVersions()
|
||||||
// keep these values in sync with security-prefs.js
|
// keep these values in sync with security-prefs.js
|
||||||
// 1 means TLS 1.0, 2 means TLS 1.1, etc.
|
// 1 means TLS 1.0, 2 means TLS 1.1, etc.
|
||||||
static const uint32_t PSM_DEFAULT_MIN_TLS_VERSION = 1;
|
static const uint32_t PSM_DEFAULT_MIN_TLS_VERSION = 1;
|
||||||
static const uint32_t PSM_DEFAULT_MAX_TLS_VERSION = 3;
|
static const uint32_t PSM_DEFAULT_MAX_TLS_VERSION = 4;
|
||||||
|
|
||||||
uint32_t minFromPrefs = Preferences::GetUint("security.tls.version.min",
|
uint32_t minFromPrefs = Preferences::GetUint("security.tls.version.min",
|
||||||
PSM_DEFAULT_MIN_TLS_VERSION);
|
PSM_DEFAULT_MIN_TLS_VERSION);
|
||||||
|
@ -1091,6 +1099,9 @@ nsNSSComponent::InitializeNSS()
|
||||||
SSL_OptionSetDefault(SSL_ENABLE_ALPN,
|
SSL_OptionSetDefault(SSL_ENABLE_ALPN,
|
||||||
Preferences::GetBool("security.ssl.enable_alpn",
|
Preferences::GetBool("security.ssl.enable_alpn",
|
||||||
ALPN_ENABLED_DEFAULT));
|
ALPN_ENABLED_DEFAULT));
|
||||||
|
SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA,
|
||||||
|
Preferences::GetBool("security.tls.enable_0rtt_data",
|
||||||
|
ENABLED_0RTT_DATA_DEFAULT));
|
||||||
|
|
||||||
if (NS_FAILED(InitializeCipherSuite())) {
|
if (NS_FAILED(InitializeCipherSuite())) {
|
||||||
MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("Unable to initialize cipher suite settings\n"));
|
MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("Unable to initialize cipher suite settings\n"));
|
||||||
|
@ -1306,6 +1317,10 @@ nsNSSComponent::Observe(nsISupports* aSubject, const char* aTopic,
|
||||||
SSL_OptionSetDefault(SSL_ENABLE_ALPN,
|
SSL_OptionSetDefault(SSL_ENABLE_ALPN,
|
||||||
Preferences::GetBool("security.ssl.enable_alpn",
|
Preferences::GetBool("security.ssl.enable_alpn",
|
||||||
ALPN_ENABLED_DEFAULT));
|
ALPN_ENABLED_DEFAULT));
|
||||||
|
} else if (prefName.EqualsLiteral("security.tls.enable_0rtt_data")) {
|
||||||
|
SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA,
|
||||||
|
Preferences::GetBool("security.tls.enable_0rtt_data",
|
||||||
|
ENABLED_0RTT_DATA_DEFAULT));
|
||||||
} else if (prefName.Equals("security.ssl.disable_session_identifiers")) {
|
} else if (prefName.Equals("security.ssl.disable_session_identifiers")) {
|
||||||
ConfigureTLSSessionIdentifiers();
|
ConfigureTLSSessionIdentifiers();
|
||||||
} else if (prefName.EqualsLiteral("security.OCSP.enabled") ||
|
} else if (prefName.EqualsLiteral("security.OCSP.enabled") ||
|
||||||
|
|
|
@ -61,6 +61,8 @@ using namespace mozilla::psm;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
#define MAX_ALPN_LENGTH 255
|
||||||
|
|
||||||
void
|
void
|
||||||
getSiteKey(const nsACString& hostName, uint16_t port,
|
getSiteKey(const nsACString& hostName, uint16_t port,
|
||||||
/*out*/ nsCSubstring& key)
|
/*out*/ nsCSubstring& key)
|
||||||
|
@ -93,6 +95,7 @@ nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags)
|
||||||
mRememberClientAuthCertificate(false),
|
mRememberClientAuthCertificate(false),
|
||||||
mPreliminaryHandshakeDone(false),
|
mPreliminaryHandshakeDone(false),
|
||||||
mNPNCompleted(false),
|
mNPNCompleted(false),
|
||||||
|
mEarlyDataAccepted(false),
|
||||||
mFalseStartCallbackCalled(false),
|
mFalseStartCallbackCalled(false),
|
||||||
mFalseStarted(false),
|
mFalseStarted(false),
|
||||||
mIsFullHandshake(false),
|
mIsFullHandshake(false),
|
||||||
|
@ -316,6 +319,71 @@ nsNSSSocketInfo::GetNegotiatedNPN(nsACString& aNegotiatedNPN)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNSSSocketInfo::GetAlpnEarlySelection(nsACString& aAlpnSelected)
|
||||||
|
{
|
||||||
|
nsNSSShutDownPreventionLock locker;
|
||||||
|
if (isAlreadyShutDown() || isPK11LoggedOut()) {
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
SSLNextProtoState alpnState;
|
||||||
|
unsigned char chosenAlpn[MAX_ALPN_LENGTH];
|
||||||
|
unsigned int chosenAlpnLen;
|
||||||
|
SECStatus rv = SSL_GetNextProto(mFd, &alpnState, chosenAlpn, &chosenAlpnLen,
|
||||||
|
AssertedCast<unsigned int>(ArrayLength(chosenAlpn)));
|
||||||
|
|
||||||
|
if (rv != SECSuccess || alpnState != SSL_NEXT_PROTO_EARLY_VALUE ||
|
||||||
|
chosenAlpnLen == 0) {
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
aAlpnSelected.Assign(BitwiseCast<char*, unsigned char*>(chosenAlpn),
|
||||||
|
chosenAlpnLen);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNSSSocketInfo::GetEarlyDataAccepted(bool* aAccepted)
|
||||||
|
{
|
||||||
|
*aAccepted = mEarlyDataAccepted;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsNSSSocketInfo::SetEarlyDataAccepted(bool aAccepted)
|
||||||
|
{
|
||||||
|
mEarlyDataAccepted = aAccepted;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNSSSocketInfo::DriveHandshake()
|
||||||
|
{
|
||||||
|
nsNSSShutDownPreventionLock locker;
|
||||||
|
if (isAlreadyShutDown() || isPK11LoggedOut()) {
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
if (!mFd) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
PRErrorCode errorCode = GetErrorCode();
|
||||||
|
if (errorCode) {
|
||||||
|
return GetXPCOMFromNSSError(errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECStatus rv = SSL_ForceHandshake(mFd);
|
||||||
|
|
||||||
|
if (rv != SECSuccess) {
|
||||||
|
errorCode = PR_GetError();
|
||||||
|
if (errorCode == PR_WOULD_BLOCK_ERROR) {
|
||||||
|
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetCanceled(errorCode, PlainErrorMessage);
|
||||||
|
return GetXPCOMFromNSSError(errorCode);
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsNSSSocketInfo::IsAcceptableForHost(const nsACString& hostname, bool* _retval)
|
nsNSSSocketInfo::IsAcceptableForHost(const nsACString& hostname, bool* _retval)
|
||||||
{
|
{
|
||||||
|
@ -704,7 +772,7 @@ nsSSLIOLayerHelpers::rememberTolerantAtVersion(const nsACString& hostName,
|
||||||
mTLSIntoleranceInfo.Put(key, entry);
|
mTLSIntoleranceInfo.Put(key, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t
|
void
|
||||||
nsSSLIOLayerHelpers::forgetIntolerance(const nsACString& hostName,
|
nsSSLIOLayerHelpers::forgetIntolerance(const nsACString& hostName,
|
||||||
int16_t port)
|
int16_t port)
|
||||||
{
|
{
|
||||||
|
@ -713,12 +781,10 @@ nsSSLIOLayerHelpers::forgetIntolerance(const nsACString& hostName,
|
||||||
|
|
||||||
MutexAutoLock lock(mutex);
|
MutexAutoLock lock(mutex);
|
||||||
|
|
||||||
uint16_t tolerant = 0;
|
|
||||||
IntoleranceEntry entry;
|
IntoleranceEntry entry;
|
||||||
if (mTLSIntoleranceInfo.Get(key, &entry)) {
|
if (mTLSIntoleranceInfo.Get(key, &entry)) {
|
||||||
entry.AssertInvariant();
|
entry.AssertInvariant();
|
||||||
|
|
||||||
tolerant = entry.tolerant;
|
|
||||||
entry.intolerant = 0;
|
entry.intolerant = 0;
|
||||||
entry.intoleranceReason = 0;
|
entry.intoleranceReason = 0;
|
||||||
if (entry.strongCipherStatus != StrongCiphersWorked) {
|
if (entry.strongCipherStatus != StrongCiphersWorked) {
|
||||||
|
@ -728,8 +794,6 @@ nsSSLIOLayerHelpers::forgetIntolerance(const nsACString& hostName,
|
||||||
entry.AssertInvariant();
|
entry.AssertInvariant();
|
||||||
mTLSIntoleranceInfo.Put(key, entry);
|
mTLSIntoleranceInfo.Put(key, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tolerant;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -753,49 +817,7 @@ nsSSLIOLayerHelpers::rememberIntolerantAtVersion(const nsACString& hostName,
|
||||||
{
|
{
|
||||||
if (intolerant <= minVersion || fallbackLimitReached(hostName, intolerant)) {
|
if (intolerant <= minVersion || fallbackLimitReached(hostName, intolerant)) {
|
||||||
// We can't fall back any further. Assume that intolerance isn't the issue.
|
// We can't fall back any further. Assume that intolerance isn't the issue.
|
||||||
uint32_t tolerant = forgetIntolerance(hostName, port);
|
forgetIntolerance(hostName, port);
|
||||||
// If we know the server is tolerant at the version, we don't have to
|
|
||||||
// gather the telemetry.
|
|
||||||
if (intolerant <= tolerant) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t fallbackLimitBucket = 0;
|
|
||||||
// added if the version has reached the min version.
|
|
||||||
if (intolerant <= minVersion) {
|
|
||||||
switch (minVersion) {
|
|
||||||
case SSL_LIBRARY_VERSION_TLS_1_0:
|
|
||||||
fallbackLimitBucket += 1;
|
|
||||||
break;
|
|
||||||
case SSL_LIBRARY_VERSION_TLS_1_1:
|
|
||||||
fallbackLimitBucket += 2;
|
|
||||||
break;
|
|
||||||
case SSL_LIBRARY_VERSION_TLS_1_2:
|
|
||||||
fallbackLimitBucket += 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// added if the version has reached the fallback limit.
|
|
||||||
if (intolerant <= mVersionFallbackLimit) {
|
|
||||||
switch (mVersionFallbackLimit) {
|
|
||||||
case SSL_LIBRARY_VERSION_TLS_1_0:
|
|
||||||
fallbackLimitBucket += 4;
|
|
||||||
break;
|
|
||||||
case SSL_LIBRARY_VERSION_TLS_1_1:
|
|
||||||
fallbackLimitBucket += 8;
|
|
||||||
break;
|
|
||||||
case SSL_LIBRARY_VERSION_TLS_1_2:
|
|
||||||
fallbackLimitBucket += 12;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if(0)
|
|
||||||
if (fallbackLimitBucket) {
|
|
||||||
Telemetry::Accumulate(Telemetry::SSL_FALLBACK_LIMIT_REACHED,
|
|
||||||
fallbackLimitBucket);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1047,6 +1069,7 @@ class SSLErrorRunnable : public SyncRunnableBase
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
#if(0)
|
||||||
uint32_t tlsIntoleranceTelemetryBucket(PRErrorCode err)
|
uint32_t tlsIntoleranceTelemetryBucket(PRErrorCode err)
|
||||||
{
|
{
|
||||||
// returns a numeric code for where we track various errors in telemetry
|
// returns a numeric code for where we track various errors in telemetry
|
||||||
|
@ -1065,9 +1088,11 @@ uint32_t tlsIntoleranceTelemetryBucket(PRErrorCode err)
|
||||||
case SSL_ERROR_DECODE_ERROR_ALERT: return 14;
|
case SSL_ERROR_DECODE_ERROR_ALERT: return 14;
|
||||||
case PR_CONNECT_RESET_ERROR: return 16;
|
case PR_CONNECT_RESET_ERROR: return 16;
|
||||||
case PR_END_OF_FILE_ERROR: return 17;
|
case PR_END_OF_FILE_ERROR: return 17;
|
||||||
|
case SSL_ERROR_INTERNAL_ERROR_ALERT: return 18;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool
|
bool
|
||||||
retryDueToTLSIntolerance(PRErrorCode err, nsNSSSocketInfo* socketInfo)
|
retryDueToTLSIntolerance(PRErrorCode err, nsNSSSocketInfo* socketInfo)
|
||||||
|
@ -1143,12 +1168,13 @@ retryDueToTLSIntolerance(PRErrorCode err, nsNSSSocketInfo* socketInfo)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if(0)
|
||||||
|
#error doesn't support TLS 1.3
|
||||||
uint32_t reason = tlsIntoleranceTelemetryBucket(err);
|
uint32_t reason = tlsIntoleranceTelemetryBucket(err);
|
||||||
if (reason == 0) {
|
if (reason == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if(0)
|
|
||||||
Telemetry::ID pre;
|
Telemetry::ID pre;
|
||||||
Telemetry::ID post;
|
Telemetry::ID post;
|
||||||
switch (range.max) {
|
switch (range.max) {
|
||||||
|
@ -2564,8 +2590,11 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS,
|
||||||
if (range.max < maxEnabledVersion) {
|
if (range.max < maxEnabledVersion) {
|
||||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||||
("[%p] nsSSLIOLayerSetOptions: enabling TLS_FALLBACK_SCSV\n", fd));
|
("[%p] nsSSLIOLayerSetOptions: enabling TLS_FALLBACK_SCSV\n", fd));
|
||||||
if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_FALLBACK_SCSV, true)) {
|
// Some servers will choke if we send the fallback SCSV with TLS 1.2.
|
||||||
return NS_ERROR_FAILURE;
|
if (range.max < SSL_LIBRARY_VERSION_TLS_1_2) {
|
||||||
|
if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_FALLBACK_SCSV, true)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ public:
|
||||||
const nsNSSShutDownPreventionLock& proofOfLock);
|
const nsNSSShutDownPreventionLock& proofOfLock);
|
||||||
|
|
||||||
void SetNegotiatedNPN(const char* value, uint32_t length);
|
void SetNegotiatedNPN(const char* value, uint32_t length);
|
||||||
|
void SetEarlyDataAccepted(bool aAccepted);
|
||||||
|
|
||||||
void SetHandshakeCompleted();
|
void SetHandshakeCompleted();
|
||||||
void NoteTimeUntilReady();
|
void NoteTimeUntilReady();
|
||||||
|
@ -139,6 +140,7 @@ private:
|
||||||
|
|
||||||
nsCString mNegotiatedNPN;
|
nsCString mNegotiatedNPN;
|
||||||
bool mNPNCompleted;
|
bool mNPNCompleted;
|
||||||
|
bool mEarlyDataAccepted;
|
||||||
bool mFalseStartCallbackCalled;
|
bool mFalseStartCallbackCalled;
|
||||||
bool mFalseStarted;
|
bool mFalseStarted;
|
||||||
bool mIsFullHandshake;
|
bool mIsFullHandshake;
|
||||||
|
@ -216,9 +218,7 @@ public:
|
||||||
PRErrorCode intoleranceReason);
|
PRErrorCode intoleranceReason);
|
||||||
bool rememberStrongCiphersFailed(const nsACString& hostName, int16_t port,
|
bool rememberStrongCiphersFailed(const nsACString& hostName, int16_t port,
|
||||||
PRErrorCode intoleranceReason);
|
PRErrorCode intoleranceReason);
|
||||||
// returns the known tolerant version
|
void forgetIntolerance(const nsACString& hostname, int16_t port);
|
||||||
// or 0 if there is no known tolerant version
|
|
||||||
uint16_t forgetIntolerance(const nsACString& hostname, int16_t port);
|
|
||||||
void adjustForTLSIntolerance(const nsACString& hostname, int16_t port,
|
void adjustForTLSIntolerance(const nsACString& hostname, int16_t port,
|
||||||
/*in/out*/ SSLVersionRange& range,
|
/*in/out*/ SSLVersionRange& range,
|
||||||
/*out*/ StrongCipherStatus& strongCipherStatus);
|
/*out*/ StrongCipherStatus& strongCipherStatus);
|
||||||
|
|
|
@ -1090,7 +1090,15 @@ NS_IMETHODIMP nsDocLoader::OnStatus(nsIRequest* aRequest, nsISupports* ctxt,
|
||||||
if (!sbs)
|
if (!sbs)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
nsXPIDLString msg;
|
nsXPIDLString msg;
|
||||||
nsresult rv = sbs->FormatStatusMessage(aStatus, aStatusArg,
|
/* TenFourFox issue 590. Map NS_NET_STATUS_TLS_HANDSHAKE_STARTING and
|
||||||
|
NS_NET_STATUS_TLS_HANDSHAKE_ENDED to NS_NET_STATUS_CONNECTED_TO so
|
||||||
|
that we don't instantly invalidate all our locales. See also
|
||||||
|
netwerk/locales/en-US/necko.properties XXX */
|
||||||
|
nsresult rv = sbs->FormatStatusMessage(
|
||||||
|
(aStatus == NS_NET_STATUS_TLS_HANDSHAKE_STARTING ||
|
||||||
|
aStatus == NS_NET_STATUS_TLS_HANDSHAKE_ENDED) ?
|
||||||
|
NS_NET_STATUS_CONNECTED_TO : aStatus,
|
||||||
|
aStatusArg,
|
||||||
getter_Copies(msg));
|
getter_Copies(msg));
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -313,13 +313,15 @@
|
||||||
ERROR(NS_NET_STATUS_WRITING, FAILURE(9)),
|
ERROR(NS_NET_STATUS_WRITING, FAILURE(9)),
|
||||||
|
|
||||||
/* nsISocketTransport */
|
/* nsISocketTransport */
|
||||||
ERROR(NS_NET_STATUS_RESOLVING_HOST, FAILURE(3)),
|
ERROR(NS_NET_STATUS_RESOLVING_HOST, FAILURE(3)),
|
||||||
ERROR(NS_NET_STATUS_RESOLVED_HOST, FAILURE(11)),
|
ERROR(NS_NET_STATUS_RESOLVED_HOST, FAILURE(11)),
|
||||||
ERROR(NS_NET_STATUS_CONNECTING_TO, FAILURE(7)),
|
ERROR(NS_NET_STATUS_CONNECTING_TO, FAILURE(7)),
|
||||||
ERROR(NS_NET_STATUS_CONNECTED_TO, FAILURE(4)),
|
ERROR(NS_NET_STATUS_CONNECTED_TO, FAILURE(4)),
|
||||||
ERROR(NS_NET_STATUS_SENDING_TO, FAILURE(5)),
|
ERROR(NS_NET_STATUS_TLS_HANDSHAKE_STARTING, FAILURE(12)),
|
||||||
ERROR(NS_NET_STATUS_WAITING_FOR, FAILURE(10)),
|
ERROR(NS_NET_STATUS_TLS_HANDSHAKE_ENDED, FAILURE(13)),
|
||||||
ERROR(NS_NET_STATUS_RECEIVING_FROM, FAILURE(6)),
|
ERROR(NS_NET_STATUS_SENDING_TO, FAILURE(5)),
|
||||||
|
ERROR(NS_NET_STATUS_WAITING_FOR, FAILURE(10)),
|
||||||
|
ERROR(NS_NET_STATUS_RECEIVING_FROM, FAILURE(6)),
|
||||||
|
|
||||||
/* nsIInterceptedChannel */
|
/* nsIInterceptedChannel */
|
||||||
/* Generic error for non-specific failures during service worker interception */
|
/* Generic error for non-specific failures during service worker interception */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user