Skip to content

Commit

Permalink
Bug 1264578 - NSS support for http with TLS 1.3. r=keeler
Browse files Browse the repository at this point in the history
  • Loading branch information
ddragana committed Aug 17, 2016
1 parent 922c056 commit 4140bdd
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 0 deletions.
1 change: 1 addition & 0 deletions netwerk/base/security-prefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ 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);
Expand Down
16 changes: 16 additions & 0 deletions netwerk/socket/nsISSLSocketControl.idl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ interface nsISSLSocketControl : nsISupports {
*/
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.
Expand Down
1 change: 1 addition & 0 deletions security/manager/ssl/nsNSSCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,7 @@ PreliminaryHandshakeDone(PRFileDesc* fd)
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,
Expand Down
9 changes: 9 additions & 0 deletions security/manager/ssl/nsNSSComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1369,6 +1369,7 @@ 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()
Expand Down Expand Up @@ -1776,6 +1777,10 @@ nsNSSComponent::InitializeNSS()
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;
Expand Down Expand Up @@ -1961,6 +1966,10 @@ nsNSSComponent::Observe(nsISupports* aSubject, const char* aTopic,
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") ||
Expand Down
68 changes: 68 additions & 0 deletions security/manager/ssl/nsNSSIOLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ using namespace mozilla::psm;

namespace {

#define MAX_ALPN_LENGTH 255

void
getSiteKey(const nsACString& hostName, uint16_t port,
/*out*/ nsCSubstring& key)
Expand Down Expand Up @@ -87,6 +89,7 @@ nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags)
mRememberClientAuthCertificate(false),
mPreliminaryHandshakeDone(false),
mNPNCompleted(false),
mEarlyDataAccepted(false),
mFalseStartCallbackCalled(false),
mFalseStarted(false),
mIsFullHandshake(false),
Expand Down Expand Up @@ -307,6 +310,71 @@ nsNSSSocketInfo::GetNegotiatedNPN(nsACString& aNegotiatedNPN)
return NS_OK;
}

NS_IMETHODIMP
nsNSSSocketInfo::GetAlpnEarlySelection(nsACString& aAlpnSelected)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
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()) {
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)
{
Expand Down
2 changes: 2 additions & 0 deletions security/manager/ssl/nsNSSIOLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class nsNSSSocketInfo final : public mozilla::psm::TransportSecurityInfo,
const nsNSSShutDownPreventionLock& proofOfLock);

void SetNegotiatedNPN(const char* value, uint32_t length);
void SetEarlyDataAccepted(bool aAccepted);

void SetHandshakeCompleted();
void NoteTimeUntilReady();
Expand Down Expand Up @@ -132,6 +133,7 @@ class nsNSSSocketInfo final : public mozilla::psm::TransportSecurityInfo,

nsCString mNegotiatedNPN;
bool mNPNCompleted;
bool mEarlyDataAccepted;
bool mFalseStartCallbackCalled;
bool mFalseStarted;
bool mIsFullHandshake;
Expand Down

0 comments on commit 4140bdd

Please sign in to comment.