Add support for retry integrity tag
This CL adds support for the retry integrity tag which was added in draft-25. It increases resilience to network errors and makes retry injection by attackers harder. This changes the wire-format of T050 and T099/draft-25 which are both disabled.
gfe-relnote: support retry integrity tag, client-only, not flag-protected
PiperOrigin-RevId: 292044658
Change-Id: Ib62a4d58cb761dce284c36b450816ad9151e4062
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index 080aa01..1170595 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -1495,6 +1495,31 @@
const QuicPacketHeader& header) {
DCHECK_EQ(Perspective::IS_CLIENT, perspective_);
+ if (version_.HasRetryIntegrityTag()) {
+ DCHECK(version_.HasLengthPrefixedConnectionIds()) << version_;
+ const size_t bytes_remaining = reader->BytesRemaining();
+ if (bytes_remaining <= kRetryIntegrityTagLength) {
+ set_detailed_error("Retry packet too short to parse integrity tag.");
+ return false;
+ }
+ const size_t retry_token_length =
+ bytes_remaining - kRetryIntegrityTagLength;
+ DCHECK_GT(retry_token_length, 0u);
+ quiche::QuicheStringPiece retry_token;
+ if (!reader->ReadStringPiece(&retry_token, retry_token_length)) {
+ set_detailed_error("Failed to read retry token.");
+ return false;
+ }
+ quiche::QuicheStringPiece retry_without_tag =
+ reader->PreviouslyReadPayload();
+ quiche::QuicheStringPiece integrity_tag = reader->ReadRemainingPayload();
+ DCHECK_EQ(integrity_tag.length(), kRetryIntegrityTagLength);
+ visitor_->OnRetryPacket(EmptyQuicConnectionId(),
+ header.source_connection_id, retry_token,
+ integrity_tag, retry_without_tag);
+ return true;
+ }
+
QuicConnectionId original_destination_connection_id;
if (version_.HasLengthPrefixedConnectionIds()) {
// Parse Original Destination Connection ID.
@@ -1526,7 +1551,9 @@
quiche::QuicheStringPiece retry_token = reader->ReadRemainingPayload();
visitor_->OnRetryPacket(original_destination_connection_id,
- header.source_connection_id, retry_token);
+ header.source_connection_id, retry_token,
+ /*retry_integrity_tag=*/quiche::QuicheStringPiece(),
+ /*retry_without_tag=*/quiche::QuicheStringPiece());
return true;
}