Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This makes the TLS 1.3 handshake look like TLS 1.2. The trickiest part here is in 0-RTT. I've chosen to remember that the alternative handshake was used and send a ChangeCipherSpec if the previous session used the alternative AND if the client enables the alternative. This assumes that a server will commit to supporting - and selecting - this alternative handshake type for as long as it supports 0-RTT from sessions that have the alternative handshake type. That is, if you negotiate the alternative handshake and the server supports 0-RTT, then it will not just support TLS 1.3 for the duration of the ticket, but also the alternative handshake type. A client can disable the alternative handshake because the version in the ClientHello indicates whether the client intended to send a CCS, but the server cannot refuse to pick it if the client offers. Of course, if we agree that the final TLS 1.3 is in this form, we don't have a problem, it's only an issue because we need to switch-hit. I chose to remove the Facebook alternative content type hack as all signs indicate that it doesn't help. --HG-- branch : NSS_TLS13_DRAFT19_BRANCH extra : rebase_source : cba8b9be8726f29acf742d225693a70af10ac5ca
- Loading branch information
1 parent
f19ab84
commit d81088d
Showing
17 changed files
with
536 additions
and
208 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | ||
/* vim: set ts=2 et sw=2 tw=80: */ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* 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/. */ | ||
|
||
#include <memory> | ||
#include <vector> | ||
#include "ssl.h" | ||
#include "sslerr.h" | ||
#include "sslproto.h" | ||
|
||
#include "gtest_utils.h" | ||
#include "tls_connect.h" | ||
#include "tls_filter.h" | ||
#include "tls_parser.h" | ||
|
||
namespace nss_test { | ||
|
||
static const uint32_t kServerHelloVersionAlt = SSL_LIBRARY_VERSION_TLS_1_2; | ||
static const uint32_t kServerHelloVersionRegular = | ||
0x7f00 | TLS_1_3_DRAFT_VERSION; | ||
|
||
class AltHandshakeTest : public TlsConnectStreamTls13 { | ||
protected: | ||
void SetUp() { | ||
TlsConnectStreamTls13::SetUp(); | ||
client_ccs_recorder_ = | ||
std::make_shared<TlsRecordRecorder>(kTlsChangeCipherSpecType); | ||
server_ccs_recorder_ = | ||
std::make_shared<TlsRecordRecorder>(kTlsChangeCipherSpecType); | ||
server_hello_recorder_ = | ||
std::make_shared<TlsInspectorRecordHandshakeMessage>( | ||
kTlsHandshakeServerHello); | ||
} | ||
|
||
void SetAltHandshakeTypeEnabled() { | ||
client_->SetAltHandshakeTypeEnabled(); | ||
server_->SetAltHandshakeTypeEnabled(); | ||
} | ||
|
||
void InstallFilters() { | ||
client_->SetPacketFilter(client_ccs_recorder_); | ||
auto chain = std::make_shared<ChainedPacketFilter>(ChainedPacketFilterInit( | ||
{server_ccs_recorder_, server_hello_recorder_})); | ||
server_->SetPacketFilter(chain); | ||
} | ||
|
||
void CheckServerHelloVersion(uint32_t server_hello_version) { | ||
uint32_t ver; | ||
ASSERT_TRUE(server_hello_recorder_->buffer().Read(0, 2, &ver)); | ||
ASSERT_EQ(server_hello_version, ver); | ||
} | ||
|
||
void CheckForRegularHandshake() { | ||
EXPECT_EQ(0U, client_ccs_recorder_->count()); | ||
EXPECT_EQ(0U, server_ccs_recorder_->count()); | ||
CheckServerHelloVersion(kServerHelloVersionRegular); | ||
} | ||
|
||
void CheckForAltHandshake() { | ||
EXPECT_EQ(1U, client_ccs_recorder_->count()); | ||
EXPECT_EQ(1U, server_ccs_recorder_->count()); | ||
CheckServerHelloVersion(kServerHelloVersionAlt); | ||
} | ||
|
||
std::shared_ptr<TlsRecordRecorder> client_ccs_recorder_; | ||
std::shared_ptr<TlsRecordRecorder> server_ccs_recorder_; | ||
std::shared_ptr<TlsInspectorRecordHandshakeMessage> server_hello_recorder_; | ||
}; | ||
|
||
TEST_F(AltHandshakeTest, ClientOnly) { | ||
client_->SetAltHandshakeTypeEnabled(); | ||
InstallFilters(); | ||
Connect(); | ||
CheckForRegularHandshake(); | ||
} | ||
|
||
TEST_F(AltHandshakeTest, ServerOnly) { | ||
server_->SetAltHandshakeTypeEnabled(); | ||
InstallFilters(); | ||
Connect(); | ||
CheckForRegularHandshake(); | ||
} | ||
|
||
TEST_F(AltHandshakeTest, Enabled) { | ||
SetAltHandshakeTypeEnabled(); | ||
InstallFilters(); | ||
Connect(); | ||
CheckForAltHandshake(); | ||
} | ||
|
||
TEST_F(AltHandshakeTest, ZeroRtt) { | ||
SetAltHandshakeTypeEnabled(); | ||
SetupForZeroRtt(); | ||
SetAltHandshakeTypeEnabled(); | ||
client_->Set0RttEnabled(true); | ||
server_->Set0RttEnabled(true); | ||
|
||
InstallFilters(); | ||
|
||
ExpectResumption(RESUME_TICKET); | ||
ZeroRttSendReceive(true, true); | ||
Handshake(); | ||
ExpectEarlyDataAccepted(true); | ||
CheckConnected(); | ||
|
||
CheckForAltHandshake(); | ||
} | ||
|
||
// Neither client nor server has the extension prior to resumption, so the | ||
// client doesn't send a CCS before its 0-RTT data. | ||
TEST_F(AltHandshakeTest, DisabledBeforeZeroRtt) { | ||
SetupForZeroRtt(); | ||
SetAltHandshakeTypeEnabled(); | ||
client_->Set0RttEnabled(true); | ||
server_->Set0RttEnabled(true); | ||
|
||
InstallFilters(); | ||
|
||
ExpectResumption(RESUME_TICKET); | ||
ZeroRttSendReceive(true, true); | ||
Handshake(); | ||
ExpectEarlyDataAccepted(true); | ||
CheckConnected(); | ||
|
||
EXPECT_EQ(0U, client_ccs_recorder_->count()); | ||
EXPECT_EQ(1U, server_ccs_recorder_->count()); | ||
CheckServerHelloVersion(kServerHelloVersionAlt); | ||
} | ||
|
||
// Both use the alternative in the initial handshake but only the server enables | ||
// it on resumption. | ||
TEST_F(AltHandshakeTest, ClientDisabledAfterZeroRtt) { | ||
SetAltHandshakeTypeEnabled(); | ||
SetupForZeroRtt(); | ||
server_->SetAltHandshakeTypeEnabled(); | ||
client_->Set0RttEnabled(true); | ||
server_->Set0RttEnabled(true); | ||
|
||
InstallFilters(); | ||
|
||
ExpectResumption(RESUME_TICKET); | ||
ZeroRttSendReceive(true, true); | ||
Handshake(); | ||
ExpectEarlyDataAccepted(true); | ||
CheckConnected(); | ||
|
||
CheckForRegularHandshake(); | ||
} | ||
|
||
// If the alternative handshake isn't negotiated after 0-RTT, and the client has | ||
// it enabled, it will send a ChangeCipherSpec. The server chokes on it if it | ||
// hasn't negotiated the alternative handshake. | ||
TEST_F(AltHandshakeTest, ServerDisabledAfterZeroRtt) { | ||
SetAltHandshakeTypeEnabled(); | ||
SetupForZeroRtt(); | ||
client_->SetAltHandshakeTypeEnabled(); | ||
client_->Set0RttEnabled(true); | ||
server_->Set0RttEnabled(true); | ||
|
||
client_->Handshake(); // Send ClientHello (and CCS) | ||
|
||
server_->Handshake(); // Consume the ClientHello, which is OK. | ||
client_->ExpectResumption(); | ||
client_->Handshake(); // Read the server handshake. | ||
EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state()); | ||
|
||
// Now the server reads the CCS instead of more handshake messages. | ||
ExpectAlert(server_, kTlsAlertBadRecordMac); | ||
server_->Handshake(); | ||
EXPECT_EQ(TlsAgent::STATE_ERROR, server_->state()); | ||
client_->Handshake(); // Consume the alert. | ||
EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state()); | ||
} | ||
|
||
} // nss_test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.