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;
 }