Skip to content

Commit

Permalink
Document and tighten CID length validation
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralith committed Mar 26, 2024
1 parent 835a65f commit 6a1467d
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions quinn-proto/src/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
connection::{Connection, ConnectionError},
crypto::{self, Keys, UnsupportedVersion},
frame,
packet::{Header, Packet, PacketDecodeError, PacketNumber, PartialDecode},
packet::{Header, Packet, PacketDecodeError, PacketNumber, PartialDecode, PlainInitialHeader},
shared::{
ConnectionEvent, ConnectionEventInner, ConnectionId, EcnCodepoint, EndpointEvent,
EndpointEventInner, IssuedCid,
Expand Down Expand Up @@ -233,7 +233,7 @@ impl Endpoint {
}
};

if let Err(reason) = self.early_validate_first_packet(dst_cid) {
if let Err(reason) = self.early_validate_first_packet(header) {
return Some(DatagramEvent::Response(self.initial_close(
header.version,
addresses,
Expand Down Expand Up @@ -566,7 +566,7 @@ impl Endpoint {
/// Check if we should refuse a connection attempt regardless of the packet's contents
fn early_validate_first_packet(
&mut self,
dst_cid: &ConnectionId,
header: &PlainInitialHeader,
) -> Result<(), TransportError> {
let server_config = self.server_config.as_ref().unwrap();
if self.connections.len() >= server_config.concurrent_connections as usize || self.is_full()
Expand All @@ -575,12 +575,18 @@ impl Endpoint {
return Err(TransportError::CONNECTION_REFUSED(""));
}

if dst_cid.len() < 8
&& (!server_config.use_retry || dst_cid.len() != self.local_cid_generator.cid_len())
// RFC9000 §7.2 dictates that initial (client-chosen) destination CIDs must be at least 8
// bytes. If this is a Retry packet, then the length must instead match our usual CID
// length. If we ever issue non-Retry address validation tokens via `NEW_TOKEN`, then we'll
// also need to validate CID length for those after decoding the token.
if header.dst_cid.len() < 8
&& (!server_config.use_retry
|| (!header.token_pos.is_empty()
&& header.dst_cid.len() != self.local_cid_generator.cid_len()))
{
debug!(
"rejecting connection due to invalid DCID length {}",
dst_cid.len()
header.dst_cid.len()
);
return Err(TransportError::PROTOCOL_VIOLATION(
"invalid destination CID length",
Expand Down

0 comments on commit 6a1467d

Please sign in to comment.