Add new methods to QuicFramer for controlling decrypters
gfe-relnote: Protected behind QUIC_VERSION_99 and quic_supports_tls_handshake
PiperOrigin-RevId: 242758726
Change-Id: I930b15327319520dec92d12e387d388e808716e4
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc
index 4e1dc9e..9a99ca7 100644
--- a/quic/core/http/quic_spdy_client_session_test.cc
+++ b/quic/core/http/quic_spdy_client_session_test.cc
@@ -489,13 +489,22 @@
EXPECT_CALL(*connection_, OnError(_)).Times(1);
// Verify that a decryptable packet with bad frames does close the connection.
- QuicConnectionId connection_id = session_->connection()->connection_id();
+ QuicConnectionId destination_connection_id =
+ session_->connection()->connection_id();
+ QuicConnectionId source_connection_id = EmptyQuicConnectionId();
QuicFramerPeer::SetLastSerializedConnectionId(
- QuicConnectionPeer::GetFramer(connection_), connection_id);
+ QuicConnectionPeer::GetFramer(connection_), destination_connection_id);
ParsedQuicVersionVector versions = {GetParam()};
+ bool version_flag = false;
+ QuicConnectionIdIncluded scid_included = CONNECTION_ID_ABSENT;
+ if (GetParam().transport_version > QUIC_VERSION_43) {
+ version_flag = true;
+ source_connection_id = destination_connection_id;
+ scid_included = CONNECTION_ID_PRESENT;
+ }
std::unique_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
- connection_id, EmptyQuicConnectionId(), false, false, 100, "data",
- CONNECTION_ID_ABSENT, CONNECTION_ID_ABSENT, PACKET_4BYTE_PACKET_NUMBER,
+ destination_connection_id, source_connection_id, version_flag, false, 100,
+ "data", CONNECTION_ID_ABSENT, scid_included, PACKET_4BYTE_PACKET_NUMBER,
&versions, Perspective::IS_SERVER));
std::unique_ptr<QuicReceivedPacket> received(
ConstructReceivedPacket(*packet, QuicTime::Zero()));
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index d90413a..d16b140 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -2874,6 +2874,20 @@
}
}
+void QuicConnection::InstallDecrypter(
+ EncryptionLevel level,
+ std::unique_ptr<QuicDecrypter> decrypter) {
+ framer_.InstallDecrypter(level, std::move(decrypter));
+ if (!undecryptable_packets_.empty() &&
+ !process_undecryptable_packets_alarm_->IsSet()) {
+ process_undecryptable_packets_alarm_->Set(clock_->ApproximateNow());
+ }
+}
+
+void QuicConnection::RemoveDecrypter(EncryptionLevel level) {
+ framer_.RemoveDecrypter(level);
+}
+
const QuicDecrypter* QuicConnection::decrypter() const {
return framer_.decrypter();
}
@@ -3894,6 +3908,13 @@
return packet_generator_.GetGuaranteedLargestMessagePayload();
}
+uint32_t QuicConnection::cipher_id() const {
+ if (version().KnowsWhichDecrypterToUse()) {
+ return framer_.GetDecrypter(last_decrypted_packet_level_)->cipher_id();
+ }
+ return framer_.decrypter()->cipher_id();
+}
+
bool QuicConnection::ShouldSetAckAlarm() const {
DCHECK(ack_frame_updated());
if (ack_alarm_->IsSet()) {
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 7f8b8c8..da666b4 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -672,6 +672,10 @@
std::unique_ptr<QuicDecrypter> decrypter,
bool latch_once_used);
+ void InstallDecrypter(EncryptionLevel level,
+ std::unique_ptr<QuicDecrypter> decrypter);
+ void RemoveDecrypter(EncryptionLevel level);
+
const QuicDecrypter* decrypter() const;
const QuicDecrypter* alternative_decrypter() const;
@@ -765,8 +769,8 @@
// connection ID lengths do not change.
QuicPacketLength GetGuaranteedLargestMessagePayload() const;
- // Return the id of the cipher of the primary decrypter of the framer.
- uint32_t cipher_id() const { return framer_.decrypter()->cipher_id(); }
+ // Returns the id of the cipher last used for decrypting packets.
+ uint32_t cipher_id() const;
std::vector<std::unique_ptr<QuicEncryptedPacket>>* termination_packets() {
return termination_packets_.get();
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 698bf8b..6cc6809 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -5,14 +5,15 @@
#include "net/third_party/quiche/src/quic/core/quic_connection.h"
#include <errno.h>
+
#include <memory>
#include <ostream>
-#include <utility>
-
#include <string>
+#include <utility>
#include "net/third_party/quiche/src/quic/core/congestion_control/loss_detection_interface.h"
#include "net/third_party/quiche/src/quic/core/congestion_control/send_algorithm_interface.h"
+#include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
@@ -358,8 +359,21 @@
}
if (use_tagging_decrypter_) {
- framer_.framer()->SetDecrypter(ENCRYPTION_INITIAL,
- QuicMakeUnique<TaggingDecrypter>());
+ if (framer_.framer()->version().KnowsWhichDecrypterToUse()) {
+ framer_.framer()->InstallDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingDecrypter>());
+ framer_.framer()->InstallDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<TaggingDecrypter>());
+ framer_.framer()->InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<TaggingDecrypter>());
+ } else {
+ framer_.framer()->SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<TaggingDecrypter>());
+ }
+ } else if (framer_.framer()->version().KnowsWhichDecrypterToUse()) {
+ framer_.framer()->InstallDecrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<NullDecrypter>(Perspective::IS_SERVER));
}
EXPECT_TRUE(framer_.ProcessPacket(packet));
if (block_on_next_write_) {
@@ -967,6 +981,12 @@
.WillRepeatedly(Return(QuicTime::Zero()));
EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
.Times(AnyNumber());
+
+ if (connection_.version().KnowsWhichDecrypterToUse()) {
+ connection_.InstallDecrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
+ }
}
QuicConnectionTest(const QuicConnectionTest&) = delete;
@@ -994,6 +1014,16 @@
void use_tagging_decrypter() { writer_->use_tagging_decrypter(); }
+ void SetDecrypter(EncryptionLevel level,
+ std::unique_ptr<QuicDecrypter> decrypter) {
+ if (connection_.version().KnowsWhichDecrypterToUse()) {
+ connection_.InstallDecrypter(level, std::move(decrypter));
+ connection_.RemoveDecrypter(ENCRYPTION_INITIAL);
+ } else {
+ connection_.SetDecrypter(level, std::move(decrypter));
+ }
+ }
+
void ProcessPacket(uint64_t number) {
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
ProcessDataPacket(number);
@@ -1048,8 +1078,11 @@
void ForceProcessFramePacket(QuicFrame frame) {
QuicFrames frames;
frames.push_back(QuicFrame(frame));
- QuicPacketCreatorPeer::SetSendVersionInPacket(
- &peer_creator_, connection_.perspective() == Perspective::IS_SERVER);
+ bool send_version = connection_.perspective() == Perspective::IS_SERVER;
+ if (connection_.version().KnowsWhichDecrypterToUse()) {
+ send_version = true;
+ }
+ QuicPacketCreatorPeer::SetSendVersionInPacket(&peer_creator_, send_version);
QuicPacketHeader header;
QuicPacketCreatorPeer::FillPacketHeader(&peer_creator_, &header);
char encrypted_buffer[kMaxOutgoingPacketSize];
@@ -1081,6 +1114,16 @@
peer_framer_.perspective() == Perspective::IS_SERVER) {
header.destination_connection_id_included = CONNECTION_ID_ABSENT;
}
+ if (level == ENCRYPTION_INITIAL &&
+ peer_framer_.version().KnowsWhichDecrypterToUse()) {
+ header.version_flag = true;
+ header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+ header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+ if (peer_framer_.perspective() == Perspective::IS_SERVER) {
+ header.source_connection_id = connection_id_;
+ header.source_connection_id_included = CONNECTION_ID_PRESENT;
+ }
+ }
header.packet_number = QuicPacketNumber(number);
QuicFrames frames;
frames.push_back(frame);
@@ -1094,9 +1137,16 @@
QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
QuicMakeUnique<TaggingEncrypter>(0x01));
// Set the corresponding decrypter.
- connection_.SetDecrypter(
- QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
- QuicMakeUnique<StrictTaggingDecrypter>(0x01));
+ if (connection_.version().KnowsWhichDecrypterToUse()) {
+ connection_.InstallDecrypter(
+ QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+ QuicMakeUnique<StrictTaggingDecrypter>(0x01));
+ connection_.RemoveDecrypter(ENCRYPTION_INITIAL);
+ } else {
+ connection_.SetDecrypter(
+ QuicPacketCreatorPeer::GetEncryptionLevel(&peer_creator_),
+ QuicMakeUnique<StrictTaggingDecrypter>(0x01));
+ }
}
char buffer[kMaxOutgoingPacketSize];
@@ -2951,8 +3001,8 @@
EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
QuicMakeUnique<TaggingEncrypter>(0x01));
- connection_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- QuicMakeUnique<StrictTaggingDecrypter>(0x01));
+ SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<StrictTaggingDecrypter>(0x01));
ProcessDataPacketAtLevel(2, false, ENCRYPTION_FORWARD_SECURE);
EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -3377,7 +3427,7 @@
1, stream_id, QUIC_ERROR_PROCESSING_STREAM, 14)));
}
EXPECT_EQ(1u, writer_->frame_count());
- EXPECT_EQ(1u, writer_->rst_stream_frames().size());
+ ASSERT_EQ(1u, writer_->rst_stream_frames().size());
EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id);
}
@@ -4031,8 +4081,8 @@
// Transition to the new encryption state and process another encrypted packet
// which should result in the original packet being processed.
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(tag));
@@ -4105,8 +4155,8 @@
// Transition to the new encryption state and process another encrypted packet
// which should result in the original packets being processed.
EXPECT_FALSE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
EXPECT_TRUE(connection_.GetProcessUndecryptablePacketsAlarm()->IsSet());
connection_.SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
connection_.SetEncrypter(ENCRYPTION_ZERO_RTT,
@@ -5441,8 +5491,8 @@
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
@@ -5483,8 +5533,8 @@
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
@@ -5564,8 +5614,8 @@
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
@@ -5626,8 +5676,8 @@
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
@@ -5764,8 +5814,8 @@
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
@@ -5820,8 +5870,8 @@
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
@@ -5881,8 +5931,8 @@
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
@@ -5948,8 +5998,8 @@
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
@@ -6035,8 +6085,8 @@
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
@@ -6106,8 +6156,8 @@
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
const uint8_t tag = 0x07;
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(tag));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(tag));
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(tag));
// Process a packet from the non-crypto stream.
@@ -6277,8 +6327,8 @@
EXPECT_CALL(visitor_, OnStreamFrame(_));
peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
QuicMakeUnique<TaggingEncrypter>(0x01));
- connection_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- QuicMakeUnique<StrictTaggingDecrypter>(0x01));
+ SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<StrictTaggingDecrypter>(0x01));
ProcessDataPacketAtLevel(1, false, ENCRYPTION_FORWARD_SECURE);
connection_.SendStreamDataWithString(
GetNthClientInitiatedStreamId(1, connection_.transport_version()), "foo",
@@ -8560,8 +8610,8 @@
EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(0x02));
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(0x02));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(0x02));
connection_.SetEncrypter(ENCRYPTION_INITIAL,
QuicMakeUnique<TaggingEncrypter>(0x02));
// Receives packet 1000 in application data.
@@ -8588,8 +8638,8 @@
peer_framer_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
QuicMakeUnique<TaggingEncrypter>(0x02));
- connection_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- QuicMakeUnique<StrictTaggingDecrypter>(0x02));
+ SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<StrictTaggingDecrypter>(0x02));
// Verify zero rtt and forward secure packets get acked in the same packet.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
ProcessDataPacketAtLevel(1003, false, ENCRYPTION_FORWARD_SECURE);
@@ -8608,8 +8658,8 @@
EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
peer_framer_.SetEncrypter(ENCRYPTION_ZERO_RTT,
QuicMakeUnique<TaggingEncrypter>(0x02));
- connection_.SetDecrypter(ENCRYPTION_ZERO_RTT,
- QuicMakeUnique<StrictTaggingDecrypter>(0x02));
+ SetDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<StrictTaggingDecrypter>(0x02));
connection_.SetEncrypter(ENCRYPTION_INITIAL,
QuicMakeUnique<TaggingEncrypter>(0x02));
// Receives packet 1000 in application data.
diff --git a/quic/core/quic_crypto_client_handshaker.cc b/quic/core/quic_crypto_client_handshaker.cc
index 013ab3f..d6c9af4 100644
--- a/quic/core/quic_crypto_client_handshaker.cc
+++ b/quic/core/quic_crypto_client_handshaker.cc
@@ -375,10 +375,16 @@
crypto_config_->pad_full_hello());
SendHandshakeMessage(out);
// Be prepared to decrypt with the new server write key.
- session()->connection()->SetAlternativeDecrypter(
- ENCRYPTION_ZERO_RTT,
- std::move(crypto_negotiated_params_->initial_crypters.decrypter),
- true /* latch once used */);
+ if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
+ session()->connection()->InstallDecrypter(
+ ENCRYPTION_ZERO_RTT,
+ std::move(crypto_negotiated_params_->initial_crypters.decrypter));
+ } else {
+ session()->connection()->SetAlternativeDecrypter(
+ ENCRYPTION_ZERO_RTT,
+ std::move(crypto_negotiated_params_->initial_crypters.decrypter),
+ true /* latch once used */);
+ }
// Send subsequent packets under encryption on the assumption that the
// server will accept the handshake.
session()->connection()->SetEncrypter(
@@ -584,10 +590,8 @@
// to see whether the response was a reject, and if so, move on to
// the reject-processing state.
if ((in->tag() == kREJ) || (in->tag() == kSREJ)) {
- // alternative_decrypter will be nullptr if the original alternative
- // decrypter latched and became the primary decrypter. That happens
- // if we received a message encrypted with the INITIAL key.
- if (session()->connection()->alternative_decrypter() == nullptr) {
+ // A reject message must be sent in ENCRYPTION_INITIAL.
+ if (session()->connection()->last_decrypted_level() != ENCRYPTION_INITIAL) {
// The rejection was sent encrypted!
stream_->CloseConnectionWithDetails(
QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, "encrypted REJ message");
@@ -603,10 +607,7 @@
return;
}
- // alternative_decrypter will be nullptr if the original alternative
- // decrypter latched and became the primary decrypter. That happens
- // if we received a message encrypted with the INITIAL key.
- if (session()->connection()->alternative_decrypter() != nullptr) {
+ if (session()->connection()->last_decrypted_level() == ENCRYPTION_INITIAL) {
// The server hello was sent without encryption.
stream_->CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
"unencrypted SHLO message");
@@ -638,9 +639,14 @@
// has been floated that the server shouldn't send packets encrypted
// with the FORWARD_SECURE key until it receives a FORWARD_SECURE
// packet from the client.
- session()->connection()->SetAlternativeDecrypter(
- ENCRYPTION_FORWARD_SECURE, std::move(crypters->decrypter),
- false /* don't latch */);
+ if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
+ session()->connection()->InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+ std::move(crypters->decrypter));
+ } else {
+ session()->connection()->SetAlternativeDecrypter(
+ ENCRYPTION_FORWARD_SECURE, std::move(crypters->decrypter),
+ false /* don't latch */);
+ }
session()->connection()->SetEncrypter(ENCRYPTION_FORWARD_SECURE,
std::move(crypters->encrypter));
session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
diff --git a/quic/core/quic_crypto_server_handshaker.cc b/quic/core/quic_crypto_server_handshaker.cc
index cd3cce9..c0e61ef 100644
--- a/quic/core/quic_crypto_server_handshaker.cc
+++ b/quic/core/quic_crypto_server_handshaker.cc
@@ -230,9 +230,16 @@
session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_ZERO_RTT);
// Set the decrypter immediately so that we no longer accept unencrypted
// packets.
- session()->connection()->SetDecrypter(
- ENCRYPTION_ZERO_RTT,
- std::move(crypto_negotiated_params_->initial_crypters.decrypter));
+ if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
+ session()->connection()->InstallDecrypter(
+ ENCRYPTION_ZERO_RTT,
+ std::move(crypto_negotiated_params_->initial_crypters.decrypter));
+ session()->connection()->RemoveDecrypter(ENCRYPTION_INITIAL);
+ } else {
+ session()->connection()->SetDecrypter(
+ ENCRYPTION_ZERO_RTT,
+ std::move(crypto_negotiated_params_->initial_crypters.decrypter));
+ }
session()->connection()->SetDiversificationNonce(*diversification_nonce);
session()->connection()->set_fully_pad_crypto_hadshake_packets(
@@ -244,10 +251,17 @@
std::move(crypto_negotiated_params_->forward_secure_crypters.encrypter));
session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- session()->connection()->SetAlternativeDecrypter(
- ENCRYPTION_FORWARD_SECURE,
- std::move(crypto_negotiated_params_->forward_secure_crypters.decrypter),
- false /* don't latch */);
+ if (session()->connection()->version().KnowsWhichDecrypterToUse()) {
+ session()->connection()->InstallDecrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ std::move(
+ crypto_negotiated_params_->forward_secure_crypters.decrypter));
+ } else {
+ session()->connection()->SetAlternativeDecrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ std::move(crypto_negotiated_params_->forward_secure_crypters.decrypter),
+ false /* don't latch */);
+ }
encryption_established_ = true;
handshake_confirmed_ = true;
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index c24a23c..fdce309 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -346,6 +346,32 @@
return NUM_PACKET_NUMBER_SPACES;
}
+EncryptionLevel GetEncryptionLevel(const QuicPacketHeader& header) {
+ switch (header.form) {
+ case GOOGLE_QUIC_PACKET:
+ QUIC_BUG << "Cannot determine EncryptionLevel from Google QUIC header";
+ break;
+ case IETF_QUIC_SHORT_HEADER_PACKET:
+ return ENCRYPTION_FORWARD_SECURE;
+ case IETF_QUIC_LONG_HEADER_PACKET:
+ switch (header.long_packet_type) {
+ case INITIAL:
+ return ENCRYPTION_INITIAL;
+ case HANDSHAKE:
+ return ENCRYPTION_HANDSHAKE;
+ case ZERO_RTT_PROTECTED:
+ return ENCRYPTION_ZERO_RTT;
+ case VERSION_NEGOTIATION:
+ case RETRY:
+ case INVALID_PACKET_TYPE:
+ QUIC_BUG << "No encryption used with type "
+ << QuicUtils::QuicLongHeaderTypetoString(
+ header.long_packet_type);
+ }
+ }
+ return NUM_ENCRYPTION_LEVELS;
+}
+
QuicStringPiece TruncateErrorString(QuicStringPiece error) {
if (error.length() <= kMaxErrorStringLength) {
return error;
@@ -3878,6 +3904,7 @@
std::unique_ptr<QuicDecrypter> decrypter) {
DCHECK_EQ(alternative_decrypter_level_, NUM_ENCRYPTION_LEVELS);
DCHECK_GE(level, decrypter_level_);
+ DCHECK(!version_.KnowsWhichDecrypterToUse());
decrypter_[decrypter_level_] = nullptr;
decrypter_[level] = std::move(decrypter);
decrypter_level_ = level;
@@ -3888,6 +3915,7 @@
std::unique_ptr<QuicDecrypter> decrypter,
bool latch_once_used) {
DCHECK_NE(level, decrypter_level_);
+ DCHECK(!version_.KnowsWhichDecrypterToUse());
if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
decrypter_[alternative_decrypter_level_] = nullptr;
}
@@ -3896,6 +3924,22 @@
alternative_decrypter_latch_ = latch_once_used;
}
+void QuicFramer::InstallDecrypter(EncryptionLevel level,
+ std::unique_ptr<QuicDecrypter> decrypter) {
+ DCHECK(version_.KnowsWhichDecrypterToUse());
+ decrypter_[level] = std::move(decrypter);
+}
+
+void QuicFramer::RemoveDecrypter(EncryptionLevel level) {
+ DCHECK(version_.KnowsWhichDecrypterToUse());
+ decrypter_[level] = nullptr;
+}
+
+const QuicDecrypter* QuicFramer::GetDecrypter(EncryptionLevel level) const {
+ DCHECK(version_.KnowsWhichDecrypterToUse());
+ return decrypter_[level].get();
+}
+
const QuicDecrypter* QuicFramer::decrypter() const {
return decrypter_[decrypter_level_].get();
}
@@ -3991,18 +4035,31 @@
size_t buffer_length,
size_t* decrypted_length,
EncryptionLevel* decrypted_level) {
- DCHECK(decrypter_[decrypter_level_] != nullptr);
+ EncryptionLevel level = decrypter_level_;
+ QuicDecrypter* decrypter = decrypter_[level].get();
QuicDecrypter* alternative_decrypter = nullptr;
- if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
+ if (version().KnowsWhichDecrypterToUse()) {
+ level = GetEncryptionLevel(header);
+ decrypter = decrypter_[level].get();
+ if (decrypter == nullptr) {
+ return false;
+ }
+ if (level == ENCRYPTION_ZERO_RTT &&
+ perspective_ == Perspective::IS_CLIENT && header.nonce != nullptr) {
+ decrypter->SetDiversificationNonce(*header.nonce);
+ }
+ } else if (alternative_decrypter_level_ != NUM_ENCRYPTION_LEVELS) {
alternative_decrypter = decrypter_[alternative_decrypter_level_].get();
}
- bool success = decrypter_[decrypter_level_]->DecryptPacket(
+ DCHECK(decrypter != nullptr);
+
+ bool success = decrypter->DecryptPacket(
header.packet_number.ToUint64(), associated_data, encrypted,
decrypted_buffer, decrypted_length, buffer_length);
if (success) {
- visitor_->OnDecryptedPacket(decrypter_level_);
- *decrypted_level = decrypter_level_;
+ visitor_->OnDecryptedPacket(level);
+ *decrypted_level = level;
} else if (alternative_decrypter != nullptr) {
if (header.nonce != nullptr) {
DCHECK_EQ(perspective_, Perspective::IS_CLIENT);
diff --git a/quic/core/quic_framer.h b/quic/core/quic_framer.h
index 84773b4..26c7125 100644
--- a/quic/core/quic_framer.h
+++ b/quic/core/quic_framer.h
@@ -475,6 +475,11 @@
std::unique_ptr<QuicDecrypter> decrypter,
bool latch_once_used);
+ void InstallDecrypter(EncryptionLevel level,
+ std::unique_ptr<QuicDecrypter> decrypter);
+ void RemoveDecrypter(EncryptionLevel level);
+
+ const QuicDecrypter* GetDecrypter(EncryptionLevel level) const;
const QuicDecrypter* decrypter() const;
const QuicDecrypter* alternative_decrypter() const;
diff --git a/quic/core/quic_framer_test.cc b/quic/core/quic_framer_test.cc
index 927b100..523b0b8 100644
--- a/quic/core/quic_framer_test.cc
+++ b/quic/core/quic_framer_test.cc
@@ -454,8 +454,13 @@
kQuicDefaultConnectionIdLength) {
SetQuicFlag(&FLAGS_quic_supports_tls_handshake, true);
framer_.set_version(version_);
- framer_.SetDecrypter(ENCRYPTION_INITIAL,
- std::unique_ptr<QuicDecrypter>(decrypter_));
+ if (framer_.version().KnowsWhichDecrypterToUse()) {
+ framer_.InstallDecrypter(ENCRYPTION_INITIAL,
+ std::unique_ptr<QuicDecrypter>(decrypter_));
+ } else {
+ framer_.SetDecrypter(ENCRYPTION_INITIAL,
+ std::unique_ptr<QuicDecrypter>(decrypter_));
+ }
framer_.SetEncrypter(ENCRYPTION_INITIAL,
std::unique_ptr<QuicEncrypter>(encrypter_));
@@ -463,6 +468,14 @@
framer_.InferPacketHeaderTypeFromVersion();
}
+ void SetDecrypterLevel(EncryptionLevel level) {
+ if (!framer_.version().KnowsWhichDecrypterToUse()) {
+ return;
+ }
+ decrypter_ = new TestDecrypter();
+ framer_.InstallDecrypter(level, std::unique_ptr<QuicDecrypter>(decrypter_));
+ }
+
// Helper function to get unsigned char representation of the handshake
// protocol byte of the current QUIC version number.
unsigned char GetQuicVersionProtocolByte() {
@@ -801,6 +814,7 @@
}
TEST_P(QuicFramerTest, LargePacket) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet[kMaxIncomingPacketSize + 1] = {
// public flags (8 byte connection_id)
@@ -958,6 +972,7 @@
}
TEST_P(QuicFramerTest, PacketHeaderWith0ByteConnectionId) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
QuicFramerPeer::SetLastSerializedConnectionId(&framer_,
FramerTestConnectionId());
QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
@@ -1013,6 +1028,7 @@
}
TEST_P(QuicFramerTest, PacketHeaderWithVersionFlag) {
+ SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
// clang-format off
PacketFragments packet = {
// public flags (0 byte connection_id)
@@ -1112,6 +1128,7 @@
}
TEST_P(QuicFramerTest, PacketHeaderWith4BytePacketNumber) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
// clang-format off
@@ -1171,6 +1188,7 @@
}
TEST_P(QuicFramerTest, PacketHeaderWith2BytePacketNumber) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
// clang-format off
@@ -1231,6 +1249,7 @@
}
TEST_P(QuicFramerTest, PacketHeaderWith1BytePacketNumber) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
QuicFramerPeer::SetLargestPacketNumber(&framer_, kPacketNumber - 2);
// clang-format off
@@ -1292,6 +1311,7 @@
}
TEST_P(QuicFramerTest, PacketNumberDecreasesThenIncreases) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// Test the case when a packet is received from the past and future packet
// numbers are still calculated relative to the largest received packet.
QuicPacketHeader header;
@@ -1358,6 +1378,7 @@
}
TEST_P(QuicFramerTest, PacketWithDiversificationNonce) {
+ SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
// clang-format off
unsigned char packet[] = {
// public flags: includes nonce flag
@@ -1527,6 +1548,7 @@
}
TEST_P(QuicFramerTest, PaddingFrame) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
@@ -1671,6 +1693,7 @@
}
TEST_P(QuicFramerTest, StreamFrame) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// public flags (8 byte connection_id)
@@ -1827,6 +1850,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// type (short header, 4 byte packet number)
@@ -1880,11 +1904,18 @@
return;
}
QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- framer_.SetDecrypter(ENCRYPTION_INITIAL,
- QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
decrypter_ = new test::TestDecrypter();
- framer_.SetAlternativeDecrypter(
- ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
+ if (framer_.version().KnowsWhichDecrypterToUse()) {
+ framer_.InstallDecrypter(ENCRYPTION_INITIAL, QuicMakeUnique<NullDecrypter>(
+ Perspective::IS_CLIENT));
+ framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
+ std::unique_ptr<QuicDecrypter>(decrypter_));
+ } else {
+ framer_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
+ framer_.SetAlternativeDecrypter(
+ ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
+ }
// clang-format off
unsigned char packet[] = {
@@ -2029,6 +2060,7 @@
}
TEST_P(QuicFramerTest, StreamFrame2ByteStreamId) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// public flags (8 byte connection_id)
@@ -2180,6 +2212,7 @@
}
TEST_P(QuicFramerTest, StreamFrame1ByteStreamId) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// public flags (8 byte connection_id)
@@ -2331,6 +2364,7 @@
}
TEST_P(QuicFramerTest, StreamFrameWithVersion) {
+ SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
// clang-format off
PacketFragments packet = {
// public flags (version, 8 byte connection_id)
@@ -2520,6 +2554,7 @@
}
TEST_P(QuicFramerTest, RejectPacket) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
visitor_.accept_packet_ = false;
// clang-format off
@@ -2665,6 +2700,7 @@
}
TEST_P(QuicFramerTest, AckFrameOneAckBlock) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// public flags (8 byte connection_id)
@@ -2816,6 +2852,7 @@
// and handles the case where the first ack block is larger than the
// largest_acked packet.
TEST_P(QuicFramerTest, FirstAckFrameUnderflow) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// public flags (8 byte connection_id)
@@ -2950,6 +2987,7 @@
// for now, only v99
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
// type (short header, 4 byte packet number)
@@ -3007,6 +3045,7 @@
// for now, only v99
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
// type (short header, 4 byte packet number)
@@ -3062,6 +3101,7 @@
// for now, only v99
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
// type (short header, 4 byte packet number)
@@ -3111,6 +3151,7 @@
// for now, only v99
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
// type (short header, 4 byte packet number)
@@ -3159,6 +3200,7 @@
// for now, only v99
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
// type (short header, 4 byte packet number)
@@ -3357,6 +3399,7 @@
}
TEST_P(QuicFramerTest, AckFrameOneAckBlockMaxLength) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// public flags (8 byte connection_id)
@@ -3499,6 +3542,7 @@
// Tests ability to handle multiple ackblocks after the first ack
// block. Non-version-99 tests include multiple timestamps as well.
TEST_P(QuicFramerTest, AckFrameTwoTimeStampsMultipleAckBlocks) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// public flags (8 byte connection_id)
@@ -4132,6 +4176,7 @@
}
TEST_P(QuicFramerTest, RstStreamFrame) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// public flags (8 byte connection_id)
@@ -4257,6 +4302,7 @@
}
TEST_P(QuicFramerTest, ConnectionCloseFrame) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// public flags (8 byte connection_id)
@@ -4409,6 +4455,7 @@
// This frame does not exist in versions other than 99.
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -4684,6 +4731,7 @@
// This frame is available only in version 99.
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
// type (short header, 4 byte packet number)
@@ -4727,6 +4775,7 @@
// This frame available only in version 99.
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
// type (short header, 4 byte packet number)
@@ -4768,6 +4817,7 @@
}
TEST_P(QuicFramerTest, BlockedFrame) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// public flags (8 byte connection_id)
@@ -4877,6 +4927,7 @@
}
TEST_P(QuicFramerTest, PingFrame) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
@@ -4960,6 +5011,7 @@
if (framer_.transport_version() <= QUIC_VERSION_44) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet45 = {
// type (short header, 4 byte packet number)
@@ -5262,11 +5314,18 @@
return;
}
QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- framer_.SetDecrypter(ENCRYPTION_INITIAL,
- QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
decrypter_ = new test::TestDecrypter();
- framer_.SetAlternativeDecrypter(
- ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
+ if (framer_.version().KnowsWhichDecrypterToUse()) {
+ framer_.InstallDecrypter(ENCRYPTION_INITIAL, QuicMakeUnique<NullDecrypter>(
+ Perspective::IS_CLIENT));
+ framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
+ std::unique_ptr<QuicDecrypter>(decrypter_));
+ } else {
+ framer_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
+ framer_.SetAlternativeDecrypter(
+ ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
+ }
// This packet cannot be decrypted because diversification nonce is missing.
QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
EXPECT_TRUE(framer_.ProcessPacket(encrypted));
@@ -5292,11 +5351,18 @@
return;
}
QuicFramerPeer::SetPerspective(&framer_, Perspective::IS_CLIENT);
- framer_.SetDecrypter(ENCRYPTION_INITIAL,
- QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
decrypter_ = new test::TestDecrypter();
- framer_.SetAlternativeDecrypter(
- ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
+ if (framer_.version().KnowsWhichDecrypterToUse()) {
+ framer_.InstallDecrypter(ENCRYPTION_INITIAL, QuicMakeUnique<NullDecrypter>(
+ Perspective::IS_CLIENT));
+ framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
+ std::unique_ptr<QuicDecrypter>(decrypter_));
+ } else {
+ framer_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<NullDecrypter>(Perspective::IS_CLIENT));
+ framer_.SetAlternativeDecrypter(
+ ENCRYPTION_ZERO_RTT, std::unique_ptr<QuicDecrypter>(decrypter_), false);
+ }
// This packet cannot be decrypted because diversification nonce is missing.
QuicEncryptedPacket encrypted(AsChars(packet), QUIC_ARRAYSIZE(packet), false);
EXPECT_FALSE(framer_.ProcessPacket(encrypted));
@@ -6202,6 +6268,7 @@
// CRYPTO frames aren't supported prior to v46.
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
@@ -9453,6 +9520,7 @@
}
TEST_P(QuicFramerTest, StopPacketProcessing) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
@@ -9647,10 +9715,14 @@
TEST_P(QuicFramerTest, ConstructEncryptedPacket) {
// Since we are using ConstructEncryptedPacket, we have to set the framer's
// crypto to be Null.
- framer_.SetDecrypter(ENCRYPTION_INITIAL,
- QuicMakeUnique<NullDecrypter>(framer_.perspective()));
- framer_.SetEncrypter(ENCRYPTION_INITIAL,
- QuicMakeUnique<NullEncrypter>(framer_.perspective()));
+ if (framer_.version().KnowsWhichDecrypterToUse()) {
+ framer_.InstallDecrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<NullDecrypter>(framer_.perspective()));
+ } else {
+ framer_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<NullDecrypter>(framer_.perspective()));
+ }
ParsedQuicVersionVector versions;
versions.push_back(framer_.version());
std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
@@ -9685,10 +9757,16 @@
// Verify that the packet returned by ConstructMisFramedEncryptedPacket()
// does cause the framer to return an error.
TEST_P(QuicFramerTest, ConstructMisFramedEncryptedPacket) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// Since we are using ConstructEncryptedPacket, we have to set the framer's
// crypto to be Null.
- framer_.SetDecrypter(ENCRYPTION_INITIAL,
- QuicMakeUnique<NullDecrypter>(framer_.perspective()));
+ if (framer_.version().KnowsWhichDecrypterToUse()) {
+ framer_.InstallDecrypter(ENCRYPTION_INITIAL, QuicMakeUnique<NullDecrypter>(
+ framer_.perspective()));
+ } else {
+ framer_.SetDecrypter(ENCRYPTION_INITIAL,
+ QuicMakeUnique<NullDecrypter>(framer_.perspective()));
+ }
framer_.SetEncrypter(ENCRYPTION_INITIAL,
QuicMakeUnique<NullEncrypter>(framer_.perspective()));
ParsedQuicVersionVector versions;
@@ -9861,6 +9939,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -9943,6 +10022,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -10030,6 +10110,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -10077,6 +10158,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -10127,6 +10209,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -10175,6 +10258,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -10228,6 +10312,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet99[] = {
@@ -10271,6 +10356,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet99[] = {
@@ -10320,6 +10406,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet99[] = {
@@ -10364,6 +10451,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet99[] = {
@@ -10411,6 +10499,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet99[] = {
@@ -10440,6 +10529,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -10492,6 +10582,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -10539,6 +10630,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -10587,6 +10679,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -10638,6 +10731,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet99[] = {
@@ -10672,6 +10766,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet99[] = {
@@ -11071,6 +11166,7 @@
// This frame is only for version 99.
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
// type (short header, 4 byte packet number)
@@ -11126,6 +11222,7 @@
// This frame is only for version 99.
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
// type (short header, 4 byte packet number)
@@ -11183,6 +11280,7 @@
// The NEW_CONNECTION_ID frame is only for version 99.
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
// type (short header, 4 byte packet number)
@@ -11275,6 +11373,7 @@
// This frame is only for version 99.
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// type (short header, 4 byte packet number)
@@ -11367,6 +11466,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -11454,6 +11554,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -11536,6 +11637,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
@@ -11702,6 +11804,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// type (short header, 4 byte packet number)
@@ -11733,6 +11836,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
@@ -11765,6 +11869,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
@@ -11797,6 +11902,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// type (short header, 4 byte packet number)
@@ -11832,6 +11938,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
@@ -11864,6 +11971,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
@@ -11896,6 +12004,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// type (short header, 4 byte packet number)
@@ -11931,6 +12040,7 @@
if (framer_.transport_version() != QUIC_VERSION_99) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packets[] = {
@@ -12331,6 +12441,7 @@
// This frame is only for version 99.
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet99 = {
// type (short header, 4 byte packet number)
@@ -12411,6 +12522,7 @@
}
TEST_P(QuicFramerTest, AckFrameWithInvalidLargestObserved) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
@@ -12511,6 +12623,7 @@
}
TEST_P(QuicFramerTest, FirstAckBlockJustUnderFlow) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
@@ -12613,6 +12726,7 @@
}
TEST_P(QuicFramerTest, ThirdAckBlockJustUnderflow) {
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char packet[] = {
// public flags (8 byte connection_id)
@@ -12761,6 +12875,7 @@
if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
// clang-format off
unsigned char packet[] = {
// first coalesced packet
@@ -12855,6 +12970,7 @@
if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
// clang-format off
unsigned char packet[] = {
// first coalesced packet
@@ -12937,6 +13053,7 @@
if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
// clang-format off
unsigned char packet[] = {
// first coalesced packet
@@ -12997,6 +13114,7 @@
if (framer_.transport_version() < QUIC_VERSION_46) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
char connection_id_bytes[9] = {0xFE, 0xDC, 0xBA, 0x98, 0x76,
0x54, 0x32, 0x10, 0x42};
QuicConnectionId connection_id(connection_id_bytes,
@@ -13037,6 +13155,7 @@
if (framer_.transport_version() < QUIC_VERSION_46) {
return;
}
+ SetDecrypterLevel(ENCRYPTION_ZERO_RTT);
framer_.SetShouldUpdateExpectedConnectionIdLength(true);
// clang-format off
@@ -13091,6 +13210,7 @@
EXPECT_EQ(visitor_.header_.get()->packet_number,
QuicPacketNumber(UINT64_C(0x12345678)));
+ SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
unsigned char short_header_packet[] = {
// type (short header, 4 byte packet number)
@@ -13158,7 +13278,13 @@
};
// clang-format on
- framer_.SetDecrypter(ENCRYPTION_ZERO_RTT, QuicMakeUnique<TestDecrypter>());
+ if (framer_.version().KnowsWhichDecrypterToUse()) {
+ framer_.InstallDecrypter(ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<TestDecrypter>());
+ framer_.RemoveDecrypter(ENCRYPTION_INITIAL);
+ } else {
+ framer_.SetDecrypter(ENCRYPTION_ZERO_RTT, QuicMakeUnique<TestDecrypter>());
+ }
if (!QuicVersionHasLongHeaderLengths(framer_.transport_version())) {
EXPECT_TRUE(framer_.ProcessPacket(
QuicEncryptedPacket(AsChars(long_header_packet),
@@ -13194,8 +13320,14 @@
QuicEncryptedPacket short_header_encrypted(
AsChars(short_header_packet), QUIC_ARRAYSIZE(short_header_packet), false);
- framer_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- QuicMakeUnique<TestDecrypter>());
+ if (framer_.version().KnowsWhichDecrypterToUse()) {
+ framer_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<TestDecrypter>());
+ framer_.RemoveDecrypter(ENCRYPTION_ZERO_RTT);
+ } else {
+ framer_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<TestDecrypter>());
+ }
EXPECT_TRUE(framer_.ProcessPacket(short_header_encrypted));
EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
diff --git a/quic/core/quic_packet_creator_test.cc b/quic/core/quic_packet_creator_test.cc
index d463846..56381ea 100644
--- a/quic/core/quic_packet_creator_test.cc
+++ b/quic/core/quic_packet_creator_test.cc
@@ -9,6 +9,7 @@
#include <ostream>
#include <string>
+#include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
@@ -164,6 +165,17 @@
client_framer_.set_visitor(&framer_visitor_);
server_framer_.set_visitor(&framer_visitor_);
client_framer_.set_data_producer(&producer_);
+ if (server_framer_.version().KnowsWhichDecrypterToUse()) {
+ server_framer_.InstallDecrypter(
+ ENCRYPTION_ZERO_RTT,
+ QuicMakeUnique<NullDecrypter>(Perspective::IS_SERVER));
+ server_framer_.InstallDecrypter(
+ ENCRYPTION_HANDSHAKE,
+ QuicMakeUnique<NullDecrypter>(Perspective::IS_SERVER));
+ server_framer_.InstallDecrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<NullDecrypter>(Perspective::IS_SERVER));
+ }
}
~QuicPacketCreatorTest() override {
diff --git a/quic/core/quic_packet_generator_test.cc b/quic/core/quic_packet_generator_test.cc
index 9edddfc..466d96b 100644
--- a/quic/core/quic_packet_generator_test.cc
+++ b/quic/core/quic_packet_generator_test.cc
@@ -9,6 +9,7 @@
#include <string>
#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
+#include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/null_encrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
@@ -215,6 +216,11 @@
QuicMakeUnique<NullEncrypter>(Perspective::IS_CLIENT));
creator_->set_encryption_level(ENCRYPTION_FORWARD_SECURE);
framer_.set_data_producer(&producer_);
+ if (simple_framer_.framer()->version().KnowsWhichDecrypterToUse()) {
+ simple_framer_.framer()->InstallDecrypter(
+ ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<NullDecrypter>(Perspective::IS_SERVER));
+ }
generator_.AttachPacketFlusher();
}
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
index ca6bdae..83263de 100644
--- a/quic/core/quic_versions.cc
+++ b/quic/core/quic_versions.cc
@@ -41,6 +41,11 @@
}
}
+bool ParsedQuicVersion::KnowsWhichDecrypterToUse() const {
+ return transport_version == QUIC_VERSION_99 ||
+ handshake_protocol == PROTOCOL_TLS1_3;
+}
+
std::ostream& operator<<(std::ostream& os, const ParsedQuicVersion& version) {
os << ParsedQuicVersionToString(version);
return os;
diff --git a/quic/core/quic_versions.h b/quic/core/quic_versions.h
index cc780b4..160adeb 100644
--- a/quic/core/quic_versions.h
+++ b/quic/core/quic_versions.h
@@ -145,6 +145,8 @@
return handshake_protocol != other.handshake_protocol ||
transport_version != other.transport_version;
}
+
+ bool KnowsWhichDecrypterToUse() const;
};
QUIC_EXPORT_PRIVATE ParsedQuicVersion UnsupportedQuicVersion();
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc
index 5081a48..932d537 100644
--- a/quic/core/tls_client_handshaker.cc
+++ b/quic/core/tls_client_handshaker.cc
@@ -73,8 +73,8 @@
session()->connection_id(), &crypters);
session()->connection()->SetEncrypter(ENCRYPTION_INITIAL,
std::move(crypters.encrypter));
- session()->connection()->SetDecrypter(ENCRYPTION_INITIAL,
- std::move(crypters.decrypter));
+ session()->connection()->InstallDecrypter(ENCRYPTION_INITIAL,
+ std::move(crypters.decrypter));
state_ = STATE_HANDSHAKE_RUNNING;
// Configure certificate verification.
// TODO(nharper): This only verifies certs on initial connection, not on
diff --git a/quic/core/tls_handshaker.cc b/quic/core/tls_handshaker.cc
index c6394b8..3a45f36 100644
--- a/quic/core/tls_handshaker.cc
+++ b/quic/core/tls_handshaker.cc
@@ -205,22 +205,8 @@
const std::vector<uint8_t>& write_secret) {
std::unique_ptr<QuicEncrypter> encrypter = CreateEncrypter(write_secret);
session()->connection()->SetEncrypter(level, std::move(encrypter));
- if (level != ENCRYPTION_FORWARD_SECURE) {
- std::unique_ptr<QuicDecrypter> decrypter = CreateDecrypter(read_secret);
- session()->connection()->SetDecrypter(level, std::move(decrypter));
- } else {
- // When forward-secure read keys are available, they get set as the
- // alternative decrypter instead of the primary decrypter. One reason for
- // this is that after the forward secure keys become available, the server
- // still has crypto handshake messages to read at the handshake encryption
- // level, meaning that both the ENCRYPTION_ZERO_RTT and
- // ENCRYPTION_FORWARD_SECURE decrypters need to be available. (Tests also
- // assume that an alternative decrypter gets set, so at some point we need
- // to call SetAlternativeDecrypter.)
- std::unique_ptr<QuicDecrypter> decrypter = CreateDecrypter(read_secret);
- session()->connection()->SetAlternativeDecrypter(
- level, std::move(decrypter), /*latch_once_used*/ true);
- }
+ std::unique_ptr<QuicDecrypter> decrypter = CreateDecrypter(read_secret);
+ session()->connection()->InstallDecrypter(level, std::move(decrypter));
}
void TlsHandshaker::WriteMessage(EncryptionLevel level, QuicStringPiece data) {
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc
index 96e1802..15b2c82 100644
--- a/quic/core/tls_server_handshaker.cc
+++ b/quic/core/tls_server_handshaker.cc
@@ -69,8 +69,8 @@
session->connection_id(), &crypters);
session->connection()->SetEncrypter(ENCRYPTION_INITIAL,
std::move(crypters.encrypter));
- session->connection()->SetDecrypter(ENCRYPTION_INITIAL,
- std::move(crypters.decrypter));
+ session->connection()->InstallDecrypter(ENCRYPTION_INITIAL,
+ std::move(crypters.decrypter));
// Configure the SSL to be a server.
SSL_set_accept_state(ssl());
diff --git a/quic/test_tools/crypto_test_utils.cc b/quic/test_tools/crypto_test_utils.cc
index af33d4e..63154b9 100644
--- a/quic/test_tools/crypto_test_utils.cc
+++ b/quic/test_tools/crypto_test_utils.cc
@@ -749,6 +749,11 @@
void CompareCrypters(const QuicEncrypter* encrypter,
const QuicDecrypter* decrypter,
std::string label) {
+ if (encrypter == nullptr || decrypter == nullptr) {
+ ADD_FAILURE() << "Expected non-null crypters; have " << encrypter << " and "
+ << decrypter;
+ return;
+ }
QuicStringPiece encrypter_key = encrypter->GetKey();
QuicStringPiece encrypter_iv = encrypter->GetNoncePrefix();
QuicStringPiece decrypter_key = decrypter->GetKey();
diff --git a/quic/test_tools/quic_test_utils.cc b/quic/test_tools/quic_test_utils.cc
index e5988e0..b6d285d 100644
--- a/quic/test_tools/quic_test_utils.cc
+++ b/quic/test_tools/quic_test_utils.cc
@@ -923,6 +923,11 @@
header.reset_flag = reset_flag;
header.packet_number_length = packet_number_length;
header.packet_number = QuicPacketNumber(packet_number);
+ if (QuicVersionHasLongHeaderLengths((*versions)[0].transport_version) &&
+ version_flag) {
+ header.retry_token_length_length = VARIABLE_LENGTH_INTEGER_LENGTH_1;
+ header.length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
+ }
QuicFrame frame(QuicStreamFrame(1, false, 0, QuicStringPiece(data)));
QuicFrames frames;
frames.push_back(frame);
@@ -941,8 +946,7 @@
GetIncludedDestinationConnectionIdLength(header),
GetIncludedSourceConnectionIdLength(header), version_flag,
false /* no diversification nonce */, packet_number_length,
- VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, VARIABLE_LENGTH_INTEGER_LENGTH_0)] =
- 0x1F;
+ header.retry_token_length_length, 0, header.length_length)] = 0x1F;
char* buffer = new char[kMaxOutgoingPacketSize];
size_t encrypted_length =
diff --git a/quic/test_tools/simulator/quic_endpoint.cc b/quic/test_tools/simulator/quic_endpoint.cc
index 1072724..9e5c3fa 100644
--- a/quic/test_tools/simulator/quic_endpoint.cc
+++ b/quic/test_tools/simulator/quic_endpoint.cc
@@ -86,8 +86,14 @@
connection_.set_visitor(this);
connection_.SetEncrypter(ENCRYPTION_FORWARD_SECURE,
QuicMakeUnique<NullEncrypter>(perspective));
- connection_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
- QuicMakeUnique<NullDecrypter>(perspective));
+ if (connection_.version().KnowsWhichDecrypterToUse()) {
+ connection_.InstallDecrypter(ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<NullDecrypter>(perspective));
+ connection_.RemoveDecrypter(ENCRYPTION_INITIAL);
+ } else {
+ connection_.SetDecrypter(ENCRYPTION_FORWARD_SECURE,
+ QuicMakeUnique<NullDecrypter>(perspective));
+ }
connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
if (perspective == Perspective::IS_SERVER) {
// Skip version negotiation.