From: Philippe Antoine Date: Wed, 19 Feb 2025 12:01:36 +0000 (+0100) Subject: quic: handle retry packets X-Git-Tag: suricata-8.0.0-beta1~393 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6d8910d2455adcfd92c5970a3654d0bf90546489;p=thirdparty%2Fsuricata.git quic: handle retry packets Ticket: 7556 --- diff --git a/rust/src/quic/parser.rs b/rust/src/quic/parser.rs index 2552743994..3fba85040b 100644 --- a/rust/src/quic/parser.rs +++ b/rust/src/quic/parser.rs @@ -357,6 +357,10 @@ impl QuicHeader { rest } } + QuicType::Retry => { + // opaque retry token and 16 bytes retry integrity tag + &rest[rest.len()..] + } _ => rest, }; let (rest, length) = if has_length { diff --git a/rust/src/quic/quic.rs b/rust/src/quic/quic.rs index 606f962beb..c636e8d1bb 100644 --- a/rust/src/quic/quic.rs +++ b/rust/src/quic/quic.rs @@ -339,12 +339,16 @@ impl QuicState { // unprotect/decrypt packet if self.keys.is_none() && header.ty == QuicType::Initial { self.keys = quic_keys_initial(u32::from(header.version), &header.dcid); + } else if !to_server && self.keys.is_some() && header.ty == QuicType::Retry { + // a retry packet discards the current keys, client will resend an initial packet with new keys + self.hello_ts = false; + self.keys = None; } // header.length was checked against rest.len() during parsing let (mut framebuf, next_buf) = rest.split_at(header.length.into()); let hlen = buf.len() - rest.len(); let mut output; - if self.keys.is_some() { + if self.keys.is_some() && !framebuf.is_empty() { output = Vec::with_capacity(framebuf.len() + 4); if let Ok(dlen) = self.decrypt(to_server, &header, framebuf, buf, hlen, &mut output)