author | Dragana Damjanovic <dd.mozilla@gmail.com> |
Fri, 19 Aug 2016 05:01:00 -0400 | |
changeset 310729 | a1fcbe1fc10c17fb0b7c6e31a46ffc0d8f7f18ef |
parent 310728 | 16bcc176a1439cc6ba5b70cd62d0d049243c41b8 |
child 310730 | 9238fb3e770e0166514a6352a6dac1ec5e3a305b |
push id | 30593 |
push user | ryanvm@gmail.com |
push date | Tue, 23 Aug 2016 14:05:29 +0000 |
treeherder | mozilla-central@052656fc513c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | keeler |
bugs | 1264578 |
milestone | 51.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/netwerk/base/security-prefs.js +++ b/netwerk/base/security-prefs.js @@ -2,16 +2,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ pref("security.tls.version.min", 1); pref("security.tls.version.max", 3); pref("security.tls.version.fallback-limit", 3); pref("security.tls.insecure_fallback_hosts", ""); pref("security.tls.unrestricted_rc4_fallback", false); +pref("security.tls.enable_0rtt_data", false); pref("security.ssl.treat_unsafe_negotiation_as_broken", false); pref("security.ssl.require_safe_negotiation", false); pref("security.ssl.enable_ocsp_stapling", true); pref("security.ssl.enable_false_start", true); pref("security.ssl.false_start.require-npn", false); pref("security.ssl.enable_npn", true); pref("security.ssl.enable_alpn", true);
--- a/netwerk/socket/nsISSLSocketControl.idl +++ b/netwerk/socket/nsISSLSocketControl.idl @@ -39,16 +39,32 @@ interface nsISSLSocketControl : nsISuppo * implement NPN. * * If negotiatedNPN is read before NPN has progressed to the point * where this information is available NS_ERROR_NOT_CONNECTED is * raised. */ 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 * a desired NPN negotiated protocol of npnProtocol can use the socket * associated with this object instead of making a new one. */ boolean joinConnection( in ACString npnProtocol, /* e.g. "spdy/2" */ in ACString hostname, in long port);
--- a/security/manager/ssl/nsNSSCallbacks.cpp +++ b/security/manager/ssl/nsNSSCallbacks.cpp @@ -833,16 +833,17 @@ PreliminaryHandshakeDone(PRFileDesc* fd) { nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret; if (!infoObject) return; SSLChannelInfo channelInfo; if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) == SECSuccess) { infoObject->SetSSLVersionUsed(channelInfo.protocolVersion); + infoObject->SetEarlyDataAccepted(channelInfo.earlyDataAccepted); SSLCipherSuiteInfo cipherInfo; if (SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo, sizeof cipherInfo) == SECSuccess) { /* Set the SSL Status information */ RefPtr<nsSSLStatus> status(infoObject->SSLStatus()); if (!status) { status = new nsSSLStatus();
--- a/security/manager/ssl/nsNSSComponent.cpp +++ b/security/manager/ssl/nsNSSComponent.cpp @@ -1364,16 +1364,17 @@ nsNSSComponent::FillTLSVersionRange(SSLV rangeOut.max = (uint16_t) maxFromPrefs; } static const int32_t OCSP_ENABLED_DEFAULT = 1; static const bool REQUIRE_SAFE_NEGOTIATION_DEFAULT = false; static const bool FALSE_START_ENABLED_DEFAULT = true; static const bool NPN_ENABLED_DEFAULT = true; static const bool ALPN_ENABLED_DEFAULT = false; +static const bool ENABLED_0RTT_DATA_DEFAULT = false; static void ConfigureTLSSessionIdentifiers() { bool disableSessionIdentifiers = Preferences::GetBool("security.ssl.disable_session_identifiers", false); SSL_OptionSetDefault(SSL_ENABLE_SESSION_TICKETS, !disableSessionIdentifiers); SSL_OptionSetDefault(SSL_NO_CACHE, disableSessionIdentifiers); @@ -1771,16 +1772,20 @@ nsNSSComponent::InitializeNSS() // preferences are true. SSL_OptionSetDefault(SSL_ENABLE_NPN, Preferences::GetBool("security.ssl.enable_npn", NPN_ENABLED_DEFAULT)); SSL_OptionSetDefault(SSL_ENABLE_ALPN, Preferences::GetBool("security.ssl.enable_alpn", ALPN_ENABLED_DEFAULT)); + SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA, + Preferences::GetBool("security.tls.enable_0rtt_data", + ENABLED_0RTT_DATA_DEFAULT)); + if (NS_FAILED(InitializeCipherSuite())) { MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("Unable to initialize cipher suite settings\n")); return NS_ERROR_FAILURE; } // TLSServerSocket may be run with the session cache enabled. It is necessary // to call this once before that can happen. This specifies a maximum of 1000 // cache entries (the default number of cache entries is 10000, which seems a @@ -1956,16 +1961,20 @@ nsNSSComponent::Observe(nsISupports* aSu } else if (prefName.EqualsLiteral("security.ssl.enable_npn")) { SSL_OptionSetDefault(SSL_ENABLE_NPN, Preferences::GetBool("security.ssl.enable_npn", NPN_ENABLED_DEFAULT)); } else if (prefName.EqualsLiteral("security.ssl.enable_alpn")) { SSL_OptionSetDefault(SSL_ENABLE_ALPN, Preferences::GetBool("security.ssl.enable_alpn", 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")) { ConfigureTLSSessionIdentifiers(); } else if (prefName.EqualsLiteral("security.OCSP.enabled") || prefName.EqualsLiteral("security.OCSP.require") || prefName.EqualsLiteral("security.OCSP.GET.enabled") || prefName.EqualsLiteral("security.pki.cert_short_lifetime_in_days") || prefName.EqualsLiteral("security.ssl.enable_ocsp_stapling") || prefName.EqualsLiteral("security.ssl.enable_ocsp_must_staple") ||
--- a/security/manager/ssl/nsNSSIOLayer.cpp +++ b/security/manager/ssl/nsNSSIOLayer.cpp @@ -53,16 +53,18 @@ using namespace mozilla::psm; //DEBUG_SSL_VERBOSE to dump SSL //read/write buffer to a log. //Uses PR_LOG except on Mac where //we always write out to our own //file. namespace { +#define MAX_ALPN_LENGTH 255 + void getSiteKey(const nsACString& hostName, uint16_t port, /*out*/ nsCSubstring& key) { key = hostName; key.AppendASCII(":"); key.AppendInt(port); } @@ -82,16 +84,17 @@ nsNSSSocketInfo::nsNSSSocketInfo(SharedS : mFd(nullptr), mCertVerificationState(before_cert_verification), mSharedState(aState), mForSTARTTLS(false), mHandshakePending(true), mRememberClientAuthCertificate(false), mPreliminaryHandshakeDone(false), mNPNCompleted(false), + mEarlyDataAccepted(false), mFalseStartCallbackCalled(false), mFalseStarted(false), mIsFullHandshake(false), mHandshakeCompleted(false), mJoined(false), mSentClientCert(false), mNotedTimeUntilReady(false), mFailedVerification(false), @@ -303,16 +306,81 @@ nsNSSSocketInfo::GetNegotiatedNPN(nsACSt if (!mNPNCompleted) return NS_ERROR_NOT_CONNECTED; aNegotiatedNPN = mNegotiatedNPN; 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 nsNSSSocketInfo::IsAcceptableForHost(const nsACString& hostname, bool* _retval) { // If this is the same hostname then the certicate status does not // need to be considered. They are joinable. if (hostname.Equals(GetHostName())) { *_retval = true; return NS_OK; }
--- a/security/manager/ssl/nsNSSIOLayer.h +++ b/security/manager/ssl/nsNSSIOLayer.h @@ -48,16 +48,17 @@ public: void SetTLSVersionRange(SSLVersionRange range) { mTLSVersionRange = range; } SSLVersionRange GetTLSVersionRange() const { return mTLSVersionRange; }; PRStatus CloseSocketAndDestroy( const nsNSSShutDownPreventionLock& proofOfLock); void SetNegotiatedNPN(const char* value, uint32_t length); + void SetEarlyDataAccepted(bool aAccepted); void SetHandshakeCompleted(); void NoteTimeUntilReady(); void SetFalseStartCallbackCalled() { mFalseStartCallbackCalled = true; } void SetFalseStarted() { mFalseStarted = true; } @@ -127,16 +128,17 @@ private: bool mHandshakePending; bool mRememberClientAuthCertificate; bool mPreliminaryHandshakeDone; // after false start items are complete nsresult ActivateSSL(); nsCString mNegotiatedNPN; bool mNPNCompleted; + bool mEarlyDataAccepted; bool mFalseStartCallbackCalled; bool mFalseStarted; bool mIsFullHandshake; bool mHandshakeCompleted; bool mJoined; bool mSentClientCert; bool mNotedTimeUntilReady; bool mFailedVerification;