Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions quiche/quic/core/quic_connection_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14416,7 +14416,7 @@ TEST_P(QuicConnectionTest, NewTokenFrameInstigateAcks) {
}
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));

QuicNewTokenFrame* new_token = new QuicNewTokenFrame();
QuicNewTokenFrame* new_token = new QuicNewTokenFrame(1, "new_token");
EXPECT_CALL(visitor_, OnNewTokenReceived(_));
ProcessFramePacket(QuicFrame(new_token));

Expand All @@ -14429,7 +14429,7 @@ TEST_P(QuicConnectionTest, ServerClosesConnectionOnNewTokenFrame) {
return;
}
set_perspective(Perspective::IS_SERVER);
QuicNewTokenFrame* new_token = new QuicNewTokenFrame();
QuicNewTokenFrame* new_token = new QuicNewTokenFrame(1, "new_token");
EXPECT_CALL(visitor_, OnNewTokenReceived(_)).Times(0);
EXPECT_CALL(visitor_, OnConnectionClosed(_, _));
EXPECT_CALL(visitor_, BeforeConnectionCloseSent());
Expand Down Expand Up @@ -16201,7 +16201,7 @@ TEST_P(QuicConnectionTest, AckElicitingFrames) {
EXPECT_CALL(visitor_, OnStreamsBlockedFrame(_));
EXPECT_CALL(visitor_, OnStopSendingFrame(_));
EXPECT_CALL(visitor_, OnDatagramReceived(""));
EXPECT_CALL(visitor_, OnNewTokenReceived(""));
EXPECT_CALL(visitor_, OnNewTokenReceived("new_token"));

SetClientConnectionId(TestConnectionId(12));
connection_.CreateConnectionIdManager();
Expand All @@ -16221,7 +16221,7 @@ TEST_P(QuicConnectionTest, AckElicitingFrames) {
QuicStopSendingFrame stop_sending_frame;
QuicPathResponseFrame path_response_frame;
QuicDatagramFrame message_frame;
QuicNewTokenFrame new_token_frame;
QuicNewTokenFrame new_token_frame(1, "new_token");
QuicAckFrequencyFrame ack_frequency_frame;
QuicResetStreamAtFrame reset_stream_at_frame;
QuicBlockedFrame blocked_frame;
Expand Down
7 changes: 7 additions & 0 deletions quiche/quic/core/quic_framer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3073,6 +3073,13 @@ bool QuicFramer::ProcessIetfFrameData(QuicDataReader* reader,
if (!ProcessNewTokenFrame(reader, &frame)) {
return RaiseError(QUIC_INVALID_NEW_TOKEN);
}
if (frame.token.empty()) {
// RFC 9000, Section 19.7: the token in a NEW_TOKEN frame MUST NOT
// be empty, and a client MUST treat receipt of an empty Token
// field as a connection error of type FRAME_ENCODING_ERROR.
set_detailed_error("New token frame has empty token.");
return RaiseError(QUIC_INVALID_FRAME_DATA);
}
QUIC_DVLOG(2) << ENDPOINT << "Processing IETF new token frame "
<< frame;
if (!visitor_->OnNewTokenFrame(frame)) {
Expand Down
33 changes: 33 additions & 0 deletions quiche/quic/core/quic_framer_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11297,6 +11297,39 @@ TEST_P(QuicFramerTest, NewTokenFrame) {
CheckFramingBoundaries(packet, QUIC_INVALID_NEW_TOKEN);
}

TEST_P(QuicFramerTest, NewTokenFrameEmptyToken) {
if (!VersionIsIetfQuic(framer_.transport_version())) {
// This frame is only for IETF QUIC only.
return;
}
SetDecrypterLevel(ENCRYPTION_FORWARD_SECURE);
// clang-format off
PacketFragments packet = {
// type (short header, 4 byte packet number)
{"",
{0x43}},
// connection_id
{"",
{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}},
// packet number
{"",
{0x12, 0x34, 0x56, 0x78}},
// frame type (IETF_NEW_TOKEN frame)
{"",
{0x07}},
// Length (0 = empty token)
{"New token frame has empty token.",
{0x00}}
};
// clang-format on

std::unique_ptr<QuicEncryptedPacket> encrypted(
AssemblePacketFromFragments(packet));
EXPECT_FALSE(framer_.ProcessPacket(*encrypted));
EXPECT_THAT(framer_.error(), IsError(QUIC_INVALID_FRAME_DATA));
EXPECT_EQ("New token frame has empty token.", framer_.detailed_error());
}

TEST_P(QuicFramerTest, BuildNewTokenFramePacket) {
if (!VersionIsIetfQuic(framer_.transport_version())) {
// This frame is only for IETF QUIC only.
Expand Down