Skip to content

Commit

Permalink
Ignore data appearing after close_notify
Browse files Browse the repository at this point in the history
  • Loading branch information
djc authored and ctz committed May 16, 2024
1 parent ef02434 commit 749121a
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
23 changes: 17 additions & 6 deletions rustls/src/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use crate::enums::{AlertDescription, ContentType};
use crate::error::{Error, PeerMisbehaved};
#[cfg(feature = "logging")]
use crate::log::trace;
use crate::msgs::deframer::{Deframed, DeframerSliceBuffer, DeframerVecBuffer, MessageDeframer};
use crate::msgs::deframer::{
Deframed, DeframerSliceBuffer, DeframerVecBuffer, FilledDeframerBuffer, MessageDeframer,
};
use crate::msgs::handshake::Random;
use crate::msgs::message::{InboundPlainMessage, Message, MessagePayload};
use crate::suites::{ExtractedSecrets, PartiallyExtractedSecrets};
Expand Down Expand Up @@ -157,22 +159,22 @@ mod connection {
/// A structure that implements [`std::io::Read`] for reading plaintext.
pub struct Reader<'a> {
pub(super) received_plaintext: &'a mut ChunkVecBuffer,
pub(super) peer_cleanly_closed: bool,
pub(super) has_received_close_notify: bool,
pub(super) has_seen_eof: bool,
}

impl<'a> Reader<'a> {
/// Check the connection's state if no bytes are available for reading.
fn check_no_bytes_state(&self) -> io::Result<()> {
match (self.peer_cleanly_closed, self.has_seen_eof) {
match (self.has_received_close_notify, self.has_seen_eof) {
// cleanly closed; don't care about TCP EOF: express this as Ok(0)
(true, _) => Ok(()),
// unclean closure
(false, true) => Err(io::Error::new(
io::ErrorKind::UnexpectedEof,
UNEXPECTED_EOF_MESSAGE,
)),
// connection still going, but need more data: signal `WouldBlock` so that
// connection still going, but needs more data: signal `WouldBlock` so that
// the caller knows this
(false, false) => Err(io::ErrorKind::WouldBlock.into()),
}
Expand Down Expand Up @@ -490,8 +492,7 @@ impl<Data> ConnectionCommon<Data> {
received_plaintext: &mut common.received_plaintext,
// Are we done? i.e., have we processed all received messages, and received a
// close_notify to indicate that no new messages will arrive?
peer_cleanly_closed: common.has_received_close_notify
&& !self.deframer_buffer.has_pending(),
has_received_close_notify: common.has_received_close_notify,
has_seen_eof: common.has_seen_eof,
}
}
Expand Down Expand Up @@ -785,6 +786,16 @@ impl<Data> ConnectionCore<Data> {
return Err(e);
}
}

if self
.common_state
.has_received_close_notify
{
// "Any data received after a closure alert has been received MUST be ignored."
// -- <https://datatracker.ietf.org/doc/html/rfc8446#section-6.1>
discard = borrowed_buffer.filled().len();
break;
}
}

deframer_buffer.discard(discard);
Expand Down
2 changes: 1 addition & 1 deletion rustls/src/msgs/deframer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ trait DeframerBuffer<'a, P: AppendPayload<'a>>: FilledDeframerBuffer {
fn copy(&mut self, payload: &P, at: usize);
}

trait FilledDeframerBuffer {
pub(crate) trait FilledDeframerBuffer {
fn filled_get_mut<I: SliceIndex<[u8]>>(&mut self, index: I) -> &mut I::Output {
self.filled_mut()
.get_mut(index)
Expand Down

0 comments on commit 749121a

Please sign in to comment.